move ast printing functions to ast_printer.zig
This commit is contained in:
parent
a3127c76e7
commit
45ae160b76
4 changed files with 198 additions and 193 deletions
190
src/ast.zig
190
src/ast.zig
|
@ -200,193 +200,3 @@ pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
|
||||||
node.* = Node{ .Root = NodeList.init(allocator) };
|
node.* = Node{ .Root = NodeList.init(allocator) };
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO move those functions to src/ast_print.zig
|
|
||||||
|
|
||||||
fn printIdent(ident: usize) void {
|
|
||||||
var i: usize = 0;
|
|
||||||
while (i < ident) : (i += 1) {
|
|
||||||
std.debug.warn("\t");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
|
|
||||||
printIdent(ident);
|
|
||||||
std.debug.warn(fmt, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn printBlock(ident: usize, block: var, endNewline: bool) void {
|
|
||||||
std.debug.warn("(\n");
|
|
||||||
|
|
||||||
for (block.toSlice()) |stmt| {
|
|
||||||
printIdent(ident);
|
|
||||||
printStmt(ident, stmt);
|
|
||||||
std.debug.warn("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endNewline) {
|
|
||||||
print(ident - 1, ")\n");
|
|
||||||
} else {
|
|
||||||
print(ident - 1, ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn printNode(node: *Node, ident: usize) void {
|
|
||||||
switch (node.*) {
|
|
||||||
.FnDecl => |decl| {
|
|
||||||
print(ident, "(fn {} (", decl.func_name.lexeme);
|
|
||||||
|
|
||||||
for (decl.params.toSlice()) |param| {
|
|
||||||
std.debug.warn("({} {}) ", param.name.lexeme, param.typ.lexeme);
|
|
||||||
}
|
|
||||||
|
|
||||||
printBlock(ident + 1, decl.body, false);
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
.ConstDecl => |consts| {
|
|
||||||
print(ident, "(const (\n");
|
|
||||||
|
|
||||||
for (consts.toSlice()) |const_decl| {
|
|
||||||
print(
|
|
||||||
ident + 1,
|
|
||||||
"({} ",
|
|
||||||
const_decl.name.lexeme,
|
|
||||||
);
|
|
||||||
|
|
||||||
printExpr(const_decl.expr);
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print(ident, "))\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Root => {
|
|
||||||
for (node.Root.toSlice()) |child| {
|
|
||||||
printNode(child, ident + 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.Expr => |expr| {
|
|
||||||
printIdent(ident);
|
|
||||||
printExpr(expr);
|
|
||||||
std.debug.warn("\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Stmt => |stmt| blk: {
|
|
||||||
printIdent(ident);
|
|
||||||
printStmt(ident, stmt);
|
|
||||||
std.debug.warn("\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
else => {
|
|
||||||
print(ident, "unknown node: {}\n", node);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parenthetize(name: []const u8, exprs: []*Expr) void {
|
|
||||||
std.debug.warn("({}", name);
|
|
||||||
|
|
||||||
for (exprs) |expr| {
|
|
||||||
std.debug.warn(" ");
|
|
||||||
printExpr(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn printExpr(expr: *Expr) void {
|
|
||||||
switch (expr.*) {
|
|
||||||
.Binary => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
|
||||||
.Logical => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
|
||||||
.Unary => |unary| parenthetize(unary.op.lexeme, &[_]*Expr{unary.right}),
|
|
||||||
.Grouping => |expr_ptr| parenthetize("group", &[_]*Expr{expr_ptr}),
|
|
||||||
|
|
||||||
.Literal => |literal| {
|
|
||||||
switch (literal) {
|
|
||||||
.Bool => |val| std.debug.warn("{}", val),
|
|
||||||
.Integer => |val| std.debug.warn("{}", val),
|
|
||||||
.Float => |val| std.debug.warn("{}", val),
|
|
||||||
.String => |val| std.debug.warn("'{}'", val),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
.Variable => |token| std.debug.warn("{}", token.lexeme),
|
|
||||||
|
|
||||||
.VarDecl => |decl| {
|
|
||||||
if (decl.mutable) {
|
|
||||||
std.debug.warn("(mut ");
|
|
||||||
} else {
|
|
||||||
std.debug.warn("(");
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn("let {} ", decl.assign.name.lexeme);
|
|
||||||
printExpr(decl.assign.value);
|
|
||||||
std.debug.warn(")");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Assign => |assign| {
|
|
||||||
std.debug.warn("(set ");
|
|
||||||
std.debug.warn("{} ", assign.name.lexeme);
|
|
||||||
printExpr(assign.value);
|
|
||||||
std.debug.warn(")");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Call => |call| {
|
|
||||||
std.debug.warn("(");
|
|
||||||
printExpr(call.callee);
|
|
||||||
|
|
||||||
for (call.arguments.toSlice()) |arg| {
|
|
||||||
std.debug.warn(" ");
|
|
||||||
printExpr(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(")");
|
|
||||||
},
|
|
||||||
|
|
||||||
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
|
||||||
switch (stmt.*) {
|
|
||||||
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
|
||||||
.Expr => |expr| printExpr(expr),
|
|
||||||
|
|
||||||
.If => |ifstmt| {
|
|
||||||
std.debug.warn("(if ");
|
|
||||||
printExpr(ifstmt.condition);
|
|
||||||
std.debug.warn(" ");
|
|
||||||
|
|
||||||
printBlock(ident + 1, ifstmt.then_branch, false);
|
|
||||||
if (ifstmt.else_branch) |else_branch| {
|
|
||||||
std.debug.warn(" else ");
|
|
||||||
printBlock(ident + 1, else_branch, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Loop => |loop| {
|
|
||||||
std.debug.warn("(loop ");
|
|
||||||
if (loop.condition) |cond| {
|
|
||||||
printExpr(cond);
|
|
||||||
} else {
|
|
||||||
std.debug.warn("true");
|
|
||||||
}
|
|
||||||
std.debug.warn(" ");
|
|
||||||
|
|
||||||
printBlock(ident + 1, loop.then_branch, false);
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
.Return => |ret| {
|
|
||||||
std.debug.warn("(return ");
|
|
||||||
printExpr(ret.value);
|
|
||||||
std.debug.warn(")\n");
|
|
||||||
},
|
|
||||||
|
|
||||||
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
193
src/ast_printer.zig
Normal file
193
src/ast_printer.zig
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const tokens = @import("tokens.zig");
|
||||||
|
const Token = tokens.Token;
|
||||||
|
|
||||||
|
usingnamespace @import("ast.zig");
|
||||||
|
|
||||||
|
fn printIdent(ident: usize) void {
|
||||||
|
var i: usize = 0;
|
||||||
|
while (i < ident) : (i += 1) {
|
||||||
|
std.debug.warn("\t");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(ident: usize, comptime fmt: []const u8, args: ...) void {
|
||||||
|
printIdent(ident);
|
||||||
|
std.debug.warn(fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn printBlock(ident: usize, block: var, endNewline: bool) void {
|
||||||
|
std.debug.warn("(\n");
|
||||||
|
|
||||||
|
for (block.toSlice()) |stmt| {
|
||||||
|
printIdent(ident);
|
||||||
|
printStmt(ident, stmt);
|
||||||
|
std.debug.warn("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endNewline) {
|
||||||
|
print(ident - 1, ")\n");
|
||||||
|
} else {
|
||||||
|
print(ident - 1, ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn printNode(node: *Node, ident: usize) void {
|
||||||
|
switch (node.*) {
|
||||||
|
.FnDecl => |decl| {
|
||||||
|
print(ident, "(fn {} (", decl.func_name.lexeme);
|
||||||
|
|
||||||
|
for (decl.params.toSlice()) |param| {
|
||||||
|
std.debug.warn("({} {}) ", param.name.lexeme, param.typ.lexeme);
|
||||||
|
}
|
||||||
|
|
||||||
|
printBlock(ident + 1, decl.body, false);
|
||||||
|
std.debug.warn(")\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
.ConstDecl => |consts| {
|
||||||
|
print(ident, "(const (\n");
|
||||||
|
|
||||||
|
for (consts.toSlice()) |const_decl| {
|
||||||
|
print(
|
||||||
|
ident + 1,
|
||||||
|
"({} ",
|
||||||
|
const_decl.name.lexeme,
|
||||||
|
);
|
||||||
|
|
||||||
|
printExpr(const_decl.expr);
|
||||||
|
std.debug.warn(")\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print(ident, "))\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Root => {
|
||||||
|
for (node.Root.toSlice()) |child| {
|
||||||
|
printNode(child, ident + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.Expr => |expr| {
|
||||||
|
printIdent(ident);
|
||||||
|
printExpr(expr);
|
||||||
|
std.debug.warn("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Stmt => |stmt| blk: {
|
||||||
|
printIdent(ident);
|
||||||
|
printStmt(ident, stmt);
|
||||||
|
std.debug.warn("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
else => {
|
||||||
|
print(ident, "unknown node: {}\n", node);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parenthetize(name: []const u8, exprs: []*Expr) void {
|
||||||
|
std.debug.warn("({}", name);
|
||||||
|
|
||||||
|
for (exprs) |expr| {
|
||||||
|
std.debug.warn(" ");
|
||||||
|
printExpr(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn printExpr(expr: *Expr) void {
|
||||||
|
switch (expr.*) {
|
||||||
|
.Binary => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
||||||
|
.Logical => |binary| parenthetize(binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }),
|
||||||
|
.Unary => |unary| parenthetize(unary.op.lexeme, &[_]*Expr{unary.right}),
|
||||||
|
.Grouping => |expr_ptr| parenthetize("group", &[_]*Expr{expr_ptr}),
|
||||||
|
|
||||||
|
.Literal => |literal| {
|
||||||
|
switch (literal) {
|
||||||
|
.Bool => |val| std.debug.warn("{}", val),
|
||||||
|
.Integer => |val| std.debug.warn("{}", val),
|
||||||
|
.Float => |val| std.debug.warn("{}", val),
|
||||||
|
.String => |val| std.debug.warn("'{}'", val),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
.Variable => |token| std.debug.warn("{}", token.lexeme),
|
||||||
|
|
||||||
|
.VarDecl => |decl| {
|
||||||
|
if (decl.mutable) {
|
||||||
|
std.debug.warn("(mut ");
|
||||||
|
} else {
|
||||||
|
std.debug.warn("(");
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn("let {} ", decl.assign.name.lexeme);
|
||||||
|
printExpr(decl.assign.value);
|
||||||
|
std.debug.warn(")");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Assign => |assign| {
|
||||||
|
std.debug.warn("(set ");
|
||||||
|
std.debug.warn("{} ", assign.name.lexeme);
|
||||||
|
printExpr(assign.value);
|
||||||
|
std.debug.warn(")");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Call => |call| {
|
||||||
|
std.debug.warn("(");
|
||||||
|
printExpr(call.callee);
|
||||||
|
|
||||||
|
for (call.arguments.toSlice()) |arg| {
|
||||||
|
std.debug.warn(" ");
|
||||||
|
printExpr(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn(")");
|
||||||
|
},
|
||||||
|
|
||||||
|
else => std.debug.warn("UnknownExpr-{}", @tagName(expr.*)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
||||||
|
switch (stmt.*) {
|
||||||
|
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
||||||
|
.Expr => |expr| printExpr(expr),
|
||||||
|
|
||||||
|
.If => |ifstmt| {
|
||||||
|
std.debug.warn("(if ");
|
||||||
|
printExpr(ifstmt.condition);
|
||||||
|
std.debug.warn(" ");
|
||||||
|
|
||||||
|
printBlock(ident + 1, ifstmt.then_branch, false);
|
||||||
|
if (ifstmt.else_branch) |else_branch| {
|
||||||
|
std.debug.warn(" else ");
|
||||||
|
printBlock(ident + 1, else_branch, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.warn(")\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Loop => |loop| {
|
||||||
|
std.debug.warn("(loop ");
|
||||||
|
if (loop.condition) |cond| {
|
||||||
|
printExpr(cond);
|
||||||
|
} else {
|
||||||
|
std.debug.warn("true");
|
||||||
|
}
|
||||||
|
std.debug.warn(" ");
|
||||||
|
|
||||||
|
printBlock(ident + 1, loop.then_branch, false);
|
||||||
|
std.debug.warn(")\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
.Return => |ret| {
|
||||||
|
std.debug.warn("(return ");
|
||||||
|
printExpr(ret.value);
|
||||||
|
std.debug.warn(")\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
else => std.debug.warn("UnknownStmt-{}", @tagName(stmt.*)),
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ const main = @import("main.zig");
|
||||||
const ast = @import("ast.zig");
|
const ast = @import("ast.zig");
|
||||||
const tokens = @import("tokens.zig");
|
const tokens = @import("tokens.zig");
|
||||||
const err = @import("errors.zig");
|
const err = @import("errors.zig");
|
||||||
|
const printer = @import("ast_printer.zig");
|
||||||
|
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const Scanner = scanners.Scanner;
|
const Scanner = scanners.Scanner;
|
||||||
|
@ -392,6 +393,7 @@ pub const Parser = struct {
|
||||||
return switch (self.peek().ttype) {
|
return switch (self.peek().ttype) {
|
||||||
.Fn => try self.parseFnDecl(),
|
.Fn => try self.parseFnDecl(),
|
||||||
.Const => try self.parseConstDecl(),
|
.Const => try self.parseConstDecl(),
|
||||||
|
// TODO .Struct => try self.parseStructDecl(),
|
||||||
|
|
||||||
else => |ttype| blk: {
|
else => |ttype| blk: {
|
||||||
self.doError("(basic) expected fn/const, got {}\n", ttype);
|
self.doError("(basic) expected fn/const, got {}\n", ttype);
|
||||||
|
@ -408,7 +410,7 @@ pub const Parser = struct {
|
||||||
|
|
||||||
while (self.peek().ttype != .RightBrace) {
|
while (self.peek().ttype != .RightBrace) {
|
||||||
var stmt = try self.parseDecl();
|
var stmt = try self.parseDecl();
|
||||||
ast.printNode(try self.mkStmt(stmt), 0);
|
printer.printNode(try self.mkStmt(stmt), 0);
|
||||||
try stmts.append(stmt);
|
try stmts.append(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +444,7 @@ pub const Parser = struct {
|
||||||
|
|
||||||
while (self.peek().ttype != .RightBrace) {
|
while (self.peek().ttype != .RightBrace) {
|
||||||
var stmt = try self.parseDecl();
|
var stmt = try self.parseDecl();
|
||||||
ast.printNode(try self.mkStmt(stmt), 0);
|
printer.printNode(try self.mkStmt(stmt), 0);
|
||||||
try block.append(stmt);
|
try block.append(stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ pub const Runner = struct {
|
||||||
var it = root.Root.iterator();
|
var it = root.Root.iterator();
|
||||||
|
|
||||||
std.debug.warn("parse tree\n");
|
std.debug.warn("parse tree\n");
|
||||||
ast.printNode(root, 0);
|
printer.printNode(root, 0);
|
||||||
|
|
||||||
return Result.Ok;
|
return Result.Ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue