95 lines
2.0 KiB
C

void generate(ASTNode* node) {
switch (node.kind) {
case NODE_FUNCTION:
gen_function(&node.fn);
break;
case NODE_TYPEDEF:
printf("typedef %s %s;\n", node.td.type, node.td.alias);
break;
case NODE_STRUCT:
gen_struct(&node.str);
break;
case NODE_VAR_DECL:
gen_var_decl(&node.var);
break;
case NODE_BLOCK:
gen_block(&node.block);
break;
default:
error("unsupported node");
}
}
void gen_function(FunctionNode* fn) {
if (fn->is_inline) printf("inline ");
else if (fn->is_static) printf("static ");
else if (fn->is_extern) printf("extern ");
else if (fn->is_export) printf("__attribute__((visibility(\"default\"))) ");
printf("%s %s(", fn->return_type, fn->name);
for (i = 0; i < fn->params.len; i++) {
gen_var_decl(&fn->params[i]);
if (i < fn->params.len - 1) printf(", ");
}
printf(") ");
gen_block(&fn->body);
}
void gen_block(BlockNode* block) {
printf("{\n");
for (stmt in block.statements) {
generate(stmt);
}
printf("}\n");
}
void gen_var_decl(VarDeclNode* var) {
printf("%s %s", var->type, var->name);
if (var->init != NULL) {
printf(" = ");
gen_expr(var->init);
}
printf(";");
}
void gen_struct(StructNode* str) {
printf("typedef struct {\n");
for (field in str.fields) {
printf("\t%s %s", field.type, field.name);
if (field.init != NULL) {
printf(" = ");
gen_expr(field.init);
}
printf(";\n");
}
printf("} %s;\n", str.name);
}
void gen_expr(ExprNode* expr) {
switch (expr.kind) {
case EXPR_LITERAL:
printf("%s", expr.lit.value);
break;
case EXPR_IDENTIFIER:
printf("%s", expr.ident);
break;
case EXPR_BINARY:
gen_expr(expr.bin.lhs);
printf(" %s ", expr.bin.op);
gen_expr(expr.bin.rhs);
break;
case EXPR_CALL:
printf("%s(", expr.call.callee);
for (i = 0; i < expr.call.args.len; i++) {
gen_expr(expr.call.args[i]);
if (i < expr.call.args.len - 1) printf(", ");
}
printf(")");
break;
case EXPR_CAST:
printf("(%s)", expr.cast.to_type);
gen_expr(expr.cast.value);
break;
}
}