ソースを参照

Merge branch 'cons'

Lucas Stadler 8 年 前
コミット
bedec509e3
共有3 個のファイルを変更した67 個の追加14 個の削除を含む
  1. 24 0
      scm/inc/compiler.scm
  2. 42 13
      scm/inc/driver.c
  3. 1 1
      scm/inc/program.scm

+ 24 - 0
scm/inc/compiler.scm

@ -159,11 +159,35 @@
159 159
     (emit "movl %eax, ~a(%rsp)" si) ; move second arg on the stack
160 160
     (emit-expr (primcall-operand1 x) (- si wordsize) env)
161 161
     (emit "addl ~a(%rsp), %eax" si))
162
    ((cons)
163
     (emit-expr (primcall-operand1 x) si env)
164
     (emit "movl %eax, 0(%rsi)") ; set the car
165
     (emit-expr (primcall-operand2 x) si env)
166
     (emit "movl %eax, 4(%rsi)") ; set the cdr
167
     (emit "movq %rsi, %rax") ; rax = rsi | 1  (cons cell/pair tag)
168
     (emit "orq  $~a, %rax" #b001)
169
     (emit "addq $8,  %rsi")) ; bump rsi
170
    ((car)
171
     (emit-expr (primcall-operand1 x) si env)
172
     (emit "movl -1(%rax), %eax"))
173
    ((cdr)
174
     (emit-expr (primcall-operand1 x) si env)
175
     (emit "movl 3(%rax), %eax"))
176
    ((cddr)
177
     (emit-expr (primcall-operand1 x) si env)
178
     (emit "movl 3(%rax), %eax")
179
     (emit "movl 3(%rax), %eax"))
180
    ((cddar)
181
     (emit-expr (primcall-operand1 x) si env)
182
     (emit "movl 3(%rax), %eax")
183
     (emit "movl 3(%rax), %eax")
184
     (emit "movl -1(%rax), %eax"))
162 185
    ))
163 186
164 187
(define (compile-program x)
165 188
  (display ".globl scheme_entry\n\n")
166 189
  (display "scheme_entry:\n")
167 190
191
  (emit "movq %rax, %rsi") ; store pointer to heap memory
168 192
  (emit-expr x (- wordsize) '())
169 193
  (emit "ret"))

+ 42 - 13
scm/inc/driver.c

@ -1,6 +1,8 @@
1 1
/* a simple driver for scheme_entry */
2 2
3 3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
4 6
5 7
#define fixnum_mask  3 // 11
6 8
#define fixnum_tag   0 // 00
@ -16,21 +18,48 @@
16 18
17 19
#define empty_list   47 // 00101111
18 20
19
int scheme_entry();
21
#define cons_tag  1 // 001
22
#define cons_mask 7 // 111
20 23
21
int main(int argc, char **argv) {
22
	int val = scheme_entry();
23
	if ((val & fixnum_mask) == fixnum_tag) {
24
		printf("%d\n", val >> fixnum_shift);
25
	} else if ((val & char_mask) == char_tag) {
26
		printf("#\\%c\n", val >> char_shift);
27
	} else if ((val & boolean_mask) == boolean_tag) {
28
		printf("#%s\n", (val >> boolean_shift) == 1 ? "t" : "f");
29
	} else if (val == empty_list) {
30
		printf("()\n");
24
#define MAX_MEMORY (1 << 20)
25
26
int scheme_entry(int *memory);
27
28
int print_hex(int i) {
29
	printf("0x%x\n", i);
30
	return i;
31
}
32
33
void print_value(int *val) {
34
	if ((*val & fixnum_mask) == fixnum_tag) {
35
		printf("%d", *val >> fixnum_shift);
36
	} else if ((*val & char_mask) == char_tag) {
37
		printf("#\\%c", *val >> char_shift);
38
	} else if ((*val & boolean_mask) == boolean_tag) {
39
		printf("#%s", (*val >> boolean_shift) == 1 ? "t" : "f");
40
	} else if (*val == empty_list) {
41
		printf("()");
42
	} else if ((*val & cons_mask) == cons_tag) {
43
		printf("(");
44
		printf("?");
45
		printf(" ");
46
		printf("?");
47
		printf(")");
31 48
	} else {
32
		printf("Error: unhandled value: %d\n", val);
33
		return 1;
49
		printf("\nError: unhandled value: %d 0x%x 0x%p\n", *val, *val, val);
50
		exit(1);
51
	}
52
}
53
54
int main(int argc, char **argv) {
55
	int *mem = (int*)malloc(MAX_MEMORY * sizeof(int));
56
	if (mem == NULL) {
57
		perror("malloc");
58
		exit(1);
34 59
	}
60
	memset(mem, 0, MAX_MEMORY * sizeof(int));
61
	int val = scheme_entry(mem);
62
	print_value(&val);
63
	printf("\n");
35 64
	return 0;
36 65
}

+ 1 - 1
scm/inc/program.scm

@ -1,3 +1,3 @@
1 1
(load "compiler.scm")
2 2
3
(compile-program '(let ((x 3) (y 4)) (if (integer? (+ x y)) 42 #f)))
3
(compile-program '(cons 10 20))