codegen almost finished
This commit is contained in:
parent
ed0ad1d095
commit
870cf8f0b4
15 changed files with 523 additions and 126 deletions
47
parser.c
47
parser.c
|
|
@ -1089,6 +1089,7 @@ static ast_node *parse_function(parser *p)
|
|||
{
|
||||
ast_node *fn = arena_alloc(p->allocator, sizeof(ast_node));
|
||||
fn->type = NODE_FUNCTION;
|
||||
fn->expr.function.is_extern = false;
|
||||
fn->expr.function.type = parse_type(p);
|
||||
fn->expr.function.name = peek(p)->lexeme;
|
||||
fn->expr.function.name_len = peek(p)->lexeme_len;
|
||||
|
|
@ -1097,7 +1098,14 @@ static ast_node *parse_function(parser *p)
|
|||
advance(p);
|
||||
|
||||
if (match(p, TOKEN_RPAREN)) {
|
||||
fn->expr.function.body = parse_compound(p);;
|
||||
// Check if this is an extern declaration (semicolon) or definition (body)
|
||||
if (match_peek(p, TOKEN_SEMICOLON)) {
|
||||
// Extern function - no body, just consume semicolon
|
||||
advance(p);
|
||||
fn->expr.function.body = NULL;
|
||||
} else {
|
||||
fn->expr.function.body = parse_compound(p);
|
||||
}
|
||||
fn->expr.function.parameters = NULL;
|
||||
fn->expr.function.parameters_len = 0;
|
||||
return fn;
|
||||
|
|
@ -1111,7 +1119,13 @@ static ast_node *parse_function(parser *p)
|
|||
error(p, "expected `,`.");
|
||||
return NULL;
|
||||
} else {
|
||||
fn->expr.function.body = parse_compound(p);
|
||||
// Check if this is an extern declaration (semicolon) or definition (body)
|
||||
if (match_peek(p, TOKEN_SEMICOLON)) {
|
||||
advance(p);
|
||||
fn->expr.function.body = NULL;
|
||||
} else {
|
||||
fn->expr.function.body = parse_compound(p);
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
}
|
||||
|
|
@ -1132,7 +1146,14 @@ static ast_node *parse_function(parser *p)
|
|||
|
||||
prev = current;
|
||||
}
|
||||
fn->expr.function.body = parse_compound(p);
|
||||
|
||||
// Check if this is an extern declaration (semicolon) or definition (body)
|
||||
if (match_peek(p, TOKEN_SEMICOLON)) {
|
||||
advance(p);
|
||||
fn->expr.function.body = NULL;
|
||||
} else {
|
||||
fn->expr.function.body = parse_compound(p);
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
|
@ -1140,6 +1161,13 @@ static ast_node *parse_function(parser *p)
|
|||
static ast_node *parse_statement(parser *p)
|
||||
{
|
||||
token *cur = peek(p);
|
||||
|
||||
/* Check for extern function declaration */
|
||||
bool is_extern = false;
|
||||
if (match(p, TOKEN_EXTERN)) {
|
||||
is_extern = true;
|
||||
}
|
||||
|
||||
ast_node *type = parse_type(p);
|
||||
if (type && type->type == NODE_STRUCT && type->expr.structure.name_len > 0) {
|
||||
goto skip_struct;
|
||||
|
|
@ -1148,9 +1176,20 @@ static ast_node *parse_statement(parser *p)
|
|||
if (p->tokens->next && p->tokens->next->type == TOKEN_LPAREN) {
|
||||
/* Function definition. */
|
||||
p->tokens = cur;
|
||||
return parse_function(p);
|
||||
if (is_extern) {
|
||||
advance(p); // Skip TOKEN_EXTERN
|
||||
}
|
||||
ast_node *fn = parse_function(p);
|
||||
if (fn && is_extern) {
|
||||
fn->expr.function.is_extern = true;
|
||||
fn->expr.function.body = NULL;
|
||||
}
|
||||
return fn;
|
||||
}
|
||||
p->tokens = cur;
|
||||
if (is_extern) {
|
||||
advance(p); // Skip TOKEN_EXTERN for non-function case
|
||||
}
|
||||
/* Variable declaration. */
|
||||
ast_node *node = arena_alloc(p->allocator, sizeof(ast_node));
|
||||
node->type = NODE_VAR_DECL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue