aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody <cody@codyq.dev>2023-02-27 12:14:16 -0600
committerCody <cody@codyq.dev>2023-02-27 12:14:16 -0600
commite4199d2837d2179f17e97b8d50366d96c8babded (patch)
treee07543001ba1aa7e05ff8b289b4d3154d7123fd6
parentf464fe944808df7865262962b8231c0009874692 (diff)
downloadsloth-e4199d2837d2179f17e97b8d50366d96c8babded.tar.gz
Added while loops & guessing game
-rw-r--r--examples/guessing.sloth26
-rw-r--r--examples/test.sloth16
-rw-r--r--src/ast/mod.rs4
-rw-r--r--src/ast/parser.rs11
-rw-r--r--src/interpreter.rs5
-rw-r--r--src/lexer.rs2
6 files changed, 48 insertions, 16 deletions
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<Stmt>,
},
+ While {
+ condition: Expr,
+ body: Vec<Stmt>,
+ },
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<Value> 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),
}
}