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,13 +148,16 @@ pub struct Signature {
pub struct TypeBody(pub Vec<Variant>); pub struct TypeBody(pub Vec<Variant>);
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum Variant { pub struct Variant {
UnitStruct(Rc<String>), pub name: Rc<String>,
TupleStruct(Rc<String>, Vec<TypeIdentifier>), pub kind: VariantKind,
Record {
name: Rc<String>,
members: Vec<(Rc<String>, TypeIdentifier)>,
} }
#[derive(Debug, PartialEq, Clone)]
pub enum VariantKind {
UnitStruct,
TupleStruct(Vec<TypeIdentifier>),
Record(Vec<(Rc<String>, TypeIdentifier)>),
} }
#[derive(Debug, Derivative, Clone)] #[derive(Debug, Derivative, Clone)]

View File

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

View File

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

View File

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