From 899c015cbe5075b8df1901fcadbd24a8548b1354 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 23 Aug 2019 16:34:41 -0300 Subject: [PATCH] add basic const parsing (needs expr) - parser: fix main root loop's priming --- examples/hello.v | 6 +- src/ast.zig | 24 +++++++ src/parser.zig | 158 ++++++++++++++++++++++------------------------- 3 files changed, 102 insertions(+), 86 deletions(-) diff --git a/examples/hello.v b/examples/hello.v index a20f831..352e921 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -1 +1,5 @@ -fn main( a int) {} +const ( + AWOO = 2 +) + +fn main(a int) {} diff --git a/src/ast.zig b/src/ast.zig index 5e20aa6..d909a5e 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -4,12 +4,14 @@ const Token = tokens.Token; pub const NodeList = std.ArrayList(*Node); pub const ParamList = std.ArrayList(ParamDecl); +pub const ConstList = std.ArrayList(SingleConst); // TODO convert FnCall to something like PrefixOp / InfixOp / SuffixOp pub const NodeType = enum { Root, FnDecl, FnCall, + ConstDecl, String, }; @@ -31,9 +33,17 @@ pub const FnCall = struct { arguments: NodeList, }; +pub const SingleConst = struct { + name: Token, + + // TODO expr + value: Token, +}; + pub const Node = union(NodeType) { Root: NodeList, FnDecl: FnDecl, + ConstDecl: ConstList, FnCall: FnCall, String: Token, }; @@ -67,11 +77,25 @@ pub fn printNode(node: *Node, ident: usize) void { ); } }, + + .ConstDecl => |consts| { + print(ident, "ConstDecl ({} consts)\n", consts.len); + for (consts.toSlice()) |const_decl| { + print( + ident + 1, + "'{}' = '{}'\n", + const_decl.name.lexeme, + const_decl.value.lexeme, + ); + } + }, + .Root => { for (node.Root.toSlice()) |child| { printNode(child, ident + 1); } }, + else => { print(ident, "unknown node: {}\n", node); }, diff --git a/src/parser.zig b/src/parser.zig index e45d404..900be10 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -76,6 +76,7 @@ pub const Parser = struct { ); self.tokens[self.tokens.len - 1] = token; + std.debug.warn("skip to {}\n", token); return token; } @@ -87,8 +88,6 @@ pub const Parser = struct { } fn consumeSingle(self: *Parser, ttype: TokenType) !Token { - std.debug.warn("consume {}, has {}\n", ttype, self.peek().ttype); - if (self.check(ttype)) { var cur = self.peek(); _ = try self.nextToken(); @@ -122,34 +121,13 @@ pub const Parser = struct { return node; } + fn mkConstDecl(self: *Parser, consts: ast.ConstList) !*ast.Node { + var node = try self.allocator.create(Node); + node.* = Node{ .ConstDecl = consts }; + return node; + } + fn functionDecl(self: *Parser) !*ast.Node { - _ = try self.consumeSingle(.Fn); - var name = try self.consumeSingle(.Identifier); - _ = try self.consumeSingle(.LeftParen); - - var param_list = ast.ParamList.init(self.allocator); - - while (true) { - var tok = self.peek(); - - switch (tok.ttype) { - .RightParen => break, - .Identifier => {}, - else => try self.doError("expected identifier, got {}", tok.ttype), - } - - var typetok = try self.nextToken(); - if (typetok.ttype != .Identifier) { - try self.doError("expected identifier for type, got {}", typetok.ttype); - } - - var param = try self.allocator.create(ast.ParamDecl); - param.* = ast.ParamDecl{ .param_name = tok, .param_type = typetok }; - - std.debug.warn("param! {}\n", param); - try param_list.append(param); - tok = try self.nextToken(); - } // function body _ = try self.nextToken(); @@ -173,34 +151,6 @@ pub const Parser = struct { return try self.mkFnDecl(name, param_list); } - fn functionCall(self: *Parser) !*ast.Node { - var identifier = try self.consumeSingle(.Identifier); - _ = try self.consumeSingle(.LeftParen); - - // arguments - var args = ast.NodeList.init(self.allocator); - - while (true) { - var tok = self.peek(); - - switch (tok.ttype) { - .RightParen => break, - .String => blk: { - var node = try self.allocator.create(Node); - node.* = Node{ .String = tok }; - try args.append(node); - }, - else => {}, - } - - tok = try self.nextToken(); - } - - _ = try self.consumeSingle(.RightParen); - - return Node{ .FnCall = ast.FnCall{ .func_name = identifier, .arguments = args } }; - } - fn processToken(self: *Parser, token: Token) anyerror!*ast.Node { var node = switch (token.ttype) { .Fn => try self.functionDecl(), @@ -216,8 +166,6 @@ pub const Parser = struct { fn block(self: *Parser) anyerror!*ast.Node { - // TODO if(self.accept(.Const)) - // while receiving functions, process more while (self.accept(.Fn)) { try self.consumeSingle(.LeftParen); @@ -228,35 +176,67 @@ pub const Parser = struct { self.statement(); } + fn fnDecl(self: *@This()) !?*Node { + var param_list = ast.ParamList.init(self.allocator); + errdefer param_list.deinit(); + + _ = try self.consumeSingle(.Fn); + var name = try self.consumeSingle(.Identifier); + + _ = try self.consumeSingle(.LeftParen); + + while (self.peek().ttype != .RightParen) { + const param_name = try self.consumeSingle(.Identifier); + const param_type = try self.consumeSingle(.Identifier); + + try param_list.append(ast.ParamDecl{ + .name = param_name, + .typ = param_type, + }); + } + + _ = try self.consumeSingle(.RightParen); + + _ = try self.consumeSingle(.LeftBrace); + // TODO block + _ = try self.consumeSingle(.RightBrace); + + std.debug.warn("!fn name: {}\n", name); + return try self.mkFnDecl(name, param_list); + } + + fn constDecl(self: *@This()) !?*Node { + var consts = ast.ConstList.init(self.allocator); + errdefer consts.deinit(); + + _ = try self.consumeSingle(.Const); + + _ = try self.consumeSingle(.LeftParen); + + while (self.peek().ttype != .RightParen) { + const const_name = try self.consumeSingle(.Identifier); + _ = try self.consumeSingle(.Equal); + + // TODO expr + const const_value = self.peek(); + _ = try self.nextToken(); + //const const_value = try self.consumeSingle(.Identifier); + + try consts.append(ast.SingleConst{ .name = const_name, .value = const_value }); + } + + _ = try self.consumeSingle(.RightParen); + + return self.mkConstDecl(consts); + } + fn topDecl(self: *@This()) !?*Node { return switch (self.peek().ttype) { - .Fn => blk: { - var param_list = ast.ParamList.init(self.allocator); - errdefer param_list.deinit(); + .Fn => try self.fnDecl(), + .Const => try self.constDecl(), - _ = try self.consumeSingle(.Fn); - var name = try self.consumeSingle(.Identifier); - - _ = try self.consumeSingle(.LeftParen); - - while (self.peek().ttype != .RightParen) { - const param_name = try self.consumeSingle(.Identifier); - const param_type = try self.consumeSingle(.Identifier); - - try param_list.append(ast.ParamDecl{ .name = param_name, .typ = param_type }); - } - - _ = try self.consumeSingle(.RightParen); - - _ = try self.consumeSingle(.LeftBrace); - // TODO block - _ = try self.consumeSingle(.RightBrace); - - std.debug.warn("!fn name: {}\n", name); - break :blk try self.mkFnDecl(name, param_list); - }, else => |ttype| blk: { - self.doError("expected fn, got {}\n", ttype); + self.doError("(basic) expected fn/const, got {}\n", ttype); break :blk null; }, }; @@ -266,8 +246,16 @@ pub const Parser = struct { self.tokens = try self.allocator.alloc(Token, 0); var root = try ast.mkRoot(self.allocator); + var token_opt: ?Token = null; + while (true) { - var token = try self.nextToken(); + if (token_opt == null) { + token_opt = try self.nextToken(); + } else { + token_opt = self.peek(); + } + + var token = token_opt.?; if (token.ttype == .EOF) break; var node = try self.topDecl();