From 44792e5c19de69323e78715d4cd39edf9f238325 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Tue, 29 Aug 2023 08:59:58 -0700 Subject: [PATCH] Add small grammer and print it --- src/expr.zig | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/token.zig | 2 +- 2 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/expr.zig diff --git a/src/expr.zig b/src/expr.zig new file mode 100644 index 0000000..11fecec --- /dev/null +++ b/src/expr.zig @@ -0,0 +1,115 @@ +const std = @import("std"); + +const token = @import("token.zig"); + +pub const ExprTag = enum { + literal, + unary, + binary, + grouping, +}; + +pub const Expr = union(ExprTag) { + literal: LiteralExpr, + unary: UnaryExpr, + binary: BinaryExpr, + grouping: GroupingExpr, +}; + +pub const LiteralTag = enum { + number, + string, + boolean, + nil, +}; + +pub const LiteralExpr = union(LiteralTag) { + number: u64, + string: []u8, + boolean: bool, + nil: void, +}; + +pub const UnaryExpr = struct { + operator: token.Token, + right: *const Expr, +}; + +pub const BinaryExpr = struct { + left: *const Expr, + operator: token.Token, + right: *const Expr, +}; + +pub const GroupingExpr = struct { + expr: *const Expr, +}; + +pub fn AstPrint(expr: Expr) void { + switch (expr) { + .literal => |*literal| { + switch (literal.*) { + .number => |*number| std.debug.print("{}", .{number.*}), + .string => |*string| std.debug.print("{s}", .{string.*}), + .boolean => |*boolean| std.debug.print("{}", .{boolean.*}), + .nil => std.debug.print("nil", .{}), + } + }, + .unary => |*unary| { + std.debug.print("({s} ", .{unary.operator.lexeme}); + AstPrint(unary.right.*); + std.debug.print(")", .{}); + }, + .binary => |*binary| { + std.debug.print("({s} ", .{binary.operator.lexeme}); + AstPrint(binary.left.*); + std.debug.print(" ", .{}); + AstPrint(binary.right.*); + std.debug.print(")", .{}); + }, + .grouping => |*grouping| { + std.debug.print("(group ", .{}); + AstPrint(grouping.expr.*); + std.debug.print(")", .{}); + }, + } +} + +test "AstPrint" { + var expr = Expr{ + .binary = BinaryExpr{ + .left = &Expr{ + .unary = UnaryExpr{ + .operator = token.Token{ + .token_type = token.TokenType.MINUS, + .lexeme = "-", + .line = 0, + }, + .right = &Expr{ + .literal = LiteralExpr{ + .number = 123, + }, + }, + }, + }, + .operator = token.Token{ + .token_type = token.TokenType.STAR, + .lexeme = "*", + .line = 0, + }, + .right = &Expr{ + .grouping = GroupingExpr{ + .expr = &Expr{ + .literal = LiteralExpr{ + .number = 85, + }, + }, + }, + }, + }, + }; + + std.debug.print("\n", .{}); + AstPrint(expr); + std.debug.print("\n", .{}); +} diff --git a/src/token.zig b/src/token.zig index 3e17dcb..537a301 100644 --- a/src/token.zig +++ b/src/token.zig @@ -52,7 +52,7 @@ pub const TokenType = enum { pub const Token = struct { token_type: TokenType, - lexeme: []u8, + lexeme: []const u8, line: u64, fn toString(self: *Token, alloc: std.mem.Allocator) ![]u8 {