From a6eb2b402098a1ec54aa97d2859af1cd82d04439 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 20 Feb 2019 22:44:45 -0800 Subject: [PATCH] Allow type annotations in let expressions --- schala-lang/language/src/ast.rs | 1 + schala-lang/language/src/parsing.rs | 18 ++++++++++++++---- schala-lang/language/src/reduced_ast.rs | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/schala-lang/language/src/ast.rs b/schala-lang/language/src/ast.rs index 05fad6e..112026f 100644 --- a/schala-lang/language/src/ast.rs +++ b/schala-lang/language/src/ast.rs @@ -56,6 +56,7 @@ pub enum Declaration { Binding { name: Rc, constant: bool, + type_anno: Option, expr: Expression, }, Impl { diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index bc96350..408d42a 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -444,10 +444,16 @@ impl Parser { _ => true }; 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 == "="); let expr = self.expression()?; - Ok(Declaration::Binding { name, constant, expr }) + Ok(Declaration::Binding { name, constant, type_anno, expr }) } #[recursive_descent_method] @@ -1368,8 +1374,12 @@ fn a(x) { #[test] 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 a = 2 + 2", AST(vec![Node::new(Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) )])); + 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, 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] @@ -1497,7 +1507,7 @@ fn a(x) { fn parsing_type_annotations() { parse_test!("let a = b : Int", AST(vec![ 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"))) }))])); parse_test!("a : Int", AST(vec![ diff --git a/schala-lang/language/src/reduced_ast.rs b/schala-lang/language/src/reduced_ast.rs index 5b164c8..b6b1dc4 100644 --- a/schala-lang/language/src/reduced_ast.rs +++ b/schala-lang/language/src/reduced_ast.rs @@ -358,7 +358,7 @@ impl Declaration { use self::Declaration::*; use crate::ast::Signature; 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 { name: name.clone(), func: Func::UserDefined {