summary refs log tree commit diff
path: root/src/evaluator.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/evaluator.zig')
-rw-r--r--src/evaluator.zig21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/evaluator.zig b/src/evaluator.zig
index c1997f3..9e89fc4 100644
--- a/src/evaluator.zig
+++ b/src/evaluator.zig
@@ -62,6 +62,9 @@ pub const Evaluator = struct {
             .IF_STATEMENT => |*if_statement| {
                 return try self.evaluate_if_statement(@ptrCast(if_statement));
             },
+            .WHILE_STATEMENT => |*while_statement| {
+                return try self.evaluate_while_statement(@ptrCast(while_statement));
+            },
             .RETURN_STATEMENT => |*return_statement| return try self.evaluate_return_statement(@ptrCast(return_statement)),
             else => unreachable,
         }
@@ -124,6 +127,24 @@ pub const Evaluator = struct {
         return null;
     }
 
+    fn evaluate_while_statement(self: *Evaluator, node: *parser.Node) !?*Variable {
+        errdefer std.debug.print("Error evaluating while statement\n", .{});
+        std.debug.assert(node.* == parser.Node.WHILE_STATEMENT);
+
+        const while_statement = node.WHILE_STATEMENT;
+
+        while (true) {
+            const while_condition_val = try self.get_expression_value(while_statement.condition);
+            std.debug.assert(while_condition_val.?.* == .BOOLEAN);
+
+            if (!while_condition_val.?.BOOLEAN) return null;
+
+            if (try self.evaluate_block_statements(while_statement.statements)) |ret| return ret;
+        }
+
+        return null;
+    }
+
     fn evaluate_return_statement(self: *Evaluator, return_statement: *parser.Node) !*Variable {
         errdefer std.debug.print("Error evaluating return statement\n", .{});
         std.debug.assert(return_statement.* == parser.Node.RETURN_STATEMENT);