5 (define (define-op constructor six-id id type-rule constant-fold code-gen)
7 (cons (constructor six-id id type-rule constant-fold code-gen)
9 (define (define-op1 six-id id type-rule constant-fold code-gen)
10 (define-op make-op1 six-id id type-rule constant-fold code-gen))
11 (define (define-op2 six-id id type-rule constant-fold code-gen)
12 (define-op make-op2 six-id id type-rule constant-fold code-gen))
13 (define (define-op3 six-id id type-rule constant-fold code-gen)
14 (define-op make-op3 six-id id type-rule constant-fold code-gen))
16 ;; no need for type checks, every type sixpic supports can be casted to / from
17 ;; ints (except void, but this is a non-issue) and promotion (by padding) and
18 ;; truncation is done at the cfg level
19 (define (type-rule-int-op1 ast)
20 (expr-type (subast1 ast)))
22 (define (largest t1 t2)
23 (if (> (type->bytes t1) (type->bytes t2))
27 (define (type-rule-int-op2 ast)
28 ;; used for any binary operation involving two integers where the result is
29 ;; of the size of the biggest operand (subtraction, bitwise operations, ...)
30 (let ((t1 (expr-type (subast1 ast)))
31 (t2 (expr-type (subast2 ast))))
34 (define (type-rule-assign ast)
35 (let ((t1 (expr-type (subast1 ast))))
36 ;; the type of the rhs is irrelevant, since it will be promoted
37 ;; or truncated at the cfg level
40 ;; the standard says it should be int
41 (define (type-rule-int-comp-op2 ast)
44 (define (type-rule-bool-op2 ast)
48 (define (constant-fold-op1 op)
50 (let* ((x (subast1 ast))
51 (lx (cond ((literal? x)
55 (let ((val ((op-constant-fold op) x)))
56 (if (literal? val) val #f))))
60 (new-literal (val->type res) res))
63 (define (constant-fold-op2 op)
65 (let* ((x (subast1 ast))
67 (lx (cond ((literal? x)
71 (let ((val ((op-constant-fold op) x)))
72 (if (literal? val) val #f))))
74 (ly (cond ((literal? y)
78 (let ((val ((op-constant-fold op) y)))
79 (if (literal? val) val #f))))
82 (let ((res (op lx ly)))
83 (new-literal (val->type res) res))
86 (define-op1 'six.!x '!x
94 (define-op1 'six.++x '++x
101 (define-op1 'six.x++ 'x++
108 (define-op1 'six.--x '--x
115 (define-op1 'six.x-- 'x--
122 (define-op1 'six.~x '~x
129 (define-op2 'six.x%y 'x%y
131 (constant-fold-op2 modulo)
135 (define-op2 'six.x*y 'x*y
137 (constant-fold-op2 *)
141 (define-op1 'six.*x '*x
143 'byte) ; we only have byte arrays
149 (define-op2 'six.index 'index
151 'byte) ; we only have byte arrays
157 (define-op2 'six.x/y 'x/y
159 (constant-fold-op2 /)
163 (define-op2 'six.x+y 'x+y
165 (constant-fold-op2 +)
169 (define-op1 'six.+x '+x
176 (define-op2 'six.x-y 'x-y
178 (constant-fold-op2 -)
182 (define-op1 'six.-x '-x
184 (constant-fold-op1 (lambda (x) (- x)))
188 (define-op2 'six.x<<y 'x<<y
190 (constant-fold-op2 arithmetic-shift)
194 (define-op2 'six.x>>y 'x>>y
196 (constant-fold-op2 (lambda (x y) (arithmetic-shift x (- y))))
200 (define-op2 'six.x<y 'x<y
201 type-rule-int-comp-op2
202 (constant-fold-op2 (lambda (x y) (if (< x y) 1 0)))
206 (define-op2 'six.x<=y 'x<=y
207 type-rule-int-comp-op2
208 (constant-fold-op2 (lambda (x y) (if (<= x y) 1 0)))
212 (define-op2 'six.x>y 'x>y
213 type-rule-int-comp-op2
214 (constant-fold-op2 (lambda (x y) (if (> x y) 1 0)))
218 (define-op2 'six.x>=y 'x>=y
219 type-rule-int-comp-op2
220 (constant-fold-op2 (lambda (x y) (if (>= x y) 1 0)))
224 (define-op2 'six.x!=y 'x!=y
225 type-rule-int-comp-op2
226 (constant-fold-op2 (lambda (x y) (if (not (= x y)) 1 0)))
230 (define-op2 'six.x==y 'x==y
231 type-rule-int-comp-op2
232 (constant-fold-op2 (lambda (x y) (if (= x y) 1 0)))
236 (define-op2 'six.x&y 'x&y
238 (constant-fold-op2 bitwise-and)
242 (define-op1 'six.&x '&x
250 (define-op2 'six.x^y 'x^y
252 (constant-fold-op2 bitwise-xor)
256 (define-op2 '|six.x\|y| '|x\|y|
258 (constant-fold-op2 bitwise-ior)
262 (define-op2 'six.x&&y 'x&&y
264 (constant-fold-op2 (lambda (x y) (if (and (not (= x 0)) (not (= y 0))) 1 0)))
268 (define-op2 '|six.x\|\|y| '|x\|\|y|
270 (constant-fold-op2 (lambda (x y) (if (or (not (= x 0)) (not (= y 0))) 1 0)))
274 (define-op3 'six.x?y:z 'x?y:z
276 ;; largest of the 2 branches
277 (let ((t1 (expr-type (subast2 ast)))
278 (t2 (expr-type (subast3 ast))))
285 (define-op2 'six.x:y 'x:y
293 (define-op2 'six.x%=y 'x%=y
300 (define-op2 'six.x&=y 'x&=y
307 (define-op2 'six.x*=y 'x*=y
314 (define-op2 'six.x+=y 'x+=y
321 (define-op2 'six.x-=y 'x-=y
328 (define-op2 'six.x/=y 'x/=y
335 (define-op2 'six.x<<=y 'x<<=y
342 (define-op2 'six.x=y 'x=y
349 (define-op2 'six.x>>=y 'x>>=y
356 (define-op2 'six.x^=y 'x^=y
363 (define-op2 '|six.x\|=y| '|x\|=y|
370 (define-op2 'six.x:=y 'x:=y
378 (define-op2 '|six.x,y| '|x,y|
386 (define-op2 'six.x:-y 'x:-y
394 (define (operation? source)
396 (let ((x (car source)))
397 (let loop ((lst operators))
400 ((eq? (op-six-id (car lst)) x)
403 (loop (cdr lst))))))))