Browse Source

Introduce tagged literals/immediate values

We don't test values other than integers yet, but it seems to work for
those.  At least the test program prints 42 as before.
Lucas Stadler 8 years ago
parent
commit
a7a04c49b0
2 changed files with 27 additions and 2 deletions
  1. 16 1
      scm/inc/compiler.scm
  2. 11 1
      scm/inc/driver.c

+ 16 - 1
scm/inc/compiler.scm

@ -3,11 +3,26 @@
3 3
  (display (apply format instr args))
4 4
  (display "\n"))
5 5
6
(define fixnum-shift 2)
7
(define char-shift 8)
8
(define boolean-shift 7)
9
6 10
(define (compile-program x)
11
  (define (immediate-rep x)
12
    (cond
13
      ((integer? x) (bitwise-arithmetic-shift x fixnum-shift))
14
      ((char? x) (bitwise-xor (bitwise-arithmetic-shift (char->integer x) 8) char-shift))
15
      ((boolean? x) (bitwise-xor (bitwise-arithmetic-shift (cond
16
                                                             ((boolean=? x #t) 1)
17
                                                             ((boolean=? x #f) 0))
18
                                                           boolean-shift)
19
                                 #b0011111))
20
      ((eq? x '()) #b00101111)))
21
7 22
  (display ".globl scheme_entry\n\n")
8 23
  (display "scheme_entry:\n")
9 24
10
  (emit "movl $~a, %eax" x)
25
  (emit "movl $~a, %eax" (immediate-rep x))
11 26
  (emit "ret"))
12 27
13 28
(compile-program 42)

+ 11 - 1
scm/inc/driver.c

@ -2,9 +2,19 @@
2 2
3 3
#include <stdio.h>
4 4
5
#define fixnum_mask  3 // 11
6
#define fixnum_tag   0 // 00
7
#define fixnum_shift 2
8
5 9
int scheme_entry();
6 10
7 11
int main(int argc, char **argv) {
8
	printf("%d\n", scheme_entry());
12
	int val = scheme_entry();
13
	if ((val & fixnum_mask) == fixnum_tag) {
14
		printf("%d\n", val >> fixnum_shift);
15
	} else {
16
		printf("Error: unhandled value: %d\n", val);
17
		return 1;
18
	}
9 19
	return 0;
10 20
}