larpcc/ast_print.c
2026-10-09 02:57:39 +02:00

370 lines
9.7 KiB
C

#include "ast.h"
#include "collection.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static void indent(FILE* f, int depth)
{
for (int i = 0; i < depth; ++i) {
fprintf(f, " ");
}
}
void ast_stmt_block_print(FILE* f, const AstStmtBlock* node, int depth)
{
fprintf(f, "StmtBlock %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "stmts: [");
if (node->stmts_size) {
fprintf(f, "\n");
for (size_t i = 0; i < node->stmts_size; ++i) {
indent(f, depth + 2);
ast_stmt_print(f, node->stmts[i], depth + 2);
fprintf(f, ",\n");
}
indent(f, depth + 1);
}
fprintf(f, "],\n");
indent(f, depth);
fprintf(f, "}");
}
void ast_stmt_print(FILE* f, const AstStmt* node, int depth)
{
switch (node->ty) {
case AstStmt_Decl: {
fprintf(f, "Stmt::Decl %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "decl: ");
ast_decl_print(f, node->decl, depth + 1);
fprintf(f, ",\n");
indent(f, depth);
fprintf(f, "}");
break;
}
case AstStmt_Expr: {
fprintf(f, "Stmt::Expr %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "expr: ");
ast_expr_print(f, node->expr, depth + 1);
fprintf(f, ",\n");
indent(f, depth);
fprintf(f, "}");
break;
}
}
}
static void spec_print(FILE* f, AstSpec spec)
{
struct {
AstSpec specifier;
const char* ident;
} spec_idents[] = {
{ AstSpec_Int, "int" },
{ AstSpec_Char, "char" },
{ AstSpec_Unsigned, "unsigned" },
{ AstSpec_Static, "static" },
{ AstSpec_Const, "const" },
{ AstSpec_Inline, "inline" },
{ AstSpec_Typedef, "typedef" },
{ AstSpec_Enum, "enum" },
{ AstSpec_Struct, "struct" },
{ AstSpec_Union, "union" },
};
bool first = true;
for (size_t i = 0; i < sizeof(spec_idents) / sizeof(spec_idents[0]); ++i) {
if (spec & spec_idents[i].specifier) {
if (!first)
fprintf(f, " ");
first = false;
fprintf(f, "%s", spec_idents[i].ident);
}
}
}
void ast_decl_print(FILE* f, const AstDecl* node, int depth)
{
fprintf(f, "Decl %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "spec: [");
spec_print(f, node->spec);
fprintf(f, "],\n");
if (node->spec & AstSpec_DefTy) {
assert(node->type_ident);
indent(f, depth + 1);
fprintf(f, "type_ident: \"%s\",\n", node->type_ident);
}
indent(f, depth + 1);
fprintf(f, "declars: [");
if (node->declars_size) {
fprintf(f, "\n");
for (size_t i = 0; i < node->declars_size; ++i) {
indent(f, depth + 2);
ast_declar_print(f, node->declars[i], depth + 2);
fprintf(f, ",\n");
}
indent(f, depth + 1);
}
fprintf(f, "],\n");
if (node->function_body) {
indent(f, depth + 1);
fprintf(f, "function_body: ");
ast_stmt_block_print(f, node->function_body, depth + 1);
fprintf(f, ",\n");
}
indent(f, depth);
fprintf(f, "}");
}
void ast_declar_print(FILE* f, const AstDeclar* node, int depth)
{
switch (node->ty) {
case AstDeclar_Ident: {
fprintf(
f, "Declar::Ident %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "ident: \"%s\",\n", node->ident);
break;
}
case AstDeclar_Pointer: {
fprintf(
f, "Declar::Pointer %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "declar: ");
ast_declar_print(f, node->pointer.declar, depth + 1);
fprintf(f, ",\n");
indent(f, depth + 1);
fprintf(f, "spec: [");
spec_print(f, node->pointer.spec);
fprintf(f, "],\n");
break;
}
case AstDeclar_Array: {
fprintf(
f, "Declar::Array %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "declar: ");
ast_declar_print(f, node->array.declar, depth + 1);
fprintf(f, ",\n");
indent(f, depth + 1);
fprintf(f, "expr: ");
ast_expr_print(f, node->array.expr, depth + 1);
fprintf(f, ",\n");
break;
}
case AstDeclar_Function: {
fprintf(
f, "Declar::Function %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "declar: ");
ast_declar_print(f, node->array.declar, depth + 1);
fprintf(f, ",\n");
indent(f, depth + 1);
fprintf(f, "params: [");
if (node->function.params_size) {
fprintf(f, "\n");
for (size_t i = 0; i < node->function.params_size; ++i) {
indent(f, depth + 2);
ast_decl_print(f, node->function.params[i], depth + 2);
fprintf(f, ",\n");
}
indent(f, depth + 1);
fprintf(f, "],\n");
} else {
fprintf(f, "],\n");
}
break;
}
}
if (node->init_expr) {
indent(f, depth + 2);
fprintf(f, "decl: ");
ast_expr_print(f, node->init_expr, depth + 2);
fprintf(f, ",\n");
}
indent(f, depth);
fprintf(f, "}");
}
void ast_expr_print(FILE* f, const AstExpr* node, int depth)
{
switch (node->ty) {
case AstExpr_Ident: {
fprintf(f, "Expr::Ident %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "ident: \"%s\",\n", node->ident);
indent(f, depth);
fprintf(f, "}");
break;
}
case AstExpr_Str: {
fprintf(f, "Expr::Str %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "str_val: \"%s\",\n", node->str_val);
indent(f, depth);
fprintf(f, "}");
break;
}
case AstExpr_Call: {
fprintf(f, "Expr::Call %d:%d {\n", node->loc.line, node->loc.col);
indent(f, depth + 1);
fprintf(f, "expr: ");
ast_expr_print(f, node->call.expr, depth + 1);
fprintf(f, ",\n");
indent(f, depth + 1);
fprintf(f, "args: [");
if (node->call.args_size) {
fprintf(f, "\n");
for (size_t i = 0; i < node->call.args_size; ++i) {
indent(f, depth + 2);
ast_expr_print(f, node->call.args[i], depth + 2);
fprintf(f, ",\n");
}
indent(f, depth + 1);
}
fprintf(f, "],\n");
indent(f, depth);
fprintf(f, "}");
break;
}
}
}
void ast_stmt_block_visit(AstVisitor* v, AstStmtBlock* node)
{
if (v->visit_stmt_block && v->visit_stmt_block(v, node) == AstVisitor_Break)
return;
ast_stmt_block_visit_body(v, node);
}
void ast_stmt_block_visit_body(AstVisitor* v, AstStmtBlock* node)
{
for (size_t i = 0; i < node->stmts_size; ++i) {
ast_stmt_visit(v, node->stmts[i]);
}
}
void ast_stmt_visit(AstVisitor* v, AstStmt* node)
{
if (v->visit_stmt && v->visit_stmt(v, node) == AstVisitor_Break)
return;
ast_stmt_visit_body(v, node);
}
void ast_stmt_visit_body(AstVisitor* v, AstStmt* node)
{
switch (node->ty) {
case AstStmt_Decl:
ast_decl_visit(v, node->decl);
break;
case AstStmt_Expr:
ast_expr_visit(v, node->expr);
break;
}
}
void ast_decl_visit(AstVisitor* v, AstDecl* node)
{
if (v->visit_decl && v->visit_decl(v, node) == AstVisitor_Break)
return;
ast_decl_visit_body(v, node);
}
void ast_decl_visit_body(AstVisitor* v, AstDecl* node)
{
for (size_t i = 0; i < node->declars_size; ++i)
ast_declar_visit(v, node->declars[i]);
if (node->function_body)
ast_stmt_block_visit(v, node->function_body);
}
void ast_declar_visit(AstVisitor* v, AstDeclar* node)
{
if (v->visit_declar && v->visit_declar(v, node) == AstVisitor_Break)
return;
ast_declar_visit_body(v, node);
}
void ast_declar_visit_body(AstVisitor* v, AstDeclar* node)
{
switch (node->ty) {
case AstDeclar_Ident:
break;
case AstDeclar_Pointer:
ast_declar_visit(v, node->pointer.declar);
break;
case AstDeclar_Array:
ast_declar_visit(v, node->array.declar);
ast_expr_visit(v, node->array.expr);
break;
case AstDeclar_Function:
ast_declar_visit(v, node->function.declar);
for (size_t i = 0; i < node->function.params_size; ++i)
ast_decl_visit(v, node->function.params[i]);
break;
}
}
void ast_expr_visit(AstVisitor* v, AstExpr* node)
{
if (v->visit_expr && v->visit_expr(v, node) == AstVisitor_Break)
return;
ast_expr_visit_body(v, node);
}
void ast_expr_visit_body(AstVisitor* v, AstExpr* node)
{
switch (node->ty) {
case AstExpr_Ident:
break;
case AstExpr_Str:
break;
case AstExpr_Call:
ast_expr_visit(v, node->call.expr);
for (size_t i = 0; i < node->call.args_size; ++i)
ast_expr_visit(v, node->call.args[i]);
break;
}
}