From 7d8883ed633ee8c8bbc42871226ae6b73edcfc6d Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Mon, 7 Dec 2020 12:38:49 +0100 Subject: [PATCH] Allow multiple statements in if conditional --- src/generator/js.rs | 9 +++++---- src/parser/mod.rs | 11 +++++++++-- src/parser/node_type.rs | 2 +- src/parser/tests.rs | 29 +++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/generator/js.rs b/src/generator/js.rs index 27af2a5..927f910 100644 --- a/src/generator/js.rs +++ b/src/generator/js.rs @@ -44,7 +44,7 @@ fn generate_statement(statement: Statement) -> String { Statement::Declare(_, _) => todo!(), Statement::Exp(val) => generate_expression(val), Statement::If(expr, if_state, else_state) => { - generate_conditional(expr, *if_state, else_state.map(|x| *x)) + generate_conditional(expr, if_state, else_state.map(|x| *x)) } Statement::While(_, _) => todo!(), } @@ -63,16 +63,17 @@ fn generate_expression(expr: Expression) -> String { fn generate_conditional( expr: Expression, - if_state: Statement, + if_state: Vec, else_state: Option, ) -> String { let expr_str = generate_expression(expr); - let if_str = generate_statement(if_state); let mut outcome = format!("if ({})", expr_str); outcome += "{\n"; - outcome += &if_str; + for statement in if_state { + outcome += &generate_statement(statement); + } outcome += "}"; outcome } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 0989c9c..a0991a6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -307,10 +307,17 @@ impl Parser { self.match_keyword(Keyword::If)?; let condition = self.parse_expression()?; self.match_token(TokenKind::CurlyBracesOpen)?; - let state = self.parse_statement()?; + + let mut statements = Vec::new(); + while let Err(_) = self.peek_token(TokenKind::CurlyBracesClose) { + let statement = self.parse_statement()?; + dbg!("{:?}", &statement); + statements.push(statement); + } + self.match_token(TokenKind::CurlyBracesClose)?; - Ok(Statement::If(condition, Box::new(state), None)) + Ok(Statement::If(condition, statements, None)) } /// In some occurences a complex expression has been evaluated before a binary operation is encountered. diff --git a/src/parser/node_type.rs b/src/parser/node_type.rs index c1896e3..b8a999d 100644 --- a/src/parser/node_type.rs +++ b/src/parser/node_type.rs @@ -23,7 +23,7 @@ pub struct Variable { pub enum Statement { Declare(Variable, Option), Return(Option), - If(Expression, Box, Option>), + If(Expression, Vec, Option>), While(Expression, Box), Exp(Expression), } diff --git a/src/parser/tests.rs b/src/parser/tests.rs index 157e3d5..7752b61 100644 --- a/src/parser/tests.rs +++ b/src/parser/tests.rs @@ -234,3 +234,32 @@ fn test_parse_compound_ops_return() { let tree = parse(tokens, Some(raw.to_string())); assert!(tree.is_ok()) } + +#[test] +fn test_parse_basic_conditional() { + let raw = " + main :: (n) { + if n { + return n + } + } + "; + let tokens = tokenize(raw); + let tree = parse(tokens, Some(raw.to_string())); + assert!(tree.is_ok()) +} + +#[test] +fn test_parse_basic_conditional_with_multiple_statements() { + let raw = " + main :: (n) { + if n { + let x = 2 * n + return x + } + } + "; + let tokens = tokenize(raw); + let tree = parse(tokens, Some(raw.to_string())); + assert!(tree.is_ok()) +}