opcodes for bit twiddling (ash, logand, logior, logxor)
[bpt/guile.git] / module / language / tree-il / primitives.scm
CommitLineData
ac4d09b1 1;;; open-coding primitive procedures
cb28c085 2
ac4d09b1 3;; Copyright (C) 2009 Free Software Foundation, Inc.
cb28c085 4
53befeb7
NJ
5;;;; This library is free software; you can redistribute it and/or
6;;;; modify it under the terms of the GNU Lesser General Public
7;;;; License as published by the Free Software Foundation; either
8;;;; version 3 of the License, or (at your option) any later version.
9;;;;
10;;;; This library is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13;;;; Lesser General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU Lesser General Public
16;;;; License along with this library; if not, write to the Free Software
17;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cb28c085
AW
18
19;;; Code:
20
55ae815b 21(define-module (language tree-il primitives)
7382f23e 22 #:use-module (system base pmatch)
39141c87 23 #:use-module (rnrs bytevector)
cb28c085
AW
24 #:use-module (system base syntax)
25 #:use-module (language tree-il)
26 #:use-module (srfi srfi-16)
55ae815b 27 #:export (resolve-primitives! add-interesting-primitive!
80af1168 28 expand-primitives! effect-free-primitive?))
55ae815b
AW
29
30(define *interesting-primitive-names*
31 '(apply @apply
32 call-with-values @call-with-values
33 call-with-current-continuation @call-with-current-continuation
34 call/cc
35 values
36 eq? eqv? equal?
37 = < > <= >= zero?
38 + * - / 1- 1+ quotient remainder modulo
b10d9330 39 ash logand logior logxor
55ae815b
AW
40 not
41 pair? null? list? acons cons cons*
42
43 list vector
44
45 car cdr
46 set-car! set-cdr!
47
48 caar cadr cdar cddr
49
50 caaar caadr cadar caddr cdaar cdadr cddar cdddr
51
52 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
d6f1ce3d
AW
53 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
54
39141c87
AW
55 vector-ref vector-set!
56
57 bytevector-u8-ref bytevector-u8-set!
58 bytevector-s8-ref bytevector-s8-set!
59
60 bytevector-u16-ref bytevector-u16-set!
61 bytevector-u16-native-ref bytevector-u16-native-set!
62 bytevector-s16-ref bytevector-s16-set!
63 bytevector-s16-native-ref bytevector-s16-native-set!
64
65 bytevector-u32-ref bytevector-u32-set!
66 bytevector-u32-native-ref bytevector-u32-native-set!
67 bytevector-s32-ref bytevector-s32-set!
68 bytevector-s32-native-ref bytevector-s32-native-set!
69
70 bytevector-u64-ref bytevector-u64-set!
71 bytevector-u64-native-ref bytevector-u64-native-set!
72 bytevector-s64-ref bytevector-s64-set!
73 bytevector-s64-native-ref bytevector-s64-native-set!
74
75 bytevector-ieee-single-ref bytevector-ieee-single-set!
76 bytevector-ieee-single-native-ref bytevector-ieee-single-native-set!
77 bytevector-ieee-double-ref bytevector-ieee-double-set!
78 bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!))
55ae815b
AW
79
80(define (add-interesting-primitive! name)
81 (hashq-set! *interesting-primitive-vars*
39141c87
AW
82 (module-variable (current-module) name)
83 name))
55ae815b
AW
84
85(define *interesting-primitive-vars* (make-hash-table))
86
87(for-each add-interesting-primitive! *interesting-primitive-names*)
88
80af1168
AW
89(define *effect-free-primitives*
90 '(values
91 eq? eqv? equal?
92 = < > <= >= zero?
93 + * - / 1- 1+ quotient remainder modulo
94 not
95 pair? null? list? acons cons cons*
96 list vector
97 car cdr
98 caar cadr cdar cddr
99 caaar caadr cadar caddr cdaar cdadr cddar cdddr
100 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
101 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
102 vector-ref
103 bytevector-u8-ref bytevector-s8-ref
104 bytevector-u16-ref bytevector-u16-native-ref
105 bytevector-s16-ref bytevector-s16-native-ref
106 bytevector-u32-ref bytevector-u32-native-ref
107 bytevector-s32-ref bytevector-s32-native-ref
108 bytevector-u64-ref bytevector-u64-native-ref
109 bytevector-s64-ref bytevector-s64-native-ref
110 bytevector-ieee-single-ref bytevector-ieee-single-native-ref
111 bytevector-ieee-double-ref bytevector-ieee-double-native-ref))
112
113
114(define *effect-free-primitive-table* (make-hash-table))
115
116(for-each (lambda (x) (hashq-set! *effect-free-primitive-table* x #t))
117 *effect-free-primitives*)
118
119(define (effect-free-primitive? prim)
120 (hashq-ref *effect-free-primitive-table* prim))
121
55ae815b
AW
122(define (resolve-primitives! x mod)
123 (post-order!
124 (lambda (x)
125 (record-case x
126 ((<toplevel-ref> src name)
c0ee3245
AW
127 (and=> (hashq-ref *interesting-primitive-vars*
128 (module-variable mod name))
129 (lambda (name) (make-primitive-ref src name))))
55ae815b
AW
130 ((<module-ref> src mod name public?)
131 ;; for the moment, we're disabling primitive resolution for
132 ;; public refs because resolve-interface can raise errors.
133 (let ((m (and (not public?) (resolve-module mod))))
c0ee3245
AW
134 (and m
135 (and=> (hashq-ref *interesting-primitive-vars*
136 (module-variable m name))
137 (lambda (name) (make-primitive-ref src name))))))
55ae815b
AW
138 (else #f)))
139 x))
140
141\f
cb28c085
AW
142
143(define *primitive-expand-table* (make-hash-table))
144
145(define (expand-primitives! x)
146 (pre-order!
147 (lambda (x)
148 (record-case x
149 ((<application> src proc args)
150 (and (primitive-ref? proc)
151 (let ((expand (hashq-ref *primitive-expand-table*
152 (primitive-ref-name proc))))
153 (and expand (apply expand src args)))))
154 (else #f)))
155 x))
156
157;;; I actually did spend about 10 minutes trying to redo this with
158;;; syntax-rules. Patches appreciated.
159;;;
160(define-macro (define-primitive-expander sym . clauses)
161 (define (inline-args args)
162 (let lp ((in args) (out '()))
163 (cond ((null? in) `(list ,@(reverse out)))
164 ((symbol? in) `(cons* ,@(reverse out) ,in))
165 ((pair? (car in))
166 (lp (cdr in)
167 (cons `(make-application src (make-primitive-ref src ',(caar in))
168 ,(inline-args (cdar in)))
169 out)))
170 ((symbol? (car in))
171 ;; assume it's locally bound
172 (lp (cdr in) (cons (car in) out)))
173 ((number? (car in))
174 (lp (cdr in) (cons `(make-const src ,(car in)) out)))
175 (else
176 (error "what what" (car in))))))
177 (define (consequent exp)
178 (cond
179 ((pair? exp)
7382f23e
AW
180 (pmatch exp
181 ((if ,test ,then ,else)
182 `(if ,test
183 ,(consequent then)
184 ,(consequent else)))
185 (else
186 `(make-application src (make-primitive-ref src ',(car exp))
187 ,(inline-args (cdr exp))))))
cb28c085
AW
188 ((symbol? exp)
189 ;; assume locally bound
190 exp)
191 ((number? exp)
192 `(make-const src ,exp))
193 (else (error "bad consequent yall" exp))))
194 `(hashq-set! *primitive-expand-table*
195 ',sym
196 (case-lambda
197 ,@(let lp ((in clauses) (out '()))
198 (if (null? in)
199 (reverse (cons '(else #f) out))
200 (lp (cddr in)
201 (cons `((src . ,(car in))
202 ,(consequent (cadr in))) out)))))))
203
9b29d607
AW
204(define-primitive-expander zero? (x)
205 (= x 0))
206
cb28c085
AW
207(define-primitive-expander +
208 () 0
209 (x) x
7382f23e
AW
210 (x y) (if (and (const? y)
211 (let ((y (const-exp y)))
eebff6d7 212 (and (number? y) (exact? y) (= y 1))))
7382f23e 213 (1+ x)
8753fd53
AW
214 (if (and (const? y)
215 (let ((y (const-exp y)))
216 (and (number? y) (exact? y) (= y -1))))
217 (1- x)
218 (if (and (const? x)
219 (let ((x (const-exp x)))
220 (and (number? y) (exact? x) (= x 1))))
221 (1+ y)
222 (+ x y))))
cb28c085
AW
223 (x y z . rest) (+ x (+ y z . rest)))
224
225(define-primitive-expander *
226 () 1
227 (x) x
228 (x y z . rest) (* x (* y z . rest)))
229
230(define-primitive-expander -
231 (x) (- 0 x)
7382f23e
AW
232 (x y) (if (and (const? y)
233 (let ((y (const-exp y)))
eebff6d7 234 (and (number? y) (exact? y) (= y 1))))
7382f23e
AW
235 (1- x)
236 (- x y))
cb28c085
AW
237 (x y z . rest) (- x (+ y z . rest)))
238
cb28c085
AW
239(define-primitive-expander /
240 (x) (/ 1 x)
81fd3152 241 (x y z . rest) (/ x (* y z . rest)))
cb28c085
AW
242
243(define-primitive-expander caar (x) (car (car x)))
244(define-primitive-expander cadr (x) (car (cdr x)))
245(define-primitive-expander cdar (x) (cdr (car x)))
246(define-primitive-expander cddr (x) (cdr (cdr x)))
247(define-primitive-expander caaar (x) (car (car (car x))))
248(define-primitive-expander caadr (x) (car (car (cdr x))))
249(define-primitive-expander cadar (x) (car (cdr (car x))))
250(define-primitive-expander caddr (x) (car (cdr (cdr x))))
251(define-primitive-expander cdaar (x) (cdr (car (car x))))
252(define-primitive-expander cdadr (x) (cdr (car (cdr x))))
253(define-primitive-expander cddar (x) (cdr (cdr (car x))))
254(define-primitive-expander cdddr (x) (cdr (cdr (cdr x))))
255(define-primitive-expander caaaar (x) (car (car (car (car x)))))
256(define-primitive-expander caaadr (x) (car (car (car (cdr x)))))
257(define-primitive-expander caadar (x) (car (car (cdr (car x)))))
258(define-primitive-expander caaddr (x) (car (car (cdr (cdr x)))))
259(define-primitive-expander cadaar (x) (car (cdr (car (car x)))))
260(define-primitive-expander cadadr (x) (car (cdr (car (cdr x)))))
261(define-primitive-expander caddar (x) (car (cdr (cdr (car x)))))
262(define-primitive-expander cadddr (x) (car (cdr (cdr (cdr x)))))
263(define-primitive-expander cdaaar (x) (cdr (car (car (car x)))))
264(define-primitive-expander cdaadr (x) (cdr (car (car (cdr x)))))
265(define-primitive-expander cdadar (x) (cdr (car (cdr (car x)))))
266(define-primitive-expander cdaddr (x) (cdr (car (cdr (cdr x)))))
267(define-primitive-expander cddaar (x) (cdr (cdr (car (car x)))))
268(define-primitive-expander cddadr (x) (cdr (cdr (car (cdr x)))))
269(define-primitive-expander cdddar (x) (cdr (cdr (cdr (car x)))))
270(define-primitive-expander cddddr (x) (cdr (cdr (cdr (cdr x)))))
271
272(define-primitive-expander cons*
273 (x) x
274 (x y) (cons x y)
275 (x y . rest) (cons x (cons* y . rest)))
276
dce042f1
AW
277(define-primitive-expander acons (x y z)
278 (cons (cons x y) z))
279
0e249fd3
AW
280(define-primitive-expander apply (f a0 . args)
281 (@apply f a0 . args))
dce042f1
AW
282
283(define-primitive-expander call-with-values (producer consumer)
284 (@call-with-values producer consumer))
285
286(define-primitive-expander call-with-current-continuation (proc)
287 (@call-with-current-continuation proc))
288
0f423f20
AW
289(define-primitive-expander call/cc (proc)
290 (@call-with-current-continuation proc))
291
dce042f1 292(define-primitive-expander values (x) x)