From ea5de0914a2b6f149c5c6f767cbbdfbc6485b952 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 24 Aug 2019 11:07:23 -0300 Subject: [PATCH] working expressions --- examples/hello.v | 16 +++++---- src/ast.zig | 46 ++++++++++++++++++++++-- src/parser.zig | 94 +++++++++++++++++++++++++++++++++--------------- 3 files changed, 119 insertions(+), 37 deletions(-) diff --git a/examples/hello.v b/examples/hello.v index cf7b836..4b4f28c 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -1,8 +1,10 @@ -const ( - Cock = 1 - Ball = 2 - Deals = 3 - Businesses = 4 -) +//const ( +// Cock = 1 +// Ball = 2 +// Deals = 3 +// Businesses = 4 +//) -fn main(a int) {} +fn main(a int) int { + 1 + 2 +} diff --git a/src/ast.zig b/src/ast.zig index 87d4164..700f491 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -26,7 +26,7 @@ pub const ParamDecl = struct { pub const FnDecl = struct { func_name: Token, params: ParamList, - body: NodeList, + body: ExprList, }; pub const SingleConst = struct { @@ -65,6 +65,8 @@ pub const Node = union(NodeType) { Root: NodeList, FnDecl: FnDecl, ConstDecl: ConstList, + + // TODO StmtList Block: ExprList, Expr: *Expr, }; @@ -75,12 +77,15 @@ pub fn mkRoot(allocator: *std.mem.Allocator) !*Node { return node; } -fn print(ident: usize, comptime fmt: []const u8, args: ...) void { +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); } @@ -97,6 +102,10 @@ pub fn printNode(node: *Node, ident: usize) void { param.typ.lexeme, ); } + + for (decl.body.toSlice()) |expr| { + printExpr(expr, ident + 1); + } }, .ConstDecl => |consts| { @@ -117,8 +126,41 @@ pub fn printNode(node: *Node, ident: usize) void { } }, + .Expr => |expr| printExpr(expr, 0), + else => { print(ident, "unknown node: {}\n", node); }, } } + +fn parenthetize(ident: usize, name: []const u8, exprs: []*Expr) void { + printIdent(ident); + std.debug.warn("({}", name); + + for (exprs) |expr| { + std.debug.warn(" "); + printExpr(expr, ident); + } + + std.debug.warn(")"); +} + +pub fn printExpr(expr: *Expr, ident: usize) void { + switch (expr.*) { + .Binary => |binary| parenthetize(ident, binary.op.lexeme, &[_]*Expr{ binary.left, binary.right }), + .Unary => |unary| parenthetize(ident, unary.op.lexeme, &[_]*Expr{unary.right}), + .Grouping => |expr_ptr| parenthetize(ident, "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), + } + }, + + else => std.debug.warn("unknown"), + } +} diff --git a/src/parser.zig b/src/parser.zig index 8bbd3e4..b5538b6 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -93,7 +93,7 @@ pub const Parser = struct { if (self.check(ttype)) { var cur = self.peek(); _ = try self.nextToken(); - std.debug.warn("now has {}\n", self.peek()); + std.debug.warn("consumed {}, now has {}\n", ttype, self.peek()); return cur; } @@ -111,21 +111,21 @@ pub const Parser = struct { fn compareAnyOf(self: *@This(), ttypes: []TokenType) bool { for (ttypes) |ttype| { - if (self.peek().ttype == ttype) return true; + if (self.check(ttype)) return true; } return false; } - fn mkFnDecl(self: *Parser, name: Token, params: ast.ParamList) !*ast.Node { + fn mkFnDecl(self: *Parser, name: Token, params: ast.ParamList, block: ast.ExprList) !*ast.Node { var node = try self.allocator.create(Node); node.* = Node{ .FnDecl = ast.FnDecl{ .func_name = name, .params = params, - // TODO replace by arg when statements work - .body = ast.NodeList.init(self.allocator), + // TODO stmt + .body = block, }, }; return node; @@ -156,6 +156,8 @@ pub const Parser = struct { } fn mkUnary(self: *Parser, op: Token, right: *Expr) !*Expr { + std.debug.warn("Unary\n"); + var expr = try self.allocator.create(Expr); expr.* = Expr{ .Unary = ast.UnaryExpr{ @@ -167,6 +169,8 @@ pub const Parser = struct { } fn mkBinary(self: *Parser, left: *Expr, op: Token, right: *Expr) !*Expr { + std.debug.warn("Binary\n"); + var expr = try self.allocator.create(Expr); expr.* = Expr{ .Binary = ast.BinaryExpr{ @@ -293,7 +297,7 @@ pub const Parser = struct { errdefer param_list.deinit(); _ = try self.consumeSingle(.Fn); - var name = try self.consumeSingle(.Identifier); + const name = try self.consumeSingle(.Identifier); _ = try self.consumeSingle(.LeftParen); @@ -310,11 +314,12 @@ pub const Parser = struct { _ = try self.consumeSingle(.RightParen); // TODO return type + const return_type = try self.consumeSingle(.Identifier); var block = try self.parseBlock(); std.debug.warn("!fn name: {}\n", name); - return try self.mkFnDecl(name, param_list); + return try self.mkFnDecl(name, param_list, block.Block); } fn parseConstDecl(self: *@This()) !?*Node { @@ -354,14 +359,18 @@ pub const Parser = struct { }; } - fn parseBlock(self: *@This()) !?*Node { + fn parseBlock(self: *@This()) !*Node { var exprs = ast.ExprList.init(self.allocator); errdefer exprs.deinit(); + _ = try self.consumeSingle(.LeftBrace); - while (self.peek().ttype != .RightBrace) - try exprs.append((try self.parseExpr()).Expr); - + while (self.peek().ttype != .RightBrace) { + var node = try self.parseExpr(); + ast.printNode(node, 0); + try exprs.append(node.Expr); + //_ = try self.nextToken(); + } _ = try self.consumeSingle(.RightBrace); return try self.mkBlock(exprs); @@ -418,21 +427,47 @@ pub const Parser = struct { fn parseAddition(self: *@This()) !*Expr { var expr = try self.parseMultiplication(); + std.debug.warn("left expr at addition:"); + ast.printExpr(expr, 0); + std.debug.warn("\n"); + while (self.compareAnyOf(&[_]TokenType{ .Minus, .Plus, })) { - var op = self.previous(); + var op = self.peek(); + _ = try self.nextToken(); + + std.debug.warn("==OP token {}\n", op); + var right = try self.parseMultiplication(); - expr.* = ast.Expr{ - .Binary = ast.BinaryExpr{ - .left = expr, - .op = op, - .right = right, - }, - }; + std.debug.warn("right expr at addition:"); + ast.printExpr(right, 0); + std.debug.warn("\n"); + + std.debug.warn("left expr at combination:"); + ast.printExpr(expr, 0); + std.debug.warn("\n"); + + expr = try self.mkBinary(expr, op, right); + + //expr.* = ast.Expr{ + // .Binary = ast.BinaryExpr{ + // .left = expr, + // .op = op, + // .right = right, + // }, + //}; + + std.debug.warn("final expr at addition:"); + ast.printExpr(expr, 0); + std.debug.warn("\n"); } + std.debug.warn("ret expr at addition:"); + ast.printExpr(expr, 0); + std.debug.warn("\n"); + return expr; } @@ -465,22 +500,24 @@ pub const Parser = struct { return try self.mkUnary(op, right); } - return try self.parsePrimary(); + var expr = try self.parsePrimary(); + return expr; } fn parsePrimary(self: *@This()) !*Expr { const curtype = self.peek().ttype; const lexeme = self.peek().lexeme; - _ = switch (curtype) { - .False => return try self.mkBool(false), - .True => return try self.mkBool(true), + var expr = switch (curtype) { + .False => try self.mkBool(false), + .True => try self.mkBool(true), - .Integer => return try self.mkInteger(lexeme), - .Float => return try self.mkFloat(lexeme), - .String => return try self.mkString(lexeme), + .Integer => try self.mkInteger(lexeme), + .Float => try self.mkFloat(lexeme), + .String => try self.mkString(lexeme), .LeftParen => blk: { + _ = try self.nextToken(); var expr = (try self.parseExpr()).Expr; _ = try self.consume(.RightParen, "Expected ')' after expression"); break :blk try self.mkGrouping(expr); @@ -492,7 +529,8 @@ pub const Parser = struct { }, }; - std.debug.warn("SHOULD NOT HAVE HAPPENED\n"); - return Result.CompileError; + _ = try self.nextToken(); + + return expr; } };