Implement if else

This commit is contained in:
Daniel M 2022-01-28 19:47:07 +01:00
parent 24f5aa30ea
commit d035724d20
4 changed files with 59 additions and 5 deletions

View File

@ -18,9 +18,9 @@
- [x] Declaration
- [x] Assignment
- [x] While loop `while X { ... }`
- [ ] If else statement `if X { ... } else { ... }`
- [ ] If Statement
- [ ] Else statement
- [x] If else statement `if X { ... } else { ... }`
- [x] If Statement
- [x] Else statement
- [ ] Line comments `//`
- [ ] Strings
- [ ] IO Intrinsics

View File

@ -28,7 +28,7 @@ impl Interpreter {
Stmt::Let(name, rhs) => {
let result = self.resolve_expr(rhs);
self.vartable.insert(name, result);
},
}
Stmt::While(condition, body) => {
loop {
// Check condition
@ -41,6 +41,13 @@ impl Interpreter {
self.run(body.clone());
}
}
Stmt::If(condition, body_if, body_else) => {
if matches!(self.resolve_expr(condition), Value::I64(0)) {
self.run(body_else);
} else {
self.run(body_if);
}
}
}
}
}

View File

@ -28,6 +28,12 @@ pub enum Token {
/// While (while)
While,
/// If (if)
If,
/// Else (else)
Else,
/// Assignment (single equal) (=)
Assign,
@ -184,6 +190,8 @@ impl<'a> Lexer<'a> {
"false" => tokens.push(Token::I64(0)),
"let" => tokens.push(Token::Let),
"while" => tokens.push(Token::While),
"if" => tokens.push(Token::If),
"else" => tokens.push(Token::Else),
_ => tokens.push(Token::Ident(ident)),
}
}

View File

@ -74,6 +74,7 @@ pub enum Stmt {
Expr(Expr),
Let(String, Expr),
While(Expr, Ast),
If(Expr, Ast, Ast),
}
#[derive(Debug, PartialEq, Eq, Clone)]
@ -106,7 +107,8 @@ expr = expr_bor
stmt_expr = expr
stmt_let = "let" IDENT "=" expr
stmt_while = "while" expr "{" (stmt)* "}"
stmt = stmt_expr | stmt_let | stmt_while
stmt_if = "if" expr "{" (stmt)* "}" ( "else" "{" (stmt)* "}" )
stmt = stmt_expr | stmt_let | stmt_while | stmt_if
*/
struct Parser<T: Iterator<Item = Token>> {
@ -133,6 +135,7 @@ impl<T: Iterator<Item = Token>> Parser<T> {
Token::RBrace => break,
Token::Let => self.parse_let_stmt(),
Token::While => self.parse_while(),
Token::If => self.parse_if(),
// By default try to parse an expression
_ => Stmt::Expr(self.parse_expr()),
};
@ -143,6 +146,42 @@ impl<T: Iterator<Item = Token>> Parser<T> {
Ast { prog }
}
fn parse_if(&mut self) -> Stmt {
if !matches!(self.next(), Token::If) {
panic!("Error parsing if: Expected if token");
}
let condition = self.parse_expr();
if !matches!(self.next(), Token::LBrace) {
panic!("Error parsing if: Expected '{{' token");
}
let body_if = self.parse();
if !matches!(self.next(), Token::RBrace) {
panic!("Error parsing if: Expected '}}' token");
}
let mut body_else = Ast { prog: Vec::new() };
if matches!(self.peek(), Token::Else) {
self.next();
if !matches!(self.next(), Token::LBrace) {
panic!("Error parsing else: Expected '{{' token");
}
body_else = self.parse();
if !matches!(self.next(), Token::RBrace) {
panic!("Error parsing else: Expected '}}' token");
}
}
Stmt::If(condition, body_if, body_else)
}
fn parse_while(&mut self) -> Stmt {
if !matches!(self.next(), Token::While) {
panic!("Error parsing while: Expected while token");