summary refs log tree commit diff
path: root/src/evaluator.zig
blob: 14f4049ead2c9da0e779d345c6d8d565f91e8d19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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"),
        };
    }
};