]> Repositories - zlox.git/blobdiff - src/Interpreter.zig
Implement print and expression statements
[zlox.git] / src / Interpreter.zig
index 0f8c224bf4b5be7e030414891e8fc906394d33ff..09d202a7076efb6172581e87d7360a395ccc058f 100644 (file)
@@ -2,6 +2,7 @@ const std = @import("std");
 const ArenaAllocator = std.heap.ArenaAllocator;
 const Allocator = std.mem.Allocator;
 const Interpreter = @This();
 const ArenaAllocator = std.heap.ArenaAllocator;
 const Allocator = std.mem.Allocator;
 const Interpreter = @This();
+const Stmt = @import("stmt.zig").Stmt;
 const Expr = @import("expr.zig").Expr;
 const Token = @import("Token.zig");
 const Literal = Token.Literal;
 const Expr = @import("expr.zig").Expr;
 const Token = @import("Token.zig");
 const Literal = Token.Literal;
@@ -25,16 +26,15 @@ pub fn deinit(self: *Interpreter) void {
     self.arena.deinit();
 }
 
     self.arena.deinit();
 }
 
-pub fn interpret(self: *Interpreter, expression: *const Expr) !void {
+pub fn interpret(self: *Interpreter, statements: []const *const Stmt) !void {
     self.allocator = self.arena.allocator();
 
     self.allocator = self.arena.allocator();
 
-    var err_payload: ErrorPayload = undefined;
-    if (self.evaluate(expression, &err_payload)) |value| {
-        const stringified = try self.stringify(value);
-        try self.stdout.print("{s}\n", .{stringified});
-    } else |err| switch (err) {
-        error.RuntimeError => try lox.runtimeError(err_payload),
-        else => return err,
+    for (statements) |statement| {
+        var err_payload: ErrorPayload = undefined;
+        self.execute(statement, &err_payload) catch |err| switch (err) {
+            error.RuntimeError => try lox.runtimeError(err_payload),
+            else => return err,
+        };
     }
 }
 
     }
 }
 
@@ -47,6 +47,22 @@ fn evaluate(self: *Interpreter, expr: *const Expr, err_payload: *ErrorPayload) (
     };
 }
 
     };
 }
 
+fn execute(self: *Interpreter, stmt: *const Stmt, err_payload: *ErrorPayload) !void {
+    try switch (stmt.*) {
+        .print => |print| self.visitPrintStmt(print, err_payload),
+        .expression => |expression| self.visitExpressionStmt(expression, err_payload),
+    };
+}
+
+fn visitExpressionStmt(self: *Interpreter, stmt: Stmt.Expression, err_payload: *ErrorPayload) !void {
+    _ = try self.evaluate(stmt.expression, err_payload);
+}
+
+fn visitPrintStmt(self: *Interpreter, stmt: Stmt.Print, err_payload: *ErrorPayload) !void {
+    const value = try self.evaluate(stmt.expression, err_payload);
+    try self.stdout.print("{s}\n", .{try self.stringify(value)});
+}
+
 fn visitBinaryExpr(self: *Interpreter, expr: Expr.Binary, err_payload: *ErrorPayload) !Literal {
     const left = try self.evaluate(expr.left, err_payload);
     const right = try self.evaluate(expr.right, err_payload);
 fn visitBinaryExpr(self: *Interpreter, expr: Expr.Binary, err_payload: *ErrorPayload) !Literal {
     const left = try self.evaluate(expr.left, err_payload);
     const right = try self.evaluate(expr.right, err_payload);