diff options
author | Manuel Palenzuela Merino <manuel.palenzuela@datadoghq.com> | 2025-01-16 22:27:29 +0100 |
---|---|---|
committer | Manuel Palenzuela Merino <manuel.palenzuela@datadoghq.com> | 2025-01-16 22:27:29 +0100 |
commit | ae8624e160eaf0d9805d9c1d2c834afd41b10433 (patch) | |
tree | f299c2c779758029daa2d519ffce079c767d38c8 | |
parent | Get function calls kind of working :) (diff) | |
download | interpreter-ae8624e160eaf0d9805d9c1d2c834afd41b10433.tar.gz interpreter-ae8624e160eaf0d9805d9c1d2c834afd41b10433.tar.bz2 interpreter-ae8624e160eaf0d9805d9c1d2c834afd41b10433.zip |
Evaluator: variables as values
-rw-r--r-- | examples/4.src | 4 | ||||
-rw-r--r-- | src/evaluator.zig | 35 |
2 files changed, 25 insertions, 14 deletions
diff --git a/examples/4.src b/examples/4.src index 6e639a8..0dd81ae 100644 --- a/examples/4.src +++ b/examples/4.src @@ -1,11 +1,11 @@ let print_one = () => { print(1); - return 0; + return 4; }; let main = () => { - let y = print_one(); + let y = print_one() + 2; print(y); diff --git a/src/evaluator.zig b/src/evaluator.zig index 6010e3b..2dd6b91 100644 --- a/src/evaluator.zig +++ b/src/evaluator.zig @@ -7,14 +7,16 @@ const EvaluatorError = error{ }; pub const Evaluator = struct { - variables: std.StringHashMap(?*parser.Node), //TODO: Reference vs value + ast: ?*parser.Node, + variables: std.StringHashMap(?i64), allocator: std.mem.Allocator, pub fn init(allocator: std.mem.Allocator) !*Evaluator { const evaluator = try allocator.create(Evaluator); evaluator.* = .{ - .variables = std.StringHashMap(?*parser.Node).init(allocator), + .ast = null, + .variables = std.StringHashMap(?i64).init(allocator), .allocator = allocator, }; return evaluator; @@ -29,7 +31,9 @@ pub const Evaluator = struct { errdefer std.debug.print("Error evaluating AST\n", .{}); std.debug.assert(ast.* == parser.Node.PROGRAM); - const main = find_main(ast) orelse return EvaluatorError.EvaluationError; + self.ast = ast; + + const main = self.find_function("main") orelse return EvaluatorError.EvaluationError; return try self.evaluate_function_definition(main); } @@ -61,7 +65,9 @@ pub const Evaluator = struct { return EvaluatorError.EvaluationError; } - try self.variables.put(assignment_statement.name, assignment_statement.expression); + const val = try self.get_expression_value(assignment_statement.expression); + + try self.variables.put(assignment_statement.name, val); } fn evaluate_print_statement(self: *Evaluator, print_statement: *parser.Node) !void { @@ -77,9 +83,9 @@ pub const Evaluator = struct { errdefer std.debug.print("Error evaluating function call statement\n", .{}); std.debug.assert(function_call_statement.* == parser.Node.FUNCTION_CALL_STATEMENT); - const node = self.variables.get(function_call_statement.FUNCTION_CALL_STATEMENT.name) orelse return EvaluatorError.EvaluationError; + const val = self.variables.get(function_call_statement.FUNCTION_CALL_STATEMENT.name) orelse return EvaluatorError.EvaluationError; - return try self.evaluate_function_definition(node.?); + return val.?; } fn evaluate_return_statement(self: *Evaluator, return_statement: *parser.Node) !i64 { @@ -109,17 +115,22 @@ pub const Evaluator = struct { return EvaluatorError.EvaluationError; }; - return self.get_expression_value(val.?); + return val.?; }, else => unreachable, } }, + .FUNCTION_CALL_STATEMENT => |x| { + const func = self.find_function(x.name) orelse return EvaluatorError.EvaluationError; + + return try self.evaluate_function_definition(func); + }, else => unreachable, } } - fn evaluate_function_definition(self: *Evaluator, node: *parser.Node) !i64 { + fn evaluate_function_definition(self: *Evaluator, node: *parser.Node) EvaluatorError!i64 { errdefer std.debug.print("Error evaluating function definition\n", .{}); std.debug.assert(node.* == parser.Node.FUNCTION_DEFINITION); @@ -136,15 +147,15 @@ pub const Evaluator = struct { return try self.evaluate_return_statement(return_stmt); } - fn find_main(ast: *parser.Node) ?*parser.Node { + fn find_function(self: *Evaluator, name: []const u8) ?*parser.Node { errdefer std.debug.print("Error finding main function\n", .{}); - std.debug.assert(ast.* == parser.Node.PROGRAM); + std.debug.assert(self.ast.?.* == parser.Node.PROGRAM); - for (ast.PROGRAM.statements) |*statement| { + for (self.ast.?.PROGRAM.statements) |*statement| { const x = statement.*.STATEMENT.statement; if (x.* != parser.Node.ASSIGNMENT_STATEMENT) continue; const y = x.*.ASSIGNMENT_STATEMENT; - if (y.is_declaration and std.mem.eql(u8, y.name, "main")) { + if (y.is_declaration and std.mem.eql(u8, y.name, name)) { return y.expression; } } |