From 1fa56800c5d11d7da52744e3fe39fb9922c5ceea Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 9 Jan 2017 20:33:08 -0800 Subject: [PATCH] Convert parsing while, if, fn exprs to use { } --- closure.schala | 8 ++++---- main.schala | 12 ++++++------ recurse.schala | 24 ++++++++++++------------ src/parser.rs | 47 ++++++++++++++++++++++++++++++++--------------- test.schala | 12 ++++++------ 5 files changed, 60 insertions(+), 43 deletions(-) diff --git a/closure.schala b/closure.schala index 3efce65..c5e4c19 100644 --- a/closure.schala +++ b/closure.schala @@ -1,11 +1,11 @@ -fn outer() - fn inner(a) +fn outer() { + fn inner(a) { a + 10 - end + } inner(20) + 8.3 -end +} outer() diff --git a/main.schala b/main.schala index bd6c1d1..a5ca877 100644 --- a/main.schala +++ b/main.schala @@ -1,17 +1,17 @@ -fn add(a, b) +fn add(a, b) { a + b -end +} -fn subtract(a, b) +fn subtract(a, b) { a - b -end +} -fn main() +fn main() { first_value = add(20, 20) second_value = subtract(700, 650) first_value + second_value -end +} main() diff --git a/recurse.schala b/recurse.schala index 2d6ed77..0941e96 100644 --- a/recurse.schala +++ b/recurse.schala @@ -1,24 +1,24 @@ -fn hella(x) +fn hella(x) { print("hey") - if x == 3 then + if x == 3 { Null - else + } else { hella(x + 1) - end -end + } +} hella(0) -fn fib(x) - if x < 3 then - 1 - else - fib(x - 1) + fib(x - 2) - end -end +fn fib(x) { + if x < 3 { + 1 + } else { + fib(x - 1) + fib(x - 2) + } +} fib(10) diff --git a/src/parser.rs b/src/parser.rs index 728efa5..cd41e9e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -9,17 +9,19 @@ use std::convert::From; // program := (statement delimiter ?)* // delimiter := Newline | Semicolon // statement := declaration | expression -// declaration := Fn prototype (statement)* End +// declaration := Fn prototype LCurlyBrace (statement)* RCurlyBrace // prototype := identifier LParen identlist RParen // identlist := Ident (Comma Ident)* | e // exprlist := Expression (Comma Expression)* | e // // expression := primary_expression (op primary_expression)* -// primary_expression := Number | String | identifier_expr | paren_expr | conditional_expr +// primary_expression := Number | String | identifier_expr | paren_expr | conditional_expr | +// while_expr // identifier_expr := call_expression | Variable +// while_expr := WHILE primary_expression LCurlyBrace (expression delimiter)* RCurlyBrace // paren_expr := LParen expression RParen // call_expr := Identifier LParen exprlist RParen -// conditional_expr := IF expression THEN (expression delimiter?)* ELSE (expresion delimiter?)* END +// conditional_expr := IF expression LCurlyBrace (expression delimiter)* RCurlyBrace (LCurlyBrace (expresion delimiter)* RCurlyBrace)? // op := '+', '-', etc. // @@ -271,8 +273,9 @@ impl Parser { fn declaration(&mut self) -> ParseResult { expect!(self, Keyword(Kw::Fn)); let prototype = try!(self.prototype()); + expect!(self, LCurlyBrace); let body = try!(self.body()); - expect!(self, Keyword(Kw::End)); + expect!(self, RCurlyBrace); Ok(Statement::FuncDefNode(Function { prototype: prototype, body: body, @@ -323,7 +326,7 @@ impl Parser { let statements = delimiter_block!( self, statement, - Some(Keyword(Kw::End)) + Some(RCurlyBrace) ); Ok(statements) } @@ -390,12 +393,13 @@ impl Parser { use self::Expression::*; expect!(self, Keyword(Kw::While)); let test = try!(self.expression()); + expect!(self, LCurlyBrace); let body = delimiter_block!( self, expression, - Some(Keyword(Kw::End)) + Some(RCurlyBrace) ); - expect!(self, Keyword(Kw::End)); + expect!(self, RCurlyBrace); Ok(While(Box::new(test), body)) } @@ -412,24 +416,35 @@ impl Parser { _ => break, } } - expect!(self, Keyword(Kw::Then)); + expect!(self, LCurlyBrace); + loop { + match self.peek() { + Some(ref t) if is_delimiter(t) => { + self.next(); + continue; + } + _ => break, + } + } let then_block = delimiter_block!( self, expression, - Some(Keyword(Kw::Else)) | Some(Keyword(Kw::End)) + Some(RCurlyBrace) ); + expect!(self, RCurlyBrace); let else_block = if let Some(Keyword(Kw::Else)) = self.peek() { self.next(); + expect!(self, LCurlyBrace); let else_exprs = delimiter_block!( self, expression, - Some(Keyword(Kw::End)) + Some(RCurlyBrace) ); Some(else_exprs) } else { None }; - expect!(self, Keyword(Kw::End)); + expect!(self, RCurlyBrace); Ok(Conditional(Box::new(test), Box::new(Block(VecDeque::from(then_block))), else_block.map(|list| Box::new(Block(VecDeque::from(list)))))) @@ -491,14 +506,14 @@ mod tests { fn call_parse_test() { use super::Function; parsetest!( - "fn a() 1 + 2 end", + "fn a() { 1 + 2 }", &[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], match &body[..] { &[ExprNode(BinExp(_, box Number(1.0), box Number(2.0)))] => true, _ => false } && **name == "a" && match ¶meters[..] { &[] => true, _ => false } ); parsetest!( - "fn a(x,y) 1 + 2 end", + "fn a(x,y){ 1 + 2 }", &[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], match &body[..] { &[ExprNode(BinExp(_, box Number(1.0), box Number(2.0)))] => true, _ => false } && **name == "a" && *parameters[0] == "x" && *parameters[1] == "y" && parameters.len() == 2 @@ -525,18 +540,20 @@ mod tests { #[test] fn conditional_parse_test() { use tokenizer; - let t1 = "if null then 20 else 40 end"; + let t1 = "if null { 20 } else { 40 }"; let tokens = tokenizer::tokenize(t1).unwrap(); match parse(&tokens, &[]).unwrap()[..] { [ExprNode(Conditional(box Null, box Block(_), Some(box Block(_))))] => (), _ => panic!(), } - let t2 = "if null\nthen\n20\nelse\n40\nend"; + /* + let t2 = "if null\n{\n20\n}\nelse {\n40\n}"; let tokens2 = tokenizer::tokenize(t2).unwrap(); match parse(&tokens2, &[]).unwrap()[..] { [ExprNode(Conditional(box Null, box Block(_), Some(box Block(_))))] => (), _ => panic!(), } + */ } } diff --git a/test.schala b/test.schala index 2518992..cf46ccc 100644 --- a/test.schala +++ b/test.schala @@ -1,11 +1,11 @@ -fn a(x) -x + 20 -end +fn a(x) { + x + 20 +} -fn x(x) - x + a(9384) -end +fn x(x) { + x + a(9384) +} a(0) x(1)