aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-01-09 16:40:58 +0100
committerBad Diode <bd@badd10de.dev>2022-01-09 16:40:58 +0100
commit3156265c7b2da8cc43fee996c0518ea274d39c8a (patch)
treeab284bfd6d8a3f07761858a9ec3edec0a6bf125b
parent6f5f0875685832be6efa75016a46d4c69dbcfd36 (diff)
downloadbdl-ir.tar.gz
bdl-ir.zip
Add support for captured loads inside lambdasir
-rw-r--r--src/ir.h24
-rw-r--r--src/parser.c2
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
377compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) { 377compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) {
378 if (IS_BUILTIN(obj->head)) { 378 if (IS_BUILTIN(obj->head)) {
379 compile_builtin(program, proc, obj); 379 compile_builtin(program, proc, obj);
380 } else if (IS_LAMBDA(obj->head)) { 380 } else {
381 // FIXME: Setup stack parameter order and call convention.
382 Object *tail = obj->tail; 381 Object *tail = obj->tail;
383 while (tail != NULL) { 382 while (tail != NULL) {
384 compile_object(program, proc, tail->head); 383 compile_object(program, proc, tail->head);
@@ -386,8 +385,6 @@ compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) {
386 } 385 }
387 compile_object(program, proc, obj->head); 386 compile_object(program, proc, obj->head);
388 INST_SIMPLE(proc, OP_CALL, obj->line, obj->col); 387 INST_SIMPLE(proc, OP_CALL, obj->line, obj->col);
389 } else {
390 assert(false && "compile_proc_call: not implemented");
391 } 388 }
392} 389}
393 390
@@ -451,8 +448,10 @@ compile_lambda(ProgramIr *program, Procedure *proc, Object *obj) {
451 if (IS_BUILTIN(last_expr->head)) { 448 if (IS_BUILTIN(last_expr->head)) {
452 compile_builtin(program, lambda, last_expr); 449 compile_builtin(program, lambda, last_expr);
453 } else { 450 } else {
454 // Discard the previous stack frame. 451 // TODO: Discard the previous stack frame.
455 // context_printf(" mov rsp, rbp\n"); 452 // context_printf(" mov rsp, rbp\n");
453 // TODO: Replace stack frame instead of compiling a new one.
454 compile_proc_call(program, lambda, last_expr);
456 455
457 // size_t old_offset = n_locals + n_captured + n_params; 456 // size_t old_offset = n_locals + n_captured + n_params;
458 // size_t new_offset = compile_call_body(last_expr); 457 // size_t new_offset = compile_call_body(last_expr);
@@ -493,7 +492,7 @@ compile_lambda(ProgramIr *program, Procedure *proc, Object *obj) {
493} 492}
494 493
495void 494void
496compile_symbol(ProgramIr *program, Procedure *proc, Object *obj) { 495compile_symbol(Procedure *proc, Object *obj) {
497 ssize_t idx = -1; 496 ssize_t idx = -1;
498 497
499 // Is a local variable? 498 // Is a local variable?
@@ -517,7 +516,11 @@ compile_symbol(ProgramIr *program, Procedure *proc, Object *obj) {
517 return; 516 return;
518 } 517 }
519 518
520 assert(idx != -1 && "unexpected index"); 519 // Not in this scope, if is in another scope, it must be captured. Since we
520 // perform semantic analysis before this should always be true in this
521 // phase.
522 array_push(proc->captured, obj);
523 INST_VAR(proc, OP_LOAD_CAPTURED, array_size(proc->captured) - 1, obj->line, obj->col);
521} 524}
522 525
523void 526void
@@ -532,12 +535,9 @@ compile_object(ProgramIr *program, Procedure *proc, Object *obj) {
532 case OBJ_TYPE_IF: { compile_if(program, proc, obj); } break; 535 case OBJ_TYPE_IF: { compile_if(program, proc, obj); } break;
533 case OBJ_TYPE_LAMBDA: { compile_lambda(program, proc, obj); } break; 536 case OBJ_TYPE_LAMBDA: { compile_lambda(program, proc, obj); } break;
534 case OBJ_TYPE_DEF: { compile_def(program, proc, obj); } break; 537 case OBJ_TYPE_DEF: { compile_def(program, proc, obj); } break;
535 case OBJ_TYPE_SYMBOL: { compile_symbol(program, proc, obj); } break; 538 case OBJ_TYPE_SYMBOL: { compile_symbol(proc, obj); } break;
536 default: { 539 default: {
537 // TODO: assert? 540 assert(false && "compile_object not implemented");
538 fprintf(stderr, "NOT IMPLEMENTED: compile_object for ");
539 OBJ_PRINT(obj);
540 exit(-1);
541 } break; 541 } break;
542 } 542 }
543} 543}
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) {
528 ssize_t idx = find_var_index(cur_env->locals, obj); 528 ssize_t idx = find_var_index(cur_env->locals, obj);
529 if (idx != -1) { 529 if (idx != -1) {
530 found = cur_env->local_values[idx]; 530 found = cur_env->local_values[idx];
531 if (cur_env != env && cur_env->parent != NULL) { 531 if (cur_env != env) {
532 insert_captured(env, obj); 532 insert_captured(env, obj);
533 } 533 }
534 break; 534 break;