From f7dbbddad1f154a5f0681bd13cf87b518bfd4d26 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 11 Jul 2018 16:44:15 -0700 Subject: [PATCH] Let and let mut syntax --- schala-lang/src/eval.rs | 12 ++++++------ schala-lang/src/parsing.rs | 24 ++++++++++++++++-------- schala-lang/src/tokenizing.rs | 5 +++-- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/schala-lang/src/eval.rs b/schala-lang/src/eval.rs index bfc5031..64322cf 100644 --- a/schala-lang/src/eval.rs +++ b/schala-lang/src/eval.rs @@ -340,8 +340,8 @@ mod eval_tests { #[test] fn test_basic_eval() { fresh_env!("1 + 2", "3"); - fresh_env!("var a = 1; a = 2", "Unit"); - fresh_env!("var a = 1; a = 2; a", "2"); + fresh_env!("let mut a = 1; a = 2", "Unit"); + fresh_env!("let mut a = 1; a = 2; a", "2"); fresh_env!(r#"("a", 1 + 2)"#, r#"("a", 3)"#); } @@ -354,18 +354,18 @@ mod eval_tests { #[test] fn scopes() { let scope_ok = r#" - const a = 20 + let a = 20 fn haha() { - const a = 10 + let a = 10 a } haha() "#; fresh_env!(scope_ok, "10"); let scope_ok = r#" - const a = 20 + let a = 20 fn haha() { - const a = 10 + let a = 10 a } a diff --git a/schala-lang/src/parsing.rs b/schala-lang/src/parsing.rs index 75ea3ee..658bf25 100644 --- a/schala-lang/src/parsing.rs +++ b/schala-lang/src/parsing.rs @@ -44,8 +44,12 @@ formal_param := IDENTIFIER type_anno+ /* Declaration - Variable bindings */ +/* OLD */ binding_declaration: 'var' IDENTIFIER '=' expression | 'const' IDENTIFIER '=' expression +/* NEW */ +binding_declaration := 'let' 'mut'? IDENTIFIER '=' expresion + /* Declaration - Interface */ interface_declaration := 'interface' interface_name signature_block @@ -296,7 +300,7 @@ impl Parser { match self.peek() { Keyword(Type) => self.type_declaration().map(|decl| { Statement::Declaration(decl) }), Keyword(Func)=> self.func_declaration().map(|func| { Statement::Declaration(func) }), - Keyword(Var) | Keyword(Const) => self.binding_declaration().map(|decl| Statement::Declaration(decl)), + Keyword(Let) => self.binding_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Interface) => self.interface_declaration().map(|decl| Statement::Declaration(decl)), Keyword(Impl) => self.impl_declaration().map(|decl| Statement::Declaration(decl)), _ => self.expression().map(|expr| { Statement::ExpressionStatement(expr) } ), @@ -396,10 +400,14 @@ impl Parser { }); parse_method!(binding_declaration(&mut self) -> ParseResult { - let constant = match self.next() { - Keyword(Var) => false, - Keyword(Const) => true, - _ => return ParseError::new("Expected 'var' or 'const'"), + + expect!(self, Keyword(Kw::Let)); + let constant = match self.peek() { + Keyword(Kw::Mut) => { + self.next(); + false + } + _ => true }; let name = self.identifier()?; expect!(self, Operator(ref o) if **o == "="); @@ -1178,8 +1186,8 @@ fn a(x) { #[test] fn parsing_bindings() { - parse_test!("var a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } )])); - parse_test!("const a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) ])); + parse_test!("let mut a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: ex!(NatLiteral(10)) } )])); + parse_test!("let a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: ex!(binexp!("+", NatLiteral(2), NatLiteral(2))) }) ])); } #[test] @@ -1294,7 +1302,7 @@ fn a(x) { #[test] fn parsing_type_annotations() { - parse_test!("const a = b : Int", AST(vec![ + parse_test!("let a = b : Int", AST(vec![ Declaration(Binding { name: rc!(a), constant: true, expr: Expression(val!("b"), Some(ty!("Int"))) })])); diff --git a/schala-lang/src/tokenizing.rs b/schala-lang/src/tokenizing.rs index 2b4b8fd..79badbe 100644 --- a/schala-lang/src/tokenizing.rs +++ b/schala-lang/src/tokenizing.rs @@ -50,7 +50,8 @@ pub enum Kw { Func, For, While, Match, - Var, Const, Let, In, + Const, Let, In, + Mut, Return, Alias, Type, SelfType, SelfIdent, Interface, Impl, @@ -68,10 +69,10 @@ lazy_static! { "fn" => Kw::Func, "for" => Kw::For, "while" => Kw::While, - "var" => Kw::Var, "const" => Kw::Const, "let" => Kw::Let, "in" => Kw::In, + "mut" => Kw::Mut, "return" => Kw::Return, "alias" => Kw::Alias, "type" => Kw::Type,