diff options
author | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-08 23:49:27 +0100 |
---|---|---|
committer | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-08 23:49:27 +0100 |
commit | dfa9ef4a951c4d498893a80728aa84734bf33775 (patch) | |
tree | 9adafce2199b1407f4a82e3a85b6270bb150cb43 /src | |
parent | Misc: Dont crash REPL if parsing fails (diff) | |
download | interpreter-dfa9ef4a951c4d498893a80728aa84734bf33775.tar.gz interpreter-dfa9ef4a951c4d498893a80728aa84734bf33775.tar.bz2 interpreter-dfa9ef4a951c4d498893a80728aa84734bf33775.zip |
Evaluator: Implement first version of evaluator that handles print statements
Diffstat (limited to 'src')
-rw-r--r-- | src/evaluator.zig | 62 | ||||
-rw-r--r-- | src/main.zig | 6 | ||||
-rw-r--r-- | src/parser.zig | 2 |
3 files changed, 69 insertions, 1 deletions
diff --git a/src/evaluator.zig b/src/evaluator.zig new file mode 100644 index 0000000..14f4049 --- /dev/null +++ b/src/evaluator.zig @@ -0,0 +1,62 @@ +const std = @import("std"); +const parser = @import("parser.zig"); + +pub const Evaluator = struct { + allocator: std.mem.Allocator, + + pub fn init(allocator: std.mem.Allocator) !*Evaluator { + const evaluator = try allocator.create(Evaluator); + evaluator.* = .{ + .allocator = allocator, + }; + return evaluator; + } + + pub fn deinit(self: *Evaluator) void { + self.allocator.destroy(self); + } + + pub fn evaluate_ast(self: *Evaluator, ast: *parser.Node) !i64 { + std.debug.assert(ast.* == parser.Node.PROGRAM); + + const program = ast.*.PROGRAM; + + for (program.statements) |statement| { + try self.evaluate_statement(statement); + } + + return 0; + } + + fn evaluate_statement(self: *Evaluator, statement: *parser.Node) !void { + std.debug.assert(statement.* == parser.Node.STATEMENT); + + return switch (statement.STATEMENT.statement.*) { + .VARIABLE_STATEMENT => |*variable_statement| try self.evaluate_variable_statement(@ptrCast(variable_statement)), + .PRINT_STATEMENT => |*print_statement| try self.evaluate_print_statement(@ptrCast(print_statement)), + else => unreachable, + }; + } + + fn evaluate_variable_statement(_: *Evaluator, variable_statement: *parser.Node) !void { + std.debug.assert(variable_statement.* == parser.Node.VARIABLE_STATEMENT); + @panic("evaluate_variable_statement unimplemented"); + } + + fn evaluate_print_statement(self: *Evaluator, print_statement: *parser.Node) !void { + std.debug.assert(print_statement.* == parser.Node.PRINT_STATEMENT); + + const print_value = try self.get_expression_value(print_statement.PRINT_STATEMENT.expression); + + std.debug.print("PRINT: {d}\n", .{print_value}); + } + + fn get_expression_value(_: *Evaluator, expression: *parser.Node) !i64 { + std.debug.assert(expression.* == parser.Node.EXPRESSION); + + return switch (expression.EXPRESSION) { + .NUMBER => |number| number.value, + .IDENTIFIER => @panic("printing identifiers not implemented"), + }; + } +}; diff --git a/src/main.zig b/src/main.zig index c8ebcfe..4a0f9ef 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,6 +1,7 @@ const std = @import("std"); const tokenizer = @import("tokenizer.zig"); const parser = @import("parser.zig"); +const evaluator = @import("evaluator.zig"); pub fn main() !void { const stdout = std.io.getStdOut().writer(); @@ -56,6 +57,11 @@ fn process_buf(buf: []u8, allocator: std.mem.Allocator) !void { defer arena.deinit(); const ast = try source_parser.parse(); std.debug.print("AST: {any}\n", .{ast}); + + const source_evaluator = try evaluator.Evaluator.init(allocator); + defer source_evaluator.deinit(); + const result = try source_evaluator.evaluate_ast(ast); + std.debug.print("Evaluation result: {any}\n", .{result}); } test { diff --git a/src/parser.zig b/src/parser.zig index 52a34b5..0db089f 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -24,7 +24,7 @@ pub const Node = union(NodeType) { PROGRAM: struct { expression: *Node, }, PRINT_STATEMENT: struct { expression: *Node, -}, EXPRESSION: union { +}, EXPRESSION: union(enum) { NUMBER: struct { value: i64, }, |