revamp ast structure

This commit is contained in:
Luna 2019-06-05 20:29:03 -03:00
parent b040f47956
commit 3becccfba8
3 changed files with 111 additions and 69 deletions

View File

@ -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
View 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,
}
}

View File

@ -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;
} }