abort-to-prompt* instead of @abort
[bpt/guile.git] / module / language / tree-il / primitives.scm
CommitLineData
ac4d09b1 1;;; open-coding primitive procedures
cb28c085 2
403d78f9 3;; Copyright (C) 2009, 2010, 2011, 2012, 2013 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)
07d22c02 23 #:use-module (rnrs bytevectors)
cb28c085
AW
24 #:use-module (system base syntax)
25 #:use-module (language tree-il)
6c498233 26 #:use-module (srfi srfi-4)
cb28c085 27 #:use-module (srfi srfi-16)
403d78f9 28 #:export (resolve-primitives add-interesting-primitive!
25450a0d 29 expand-primitives
11671bba 30 effect-free-primitive? effect+exception-free-primitive?
f26c3a93 31 constructor-primitive? accessor-primitive?
c46e0a8a
AW
32 singly-valued-primitive? equality-primitive?
33 bailout-primitive?
5deea34d 34 negate-primitive))
55ae815b 35
5deea34d
AW
36;; When adding to this, be sure to update *multiply-valued-primitives*
37;; if appropriate.
55ae815b
AW
38(define *interesting-primitive-names*
39 '(apply @apply
40 call-with-values @call-with-values
41 call-with-current-continuation @call-with-current-continuation
42 call/cc
1bf78495 43 dynamic-wind
d69531e2 44 @dynamic-wind
55ae815b
AW
45 values
46 eq? eqv? equal?
349d5c44 47 memq memv
55ae815b
AW
48 = < > <= >= zero?
49 + * - / 1- 1+ quotient remainder modulo
b3f25e62 50 ash logand logior logxor lognot
55ae815b 51 not
c46e0a8a 52 pair? null? list? symbol? vector? string? struct? number? char? nil?
5deea34d
AW
53
54 complex? real? rational? inf? nan? integer? exact? inexact? even? odd?
55
56 char<? char<=? char>=? char>?
57
2874f660
AW
58 integer->char char->integer number->string string->number
59
9be8a338 60 acons cons cons*
55ae815b
AW
61
62 list vector
63
64 car cdr
65 set-car! set-cdr!
66
67 caar cadr cdar cddr
68
69 caaar caadr cadar caddr cdaar cdadr cddar cdddr
70
71 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
d6f1ce3d
AW
72 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
73
ba9f9f0d 74 vector-length vector-ref vector-set!
1d30393f 75 variable-ref variable-set!
d27a7811 76 variable-bound?
39141c87 77
f5b1f76a
AW
78 fluid-ref fluid-set!
79
38504994
AW
80 @prompt call-with-prompt
81 abort-to-prompt* abort-to-prompt
38030bdf 82 make-prompt-tag
747022e4 83
5deea34d
AW
84 throw error scm-error
85
9be8a338
AW
86 string-length string-ref string-set!
87
88 struct-vtable make-struct struct-ref struct-set!
bd91ecce 89
39141c87
AW
90 bytevector-u8-ref bytevector-u8-set!
91 bytevector-s8-ref bytevector-s8-set!
6c498233
AW
92 u8vector-ref u8vector-set! s8vector-ref s8vector-set!
93
39141c87
AW
94 bytevector-u16-ref bytevector-u16-set!
95 bytevector-u16-native-ref bytevector-u16-native-set!
96 bytevector-s16-ref bytevector-s16-set!
97 bytevector-s16-native-ref bytevector-s16-native-set!
6c498233 98 u16vector-ref u16vector-set! s16vector-ref s16vector-set!
39141c87
AW
99
100 bytevector-u32-ref bytevector-u32-set!
101 bytevector-u32-native-ref bytevector-u32-native-set!
102 bytevector-s32-ref bytevector-s32-set!
103 bytevector-s32-native-ref bytevector-s32-native-set!
6c498233 104 u32vector-ref u32vector-set! s32vector-ref s32vector-set!
39141c87
AW
105
106 bytevector-u64-ref bytevector-u64-set!
107 bytevector-u64-native-ref bytevector-u64-native-set!
108 bytevector-s64-ref bytevector-s64-set!
109 bytevector-s64-native-ref bytevector-s64-native-set!
6c498233 110 u64vector-ref u64vector-set! s64vector-ref s64vector-set!
39141c87
AW
111
112 bytevector-ieee-single-ref bytevector-ieee-single-set!
113 bytevector-ieee-single-native-ref bytevector-ieee-single-native-set!
114 bytevector-ieee-double-ref bytevector-ieee-double-set!
6c498233
AW
115 bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!
116 f32vector-ref f32vector-set! f64vector-ref f64vector-set!))
55ae815b
AW
117
118(define (add-interesting-primitive! name)
119 (hashq-set! *interesting-primitive-vars*
83c76550
AW
120 (or (module-variable (current-module) name)
121 (error "unbound interesting primitive" name))
39141c87 122 name))
55ae815b
AW
123
124(define *interesting-primitive-vars* (make-hash-table))
125
126(for-each add-interesting-primitive! *interesting-primitive-names*)
127
11671bba
LC
128(define *primitive-constructors*
129 ;; Primitives that return a fresh object.
d851e32f 130 '(acons cons cons* list vector make-struct make-struct/no-tail
f26c3a93
AW
131 make-prompt-tag))
132
133(define *primitive-accessors*
134 ;; Primitives that are pure, but whose result depends on the mutable
135 ;; memory pointed to by their operands.
136 '(vector-ref
137 car cdr
138 memq memv
5deea34d 139 struct-ref
9be8a338 140 string-ref
f26c3a93
AW
141 bytevector-u8-ref bytevector-s8-ref
142 bytevector-u16-ref bytevector-u16-native-ref
143 bytevector-s16-ref bytevector-s16-native-ref
144 bytevector-u32-ref bytevector-u32-native-ref
145 bytevector-s32-ref bytevector-s32-native-ref
146 bytevector-u64-ref bytevector-u64-native-ref
147 bytevector-s64-ref bytevector-s64-native-ref
148 bytevector-ieee-single-ref bytevector-ieee-single-native-ref
149 bytevector-ieee-double-ref bytevector-ieee-double-native-ref))
11671bba 150
80af1168 151(define *effect-free-primitives*
11671bba 152 `(values
80af1168
AW
153 eq? eqv? equal?
154 = < > <= >= zero?
b3f25e62 155 ash logand logior logxor lognot
80af1168
AW
156 + * - / 1- 1+ quotient remainder modulo
157 not
c46e0a8a 158 pair? null? list? symbol? vector? struct? string? number? char? nil
5deea34d
AW
159 complex? real? rational? inf? nan? integer? exact? inexact? even? odd?
160 char<? char<=? char>=? char>?
2874f660 161 integer->char char->integer number->string string->number
5deea34d 162 struct-vtable
ba9f9f0d 163 string-length vector-length
25450a0d 164 ;; These all should get expanded out by expand-primitives.
80af1168
AW
165 caar cadr cdar cddr
166 caaar caadr cadar caddr cdaar cdadr cddar cdddr
167 caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr
168 cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
f26c3a93
AW
169 ,@*primitive-constructors*
170 ,@*primitive-accessors*))
80af1168 171
4ee781a6
AW
172;; Like *effect-free-primitives* above, but further restricted in that they
173;; cannot raise exceptions.
174(define *effect+exception-free-primitives*
175 '(values
176 eq? eqv? equal?
177 not
5deea34d 178 pair? null? list? symbol? vector? struct? string? number? char?
f26c3a93 179 acons cons cons* list vector))
80af1168 180
5deea34d
AW
181;; Primitives that don't always return one value.
182(define *multiply-valued-primitives*
183 '(apply @apply
184 call-with-values @call-with-values
185 call-with-current-continuation @call-with-current-continuation
186 call/cc
187 dynamic-wind
188 @dynamic-wind
189 values
38504994
AW
190 @prompt call-with-prompt
191 @abort abort-to-prompt))
5deea34d
AW
192
193;; Procedures that cause a nonlocal, non-resumable abort.
194(define *bailout-primitives*
195 '(throw error scm-error))
196
197;; Negatable predicates.
198(define *negatable-primitives*
199 '((even? . odd?)
200 (exact? . inexact?)
201 (< . >=)
202 (> . <=)
203 (char<? . char>=?)
204 (char>? . char<=?)))
03026d0f 205
3c65e3fd
NL
206(define *equality-primitives*
207 '(eq? eqv? equal?))
208
80af1168 209(define *effect-free-primitive-table* (make-hash-table))
4ee781a6 210(define *effect+exceptions-free-primitive-table* (make-hash-table))
3c65e3fd 211(define *equality-primitive-table* (make-hash-table))
5deea34d
AW
212(define *multiply-valued-primitive-table* (make-hash-table))
213(define *bailout-primitive-table* (make-hash-table))
214(define *negatable-primitive-table* (make-hash-table))
80af1168 215
4ee781a6
AW
216(for-each (lambda (x)
217 (hashq-set! *effect-free-primitive-table* x #t))
80af1168 218 *effect-free-primitives*)
4ee781a6
AW
219(for-each (lambda (x)
220 (hashq-set! *effect+exceptions-free-primitive-table* x #t))
221 *effect+exception-free-primitives*)
3c65e3fd
NL
222(for-each (lambda (x)
223 (hashq-set! *equality-primitive-table* x #t))
224 *equality-primitives*)
03026d0f 225(for-each (lambda (x)
5deea34d
AW
226 (hashq-set! *multiply-valued-primitive-table* x #t))
227 *multiply-valued-primitives*)
228(for-each (lambda (x)
229 (hashq-set! *bailout-primitive-table* x #t))
230 *bailout-primitives*)
231(for-each (lambda (x)
232 (hashq-set! *negatable-primitive-table* (car x) (cdr x))
233 (hashq-set! *negatable-primitive-table* (cdr x) (car x)))
234 *negatable-primitives*)
80af1168 235
11671bba
LC
236(define (constructor-primitive? prim)
237 (memq prim *primitive-constructors*))
f26c3a93
AW
238(define (accessor-primitive? prim)
239 (memq prim *primitive-accessors*))
80af1168
AW
240(define (effect-free-primitive? prim)
241 (hashq-ref *effect-free-primitive-table* prim))
4ee781a6
AW
242(define (effect+exception-free-primitive? prim)
243 (hashq-ref *effect+exceptions-free-primitive-table* prim))
3c65e3fd
NL
244(define (equality-primitive? prim)
245 (hashq-ref *equality-primitive-table* prim))
03026d0f 246(define (singly-valued-primitive? prim)
5deea34d
AW
247 (not (hashq-ref *multiply-valued-primitive-table* prim)))
248(define (bailout-primitive? prim)
249 (hashq-ref *bailout-primitive-table* prim))
250(define (negate-primitive prim)
251 (hashq-ref *negatable-primitive-table* prim))
80af1168 252
403d78f9 253(define (resolve-primitives x mod)
14b20818
AW
254 (define local-definitions
255 (make-hash-table))
256
257 (let collect-local-definitions ((x x))
258 (record-case x
259 ((<toplevel-define> name)
260 (hashq-set! local-definitions name #t))
261 ((<seq> head tail)
262 (collect-local-definitions head)
263 (collect-local-definitions tail))
264 (else #f)))
265
403d78f9 266 (post-order
55ae815b 267 (lambda (x)
403d78f9
AW
268 (or
269 (record-case x
270 ((<toplevel-ref> src name)
271 (and=> (and (not (hashq-ref local-definitions name))
272 (hashq-ref *interesting-primitive-vars*
273 (module-variable mod name)))
274 (lambda (name) (make-primitive-ref src name))))
275 ((<module-ref> src mod name public?)
276 ;; for the moment, we're disabling primitive resolution for
277 ;; public refs because resolve-interface can raise errors.
278 (and=> (and=> (resolve-module mod)
279 (if public?
280 module-public-interface
281 identity))
282 (lambda (m)
283 (and=> (hashq-ref *interesting-primitive-vars*
284 (module-variable m name))
285 (lambda (name)
286 (make-primitive-ref src name))))))
287 ((<call> src proc args)
288 (and (primitive-ref? proc)
289 (make-primcall src (primitive-ref-name proc) args)))
290 (else #f))
291 x))
55ae815b
AW
292 x))
293
294\f
cb28c085
AW
295
296(define *primitive-expand-table* (make-hash-table))
297
25450a0d
AW
298(define (expand-primitives x)
299 (pre-order
cb28c085
AW
300 (lambda (x)
301 (record-case x
a881a4ae
AW
302 ((<primcall> src name args)
303 (let ((expand (hashq-ref *primitive-expand-table* name)))
25450a0d
AW
304 (or (and expand (apply expand src args))
305 x)))
306 (else x)))
cb28c085
AW
307 x))
308
309;;; I actually did spend about 10 minutes trying to redo this with
310;;; syntax-rules. Patches appreciated.
311;;;
312(define-macro (define-primitive-expander sym . clauses)
313 (define (inline-args args)
314 (let lp ((in args) (out '()))
315 (cond ((null? in) `(list ,@(reverse out)))
316 ((symbol? in) `(cons* ,@(reverse out) ,in))
317 ((pair? (car in))
318 (lp (cdr in)
9b2a2a39
AW
319 (cons (if (eq? (caar in) 'quote)
320 `(make-const src ,@(cdar in))
a881a4ae
AW
321 `(make-primcall src ',(caar in)
322 ,(inline-args (cdar in))))
cb28c085
AW
323 out)))
324 ((symbol? (car in))
325 ;; assume it's locally bound
326 (lp (cdr in) (cons (car in) out)))
9b2a2a39 327 ((self-evaluating? (car in))
cb28c085
AW
328 (lp (cdr in) (cons `(make-const src ,(car in)) out)))
329 (else
330 (error "what what" (car in))))))
331 (define (consequent exp)
332 (cond
333 ((pair? exp)
7382f23e
AW
334 (pmatch exp
335 ((if ,test ,then ,else)
336 `(if ,test
337 ,(consequent then)
338 ,(consequent else)))
339 (else
a881a4ae
AW
340 `(make-primcall src ',(car exp)
341 ,(inline-args (cdr exp))))))
cb28c085
AW
342 ((symbol? exp)
343 ;; assume locally bound
344 exp)
345 ((number? exp)
346 `(make-const src ,exp))
9a974fd3
AW
347 ((not exp)
348 ;; failed match
349 #f)
cb28c085
AW
350 (else (error "bad consequent yall" exp))))
351 `(hashq-set! *primitive-expand-table*
352 ',sym
353 (case-lambda
354 ,@(let lp ((in clauses) (out '()))
355 (if (null? in)
356 (reverse (cons '(else #f) out))
357 (lp (cddr in)
358 (cons `((src . ,(car in))
359 ,(consequent (cadr in))) out)))))))
360
9b29d607
AW
361(define-primitive-expander zero? (x)
362 (= x 0))
363
11671bba
LC
364;; FIXME: All the code that uses `const?' is redundant with `peval'.
365
cb28c085
AW
366(define-primitive-expander +
367 () 0
b88fef55 368 (x) (values x)
7382f23e
AW
369 (x y) (if (and (const? y)
370 (let ((y (const-exp y)))
eebff6d7 371 (and (number? y) (exact? y) (= y 1))))
7382f23e 372 (1+ x)
8753fd53 373 (if (and (const? y)
dd902692
LC
374 (let ((y (const-exp y)))
375 (and (number? y) (exact? y) (= y -1))))
8753fd53
AW
376 (1- x)
377 (if (and (const? x)
378 (let ((x (const-exp x)))
dd902692 379 (and (number? x) (exact? x) (= x 1))))
8753fd53
AW
380 (1+ y)
381 (+ x y))))
cb28c085
AW
382 (x y z . rest) (+ x (+ y z . rest)))
383
384(define-primitive-expander *
385 () 1
b88fef55 386 (x) (values x)
cb28c085
AW
387 (x y z . rest) (* x (* y z . rest)))
388
389(define-primitive-expander -
390 (x) (- 0 x)
7382f23e
AW
391 (x y) (if (and (const? y)
392 (let ((y (const-exp y)))
eebff6d7 393 (and (number? y) (exact? y) (= y 1))))
7382f23e
AW
394 (1- x)
395 (- x y))
cb28c085
AW
396 (x y z . rest) (- x (+ y z . rest)))
397
cb28c085
AW
398(define-primitive-expander /
399 (x) (/ 1 x)
81fd3152 400 (x y z . rest) (/ x (* y z . rest)))
cb28c085 401
b3f25e62
AW
402(define-primitive-expander logior
403 () 0
404 (x) (logior x 0)
405 (x y) (logior x y)
406 (x y z . rest) (logior x (logior y z . rest)))
407
408(define-primitive-expander logand
409 () -1
410 (x) (logand x -1)
411 (x y) (logand x y)
412 (x y z . rest) (logand x (logand y z . rest)))
413
cb28c085
AW
414(define-primitive-expander caar (x) (car (car x)))
415(define-primitive-expander cadr (x) (car (cdr x)))
416(define-primitive-expander cdar (x) (cdr (car x)))
417(define-primitive-expander cddr (x) (cdr (cdr x)))
418(define-primitive-expander caaar (x) (car (car (car x))))
419(define-primitive-expander caadr (x) (car (car (cdr x))))
420(define-primitive-expander cadar (x) (car (cdr (car x))))
421(define-primitive-expander caddr (x) (car (cdr (cdr x))))
422(define-primitive-expander cdaar (x) (cdr (car (car x))))
423(define-primitive-expander cdadr (x) (cdr (car (cdr x))))
424(define-primitive-expander cddar (x) (cdr (cdr (car x))))
425(define-primitive-expander cdddr (x) (cdr (cdr (cdr x))))
426(define-primitive-expander caaaar (x) (car (car (car (car x)))))
427(define-primitive-expander caaadr (x) (car (car (car (cdr x)))))
428(define-primitive-expander caadar (x) (car (car (cdr (car x)))))
429(define-primitive-expander caaddr (x) (car (car (cdr (cdr x)))))
430(define-primitive-expander cadaar (x) (car (cdr (car (car x)))))
431(define-primitive-expander cadadr (x) (car (cdr (car (cdr x)))))
432(define-primitive-expander caddar (x) (car (cdr (cdr (car x)))))
433(define-primitive-expander cadddr (x) (car (cdr (cdr (cdr x)))))
434(define-primitive-expander cdaaar (x) (cdr (car (car (car x)))))
435(define-primitive-expander cdaadr (x) (cdr (car (car (cdr x)))))
436(define-primitive-expander cdadar (x) (cdr (car (cdr (car x)))))
437(define-primitive-expander cdaddr (x) (cdr (car (cdr (cdr x)))))
438(define-primitive-expander cddaar (x) (cdr (cdr (car (car x)))))
439(define-primitive-expander cddadr (x) (cdr (cdr (car (cdr x)))))
440(define-primitive-expander cdddar (x) (cdr (cdr (cdr (car x)))))
441(define-primitive-expander cddddr (x) (cdr (cdr (cdr (cdr x)))))
442
443(define-primitive-expander cons*
b88fef55 444 (x) (values x)
cb28c085
AW
445 (x y) (cons x y)
446 (x y . rest) (cons x (cons* y . rest)))
447
dce042f1
AW
448(define-primitive-expander acons (x y z)
449 (cons (cons x y) z))
450
0e249fd3
AW
451(define-primitive-expander apply (f a0 . args)
452 (@apply f a0 . args))
dce042f1
AW
453
454(define-primitive-expander call-with-values (producer consumer)
455 (@call-with-values producer consumer))
456
457(define-primitive-expander call-with-current-continuation (proc)
458 (@call-with-current-continuation proc))
459
0f423f20
AW
460(define-primitive-expander call/cc (proc)
461 (@call-with-current-continuation proc))
462
9a974fd3
AW
463(define-primitive-expander make-struct (vtable tail-size . args)
464 (if (and (const? tail-size)
465 (let ((n (const-exp tail-size)))
466 (and (number? n) (exact? n) (zero? n))))
467 (make-struct/no-tail vtable . args)
468 #f))
469
6c498233
AW
470(define-primitive-expander u8vector-ref (vec i)
471 (bytevector-u8-ref vec i))
472(define-primitive-expander u8vector-set! (vec i x)
473 (bytevector-u8-set! vec i x))
474(define-primitive-expander s8vector-ref (vec i)
475 (bytevector-s8-ref vec i))
476(define-primitive-expander s8vector-set! (vec i x)
477 (bytevector-s8-set! vec i x))
478
479(define-primitive-expander u16vector-ref (vec i)
480 (bytevector-u16-native-ref vec (* i 2)))
481(define-primitive-expander u16vector-set! (vec i x)
482 (bytevector-u16-native-set! vec (* i 2) x))
483(define-primitive-expander s16vector-ref (vec i)
484 (bytevector-s16-native-ref vec (* i 2)))
485(define-primitive-expander s16vector-set! (vec i x)
486 (bytevector-s16-native-set! vec (* i 2) x))
487
488(define-primitive-expander u32vector-ref (vec i)
489 (bytevector-u32-native-ref vec (* i 4)))
490(define-primitive-expander u32vector-set! (vec i x)
491 (bytevector-u32-native-set! vec (* i 4) x))
492(define-primitive-expander s32vector-ref (vec i)
493 (bytevector-s32-native-ref vec (* i 4)))
494(define-primitive-expander s32vector-set! (vec i x)
495 (bytevector-s32-native-set! vec (* i 4) x))
496
497(define-primitive-expander u64vector-ref (vec i)
498 (bytevector-u64-native-ref vec (* i 8)))
499(define-primitive-expander u64vector-set! (vec i x)
500 (bytevector-u64-native-set! vec (* i 8) x))
501(define-primitive-expander s64vector-ref (vec i)
502 (bytevector-s64-native-ref vec (* i 8)))
503(define-primitive-expander s64vector-set! (vec i x)
504 (bytevector-s64-native-set! vec (* i 8) x))
505
506(define-primitive-expander f32vector-ref (vec i)
507 (bytevector-ieee-single-native-ref vec (* i 4)))
508(define-primitive-expander f32vector-set! (vec i x)
509 (bytevector-ieee-single-native-set! vec (* i 4) x))
510(define-primitive-expander f32vector-ref (vec i)
511 (bytevector-ieee-single-native-ref vec (* i 4)))
512(define-primitive-expander f32vector-set! (vec i x)
513 (bytevector-ieee-single-native-set! vec (* i 4) x))
514
515(define-primitive-expander f64vector-ref (vec i)
516 (bytevector-ieee-double-native-ref vec (* i 8)))
517(define-primitive-expander f64vector-set! (vec i x)
518 (bytevector-ieee-double-native-set! vec (* i 8) x))
519(define-primitive-expander f64vector-ref (vec i)
520 (bytevector-ieee-double-native-ref vec (* i 8)))
521(define-primitive-expander f64vector-set! (vec i x)
522 (bytevector-ieee-double-native-set! vec (* i 8) x))
1bf78495 523
75a5de18
MW
524;; Appropriate for use with either 'eqv?' or 'equal?'.
525(define maybe-simplify-to-eq
526 (case-lambda
527 ((src a b)
528 ;; Simplify cases where either A or B is constant.
529 (define (maybe-simplify a b)
530 (and (const? a)
531 (let ((v (const-exp a)))
532 (and (or (memq v '(#f #t () #nil))
533 (symbol? v)
534 (and (integer? v)
535 (exact? v)
fa980bcc
MW
536 (<= v most-positive-fixnum)
537 (>= v most-negative-fixnum)))
538 (make-primcall src 'eq? (list a b))))))
75a5de18
MW
539 (or (maybe-simplify a b) (maybe-simplify b a)))
540 (else #f)))
541
542(hashq-set! *primitive-expand-table* 'eqv? maybe-simplify-to-eq)
543(hashq-set! *primitive-expand-table* 'equal? maybe-simplify-to-eq)
2446f8e1 544
d69531e2
AW
545(hashq-set! *primitive-expand-table*
546 '@dynamic-wind
547 (case-lambda
548 ((src pre expr post)
9b965638
AW
549 (let* ((PRE (gensym "pre-"))
550 (POST (gensym "post-"))
551 (winder (make-lexical-ref #f 'winder PRE))
552 (unwinder (make-lexical-ref #f 'unwinder POST)))
553 (define (make-begin0 src first second)
554 (make-let-values
555 src
556 first
557 (let ((vals (gensym "vals ")))
558 (make-lambda-case
559 #f
560 '() #f 'vals #f '() (list vals)
561 (make-seq
562 src
563 second
564 (make-primcall #f 'apply
565 (list
566 (make-primitive-ref #f 'values)
567 (make-lexical-ref #f 'vals vals))))
568 #f))))
569 (make-let src '(pre post) (list PRE POST) (list pre post)
570 (make-seq src
571 (make-call src winder '())
572 (make-begin0
573 src
574 (make-dynwind src winder expr unwinder)
575 (make-call src unwinder '()))))))))
d69531e2 576
f5b1f76a
AW
577(hashq-set! *primitive-expand-table*
578 'fluid-ref
579 (case-lambda
580 ((src fluid) (make-dynref src fluid))
581 (else #f)))
582
583(hashq-set! *primitive-expand-table*
584 'fluid-set!
585 (case-lambda
586 ((src fluid exp) (make-dynset src fluid exp))
587 (else #f)))
588
9b2a2a39
AW
589(hashq-set! *primitive-expand-table*
590 '@prompt
591 (case-lambda
ea6b18e8
AW
592 ((src tag exp handler)
593 (let ((args-sym (gensym)))
594 (make-prompt
595 src tag exp
596 ;; If handler itself is a lambda, the inliner can do some
597 ;; trickery here.
598 (make-lambda-case
599 (tree-il-src handler) '() #f 'args #f '() (list args-sym)
a881a4ae
AW
600 (make-primcall #f 'apply
601 (list handler
602 (make-lexical-ref #f 'args args-sym)))
ea6b18e8 603 #f))))
9b2a2a39
AW
604 (else #f)))
605
606(hashq-set! *primitive-expand-table*
8fc43b12 607 'call-with-prompt
9b2a2a39 608 (case-lambda
f828ab4f 609 ((src tag thunk handler)
20337139
AW
610 (let ((handler-sym (gensym))
611 (args-sym (gensym)))
612 (make-let
613 src '(handler) (list handler-sym) (list handler)
614 (make-prompt
d4899983 615 src tag (make-call #f thunk '())
20337139
AW
616 ;; If handler itself is a lambda, the inliner can do some
617 ;; trickery here.
618 (make-lambda-case
619 (tree-il-src handler) '() #f 'args #f '() (list args-sym)
d4899983
AW
620 (make-primcall
621 #f 'apply
20337139
AW
622 (list (make-lexical-ref #f 'handler handler-sym)
623 (make-lexical-ref #f 'args args-sym)))
624 #f)))))
9b2a2a39 625 (else #f)))
f828ab4f 626
2d026f04 627(hashq-set! *primitive-expand-table*
38504994 628 'abort-to-prompt*
2d026f04
AW
629 (case-lambda
630 ((src tag tail-args)
631 (make-abort src tag '() tail-args))
632 (else #f)))
9b2a2a39 633(hashq-set! *primitive-expand-table*
8fc43b12 634 'abort-to-prompt
9b2a2a39 635 (case-lambda
6e84cb95 636 ((src tag . args)
2d026f04 637 (make-abort src tag args (make-const #f '())))
9b2a2a39 638 (else #f)))