-
Notifications
You must be signed in to change notification settings - Fork 0
/
secd-vm.lisp
149 lines (121 loc) · 4.13 KB
/
secd-vm.lisp
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(uiop/package:define-package :secd-vm/secd-vm
(:nicknames)
(:use :cl)
(:shadow)
(:export :make-vm :vm-run :vm-step :vm)
(:intern))
(in-package :secd-vm/secd-vm)
;;don't edit above
(defun ld (s e c d)
(destructuring-bind (i &rest cr) (cdr c)
(list (cons (nth (cdr i) (nth (car i) e)) s) e cr d)))
(defun ldc (s e c d)
(destructuring-bind (x &rest cr) (cdr c)
(list (cons x s) e cr d)))
(defun ldf (s e c d)
(destructuring-bind (cf &rest cr) (cdr c)
(list (cons (cons cf e) s) e cr d)))
(defun ap (s e c d)
(let ((cr (cdr c))
(cfe2 (car s)))
(destructuring-bind (cf &rest e2) cfe2
(destructuring-bind (v &rest s2) (cdr s)
(list nil (cons v e2) cf (append (list s2 e cr) d))))))
(defun rtn (s e c d)
(destructuring-bind (s2 e2 c2 &rest d2) d
(list (cons (car s) s2) e2 c2 d2)))
(defun dum (s e c d)
(list s (cons nil e) (cdr c) d))
(defun rap (s e c d)
(let ((cr (cdr c))
(cfe2 (car s)))
(destructuring-bind (cf &rest e2) cfe2
(destructuring-bind (v &rest s2) (cdr s)
(setf (car e2) v)
(list nil e2 cf (append (list s2 (cdr e) cr) d))))))
(defun sel (s e c d)
(destructuring-bind (ct cf &rest cr) (cdr c)
(list (cdr s) e (if (car s) ct cf) (cons cr d))))
(defun join (s e c d)
(list s e (car d) (cdr d)))
(defun vm-nil (s e c d)
(list (cons nil s) e (cdr c) d))
(defun vm-car (s e c d)
(list (cons (car (car s)) (cdr s)) e (cdr c) d))
(defun vm-cdr (s e c d)
(list (cons (cdr (car s)) (cdr s)) e (cdr c) d))
(defun vm-cons (s e c d)
(list (cons (cons (car s) (cadr s)) (cddr s)) e (cdr c) d))
(defun vm-eq (s e c d)
(list (cons (eq (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-less (s e c d)
(list (cons (< (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-add (s e c d)
(list (cons (+ (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-sub (s e c d)
(list (cons (- (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-mul (s e c d)
(list (cons (* (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-div (s e c d)
(list (cons (floor (cadr s) (car s)) (cddr s)) e (cdr c) d))
(defun vm-rem (s e c d)
(list (cons (cadr (multiple-value-list (floor (cadr s) (car s))))
(cddr s))
e (cdr c) d))
(defun vm-atom (s e c d)
(list (cons (atom (car s)) (cdr s)) e (cdr c) d))
(defun vm-symbolp (s e c d)
(list (cons (symbolp (car s)) (cdr s)) e (cdr c) d))
(defun vm-integerp (s e c d)
(list (cons (integerp (car s)) (cdr s)) e (cdr c) d))
(defun vm (s e c d)
(cond
;; instructions
((and (null c) (null d))
(values (car s) t))
((null c) (rtn s e c d))
((eq (car c) nil) (vm-nil s e c d))
((eq (car c) :ld) (ld s e c d))
((eq (car c) :ldc) (ldc s e c d))
((eq (car c) :ldf) (ldf s e c d))
((eq (car c) :ap) (ap s e c d))
((eq (car c) :rtn) (rtn s e c d))
((eq (car c) :dum) (dum s e c d))
((eq (car c) :rap) (rap s e c d))
((eq (car c) :sel) (sel s e c d))
((eq (car c) :join) (join s e c d))
;; basic function
((eq (car c) :car) (vm-car s e c d))
((eq (car c) :cdr) (vm-cdr s e c d))
((eq (car c) :cons) (vm-cons s e c d))
((eq (car c) :eq) (vm-eq s e c d))
((eq (car c) :less) (vm-less s e c d))
((eq (car c) :add) (vm-add s e c d))
((eq (car c) :sub) (vm-sub s e c d))
((eq (car c) :mul) (vm-mul s e c d))
((eq (car c) :div) (vm-div s e c d))
((eq (car c) :rem) (vm-rem s e c d))
((eq (car c) :atom) (vm-atom s e c d))
((eq (car c) :symbolp) (vm-symbolp s e c d))
((eq (car c) :integerp) (vm-integerp s e c d))
(t (error "~{~A ~}" (list s e c d)))))
(defun vm-step (secd)
(destructuring-bind (s e c d) secd
(vm s e c d)))
(defun vm-run (s e c d)
(do ((state (list s e c d))
(stop nil))
(stop state)
(multiple-value-bind (next-state stop?) (vm-step state)
(setf state next-state)
(setf stop stop?))))
(defun make-vm (c)
(let ((state (list nil nil c nil))
(stop nil))
(lambda ()
(if stop
state
(multiple-value-bind (next-state stop?) (vm-step state)
(setf state next-state)
(setf stop stop?)
state)))))