Type singletons test work

This commit is contained in:
greg 2018-02-12 00:51:53 -08:00
parent ef4620e90a
commit 681d767855
2 changed files with 38 additions and 30 deletions

View File

@ -254,7 +254,7 @@ statement := expression | declaration
declaration := type_declaration | func_declaration | binding_declaration | impl_declaration declaration := type_declaration | func_declaration | binding_declaration | impl_declaration
type_declaration := 'type' type_declaration_body type_declaration := 'type' type_declaration_body
type_declaration_body := 'alias' type_alias | IDENTIFIER '=' type_body type_declaration_body := 'alias' type_alias | type_singleton_name '=' type_body
type_alias := IDENTIFIER '=' type_name type_alias := IDENTIFIER '=' type_name
type_body := variant_specifier ('|' variant_specifier)* type_body := variant_specifier ('|' variant_specifier)*
@ -279,8 +279,9 @@ decl_block := '{' (func_declaration)* '}'
trait_name := IDENTIFIER trait_name := IDENTIFIER
type_anno := (':' type_name)+ type_anno := (':' type_name)+
type_name := IDENTIFIER (type_params)* | '(' type_names ')' type_name := type_singleton_name | '(' type_names ')'
type_names := ε | type_name (, type_name)* type_names := ε | type_name (, type_name)*
type_singleton_name = IDENTIFIER (type_params)*
type_params := '<' type_name (, type_name)* '>' type_params := '<' type_name (, type_name)* '>'
expression := precedence_expr type_anno+ expression := precedence_expr type_anno+
@ -403,7 +404,7 @@ type FormalParam = (ParamName, Option<TypeName>);
pub enum Declaration { pub enum Declaration {
FuncSig(Signature), FuncSig(Signature),
FuncDecl(Signature, Vec<Statement>), FuncDecl(Signature, Vec<Statement>),
TypeDecl(Rc<String>, TypeBody), //should have TypeSingletonName in it TypeDecl(TypeSingletonName, TypeBody), //should have TypeSingletonName in it
TypeAlias(Rc<String>, Rc<String>), //should have TypeSingletonName in it, or maybe just String, not sure TypeAlias(Rc<String>, Rc<String>), //should have TypeSingletonName in it, or maybe just String, not sure
Binding { Binding {
name: Rc<String>, name: Rc<String>,
@ -598,7 +599,7 @@ impl Parser {
if let Keyword(Alias) = self.peek() { if let Keyword(Alias) = self.peek() {
self.type_alias() self.type_alias()
} else { } else {
let name = self.identifier()?; let name = self.type_singleton_name()?;
expect!(self, Operator(ref c) if **c == "=", "'='"); expect!(self, Operator(ref c) if **c == "=", "'='");
let body = self.type_body()?; let body = self.type_body()?;
Ok(Declaration::TypeDecl(name, body)) Ok(Declaration::TypeDecl(name, body))
@ -749,14 +750,18 @@ impl Parser {
use self::TypeName::*; use self::TypeName::*;
Ok(match self.peek() { Ok(match self.peek() {
LParen => Tuple(delimited!(self, LParen, '(', type_name, Comma, RParen, ')')), LParen => Tuple(delimited!(self, LParen, '(', type_name, Comma, RParen, ')')),
_ => Singleton(TypeSingletonName { _ => Singleton(self.type_singleton_name()?),
})
});
parse_method!(type_singleton_name(&mut self) -> ParseResult<TypeSingletonName> {
Ok(TypeSingletonName {
name: self.identifier()?, name: self.identifier()?,
params: match self.peek() { params: match self.peek() {
LAngleBracket => delimited!(self, LAngleBracket, '<', type_name, Comma, RAngleBracket, '>'), LAngleBracket => delimited!(self, LAngleBracket, '<', type_name, Comma, RAngleBracket, '>'),
_ => vec![], _ => vec![],
} }
}) })
})
}); });
// this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ // this implements Pratt parsing, see http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
@ -1071,6 +1076,7 @@ mod parse_tests {
use super::Declaration::*; use super::Declaration::*;
use super::Signature; use super::Signature;
use super::TypeName::*; use super::TypeName::*;
use super::TypeSingletonName;
use super::ExpressionType::*; use super::ExpressionType::*;
use super::Variant::*; use super::Variant::*;
@ -1103,7 +1109,10 @@ mod parse_tests {
($expr_type:expr) => { Expression($expr_type, None) } ($expr_type:expr) => { Expression($expr_type, None) }
} }
macro_rules! ty { macro_rules! ty {
($name:expr) => { Singleton { name: Rc::new($name.to_string()), params: vec![] } }; ($name:expr) => { Singleton(tys!($name)) }
}
macro_rules! tys {
($name:expr) => { TypeSingletonName { name: Rc::new($name.to_string()), params: vec![] } };
} }
#[test] #[test]
@ -1225,18 +1234,18 @@ mod parse_tests {
#[test] #[test]
fn parsing_types() { fn parsing_types() {
parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl(rc!(Yolo), TypeBody(vec![UnitStruct(rc!(Yolo))])))])); parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl(tys!("Yolo"), TypeBody(vec![UnitStruct(rc!(Yolo))])))]));
parse_test!("type alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))])); parse_test!("type alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))]));
parse_test!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esparanza { a: Int, b: String }", parse_test!("type Sanchez = Miguel | Alejandro(Int, Option<a>) | Esparenza { a: Int, b: String }",
AST(vec![Declaration(TypeDecl(rc!(Sanchez), TypeBody(vec![ AST(vec![Declaration(TypeDecl(tys!("Sanchez"), TypeBody(vec![
UnitStruct(rc!(Miguel)), UnitStruct(rc!(Miguel)),
TupleStruct(rc!(Alejandro), vec![ TupleStruct(rc!(Alejandro), vec![
Singleton { name: rc!(Int), params: vec![] }, Singleton(TypeSingletonName { name: rc!(Int), params: vec![] }),
Singleton { name: rc!(Option), params: vec![Singleton { name: rc!(a), params: vec![] }] }, Singleton(TypeSingletonName { name: rc!(Option), params: vec![Singleton(TypeSingletonName { name: rc!(a), params: vec![] })] }),
]), ]),
Record(rc!(Esparanza), vec![ Record(rc!(Esparenza), vec![
(rc!(a), Singleton { name: rc!(Int), params: vec![] }), (rc!(a), Singleton(TypeSingletonName { name: rc!(Int), params: vec![] })),
(rc!(b), Singleton { name: rc!(String), params: vec![] }), (rc!(b), Singleton(TypeSingletonName { name: rc!(String), params: vec![] })),
])])))])); ])])))]));
} }
@ -1300,7 +1309,7 @@ mod parse_tests {
] })])); ] })]));
parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![ parse_test!("impl Option<WTFMate> { fn oi() }", AST(vec![
Declaration(Impl { Declaration(Impl {
type_name: Singleton { name: rc!(Option), params: vec![ty!("WTFMate")]}, type_name: Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("WTFMate")]}),
trait_name: None, trait_name: None,
block: vec![ block: vec![
FuncSig(Signature { name: rc!(oi), params: vec![], type_anno: None }), FuncSig(Signature { name: rc!(oi), params: vec![], type_anno: None }),
@ -1319,19 +1328,19 @@ mod parse_tests {
])); ]));
parse_test!("a : Option<Int>", AST(vec![ parse_test!("a : Option<Int>", AST(vec![
exprstatement!(val!("a"), Singleton { name: rc!(Option), params: vec![ty!("Int")] }) exprstatement!(val!("a"), Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("Int")] }))
])); ]));
parse_test!("a : KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >", AST(vec![ parse_test!("a : KoreanBBQSpecifier<Kimchi, Option<Bulgogi> >", AST(vec![
exprstatement!(val!("a"), Singleton { name: rc!(KoreanBBQSpecifier), params: vec![ exprstatement!(val!("a"), Singleton(TypeSingletonName { name: rc!(KoreanBBQSpecifier), params: vec![
ty!("Kimchi"), Singleton { name: rc!(Option), params: vec![ty!("Bulgogi")] } ty!("Kimchi"), Singleton(TypeSingletonName { name: rc!(Option), params: vec![ty!("Bulgogi")] })
] }) ] }))
])); ]));
parse_test!("a : (Int, Yolo<a>)", AST(vec![ parse_test!("a : (Int, Yolo<a>)", AST(vec![
exprstatement!(val!("a"), Tuple( exprstatement!(val!("a"), Tuple(
vec![ty!("Int"), Singleton { vec![ty!("Int"), Singleton(TypeSingletonName {
name: rc!(Yolo), params: vec![ty!("a")] name: rc!(Yolo), params: vec![ty!("a")]
}]))])); })]))]));
} }
} }

View File

@ -179,7 +179,7 @@ impl TypeContext {
let (spec, ty) = match variant { let (spec, ty) = match variant {
&Variant::UnitStruct(ref data_constructor) => { &Variant::UnitStruct(ref data_constructor) => {
let spec = PathSpecifier(data_constructor.clone()); let spec = PathSpecifier(data_constructor.clone());
let ty = TConst(UserT(type_constructor.clone())); let ty = TConst(UserT(type_constructor.name.clone()));
(spec, ty) (spec, ty)
}, },
&Variant::TupleStruct(ref data_construcor, ref args) => { &Variant::TupleStruct(ref data_construcor, ref args) => {
@ -187,9 +187,8 @@ impl TypeContext {
let arg = args.get(0).unwrap(); let arg = args.get(0).unwrap();
let type_arg = self.from_anno(arg); let type_arg = self.from_anno(arg);
let spec = PathSpecifier(data_construcor.clone()); let spec = PathSpecifier(data_construcor.clone());
let ty = TFunc(Box::new(type_arg), Box::new(TConst(UserT(type_constructor.clone())))); let ty = TFunc(Box::new(type_arg), Box::new(TConst(UserT(type_constructor.name.clone()))));
(spec, ty) (spec, ty)
}, },
&Variant::Record(_, _) => unimplemented!(), &Variant::Record(_, _) => unimplemented!(),
}; };