-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile.scm
101 lines (90 loc) · 2.48 KB
/
compile.scm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(use matchable)
(define (tail? next)
(eq? (car next) 'return))
(define (vm-compile x next)
(cond [(symbol? x)
(list 'refer x next)]
[(pair? x)
(match x
[('quote obj)
(list 'constant obj next)]
[('lambda vars body)
(list 'close vars (vm-compile body '(return)) next)]
[('if test then els)
(let ([thenc (vm-compile then next)]
[elsec (vm-compile els next)])
(vm-compile test (list 'test thenc elsec)))]
[('set! var x)
(vm-compile x (list 'assign var next))]
[('call/cc x)
(let ([c (list 'conti
(list 'argument
(vm-compile x '(apply))))])
(if (tail? next)
c
(list 'frame next c)))]
[else
(let loop ([args (cdr x)]
[c (vm-compile (car x) '(apply))])
(if (null? args)
(if (tail? next)
c
(list 'frame next c))
(loop (cdr args)
(vm-compile (car args)
(list 'argument c)))))])]
[else
(list 'constant x next)]))
(define (lookup var e)
(let nxtrib ([e e])
(let nxtelt ([vars (caar e)]
[vals (cdar e)])
(cond
[(null? vars) (nxtrib (cdr e))]
[(eq? (car vars) var) vals]
[else (nxtelt (cdr vars) (cdr vals))]))))
(define (extend e vars vals)
(cons (cons vars vals) e))
(define (closure body e vars)
(list body e vars))
(define (continuation s)
(closure (list 'nuate s 'v) '() '(v)))
(define (call-frame x e r s)
(list x e r s))
;; (record (var ...) val exp ...) −→
;; (apply (lambda (var ...) exp ...) val)
(define-syntax record
(syntax-rules ()
[(_ (var ...) val expr ...)
(apply (lambda (var ...) expr ...) val)]))
(define (VM a x e r s)
(printf "a: ~A\nx: ~A\ne: ~A\nr: ~A\ns: ~A\n\n" a x e r s)
(match x
[('halt) a]
[('refer var x)
(VM (car (lookup var e)) x e r s)]
[('constant obj x)
(VM obj x e r s)]
[('close vars body x)
(VM (closure body e vars) x e r s)]
[('test then else)
(VM a (if a then else) e r s)]
[('assign var x)
(set-car! (lookup var e) a)
(VM a x e r s)]
[('conti x)
(VM (continuation s) x e r s)]
[('nuate s var)
(VM (car (lookup var e)) '(return) e r s)]
[('frame ret x)
(VM a x e '() (call-frame ret e r s))]
[('argument x)
(VM a x e (cons a r) s)]
[('apply)
(record (body e vars) a
(VM a body (extend e vars r) '() s))]
[('return)
(record (x e r s) s
(VM a x e r s))]))
(define (vm-eval x)
(VM '() (vm-compile x '(halt)) '() '() '()))