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
|
const std = @import("std");
const tokenizer = @import("tokenizer.zig");
const NodeType = enum {
PROGRAM,
VARIABLE_STATEMENT,
PRINT_STATEMENT,
NUMBER,
IDENTIFIER,
};
pub const Node = union(NodeType) {
PROGRAM: struct {
statements: []*Node,
},
VARIABLE_STATEMENT: struct {
is_declaration: bool,
name: []const u8,
expression: *Node,
},
PRINT_STATEMENT: struct {
expression: *Node,
},
NUMBER: struct {
value: i32,
},
IDENTIFIER: struct {
name: []const u8,
},
};
pub const Parser = struct {
pub fn parse(_: []tokenizer.Token) !Node {
return Node{
.NUMBER = .{ .value = 9 },
};
}
};
test "simple" {
const tokens: []tokenizer.Token = @constCast(&[_]tokenizer.Token{
tokenizer.Token{ .LET = void{} },
tokenizer.Token{ .IDENTIFIER = @constCast("i") },
tokenizer.Token{ .EQUALS = void{} },
tokenizer.Token{ .NUMBER = 2 },
tokenizer.Token{ .SEMICOLON = void{} },
});
const ast = try Parser.parse(tokens);
try std.testing.expectEqualDeep(Node{ .PROGRAM = .{ .statements = @constCast(&[_]*Node{
@constCast(&Node{ .VARIABLE_STATEMENT = .{ .is_declaration = true, .name = @constCast("i"), .expression = @constCast(&Node{
.NUMBER = .{ .value = 2 },
}) } }),
}) } }, ast);
}
|