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