par2serial-cc / src /ast.c
clarenceleo's picture
Add ast.c - AST construction and debug printing
a791cbc verified
Raw
History Blame Contribute Delete
8.58 kB
/*
* par2serial-cc: ast.c - AST construction and debug printing
*/
#include "ast.h"
ASTNode *ast_new(Arena *a, NodeType type, SourceLoc loc) {
ASTNode *n = (ASTNode *)arena_alloc(a, sizeof(ASTNode));
memset(n, 0, sizeof(ASTNode));
n->type = type;
n->loc = loc;
return n;
}
ASTType *ast_new_type(Arena *a, TypeKind kind) {
ASTType *t = (ASTType *)arena_alloc(a, sizeof(ASTType));
memset(t, 0, sizeof(ASTType));
t->kind = kind;
t->array_size = -1;
return t;
}
ASTType *ast_ptr_type(Arena *a, ASTType *base) {
ASTType *t = ast_new_type(a, TYPE_POINTER);
t->base = base;
return t;
}
ASTType *ast_array_type(Arena *a, ASTType *base, int size) {
ASTType *t = ast_new_type(a, TYPE_ARRAY);
t->base = base;
t->array_size = size;
return t;
}
/* ── String representations ──────────────────────────────── */
const char *node_type_str(NodeType t) {
static const char *names[] = {
[NODE_PROGRAM]="Program", [NODE_FUNC_DECL]="FuncDecl",
[NODE_VAR_DECL]="VarDecl", [NODE_PARAM]="Param",
[NODE_STRUCT_DECL]="StructDecl",
[NODE_BLOCK]="Block", [NODE_EXPR_STMT]="ExprStmt",
[NODE_IF]="If", [NODE_WHILE]="While", [NODE_DO_WHILE]="DoWhile",
[NODE_FOR]="For", [NODE_RETURN]="Return",
[NODE_BREAK]="Break", [NODE_CONTINUE]="Continue",
[NODE_BINARY]="Binary", [NODE_UNARY]="Unary",
[NODE_POSTFIX]="Postfix", [NODE_ASSIGN]="Assign",
[NODE_TERNARY]="Ternary", [NODE_CALL]="Call",
[NODE_INDEX]="Index", [NODE_MEMBER]="Member",
[NODE_ARROW]="Arrow", [NODE_CAST]="Cast",
[NODE_SIZEOF]="Sizeof", [NODE_IDENT]="Ident",
[NODE_INT_LIT]="IntLit", [NODE_FLOAT_LIT]="FloatLit",
[NODE_STRING_LIT]="StringLit", [NODE_CHAR_LIT]="CharLit",
[NODE_COMMA_EXPR]="CommaExpr",
[NODE_ADDR_OF]="AddrOf", [NODE_DEREF]="Deref",
[NODE_PARALLEL_FOR]="ParallelFor",
[NODE_PARALLEL_REDUCE]="ParallelReduce",
[NODE_PARALLEL_SCAN]="ParallelScan",
[NODE_PARALLEL_MAP]="ParallelMap",
[NODE_BARRIER]="Barrier",
[NODE_SHARED_DECL]="SharedDecl",
[NODE_TILE_HINT]="TileHint",
[NODE_SIMD_HINT]="SimdHint",
[NODE_MEMORY_LAYOUT]="MemoryLayout",
[NODE_ATOMIC_ADD]="AtomicAdd",
[NODE_ATOMIC_CAS]="AtomicCAS",
[NODE_PREPROC]="Preproc",
};
if (t >= 0 && t < NODE_TYPE_COUNT && names[t]) return names[t];
return "Unknown";
}
const char *op_type_str(OpType op) {
static const char *ops[] = {
[OP_ADD]="+", [OP_SUB]="-", [OP_MUL]="*", [OP_DIV]="/", [OP_MOD]="%",
[OP_AND]="&", [OP_OR]="|", [OP_XOR]="^", [OP_NOT]="~", [OP_LNOT]="!",
[OP_LSHIFT]="<<", [OP_RSHIFT]=">>",
[OP_EQ]="==", [OP_NEQ]="!=", [OP_LT]="<", [OP_GT]=">",
[OP_LE]="<=", [OP_GE]=">=", [OP_LAND]="&&", [OP_LOR]="||",
[OP_NEG]="-", [OP_POS]="+", [OP_INC]="++", [OP_DEC]="--",
[OP_POST_INC]="(post)++", [OP_POST_DEC]="(post)--",
[OP_ASSIGN]="=",
[OP_ADD_ASSIGN]="+=", [OP_SUB_ASSIGN]="-=",
[OP_MUL_ASSIGN]="*=", [OP_DIV_ASSIGN]="/=",
[OP_MOD_ASSIGN]="%=", [OP_AND_ASSIGN]="&=",
[OP_OR_ASSIGN]="|=", [OP_XOR_ASSIGN]="^=",
[OP_LSHIFT_ASSIGN]="<<=", [OP_RSHIFT_ASSIGN]=">>=",
[OP_COMMA]=",",
};
return ops[op];
}
/* ── Pretty printer ──────────────────────────────────────── */
static void indent(int level) {
for (int i = 0; i < level; i++) printf(" ");
}
void ast_print(ASTNode *node, int ind) {
if (!node) { indent(ind); printf("(null)\n"); return; }
indent(ind);
printf("%s", node_type_str(node->type));
switch (node->type) {
case NODE_PROGRAM:
printf(" (%zu decls)\n", node->program.decls.len);
for (size_t i = 0; i < node->program.decls.len; i++)
ast_print(node->program.decls.data[i], ind + 1);
break;
case NODE_FUNC_DECL:
printf(" '%s' (%zu params)\n", node->func.name, node->func.params.len);
for (size_t i = 0; i < node->func.params.len; i++)
ast_print(node->func.params.data[i], ind + 1);
if (node->func.body)
ast_print(node->func.body, ind + 1);
break;
case NODE_VAR_DECL:
printf(" '%s'", node->var.name);
if (node->var.init) { printf(" =\n"); ast_print(node->var.init, ind + 1); }
else printf("\n");
break;
case NODE_PARAM:
printf(" '%s'\n", node->param.name);
break;
case NODE_BLOCK:
printf(" (%zu stmts)\n", node->block.stmts.len);
for (size_t i = 0; i < node->block.stmts.len; i++)
ast_print(node->block.stmts.data[i], ind + 1);
break;
case NODE_IF:
printf("\n");
indent(ind + 1); printf("cond:\n"); ast_print(node->if_stmt.cond, ind + 2);
indent(ind + 1); printf("then:\n"); ast_print(node->if_stmt.then_body, ind + 2);
if (node->if_stmt.else_body) {
indent(ind + 1); printf("else:\n"); ast_print(node->if_stmt.else_body, ind + 2);
}
break;
case NODE_FOR:
printf("\n");
if (node->for_stmt.init) { indent(ind+1); printf("init:\n"); ast_print(node->for_stmt.init, ind+2); }
if (node->for_stmt.cond) { indent(ind+1); printf("cond:\n"); ast_print(node->for_stmt.cond, ind+2); }
if (node->for_stmt.step) { indent(ind+1); printf("step:\n"); ast_print(node->for_stmt.step, ind+2); }
indent(ind+1); printf("body:\n"); ast_print(node->for_stmt.body, ind+2);
break;
case NODE_WHILE:
case NODE_DO_WHILE:
printf("\n");
ast_print(node->while_stmt.cond, ind + 1);
ast_print(node->while_stmt.body, ind + 1);
break;
case NODE_RETURN:
printf("\n");
if (node->ret.value) ast_print(node->ret.value, ind + 1);
break;
case NODE_EXPR_STMT:
printf("\n");
ast_print(node->expr_stmt.expr, ind + 1);
break;
case NODE_BINARY:
printf(" '%s'\n", op_type_str(node->binary.op));
ast_print(node->binary.left, ind + 1);
ast_print(node->binary.right, ind + 1);
break;
case NODE_UNARY:
printf(" '%s'\n", op_type_str(node->unary.op));
ast_print(node->unary.operand, ind + 1);
break;
case NODE_ASSIGN:
printf(" '%s'\n", op_type_str(node->assign.op));
ast_print(node->assign.target, ind + 1);
ast_print(node->assign.value, ind + 1);
break;
case NODE_CALL:
printf("\n");
indent(ind + 1); printf("func:\n"); ast_print(node->call.func, ind + 2);
for (size_t i = 0; i < node->call.args.len; i++) {
indent(ind + 1); printf("arg %zu:\n", i);
ast_print(node->call.args.data[i], ind + 2);
}
break;
case NODE_INDEX:
printf("\n");
ast_print(node->index.array, ind + 1);
ast_print(node->index.index, ind + 1);
break;
case NODE_IDENT:
printf(" '%s'\n", node->ident.name);
break;
case NODE_INT_LIT:
printf(" %ld\n", (long)node->int_lit.value);
break;
case NODE_FLOAT_LIT:
printf(" %g\n", node->float_lit.value);
break;
case NODE_STRING_LIT:
printf(" \"%s\"\n", node->string_lit.value);
break;
case NODE_PARALLEL_FOR:
printf(" iter='%s'\n", node->par_for.iter_var);
indent(ind+1); printf("lo:\n"); ast_print(node->par_for.lo, ind+2);
indent(ind+1); printf("hi:\n"); ast_print(node->par_for.hi, ind+2);
indent(ind+1); printf("body:\n"); ast_print(node->par_for.body, ind+2);
break;
case NODE_PARALLEL_REDUCE:
printf(" accum='%s' iter='%s'\n", node->par_reduce.accum_var, node->par_reduce.iter_var);
indent(ind+1); printf("lo:\n"); ast_print(node->par_reduce.lo, ind+2);
indent(ind+1); printf("hi:\n"); ast_print(node->par_reduce.hi, ind+2);
indent(ind+1); printf("body:\n"); ast_print(node->par_reduce.body, ind+2);
break;
case NODE_TILE_HINT:
printf(" target='%s' size=%d\n", node->tile_hint.target, node->tile_hint.tile_size);
break;
case NODE_SIMD_HINT:
printf(" target='%s'\n", node->simd_hint.target);
break;
case NODE_PREPROC:
printf(" '%s'\n", node->preproc.text);
break;
default:
printf("\n");
break;
}
}