diff options
| author | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-17 00:10:30 +0000 |
|---|---|---|
| committer | Zuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian> | 2026-01-17 00:10:30 +0000 |
| commit | ea160abc678e9578b5e140121a6d7c59a3b9dd06 (patch) | |
| tree | 0ae4d0ed1449f74d6cc361a5f8787892c0789168 /src/codegen | |
| parent | a5d5a97818fb4fbd26c4fb25a5c410b1a60a1b18 (diff) | |
Improved struct pointer codegen, template instantiation and docs...
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/codegen.c | 91 | ||||
| -rw-r--r-- | src/codegen/codegen.h | 2 | ||||
| -rw-r--r-- | src/codegen/codegen_decl.c | 12 | ||||
| -rw-r--r-- | src/codegen/codegen_utils.c | 96 |
4 files changed, 150 insertions, 51 deletions
diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index d308662..62f3126 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -596,7 +596,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out) fprintf(out, "; "); Type *ft = node->call.callee->type_info; - char *ret = type_to_string(ft->inner); + char *ret = codegen_type_to_string(ft->inner); if (strcmp(ret, "string") == 0) { free(ret); @@ -606,7 +606,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out) fprintf(out, "((%s (*)(void*", ret); for (int i = 0; i < ft->arg_count; i++) { - char *as = type_to_string(ft->args[i]); + char *as = codegen_type_to_string(ft->args[i]); fprintf(out, ", %s", as); free(as); } @@ -792,7 +792,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out) char *tname = "unknown"; if (node->type_info && node->type_info->inner) { - tname = type_to_string(node->type_info->inner); + tname = codegen_type_to_string(node->type_info->inner); } fprintf(out, "({ "); @@ -1021,7 +1021,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out) Type *t = node->reflection.target_type; if (node->reflection.kind == 0) { // @type_name - char *s = type_to_string(t); + char *s = codegen_type_to_string(t); fprintf(out, "\"%s\"", s); free(s); } @@ -1112,7 +1112,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out) int free_ret = 0; if (node->type_info) { - char *t = type_to_string(node->type_info); + char *t = codegen_type_to_string(node->type_info); if (t) { ret_type = t; @@ -1378,7 +1378,8 @@ void codegen_node_single(ParserContext *ctx, ASTNode *node, FILE *out) { fprintf(out, "inline "); } - fprintf(out, "%s %s(%s)\n", node->func.ret_type, node->func.name, node->func.args); + emit_func_signature(out, node, NULL); + fprintf(out, "\n"); fprintf(out, "{\n"); char *prev_ret = g_current_func_ret_type; g_current_func_ret_type = node->func.ret_type; @@ -1527,10 +1528,10 @@ void codegen_node_single(ParserContext *ctx, ASTNode *node, FILE *out) } { char *tname = NULL; - Type *tinfo = node->var_decl.type_info; - if (tinfo && tinfo->name) + // Use type_info with codegen_type_to_string if available + if (node->type_info) { - tname = tinfo->name; + tname = codegen_type_to_string(node->type_info); } else if (node->var_decl.type_str && strcmp(node->var_decl.type_str, "__auto_type") != 0) { @@ -1539,55 +1540,61 @@ void codegen_node_single(ParserContext *ctx, ASTNode *node, FILE *out) if (tname) { + // Cleanup attribute ASTNode *def = find_struct_def(ctx, tname); if (def && def->type_info && def->type_info->has_drop) { fprintf(out, "__attribute__((cleanup(%s__Drop_glue))) ", tname); } - } - } - if (node->var_decl.type_str && strcmp(node->var_decl.type_str, "__auto_type") != 0) - { - emit_var_decl_type(ctx, out, node->var_decl.type_str, node->var_decl.name); - add_symbol(ctx, node->var_decl.name, node->var_decl.type_str, node->var_decl.type_info); - if (node->var_decl.init_expr) - { - fprintf(out, " = "); - codegen_expression(ctx, node->var_decl.init_expr, out); - } - fprintf(out, ";\n"); - } - else - { - char *inferred = NULL; - if (node->var_decl.init_expr) - { - inferred = infer_type(ctx, node->var_decl.init_expr); - } - if (inferred && strcmp(inferred, "__auto_type") != 0) - { - emit_var_decl_type(ctx, out, inferred, node->var_decl.name); - add_symbol(ctx, node->var_decl.name, inferred, NULL); + // Emit Variable with Type + emit_var_decl_type(ctx, out, tname, node->var_decl.name); + add_symbol(ctx, node->var_decl.name, tname, node->type_info); + + if (node->var_decl.init_expr) + { + fprintf(out, " = "); + codegen_expression(ctx, node->var_decl.init_expr, out); + } + fprintf(out, ";\n"); + + if (node->type_info) + { + free(tname); // Free if allocated by codegen_type_to_string + } } else { - emit_auto_type(ctx, node->var_decl.init_expr, node->token, out); - fprintf(out, " %s", node->var_decl.name); + // Inference Fallback + char *inferred = NULL; + if (node->var_decl.init_expr) + { + inferred = infer_type(ctx, node->var_decl.init_expr); + } - if (inferred) + if (inferred && strcmp(inferred, "__auto_type") != 0) { + emit_var_decl_type(ctx, out, inferred, node->var_decl.name); add_symbol(ctx, node->var_decl.name, inferred, NULL); + fprintf(out, " = "); + codegen_expression(ctx, node->var_decl.init_expr, out); + fprintf(out, ";\n"); } else { - // Here we are cooked. + emit_auto_type(ctx, node->var_decl.init_expr, node->token, out); + fprintf(out, " %s", node->var_decl.name); + + if (inferred) + { + add_symbol(ctx, node->var_decl.name, inferred, NULL); + } + + fprintf(out, " = "); + codegen_expression(ctx, node->var_decl.init_expr, out); + fprintf(out, ";\n"); } } - - fprintf(out, " = "); - codegen_expression(ctx, node->var_decl.init_expr, out); - fprintf(out, ";\n"); } break; case NODE_CONST: @@ -1981,7 +1988,7 @@ void codegen_node_single(ParserContext *ctx, ASTNode *node, FILE *out) int free_ret = 0; if (node->type_info) { - char *t = type_to_string(node->type_info); + char *t = codegen_type_to_string(node->type_info); if (t) { ret_type = t; diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index 4b66f99..45a00ed 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -22,6 +22,8 @@ void emit_var_decl_type(ParserContext *ctx, FILE *out, const char *type_str, con char *replace_string_type(const char *args); const char *parse_original_method_name(const char *mangled); void emit_auto_type(ParserContext *ctx, ASTNode *init_expr, Token t, FILE *out); +char *codegen_type_to_string(Type *t); +void emit_func_signature(FILE *out, ASTNode *func, const char *name_override); // Declaration emission (codegen_decl.c). void emit_preamble(ParserContext *ctx, FILE *out); diff --git a/src/codegen/codegen_decl.c b/src/codegen/codegen_decl.c index fe2829e..18e6987 100644 --- a/src/codegen/codegen_decl.c +++ b/src/codegen/codegen_decl.c @@ -170,7 +170,7 @@ void emit_enum_protos(ASTNode *node, FILE *out) { if (v->variant.payload) { - char *tstr = type_to_string(v->variant.payload); + char *tstr = codegen_type_to_string(v->variant.payload); fprintf(out, "%s %s_%s(%s v);\n", node->enm.name, node->enm.name, v->variant.name, tstr); free(tstr); @@ -306,7 +306,7 @@ void emit_struct_defs(ParserContext *ctx, ASTNode *node, FILE *out) { if (v->variant.payload) { - char *tstr = type_to_string(v->variant.payload); + char *tstr = codegen_type_to_string(v->variant.payload); fprintf(out, "%s %s; ", tstr, v->variant.name); free(tstr); } @@ -318,7 +318,7 @@ void emit_struct_defs(ParserContext *ctx, ASTNode *node, FILE *out) { if (v->variant.payload) { - char *tstr = type_to_string(v->variant.payload); + char *tstr = codegen_type_to_string(v->variant.payload); fprintf(out, "%s %s_%s(%s v) { return (%s){.tag=%s_%s_Tag, " ".data.%s=v}; }\n", @@ -498,7 +498,8 @@ void emit_protos(ASTNode *node, FILE *out) } else { - fprintf(out, "%s %s(%s);\n", f->func.ret_type, f->func.name, f->func.args); + emit_func_signature(out, f, NULL); + fprintf(out, ";\n"); } } else if (f->type == NODE_IMPL) @@ -574,7 +575,8 @@ void emit_protos(ASTNode *node, FILE *out) } else { - fprintf(out, "%s %s(%s);\n", m->func.ret_type, proto, m->func.args); + emit_func_signature(out, m, proto); + fprintf(out, ";\n"); } free(proto); diff --git a/src/codegen/codegen_utils.c b/src/codegen/codegen_utils.c index acb09fe..392557f 100644 --- a/src/codegen/codegen_utils.c +++ b/src/codegen/codegen_utils.c @@ -137,7 +137,7 @@ char *infer_type(ParserContext *ctx, ASTNode *node) } if (sym->type_info) { - return type_to_string(sym->type_info); + return codegen_type_to_string(sym->type_info); } } } @@ -155,7 +155,7 @@ char *infer_type(ParserContext *ctx, ASTNode *node) } if (sig->ret_type) { - return type_to_string(sig->ret_type); + return codegen_type_to_string(sig->ret_type); } } @@ -198,7 +198,7 @@ char *infer_type(ParserContext *ctx, ASTNode *node) FuncSig *sig = find_func(ctx, func_name); if (sig && sig->ret_type) { - return type_to_string(sig->ret_type); + return codegen_type_to_string(sig->ret_type); } } } @@ -368,7 +368,7 @@ char *infer_type(ParserContext *ctx, ASTNode *node) FuncSig *sig = find_func(ctx, node->unary.operand->call.callee->var_ref.name); if (sig && sig->ret_type) { - return type_to_string(sig->ret_type); + return codegen_type_to_string(sig->ret_type); } } @@ -519,3 +519,91 @@ void emit_auto_type(ParserContext *ctx, ASTNode *init_expr, Token t, FILE *out) } } } +// C-compatible type stringifier for codegen. +// Identical to type_to_string but strictly uses 'struct T' for structs to support +// external/non-typedef'd types. +char *codegen_type_to_string(Type *t) +{ + return type_to_c_string(t); +} + +// Emit function signature using Type info for correct C codegen +void emit_func_signature(FILE *out, ASTNode *func, const char *name_override) +{ + if (!func || func->type != NODE_FUNCTION) + { + return; + } + + // Return type + char *ret_str; + if (func->func.ret_type_info) + { + ret_str = codegen_type_to_string(func->func.ret_type_info); + } + else if (func->func.ret_type) + { + ret_str = xstrdup(func->func.ret_type); + } + else + { + ret_str = xstrdup("void"); + } + + fprintf(out, "%s %s(", ret_str, name_override ? name_override : func->func.name); + free(ret_str); + + // Args + if (func->func.arg_count == 0 && !func->func.is_varargs) + { + fprintf(out, "void"); + } + else + { + for (int i = 0; i < func->func.arg_count; i++) + { + if (i > 0) + { + fprintf(out, ", "); + } + + char *type_str = NULL; + if (func->func.arg_types && func->func.arg_types[i]) + { + type_str = codegen_type_to_string(func->func.arg_types[i]); + } + else + { + type_str = xstrdup("void*"); // Fallback + } + + const char *name = ""; + if (func->func.param_names && func->func.param_names[i]) + { + name = func->func.param_names[i]; + } + + // check if array type + char *bracket = strchr(type_str, '['); + if (bracket) + { + int base_len = bracket - type_str; + fprintf(out, "%.*s %s%s", base_len, type_str, name, bracket); + } + else + { + fprintf(out, "%s %s", type_str, name); + } + free(type_str); + } + if (func->func.is_varargs) + { + if (func->func.arg_count > 0) + { + fprintf(out, ", "); + } + fprintf(out, "..."); + } + } + fprintf(out, ")"); +} |
