125 lines
No EOL
3 KiB
C
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;
|
|
} |