Add small grammer and print it
This commit is contained in:
parent
5f9cd99fe0
commit
44792e5c19
|
@ -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", .{});
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ pub const TokenType = enum {
|
||||||
|
|
||||||
pub const Token = struct {
|
pub const Token = struct {
|
||||||
token_type: TokenType,
|
token_type: TokenType,
|
||||||
lexeme: []u8,
|
lexeme: []const u8,
|
||||||
line: u64,
|
line: u64,
|
||||||
|
|
||||||
fn toString(self: *Token, alloc: std.mem.Allocator) ![]u8 {
|
fn toString(self: *Token, alloc: std.mem.Allocator) ![]u8 {
|
||||||
|
|
Loading…
Reference in New Issue