From e4199d2837d2179f17e97b8d50366d96c8babded Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 27 Feb 2023 12:14:16 -0600 Subject: Added while loops & guessing game --- examples/guessing.sloth | 26 ++++++++++++++++++++++++++ examples/test.sloth | 16 ---------------- src/ast/mod.rs | 4 ++++ src/ast/parser.rs | 11 +++++++++++ src/interpreter.rs | 5 +++++ src/lexer.rs | 2 ++ 6 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 examples/guessing.sloth delete mode 100644 examples/test.sloth diff --git a/examples/guessing.sloth b/examples/guessing.sloth new file mode 100644 index 0000000..5d69944 --- /dev/null +++ b/examples/guessing.sloth @@ -0,0 +1,26 @@ +val computer = random(1, 10); + +var tries = 0; +var correct = false; + +while !correct { + print("\nPick a number between 1 and 5: "); + val human = parse_int(readln()); + + if human == computer { + println("You guessed the same number as me!"); + correct = true; + } + + if human > computer { + println("Your guess was too high."); + } + + if human < computer { + println("Your guess was too low."); + } + + tries = tries + 1; +} + +println("\nIt took you ", tries, " tries to guess correctly!"); diff --git a/examples/test.sloth b/examples/test.sloth deleted file mode 100644 index 7104593..0000000 --- a/examples/test.sloth +++ /dev/null @@ -1,16 +0,0 @@ -print("Pick a number between 1 and 5: "); - -val human = parse_int(readln()); -val computer = random(1, 5); - -if human == computer { - println("You guessed the same number as me!"); -} - -if human > computer { - println("Your guess was too high."); -} - -if human < computer { - println("Your guess was too low."); -} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index d006737..4e1d639 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -36,6 +36,10 @@ pub enum Stmt { range: (Expr, Expr), body: Vec, }, + While { + condition: Expr, + body: Vec, + }, Return { value: Expr, }, diff --git a/src/ast/parser.rs b/src/ast/parser.rs index 842ad09..bc29f94 100644 --- a/src/ast/parser.rs +++ b/src/ast/parser.rs @@ -118,6 +118,10 @@ impl<'a> AstParser<'a> { return self.for_statement(); } + if self.advance_if_eq(&TokenType::While) { + return self.while_statement(); + } + // If we couldn't parse a statement return an expression statement self.expression_statement() } @@ -186,6 +190,13 @@ impl<'a> AstParser<'a> { } } + fn while_statement(&mut self) -> Stmt { + let condition = self.expression(); + let body = self.block(); + + Stmt::While { condition, body } + } + fn expression_statement(&mut self) -> Stmt { let expr = self.expression(); diff --git a/src/interpreter.rs b/src/interpreter.rs index b548d9e..adf6755 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -69,6 +69,11 @@ impl AstVisitor for AstInterpreter { self.memory.remove(binding); } + Stmt::While { condition, body } => { + while self.visit_expr(condition) == Value::Bool(true) { + self.interpret(body); + } + } Stmt::Return { value } => todo!(), }; diff --git a/src/lexer.rs b/src/lexer.rs index 2d65afc..01d1ab6 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -283,6 +283,8 @@ impl<'a> Iterator for Lexer<'a> { "loop" => TokenType::Loop, "break" => TokenType::Break, "continue" => TokenType::Continue, + "true" => TokenType::Literal(Literal::Bool(true)), + "false" => TokenType::Literal(Literal::Bool(false)), _ => TokenType::Identifier(value), } } -- cgit v1.2.3