From fc0ad68b500c0027f2f8e2814a8ba01169ee78fe Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 8 Oct 2024 21:46:09 -0400 Subject: Bugfix for reductions over conditional comprehensions that have no values. --- compile.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 9ea968a9..3018249a 100644 --- a/compile.c +++ b/compile.c @@ -3112,30 +3112,13 @@ CORD compile(env_t *env, ast_t *ast) CORD code = CORD_all( "({ // Reduction:\n", compile_declaration(t, "reduction"), ";\n" - "Bool_t is_first = yes;\n" + "Bool_t has_value = no;\n" ); env_t *scope = fresh_scope(env); - ast_t *result = FakeAST(Var, "$reduction"); set_binding(scope, "$reduction", new(binding_t, .type=t, .code="reduction")); - ast_t *empty = NULL; - if (reduction->fallback) { - type_t *fallback_type = get_type(scope, reduction->fallback); - if (fallback_type->tag == AbortType || fallback_type->tag == ReturnType) { - empty = reduction->fallback; - } else { - empty = FakeAST(Assign, .targets=new(ast_list_t, .ast=result), .values=new(ast_list_t, .ast=reduction->fallback)); - } - } else { - empty = FakeAST( - InlineCCode, - CORD_asprintf("fail_source(%r, %ld, %ld, \"This collection was empty!\");\n", - CORD_quoted(ast->file->filename), - (long)(reduction->iter->start - reduction->iter->file->text), - (long)(reduction->iter->end - reduction->iter->file->text))); - } ast_t *item = FakeAST(Var, "$iter_value"); ast_t *body = FakeAST(InlineCCode, .code="{}"); // placeholder - ast_t *loop = FakeAST(For, .vars=new(ast_list_t, .ast=item), .iter=reduction->iter, .body=body, .empty=empty); + ast_t *loop = FakeAST(For, .vars=new(ast_list_t, .ast=item), .iter=reduction->iter, .body=body); env_t *body_scope = for_scope(scope, loop); // For the special case of (or)/(and), we need to early out if we can: @@ -3149,14 +3132,29 @@ CORD compile(env_t *env, ast_t *ast) } body->__data.InlineCCode.code = CORD_all( - "if (is_first) {\n" + "if (!has_value) {\n" " reduction = ", compile(body_scope, item), ";\n" - " is_first = no;\n" + " has_value = yes;\n" "} else {\n" " reduction = ", compile(body_scope, reduction->combination), ";\n", early_out, "}\n"); - code = CORD_all(code, compile_statement(scope, loop), "\nreduction;})"); + + CORD empty_handling; + if (reduction->fallback) { + type_t *fallback_type = get_type(scope, reduction->fallback); + if (fallback_type->tag == AbortType || fallback_type->tag == ReturnType) { + empty_handling = CORD_all("if (!has_value) ", compile_statement(env, reduction->fallback), "\n"); + } else { + empty_handling = CORD_all("if (!has_value) reduction = ", compile(env, reduction->fallback), ";\n"); + } + } else { + empty_handling = CORD_asprintf("if (!has_value) fail_source(%r, %ld, %ld, \"This collection was empty!\");\n", + CORD_quoted(ast->file->filename), + (long)(reduction->iter->start - reduction->iter->file->text), + (long)(reduction->iter->end - reduction->iter->file->text)); + } + code = CORD_all(code, compile_statement(scope, loop), "\n", empty_handling, "reduction;})"); return code; } case FieldAccess: { -- cgit v1.2.3