diff options
Diffstat (limited to 'src/ast.zig')
| -rw-r--r-- | src/ast.zig | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/src/ast.zig b/src/ast.zig deleted file mode 100644 index e8f3a8e..0000000 --- a/src/ast.zig +++ /dev/null @@ -1,161 +0,0 @@ -const std = @import("std"); -const tok = @import("tokenize.zig"); - -const SyntaxError = error{SyntaxError}; -const expectedToken = error{ExpectedToken}; - -pub const BinOp = enum(u32) { - Add = 0b000, - Sub = 0b001, - Mul = 0b100, - Div = 0b101, - Mod = 0b110, - - fn init(typ: tok.TokenType) ?BinOp { - return switch (typ) { - .plus => .Add, - .minus => .Sub, - .star => .Mul, - .slash => .Div, - else => null, - }; - } - - fn greater(self: BinOp, other: ?BinOp) bool { - if (other == null) return true; - return (@intFromEnum(self) >> 2) > (@intFromEnum(other.?) >> 2); - } -}; - -pub const Literal = union(enum) { - Int: i32, -}; - -pub const AstExpr = struct { - kind: ExprKind, - allocator: std.mem.Allocator, - pub fn init(allocator: std.mem.Allocator) !*AstExpr { - const value = try allocator.create(AstExpr); - value.* = .{ - .kind = .Void, - .allocator = allocator, - }; - return value; - } - pub fn deinit(self: *AstExpr) void { - self.allocator.free(self); - } -}; - -pub const AstStmt = struct { - kind: StmtKind, - allocator: std.mem.Allocator, - pub fn init(allocator: std.mem.Allocator) !*AstStmt { - const value = try allocator.create(AstStmt); - value.* = .{ - .kind = .Void, - .allocator = allocator, - }; - return value; - } - pub fn deinit(self: *AstStmt) void { - self.allocator.free(self); - } -}; - -pub const Ast = union(enum) { - Expr: AstExpr, - Stmt: AstStmt, -}; - -const StmtKind = union(enum) { - exit: AstExpr, - Void, -}; - -const ExprKind = union(enum) { - Literal: Literal, - BinaryOp: struct { - op: BinOp, - left: *AstExpr, - right: *AstExpr, - }, - Void, -}; - -const AstParser = struct { - tokens: tok.Iterator(tok.Token), - arena: std.heap.ArenaAllocator, - allocator: std.mem.Allocator, - - fn init(allocator: *std.heap.ArenaAllocator, tokens: tok.Iterator(tok.Token)) AstParser { - return AstParser{ - .tokens = tokens, - .arena = allocator.*, - .allocator = allocator.allocator(), - }; - } - - fn deinit(self: *AstParser) void { - self.arena.deinit(); - } - - fn parseStmt(self: *AstParser) !AstStmt { - return switch (self.tokens.peek().?) { - .ret => self.exitStmt(), - else => error.SyntaxError, - }; - } - - fn parseExpr(self: *AstParser, lastOp: ?BinOp) !*AstExpr { - if (!tok.checkType(self.tokens.peek().?, tok.TokenType.intLit)) return error.ExpectedToken; - const kind = ExprKind{ .Literal = .{ .Int = self.tokens.consume().?.intLit } }; - var lhs = try AstExpr.init(self.allocator); - lhs.*.kind = kind; - while (self.tokens.peek()) |tokn| { - const op = BinOp.init(tokn); - if (op != null and op.?.greater(lastOp)) { - self.tokens.skip(); - const rhs = try self.parseExpr(op); - const newkind = ExprKind{ .BinaryOp = .{ - .op = op.?, - .left = lhs, - .right = rhs, - } }; - lhs = try AstExpr.init(self.allocator); - lhs.*.kind = newkind; - } - return lhs; - } - return lhs; - } - - fn exitStmt(self: *AstParser) !AstStmt { - if (!tok.checkType(self.tokens.consume().?, tok.TokenType.ret)) - return error.ExpectedToken; - const value = try self.parseExpr(null); - - if (!tok.checkType(self.tokens.consume().?, tok.TokenType.semiCol)) return error.ExpectedToken; - const kind = StmtKind{ .exit = value.* }; - const stmt = try AstStmt.init(self.allocator); - stmt.kind = kind; - return stmt.*; - } -}; - -test "AstParse" { - std.testing.log_level = std.log.Level.info; - const expect = std.testing.expect; - const testSource: []const u8 = "exit 120 + 150;"; - var toks = tok.Tokenizer.init(std.testing.allocator, testSource); - defer toks.deinit(); - var arrtoks = try toks.tokenize(); - const slice = try arrtoks.toOwnedSlice(); - const iter = tok.Iterator(tok.Token).init(slice); - var arena = std.heap.ArenaAllocator.init(std.testing.allocator); - var parser = AstParser.init(&arena, iter); - defer parser.deinit(); - const stmt = try parser.parseStmt(); - _ = stmt; - _ = expect; -} |
