2019-08-26 13:25:14 +00:00
|
|
|
const std = @import("std");
|
|
|
|
const tokens = @import("tokens.zig");
|
|
|
|
const Token = tokens.Token;
|
|
|
|
|
|
|
|
usingnamespace @import("ast.zig");
|
|
|
|
|
2019-08-26 16:15:08 +00:00
|
|
|
const warn = std.debug.warn;
|
|
|
|
|
2019-08-26 13:25:14 +00:00
|
|
|
fn printIdent(ident: usize) void {
|
|
|
|
var i: usize = 0;
|
|
|
|
while (i < ident) : (i += 1) {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("\t", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
fn print(ident: usize, comptime fmt: []const u8, args: var) void {
|
2019-08-26 13:25:14 +00:00
|
|
|
printIdent(ident);
|
|
|
|
std.debug.warn(fmt, args);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn printBlock(ident: usize, block: var, endNewline: bool) void {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
for (block.toSlice()) |stmt| {
|
|
|
|
printIdent(ident);
|
|
|
|
printStmt(ident, stmt);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (endNewline) {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident - 1, ")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident - 1, ")", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn printNode(node: *Node, ident: usize) void {
|
|
|
|
switch (node.*) {
|
|
|
|
.FnDecl => |decl| {
|
2019-08-26 23:36:48 +00:00
|
|
|
const name = decl.func_name.lexeme;
|
|
|
|
|
|
|
|
printIdent(ident);
|
|
|
|
|
2019-08-27 00:12:41 +00:00
|
|
|
const ret_type = decl.return_type.lexeme;
|
2019-08-26 23:36:48 +00:00
|
|
|
|
|
|
|
if (decl.method) |method| {
|
|
|
|
const vari = method.variable.lexeme;
|
|
|
|
const typ = method.typ.lexeme;
|
|
|
|
|
|
|
|
if (method.mutable) {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("(method mut {} {} {} {} ", .{ vari, typ, name, ret_type });
|
2019-08-26 23:36:48 +00:00
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("(method {} {} {} {} ", .{ vari, typ, name, ret_type });
|
2019-08-26 23:36:48 +00:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("(fn {} {} (", .{ name, ret_type });
|
2019-08-26 23:36:48 +00:00
|
|
|
}
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
for (decl.params.toSlice()) |param| {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("({} {}) ", .{ param.name.lexeme, param.typ.lexeme });
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
printBlock(ident + 1, decl.body, false);
|
2020-04-10 19:48:10 +00:00
|
|
|
warn(")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
.ConstDecl => |consts| {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "(const (\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
for (consts.toSlice()) |const_decl| {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident + 1, "({} ", .{
|
2019-08-26 13:25:14 +00:00
|
|
|
const_decl.name.lexeme,
|
2020-04-10 19:48:10 +00:00
|
|
|
});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
printExpr(const_decl.expr);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "))\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
2019-08-27 15:31:02 +00:00
|
|
|
.Enum => |decl| {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "(enum {} (\n", .{decl.name.lexeme});
|
2019-08-27 15:31:02 +00:00
|
|
|
|
|
|
|
for (decl.fields.toSlice()) |field| {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident + 1, "{}\n", .{
|
2019-08-27 15:31:02 +00:00
|
|
|
field.lexeme,
|
2020-04-10 19:48:10 +00:00
|
|
|
});
|
2019-08-27 15:31:02 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "))\n", .{});
|
2019-08-27 15:31:02 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 13:25:14 +00:00
|
|
|
.Root => {
|
|
|
|
for (node.Root.toSlice()) |child| {
|
|
|
|
printNode(child, ident + 1);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-08-26 13:49:43 +00:00
|
|
|
.Stmt => |stmt| {
|
2019-08-26 13:25:14 +00:00
|
|
|
printIdent(ident);
|
|
|
|
printStmt(ident, stmt);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 13:49:43 +00:00
|
|
|
.Struct => |struc| {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "(struct {} (\n", .{struc.name.lexeme});
|
2019-08-26 13:49:43 +00:00
|
|
|
for (struc.fields.toSlice()) |field| {
|
|
|
|
printIdent(ident + 1);
|
|
|
|
if (field.mutable) {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(mut ", .{});
|
2019-08-26 13:49:43 +00:00
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(", .{});
|
2019-08-26 13:49:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (field.public) {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("pub ", .{});
|
2019-08-26 13:49:43 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 00:43:58 +00:00
|
|
|
if (field.mutable_outside) {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("MUT_OUT ", .{});
|
2019-08-27 00:43:58 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("{} {})\n", .{ field.name.lexeme, field.typ.lexeme });
|
2019-08-26 13:49:43 +00:00
|
|
|
}
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "))\n", .{});
|
2019-08-26 13:49:43 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 13:25:14 +00:00
|
|
|
else => {
|
2020-04-10 19:48:10 +00:00
|
|
|
print(ident, "unknown node: {}\n", .{node});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
fn parenthetize(name: []const u8, exprs: []*const Expr) void {
|
|
|
|
std.debug.warn("({}", .{name});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
for (exprs) |expr| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(expr);
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
pub fn printExpr(expr: *const Expr) void {
|
2019-08-26 13:25:14 +00:00
|
|
|
switch (expr.*) {
|
2020-04-10 19:48:10 +00:00
|
|
|
.Binary => |binary| parenthetize(binary.op.lexeme, &[_]*const Expr{ binary.left, binary.right }),
|
|
|
|
.Logical => |binary| parenthetize(binary.op.lexeme, &[_]*const Expr{ binary.left, binary.right }),
|
|
|
|
.Unary => |unary| parenthetize(unary.op.lexeme, &[_]*const Expr{unary.right}),
|
|
|
|
.Grouping => |expr_ptr| parenthetize("group", &[_]*const Expr{expr_ptr}),
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
.Literal => |literal| {
|
|
|
|
switch (literal) {
|
2020-04-10 19:48:10 +00:00
|
|
|
.Bool => |val| std.debug.warn("{}", .{val}),
|
|
|
|
.Integer => |val| std.debug.warn("{}", .{val}),
|
|
|
|
.Float => |val| std.debug.warn("{}", .{val}),
|
|
|
|
.String => |val| std.debug.warn("'{}'", .{val}),
|
2019-08-27 15:19:10 +00:00
|
|
|
.Array => |exprs| {
|
|
|
|
parenthetize("array", exprs.toSlice());
|
|
|
|
},
|
2020-04-10 19:48:10 +00:00
|
|
|
else => |typ| std.debug.warn("UnknownLiteral-{}", .{typ}),
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
.Variable => |token| std.debug.warn("{}", .{token.lexeme}),
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
.VarDecl => |decl| {
|
|
|
|
if (decl.mutable) {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(mut ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("let {} ", .{decl.assign.name.lexeme});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(decl.assign.value);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
.Assign => |assign| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(set ", .{});
|
|
|
|
std.debug.warn("{} ", .{assign.name.lexeme});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(assign.value);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
.Call => |call| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(call.callee);
|
|
|
|
|
|
|
|
for (call.arguments.toSlice()) |arg| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(arg);
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 14:59:32 +00:00
|
|
|
.Struct => |val| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("({} (", .{val.name.lexeme});
|
2019-08-26 14:59:32 +00:00
|
|
|
|
|
|
|
for (val.inits.toSlice()) |init| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" ({} ", .{init.field.lexeme});
|
2019-08-26 14:59:32 +00:00
|
|
|
printExpr(init.expr);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")", .{});
|
2019-08-26 14:59:32 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("))", .{});
|
2019-08-26 14:59:32 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 16:15:08 +00:00
|
|
|
.Get => |get| {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("(", .{});
|
2019-08-26 16:15:08 +00:00
|
|
|
printExpr(get.struc);
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("{}", .{get.name.lexeme});
|
2019-08-26 16:15:08 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 16:29:45 +00:00
|
|
|
.Set => |set| {
|
2020-04-10 19:48:10 +00:00
|
|
|
warn("(set ", .{});
|
2019-08-26 16:29:45 +00:00
|
|
|
printExpr(set.struc);
|
2020-04-10 19:48:10 +00:00
|
|
|
warn(" {} ", .{set.field.lexeme});
|
2019-08-26 16:29:45 +00:00
|
|
|
printExpr(set.value);
|
2020-04-10 19:48:10 +00:00
|
|
|
warn(")", .{});
|
2019-08-26 16:29:45 +00:00
|
|
|
},
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
else => std.debug.warn("UnknownExpr-{}", .{@tagName(expr.*)}),
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn printStmt(ident: usize, stmt: *Stmt) void {
|
|
|
|
switch (stmt.*) {
|
|
|
|
.Println => |expr| parenthetize("println", &[_]*Expr{expr}),
|
|
|
|
.Expr => |expr| printExpr(expr),
|
|
|
|
|
|
|
|
.If => |ifstmt| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(if ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(ifstmt.condition);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
printBlock(ident + 1, ifstmt.then_branch, false);
|
|
|
|
if (ifstmt.else_branch) |else_branch| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" else ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printBlock(ident + 1, else_branch, false);
|
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
.Loop => |loop| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(loop ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
if (loop.condition) |cond| {
|
|
|
|
printExpr(cond);
|
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("true", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(" ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
|
|
|
|
printBlock(ident + 1, loop.then_branch, false);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
2019-08-29 17:30:33 +00:00
|
|
|
.For => |forstmt| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(for ", .{});
|
2019-08-29 17:30:33 +00:00
|
|
|
|
|
|
|
if (forstmt.index) |index| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("({} {}) ", .{ index.lexeme, forstmt.value.lexeme });
|
2019-08-29 17:30:33 +00:00
|
|
|
} else {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("{} ", .{forstmt.value.lexeme});
|
2019-08-29 17:30:33 +00:00
|
|
|
}
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("{} ", .{forstmt.array.lexeme});
|
2019-08-29 17:30:33 +00:00
|
|
|
|
|
|
|
printBlock(ident + 1, forstmt.block, false);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")\n", .{});
|
2019-08-29 17:30:33 +00:00
|
|
|
},
|
|
|
|
|
2019-08-26 13:25:14 +00:00
|
|
|
.Return => |ret| {
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn("(return ", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
printExpr(ret.value);
|
2020-04-10 19:48:10 +00:00
|
|
|
std.debug.warn(")\n", .{});
|
2019-08-26 13:25:14 +00:00
|
|
|
},
|
|
|
|
|
2020-04-10 19:48:10 +00:00
|
|
|
else => std.debug.warn("UnknownStmt-{}", .{@tagName(stmt.*)}),
|
2019-08-26 13:25:14 +00:00
|
|
|
}
|
|
|
|
}
|