Allow type annotations in let expressions

This commit is contained in:
greg 2019-02-20 22:44:45 -08:00
parent 03793e08d3
commit a6eb2b4020
3 changed files with 16 additions and 5 deletions

View File

@ -56,6 +56,7 @@ pub enum Declaration {
Binding { Binding {
name: Rc<String>, name: Rc<String>,
constant: bool, constant: bool,
type_anno: Option<TypeIdentifier>,
expr: Expression, expr: Expression,
}, },
Impl { Impl {

View File

@ -444,10 +444,16 @@ impl Parser {
_ => true _ => true
}; };
let name = self.identifier()?; let name = self.identifier()?;
let type_anno = if let Colon = self.token_handler.peek_kind() {
Some(self.type_anno()?)
} else {
None
};
expect!(self, Operator(ref o) if **o == "="); expect!(self, Operator(ref o) if **o == "=");
let expr = self.expression()?; let expr = self.expression()?;
Ok(Declaration::Binding { name, constant, expr }) Ok(Declaration::Binding { name, constant, type_anno, expr })
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1368,8 +1374,12 @@ fn a(x) {
#[test] #[test]
fn parsing_bindings() { fn parsing_bindings() {
parse_test!("let mut a = 10", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } ))])); parse_test!("let mut a = 10", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: false, type_anno: None, expr: ex!(NatLiteral(10)) } ))]));
parse_test!("let a = 2 + 2", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) )])); parse_test!("let a = 2 + 2", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) )]));
parse_test!("let a: Nat = 2 + 2", AST(vec![Node::new(Declaration(
Binding { name: rc!(a), constant: true, type_anno: Some(Singleton(TypeSingletonName { name: rc!(Nat), params: vec![] })),
expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }
))]));
} }
#[test] #[test]
@ -1497,7 +1507,7 @@ fn a(x) {
fn parsing_type_annotations() { fn parsing_type_annotations() {
parse_test!("let a = b : Int", AST(vec![ parse_test!("let a = b : Int", AST(vec![
Node::new( Node::new(
Declaration(Binding { name: rc!(a), constant: true, expr: Declaration(Binding { name: rc!(a), constant: true, type_anno: None, expr:
Expression(val!("b"), Some(ty!("Int"))) }))])); Expression(val!("b"), Some(ty!("Int"))) }))]));
parse_test!("a : Int", AST(vec![ parse_test!("a : Int", AST(vec![

View File

@ -358,7 +358,7 @@ impl Declaration {
use self::Declaration::*; use self::Declaration::*;
use crate::ast::Signature; use crate::ast::Signature;
match self { match self {
Binding {name, constant, expr } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce(symbol_table) }, Binding {name, constant, expr, .. } => Stmt::Binding { name: name.clone(), constant: *constant, expr: expr.reduce(symbol_table) },
FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding { FuncDecl(Signature { name, params, .. }, statements) => Stmt::PreBinding {
name: name.clone(), name: name.clone(),
func: Func::UserDefined { func: Func::UserDefined {