From fedab6bac08333ca31e69f21add7b66c575ec87c Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 2 Nov 2021 14:07:46 +0100 Subject: Add compilation of `display` primitive --- src/compiler.h | 19 +++++++++++++++++++ src/parser.c | 3 +++ src/x86_64/postlude.asm | 24 +----------------------- src/x86_64/prelude.asm | 30 +++++++++++++++++++++--------- 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/compiler.h b/src/compiler.h index 76d6ccf..18e8a3e 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -139,6 +139,12 @@ compile_type_predicate(OpType op, Object* args) { printf(" ;; <-- compile_type_predicate\n"); } + +// TODO: Next -> numerical comparison operators =, <=, ... +// "=", "<", ">", "<=", ">=", +// "not", "and", "or", +// NOTE: Make sure to stop evaluating if the condition is not met. + void compile_arithmetic_list(OpType op, Object* args) { printf(" ;; --> compile_arithmetic_list\n"); @@ -183,6 +189,11 @@ compile_proc_call(Object *obj) { if (sv_equal(&obj->head->text, &STRING("bool?"))) { compile_type_predicate(OP_IS_BOOL, obj->tail); } + if (sv_equal(&obj->head->text, &STRING("display"))) { + compile_object(obj->tail->head); + printf(" pop rdi\n"); + printf(" call display\n"); + } } void @@ -199,6 +210,14 @@ compile_object(Object *obj) { void compile(Root *roots) { + printf("%%define NIL_VAL %d\n", NIL_VAL); + printf("%%define BOOL_MASK %d\n", BOOL_MASK); + printf("%%define BOOL_TAG %d\n", BOOL_TAG); + printf("%%define BOOL_SHIFT %d\n", BOOL_SHIFT); + printf("%%define FIXNUM_MASK %d\n", FIXNUM_MASK); + printf("%%define FIXNUM_TAG %d\n", FIXNUM_TAG); + printf("%%define FIXNUM_SHIFT %d\n", FIXNUM_SHIFT); + printf("\n"); emit_file(PRELUDE_FILE); for (size_t i = 0; i < array_size(roots); i++) { Object *root = roots[i]; diff --git a/src/parser.c b/src/parser.c index 86cf713..9191aa2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,6 +10,7 @@ static char *builtins [] = { "=", "<", ">", "<=", ">=", "not", "and", "or", "nil?", "zero?", "fixnum?", "bool?", + "display", }; uint64_t @@ -597,6 +598,8 @@ parse(Token *tokens, Errors *errors) { array_free(roots); roots = final_roots; + // TODO: Check if primitive procedures have been given the right number of + // arguments. // TODO: Type check basic expressions (e.g. arithmetic/numeric comparisons). // We can't be sure when we have functions unless the return type is known. diff --git a/src/x86_64/postlude.asm b/src/x86_64/postlude.asm index 5c8e56f..3355286 100644 --- a/src/x86_64/postlude.asm +++ b/src/x86_64/postlude.asm @@ -2,29 +2,7 @@ _start_return: ;; return the last value in the stack pop rdi - - ;; is nil? - mov rax, rdi - cmp rax, NIL_VAL - je exit - - ;; is boolean? - mov rax, rdi - and rax, BOOL_MASK - cmp rax, BOOL_TAG - jne not_bool - call printbool - jmp exit -not_bool: - - ;; is fixnum? - mov rax, rdi - and rax, FIXNUM_MASK - cmp rax, FIXNUM_TAG - jne not_fixnum - call printdln - jmp exit -not_fixnum: + call display exit: ; exit syscall diff --git a/src/x86_64/prelude.asm b/src/x86_64/prelude.asm index c314ba4..6bb6627 100644 --- a/src/x86_64/prelude.asm +++ b/src/x86_64/prelude.asm @@ -1,12 +1,3 @@ -;; Value types. -%define NIL_VAL 1 -%define BOOL_MASK 3 -%define BOOL_TAG 3 -%define BOOL_SHIFT 2 -%define FIXNUM_MASK 1 -%define FIXNUM_TAG 0 -%define FIXNUM_SHIFT 1 - printdln: sar rdi, FIXNUM_SHIFT sub rsp, 40 @@ -84,6 +75,27 @@ true_str: false_str: db "false", 10 +display: + ;; is nil? + mov rax, rdi + cmp rax, NIL_VAL + je display_end + + ; ;; is boolean? + mov rax, rdi + and rax, BOOL_MASK + cmp rax, BOOL_TAG + jne not_bool + call printbool + ret +not_bool: + + ;; is fixnum? + mov rax, rdi + call printdln +display_end: + ret + global _start _start: push NIL_VAL -- cgit v1.2.1