95 lines
2.0 KiB
C
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;
|
|
}
|
|
}
|