Browse Source

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

match-statements
Garrit Franke 3 years 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") 1 => println("x is 1")
2 => println("x is 2") 2 => println("x is 2")
42 => println("The answer to the universe and everything!") 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. 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 += &format!("{}\n", &generate_statement(statement));
out_str += "break;"; out_str += "break;";
} }
MatchArm::Default(statement) => { MatchArm::Else(statement) => {
out_str += "default:\n"; out_str += "default:\n";
out_str += &format!("{}\n", &generate_statement(statement)); out_str += &format!("{}\n", &generate_statement(statement));
} }

2
src/lexer/mod.rs

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

2
src/parser/node_type.rs

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

18
src/parser/rules.rs

@ -465,22 +465,22 @@ impl Parser {
self.match_token(TokenKind::CurlyBracesOpen)?; self.match_token(TokenKind::CurlyBracesOpen)?;
let mut arms: Vec<MatchArm> = Vec::new(); let mut arms: Vec<MatchArm> = Vec::new();
// Used to mitigate multiple default cases were defined // Used to mitigate multiple else cases were defined
let mut has_default = false; let mut has_else = false;
loop { loop {
let next = self.peek()?; let next = self.peek()?;
match next.kind { match next.kind {
TokenKind::Literal(_) TokenKind::Literal(_)
| TokenKind::Identifier(_) | TokenKind::Identifier(_)
| TokenKind::Keyword(Keyword::Boolean) => arms.push(self.parse_match_arm()?), | TokenKind::Keyword(Keyword::Boolean) => arms.push(self.parse_match_arm()?),
TokenKind::Keyword(Keyword::Default) => { TokenKind::Keyword(Keyword::Else) => {
if has_default { if has_else {
return Err(self.make_error_msg( return Err(self.make_error_msg(
next.pos, 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()?); arms.push(self.parse_match_arm()?);
} }
TokenKind::CurlyBracesClose => break, TokenKind::CurlyBracesClose => break,
@ -495,10 +495,10 @@ impl Parser {
let next = self.peek()?; let next = self.peek()?;
match next.kind { match next.kind {
TokenKind::Keyword(Keyword::Default) => { TokenKind::Keyword(Keyword::Else) => {
self.match_keyword(Keyword::Default)?; self.match_keyword(Keyword::Else)?;
self.match_token(TokenKind::ArrowRight)?; self.match_token(TokenKind::ArrowRight)?;
Ok(MatchArm::Default(self.parse_statement()?)) Ok(MatchArm::Else(self.parse_statement()?))
} }
_ => { _ => {
let expr = self.parse_expression()?; 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") println("x is 2, in case you are wondering")
} }
42 => println("The answer to the universe and everything!") 42 => println("The answer to the universe and everything!")
default => println("Default case") else => println("Default case")
} }
} }

Loading…
Cancel
Save