1 ;;; open-coding primitive procedures
3 ;; Copyright (C) 2009 Free Software Foundation, Inc.
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.
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.
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
21 (define-module (language tree-il primitives)
22 #:use-module (system base pmatch)
23 #:use-module (rnrs bytevector)
24 #:use-module (system base syntax)
25 #:use-module (language tree-il)
26 #:use-module (srfi srfi-16)
27 #:export (resolve-primitives! add-interesting-primitive!
30 (define *interesting-primitive-names*
32 call-with-values @call-with-values
33 call-with-current-continuation @call-with-current-continuation
38 + * - / 1- 1+ quotient remainder modulo
40 pair? null? list? acons cons cons*
49 caaar caadr cadar caddr cdaar cdadr cddar cdddr
51 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
52 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
54 vector-ref vector-set!
56 bytevector-u8-ref bytevector-u8-set!
57 bytevector-s8-ref bytevector-s8-set!
59 bytevector-u16-ref bytevector-u16-set!
60 bytevector-u16-native-ref bytevector-u16-native-set!
61 bytevector-s16-ref bytevector-s16-set!
62 bytevector-s16-native-ref bytevector-s16-native-set!
64 bytevector-u32-ref bytevector-u32-set!
65 bytevector-u32-native-ref bytevector-u32-native-set!
66 bytevector-s32-ref bytevector-s32-set!
67 bytevector-s32-native-ref bytevector-s32-native-set!
69 bytevector-u64-ref bytevector-u64-set!
70 bytevector-u64-native-ref bytevector-u64-native-set!
71 bytevector-s64-ref bytevector-s64-set!
72 bytevector-s64-native-ref bytevector-s64-native-set!
74 bytevector-ieee-single-ref bytevector-ieee-single-set!
75 bytevector-ieee-single-native-ref bytevector-ieee-single-native-set!
76 bytevector-ieee-double-ref bytevector-ieee-double-set!
77 bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!))
79 (define (add-interesting-primitive! name)
80 (hashq-set! *interesting-primitive-vars*
81 (module-variable (current-module) name)
84 (define *interesting-primitive-vars* (make-hash-table))
86 (for-each add-interesting-primitive! *interesting-primitive-names*)
88 (define (resolve-primitives! x mod)
92 ((<toplevel-ref> src name)
93 (and=> (hashq-ref *interesting-primitive-vars*
94 (module-variable mod name))
95 (lambda (name) (make-primitive-ref src name))))
96 ((<module-ref> src mod name public?)
97 ;; for the moment, we're disabling primitive resolution for
98 ;; public refs because resolve-interface can raise errors.
99 (let ((m (and (not public?) (resolve-module mod))))
101 (and=> (hashq-ref *interesting-primitive-vars*
102 (module-variable m name))
103 (lambda (name) (make-primitive-ref src name))))))
109 (define *primitive-expand-table* (make-hash-table))
111 (define (expand-primitives! x)
115 ((<application> src proc args)
116 (and (primitive-ref? proc)
117 (let ((expand (hashq-ref *primitive-expand-table*
118 (primitive-ref-name proc))))
119 (and expand (apply expand src args)))))
123 ;;; I actually did spend about 10 minutes trying to redo this with
124 ;;; syntax-rules. Patches appreciated.
126 (define-macro (define-primitive-expander sym . clauses)
127 (define (inline-args args)
128 (let lp ((in args) (out '()))
129 (cond ((null? in) `(list ,@(reverse out)))
130 ((symbol? in) `(cons* ,@(reverse out) ,in))
133 (cons `(make-application src (make-primitive-ref src ',(caar in))
134 ,(inline-args (cdar in)))
137 ;; assume it's locally bound
138 (lp (cdr in) (cons (car in) out)))
140 (lp (cdr in) (cons `(make-const src ,(car in)) out)))
142 (error "what what" (car in))))))
143 (define (consequent exp)
147 ((if ,test ,then ,else)
152 `(make-application src (make-primitive-ref src ',(car exp))
153 ,(inline-args (cdr exp))))))
155 ;; assume locally bound
158 `(make-const src ,exp))
159 (else (error "bad consequent yall" exp))))
160 `(hashq-set! *primitive-expand-table*
163 ,@(let lp ((in clauses) (out '()))
165 (reverse (cons '(else #f) out))
167 (cons `((src . ,(car in))
168 ,(consequent (cadr in))) out)))))))
170 (define-primitive-expander +
173 (x y) (if (and (const? y)
174 (let ((y (const-exp y)))
175 (and (exact? y) (= y 1))))
178 (let ((x (const-exp x)))
179 (and (exact? x) (= x 1))))
182 (x y z . rest) (+ x (+ y z . rest)))
184 (define-primitive-expander *
187 (x y z . rest) (* x (* y z . rest)))
189 (define-primitive-expander -
191 (x y) (if (and (const? y)
192 (let ((y (const-exp y)))
193 (and (exact? y) (= y 1))))
196 (x y z . rest) (- x (+ y z . rest)))
198 (define-primitive-expander /
200 (x y z . rest) (/ x (* y z . rest)))
202 (define-primitive-expander caar (x) (car (car x)))
203 (define-primitive-expander cadr (x) (car (cdr x)))
204 (define-primitive-expander cdar (x) (cdr (car x)))
205 (define-primitive-expander cddr (x) (cdr (cdr x)))
206 (define-primitive-expander caaar (x) (car (car (car x))))
207 (define-primitive-expander caadr (x) (car (car (cdr x))))
208 (define-primitive-expander cadar (x) (car (cdr (car x))))
209 (define-primitive-expander caddr (x) (car (cdr (cdr x))))
210 (define-primitive-expander cdaar (x) (cdr (car (car x))))
211 (define-primitive-expander cdadr (x) (cdr (car (cdr x))))
212 (define-primitive-expander cddar (x) (cdr (cdr (car x))))
213 (define-primitive-expander cdddr (x) (cdr (cdr (cdr x))))
214 (define-primitive-expander caaaar (x) (car (car (car (car x)))))
215 (define-primitive-expander caaadr (x) (car (car (car (cdr x)))))
216 (define-primitive-expander caadar (x) (car (car (cdr (car x)))))
217 (define-primitive-expander caaddr (x) (car (car (cdr (cdr x)))))
218 (define-primitive-expander cadaar (x) (car (cdr (car (car x)))))
219 (define-primitive-expander cadadr (x) (car (cdr (car (cdr x)))))
220 (define-primitive-expander caddar (x) (car (cdr (cdr (car x)))))
221 (define-primitive-expander cadddr (x) (car (cdr (cdr (cdr x)))))
222 (define-primitive-expander cdaaar (x) (cdr (car (car (car x)))))
223 (define-primitive-expander cdaadr (x) (cdr (car (car (cdr x)))))
224 (define-primitive-expander cdadar (x) (cdr (car (cdr (car x)))))
225 (define-primitive-expander cdaddr (x) (cdr (car (cdr (cdr x)))))
226 (define-primitive-expander cddaar (x) (cdr (cdr (car (car x)))))
227 (define-primitive-expander cddadr (x) (cdr (cdr (car (cdr x)))))
228 (define-primitive-expander cdddar (x) (cdr (cdr (cdr (car x)))))
229 (define-primitive-expander cddddr (x) (cdr (cdr (cdr (cdr x)))))
231 (define-primitive-expander cons*
234 (x y . rest) (cons x (cons* y . rest)))
236 (define-primitive-expander acons (x y z)
239 (define-primitive-expander apply (f . args)
242 (define-primitive-expander call-with-values (producer consumer)
243 (@call-with-values producer consumer))
245 (define-primitive-expander call-with-current-continuation (proc)
246 (@call-with-current-continuation proc))
248 (define-primitive-expander call/cc (proc)
249 (@call-with-current-continuation proc))
251 (define-primitive-expander values (x) x)