]> Repositories - zlox.git/blob - lox.zig
ec4478bce4aa8e614b020308006ef128d46f51ae
[zlox.git] / lox.zig
1 const std = @import("std");
2 const Allocator = std.mem.Allocator;
3 const Scanner = @import("Scanner.zig");
4
5 var hadError = false;
6
7 pub fn main() !u8 {
8     var gpa: std.heap.DebugAllocator(.{}) = .init;
9     defer _ = gpa.deinit();
10     const allocator = gpa.allocator();
11     const args = try std.process.argsAlloc(allocator);
12     defer std.process.argsFree(allocator, args);
13
14     if (args.len > 2) {
15         var stdout_writer = std.fs.File.stdout().writer(&.{});
16         const stdout = &stdout_writer.interface;
17         try stdout.writeAll("Usage: zlox [script]\n");
18         return 64;
19     } else if (args.len == 2) {
20         return runFile(allocator, args[1]);
21     } else {
22         try runPrompt(allocator);
23     }
24
25     return 0;
26 }
27
28 fn runFile(allocator: Allocator, path: []const u8) !u8 {
29     const bytes = try std.fs.cwd().readFileAlloc(allocator, path, std.math.maxInt(usize));
30     defer allocator.free(bytes);
31     try run(allocator, bytes);
32
33     // Indicate an error in the exit code.
34     if (hadError) return 65;
35
36     return 0;
37 }
38
39 fn runPrompt(allocator: Allocator) !void {
40     var stdin_buffer: [1024]u8 = undefined;
41     var stdin_reader = std.fs.File.stdin().reader(&stdin_buffer);
42     const stdin = &stdin_reader.interface;
43     var stdout_writer = std.fs.File.stdout().writer(&.{});
44     const stdout = &stdout_writer.interface;
45
46     while (true) {
47         try stdout.writeAll("> ");
48         const line = try stdin.takeDelimiter('\n');
49         if (line == null) break;
50         try run(allocator, line.?);
51         hadError = false;
52     }
53 }
54
55 fn run(allocator: Allocator, source: []const u8) !void {
56     var scanner = Scanner.init(source);
57     const tokens = try scanner.scanTokens(allocator);
58     defer allocator.free(tokens);
59
60     // For now, just print the tokens.
61     for (tokens) |token| {
62         std.debug.print("{f}\n", .{token});
63     }
64 }
65
66 pub fn @"error"(line: u32, message: []const u8) !void {
67     try report(line, "", message);
68 }
69
70 var stderr_buffer: [1024]u8 = undefined;
71 var stderr_writer = std.fs.File.stderr().writer(&stderr_buffer);
72 const stderr = &stderr_writer.interface;
73
74 fn report(line: u32, where: []const u8, message: []const u8) !void {
75     try stderr.print("[line {}] Error{s}: {s}\n", .{ line, where, message });
76     try stderr.flush();
77     hadError = true;
78 }