revamp ast structure
This commit is contained in:
parent
b040f47956
commit
3becccfba8
3 changed files with 111 additions and 69 deletions
115
src/ast.zig
115
src/ast.zig
|
@ -1,27 +1,63 @@
|
||||||
pub const AstNodeType = enum {
|
const tokens = @import("tokens.zig");
|
||||||
Program,
|
const Token = tokens.Token;
|
||||||
BinOp,
|
|
||||||
|
pub const ExprType = enum {
|
||||||
|
Unary,
|
||||||
|
Binary,
|
||||||
|
Grouping,
|
||||||
Number,
|
Number,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const AstNode = union(AstNodeType) {
|
pub const Expr = union(ExprType) {
|
||||||
Program: []AstNode,
|
Unary: UnaryExpr,
|
||||||
BinOp: AstBinOp,
|
Binary: BinaryExpr,
|
||||||
Number: AstNumber,
|
Grouping: Grouping,
|
||||||
|
Number: Number,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const BinOpType = enum {
|
pub const UnaryExpr = struct {
|
||||||
Equality,
|
operator: Token,
|
||||||
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const AstBinOp = struct {
|
pub fn mkUnary(operator: Token, right: *Expr) Expr {
|
||||||
optype: BinOpType,
|
return Expr{
|
||||||
|
.Unary = UnaryExpr{
|
||||||
|
.operator = operator,
|
||||||
|
.right = right,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// TODO expression
|
pub const BinaryExpr = struct {
|
||||||
left: *AstNode,
|
left: *Expr,
|
||||||
right: *AstNode,
|
operator: Token,
|
||||||
|
right: *Expr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub fn mkBinary(left: *Expr, operator: Token, right: *Expr) Expr {
|
||||||
|
return Expr{
|
||||||
|
.Binary = BinaryExpr{
|
||||||
|
.left = left,
|
||||||
|
.operator = operator,
|
||||||
|
.right = right,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Grouping = struct {
|
||||||
|
expression: *Expr,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn mkGrouping(expression: *Expr) Expr {
|
||||||
|
return Expr{
|
||||||
|
.Grouping = Grouping{
|
||||||
|
.expression = expression,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the default number literals in V.
|
||||||
pub const NumberType = enum {
|
pub const NumberType = enum {
|
||||||
Integer32,
|
Integer32,
|
||||||
Integer64,
|
Integer64,
|
||||||
|
@ -31,7 +67,9 @@ pub const NumberType = enum {
|
||||||
Float64,
|
Float64,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const AstNumber = union(NumberType) {
|
/// "translation" of V number types to Zig number types for nicer
|
||||||
|
/// representation.
|
||||||
|
pub const Number = union(NumberType) {
|
||||||
Integer32: i32,
|
Integer32: i32,
|
||||||
Integer64: i64,
|
Integer64: i64,
|
||||||
Unsigned32: u32,
|
Unsigned32: u32,
|
||||||
|
@ -40,41 +78,16 @@ pub const AstNumber = union(NumberType) {
|
||||||
Float64: f64,
|
Float64: f64,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn printNode(stdout: var, node: AstNode) anyerror!void {
|
pub fn mkNum(comptime T: type, num: T) Expr {
|
||||||
switch (node) {
|
var expr = switch (T) {
|
||||||
.Program => |children| try printNodes(stdout, children),
|
i32 => Expr{ .Number = Number{ .Integer32 = num } },
|
||||||
.BinOp => |bin_op| blk: {
|
i64 => Expr{ .Number = Number{ .Integer64 = num } },
|
||||||
try stdout.print("(");
|
u32 => Expr{ .Number = Number{ .Unsigned32 = num } },
|
||||||
switch (bin_op.optype) {
|
u64 => Expr{ .Number = Number{ .Unsigned64 = num } },
|
||||||
.Equality => try stdout.write("=="),
|
f32 => Expr{ .Number = Number{ .Float32 = num } },
|
||||||
}
|
f64 => Expr{ .Number = Number{ .Float64 = num } },
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
|
||||||
try stdout.write(" ");
|
return expr;
|
||||||
try printNode(stdout, bin_op.left.*);
|
|
||||||
try stdout.write(" ");
|
|
||||||
try printNode(stdout, bin_op.right.*);
|
|
||||||
try stdout.print(")");
|
|
||||||
},
|
|
||||||
.Number => |ast_num| {
|
|
||||||
switch (ast_num) {
|
|
||||||
.Integer32 => |num| try stdout.print("{}", num),
|
|
||||||
.Integer64 => |num| try stdout.print("{}", num),
|
|
||||||
.Unsigned32 => |num| try stdout.print("{}", num),
|
|
||||||
.Unsigned64 => |num| try stdout.print("{}", num),
|
|
||||||
.Float32 => |num| try stdout.print("{}", num),
|
|
||||||
.Float64 => |num| try stdout.print("{}", num),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn printNodes(stdout: var, nodes: []AstNode) anyerror!void {
|
|
||||||
try stdout.print("(");
|
|
||||||
|
|
||||||
for (nodes) |node| {
|
|
||||||
try stdout.print(" ");
|
|
||||||
try printNode(stdout, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
try stdout.print(")");
|
|
||||||
}
|
}
|
||||||
|
|
32
src/ast_printer.zig
Normal file
32
src/ast_printer.zig
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const ast = @import("ast.zig");
|
||||||
|
|
||||||
|
fn parenthesize(name: []const u8, exprs: []*ast.Expr) void {
|
||||||
|
std.debug.warn("({}", name);
|
||||||
|
|
||||||
|
for (exprs) |expr| {
|
||||||
|
std.debug.warn(" ");
|
||||||
|
printAst(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn printAst(ast_expr: *ast.Expr) void {
|
||||||
|
switch (ast_expr.*) {
|
||||||
|
.Binary => |expr| parenthesize(expr.operator.lexeme, &[]*ast.Expr{ expr.left, expr.right }),
|
||||||
|
.Grouping => |expr| parenthesize("group", &[]*ast.Expr{expr.expression}),
|
||||||
|
.Unary => |expr| parenthesize(expr.operator.lexeme, &[]*ast.Expr{expr.right}),
|
||||||
|
.Number => |ast_num| {
|
||||||
|
switch (ast_num) {
|
||||||
|
.Integer32 => |num| std.debug.warn("{}", num),
|
||||||
|
.Integer64 => |num| std.debug.warn("{}", num),
|
||||||
|
.Unsigned32 => |num| std.debug.warn("{}", num),
|
||||||
|
.Unsigned64 => |num| std.debug.warn("{}", num),
|
||||||
|
.Float32 => |num| std.debug.warn("{}", num),
|
||||||
|
.Float64 => |num| std.debug.warn("{}", num),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,9 @@ const parsers = @import("parser.zig");
|
||||||
const main = @import("main.zig");
|
const main = @import("main.zig");
|
||||||
const ast = @import("ast.zig");
|
const ast = @import("ast.zig");
|
||||||
|
|
||||||
|
const tokens = @import("tokens.zig");
|
||||||
|
const printer = @import("ast_printer.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Result = main.Result;
|
const Result = main.Result;
|
||||||
const Parser = parsers.Parser;
|
const Parser = parsers.Parser;
|
||||||
|
@ -42,24 +45,18 @@ pub const Runner = struct {
|
||||||
scanner = scanners.Scanner.init(self.allocator, code);
|
scanner = scanners.Scanner.init(self.allocator, code);
|
||||||
//var parser = Parser.init(self.allocator, &scanner);
|
//var parser = Parser.init(self.allocator, &scanner);
|
||||||
//var tree = try parser.parse();
|
//var tree = try parser.parse();
|
||||||
try ast.printNode(self.stdout, ast.AstNode{
|
|
||||||
.Program = &[]ast.AstNode{ast.AstNode{
|
var expr = ast.mkBinary(
|
||||||
.BinOp = ast.AstBinOp{
|
&ast.mkUnary(
|
||||||
.optype = ast.BinOpType.Equality,
|
tokens.Token{ .ttype = .Minus, .lexeme = "-", .line = 1 },
|
||||||
.left = &ast.AstNode{
|
&ast.mkNum(i32, 123),
|
||||||
.Number = ast.AstNumber{
|
),
|
||||||
.Integer32 = 30,
|
tokens.Token{ .ttype = .Star, .lexeme = "*", .line = 1 },
|
||||||
},
|
&ast.mkGrouping(&ast.mkNum(f32, 45.67)),
|
||||||
},
|
);
|
||||||
.right = &ast.AstNode{
|
|
||||||
.Number = ast.AstNumber{
|
printer.printAst(&expr);
|
||||||
.Integer32 = 30,
|
std.debug.warn("\n");
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
});
|
|
||||||
try self.stdout.print("\n");
|
|
||||||
|
|
||||||
return Result.Ok;
|
return Result.Ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue