diff --git a/build.zig b/build.zig index 5055642..0cb19e4 100644 --- a/build.zig +++ b/build.zig @@ -22,6 +22,13 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); + // Declare an option to build the program with debug statements + const executionTracing = b.option(bool, "tracing", "enable execution tracing") orelse false; + const options = b.addOptions(); + options.addOption(bool, "tracing", executionTracing); + + exe.root_module.addOptions("config", options); + // // Error handling module // diff --git a/src/errors/root.zig b/src/errors/root.zig index 15e2a6b..8191a29 100644 --- a/src/errors/root.zig +++ b/src/errors/root.zig @@ -1,5 +1,7 @@ const std = @import("std"); +/// Holds information about errors generated during the compilation, +/// and pretty prints them. pub const ErrorData = struct { reason: []const u8, start_position: usize, diff --git a/src/main.zig b/src/main.zig index db496db..58868be 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,9 @@ const std = @import("std"); const lexic = @import("lexic"); const syntax = @import("syntax"); +const errors = @import("errors"); + +const tracing = @import("config").tracing; const thp_version: []const u8 = "0.0.1"; @@ -12,27 +15,65 @@ fn repl() !void { const stdout_file = std.io.getStdOut().writer(); var bw = std.io.bufferedWriter(stdout_file); const stdout = bw.writer(); + + if (tracing) { + try stdout.print("\n|\n| DEBUG MODE\n|\n\n", .{}); + try bw.flush(); + } + try stdout.print("The THP REPL, v{s}\n", .{thp_version}); try stdout.print("Enter expressions to evaluate. Enter CTRL-D to exit.\n", .{}); try bw.flush(); - const stdin = std.io.getStdIn().reader(); - - try stdout.print("\nthp => ", .{}); - try bw.flush(); - - const bare_line = try stdin.readUntilDelimiterAlloc(std.heap.page_allocator, '\n', 8192); - defer std.heap.page_allocator.free(bare_line); - const line = std.mem.trim(u8, bare_line, "\r"); - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const alloc = gpa.allocator(); + const stdin = std.io.getStdIn().reader(); - const tokens = try lexic.tokenize(line, alloc); - defer tokens.deinit(); + var running = true; + while (running) { + // + // Print prompt + // + try stdout.print("\nthp => ", .{}); + try bw.flush(); - var module_ast: syntax.Module = undefined; - try module_ast.init(&tokens, 0, alloc); + // + // Read stdin + // + const bare_line = try stdin.readUntilDelimiterAlloc(std.heap.page_allocator, '\n', 8192); + defer std.heap.page_allocator.free(bare_line); + const line = std.mem.trim(u8, bare_line, "\r"); + + // + // Tokenize + // + const tokens = try lexic.tokenize(line, alloc); + defer tokens.deinit(); + + // Trace tokens + if (tracing) { + for (tokens.items) |token| { + trace_header(); + std.debug.print( + "token: `{s}`, type: `{s}`, start: `{d}` \n", + .{ token.value, @tagName(token.token_type), token.start_pos }, + ); + } + } + + running = false; + } + + // var module_ast: syntax.Module = undefined; + // const parsing_error = try alloc.create(errors.ErrorData); + // defer parsing_error.deinit(); + // defer alloc.destroy(parsing_error); + // + // try module_ast.init(&tokens, 0, alloc, parsing_error); try bw.flush(); } + +inline fn trace_header() void { + std.debug.print(" |TRACE> ", .{}); +}