summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-08 23:49:27 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-08 23:49:27 +0100
commitdfa9ef4a951c4d498893a80728aa84734bf33775 (patch)
tree9adafce2199b1407f4a82e3a85b6270bb150cb43 /src
parentMisc: Dont crash REPL if parsing fails (diff)
downloadinterpreter-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.zig62
-rw-r--r--src/main.zig6
-rw-r--r--src/parser.zig2
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,
     },