From 914f853e1e22e2c7060d01ea3b7f8a4fd23428d7 Mon Sep 17 00:00:00 2001 From: Garrit Franke Date: Sun, 21 Feb 2021 18:06:32 +0100 Subject: [PATCH] feat: default arm for match --- src/generator/js.rs | 16 ++++++++++++---- src/parser/node_type.rs | 8 ++++++-- src/parser/rules.rs | 19 +++++++++++++++---- tests/match_statements.sb | 2 +- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/generator/js.rs b/src/generator/js.rs index c5badd8..d8dbd55 100644 --- a/src/generator/js.rs +++ b/src/generator/js.rs @@ -168,10 +168,18 @@ fn generate_continue() -> String { 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;"; + for arm in arms { + match arm { + MatchArm::Case(expr, statement) => { + out_str += &format!("case {}:\n", generate_expression(expr)); + out_str += &format!("{}\n", &generate_statement(statement)); + out_str += "break;"; + } + MatchArm::Default(statement) => { + out_str += "default:\n"; + out_str += &format!("{}\n", &generate_statement(statement)); + } + } } out_str += "}"; diff --git a/src/parser/node_type.rs b/src/parser/node_type.rs index e680e13..9d80332 100644 --- a/src/parser/node_type.rs +++ b/src/parser/node_type.rs @@ -20,8 +20,6 @@ use std::collections::HashMap; /// Table that contains all symbol and its types pub type SymbolTable = HashMap>; -pub type MatchArm = (Expression, Statement); - #[derive(Debug)] pub struct Program { pub func: Vec, @@ -144,6 +142,12 @@ impl TryFrom for Expression { } } +#[derive(Debug, Eq, PartialEq, Clone)] +pub enum MatchArm { + Case(Expression, Statement), + Default(Statement) +} + #[derive(Debug, Eq, PartialEq, Clone)] pub enum BinOp { Addition, diff --git a/src/parser/rules.rs b/src/parser/rules.rs index fe296e9..5f54263 100644 --- a/src/parser/rules.rs +++ b/src/parser/rules.rs @@ -492,11 +492,22 @@ impl Parser { } fn parse_match_arm(&mut self) -> Result { - let expr = self.parse_expression()?; - self.match_token(TokenKind::ArrowRight)?; - let statement = self.parse_statement()?; + let next = self.peek()?; - Ok((expr, statement)) + match next.kind { + TokenKind::Keyword(Keyword::Default) => { + self.match_keyword(Keyword::Default)?; + self.match_token(TokenKind::ArrowRight)?; + return Ok(MatchArm::Default(self.parse_statement()?)); + } + _ => { + let expr = self.parse_expression()?; + self.match_token(TokenKind::ArrowRight)?; + let statement = self.parse_statement()?; + + Ok(MatchArm::Case(expr, statement)) + } + } } fn parse_conditional_statement(&mut self) -> Result { diff --git a/tests/match_statements.sb b/tests/match_statements.sb index 70e559b..bfc9ba2 100644 --- a/tests/match_statements.sb +++ b/tests/match_statements.sb @@ -26,7 +26,7 @@ fn test_match_with_block_statement() { println("x is 2, in case you are wondering") } 42 => println("The answer to the universe and everything!") - // default => println("Default case") + default => println("Default case") } }