diff options
Diffstat (limited to 'src/compile/conditionals.c')
| -rw-r--r-- | src/compile/conditionals.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/src/compile/conditionals.c b/src/compile/conditionals.c index 6071b6c4..23d2a177 100644 --- a/src/compile/conditionals.c +++ b/src/compile/conditionals.c @@ -36,19 +36,38 @@ Text_t compile_if_statement(env_t *env, ast_t *ast) { DeclareMatch(if_, ast, If); ast_t *condition = if_->condition; if (condition->tag == Declare) { - if (Match(condition, Declare)->value == NULL) code_err(condition, "This declaration must have a value"); + DeclareMatch(decl, condition, Declare); + if (decl->value == NULL) code_err(condition, "This declaration must have a value"); + env_t *truthy_scope = fresh_scope(env); - Text_t code = Texts("IF_DECLARE(", compile_statement(truthy_scope, condition), ", "); + ast_t *var = decl->var; + type_t *var_type = get_type(truthy_scope, decl->value); + + const char *name = Match(var, Var)->name; bind_statement(truthy_scope, condition); - ast_t *var = Match(condition, Declare)->var; - code = Texts(code, compile_condition(truthy_scope, var), ", "); - type_t *cond_t = get_type(truthy_scope, var); - if (cond_t->tag == OptionalType) { - set_binding(truthy_scope, Match(var, Var)->name, Match(cond_t, OptionalType)->type, - optional_into_nonnone(cond_t, compile(truthy_scope, var))); + + Text_t code = Texts("if (true) {\n", compile_statement(env, condition), // + "if (", compile_condition(truthy_scope, var), ")"); + + env_t *nonnull_scope = truthy_scope; + if (var_type->tag == OptionalType) { + nonnull_scope = fresh_scope(truthy_scope); + set_binding(nonnull_scope, name, Match(var_type, OptionalType)->type, + optional_into_nonnone(var_type, compile(truthy_scope, var))); } - code = Texts(code, compile_statement(truthy_scope, if_->body), ")"); - if (if_->else_body) code = Texts(code, "\nelse ", compile_statement(env, if_->else_body)); + + code = Texts(code, compile_block(nonnull_scope, if_->body)); + + if (if_->else_body) { + Text_t label = Texts("_falsey_", String((int64_t)(ast->start - ast->file->text))); + code = Texts(code, "else goto ", label, + ";\n" + "} else {\n", + label, ":;\n", compile_inline_block(env, if_->else_body), "}\n"); + } else { + code = Texts(code, "}\n"); + } + return code; } else { Text_t code = Texts("if (", compile_condition(env, condition), ")"); |
