Browse Source

feat: js generation for match statements

match-statements
Garrit Franke 3 years ago
parent
commit
bdec0b2fc6
  1. 15
      src/generator/js.rs
  2. 9
      src/parser/rules.rs
  3. 10
      tests/match_statements.sb

15
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<MatchArm>) -> 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<Expression>) -> String {
let mut out_str = String::from("[");

9
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<Statement, String> {

10
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()
}

Loading…
Cancel
Save