]> Repositories - zlox.git/blobdiff - src/main.zig
Implement interpreter
[zlox.git] / src / main.zig
index a17dbd73fe1b6e874ef360d0b4795c5b1b1220a9..1f02d3e7f89026fd72a6534bdf48eed06b9c7bc2 100644 (file)
@@ -3,26 +3,35 @@ const Allocator = std.mem.Allocator;
 const Scanner = @import("Scanner.zig");
 const Token = @import("Token.zig");
 const Parser = @import("Parser.zig");
 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 hadError = false;
+var hadRuntimeError = false;
 
 pub fn main() !u8 {
     var gpa: std.heap.DebugAllocator(.{}) = .init;
     defer _ = gpa.deinit();
     const allocator = gpa.allocator();
 
 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);
 
     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) {
     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.writeAll("Usage: zlox [script]\n");
+        try stdout.flush();
         return 64;
     } else if (args.len == 2) {
         return runFile(allocator, args[1]);
     } else {
         return 64;
     } else if (args.len == 2) {
         return runFile(allocator, args[1]);
     } else {
-        try runPrompt(allocator);
+        try runPrompt(allocator, stdout);
     }
 
     return 0;
     }
 
     return 0;
@@ -35,19 +44,19 @@ fn runFile(allocator: Allocator, path: []const u8) !u8 {
 
     // Indicate an error in the exit code.
     if (hadError) return 65;
 
     // Indicate an error in the exit code.
     if (hadError) return 65;
+    if (hadRuntimeError) return 70;
 
     return 0;
 }
 
 
     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 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("> ");
 
     while (true) {
         try stdout.writeAll("> ");
+        try stdout.flush();
         const line = try stdin.takeDelimiter('\n');
         if (line == null) break;
         try run(allocator, line.?);
         const line = try stdin.takeDelimiter('\n');
         if (line == null) break;
         try run(allocator, line.?);
@@ -66,9 +75,8 @@ fn run(allocator: Allocator, source: []const u8) !void {
     // Stop if there was a syntax error.
     if (hadError) return;
 
     // 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 {
 }
 
 pub fn scanError(line: u32, message: []const u8) !void {
@@ -92,3 +100,9 @@ pub fn parseError(allocator: Allocator, token: Token, message: []const u8) !void
         try report(token.line, try std.fmt.allocPrint(allocator, " at '{s}'", .{token.lexeme}), message);
     }
 }
         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;
+}