about summary refs log tree commit diff
path: root/src/parser.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.zig')
-rw-r--r--src/parser.zig56
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);
+}