diff options
author | Bad Diode <bd@badd10de.dev> | 2021-11-15 22:47:37 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-11-15 22:47:37 +0100 |
commit | 3331c755238e2a12d738ea804232274e1ce4cfc9 (patch) | |
tree | 1773c7c12beaf65ce3e9220eedbe28f05f236e0f | |
parent | 62984fb580b9e355cf9eacf9de53bff8c895c0b5 (diff) | |
download | bdl-3331c755238e2a12d738ea804232274e1ce4cfc9.tar.gz bdl-3331c755238e2a12d738ea804232274e1ce4cfc9.zip |
Add workaround for `void` return in function calls
-rw-r--r-- | src/compiler.h | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/src/compiler.h b/src/compiler.h index e91798a..e198127 100644 --- a/src/compiler.h +++ b/src/compiler.h | |||
@@ -358,8 +358,6 @@ compile_call(Object *obj) { | |||
358 | 358 | ||
359 | // Restore stack to previous location and store the result on top. | 359 | // Restore stack to previous location and store the result on top. |
360 | context_printf(" add rsp, %zu\n", 8 * (n_args + 1)); | 360 | context_printf(" add rsp, %zu\n", 8 * (n_args + 1)); |
361 | // TODO: Handle the case where the function doesn't return anything, for | ||
362 | // example if the last parameter is (display ...) or (def ...). | ||
363 | context_printf(" push rax\n"); | 361 | context_printf(" push rax\n"); |
364 | context_printf(" ;; <-- compile_call\n"); | 362 | context_printf(" ;; <-- compile_call\n"); |
365 | } | 363 | } |
@@ -489,9 +487,19 @@ compile_lambda(Object *obj) { | |||
489 | context_printf(" mov rbp, rsp\n"); | 487 | context_printf(" mov rbp, rsp\n"); |
490 | 488 | ||
491 | // Procedure body. | 489 | // Procedure body. |
492 | for (size_t i = 0; i < array_size(obj->body); i++) { | 490 | // In case the last expression of a function doesn't return anything (e.g. |
491 | // a `def` or `display` primitive), we store a sentinel `nil` value at the | ||
492 | // end of the stack. | ||
493 | // | ||
494 | // NOTE: This is probably better handled by a type system that | ||
495 | // allows functions to return void, but right now the caller and function | ||
496 | // creation expect that all functions return values. Failure to comply with | ||
497 | // this convention will result in a corrupted stack. | ||
498 | for (size_t i = 0; i < array_size(obj->body) - 1; i++) { | ||
493 | compile_object(obj->body[i]); | 499 | compile_object(obj->body[i]); |
494 | } | 500 | } |
501 | compile_nil(); | ||
502 | compile_object(obj->body[array_size(obj->body) - 1]); | ||
495 | 503 | ||
496 | // Return is stored in the `rax`. | 504 | // Return is stored in the `rax`. |
497 | context_printf(" pop rax\n"); | 505 | context_printf(" pop rax\n"); |