summaryrefslogtreecommitdiff
path: root/src/codegen/codegen_utils.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-22 02:59:58 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-22 03:00:08 +0000
commitbb44db8e61a40d4fcd31a87140f3c61aed551a2c (patch)
tree7a79a68508e78e7c8f10913fa98a47075b962db5 /src/codegen/codegen_utils.c
parentf912e071eaaa362b369626d7312589d4c9ac311b (diff)
This one is big, it solves several bugs that were not detected.
Diffstat (limited to 'src/codegen/codegen_utils.c')
-rw-r--r--src/codegen/codegen_utils.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/src/codegen/codegen_utils.c b/src/codegen/codegen_utils.c
index f712ca4..e490789 100644
--- a/src/codegen/codegen_utils.c
+++ b/src/codegen/codegen_utils.c
@@ -26,8 +26,20 @@ void emit_var_decl_type(ParserContext *ctx, FILE *out, const char *type_str, con
(void)ctx;
char *bracket = strchr(type_str, '[');
+ char *generic = strchr(type_str, '<');
- if (bracket)
+ if (generic && (!bracket || generic < bracket))
+ {
+ // Strip generic part for C output
+ int base_len = generic - type_str;
+ fprintf(out, "%.*s %s", base_len, type_str, var_name);
+
+ if (bracket)
+ {
+ fprintf(out, "%s", bracket);
+ }
+ }
+ else if (bracket)
{
int base_len = bracket - type_str;
fprintf(out, "%.*s %s%s", base_len, type_str, var_name, bracket);
@@ -116,7 +128,8 @@ char *infer_type(ParserContext *ctx, ASTNode *node)
{
return NULL;
}
- if (node->resolved_type && strcmp(node->resolved_type, "unknown") != 0)
+ if (node->resolved_type && strcmp(node->resolved_type, "unknown") != 0 &&
+ strcmp(node->resolved_type, "void*") != 0)
{
return node->resolved_type;
}
@@ -155,6 +168,16 @@ char *infer_type(ParserContext *ctx, ASTNode *node)
{
if (sig->is_async)
{
+ if (sig->ret_type)
+ {
+ char *inner = codegen_type_to_string(sig->ret_type);
+ if (inner)
+ {
+ char *buf = xmalloc(strlen(inner) + 10);
+ sprintf(buf, "Async<%s>", inner);
+ return buf;
+ }
+ }
return "Async";
}
if (sig->ret_type)
@@ -365,7 +388,28 @@ char *infer_type(ParserContext *ctx, ASTNode *node)
if (node->type == NODE_AWAIT)
{
// Infer underlying type T from await Async<T>
- // If it's a direct call await foo(), we know T from foo's signature.
+ // Check operand type for Generics <T>
+ char *op_type = infer_type(ctx, node->unary.operand);
+ if (op_type)
+ {
+ char *start = strchr(op_type, '<');
+ if (start)
+ {
+ start++; // Skip <
+ char *end = strrchr(op_type, '>');
+ if (end && end > start)
+ {
+ int len = end - start;
+ char *extracted = xmalloc(len + 1);
+ strncpy(extracted, start, len);
+ extracted[len] = 0;
+ return extracted;
+ }
+ }
+ }
+
+ // Fallback: If it's a direct call await foo(), we can lookup signature even if generic
+ // syntax wasn't used
if (node->unary.operand->type == NODE_EXPR_CALL &&
node->unary.operand->call.callee->type == NODE_EXPR_VAR)
{