From bdec0b2fc64084a0aa97ee3aa037a33c1af450e8 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Sun, 21 Feb 2021 17:24:15 +0100 Subject: [PATCH] feat: js generation for match statements --- src/generator/js.rs | 15 ++++++++++++++- src/parser/rules.rs | 9 ++++----- tests/match_statements.sb | 10 ++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/generator/js.rs b/src/generator/js.rs index d777344..c5badd8 100644 --- a/src/generator/js.rs +++ b/src/generator/js.rs @@ -103,7 +103,7 @@ fn generate_statement(statement: Statement) -> String { Statement::For(ident, expr, body) => generate_for_loop(ident, expr, *body), Statement::Continue => generate_continue(), Statement::Break => generate_break(), - Statement::Match(_, _) => todo!(), + Statement::Match(subject, arms) => generate_match(subject, arms), }; format!("{};\n", state) @@ -166,6 +166,19 @@ fn generate_continue() -> String { "continue;\n".into() } +fn generate_match(subject: Expression, arms: Vec) -> String { + let mut out_str = format!("switch ({E}) {{\n", E = generate_expression(subject)); + for (case, statement) in arms { + out_str += &format!("case {}:\n", generate_expression(case)); + out_str += &format!("{}\n", &generate_statement(statement)); + out_str += "break;"; + } + + out_str += "}"; + + out_str +} + fn generate_array(elements: Vec) -> String { let mut out_str = String::from("["); diff --git a/src/parser/rules.rs b/src/parser/rules.rs index 3086931..a739ebb 100644 --- a/src/parser/rules.rs +++ b/src/parser/rules.rs @@ -469,9 +469,9 @@ impl Parser { loop { let next = self.peek()?; match next.kind { - TokenKind::Literal(_) | TokenKind::Identifier(_) => { - arms.push(self.parse_match_arm()?) - } + TokenKind::Literal(_) + | TokenKind::Identifier(_) + | TokenKind::Keyword(Keyword::Boolean) => arms.push(self.parse_match_arm()?), TokenKind::Keyword(Keyword::Default) => { if has_default { return Err(self.make_error_msg( @@ -483,7 +483,7 @@ impl Parser { arms.push(self.parse_match_arm()?); } TokenKind::CurlyBracesClose => break, - _ => return Err(self.make_error_msg(next.pos, "Illegal token".to_string())) + _ => return Err(self.make_error_msg(next.pos, "Illegal token".to_string())), } } self.match_token(TokenKind::CurlyBracesClose)?; @@ -496,7 +496,6 @@ impl Parser { let statement = self.parse_statement()?; Ok((expr, statement)) - } fn parse_conditional_statement(&mut self) -> Result { diff --git a/tests/match_statements.sb b/tests/match_statements.sb index 1bcb7e4..0ce62f2 100644 --- a/tests/match_statements.sb +++ b/tests/match_statements.sb @@ -1,4 +1,13 @@ fn test_basic_match() { + let x = 1 + + match x { + 1 => assert(true) + 2 => assert(false) + } +} + +fn test_boolean_match() { let x = true match x { @@ -9,4 +18,5 @@ fn test_basic_match() { fn main() { test_basic_match() + test_boolean_match() }