diff options
author | Bad Diode <bd@badd10de.dev> | 2022-01-09 16:40:58 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-01-09 16:40:58 +0100 |
commit | 3156265c7b2da8cc43fee996c0518ea274d39c8a (patch) | |
tree | ab284bfd6d8a3f07761858a9ec3edec0a6bf125b | |
parent | 6f5f0875685832be6efa75016a46d4c69dbcfd36 (diff) | |
download | bdl-ir.tar.gz bdl-ir.zip |
Add support for captured loads inside lambdasir
-rw-r--r-- | src/ir.h | 24 | ||||
-rw-r--r-- | src/parser.c | 2 |
2 files changed, 13 insertions, 13 deletions
@@ -377,8 +377,7 @@ void | |||
377 | compile_proc_call(ProgramIr *program, Procedure *proc, Object *obj) { | 377 | compile_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 | ||
495 | void | 494 | void |
496 | compile_symbol(ProgramIr *program, Procedure *proc, Object *obj) { | 495 | compile_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 | ||
523 | void | 526 | void |
@@ -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; |