|
|
@ -43,50 +43,91 @@
|
|
43
|
43
|
(emit "sall $~a, %eax" boolean-shift) ; construct correctly tagged boolean value
|
|
44
|
44
|
(emit "xorl $~a, %eax" #b0011111))
|
|
45
|
45
|
|
|
46
|
|
(define (emit-expr x si)
|
|
|
46
|
(define (variable? x) (symbol? x))
|
|
|
47
|
|
|
|
48
|
(define (let? x)
|
|
|
49
|
(and (list? x) (eq? (car x) 'let) (list? (cadr x)) (list? (caadr x))))
|
|
|
50
|
|
|
|
51
|
(define (emit-expr x si env)
|
|
47
|
52
|
(cond
|
|
48
|
53
|
((immediate? x)
|
|
49
|
54
|
(emit "movl $~a, %eax" (immediate-rep x)))
|
|
50
|
|
((primcall? x) (emit-primitive-call x si))))
|
|
|
55
|
((variable? x)
|
|
|
56
|
(emit "movl ~a(%rsp), %eax" (lookup x env)))
|
|
|
57
|
((let? x)
|
|
|
58
|
(emit-let (bindings x) (body x) si env))
|
|
|
59
|
((primcall? x) (emit-primitive-call x si env))))
|
|
|
60
|
|
|
|
61
|
(define (lookup x env)
|
|
|
62
|
(cond
|
|
|
63
|
((null? env) (error 'lookup (format "~a is undefined" x)))
|
|
|
64
|
((eq? x (caar env)) (cadar env))
|
|
|
65
|
(else (lookup x (cdr env)))))
|
|
|
66
|
|
|
|
67
|
(define (bindings let-expr) (cadr let-expr))
|
|
|
68
|
(define (body let-expr) (caddr let-expr))
|
|
|
69
|
|
|
|
70
|
(define (extend-env name val env)
|
|
|
71
|
(cons (cons name (cons val '())) env))
|
|
|
72
|
|
|
|
73
|
(define (emit-let bindings body si env)
|
|
|
74
|
(let f ((b* bindings) (new-env env) (si si))
|
|
|
75
|
(cond
|
|
|
76
|
; if we're done with the bindings, emit the code for the body
|
|
|
77
|
((null? b*) (emit-expr body si new-env))
|
|
|
78
|
; otherwise, continue evaluating bindings in sequence
|
|
|
79
|
(else
|
|
|
80
|
(let ((b (car b*))) ; current binding
|
|
|
81
|
; emit code for current binding
|
|
|
82
|
(emit-expr (rhs b) si env)
|
|
|
83
|
; move it onto the stack
|
|
|
84
|
(emit "movl %eax, ~a(%rsp)" si)
|
|
|
85
|
; store current binding in env, continue generating bindings
|
|
|
86
|
(f (cdr b*)
|
|
|
87
|
(extend-env (lhs b) si new-env)
|
|
|
88
|
(- si wordsize)))))))
|
|
|
89
|
|
|
|
90
|
(define (lhs binding) (car binding))
|
|
|
91
|
(define (rhs binding) (cadr binding))
|
|
51
|
92
|
|
|
52
|
|
(define (emit-primitive-call x si)
|
|
|
93
|
(define (emit-primitive-call x si env)
|
|
53
|
94
|
(case (primcall-op x)
|
|
54
|
95
|
((add1)
|
|
55
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
96
|
(emit-expr (primcall-operand1 x) si env)
|
|
56
|
97
|
(emit "addl $~a, %eax" (immediate-rep 1)))
|
|
57
|
98
|
((integer->char)
|
|
58
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
99
|
(emit-expr (primcall-operand1 x) si env)
|
|
59
|
100
|
(emit "shl $6, %eax")
|
|
60
|
101
|
(emit "xorl $15, %eax"))
|
|
61
|
102
|
((char->integer)
|
|
62
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
103
|
(emit-expr (primcall-operand1 x) si env)
|
|
63
|
104
|
(emit "shrl $6, %eax"))
|
|
64
|
105
|
((zero?)
|
|
65
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
106
|
(emit-expr (primcall-operand1 x) si env)
|
|
66
|
107
|
(emit "cmpl $0, %eax") ; x == 0
|
|
67
|
108
|
(emit-compare))
|
|
68
|
109
|
((null?)
|
|
69
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
110
|
(emit-expr (primcall-operand1 x) si env)
|
|
70
|
111
|
(emit "cmpl $~a, %eax" #b00101111)
|
|
71
|
112
|
(emit-compare))
|
|
72
|
113
|
((integer?)
|
|
73
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
114
|
(emit-expr (primcall-operand1 x) si env)
|
|
74
|
115
|
(emit "andl $~a, %eax" #b11)
|
|
75
|
116
|
(emit-compare))
|
|
76
|
117
|
((char?)
|
|
77
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
118
|
(emit-expr (primcall-operand1 x) si env)
|
|
78
|
119
|
(emit "andl $~a, %eax" #b11111111)
|
|
79
|
120
|
(emit "cmpl $~a, %eax" #b00001111)
|
|
80
|
121
|
(emit-compare))
|
|
81
|
122
|
((boolean?)
|
|
82
|
|
(emit-expr (primcall-operand1 x) si)
|
|
|
123
|
(emit-expr (primcall-operand1 x) si env)
|
|
83
|
124
|
(emit "andl $~a, %eax" #b1111111)
|
|
84
|
125
|
(emit "cmpl $~a, %eax" #b0011111)
|
|
85
|
126
|
(emit-compare))
|
|
86
|
127
|
((+)
|
|
87
|
|
(emit-expr (primcall-operand2 x) si)
|
|
|
128
|
(emit-expr (primcall-operand2 x) si env)
|
|
88
|
129
|
(emit "movl %eax, ~a(%rsp)" si) ; move second arg on the stack
|
|
89
|
|
(emit-expr (primcall-operand1 x) (- si wordsize))
|
|
|
130
|
(emit-expr (primcall-operand1 x) (- si wordsize) env)
|
|
90
|
131
|
(emit "addl ~a(%rsp), %eax" si))
|
|
91
|
132
|
))
|
|
92
|
133
|
|
|
|
@ -94,5 +135,5 @@
|
|
94
|
135
|
(display ".globl scheme_entry\n\n")
|
|
95
|
136
|
(display "scheme_entry:\n")
|
|
96
|
137
|
|
|
97
|
|
(emit-expr x (- wordsize))
|
|
|
138
|
(emit-expr x (- wordsize) '())
|
|
98
|
139
|
(emit "ret"))
|