diff options
| -rw-r--r-- | build.zig | 8 | ||||
| -rw-r--r-- | src/ast.zig | 67 | ||||
| -rw-r--r-- | src/main.zig | 1 | ||||
| -rw-r--r-- | src/tokenize.zig | 9 |
4 files changed, 84 insertions, 1 deletions
@@ -31,6 +31,12 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); + const ast_unit_tests = b.addTest(.{ + .root_source_file = b.path("src/ast.zig"), + .target = target, + .optimize = optimize, + }); + const token_unit_tests = b.addTest(.{ .root_source_file = b.path("src/tokenize.zig"), .target = target, @@ -38,9 +44,11 @@ pub fn build(b: *std.Build) void { }); const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + const run_ast_unit_tests = b.addRunArtifact(ast_unit_tests); const run_token_unit_tests = b.addRunArtifact(token_unit_tests); const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&run_exe_unit_tests.step); + test_step.dependOn(&run_ast_unit_tests.step); test_step.dependOn(&run_token_unit_tests.step); } diff --git a/src/ast.zig b/src/ast.zig new file mode 100644 index 0000000..2f8f209 --- /dev/null +++ b/src/ast.zig @@ -0,0 +1,67 @@ +const std = @import("std"); +const tok = @import("tokenize.zig"); + +const SyntaxError = error{SyntaxError}; +const expectedToken = error{ExpectedToken}; + +pub const BinOp = enum { + Add, + Sub, + Mul, + Div, +}; + +pub const Literal = union(enum) { + Int: i32, +}; + +pub const Ast = union(enum) { + Expr: struct { + kind: ExprKind, + }, + Stmt: struct { + kind: StmtKind, + }, +}; + +const StmtKind = union(enum) { + exit: Ast.Expr, +}; + +const ExprKind = union(enum) { + Literal: Literal, + BinaryOp: struct { + op: BinOp, + left: Ast.Expr, + right: Ast.Expr, + }, +}; + +fn checkType(token: tok.Token, typ: tok.TokenType) bool { + return switch (token) { + typ => true, + else => false, + }; +} + +const AstParser = struct { + tokens: tok.Iterator(tok.Token), + fn parseStmt(self: *AstParser) !Ast.Stmt { + return switch (self.tokens.peek().?) { + .ret => try self.exitStmt(), + }; + } + + fn parseExpr(self: *AstParser) !Ast.Expr { + + } + + fn exitStmt(self: *AstParser) !Ast.Stmt { + if (!checkType(self.tokens.consume().?, tok.TokenType.ret)) return expectedToken; + const value = self.parseExpr(); + + if (!checkType(self.tokens.consume().?, tok.TokenType.semiCol)) return expectedToken; + const kind = StmtKind{ .exit = value }; + return Ast.Stmt{ .kind = kind }; + } +}; diff --git a/src/main.zig b/src/main.zig index c24f8a8..4a0bbca 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ const std = @import("std"); const tok = @import("tokenize.zig"); +const ast = @import("ast.zig"); const gftCompilerError = error{NoInputFile}; diff --git a/src/tokenize.zig b/src/tokenize.zig index 37080b4..93a3ac9 100644 --- a/src/tokenize.zig +++ b/src/tokenize.zig @@ -1,8 +1,15 @@ const std = @import("std"); const TokenError = error{UnknownToken}; +const TokenType = enum { + ret, + intLit, + binaryOp, + semiCol, + nil, +}; -pub const Token = union(enum) { +pub const Token = union(TokenType) { ret: []const u8, intLit: i32, binaryOp: u8, |
