Type singletons test work
This commit is contained in:
parent
cfc507a2df
commit
c18bf9c29f
@ -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")]
|
||||||
}]))]));
|
})]))]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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!(),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user