Browse Source

feat: use "else" keyword instead of "default"

match-statements
Garrit Franke 9 months ago
parent
commit
9097f4c762
  1. 4
      docs/concepts/control-flow.md
  2. 2
      src/generator/js.rs
  3. 2
      src/lexer/mod.rs
  4. 2
      src/parser/node_type.rs
  5. 18
      src/parser/rules.rs
  6. 2
      tests/match_statements.sb

4
docs/concepts/control-flow.md

@ -86,11 +86,11 @@ Working with `if` statements with multiple `else` branches can become tedious. `
1 => println("x is 1")
2 => println("x is 2")
42 => println("The answer to the universe and everything!")
default => println("This will not be called")
else => println("This will not be called")
}
```
In this example, we check the value of `x`, and execute some code based on the value. Instead of having to type `x == 1`, `x == 2` and so on, we instead provide the value only once, and decide what to do for each case. We can optionally provide a `default` case, which will be executed if no other case was triggered.
In this example, we check the value of `x`, and execute some code based on the value. Instead of having to type `x == 1`, `x == 2` and so on, we instead provide the value only once, and decide what to do for each case. We can optionally provide a `else` case, which will be executed if no other case was triggered.
You can execute multiple statements inside a single case. A common case would be to log some debug output and then return a value.

2
src/generator/js.rs

@ -175,7 +175,7 @@ fn generate_match(subject: Expression, arms: Vec<MatchArm>) -> String {
out_str += &format!("{}\n", &generate_statement(statement));
out_str += "break;";
}
MatchArm::Default(statement) => {
MatchArm::Else(statement) => {
out_str += "default:\n";
out_str += &format!("{}\n", &generate_statement(statement));
}

2
src/lexer/mod.rs

@ -148,7 +148,6 @@ pub enum Keyword {
Struct,
New,
Match,
Default,
Unknown,
}
@ -377,7 +376,6 @@ impl Cursor<'_> {
c if c == "struct" => Keyword::Struct,
c if c == "new" => Keyword::New,
c if c == "match" => Keyword::Match,
c if c == "default" => Keyword::Default,
_ => Keyword::Unknown,
}
}

2
src/parser/node_type.rs

@ -145,7 +145,7 @@ impl TryFrom<Token> for Expression {
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum MatchArm {
Case(Expression, Statement),
Default(Statement),
Else(Statement),
}
#[derive(Debug, Eq, PartialEq, Clone)]

18
src/parser/rules.rs

@ -465,22 +465,22 @@ impl Parser {
self.match_token(TokenKind::CurlyBracesOpen)?;
let mut arms: Vec<MatchArm> = Vec::new();
// Used to mitigate multiple default cases were defined
let mut has_default = false;
// Used to mitigate multiple else cases were defined
let mut has_else = false;
loop {
let next = self.peek()?;
match next.kind {
TokenKind::Literal(_)
| TokenKind::Identifier(_)
| TokenKind::Keyword(Keyword::Boolean) => arms.push(self.parse_match_arm()?),
TokenKind::Keyword(Keyword::Default) => {
if has_default {
TokenKind::Keyword(Keyword::Else) => {
if has_else {
return Err(self.make_error_msg(
next.pos,
"Multiple defaults are not allowed".to_string(),
"Multiple else arms are not allowed".to_string(),
));
}
has_default = true;
has_else = true;
arms.push(self.parse_match_arm()?);
}
TokenKind::CurlyBracesClose => break,
@ -495,10 +495,10 @@ impl Parser {
let next = self.peek()?;
match next.kind {
TokenKind::Keyword(Keyword::Default) => {
self.match_keyword(Keyword::Default)?;
TokenKind::Keyword(Keyword::Else) => {
self.match_keyword(Keyword::Else)?;
self.match_token(TokenKind::ArrowRight)?;
Ok(MatchArm::Default(self.parse_statement()?))
Ok(MatchArm::Else(self.parse_statement()?))
}
_ => {
let expr = self.parse_expression()?;

2
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")
else => println("Default case")
}
}

Loading…
Cancel
Save