Added some side-effecting operations for sets, for performance reasons.
[sixpic.git] / ast.scm
blob7cb1b700ae0c6ef8959b8abb81e5ca35ad31423b
1 ;;; definition of ast types
3 (define-type ast
4   extender: define-type-of-ast
5   (parent unprintable:)
6   subasts)
8 (define (link-parent! subast parent)
9   (ast-parent-set! subast parent)
10   parent)
12 (define (multi-link-parent! subasts parent)
13   (for-each (lambda (subast) (link-parent! subast parent))
14             subasts)
15   parent)
17 (define (unlink-parent! subast)
18   (let ((parent (ast-parent subast)))
19     (if (and (def-variable? subast) (def-procedure? parent))
20         (def-procedure-params-set!
21           parent
22           (remove subast (def-procedure-params parent)))
23         (ast-subasts-set!
24          parent
25          (remove subast (ast-subasts parent))))
26     (ast-parent-set! subast #f)
27     subast))
29 (define (subast1 ast) (car (ast-subasts ast)))
30 (define (subast2 ast) (cadr (ast-subasts ast)))
31 (define (subast3 ast) (caddr (ast-subasts ast)))
32 (define (subast4 ast) (cadddr (ast-subasts ast)))
34 (define-type-of-ast def
35   extender: define-type-of-def
36   id
37   unprintable:
38   refs)
40 (define-type value
41   bytes)
42 (define (new-value bytes)
43   (make-value bytes))
45 (define-type byte-cell
46   adr
47   (interferes-with unprintable:) ; these 2 are stored as sets
48   (coalesceable-with unprintable:))
49 (define (new-byte-cell)
50   (make-byte-cell #f (new-empty-set) (new-empty-set)))
51 (define (get-register n)
52   (make-byte-cell n  (new-empty-set) (new-empty-set)))
54 (define-type byte-lit
55   val)
56 (define (new-byte-lit x)
57   (make-byte-lit x))
59 (define types-bytes
60   '((void  . 0)
61     (bool  . 1)
62     (int   . 1)
63     (byte  . 1)
64     (int8  . 1)
65     (int16 . 2)
66     (int24 . 3)
67     (int32 . 4)))
69 (define (type->bytes type)
70   (cond ((assq type types-bytes)
71          => (lambda (x) (cdr x)))
72         (else (error "wrong number of bytes ?"))))
74 (define (bytes->type n)
75   (let loop ((l types-bytes))
76     (cond ((null? l)     (error (string-append "no type contains "
77                                                (number->string n)
78                                                " bytes")))
79           ((= n (cdar l)) (caar l))
80           (else (loop (cdr l))))))
82 (define (int->value n type)
83   (let ((len (type->bytes type)))
84     (let loop ((len len) (n n) (rev-bytes '()))
85       (if (= len 0)
86           (new-value (reverse rev-bytes))
87           (loop (- len 1)
88                 (arithmetic-shift n -8)
89                 (cons (new-byte-lit (modulo n 256))
90                       rev-bytes))))))
91 (define (value->int val)
92   (let loop ((bytes (reverse (value-bytes val)))
93              (n     0))
94     (if (null? bytes)
95         n
96         (loop (cdr bytes)
97               (+ (* 256 n) (byte-lit-val (car bytes)))))))
99 ;; TODO instead of carrying types around, use the length instead
100 (define (extend value type)
101   ;; literals must be extended with literal 0s, while variables must be
102   ;; extended with byte cells
103   (let* ((bytes (value-bytes value))
104          (lit?  (byte-lit? (car bytes))))
105     (let loop ((rev-bytes (reverse bytes))
106                (n         (max 0 (- (type->bytes type) (length bytes)))))
107       (if (= n 0)
108           (new-value (reverse rev-bytes))
109           (loop (cons (if lit? (new-byte-lit 0) (new-byte-cell))
110                       rev-bytes)
111                 (- n 1))))))
113 (define (alloc-value type)
114   (let ((len (type->bytes type)))
115     (let loop ((len len) (rev-bytes '()))
116       (if (= len 0)
117           (new-value (reverse rev-bytes))
118           (loop (- len 1)
119                 (cons (new-byte-cell)
120                       rev-bytes))))))
122 (define-type-of-def def-variable
123   type
124   value
125   unprintable:
126   sets)
127 (define (new-def-variable subasts id refs type value sets)
128   (multi-link-parent!
129    subasts
130    (make-def-variable #f subasts id refs type value sets)))
132 (define-type-of-def def-procedure
133   type
134   value
135   params
136   entry
137   live-after-calls) ; stored as a set
138 (define (new-def-procedure subasts id refs type value params)
139   (multi-link-parent!
140    subasts
141    (make-def-procedure #f subasts id refs type value params #f (new-empty-set))))
144 (define-type-of-ast expr
145   extender: define-type-of-expr
146   type)
148 (define-type-of-expr literal
149   val)
150 (define (new-literal type val)
151   (make-literal #f '() type val))
153 (define-type-of-expr ref
154   def-var)
155 (define (new-ref type def)
156   (make-ref #f '() type def))
158 (define-type-of-expr oper
159   op)
160 (define (new-oper subasts type op)
161   (multi-link-parent!
162    subasts
163    (make-oper #f subasts type op)))
165 (define-type-of-expr call
166   (def-proc unprintable:))
167 (define (new-call subasts type proc-def)
168   (multi-link-parent!
169    subasts
170    (make-call #f subasts type proc-def)))
172 (define-type-of-ast block
173   name) ; blocks that begin with a label have a name, the other have #f
174 (define (new-block subasts)
175   (multi-link-parent!
176    subasts
177    (make-block #f subasts #f)))
178 (define (new-named-block name subasts)
179   (multi-link-parent!
180    subasts
181    (make-block #f subasts name)))
183 (define-type-of-ast if)
184 (define (new-if subasts)
185   (multi-link-parent!
186    subasts
187    (make-if #f subasts)))
189 (define-type-of-ast switch)
190 (define (new-switch subasts)
191   (multi-link-parent!
192    subasts
193    (make-switch #f subasts)))
195 (define-type-of-ast while)
196 (define (new-while subasts)
197   (multi-link-parent!
198    subasts
199    (make-while #f subasts)))
201 (define-type-of-ast do-while)
202 (define (new-do-while subasts)
203   (multi-link-parent!
204    subasts
205    (make-do-while #f subasts)))
207 (define-type-of-ast for)
208 (define (new-for subasts)
209   (multi-link-parent!
210    subasts
211    (make-for #f subasts)))
213 (define-type-of-ast return)
214 (define (new-return subasts)
215   (multi-link-parent!
216    subasts
217    (make-return #f subasts)))
219 (define-type-of-ast break)
220 (define (new-break)
221   (make-break #f '()))
223 (define-type-of-ast continue)
224 (define (new-continue)
225   (make-continue #f '()))
227 (define-type-of-ast goto)
228 (define (new-goto label)
229   (make-goto #f (list label)))
231 (define-type-of-ast program)
232 (define (new-program subasts) ;; TODO add suport for main
233   (multi-link-parent!
234    subasts
235    (make-program #f subasts)))
237 (define-type op
238   extender: define-type-of-op
239   (six-id unprintable:)
240   id
241   unprintable:
242   type-rule
243   constant-fold
244   code-gen)
246 (define-type-of-op op1)
247 (define-type-of-op op2)
248 (define-type-of-op op3)