diff --git a/examples/hello.v b/examples/hello.v index f328e4d..93536f3 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -1 +1,3 @@ -fn main() {} +fn main(a int) { + // println("hello world!"); +} diff --git a/src/ast.zig b/src/ast.zig index 52f25a9..365ef26 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -5,12 +5,9 @@ const Token = tokens.Token; pub const NodeList = std.ArrayList(*Node); pub const ParamList = std.ArrayList(*ParamDecl); -// TODO convert FnCall to something like PrefixOp / InfixOp / SuffixOp pub const NodeType = enum { Root, FnDecl, - FnCall, - String, }; pub const ParamDecl = struct { @@ -26,16 +23,9 @@ pub const FnDecl = struct { body: NodeList, }; -pub const FnCall = struct { - func_name: Token, - arguments: NodeList, -}; - pub const Node = union(NodeType) { Root: NodeList, FnDecl: FnDecl, - FnCall: FnCall, - String: Token, }; pub fn mkRoot(allocator: *std.mem.Allocator) !*Node { diff --git a/src/parser.zig b/src/parser.zig index f07ebc3..cd15872 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -18,18 +18,16 @@ pub const Parser = struct { tokens: []Token = undefined, - hadError: bool = false, - pub fn init(allocator: *Allocator, scanner: *Scanner) Parser { return Parser{ .allocator = allocator, .scanner = scanner }; } - fn doError(self: *Parser, comptime fmt: []const u8, args: ...) void { - self.hadError = true; - + fn doError(self: *Parser, comptime fmt: []const u8, args: ...) Result!void { std.debug.warn("parser error at line {}\n\t", self.scanner.line); std.debug.warn(fmt, args); std.debug.warn("\n"); + + return Result.CompileError; } fn peek(self: *Parser) Token { @@ -132,10 +130,9 @@ pub const Parser = struct { while (true) { var tok = self.peek(); - switch (tok.ttype) { - .RightParen => break, - .Identifier => {}, - else => try self.doError("expected identifier, got {}", tok.ttype), + if (tok.ttype == .RightParen) break; + if (tok.ttype != .Identifier) { + try self.doError("expected identifier, got {}", tok.ttype); } var typetok = try self.nextToken(); @@ -148,24 +145,15 @@ pub const Parser = struct { std.debug.warn("param! {}\n", param); try param_list.append(param); - tok = try self.nextToken(); } // function body - _ = try self.nextToken(); _ = try self.consumeSingle(.LeftBrace); - var body = ast.NodeList.init(self.allocator); - while (true) { var tok = self.peek(); if (tok.ttype == .RightBrace) break; - - // TODO statements - //var node = try self.processToken(tok); - //std.debug.warn("stmt:{}\n", node); - //try body.append(node); - - tok = try self.nextToken(); + // TODO statements? + //var node = self.processToken(tok); } _ = try self.consumeSingle(.RightBrace); @@ -173,38 +161,9 @@ 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 { + fn processToken(self: *Parser, token: Token) !*ast.Node { var node = switch (token.ttype) { .Fn => try self.functionDecl(), - .Identifier => try self.functionCall(), else => blk: { try self.doError("TODO handle {}\n", token.ttype); return Result.CompileError; @@ -214,53 +173,18 @@ pub const Parser = struct { return node; } - 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); - try self.consumeSingle(.RightParen); - var block = try self.block(); - } - - self.statement(); - } - - fn topDecl(self: *@This()) !?*Node { - return switch (self.peek().ttype) { - .Fn => blk: { - _ = try self.consumeSingle(.Fn); - var name = try self.consumeSingle(.Identifier); - std.debug.warn("!fn name: {}\n", name); - break :blk try self.mkFnDecl( - name, - ast.ParamList.init(self.allocator), - ); - }, - else => |ttype| blk: { - self.doError("expected fn, got {}\n", ttype); - break :blk null; - }, - }; - } - pub fn parse(self: *Parser) !*ast.Node { self.tokens = try self.allocator.alloc(Token, 0); var root = try ast.mkRoot(self.allocator); while (true) { var token = try self.nextToken(); + if (token.ttype == .EOF) break; - var node = try self.topDecl(); - if (node == null) continue; - try root.Root.append(node.?); - } - - if (self.hadError) { - return error.ParseError; + var node = try self.processToken(token); + std.debug.warn("{}\n", node.*); + try root.Root.append(node); } return root;