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