diff options
Diffstat (limited to 'src/parser.zig')
| -rw-r--r-- | src/parser.zig | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/parser.zig b/src/parser.zig new file mode 100644 index 0000000..c92ca0c --- /dev/null +++ b/src/parser.zig @@ -0,0 +1,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); +} |