summaryrefslogtreecommitdiff
path: root/src/codegen/codegen.c
diff options
context:
space:
mode:
authorSAJJA EASWAR <eshwarsajja20@gmail.com>2026-01-25 22:59:36 +0530
committerSAJJA EASWAR <eshwarsajja20@gmail.com>2026-01-25 22:59:36 +0530
commitebc8b94baa6bc694cb4829e2eb2934a1f17fa6a1 (patch)
tree71b952ad455bf17d5bdea01472f0e2297f25eabe /src/codegen/codegen.c
parent863118c95caac0d69a35f6ae4d2e83844734a8a1 (diff)
parent489336b2101bf16edeec7bfc4379408eb19b936e (diff)
Merge branch 'main' into pr-109
Diffstat (limited to 'src/codegen/codegen.c')
-rw-r--r--src/codegen/codegen.c180
1 files changed, 162 insertions, 18 deletions
diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c
index 706d613..7c58943 100644
--- a/src/codegen/codegen.c
+++ b/src/codegen/codegen.c
@@ -14,19 +14,19 @@
// Emit literal expression (int, float, string, char)
static void codegen_literal_expr(ASTNode *node, FILE *out)
{
- if (node->literal.type_kind == TOK_STRING)
+ if (node->literal.type_kind == LITERAL_STRING)
{
fprintf(out, "\"%s\"", node->literal.string_val);
}
- else if (node->literal.type_kind == TOK_CHAR)
+ else if (node->literal.type_kind == LITERAL_CHAR)
{
fprintf(out, "%s", node->literal.string_val);
}
- else if (node->literal.type_kind == 1) // float
+ else if (node->literal.type_kind == LITERAL_FLOAT)
{
fprintf(out, "%f", node->literal.float_val);
}
- else // int
+ else // LITERAL_INT
{
if (node->literal.int_val > 9223372036854775807ULL)
{
@@ -34,7 +34,7 @@ static void codegen_literal_expr(ASTNode *node, FILE *out)
}
else
{
- fprintf(out, "%llu", (unsigned long long)node->literal.int_val);
+ fprintf(out, "%lld", (long long)node->literal.int_val);
}
}
}
@@ -56,7 +56,7 @@ static void codegen_var_expr(ParserContext *ctx, ASTNode *node, FILE *out)
if (node->resolved_type && strcmp(node->resolved_type, "unknown") == 0)
{
- if (node->var_ref.suggestion)
+ if (node->var_ref.suggestion && !ctx->silent_warnings)
{
char msg[256];
sprintf(msg, "Undefined variable '%s'", node->var_ref.name);
@@ -289,9 +289,22 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
else
{
fprintf(out, "(");
- codegen_expression(ctx, node->binary.left, out);
+ int is_assignment =
+ (node->binary.op[strlen(node->binary.op) - 1] == '=' &&
+ strcmp(node->binary.op, "==") != 0 && strcmp(node->binary.op, "!=") != 0 &&
+ strcmp(node->binary.op, "<=") != 0 && strcmp(node->binary.op, ">=") != 0);
+
+ if (is_assignment)
+ {
+ codegen_expression(ctx, node->binary.left, out);
+ }
+ else
+ {
+ codegen_expression_with_move(ctx, node->binary.left, out);
+ }
+
fprintf(out, " %s ", node->binary.op);
- codegen_expression(ctx, node->binary.right, out);
+ codegen_expression_with_move(ctx, node->binary.right, out);
fprintf(out, ")");
}
break;
@@ -328,6 +341,61 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
}
}
+ // Check for Static Enum Variant Call: Enum.Variant(...)
+ if (target->type == NODE_EXPR_VAR)
+ {
+ ASTNode *def = find_struct_def(ctx, target->var_ref.name);
+ if (def && def->type == NODE_ENUM)
+ {
+ char mangled[256];
+ sprintf(mangled, "%s_%s", target->var_ref.name, method);
+ FuncSig *sig = find_func(ctx, mangled);
+ if (sig)
+ {
+ fprintf(out, "%s(", mangled);
+ ASTNode *arg = node->call.args;
+ int arg_idx = 0;
+ while (arg)
+ {
+ if (arg_idx > 0 && arg)
+ {
+ fprintf(out, ", ");
+ }
+
+ Type *param_t =
+ (arg_idx < sig->total_args) ? sig->arg_types[arg_idx] : NULL;
+
+ // Tuple Packing Logic
+ if (param_t && param_t->kind == TYPE_STRUCT &&
+ strncmp(param_t->name, "Tuple_", 6) == 0 && sig->total_args == 1 &&
+ node->call.arg_count > 1)
+ {
+ fprintf(out, "(%s){", param_t->name);
+ int first = 1;
+ while (arg)
+ {
+ if (!first)
+ {
+ fprintf(out, ", ");
+ }
+ first = 0;
+ codegen_expression(ctx, arg, out);
+ arg = arg->next;
+ }
+ fprintf(out, "}");
+ break; // All args consumed
+ }
+
+ codegen_expression(ctx, arg, out);
+ arg = arg->next;
+ arg_idx++;
+ }
+ fprintf(out, ")");
+ return;
+ }
+ }
+ }
+
char *type = infer_type(ctx, target);
if (type)
{
@@ -353,7 +421,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
while (arg)
{
fprintf(out, ", ");
- codegen_expression(ctx, arg, out);
+ codegen_expression_with_move(ctx, arg, out);
arg = arg->next;
}
fprintf(out, "); })");
@@ -396,6 +464,32 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
ref = ref->next;
}
+ if (!resolved_method_suffix)
+ {
+ GenericImplTemplate *it = ctx->impl_templates;
+ while (it)
+ {
+ char *tname = NULL;
+ if (it->impl_node && it->impl_node->type == NODE_IMPL_TRAIT)
+ {
+ tname = it->impl_node->impl_trait.trait_name;
+ }
+ if (tname)
+ {
+ char trait_mangled[512];
+ sprintf(trait_mangled, "%s__%s_%s", base, tname, method);
+ if (find_func(ctx, trait_mangled))
+ {
+ char *suffix = xmalloc(strlen(tname) + strlen(method) + 2);
+ sprintf(suffix, "%s_%s", tname, method);
+ resolved_method_suffix = suffix;
+ break;
+ }
+ }
+ it = it->next;
+ }
+ }
+
if (resolved_method_suffix)
{
method = resolved_method_suffix;
@@ -436,7 +530,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
while (arg)
{
fprintf(out, ", ");
- codegen_expression(ctx, arg, out);
+ codegen_expression_with_move(ctx, arg, out);
arg = arg->next;
}
fprintf(out, ")");
@@ -455,7 +549,8 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
}
}
- if (node->call.callee->type_info && node->call.callee->type_info->kind == TYPE_FUNCTION)
+ if (node->call.callee->type_info && node->call.callee->type_info->kind == TYPE_FUNCTION &&
+ !node->call.callee->type_info->is_raw)
{
fprintf(out, "({ z_closure_T _c = ");
codegen_expression(ctx, node->call.callee, out);
@@ -486,7 +581,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
while (arg)
{
fprintf(out, ", ");
- codegen_expression(ctx, arg, out);
+ codegen_expression_with_move(ctx, arg, out);
arg = arg->next;
}
fprintf(out, "); })");
@@ -528,7 +623,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
fprintf(out, ", ");
}
first = 0;
- codegen_expression(ctx, arg, out);
+ codegen_expression_with_move(ctx, arg, out);
arg = arg->next;
}
}
@@ -561,18 +656,55 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
free(inner);
handled = 1;
}
+ else if (param_t && param_t->kind == TYPE_STRUCT &&
+ strncmp(param_t->name, "Tuple_", 6) == 0 && sig->total_args == 1 &&
+ node->call.arg_count > 1)
+ {
+ // Implicit Tuple Packing:
+ // Function expects 1 Tuple argument, but call has multiple args -> Pack
+ // them
+ fprintf(out, "(%s){", param_t->name);
+
+ ASTNode *curr = arg;
+ int first_field = 1;
+ while (curr)
+ {
+ if (!first_field)
+ {
+ fprintf(out, ", ");
+ }
+ first_field = 0;
+ codegen_expression_with_move(ctx, curr, out);
+ curr = curr->next;
+ }
+ fprintf(out, "}");
+ handled = 1;
+
+ // Advance main loop iterator to end
+ arg = NULL;
+ }
}
- if (!handled)
+ if (handled)
{
- codegen_expression(ctx, arg, out);
+ if (arg == NULL)
+ {
+ break; // Tuple packed all args
+ }
+ }
+ else
+ {
+ codegen_expression_with_move(ctx, arg, out);
}
- if (arg->next)
+ if (arg && arg->next)
{
fprintf(out, ", ");
}
- arg = arg->next;
+ if (arg)
+ {
+ arg = arg->next;
+ }
arg_idx++;
}
}
@@ -1033,6 +1165,7 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
}
int is_zen_struct = 0;
+ int is_union = 0;
StructRef *sr = ctx->parsed_structs_list;
while (sr)
{
@@ -1040,6 +1173,10 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
strcmp(sr->node->strct.name, struct_name) == 0)
{
is_zen_struct = 1;
+ if (sr->node->strct.is_union)
+ {
+ is_union = 1;
+ }
break;
}
sr = sr->next;
@@ -1047,7 +1184,14 @@ void codegen_expression(ParserContext *ctx, ASTNode *node, FILE *out)
if (is_zen_struct)
{
- fprintf(out, "(struct %s){", struct_name);
+ if (is_union)
+ {
+ fprintf(out, "(union %s){", struct_name);
+ }
+ else
+ {
+ fprintf(out, "(struct %s){", struct_name);
+ }
}
else
{