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;
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();
- 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,
+ };
}
}
};
}
+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);