Redesign Variant struct

This commit is contained in:
Greg Shuflin 2021-10-21 19:53:50 -07:00
parent 2256f25482
commit b4f765167b
4 changed files with 40 additions and 31 deletions

View File

@ -148,14 +148,17 @@ pub struct Signature {
pub struct TypeBody(pub Vec<Variant>);
#[derive(Debug, PartialEq, Clone)]
pub enum Variant {
UnitStruct(Rc<String>),
TupleStruct(Rc<String>, Vec<TypeIdentifier>),
Record {
name: Rc<String>,
members: Vec<(Rc<String>, TypeIdentifier)>,
}
}
pub struct Variant {
pub name: Rc<String>,
pub kind: VariantKind,
}
#[derive(Debug, PartialEq, Clone)]
pub enum VariantKind {
UnitStruct,
TupleStruct(Vec<TypeIdentifier>),
Record(Vec<(Rc<String>, TypeIdentifier)>),
}
#[derive(Debug, Derivative, Clone)]
#[derivative(PartialEq)]

View File

@ -447,20 +447,22 @@ impl Parser {
#[recursive_descent_method]
fn variant_specifier(&mut self) -> ParseResult<Variant> {
use self::Variant::*;
let name = self.identifier()?;
match self.token_handler.peek_kind() {
let kind = match self.token_handler.peek_kind() {
LParen => {
let tuple_members = delimited!(self, LParen, type_name, Comma, RParen);
Ok(TupleStruct(name, tuple_members))
VariantKind::TupleStruct(tuple_members)
},
LCurlyBrace => {
let typed_identifier_list = delimited!(self, LCurlyBrace, typed_identifier, Comma, RCurlyBrace);
Ok(Record {name, members: typed_identifier_list })
VariantKind::Record(typed_identifier_list)
},
_ => Ok(UnitStruct(name))
}
_ => VariantKind::UnitStruct
};
Ok(Variant {
name,
kind
})
}
#[recursive_descent_method]

View File

@ -12,7 +12,7 @@ use super::Signature;
use super::TypeIdentifier::*;
use super::TypeSingletonName;
use super::ExpressionKind::*;
use super::Variant::*;
use super::VariantKind::*;
use super::ForBody::*;
fn make_parser(input: &str) -> Parser {
@ -322,24 +322,27 @@ fn parsing_strings() {
#[test]
fn parsing_types() {
parse_test_wrap_ast!("type Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: false} ));
parse_test_wrap_ast!("type mut Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![UnitStruct(rc!(Yolo))]), mutable: true} ));
parse_test_wrap_ast!("type Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![Variant { kind: UnitStruct, name: rc!(Yolo) }]), mutable: false} ));
parse_test_wrap_ast!("type mut Yolo = Yolo", decl!(TypeDecl { name: tys!("Yolo"), body: TypeBody(vec![Variant { kind: UnitStruct, name: rc!(Yolo) }]), mutable: true} ));
parse_test_wrap_ast!("type alias Sex = Drugs", decl!(TypeAlias { alias: rc!(Sex), original: rc!(Drugs) }));
parse_test_wrap_ast!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esperanza { a: Int, b: String }",
decl!(TypeDecl {
name: tys!("Sanchez"),
body: TypeBody(vec![
UnitStruct(rc!(Miguel)),
TupleStruct(rc!(Alejandro), vec![
Variant { kind: UnitStruct, name: rc!(Miguel) },
Variant {
name: rc!(Alejandro),
kind: TupleStruct(vec![
Singleton(TypeSingletonName { name: rc!(Int), params: vec![] }),
Singleton(TypeSingletonName { name: rc!(Option), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] }),
]),
Record{
name: rc!(Esperanza),
members: vec![
])
},
Variant {
name: rc!(Esperanza),
kind: Record(vec![
(rc!(a), Singleton(TypeSingletonName { name: rc!(Int), params: vec![] })),
(rc!(b), Singleton(TypeSingletonName { name: rc!(String), params: vec![] })),
]
])
}
]),
mutable: false
@ -349,7 +352,7 @@ fn parsing_types() {
"type Jorge<a> = Diego | Kike(a)",
decl!(TypeDecl{
name: TypeSingletonName { name: rc!(Jorge), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] },
body: TypeBody(vec![UnitStruct(rc!(Diego)), TupleStruct(rc!(Kike), vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })])]),
body: TypeBody(vec![Variant{ kind: UnitStruct, name: rc!(Diego) }, Variant { name: rc!(Kike), kind: TupleStruct( vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })]) }]),
mutable: false
}
)

View File

@ -5,7 +5,7 @@ use std::rc::Rc;
use crate::ast;
use crate::ast::{
Declaration, ItemId, ModuleSpecifier, Statement, StatementKind, TypeBody, TypeSingletonName,
Variant,
Variant, VariantKind,
};
use crate::tokenizing::Location;
use crate::typechecking::TypeName;
@ -422,8 +422,9 @@ impl SymbolTable {
scope_stack.push(new_scope);
for (index, variant) in variants.iter().enumerate() {
match variant {
Variant::UnitStruct(name) => {
let Variant { name, kind } = variant;
match kind {
VariantKind::UnitStruct => {
let fq_name = Fqsn::from_scope_stack(scope_stack.as_ref(), name.clone());
let spec = SymbolSpec::DataConstructor {
index,
@ -432,7 +433,7 @@ impl SymbolTable {
};
register(fq_name, spec);
}
Variant::TupleStruct(name, items) => {
VariantKind::TupleStruct(items) => {
let fq_name = Fqsn::from_scope_stack(scope_stack.as_ref(), name.clone());
let spec = SymbolSpec::DataConstructor {
index,
@ -441,7 +442,7 @@ impl SymbolTable {
};
register(fq_name, spec);
}
Variant::Record { name, members } => {
VariantKind::Record(members) => {
let fq_name = Fqsn::from_scope_stack(scope_stack.as_ref(), name.clone());
let mut seen_members = HashMap::new();