const Scanner = @import("Scanner.zig");
const Token = @import("Token.zig");
const Parser = @import("Parser.zig");
-const ast_printer = @import("ast_printer.zig");
+const Interpreter = @import("Interpreter.zig");
+const ErrorPayload = Interpreter.ErrorPayload;
+var interpreter: Interpreter = undefined;
var hadError = false;
+var hadRuntimeError = false;
pub fn main() !u8 {
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer _ = gpa.deinit();
const allocator = gpa.allocator();
+
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
+ var stdout_buffer: [1024]u8 = undefined;
+ var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer);
+ const stdout = &stdout_writer.interface;
+ interpreter = Interpreter.init(allocator, stdout);
+ defer interpreter.deinit();
+
if (args.len > 2) {
- var stdout_writer = std.fs.File.stdout().writer(&.{});
- const stdout = &stdout_writer.interface;
try stdout.writeAll("Usage: zlox [script]\n");
+ try stdout.flush();
return 64;
} else if (args.len == 2) {
return runFile(allocator, args[1]);
} else {
- try runPrompt(allocator);
+ try runPrompt(allocator, stdout);
}
return 0;
// Indicate an error in the exit code.
if (hadError) return 65;
+ if (hadRuntimeError) return 70;
return 0;
}
-fn runPrompt(allocator: Allocator) !void {
+fn runPrompt(allocator: Allocator, stdout: *std.Io.Writer) !void {
var stdin_buffer: [1024]u8 = undefined;
var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer);
const stdin = &stdin_reader.interface;
- var stdout_writer = std.fs.File.stdout().writer(&.{});
- const stdout = &stdout_writer.interface;
while (true) {
try stdout.writeAll("> ");
+ try stdout.flush();
const line = try stdin.takeDelimiter('\n');
if (line == null) break;
try run(allocator, line.?);
// Stop if there was a syntax error.
if (hadError) return;
- const printed = try ast_printer.print(allocator, expression.?);
- defer allocator.free(printed);
- std.debug.print("{s}\n", .{printed});
+ try interpreter.interpret(expression.?);
+ try interpreter.stdout.flush();
}
pub fn scanError(line: u32, message: []const u8) !void {
try report(token.line, try std.fmt.allocPrint(allocator, " at '{s}'", .{token.lexeme}), message);
}
}
+
+pub fn runtimeError(err: ErrorPayload) !void {
+ try stderr.print("{s}\n[line {}]\n", .{ err.message, err.token.line });
+ try stderr.flush();
+ hadRuntimeError = true;
+}