diff options
Diffstat (limited to 'src/compiler.h')
-rw-r--r-- | src/compiler.h | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/compiler.h b/src/compiler.h index 0223269..d4b9e72 100644 --- a/src/compiler.h +++ b/src/compiler.h | |||
@@ -363,6 +363,7 @@ compile_proc_call(Object *obj) { | |||
363 | compile_object(obj->tail->head); | 363 | compile_object(obj->tail->head); |
364 | context_printf(" pop rdi\n"); | 364 | context_printf(" pop rdi\n"); |
365 | context_printf(" call display\n"); | 365 | context_printf(" call display\n"); |
366 | compile_nil(); | ||
366 | } else if (sv_equal(&obj->head->text, &STRING("not"))) { | 367 | } else if (sv_equal(&obj->head->text, &STRING("not"))) { |
367 | compile_not(obj->tail); | 368 | compile_not(obj->tail); |
368 | } else if (sv_equal(&obj->head->text, &STRING("and"))) { | 369 | } else if (sv_equal(&obj->head->text, &STRING("and"))) { |
@@ -387,12 +388,18 @@ compile_proc_call(Object *obj) { | |||
387 | compile_cdr(obj->tail); | 388 | compile_cdr(obj->tail); |
388 | } else { | 389 | } else { |
389 | compile_object(obj->head); | 390 | compile_object(obj->head); |
390 | context_printf(" pop rax\n"); | 391 | size_t n_args = 0; |
392 | while (obj->tail != NULL) { | ||
393 | obj = obj->tail; | ||
394 | compile_object(obj->head); | ||
395 | n_args++; | ||
396 | } | ||
397 | context_printf(" mov rax, [rsp + %zu]\n", 8 * n_args); | ||
391 | context_printf(" mov rcx, PTR_MASK\n"); | 398 | context_printf(" mov rcx, PTR_MASK\n"); |
392 | context_printf(" and rcx, rax\n"); | 399 | context_printf(" and rcx, rax\n"); |
393 | context_printf(" mov rax, [rcx]\n"); | 400 | context_printf(" mov rax, [rcx]\n"); |
394 | context_printf(" call rax\n"); | 401 | context_printf(" call rax\n"); |
395 | // TODO: prepare call-stack with arguments etc. | 402 | context_printf(" push rax\n"); |
396 | } | 403 | } |
397 | } | 404 | } |
398 | 405 | ||
@@ -457,9 +464,22 @@ compile_lambda(Object *obj) { | |||
457 | char *name = generate_label("BDLP"); | 464 | char *name = generate_label("BDLP"); |
458 | context_printf("alignb 8\n"); | 465 | context_printf("alignb 8\n"); |
459 | context_printf("%s:\n", name); | 466 | context_printf("%s:\n", name); |
467 | |||
468 | // Initialize function call frame. | ||
469 | context_printf(" push rbp\n"); | ||
470 | context_printf(" mov rbp, rsp\n"); | ||
471 | |||
472 | // Procedure body. | ||
460 | for (size_t i = 0; i < array_size(obj->body); i++) { | 473 | for (size_t i = 0; i < array_size(obj->body); i++) { |
461 | compile_object(obj->body[i]); | 474 | compile_object(obj->body[i]); |
462 | } | 475 | } |
476 | |||
477 | // Return is stored in the `rax`. | ||
478 | context_printf(" pop rax\n"); | ||
479 | |||
480 | // Restore the previous call frame. | ||
481 | context_printf(" mov rsp, rbp\n"); | ||
482 | context_printf(" pop rbp\n"); | ||
463 | context_printf(" ret\n"); | 483 | context_printf(" ret\n"); |
464 | context_printf("\n"); | 484 | context_printf("\n"); |
465 | 485 | ||