From b920fae93bcec492041c704c23094e44a3038c33 Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 17 Sep 2017 06:04:24 -0700 Subject: [PATCH] variable bindings --- src/schala_lang/parsing.rs | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/schala_lang/parsing.rs b/src/schala_lang/parsing.rs index 29da57f..de69a49 100644 --- a/src/schala_lang/parsing.rs +++ b/src/schala_lang/parsing.rs @@ -327,7 +327,7 @@ program := (statement delimiter)* EOF delimiter := NEWLINE | ';' statement := expression | declaration -declaration := type_alias | type_declaration | func_declaration +declaration := type_alias | type_declaration | func_declaration | binding_declaration type_alias := 'alias' IDENTIFIER '=' IDENTIFIER type_declaration := 'type' IDENTIFIER '=' type_body @@ -338,6 +338,9 @@ member_list := (IDENTIFIER type_anno)* func_declaration := 'fn' IDENTIFIER '(' param_list ')' param_list := (IDENTIFIER type_anno+ ',')* +binding_declaration: 'var' IDENTIFIER '=' expression + | 'const' IDENTIFIER '=' expression + type_anno := ':' type expression := precedence_expr @@ -435,7 +438,12 @@ pub enum Declaration { params: FormalParamList, }, TypeDecl(Rc, TypeBody), - TypeAlias(Rc, Rc) + TypeAlias(Rc, Rc), + Binding { + name: Rc, + constant: bool, + expr: Expression, + } } #[derive(Debug, PartialEq)] @@ -522,6 +530,7 @@ impl Parser { Keyword(Alias) => self.type_alias().map(|alias| { Statement::Declaration(alias) }), 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)), _ => self.expression().map(|expr| { Statement::Expression(expr) } ), } }); @@ -564,6 +573,19 @@ impl Parser { Ok(vec!()) }); + 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'"), + }; + let name = self.identifier()?; + expect!(self, Operator(ref o) if **o == "=", "Expected '='"); + let expr = self.expression()?; + + Ok(Declaration::Binding { name, constant, expr }) + }); + parse_method!(expression(&mut self) -> ParseResult { self.precedence_expr(Operation::min_precedence()) }); @@ -846,7 +868,7 @@ mod parse_tests { } #[test] - fn parse_complicated_operators() { + fn parsing_complicated_operators() { parse_test!("a <- b", AST(vec![Expression(binexp!(op!("<-"), var!("a"), var!("b")))])); parse_test!("a || b", AST(vec![Expression(binexp!(op!("||"), var!("a"), var!("b")))])); parse_test!("a<>b", AST(vec![Expression(binexp!(op!("<>"), var!("a"), var!("b")))])); @@ -868,7 +890,7 @@ mod parse_tests { } #[test] - fn parse_bools() { + fn parsing_bools() { parse_test!("false", AST(vec![Expression(BoolLiteral(false))])); parse_test!("true", AST(vec![Expression(BoolLiteral(true))])); } @@ -883,4 +905,10 @@ mod parse_tests { parse_test!("type Yolo = Yolo", AST(vec![Declaration(TypeDecl(rc!(Yolo), TypeBody(vec![Variant::Singleton(rc!(Yolo))])))])); parse_test!("alias Sex = Drugs", AST(vec![Declaration(TypeAlias(rc!(Sex), rc!(Drugs)))])); } + + #[test] + fn parsing_bindings() { + parse_test!("var a = 10", AST(vec![Declaration(Binding { name: rc!(a), constant: false, expr: IntLiteral(10) } )])); + parse_test!("const a = 2 + 2", AST(vec![Declaration(Binding { name: rc!(a), constant: true, expr: binexp!(op!("+"), IntLiteral(2), IntLiteral(2)) }) ])); + } }