Skip to content

Commit

Permalink
fix(rivetc.parser+rivet/parser): check missing function return type
Browse files Browse the repository at this point in the history
  • Loading branch information
StunxFS committed Oct 29, 2023
1 parent 19a11ae commit 2fb8e68
Show file tree
Hide file tree
Showing 32 changed files with 5,203 additions and 223 deletions.
6 changes: 5 additions & 1 deletion lib/rivet/src/parser/decls.ri
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,11 @@ extend Parser {
ret_t_pos := self.tok.pos;
if self.accept(.Arrow2) {
is_result := self.accept(.Bang);
if self.tok.kind != .Lbrace {
if self.tok.kind == .Lbrace {
if !is_result {
report.error("expected return type declaration", self.prev_tok.pos);
}
} else {
ret_type = self.parse_type();
}
if is_result {
Expand Down
33 changes: 15 additions & 18 deletions lib/rivet/tests/tokenizer.ri
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,15 @@ func tokenize(text: string) -> []token.Token {
return tokens;
}

test "tokenizer: simple `func main() -> { }`" {
tokens := tokenize("func main() -> { }");
@assert(tokens.len == 7);
test "tokenizer: simple `func main() { }`" {
tokens := tokenize("func main() { }");
@assert(tokens.len == 6);
@assert(tokens[0].kind == .KwFunc);
@assert(tokens[1].kind == .Name and tokens[1].lit == "main");
@assert(tokens[2].kind == .Lparen);
@assert(tokens[3].kind == .Rparen);
@assert(tokens[4].kind == .Arrow2);
@assert(tokens[5].kind == .Lbrace);
@assert(tokens[6].kind == .Rbrace);
@assert(tokens[4].kind == .Lbrace);
@assert(tokens[5].kind == .Rbrace);
}

test "tokenizer: number constant input format" {
Expand All @@ -59,29 +58,27 @@ test "tokenizer: float conversion and reading" {
}

test "tokenizer: preprocessor" {
mut tokens := tokenize("#if true func main() -> { } #endif");
@assert(tokens.len == 7);
mut tokens := tokenize("#if true func main() { } #endif");
@assert(tokens.len == 6);
@assert(tokens[0].kind == .KwFunc);
@assert(tokens[1].kind == .Name and tokens[1].lit == "main");
@assert(tokens[2].kind == .Lparen);
@assert(tokens[3].kind == .Rparen);
@assert(tokens[4].kind == .Arrow2);
@assert(tokens[5].kind == .Lbrace);
@assert(tokens[6].kind == .Rbrace);
@assert(tokens[4].kind == .Lbrace);
@assert(tokens[5].kind == .Rbrace);

tokens = tokenize("#if false func main() -> { } #endif");
tokens = tokenize("#if false func main() { } #endif");
@assert(tokens.len == 1); // EndOfFile

tokens = tokenize("#if !CUSTOM_FLAG func main() -> { } #endif");
@assert(tokens.len == 7);
tokens = tokenize("#if !CUSTOM_FLAG func main() { } #endif");
@assert(tokens.len == 6);
@assert(tokens[0].kind == .KwFunc);
@assert(tokens[1].kind == .Name and tokens[1].lit == "main");
@assert(tokens[2].kind == .Lparen);
@assert(tokens[3].kind == .Rparen);
@assert(tokens[4].kind == .Arrow2);
@assert(tokens[5].kind == .Lbrace);
@assert(tokens[6].kind == .Rbrace);
@assert(tokens[4].kind == .Lbrace);
@assert(tokens[5].kind == .Rbrace);

tokens = tokenize("#if CUSTOM_FLAG func main() -> { } #endif");
tokens = tokenize("#if CUSTOM_FLAG func main() { } #endif");
@assert(tokens.len == 1); // EndOfFile
}
5 changes: 4 additions & 1 deletion rivetc/src/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,10 @@ def parse_func_decl(
ret_typ = self.comp.void_t
if self.accept(Kind.Arrow2):
is_result = self.accept(Kind.Bang)
if self.tok.kind != Kind.Lbrace:
if self.tok.kind == Kind.Lbrace:
if not is_result:
report.error("expected return type declaration", self.prev_tok.pos)
else:
ret_typ = self.parse_type()
if is_result:
ret_typ = type.Result(ret_typ)
Expand Down
2 changes: 1 addition & 1 deletion tests/b_invalid/duplicate_symbols.out
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/b_invalid/duplicate_symbols.ri:15:6: error: module `duplicate_symbols` has duplicate symbol `other`
15 | func other(a: int32) -> { // FAIL
15 | func other(a: int32) { // FAIL
| ^
tests/b_invalid/duplicate_symbols.ri:20:8: error: module `duplicate_symbols` has duplicate symbol `Gota`
20 | struct Gota { } // FAIL
Expand Down
2 changes: 1 addition & 1 deletion tests/b_invalid/duplicate_symbols.ri
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func other(a: int32) {
a := 1;
}

func other(a: int32) -> { // FAIL
func other(a: int32) { // FAIL
a := 1;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/b_invalid/expected_type.out
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/b_invalid/expected_type.ri:3:11: error: expected type, found function
3 | func x(a: my_fn) -> {}
3 | func x(a: my_fn) {}
| ^
rivetc: error: could not compile module `expected_type`, aborting due to previous error
6 changes: 3 additions & 3 deletions tests/b_invalid/expected_type.ri
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
func my_fn() -> { }
func my_fn() { }

func x(a: my_fn) -> {}
func x(a: my_fn) {}

func main() -> { }
func main() { }
2 changes: 1 addition & 1 deletion tests/b_invalid/types.ri
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ struct St {
f5: =;
}

func main() -> { }
func main() { }
Loading

0 comments on commit 2fb8e68

Please sign in to comment.