From 3156265c7b2da8cc43fee996c0518ea274d39c8a Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 9 Jan 2022 16:40:58 +0100 Subject: Add support for captured loads inside lambdas --- src/ir.h | 24 ++++++++++++------------ src/parser.c | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ir.h b/src/ir.h index 1c7a6c8..1a258e8 100644 --- a/src/ir.h +++ b/src/ir.h @@ -377,8 +377,7 @@ void compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) { if (IS_BUILTIN(obj->head)) { compile_builtin(program, proc, obj); - } else if (IS_LAMBDA(obj->head)) { - // FIXME: Setup stack parameter order and call convention. + } else { Object *tail = obj->tail; while (tail != NULL) { compile_object(program, proc, tail->head); @@ -386,8 +385,6 @@ compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) { } compile_object(program, proc, obj->head); INST_SIMPLE(proc, OP_CALL, obj->line, obj->col); - } else { - assert(false && "compile_proc_call: not implemented"); } } @@ -451,8 +448,10 @@ compile_lambda(ProgramIr *program, Procedure *proc, Object *obj) { if (IS_BUILTIN(last_expr->head)) { compile_builtin(program, lambda, last_expr); } else { - // Discard the previous stack frame. + // TODO: Discard the previous stack frame. // context_printf(" mov rsp, rbp\n"); + // TODO: Replace stack frame instead of compiling a new one. + compile_proc_call(program, lambda, last_expr); // size_t old_offset = n_locals + n_captured + n_params; // size_t new_offset = compile_call_body(last_expr); @@ -493,7 +492,7 @@ compile_lambda(ProgramIr *program, Procedure *proc, Object *obj) { } void -compile_symbol(ProgramIr *program, Procedure *proc, Object *obj) { +compile_symbol(Procedure *proc, Object *obj) { ssize_t idx = -1; // Is a local variable? @@ -517,7 +516,11 @@ compile_symbol(ProgramIr *program, Procedure *proc, Object *obj) { return; } - assert(idx != -1 && "unexpected index"); + // Not in this scope, if is in another scope, it must be captured. Since we + // perform semantic analysis before this should always be true in this + // phase. + array_push(proc->captured, obj); + INST_VAR(proc, OP_LOAD_CAPTURED, array_size(proc->captured) - 1, obj->line, obj->col); } void @@ -532,12 +535,9 @@ compile_object(ProgramIr *program, Procedure *proc, Object *obj) { case OBJ_TYPE_IF: { compile_if(program, proc, obj); } break; case OBJ_TYPE_LAMBDA: { compile_lambda(program, proc, obj); } break; case OBJ_TYPE_DEF: { compile_def(program, proc, obj); } break; - case OBJ_TYPE_SYMBOL: { compile_symbol(program, proc, obj); } break; + case OBJ_TYPE_SYMBOL: { compile_symbol(proc, obj); } break; default: { - // TODO: assert? - fprintf(stderr, "NOT IMPLEMENTED: compile_object for "); - OBJ_PRINT(obj); - exit(-1); + assert(false && "compile_object not implemented"); } break; } } diff --git a/src/parser.c b/src/parser.c index f6f5f41..a5e2b42 100644 --- a/src/parser.c +++ b/src/parser.c @@ -528,7 +528,7 @@ semantic_analysis(Environment *env, Object *obj, Errors *errors) { ssize_t idx = find_var_index(cur_env->locals, obj); if (idx != -1) { found = cur_env->local_values[idx]; - if (cur_env != env && cur_env->parent != NULL) { + if (cur_env != env) { insert_captured(env, obj); } break; -- cgit v1.2.1