implemented function parsing

This commit is contained in:
Lorenzo Torres 2025-12-03 18:22:34 +01:00
parent 7d6436bb97
commit b504739d59
6 changed files with 80 additions and 9 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
**/*.o **/*.o
**/*~ **/*~
lc lc
*.swp

10
lc.c
View file

@ -168,7 +168,13 @@ void print_ast(ast_node *node, int depth) {
print_ast(node->expr.var_decl.value, depth + 1); print_ast(node->expr.var_decl.value, depth + 1);
break; break;
case NODE_FUNCTION: case NODE_FUNCTION:
printf("FunctionDef (Fields missing in struct)\n"); printf("Function: %.*s\n", (int)node->expr.function.name_len, node->expr.function.name);
m = node->expr.function.parameters;
while (m) {
print_ast(m->type, depth + 1);
m = m->next;
}
print_ast(node->expr.function.body, depth + 1);
break; break;
case NODE_RETURN: case NODE_RETURN:
printf("Return:\n"); printf("Return:\n");
@ -203,7 +209,7 @@ void print_ast(ast_node *node, int depth) {
int main(void) int main(void)
{ {
FILE *fp = fopen("test.c", "r"); FILE *fp = fopen("test.l", "r");
usize size = 0; usize size = 0;
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size = ftell(fp); size = ftell(fp);

View file

@ -869,6 +869,60 @@ static ast_node *parse_struct(parser *p)
return structure; return structure;
} }
static ast_node *parse_function(parser *p)
{
ast_node *fn = arena_alloc(p->allocator, sizeof(ast_node));
fn->type = NODE_FUNCTION;
fn->expr.function.type = peek(p)->lexeme;
fn->expr.function.type_len = peek(p)->lexeme_len;
advance(p);
fn->expr.function.name = peek(p)->lexeme;
fn->expr.function.name_len = peek(p)->lexeme_len;
advance(p);
/* Consume `(` */
advance(p);
if (match(p, TOKEN_RPAREN)) {
fn->expr.function.body = parse_compound(p);
fn->expr.function.parameters = NULL;
fn->expr.function.parameters_len = 0;
return fn;
}
member *prev = parse_member(p);
member *head = prev;
fn->expr.function.parameters = head;
fn->expr.function.parameters_len = 1;
if (!match(p, TOKEN_COMMA)) {
if (!match(p, TOKEN_RPAREN)) {
error(p, "expected `,`.");
return NULL;
} else {
fn->expr.function.body = parse_compound(p);
return fn;
}
}
while (!match(p, TOKEN_RPAREN)) {
member *current = parse_member(p);
if (!current) {
error(p, "expected parameter.");
return NULL;
}
prev->next = current;
if (!match(p, TOKEN_COMMA)) {
if (!match_peek(p, TOKEN_RPAREN)) {
error(p, "expected `,`.");
return NULL;
}
}
fn->expr.function.parameters_len += 1;
prev = current;
}
fn->expr.function.body = parse_compound(p);
return fn;
}
static ast_node *parse_statement(parser *p) static ast_node *parse_statement(parser *p)
{ {
if (match(p, TOKEN_BREAK)) if (match(p, TOKEN_BREAK))
@ -993,6 +1047,10 @@ static ast_node *parse_statement(parser *p)
} }
else if (match_peek(p, TOKEN_IDENTIFIER) && p->tokens->next && p->tokens->next->type == TOKEN_IDENTIFIER) else if (match_peek(p, TOKEN_IDENTIFIER) && p->tokens->next && p->tokens->next->type == TOKEN_IDENTIFIER)
{ {
if (p->tokens->next->next && p->tokens->next->next->type == TOKEN_LPAREN) {
/* Function definition. */
return parse_function(p);
}
/* Variable declaration. */ /* Variable declaration. */
ast_node *node = arena_alloc(p->allocator, sizeof(ast_node)); ast_node *node = arena_alloc(p->allocator, sizeof(ast_node));
node->type = NODE_VAR_DECL; node->type = NODE_VAR_DECL;

View file

@ -191,6 +191,15 @@ typedef struct _ast_node {
char *name; char *name;
usize name_len; usize name_len;
} structure; } structure;
struct {
member *parameters;
usize parameters_len;
char *name;
usize name_len;
char *type;
usize type_len;
struct _ast_node *body;
} function;
struct { struct {
variant *variants; variant *variants;
char *name; char *name;

7
test.c
View file

@ -1,7 +0,0 @@
enum {
a = 4,
b,
c
}
a = 3;

4
test.l Normal file
View file

@ -0,0 +1,4 @@
u32 a(u32 a)
{
u32 x = 3;
}