codegen almost finished

This commit is contained in:
Lorenzo Torres 2026-01-16 23:26:28 +01:00
parent ed0ad1d095
commit 870cf8f0b4
15 changed files with 523 additions and 126 deletions

View file

@ -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;