diff --git a/examples/hello.v b/examples/hello.v index 561bd45..5167113 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -52,3 +52,5 @@ fn main(a int) int { v()()() } + +fn voidfunc() {} diff --git a/src/parser.zig b/src/parser.zig index 0a3007e..8818e2a 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -375,6 +375,16 @@ pub const Parser = struct { return root; } + /// Copy a token with a different lexeme. + fn mkToken(self: *@This(), ttype: TokenType, lexeme: []const u8, line: usize) !Token { + const owned_lexeme = try std.mem.dupe(self.allocator, u8, lexeme); + return Token{ + .ttype = ttype, + .lexeme = owned_lexeme, + .line = line, + }; + } + fn parseFnDecl(self: *@This()) !*Node { var param_list = ast.ParamList.init(self.allocator); errdefer param_list.deinit(); @@ -387,7 +397,7 @@ pub const Parser = struct { while (self.peek().ttype != .RightParen) { const param_name = try self.consumeSingle(.Identifier); - // TODO dedicated function to consume a type + // TODO dedicated function to consume a type? const param_type = try self.consumeSingle(.Identifier); try param_list.append(ast.ParamDecl{ @@ -398,8 +408,15 @@ pub const Parser = struct { _ = try self.consumeSingle(.RightParen); - // TODO dedicated function to consume a type - const return_type = try self.consumeSingle(.Identifier); + // the return type is default void if a type + // is not provided + var return_type: Token = undefined; + if (self.check(.Identifier)) { + return_type = try self.consumeSingle(.Identifier); + } else { + return_type = try self.mkToken(.Identifier, "void", name.line); + } + var block_node = try self.parseBlock(); return try self.mkFnDecl(name, param_list, return_type, block_node.Block); }