Skip to content

Commit

Permalink
Support void inside function definition
Browse files Browse the repository at this point in the history
  • Loading branch information
splasky committed May 8, 2018
1 parent 0adbcba commit b3f2e3f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
20 changes: 16 additions & 4 deletions shivyc/parser/declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,21 @@ def parse_parameter_list(index):
if token_is(index, token_kinds.close_paren):
return params, index

# argument is void and is not function declaration
if token_is(index, token_kinds.void_kw) \
and token_is(index + 1, token_kinds.close_paren):
if token_is(index + 2, token_kinds.open_brack):
return params, index + 1
elif token_is(index + 1, token_kinds.identifier):
err = "'void' must be the only parameter"
raise_error(err, index, ParserError.AT)

while True:
# Try parsing declaration specifiers, quit if no more exist
specs, index = parse_decl_specifiers(index)
decl, index = parse_declarator(index)

# New ast root
params.append(decl_nodes.Root(specs, [decl]))

# Expect a comma, and break if there isn't one
Expand Down Expand Up @@ -357,8 +368,8 @@ def _find_decl_end(index):
greater than the last index in this declarator.
"""
if (token_is(index, token_kinds.star) or
token_is(index, token_kinds.identifier) or
token_is(index, token_kinds.const_kw)):
token_is(index, token_kinds.identifier) or
token_is(index, token_kinds.const_kw)):
return _find_decl_end(index + 1)
elif token_is(index, token_kinds.open_paren):
close = _find_pair_forward(index)
Expand Down Expand Up @@ -392,7 +403,7 @@ def _parse_declarator_raw(start, end, is_typedef):
return decl_nodes.Identifier(None)

elif (start + 1 == end and
p.tokens[start].kind == token_kinds.identifier):
p.tokens[start].kind == token_kinds.identifier):
p.symbols.add_symbol(p.tokens[start], is_typedef)
return decl_nodes.Identifier(p.tokens[start])

Expand All @@ -402,7 +413,8 @@ def _parse_declarator_raw(start, end, is_typedef):
_parse_declarator(index, end, is_typedef), const)

func_decl = _try_parse_func_decl(start, end, is_typedef)
if func_decl: return func_decl
if func_decl:
return func_decl

# First and last elements make a parenthesis pair
elif (p.tokens[start].kind == token_kinds.open_paren and
Expand Down
7 changes: 7 additions & 0 deletions tests/feature_tests/error_function_def.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ const int func() {
return 4;
}

int func_void(void) {
return 4;
}

// error: 'void' must be the only parameter
int func_void_void(void a,void b){}

// error: redefinition of 'a'
void repeat_param(int a, int a) { }

Expand Down

0 comments on commit b3f2e3f

Please sign in to comment.