#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); }