summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson@vistahigherlearning.com>2022-08-10 18:49:33 -0400
committerDavid Thompson <dthompson@vistahigherlearning.com>2022-08-10 18:50:10 -0400
commit9f65c417b7575eab5ebd2733a817a0f0e954c4d9 (patch)
tree8343f16a11a92a8eefb35095bf5cfbdf7cf44997
parentc441f8f092cd5da5b09e3e4e826141d915189ab5 (diff)
Step 2: Immediate Constants
-rw-r--r--compiler.scm19
-rw-r--r--test.c27
2 files changed, 44 insertions, 2 deletions
diff --git a/compiler.scm b/compiler.scm
index 1285ac6..919be4c 100644
--- a/compiler.scm
+++ b/compiler.scm
@@ -5,6 +5,23 @@
(newline))
(define (compile-program x)
+ (define fixnum-shift 2)
+ (define fixnum-tag 0)
+ (define char-shift 8)
+ (define char-tag 15)
+ (define boolean-shift 7)
+ (define boolean-tag 31)
+ (define empty-list 47) ;; #b00101111
+ (define (immediate-rep x)
+ (cond
+ ((integer? x)
+ (ash x fixnum-shift))
+ ((char? x)
+ (logior (ash (char->integer x) char-shift) char-tag))
+ ((boolean? x)
+ (logior (ash (if x 1 0) boolean-shift) boolean-tag))
+ ((null? x)
+ empty-list)))
(with-output-to-file "scheme_entry.S"
(lambda ()
(display ".text
@@ -13,5 +30,5 @@
.type scheme_entry, @function
scheme_entry:
")
- (emit "movl $~a, %eax" x)
+ (emit "movl $~a, %eax" (immediate-rep x))
(emit "ret"))))
diff --git a/test.c b/test.c
index 2d814e0..f41ae64 100644
--- a/test.c
+++ b/test.c
@@ -1,6 +1,31 @@
#include <stdio.h>
+#define fixnum_mask 3
+#define fixnum_tag 0
+#define fixnum_shift 2
+#define char_mask 255
+#define char_shift 8
+#define char_tag 15
+#define boolean_mask 127
+#define boolean_shift 7
+#define boolean_tag 31
+#define empty_list 47
+
int main(int argc, char** argv) {
- printf("%d\n", scheme_entry());
+ int val = scheme_entry();
+
+ if((val & fixnum_mask) == fixnum_tag) {
+ printf("%d\n", val >> fixnum_shift);
+ } else if((val & char_mask) == char_tag) {
+ printf("%c\n", val >> char_shift);
+ } else if((val & boolean_mask) == boolean_tag) {
+ if((val >> boolean_shift) == 1) {
+ printf("#t\n");
+ } else {
+ printf("#f\n");
+ }
+ } else if(val == empty_list) {
+ printf("()\n");
+ }
return 0;
}