implemented function parsing
This commit is contained in:
parent
7d6436bb97
commit
b504739d59
6 changed files with 80 additions and 9 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
||||||
**/*.o
|
**/*.o
|
||||||
**/*~
|
**/*~
|
||||||
lc
|
lc
|
||||||
|
*.swp
|
||||||
|
|
|
||||||
10
lc.c
10
lc.c
|
|
@ -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);
|
||||||
|
|
|
||||||
58
parser.c
58
parser.c
|
|
@ -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;
|
||||||
|
|
|
||||||
9
parser.h
9
parser.h
|
|
@ -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
7
test.c
|
|
@ -1,7 +0,0 @@
|
||||||
enum {
|
|
||||||
a = 4,
|
|
||||||
b,
|
|
||||||
c
|
|
||||||
}
|
|
||||||
|
|
||||||
a = 3;
|
|
||||||
4
test.l
Normal file
4
test.l
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
u32 a(u32 a)
|
||||||
|
{
|
||||||
|
u32 x = 3;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue