compiler/ast_print.c
2025-02-24 22:12:13 -06:00

107 lines
3.0 KiB
C

#include "assert.h"
#include "printf.h"
#include "ast_print.h"
static void print_indent(int indent)
{
for (int i = 0; i < indent; i++) {
print_char(' ');
print_char(' ');
}
}
#define printi(indent, ...) \
do { \
print_indent(indent); \
_printf(__VA_ARGS__); \
} while (0);
const char * statement_type_str(enum statement_type type)
{
static const char * map[] = {
[STATEMENT_RETURN] = "STATEMENT_RETURN",
[STATEMENT_IF_ELSE] = "STATEMENT_IF_ELSE",
};
assert(((int)type) < ((sizeof (map)) / (sizeof (map[0]))));
return map[(int)type];
}
const char * token_type_str(enum token_type type) {
static const char * map[] = {
[TOKEN_INVALID] = "TOKEN_INVALID",
[TOKEN_EOF] = "TOKEN_EOF",
[TOKEN_IDENTIFIER] = "TOKEN_IDENTIFIER",
[TOKEN_CONSTANT] = "TOKEN_CONSTANT",
[TOKEN_INT] = "TOKEN_INT",
[TOKEN_VOID] = "TOKEN_VOID",
[TOKEN_RETURN] = "TOKEN_RETURN",
[TOKEN_LPAREN] = "TOKEN_LPAREN",
[TOKEN_RPAREN] = "TOKEN_RPAREN",
[TOKEN_LBRACE] = "TOKEN_LBRACE",
[TOKEN_RBRACE] = "TOKEN_RBRACE",
[TOKEN_SEMICOLON] = "TOKEN_SEMICOLON",
};
assert(((int)type) < ((sizeof (map)) / (sizeof (map[0]))));
return map[(int)type];
}
void print_token(int indent, struct token token)
{
printi(indent, "type=%s str=", token_type_str(token.type));
const uint8_t * bufi = token.start;
while (bufi < token.end) {
print_char((char)*bufi++);
}
print_char('\n');
}
void print_expression(int indent, struct expression * expression)
{
printi(indent, "token=(\n");
print_token(indent + 1, expression->constant);
printi(indent, ")\n");
}
void print_return(int indent, struct statement_return * statement_return)
{
printi(indent, "expression=(\n");
print_expression(indent + 1, statement_return->expression);
printi(indent, ")\n");
}
void print_if_else(int indent, struct statement_if_else * statement_if_else)
{
printi(indent, "expression=(\n");
print_expression(indent + 1, statement_if_else->expression);
printi(indent, ")\n");
printi(indent, "statement_if=(\n");
print_statement(indent + 1, statement_if_else->statement_if);
printi(indent, ")\n");
printi(indent, "statement_else=(\n");
if (statement_if_else->statement_else == nullptr) {
printi(indent + 1, "nullptr\n");
} else {
print_statement(indent + 1, statement_if_else->statement_else);
}
printi(indent, ")\n");
}
void print_statement(int indent, struct statement * statement)
{
printi(indent, "statement type=%s (\n", statement_type_str(statement->type));
switch (statement->type) {
case STATEMENT_RETURN: print_return(indent + 1, statement->statement_return); break;
case STATEMENT_IF_ELSE: print_if_else(indent + 1, statement->statement_if_else); break;
default:
assert(false);
break;
}
printi(indent, ")\n");
}
void print_function_definition(int indent, struct statement * statement)
{
printi(indent, "function_definition name=");
print_token(statement->name);
}