diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-05-01 13:53:51 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-05-01 13:53:51 -0400 |
| commit | c2daf6a92895d9835ecf75118f7fa1f25ff0395f (patch) | |
| tree | 98786db0bd2246874e362475bca5da5a95d15c77 /compile.c | |
| parent | e3ad5fdaaae075b4080c86bd243f5c7f3b09972b (diff) | |
Clean up 'when' syntax
Diffstat (limited to 'compile.c')
| -rw-r--r-- | compile.c | 24 |
1 files changed, 20 insertions, 4 deletions
@@ -182,10 +182,26 @@ CORD compile_statement(env_t *env, ast_t *ast) } assert(tag_type); env_t *scope = env; - if (clause->var) { - code = CORD_all(code, compile_type(env, tag_type), " ", compile(env, clause->var), " = subject.", clause_tag_name, ";\n"); - scope = fresh_scope(env); - set_binding(scope, Match(clause->var, Var)->name, new(binding_t, .type=tag_type)); + + auto tag_struct = Match(tag_type, StructType); + if (clause->args && !clause->args->next && tag_struct->fields && tag_struct->fields->next) { + code = CORD_all(code, compile_type(env, tag_type), " ", compile(env, clause->args->ast), " = subject.", clause_tag_name, ";\n"); + scope = fresh_scope(scope); + set_binding(scope, Match(clause->args->ast, Var)->name, new(binding_t, .type=tag_type)); + } else if (clause->args) { + scope = fresh_scope(scope); + ast_list_t *var = clause->args; + arg_t *field = tag_struct->fields; + while (var || field) { + if (!var) + code_err(clause->tag_name, "The field %T.%s.%s wasn't accounted for", subject_t, clause_tag_name, field->name); + if (!field) + code_err(var->ast, "This is one more field than %T has", subject_t); + code = CORD_all(code, compile_type(env, field->type), " ", compile(env, var->ast), " = subject.", clause_tag_name, ".", field->name, ";\n"); + set_binding(scope, Match(var->ast, Var)->name, new(binding_t, .type=field->type)); + var = var->next; + field = field->next; + } } code = CORD_all(code, compile_statement(scope, clause->body), "\nbreak;\n}\n"); } |
