diff --git a/examples/hello.v b/examples/hello.v index 13de5a8..9a3e886 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -34,15 +34,4 @@ fn main(a int) int { cock_and_ball_torture('cbt', 1, 2, 3) return 23 - - //p := Point{ - // x: 10 - // y: 20 - //} - //println(p.x) } - -//struct Point { -// x int -// y int -//} diff --git a/src/ast.zig b/src/ast.zig index 1bd9a81..9970d18 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -200,3 +200,193 @@ pub fn mkRoot(allocator: *std.mem.Allocator) !*Node { node.* = Node{ .Root = NodeList.init(allocator) }; 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.*)), + } +} diff --git a/src/ast_printer.zig b/src/ast_printer.zig deleted file mode 100644 index 3bedd68..0000000 --- a/src/ast_printer.zig +++ /dev/null @@ -1,193 +0,0 @@ -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.*)), - } -} diff --git a/src/parser.zig b/src/parser.zig index ea42dcf..0bf4055 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -4,7 +4,6 @@ const main = @import("main.zig"); const ast = @import("ast.zig"); const tokens = @import("tokens.zig"); const err = @import("errors.zig"); -const printer = @import("ast_printer.zig"); const Allocator = std.mem.Allocator; const Scanner = scanners.Scanner; @@ -326,7 +325,8 @@ pub const Parser = struct { if (token.ttype == .EOF) break; var node = try self.parseTopDecl(); - try root.Root.append(node); + if (node == null) continue; + try root.Root.append(node.?); } if (self.hadError) { @@ -336,7 +336,7 @@ pub const Parser = struct { return root; } - fn parseFnDecl(self: *@This()) !*Node { + fn parseFnDecl(self: *@This()) !?*Node { var param_list = ast.ParamList.init(self.allocator); errdefer param_list.deinit(); @@ -365,7 +365,7 @@ pub const Parser = struct { return try self.mkFnDecl(name, param_list, return_type, block_node.Block); } - fn parseConstDecl(self: *@This()) !*Node { + fn parseConstDecl(self: *@This()) !?*Node { var consts = ast.ConstList.init(self.allocator); errdefer consts.deinit(); @@ -389,15 +389,14 @@ pub const Parser = struct { return self.mkConstDecl(consts); } - fn parseTopDecl(self: *@This()) !*Node { + fn parseTopDecl(self: *@This()) !?*Node { return switch (self.peek().ttype) { .Fn => try self.parseFnDecl(), .Const => try self.parseConstDecl(), - // TODO .Struct => try self.parseStructDecl(), else => |ttype| blk: { self.doError("(basic) expected fn/const, got {}\n", ttype); - return Result.CompileError; + break :blk null; }, }; } @@ -410,7 +409,7 @@ pub const Parser = struct { while (self.peek().ttype != .RightBrace) { var stmt = try self.parseDecl(); - printer.printNode(try self.mkStmt(stmt), 0); + ast.printNode(try self.mkStmt(stmt), 0); try stmts.append(stmt); } @@ -444,7 +443,7 @@ pub const Parser = struct { while (self.peek().ttype != .RightBrace) { var stmt = try self.parseDecl(); - printer.printNode(try self.mkStmt(stmt), 0); + ast.printNode(try self.mkStmt(stmt), 0); try block.append(stmt); } diff --git a/src/runner.zig b/src/runner.zig index 9c9f0f5..34d81d0 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -49,7 +49,7 @@ pub const Runner = struct { var it = root.Root.iterator(); std.debug.warn("parse tree\n"); - printer.printNode(root, 0); + ast.printNode(root, 0); return Result.Ok; }