From d035724d207360babc8a5c3939f33ae84d4d67eb Mon Sep 17 00:00:00 2001 From: Daniel M Date: Fri, 28 Jan 2022 19:47:07 +0100 Subject: [PATCH] Implement if else --- README.md | 6 +++--- src/interpreter.rs | 9 ++++++++- src/lexer.rs | 8 ++++++++ src/parser.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fbc53e7..2959e1f 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/interpreter.rs b/src/interpreter.rs index d426f7a..aa946b5 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -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); + } + } } } } diff --git a/src/lexer.rs b/src/lexer.rs index 90d7a10..fb3194a 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -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)), } } diff --git a/src/parser.rs b/src/parser.rs index 020f60d..fc8a297 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -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> { @@ -133,6 +135,7 @@ impl> Parser { 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> Parser { 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");