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