compiler-lightning/src/ast.c
2024-07-21 10:54:12 +12:00

125 lines
No EOL
3 KiB
C

#include <ast.h>
#include <helpers.h>
const char* ASTTypeText[] = {
"Program",
"CallExpression",
"NumberLiteral",
"StringLiteral"
};
ASTNode* ast_parse(Token** token) {
ASTVec body = { 0 };
while((*token) != NULL) {
sl_vec_push(body, ast_walk(token));
}
return ast_create_program(body);
}
ASTNode* ast_walk(Token** token) {
if((*token)->type == TOKEN_NUMBER) {
ASTNode* number = ast_create_number_literal((*token)->value);
ast_step(token);
return number;
}
if((*token)->type == TOKEN_STRING) {
ASTNode* string = ast_create_string_literal((*token)->value);
ast_step(token);
return string;
}
if((*token)->type == TOKEN_LPAREN) { // Call expression
ast_step(token);
const char* name = (*token)->value;
ASTVec params = { 0 };
ast_step(token);
while((*token)->type != TOKEN_RPAREN) {
sl_vec_push(params, ast_walk(token));
}
ast_step(token);
return ast_create_call_expression(name, params);
}
return NULL;
}
void ast_step(Token** token) {
(*token) = (*token)->next;
}
void ast_print(ASTNode* node, int indent) {
switch(node->type) {
case AST_PROGRAM:
printf("%s%s\n%sBody:\n",
gen_ident(indent), ASTTypeText[node->type],
gen_ident(indent + 2));
indent += 2;
for(sl_vec_it(n, node->body)) {
ast_print(*n, indent + 2);
}
break;
case AST_CALL_EXPRESSION:
printf("%s%s\n%sName: %s\n%sParams:\n",
gen_ident(indent), ASTTypeText[node->type],
gen_ident(indent + 2), node->name,
gen_ident(indent + 2));
indent += 2;
for(sl_vec_it(n, node->params)) {
ast_print(*n, indent + 2);
}
break;
case AST_NUMBER_LITERAL:
printf("%s%s\n%sValue: %s\n",
gen_ident(indent), ASTTypeText[node->type],
gen_ident(indent + 2), node->value);
break;
case AST_STRING_LITERAL:
printf("%s%s\n%sValue: %s\n",
gen_ident(indent), ASTTypeText[node->type],
gen_ident(indent + 2), node->value);
break;
}
}
ASTNode* ast_create_empty(ASTType type) {
ASTNode* new_node = malloc(sizeof(ASTNode));
new_node->type = type;
return new_node;
}
ASTNode* ast_create_program(ASTVec body) {
ASTNode* node = ast_create_empty(AST_PROGRAM);
node->body = body;
return node;
}
ASTNode* ast_create_call_expression(const char* name, ASTVec params) {
ASTNode* node = ast_create_empty(AST_CALL_EXPRESSION);
node->name = name;
node->params = params;
return node;
}
ASTNode* ast_create_number_literal(const char* value) {
ASTNode* node = ast_create_empty(AST_NUMBER_LITERAL);
node->value = value;
return node;
}
ASTNode* ast_create_string_literal(const char* value) {
ASTNode* node = ast_create_empty(AST_STRING_LITERAL);
node->value = value;
return node;
}