summaryrefslogtreecommitdiff
path: root/src/codegen/codegen_stmt.c
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-25 10:33:34 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-25 10:33:34 +0000
commit17cc0542def402f5b0788ff9e8fe0538f81d5ddf (patch)
tree58ef40e2974cb34cae20c7da96b7de9341988c4c /src/codegen/codegen_stmt.c
parent7813a12ed59274989ce954c931bf02ebea2a0104 (diff)
Fix for #114
Diffstat (limited to 'src/codegen/codegen_stmt.c')
-rw-r--r--src/codegen/codegen_stmt.c157
1 files changed, 65 insertions, 92 deletions
diff --git a/src/codegen/codegen_stmt.c b/src/codegen/codegen_stmt.c
index 406a6e5..55a4be2 100644
--- a/src/codegen/codegen_stmt.c
+++ b/src/codegen/codegen_stmt.c
@@ -325,152 +325,125 @@ void codegen_match_internal(ParserContext *ctx, ASTNode *node, FILE *out, int us
emit_pattern_condition(ctx, c->match_case.pattern, id, has_ref_binding, out);
}
fprintf(out, ") { ");
- if (c->match_case.binding_name)
+ if (c->match_case.binding_count > 0)
{
- if (is_option)
+ for (int i = 0; i < c->match_case.binding_count; i++)
{
- if (strstr(g_config.cc, "tcc"))
+ char *bname = c->match_case.binding_names[i];
+ int is_r = c->match_case.binding_refs ? c->match_case.binding_refs[i] : 0;
+
+ if (is_option)
{
- if (c->match_case.is_ref)
+ if (strstr(g_config.cc, "tcc"))
{
- fprintf(out, "__typeof__(&_m_%d.val) %s = &_m_%d.val; ", id,
- c->match_case.binding_name, id);
+ if (is_r)
+ {
+ fprintf(out, "__typeof__(&_m_%d.val) %s = &_m_%d.val; ", id, bname, id);
+ }
+ else
+ {
+ fprintf(out, "__typeof__(_m_%d.val) %s = _m_%d.val; ", id, bname, id);
+ }
}
else
{
- fprintf(out, "__typeof__(_m_%d.val) %s = _m_%d.val; ", id,
- c->match_case.binding_name, id);
+ if (is_r)
+ {
+ fprintf(out, "ZC_AUTO %s = &_m_%d->val; ", bname, id);
+ }
+ else if (has_ref_binding)
+ {
+ fprintf(out, "ZC_AUTO %s = _m_%d->val; ", bname, id);
+ }
+ else
+ {
+ fprintf(out, "ZC_AUTO %s = _m_%d.val; ", bname, id);
+ }
}
}
- else
+ else if (is_result)
{
- if (c->match_case.is_ref)
+ char *field = "val";
+ if (strcmp(c->match_case.pattern, "Err") == 0)
{
- // _m is pointer when has_ref_binding, use ->
- fprintf(out, "ZC_AUTO %s = &_m_%d->val; ", c->match_case.binding_name, id);
+ field = "err";
}
- else if (has_ref_binding)
- {
- // _m is pointer, use -> but don't take address
- fprintf(out, "ZC_AUTO %s = _m_%d->val; ", c->match_case.binding_name, id);
- }
- else
- {
- // _m is value, use .
- fprintf(out, "ZC_AUTO %s = _m_%d.val; ", c->match_case.binding_name, id);
- }
- }
- }
- else if (is_result) // FIX: Changed 'if' to 'else if' to match original logic structure
- // if needed, but original code had implicit fallthrough checks? No,
- // checks match pattern.
- {
- if (strcmp(c->match_case.pattern, "Ok") == 0)
- {
+
if (strstr(g_config.cc, "tcc"))
{
- if (c->match_case.is_ref)
+ if (is_r)
{
- fprintf(out, "__typeof__(&_m_%d->val) %s = &_m_%d->val; ", id,
- c->match_case.binding_name, id);
+ fprintf(out, "__typeof__(&_m_%d->%s) %s = &_m_%d->%s; ", id, field,
+ bname, id, field);
}
else
{
- fprintf(out, "__typeof__(_m_%d->val) %s = _m_%d->val; ", id,
- c->match_case.binding_name, id);
+ fprintf(out, "__typeof__(_m_%d->%s) %s = _m_%d->%s; ", id, field, bname,
+ id, field);
}
}
else
{
- if (c->match_case.is_ref)
+ if (is_r)
{
- // _m is pointer when has_ref_binding, use ->
- fprintf(out, "ZC_AUTO %s = &_m_%d->val; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = &_m_%d->%s; ", bname, id, field);
}
else if (has_ref_binding)
{
- // _m is pointer, use -> but don't take address
- fprintf(out, "ZC_AUTO %s = _m_%d->val; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = _m_%d->%s; ", bname, id, field);
}
else
{
- // _m is value, use .
- fprintf(out, "ZC_AUTO %s = _m_%d.val; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = _m_%d.%s; ", bname, id, field);
}
}
}
else
{
- if (strstr(g_config.cc, "tcc"))
+ char *v = strrchr(c->match_case.pattern, '_');
+ if (v)
+ {
+ v++;
+ }
+ else
+ {
+ v = c->match_case.pattern;
+ }
+
+ if (c->match_case.binding_count > 1)
{
- if (c->match_case.is_ref)
+ // Tuple destructuring: data.Variant.vI
+ if (is_r)
{
- fprintf(out, "__typeof__(&_m_%d->err) %s = &_m_%d->err; ", id,
- c->match_case.binding_name, id);
+ fprintf(out, "ZC_AUTO %s = &_m_%d->data.%s.v%d; ", bname, id, v, i);
+ }
+ else if (has_ref_binding)
+ {
+ fprintf(out, "ZC_AUTO %s = _m_%d->data.%s.v%d; ", bname, id, v, i);
}
else
{
- fprintf(out, "__typeof__(_m_%d->err) %s = _m_%d->err; ", id,
- c->match_case.binding_name, id);
+ fprintf(out, "ZC_AUTO %s = _m_%d.data.%s.v%d; ", bname, id, v, i);
}
}
else
{
- if (c->match_case.is_ref)
+ // Single destructuring: data.Variant
+ if (is_r)
{
- // _m is pointer when has_ref_binding, use ->
- fprintf(out, "ZC_AUTO %s = &_m_%d->err; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = &_m_%d->data.%s; ", bname, id, v);
}
else if (has_ref_binding)
{
- // _m is pointer, use -> but don't take address
- fprintf(out, "ZC_AUTO %s = _m_%d->err; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = _m_%d->data.%s; ", bname, id, v);
}
else
{
- // _m is value, use .
- fprintf(out, "ZC_AUTO %s = _m_%d.err; ", c->match_case.binding_name,
- id);
+ fprintf(out, "ZC_AUTO %s = _m_%d.data.%s; ", bname, id, v);
}
}
}
}
- else
- {
- char *f = strrchr(c->match_case.pattern, '_');
- if (f)
- {
- f++;
- }
- else
- {
- f = c->match_case.pattern;
- }
- // Generic struct destructuring (for example, MyStruct_Variant)
- // Assuming data union or accessible field.
- if (c->match_case.is_ref)
- {
- // _m is pointer when has_ref_binding, use ->
- fprintf(out, "ZC_AUTO %s = &_m_%d->data.%s; ", c->match_case.binding_name, id,
- f);
- }
- else if (has_ref_binding)
- {
- // _m is pointer, use -> but don't take address
- fprintf(out, "ZC_AUTO %s = _m_%d->data.%s; ", c->match_case.binding_name, id,
- f);
- }
- else
- {
- // _m is value, use .
- fprintf(out, "ZC_AUTO %s = _m_%d.data.%s; ", c->match_case.binding_name, id, f);
- }
- }
}
// Check if body is a string literal (should auto-print).