1 ;;;============================================================================
5 ;;; Copyright (c) 1994-2011 by Marc Feeley, All Rights Reserved.
7 ;;;============================================================================
9 (##include "header.scm")
11 ;;;============================================================================
13 ;;; Decompilation of a piece of code
15 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17 (##define-macro (mk-degen params . def)
18 `(let () (##declare (not inline)) (lambda ($code ,@params) ,@def)))
20 (##define-macro (degen proc . args)
21 `(,proc $code ,@args))
23 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
25 (define-prim (##extract-container $code rte)
26 (let loop ((c (macro-code-cte $code)) (r rte))
30 (let ((vars (##cte-frame-vars c)))
31 (if (and (##pair? vars)
32 (let ((var (##car vars)))
34 (##eq? (##var-i-name var) (macro-self-var)))))
36 (loop (##cte-parent-cte c) (macro-rte-up r)))))
38 (loop (##cte-parent-cte c) r)))))
40 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
42 (define-prim (##begin? x) (and (##pair? x) (##eq? (##car x) 'begin)))
43 (define-prim (##cond? x) (and (##pair? x) (##eq? (##car x) 'cond)))
44 (define-prim (##and? x) (and (##pair? x) (##eq? (##car x) 'and)))
45 (define-prim (##or? x) (and (##pair? x) (##eq? (##car x) 'or)))
46 (define-prim (##void-constant? x)
48 (##eq? (##car x) 'quote)
49 (##eq? (##cadr x) (##void))))
51 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53 (define-prim ##degen-top
57 (define-prim ##degen-cst
60 (##inverse-eval val))))
62 (define-prim ##degen-loc-ref-x-y
64 (degen ##degen-up-over up over)))
66 (define-prim ##degen-up-over
68 (let loop1 ((c (macro-code-cte $code)) (up up))
69 (cond ((##cte-frame? c)
71 (let loop2 ((vars (##cte-frame-vars c)) (i over))
73 (let ((var (##car vars)))
77 (loop2 (##cdr vars) (##fixnum.- i 1))))
78 (loop1 (##cte-parent-cte c) (##fixnum.- up 1))))
80 (loop1 (##cte-parent-cte c) up))))))
82 (define-prim ##degen-loc-ref
84 (degen ##degen-loc-ref-x-y (^ 0) (^ 1))))
86 (define-prim ##degen-glo-ref
88 (##global-var->identifier (^ 0))))
90 (define-prim ##degen-loc-set
92 (##list 'set! (degen ##degen-up-over (^ 1) (^ 2))
95 (define-prim ##degen-glo-set
97 (##list 'set! (##global-var->identifier (^ 1))
100 (define-prim ##degen-glo-def
102 (##list 'define (##global-var->identifier (^ 1))
105 (define-prim ##degen-if2
107 (##list 'if (##decomp (^ 0))
110 (define-prim ##degen-if3
112 (##list 'if (##decomp (^ 0))
116 (define-prim ##degen-seq
118 (let ((val1 (##decomp (^ 0)))
119 (val2 (##decomp (^ 1))))
121 (##cons 'begin (##cons val1 (##cdr val2)))
122 (##list 'begin val1 val2)))))
124 (define-prim ##degen-quasi-list->vector
128 (##degen-quasi-unquote-splicing-cdr
129 (##decomp (^ 0)))))))
131 (define-prim ##degen-quasi-append
133 (##degen-quasi-append-aux
134 (##degen-quasi-unquote-splicing (##decomp (^ 0)))
137 (define-prim ##degen-quasi-cons
139 (##degen-quasi-append-aux
140 (##degen-quasi-unquote (##decomp (^ 0)))
143 (define-prim (##degen-quasi-append-aux a b)
146 (##degen-quasi-unquote-splicing-cdr b))))
148 (define-prim (##degen-quasi-unquote expr)
149 (let ((x (##degen-quasi-optimize expr)))
152 (##list 'unquote expr))))
154 (define-prim (##degen-quasi-unquote-splicing-cdr expr)
155 (let ((x (##degen-quasi-optimize expr)))
158 (##list (##degen-quasi-unquote-splicing expr)))))
160 (define-prim (##degen-quasi-unquote-splicing expr)
161 (##list 'unquote-splicing expr))
163 (define-prim (##degen-quasi-optimize expr)
164 (let ((x (##degen-quasi-extract expr 'quasiquote)))
167 (let ((y (##degen-quasi-extract expr 'quote)))
168 (if (and y (##not (##pair? (##car y)))) ;; in case of embedded unquotes
172 (define-prim (##degen-quasi-extract expr tag)
173 (and ;; #f ;; uncomment to disable optimization
175 (##eq? (##car expr) tag)
176 (let ((x (##cdr expr)))
179 (##list (##car x))))))
181 (define-prim ##degen-cond-if
183 (let ((val1 (##decomp (^ 0)))
184 (val2 (##decomp (^ 1)))
185 (val3 (##decomp (^ 2))))
188 (##cons val1 (##cdr val2))
192 (define-prim ##degen-cond-or
194 (let ((val1 (##decomp (^ 0)))
195 (val2 (##decomp (^ 1))))
196 (##build-cond (##list val1) val2))))
198 (define-prim ##degen-cond-send
200 (let ((val1 (##decomp (^ 0)))
201 (val2 (##decomp (^ 1)))
202 (val3 (##decomp (^ 2))))
203 (##build-cond (##list val1 '=> val2) val3))))
205 (define-prim (##build-cond clause rest)
206 (cond ((##cond? rest)
207 (##cons 'cond (##cons clause (##cdr rest))))
209 (##cons 'cond (##list clause (##cons 'else (##cdr rest)))))
210 ((##void-constant? rest)
211 (##list 'cond clause))
213 (##list 'cond clause (##list 'else rest)))))
215 (define-prim ##degen-or
217 (let ((val1 (##decomp (^ 0)))
218 (val2 (##decomp (^ 1))))
220 (##cons 'or (##cons val1 (##cdr val2)))
221 (##list 'or val1 val2)))))
223 (define-prim ##degen-and
225 (let ((val1 (##decomp (^ 0)))
226 (val2 (##decomp (^ 1))))
228 (##cons 'and (##cons val1 (##cdr val2)))
229 (##list 'and val1 val2)))))
231 (define-prim ##degen-case
233 (let ((val1 (##decomp (^ 0)))
234 (val2 (##decomp (^ 1))))
235 (##cons 'case (##cons val1 val2)))))
237 (define-prim ##degen-case-clause
239 (let ((val1 (##decomp (^ 0)))
240 (val2 (##decomp (^ 1))))
241 (##cons (if (##begin? val1)
242 (##cons (^ 2) (##cdr val1))
246 (define-prim ##degen-case-else
248 (let ((val (##decomp (^ 0))))
249 (if (##void-constant? val)
251 (##list (if (##begin? val)
252 (##cons 'else (##cdr val))
253 (##list 'else val)))))))
255 (define-prim ##degen-let
257 (let ((n (macro-code-length $code)))
258 (let loop ((i (##fixnum.- n 2)) (vals '()))
260 (loop (##fixnum.- i 1)
261 (##cons (##decomp (macro-code-ref $code i)) vals))
265 (##make-bindings (macro-code-ref $code (##fixnum.- n 1))
268 (##cons 'let (##cons bindings (##cdr body)))
269 (##list 'let bindings body))))))))
271 (define-prim (##make-bindings l1 l2)
273 (##cons (##list (##car l1) (##car l2))
274 (##make-bindings (##cdr l1) (##cdr l2)))
277 (define-prim ##degen-letrec
279 (let ((n (macro-code-length $code)))
280 (let loop ((i (##fixnum.- n 2)) (vals '()))
282 (loop (##fixnum.- i 1)
283 (##cons (##decomp (macro-code-ref $code i)) vals))
287 (##make-bindings (macro-code-ref $code (##fixnum.- n 1))
290 (##cons 'letrec (##cons bindings (##cdr body)))
291 (##list 'letrec bindings body))))))))
293 (define-prim ##degen-prc-req
295 (let* ((n (macro-code-length $code))
296 (body (##decomp (^ 0)))
297 (params (macro-code-ref $code (##fixnum.- n 1))))
299 (##cons 'lambda (##cons params (##cdr body)))
300 (##list 'lambda params body)))))
302 (define-prim ##degen-prc-rest
304 (let ((body (##decomp (^ 0)))
305 (params (##make-params (^ 3) #t #f '())))
307 (##cons 'lambda (##cons params (##cdr body)))
308 (##list 'lambda params body)))))
310 (define-prim ##degen-prc
312 (let ((n (macro-code-length $code)))
313 (let loop ((i (##fixnum.- n 8)) (inits '()))
314 (if (##not (##fixnum.< i 1))
315 (loop (##fixnum.- i 1)
316 (##cons (##decomp (macro-code-ref $code i)) inits))
321 (macro-code-ref $code (##fixnum.- n 1))
322 (macro-code-ref $code (##fixnum.- n 4))
323 (macro-code-ref $code (##fixnum.- n 3))
326 (##cons 'lambda (##cons params (##cdr body)))
327 (##list 'lambda params body))))))))
329 (define-prim (##make-params parms rest? keys inits)
335 (##fixnum.- nb-parms (##fixnum.+ nb-inits (if rest? 1 0))))
337 (##fixnum.- nb-inits (if keys (##vector-length keys) 0))))
340 (let loop ((parms parms)
344 (let ((parm (##car parms)))
347 (##fixnum.- i 1)))))))
349 (define (build-opts parms)
350 (if (##fixnum.= nb-opts 0)
351 (build-rest-and-keys parms inits)
353 (let loop ((parms parms)
357 (build-rest-and-keys parms inits)
358 (let ((parm (##car parms))
359 (init (##car inits)))
360 (##cons (if (##eq? init #f) parm (##list parm init))
363 (##cdr inits)))))))))
365 (define (build-rest-and-keys parms inits)
366 (if (##eq? rest? 'dsssl)
368 (##cons (##car parms)
369 (build-keys (##cdr parms) inits)))
370 (build-keys parms inits)))
372 (define (build-keys parms inits)
374 (build-rest-at-end parms)
376 (let loop ((parms parms)
377 (i (##vector-length keys))
380 (build-rest-at-end parms)
381 (let ((parm (##car parms))
382 (init (##car inits)))
383 (##cons (if (##eq? init #f) parm (##list parm init))
386 (##cdr inits)))))))))
388 (define use-dotted-rest-parameter-when-possible? #t)
390 (define (build-rest-at-end parms)
392 (if use-dotted-rest-parameter-when-possible?
394 (##cons #!rest (##cons (##car parms) '())))
399 (define-prim ##degen-app0
401 (##list (##decomp (^ 0)))))
403 (define-prim ##degen-app1
405 (##list (##decomp (^ 0))
408 (define-prim ##degen-app2
410 (##list (##decomp (^ 0))
414 (define-prim ##degen-app3
416 (##list (##decomp (^ 0))
421 (define-prim ##degen-app4
423 (##list (##decomp (^ 0))
429 (define-prim ##degen-app
431 (let ((n (macro-code-length $code)))
432 (let loop ((i (##fixnum.- n 1)) (vals '()))
433 (if (##not (##fixnum.< i 0))
434 (loop (##fixnum.- i 1)
435 (##cons (##decomp (macro-code-ref $code i)) vals))
438 (define-prim ##degen-delay
440 (##list 'delay (##decomp (^ 0)))))
442 (define-prim ##degen-future
444 (##list 'future (##decomp (^ 0)))))
446 (define-prim ##degen-require
450 ;;;----------------------------------------------------------------------------
452 (define ##decomp-dispatch-table #f)
454 (define-prim (##setup-decomp-dispatch-table)
455 (set! ##decomp-dispatch-table
457 (##cons ##cprc-top ##degen-top)
459 (##cons ##cprc-cst ##degen-cst)
461 (##cons ##cprc-loc-ref-0-1 (mk-degen () (degen ##degen-loc-ref-x-y 0 1)))
462 (##cons ##cprc-loc-ref-0-2 (mk-degen () (degen ##degen-loc-ref-x-y 0 2)))
463 (##cons ##cprc-loc-ref-0-3 (mk-degen () (degen ##degen-loc-ref-x-y 0 3)))
464 (##cons ##cprc-loc-ref-1-1 (mk-degen () (degen ##degen-loc-ref-x-y 1 1)))
465 (##cons ##cprc-loc-ref-1-2 (mk-degen () (degen ##degen-loc-ref-x-y 1 2)))
466 (##cons ##cprc-loc-ref-1-3 (mk-degen () (degen ##degen-loc-ref-x-y 1 3)))
467 (##cons ##cprc-loc-ref-2-1 (mk-degen () (degen ##degen-loc-ref-x-y 2 1)))
468 (##cons ##cprc-loc-ref-2-2 (mk-degen () (degen ##degen-loc-ref-x-y 2 2)))
469 (##cons ##cprc-loc-ref-2-3 (mk-degen () (degen ##degen-loc-ref-x-y 2 3)))
470 (##cons ##cprc-loc-ref ##degen-loc-ref)
471 (##cons ##cprc-loc-ref-box ##degen-loc-ref)
472 (##cons ##cprc-glo-ref ##degen-glo-ref)
474 (##cons ##cprc-loc-set ##degen-loc-set)
475 (##cons ##cprc-loc-set-box ##degen-loc-set)
476 (##cons ##cprc-glo-set ##degen-glo-set)
477 (##cons ##cprc-glo-def ##degen-glo-def)
479 (##cons ##cprc-if2 ##degen-if2)
480 (##cons ##cprc-if3 ##degen-if3)
481 (##cons ##cprc-seq ##degen-seq)
482 (##cons ##cprc-quasi-list->vector ##degen-quasi-list->vector)
483 (##cons ##cprc-quasi-append ##degen-quasi-append)
484 (##cons ##cprc-quasi-cons ##degen-quasi-cons)
485 (##cons ##cprc-cond-if ##degen-cond-if)
486 (##cons ##cprc-cond-or ##degen-cond-or)
487 (##cons ##cprc-cond-send-red ##degen-cond-send)
488 (##cons ##cprc-cond-send-sub ##degen-cond-send)
490 (##cons ##cprc-or ##degen-or)
491 (##cons ##cprc-and ##degen-and)
493 (##cons ##cprc-case ##degen-case)
494 (##cons ##cprc-case-clause ##degen-case-clause)
495 (##cons ##cprc-case-else ##degen-case-else)
497 (##cons ##cprc-let ##degen-let)
498 (##cons ##cprc-letrec ##degen-letrec)
500 (##cons ##cprc-prc-req0 ##degen-prc-req)
501 (##cons ##cprc-prc-req1 ##degen-prc-req)
502 (##cons ##cprc-prc-req2 ##degen-prc-req)
503 (##cons ##cprc-prc-req3 ##degen-prc-req)
504 (##cons ##cprc-prc-req ##degen-prc-req)
505 (##cons ##cprc-prc-rest ##degen-prc-rest)
506 (##cons ##cprc-prc ##degen-prc)
508 (##cons ##cprc-app0-red ##degen-app0)
509 (##cons ##cprc-app1-red ##degen-app1)
510 (##cons ##cprc-app2-red ##degen-app2)
511 (##cons ##cprc-app3-red ##degen-app3)
512 (##cons ##cprc-app4-red ##degen-app4)
513 (##cons ##cprc-app-red ##degen-app)
514 (##cons ##cprc-app0-sub ##degen-app0)
515 (##cons ##cprc-app1-sub ##degen-app1)
516 (##cons ##cprc-app2-sub ##degen-app2)
517 (##cons ##cprc-app3-sub ##degen-app3)
518 (##cons ##cprc-app4-sub ##degen-app4)
519 (##cons ##cprc-app-sub ##degen-app)
521 (##cons ##cprc-delay ##degen-delay)
522 (##cons ##cprc-future ##degen-future)
524 (##cons ##cprc-require ##degen-require)
527 (##setup-decomp-dispatch-table)
529 ;;;----------------------------------------------------------------------------
531 ;;; Pretty-printer that decompiles procedures.
536 (port (macro-absent-obj)))
537 (macro-force-vars (obj port)
539 (if (##eq? port (macro-absent-obj))
542 (macro-check-output-port p 2 (pp obj p)
544 (if (##procedure? obj)
549 (define-prim (##decomp $code)
550 (let ((cprc (macro-code-cprc $code)))
551 (let ((x (##assq cprc ##decomp-dispatch-table)))
556 (define-prim (##decompile proc)
559 (let ((src-info (##subprocedure-source-info p)))
560 (cond ((##source? src-info)
561 (source->expression src-info))
562 ((or (##locat? src-info)
568 (define (compiler-source-code src)
571 (define (source->expression src)
573 (define (list->expression l)
575 (##cons (source->expression (##car l))
576 (list->expression (##cdr l))))
580 (source->expression l))))
582 (define (vector->expression v)
583 (let* ((len (##vector-length v))
584 (x (##make-vector len 0)))
585 (let loop ((i (##fixnum.- len 1)))
586 (if (##not (##fixnum.< i 0))
588 (##vector-set! x i (source->expression (##vector-ref v i)))
589 (loop (##fixnum.- i 1)))))
592 (let ((code (compiler-source-code src)))
593 (cond ((##pair? code) (list->expression code))
594 ((##vector? code) (vector->expression code))
598 (cond ((##interp-procedure? p)
599 (let* (($code (##interp-procedure-code p))
600 (cprc (macro-code-cprc $code)))
601 (if (##eq? cprc ##interp-procedure-wrapper)
605 (decomp (##closure-code p)))
609 (define-prim (##procedure-locat proc)
612 (let ((src-info (##subprocedure-source-info p)))
613 (cond ((##source? src-info)
614 (compiler-source-locat src-info))
620 (define (compiler-source-locat src)
621 (##source-locat src))
624 (cond ((##interp-procedure? p)
625 (let* (($code (##interp-procedure-code p))
626 (cprc (macro-code-cprc $code)))
627 (if (##eq? cprc ##interp-procedure-wrapper)
629 (##code-locat $code))))
631 (locat (##closure-code p)))
635 (define-prim (##code-locat $code)
636 (let ((locat-or-position (macro-code-locat $code)))
637 (if (or (##locat? locat-or-position) (##not locat-or-position))
639 (let loop ((parent (macro-code-link $code)))
641 (let ((locat-or-position-parent (macro-code-locat parent)))
642 (if (##locat? locat-or-position-parent)
643 (##make-locat (##locat-container locat-or-position-parent)
645 (loop (macro-code-link parent))))
648 (define-prim (##subprocedure-source-info proc)
649 (let ((info (##subprocedure-info proc)))
651 (##vector-ref info 1)
654 (define-prim (##subprocedure-info proc)
655 (let* ((id (##subprocedure-id proc))
656 (parent-info (##subprocedure-parent-info proc)))
658 (let ((v (##vector-ref parent-info 0)))
659 (let loop ((i (##fixnum.- (##vector-length v) 1)))
662 (let ((x (##vector-ref v i)))
663 (if (##fixnum.= id (##vector-ref x 0))
665 (loop (##fixnum.- i 1)))))))
668 ;;;============================================================================
672 ;;;----------------------------------------------------------------------------
674 (define-prim (##procedure-friendly-name p)
675 (or (##procedure-name p)
678 (define-prim (##procedure-name p)
679 (and (##procedure? p)
680 (or (and (##interp-procedure? p)
681 (let* (($code (##interp-procedure-code p))
682 (rte (##interp-procedure-rte p)))
683 (##object->lexical-var->identifier
684 (macro-code-cte $code)
687 (##object->global-var->identifier p))))
689 (define-prim (##object->lexical-var->identifier cte rte obj)
692 (cond ((##cte-top? c)
695 (let loop2 ((vars (##cte-frame-vars c))
698 (let ((var (##car vars)))
699 (if (and (##not (##hidden-local-var? var))
700 (let ((val-or-box (##vector-ref r i)))
702 (if (and (##var-c? var)
703 (##var-c-boxed? var))
709 (loop1 (##cte-parent-cte c)
712 (loop1 (##cte-parent-cte c)
715 ;;;----------------------------------------------------------------------------
717 ;; Internal variables and parameters are uninteresting for the user.
719 (define-prim (##hidden-local-var? var)
720 (and ;; (##var-i? var) test is redundant
721 (or (##eq? var (macro-self-var))
722 (##eq? var (macro-selector-var))
723 (##eq? var (macro-do-loop-var)))))
725 (define-prim (##hidden-parameter? param)
726 (or (##eq? param ##trace-depth)
727 (##eq? param ##current-user-interrupt-handler)))
729 ;;;----------------------------------------------------------------------------
731 ;;; Access to structure of closures for interpreter procedures.
733 ;; Layout of closed variables for closures created by ##cprc-prcXXX and
734 ;; ##interp-procedure-wrapper:
740 (define ##interp-procedure-code-pointers
741 (let (($code (macro-make-code #f #f #f (##no-stepper) ()))
743 (##list (##closure-code (##cprc-prc-req0 $code rte))
744 (##closure-code (##cprc-prc-req1 $code rte))
745 (##closure-code (##cprc-prc-req2 $code rte))
746 (##closure-code (##cprc-prc-req3 $code rte))
747 (##closure-code (##cprc-prc-req $code rte))
748 (##closure-code (##cprc-prc-rest $code rte))
749 (##closure-code (##cprc-prc $code rte))
750 (##closure-code (##interp-procedure-wrapper $code rte)))))
752 (define-prim (##interp-procedure? x)
753 (and (##procedure? x)
755 (##memq (##closure-code x) ##interp-procedure-code-pointers)))
757 (define-prim (##interp-procedure-code x) ;; return "$code" closed variable of x
760 (define-prim (##interp-procedure-rte x) ;; return "rte" closed variable of x
763 ;;;----------------------------------------------------------------------------
765 ;;; Access to continuations
767 (define-prim (##continuation-parent cont)
768 (##subprocedure-parent (##continuation-ret cont)))
770 (define ##show-all-continuations? #f)
771 (set! ##show-all-continuations? #f)
773 (define-prim (##hidden-continuation? cont)
774 (if ##show-all-continuations?
776 (let ((parent (##continuation-parent cont)))
777 (or (##eq? parent ##interp-procedure-wrapper);;;;;;;;;;;;;;;;;;
778 (##eq? parent ##dynamic-wind)
779 (##eq? parent ##dynamic-env-bind)
780 (##eq? parent ##kernel-handlers)
781 (##eq? parent ##execute-modules)
782 (##eq? parent ##repl-debug)
783 (##eq? parent ##repl-debug-main)
784 (##eq? parent ##repl-within)
785 (##eq? parent ##eval-within)
786 (##eq? parent ##with-no-result-expected)
787 (##eq? parent ##with-no-result-expected-toplevel)
788 (##eq? parent ##check-heap)
789 (##eq? parent ##nontail-call-for-leap)
790 (##eq? parent ##nontail-call-for-step)
791 (##eq? parent ##trace-generate)
792 (##eq? parent ##thread-interrupt!)
793 (##eq? parent ##thread-call)))))
795 (define-prim (##interp-subproblem-continuation? cont)
796 (let ((parent (##continuation-parent cont)))
797 (or (##eq? parent ##subproblem-apply0)
798 (##eq? parent ##subproblem-apply1)
799 (##eq? parent ##subproblem-apply2)
800 (##eq? parent ##subproblem-apply3)
801 (##eq? parent ##subproblem-apply4)
802 (##eq? parent ##subproblem-apply))))
804 (define-prim (##interp-internal-continuation? cont)
805 (let ((parent (##continuation-parent cont)))
806 (or (##eq? parent ##step-handler)
807 (##eq? parent ##repl-within-proc)
808 (##assq parent ##decomp-dispatch-table))))
810 (define-prim (##interp-continuation? cont)
811 (or (##interp-subproblem-continuation? cont)
812 (##interp-internal-continuation? cont)))
814 (define-prim (##continuation-creator cont) ;; returns #f if creator is REPL
816 (if (##interp-continuation? cont)
817 (let (($code (##interp-continuation-code cont))
818 (rte (##interp-continuation-rte cont)))
819 (##extract-container $code rte))
820 (##continuation-parent cont))))
822 (define-prim (##continuation-locat cont) ;; returns #f if location unknown
824 (if (##interp-continuation? cont)
825 (##code-locat (##interp-continuation-code cont))
826 (##procedure-locat (##continuation-ret cont)))))
828 (define-prim (##interp-continuation-code cont)
829 (##local->value (##continuation-locals cont '$code)))
831 (define-prim (##interp-continuation-rte cont)
832 (##local->value (##continuation-locals cont 'rte)))
834 (define-prim (##local->value x)
835 (let ((var-c (##car x))
836 (val-or-box (##cdr x)))
837 (if (##var-c-boxed? var-c)
841 (define-prim (##interesting-continuation? cont)
842 (or ##show-all-continuations?
843 (##interp-subproblem-continuation? cont)
844 (and (##not (##interp-internal-continuation? cont))
845 (##not (##hidden-continuation? cont)))))
847 (define-prim (##continuation-first-frame cont all-frames?)
850 (##not (##hidden-continuation? cont)))
852 (##continuation-next-frame cont all-frames?))))
854 (define-prim (##continuation-next-frame cont all-frames?)
856 (let loop ((cont cont))
857 (let ((next (##continuation-next cont)))
860 (##interesting-continuation? next))
864 (define-prim (##continuation-count-frames cont all-frames?)
865 (let loop ((cont cont) (n 0))
867 (loop (##continuation-next cont)
869 (##interesting-continuation? cont))
874 (define-prim (##continuation-locals cont #!optional (var (macro-absent-obj)))
875 (##subprocedure-locals (##continuation-ret cont) cont var))
877 (define-prim (##subprocedure-locals
880 (cont (macro-absent-obj))
881 (var (macro-absent-obj)))
882 (let* ((parent-info (##subprocedure-parent-info proc))
883 (info (##subprocedure-info proc)))
884 (if (and parent-info info)
885 (let ((var-descrs (##vector-ref parent-info 1)))
886 (let loop1 ((j 2) (result '()))
887 (if (##fixnum.< j (##vector-length info))
889 (##vector-ref info j))
891 (##fixnum.quotient descr 32768))
894 (##fixnum.modulo descr 32768)
897 (##vector-ref var-descrs var-descr-index))
899 (if (##eq? cont (macro-absent-obj))
901 (##continuation-ref cont slot-index))))
904 (##cons (##var-c var-descr
906 (##fixnum.modulo descr 2)
910 (if (##pair? var-descr)
912 (let loop2 ((lst var-descr) (result result))
917 (##fixnum.quotient descr 32768))
920 (##fixnum.modulo descr 32768)
923 (##vector-ref var-descrs var-descr-index)))
926 (##cons (##var-c var-descr
928 (##fixnum.modulo descr 2)
930 (##closure-ref val-or-box1
933 (cond ((##eq? cont (macro-absent-obj))
937 ((##eq? var (macro-absent-obj))
942 (if (##eq? var var-descr)
946 (loop1 (##fixnum.+ j 1)
949 (cond ((##eq? cont (macro-absent-obj))
950 (loop1 (##fixnum.+ j 1)
953 ((##eq? var (macro-absent-obj))
954 (loop1 (##fixnum.+ j 1)
958 (if (##eq? var var-descr)
960 (loop1 (##fixnum.+ j 1)
965 ;;;----------------------------------------------------------------------------
967 (define-prim (##cmd-? port)
969 ",? : Summary of comma commands
970 ,h | ,(h X) : Help on procedure of last error or procedure/macro named X
971 ,q : Terminate the process
972 ,qt : Terminate the current thread
973 ,t : Jump to toplevel REPL
974 ,d : Jump to enclosing REPL
975 ,c | ,(c X) : Continue the computation with stepping off
976 ,s | ,(s X) : Continue the computation with stepping on (step)
977 ,l | ,(l X) : Continue the computation with stepping on (leap)
978 ,N : Move to specific continuation frame (N>=0)
979 ,N+ | ,N- : Move forward/backward by N continuation frames (N>=0)
980 ,+ | ,- : Like ,1+ and ,1-
981 ,++ | ,-- : Like ,N+ and ,N- with N = nb. of frames at head of backtrace
982 ,y : Display one-line summary of current frame
983 ,i : Display procedure attached to current frame
984 ,b | ,(b X) : Display backtrace of current continuation or X (cont/thread)
985 ,be | ,(be X) : Like ,b and ,(b X) but also display environment
986 ,bed | ,(bed X) : Like ,be and ,(be X) but also display dynamic environment
987 ,e | ,(e X) : Display environment of current frame or X (proc/cont/thread)
988 ,ed | ,(ed X) : Like ,e and ,(e X) but also display dynamic environment
989 ,st | ,(st X) : Display current thread group, or X (thread/thread group)
990 ,(v X) : Start a REPL visiting X (proc/cont/thread)
993 ;;;,(p [N M]) : Configure REPL's pretty printer (N=max level, M=max length)
995 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
997 (define ##backtrace-default-max-head #f)
998 (set! ##backtrace-default-max-head 10)
1000 (define ##backtrace-default-max-tail #f)
1001 (set! ##backtrace-default-max-tail 4)
1003 (define ##frame-locat-display? #f)
1004 (set! ##frame-locat-display? #t)
1006 (define ##frame-call-display? #f)
1007 (set! ##frame-call-display? #t)
1009 (define-prim (##cmd-b cont port depth display-env?)
1010 (##display-continuation-backtrace
1015 ##backtrace-default-max-head
1016 ##backtrace-default-max-tail
1019 (define-prim (##display-continuation-backtrace
1028 (j (##fixnum.- (##continuation-count-frames cont all-frames?) 1))
1029 (cont (##continuation-first-frame cont all-frames?)))
1032 (cond ((or (##fixnum.< i max-head) (##fixnum.< j max-tail)
1033 (and (##fixnum.= i max-head) (##fixnum.= j max-tail)))
1034 (##display-continuation-frame
1039 (##fixnum.+ depth i)))
1040 ((##fixnum.= i max-head)
1041 (##write-string "..." port)
1043 (loop (##fixnum.+ i 1)
1045 (##continuation-next-frame cont all-frames?))))))
1047 (define-prim (display-continuation-backtrace
1050 (port (macro-absent-obj))
1051 (all-frames? (macro-absent-obj))
1052 (display-env? (macro-absent-obj))
1053 (max-head (macro-absent-obj))
1054 (max-tail (macro-absent-obj))
1055 (depth (macro-absent-obj)))
1056 (macro-force-vars (cont port all-frames? display-env? max-head max-tail depth)
1058 (if (##eq? port (macro-absent-obj))
1059 (macro-current-output-port)
1062 (if (##eq? display-env? (macro-absent-obj))
1066 (if (##eq? all-frames? (macro-absent-obj))
1070 (if (##eq? max-head (macro-absent-obj))
1071 ##backtrace-default-max-head
1074 (if (##eq? max-tail (macro-absent-obj))
1075 ##backtrace-default-max-tail
1078 (if (##eq? depth (macro-absent-obj))
1081 (macro-check-continuation cont 1 (display-continuation-backtrace cont port display-env? all-frames? max-head max-tail depth)
1082 (macro-check-character-output-port p 2 (display-continuation-backtrace cont port display-env? all-frames? max-head max-tail depth)
1083 (macro-check-fixnum mh 5 (display-continuation-backtrace cont port display-env? all-frames? max-head max-tail depth)
1084 (macro-check-fixnum mt 6 (display-continuation-backtrace cont port display-env? all-frames? max-head max-tail depth)
1085 (macro-check-fixnum d 7 (display-continuation-backtrace cont port display-env? all-frames? max-head max-tail depth)
1086 (##display-continuation-backtrace cont p de af mh mt d)))))))))
1088 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1090 (define-prim (##cmd-y cont port pinpoint? depth)
1091 (##display-continuation-frame
1098 (define-prim (##display-continuation-frame
1106 (let* ((current (##output-port-column port))
1107 (n (##fixnum.- col current)))
1108 (##display-spaces (##fixnum.max n 1) port)))
1111 (let ((port-width (##output-port-width port)))
1113 (define depth-width 4)
1114 (define creator-width 24)
1115 (define locat-width 24)
1116 (define call-width 27)
1122 (##fixnum.- port-width
1130 (##fixnum.+ depth-width
1138 ##frame-locat-display?)
1140 ##frame-call-display?))
1141 (##write depth port)
1143 (let ((creator (##continuation-creator cont)))
1145 (##write (##procedure-friendly-name creator) port)
1146 (##write-string "(interaction)" port)))
1150 (let ((locat (##continuation-locat cont)))
1151 (##display-locat locat pinpoint? port))))
1154 (if (##interp-continuation? cont)
1155 (let* (($code (##interp-continuation-code cont))
1156 (cprc (macro-code-cprc $code)))
1157 (if (##eq? cprc ##interp-procedure-wrapper)
1160 (let* ((ret (##continuation-ret cont))
1161 (call (##decompile ret)))
1162 (if (##eq? call ret)
1167 (tab (if locat-display? col4 col3))
1171 (##fixnum.- port-width
1172 (##output-port-column port)))
1175 (##display-continuation-env
1178 (##fixnum.+ 4 depth-width)
1181 (define-prim (##display-spaces n port)
1182 (if (##fixnum.< 0 n)
1183 (let ((m (if (##fixnum.< 40 n) 40 n)))
1184 (##write-substring " " 0 m port)
1185 (##display-spaces (##fixnum.- n m) port)
1188 (define-prim (##display-locat locat pinpoint? port)
1189 (if locat ;; locat is #f if location unknown
1190 (let* ((container (##locat-container locat))
1191 (path (##container->path container)))
1193 (##write (##path-normalize path
1194 ##repl-location-relative
1195 ##repl-location-origin
1198 (##write-string (##container->id container) port))
1199 (let* ((filepos (##position->filepos (##locat-position locat)))
1200 (line (##fixnum.+ (##filepos-line filepos) 1))
1201 (col (##fixnum.+ (##filepos-col filepos) 1)))
1202 (##write-string "@" port)
1204 (##write-string (if pinpoint? "." ":") port)
1205 (##write col port)))))
1207 (define ##repl-location-relative #f)
1208 (set! ##repl-location-relative 'shortest)
1210 (define ##repl-location-origin #f)
1211 (set! ##repl-location-origin #f)
1213 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1215 (define-prim (##inverse-eval-in-env obj cte)
1216 (if (##procedure? obj)
1217 (let ((id (##object->global-var->identifier obj)))
1220 (let ((x (##decompile obj)))
1221 (if (##procedure? x)
1226 (let ((ind (##cte-lookup cte id)))
1227 (if (##eq? (##vector-ref ind 0) 'not-found)
1232 (##inverse-eval obj)))
1234 (define-prim (##inverse-eval obj)
1235 (if (##self-eval? obj)
1237 (##list 'quote obj)))
1239 (define (##display-var-val var val-or-box cte indent port)
1240 (cond ((##var-i? var)
1241 (##display-var-val-aux (##var-i-name var)
1247 ((##var-c-boxed? var)
1248 (##display-var-val-aux (##var-c-name var)
1249 (##unbox val-or-box)
1255 (##display-var-val-aux (##var-c-name var)
1262 (define (##display-var-val-aux var val mutable? cte indent port)
1263 (##display-spaces indent port)
1265 (##write-string (if mutable? " = " " == ") port)
1268 (if (##cte-top? cte)
1269 (##inverse-eval-in-env val cte)
1270 (##inverse-eval-in-env val (##cte-parent-cte cte)))
1271 (##fixnum.- (##output-port-width port)
1272 (##output-port-column port)))
1276 (define (##display-rte cte rte indent port)
1279 (cond ((##cte-top? c))
1281 (let loop2 ((vars (##cte-frame-vars c))
1282 (vals (##cdr (##vector->list r))))
1284 (let ((var (##car vars)))
1285 (if (##not (##hidden-local-var? var))
1286 (let ((val-or-box (##car vals)))
1287 (##display-var-val var val-or-box c indent port)))
1290 (loop1 (##cte-parent-cte c)
1291 (macro-rte-up r)))))
1293 (loop1 (##cte-parent-cte c)
1296 (define (##display-vars lst cte indent port)
1297 (let loop ((lst lst))
1299 (let* ((loc (##car lst))
1302 (##display-var-val var val cte indent port)
1303 (loop (##cdr lst))))))
1305 (define (##display-locals lst cte indent port)
1307 (##display-vars lst cte indent port)))
1309 (define (##display-parameters lst cte indent port)
1310 (let loop ((lst lst))
1312 (let* ((param-val (##car lst))
1313 (param (##car param-val))
1314 (val (##cdr param-val)))
1315 (if (##not (##hidden-parameter? param))
1316 (let ((x (##inverse-eval-in-env param cte)))
1317 (##display-var-val-aux (##list x) val #t cte indent port)))
1318 (loop (##cdr lst))))))
1320 (define-prim (##display-continuation-environment cont port indent)
1321 (if (##interp-continuation? cont)
1322 (let (($code (##interp-continuation-code cont))
1323 (rte (##interp-continuation-rte cont)))
1324 (##display-rte (macro-code-cte $code) rte indent port))
1325 (##display-locals (##continuation-locals cont)
1331 (define-prim (display-continuation-environment
1334 (port (macro-absent-obj))
1335 (indent (macro-absent-obj)))
1336 (macro-force-vars (cont port indent)
1338 (if (##eq? port (macro-absent-obj))
1339 (macro-current-output-port)
1342 (if (##eq? indent (macro-absent-obj))
1345 (macro-check-continuation cont 1 (display-continuation-environment cont port indent)
1346 (macro-check-character-output-port p 2 (display-continuation-environment cont p indent)
1347 (macro-check-fixnum i 3 (display-continuation-environment cont p i)
1348 (##display-continuation-environment cont p i)))))))
1350 (define-prim (##display-continuation-dynamic-environment cont port indent)
1351 (##display-parameters
1352 (##dynamic-env->list (macro-continuation-denv cont))
1353 (if (##interp-continuation? cont)
1354 (let (($code (##interp-continuation-code cont)))
1355 (macro-code-cte $code))
1361 (define-prim (display-continuation-dynamic-environment
1364 (port (macro-absent-obj))
1365 (indent (macro-absent-obj)))
1366 (macro-force-vars (cont port indent)
1368 (if (##eq? port (macro-absent-obj))
1369 (macro-current-output-port)
1372 (if (##eq? indent (macro-absent-obj))
1375 (macro-check-continuation cont 1 (display-continuation-dynamic-environment cont port indent)
1376 (macro-check-character-output-port p 2 (display-continuation-dynamic-environment cont p indent)
1377 (macro-check-fixnum i 3 (display-continuation-dynamic-environment cont p i)
1378 (##display-continuation-dynamic-environment cont p i)))))))
1380 (define ##display-dynamic-environment?
1381 (##make-parameter #f))
1383 (define display-dynamic-environment?
1384 ##display-dynamic-environment?)
1386 (define-prim (##display-continuation-env cont port indent display-env?)
1388 (let ((c (##continuation-first-frame cont #f)))
1390 (##display-continuation-environment c port indent))
1391 (if (or (##eq? display-env? 'dynamic)
1392 (##display-dynamic-environment?))
1393 (##display-continuation-dynamic-environment cont port indent)))))
1395 (define-prim (##cmd-e proc-or-cont port display-env?)
1397 (if (##continuation? proc-or-cont)
1398 (##display-continuation-env proc-or-cont port 0 display-env?)
1399 (##display-procedure-environment proc-or-cont port 0))))
1401 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1403 (define-prim (##display-procedure-environment proc port indent)
1404 (cond ((##interp-procedure? proc)
1405 (let* (($code (##interp-procedure-code proc))
1406 (rte (##interp-procedure-rte proc)))
1407 (##display-rte (macro-code-cte $code) rte indent port)))
1409 (error "Can't access compiled procedure's environment")));;;;;;;;;;;
1412 (define-prim (display-procedure-environment
1415 (port (macro-absent-obj))
1416 (indent (macro-absent-obj)))
1417 (macro-force-vars (proc port indent)
1419 (if (##eq? port (macro-absent-obj))
1420 (macro-current-output-port)
1423 (if (##eq? indent (macro-absent-obj))
1426 (macro-check-procedure proc 1 (display-procedure-environment proc port indent)
1427 (macro-check-character-output-port p 2 (display-procedure-environment proc p indent)
1428 (macro-check-fixnum i 3 (display-procedure-environment proc p i)
1429 (##display-procedure-environment proc p i)))))))
1431 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1433 (define-prim (##cmd-i cont port)
1435 (let ((creator (##continuation-creator cont)))
1437 (let ((decomp-creator (##decompile creator)))
1438 (##write creator port)
1439 (if (##eq? creator decomp-creator)
1442 (##write-string " =" port)
1444 (##pretty-print decomp-creator port))))
1446 (##write-string "(interaction)" port)
1447 (##newline port))))))
1449 ;;; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1451 (define-prim (##cmd-st thread-or-tgroup port)
1452 (if (macro-thread? thread-or-tgroup)
1453 (##display-thread-state thread-or-tgroup port)
1454 (##display-thread-group-state thread-or-tgroup port))
1457 (define-prim (##display-thread-state thread port)
1458 (let ((now (##current-time-point)))
1459 (##display-thread-state-relative thread port now)))
1461 (define-prim (##display-thread-state-relative thread port time-point)
1464 (let* ((current (##output-port-column port))
1465 (n (##fixnum.- col current)))
1466 (##display-spaces (##fixnum.max n 1) port)))
1468 (define (write-timeout to)
1469 (##write-string " " port)
1470 (let ((expiry (##flonum.- (macro-time-point to) time-point)))
1471 (##write (##flonum./ (##flonum.round (##flonum.* 10.0 expiry)) 10.0)
1473 (##write-string "s" port))
1475 (let ((port-width (##output-port-width port)))
1477 (define thread-width 14)
1483 (##fixnum.- port-width thread-width)
1485 (##write thread port)
1486 (tab (##fixnum.+ thread-width extra))
1487 (let ((ts (##thread-state thread)))
1488 (cond ((macro-thread-state-uninitialized? ts)
1489 (##write-string "UNINITIALIZED" port))
1490 ((macro-thread-state-initialized? ts)
1491 (##write-string "INITIALIZED" port))
1492 ((macro-thread-state-normally-terminated? ts)
1493 (##write-string "NORMALLY TERMINATED" port))
1494 ((macro-thread-state-abnormally-terminated? ts)
1495 (##write-string "ABNORMALLY TERMINATED" port))
1496 ((macro-thread-state-active? ts)
1497 (let ((wf (macro-thread-state-active-waiting-for ts))
1498 (to (macro-thread-state-active-timeout ts)))
1500 (##write-string "WAITING " port)
1503 (write-timeout to)))
1505 (##write-string "SLEEPING" port)
1508 (##write-string "RUNNING" port)))))
1510 (##write ts port))))
1513 (define-prim (##display-thread-group-state tgroup port)
1514 (let* ((threads (##tgroup->thread-vector tgroup))
1515 (now (##current-time-point)))
1517 (if (##fixnum.< i (##vector-length threads))
1518 (let ((thread (##vector-ref threads i)))
1519 (##display-thread-state-relative thread port now)
1520 (loop (##fixnum.+ i 1)))
1523 (define-prim (##top tgroup port)
1525 (define interval 1.0)
1528 (##write-string "\033[" port)
1530 (##write-string "A\033[J" port))
1532 (let ((start-time-point (##current-time-point)))
1533 (let loop ((last start-time-point))
1534 (##write-string "*** THREAD LIST:\n" port)
1535 (let* ((n (##fixnum.+ 1 (##display-thread-group-state tgroup port)))
1536 (next (##flonum.+ last interval))
1537 (now (##current-time-point))
1538 (diff (##flonum.- next now)))
1539 (if (##flonum.negative? diff)
1544 (##thread-sleep! diff)
1550 (tgroup (macro-absent-obj))
1551 (port (macro-absent-obj)))
1552 (macro-force-vars (port)
1554 (if (##eq? tgroup (macro-absent-obj))
1555 (macro-thread-tgroup (macro-current-thread))
1558 (if (##eq? port (macro-absent-obj))
1559 (##repl-output-port)
1561 (macro-check-tgroup tg 1 (top tgroup port)
1562 (macro-check-character-output-port p 2 (top tgroup port)
1565 ;;;----------------------------------------------------------------------------
1567 ;;; Tracing and single stepping.
1569 (define-prim (##interp-procedure-entry-hook proc)
1570 (let (($code (##interp-procedure-code proc)))
1571 (macro-code-ref $code (##fixnum.- (macro-code-length $code) 2))))
1573 (define-prim (##interp-procedure-entry-hook-set! proc hook)
1574 (let (($code (##interp-procedure-code proc)))
1575 (macro-code-set! $code (##fixnum.- (macro-code-length $code) 2) hook)))
1577 (define-prim (##interp-procedure-default-entry-hook proc)
1578 (let ((hook (##interp-procedure-entry-hook proc)))
1581 (##eq? (##subprocedure-parent (##closure-code hook))
1582 ##make-default-entry-hook))
1586 (define-prim (##make-default-entry-hook)
1587 (let ((settings (##vector #f #f)))
1588 (lambda (proc args execute)
1589 (if (##vector-ref settings 0)
1590 (##step-on)) ;; turn on single-stepping
1591 (if (##vector-ref settings 1)
1593 (##make-call-form proc
1594 (##argument-list-remove-absent! args '())
1600 (define-prim (##make-call-form proc args max-args)
1602 (define (inverse-eval-args i lst)
1604 (if (##fixnum.< max-args i)
1606 (##cons (##inverse-eval (##car lst))
1607 (inverse-eval-args (##fixnum.+ i 1) (##cdr lst))))
1610 (##cons (##procedure-friendly-name proc)
1611 (inverse-eval-args 1 args)))
1613 (define ##trace-depth (##make-parameter 0))
1615 (define-prim (##trace-generate form execute leap?)
1617 (define max-depth 10)
1619 (define (bars width output-port)
1621 (if (##fixnum.< i width)
1624 (if (##fixnum.= (##fixnum.remainder i 2) 0) "|" " ")
1626 (loop (##fixnum.+ i 1))))))
1628 (define (bars-width depth)
1629 (let ((d (if (##fixnum.< max-depth depth) max-depth depth)))
1630 (if (##fixnum.< 0 d) (##fixnum.- (##fixnum.* d 2) 1) 0)))
1632 (define (indent depth output-port)
1633 (let ((w (bars-width depth)))
1634 (if (##fixnum.< max-depth depth)
1635 (let ((depth-str (##number->string depth 10)))
1636 (bars (##fixnum.- w (##fixnum.+ (##string-length depth-str) 2))
1638 (##write-string "[" output-port)
1639 (##write-string depth-str output-port)
1640 (##write-string "]" output-port))
1641 (bars w output-port))
1644 (define (output-to-repl proc)
1645 (let ((old (##current-user-interrupt-handler)))
1647 ##current-user-interrupt-handler
1648 ##defer-user-interrupts
1651 (##current-user-interrupt-handler old)))))
1653 (##continuation-capture
1656 (##continuation-parent cont))
1658 (and (##not (##eq? ##nontail-call-for-leap parent))
1659 (##not (##eq? ##nontail-call-for-step parent))))
1664 (##fixnum.+ current-depth 1)
1667 (define (nest wrapper)
1672 (lambda () (wrapper execute)))))
1675 (lambda (first output-port)
1677 (##fixnum.+ (indent depth output-port) 1)))
1678 (##write-string " " output-port)
1682 (##fixnum.- (##output-port-width output-port) width))
1684 (##newline output-port)
1690 (lambda (first output-port)
1692 (##fixnum.+ (indent depth output-port) 3)))
1693 (##write-string " > " output-port)
1697 (##fixnum.- (##output-port-width output-port) width))
1699 (##newline output-port)
1703 (cond ((##eq? ##nontail-call-for-leap parent)
1705 ((##eq? ##nontail-call-for-step parent)
1706 (##nontail-call-for-leap execute))
1708 (nest ##nontail-call-for-leap)))
1709 (cond ((##eq? ##nontail-call-for-leap parent)
1711 ((##eq? ##nontail-call-for-step parent)
1714 (nest ##nontail-call-for-step))))))))
1716 (define-prim (##nontail-call-for-leap execute)
1717 (let ((result (execute)))
1721 (define-prim (##nontail-call-for-step execute)
1722 (##first-argument (execute)))
1724 (define ##trace-list '())
1726 (define-prim (##trace proc)
1728 (define (setup hook)
1729 (let ((settings (##closure-ref hook 1)))
1730 (##vector-set! settings 1 #t)
1731 (if (##not (##memq proc ##trace-list))
1732 (set! ##trace-list (##cons proc ##trace-list)))))
1734 (let ((hook (##interp-procedure-default-entry-hook proc)))
1737 (let ((new-hook (##make-default-entry-hook)))
1738 (##interp-procedure-entry-hook-set! proc new-hook)
1739 (setup new-hook)))))
1741 (define-prim (##untrace proc)
1742 (let ((hook (##interp-procedure-default-entry-hook proc)))
1744 (let ((settings (##closure-ref hook 1)))
1745 (##vector-set! settings 1 #f)
1746 (if (##not (##vector-ref settings 0))
1747 (##interp-procedure-entry-hook-set! proc #f))))
1748 (set! ##trace-list (##remove proc ##trace-list))))
1750 (define-prim (trace . args)
1752 (##for-each-interp-procedure
1759 (define-prim (untrace . args)
1760 (##for-each-interp-procedure
1764 (if (##pair? args) args ##trace-list)))
1766 (define ##break-list '())
1768 (define-prim (##break proc)
1770 (define (setup hook)
1771 (let ((settings (##closure-ref hook 1)))
1772 (##vector-set! settings 0 #t)
1773 (if (##not (##memq proc ##break-list))
1774 (set! ##break-list (##cons proc ##break-list)))))
1776 (let ((hook (##interp-procedure-default-entry-hook proc)))
1779 (let ((new-hook (##make-default-entry-hook)))
1780 (##interp-procedure-entry-hook-set! proc new-hook)
1781 (setup new-hook)))))
1783 (define-prim (##unbreak proc)
1784 (let ((hook (##interp-procedure-default-entry-hook proc)))
1786 (let ((settings (##closure-ref hook 1)))
1787 (##vector-set! settings 0 #f)
1788 (if (##not (##vector-ref settings 1))
1789 (##interp-procedure-entry-hook-set! proc #f))))
1790 (set! ##break-list (##remove proc ##break-list))))
1792 (define-prim (break . args)
1794 (##for-each-interp-procedure
1801 (define-prim (unbreak . args)
1802 (##for-each-interp-procedure
1806 (if (##pair? args) args ##break-list)))
1808 (define-prim (##step-on)
1809 (##declare (not interrupts-enabled))
1810 (let* ((stepper (##current-stepper))
1811 (handlers (##vector-ref stepper 0)))
1812 (let loop ((i (##vector-length handlers)))
1813 (if (##not (##fixnum.< i 1))
1814 (let ((i-1 (##fixnum.- i 1)))
1815 (##vector-set! stepper i (##vector-ref handlers i-1))
1819 (define-prim (##step-off)
1820 (##declare (not interrupts-enabled))
1821 (let* ((stepper (##current-stepper))
1822 (handlers (##vector-ref stepper 0)))
1823 (let loop ((i (##vector-length handlers)))
1824 (if (##not (##fixnum.< i 1))
1825 (let ((i-1 (##fixnum.- i 1)))
1826 (##vector-set! stepper i #f)
1833 (define-prim (##step-level-set! n)
1834 (##declare (not interrupts-enabled))
1835 (let* ((stepper (##current-stepper))
1836 (handlers (##vector-ref stepper 0)))
1837 (let loop ((i (##vector-length handlers)))
1838 (if (##not (##fixnum.< i 1))
1839 (let ((i-1 (##fixnum.- i 1)))
1840 (##vector-set! handlers i-1
1841 (if (##fixnum.< i-1 n)
1842 (##vector-ref ##step-handlers i-1)
1847 (define-prim (step-level-set! n)
1848 (macro-force-vars (n)
1849 (macro-check-fixnum-range-incl n 1 0 7 (step-level-set! n)
1850 (##step-level-set! n))))
1852 (define ##step-handlers (macro-make-step-handlers))
1854 (set! ##main-stepper (macro-make-main-stepper))
1856 (define ##repl-display-environment?
1857 (##make-parameter #f))
1859 (define repl-display-environment?
1860 ##repl-display-environment?)
1862 (define-prim (display-environment-set! display?)
1864 (##repl-display-environment? (if display? #t #f))
1867 (define-prim (##step-handler leapable? $code rte execute-body . other)
1868 (##declare (not interrupts-enabled) (environment-map))
1869 (##step-off) ;; turn off single-stepping
1870 (##step-handler-continue
1871 (##step-handler-get-command $code rte)
1878 (define-prim (##step-handler-continuation? cont)
1879 (##eq? (##continuation-parent cont) ##step-handler))
1881 (define-prim (##with-no-result-expected-continuation? cont)
1882 (##eq? (##continuation-parent cont) ##with-no-result-expected))
1884 (define-prim (##with-no-result-expected-toplevel-continuation? cont)
1885 (##eq? (##continuation-parent cont) ##with-no-result-expected-toplevel))
1887 (define-prim (##step-handler-get-command $code rte)
1889 (lambda (first output-port)
1890 (##display-situation
1892 (##extract-container $code rte)
1893 (##code-locat $code)
1895 (##newline output-port)
1898 (define-prim (##step-handler-continue cmd leapable? $code rte execute-body other)
1900 ;; cmd is one of the symbols "c", "s" or "l" or a one element vector
1903 (##apply execute-body (##cons $code (##cons rte other))))
1905 (cond ((##eq? cmd 'c)
1907 ((and (##eq? cmd 'l) leapable?)
1908 (##trace-generate (##decomp $code) execute #t))
1909 ((or (##eq? cmd 'l) (##eq? cmd 's))
1911 (##trace-generate (##decomp $code) execute #f))
1913 (##vector-ref cmd 0))))
1915 (define-prim (##for-each-interp-procedure prim args fn procs)
1916 (let loop ((lst1 procs) (lst2 '()) (arg-num 1))
1918 (let ((proc (##car lst1)))
1919 (if (##procedure? proc)
1920 (if (##interp-procedure? proc)
1923 (##fixnum.+ arg-num 1))
1924 (let ((id (##object->global-var->identifier proc)))
1925 (if id ;; procedure is bound to a global variable
1928 (lambda (first output-port)
1930 "*** WARNING -- Rebinding global variable \""
1932 (##write id output-port)
1934 "\" to an interpreted procedure\n"
1938 (##make-interp-procedure proc)))
1939 (##global-var-set! (##make-global-var id) new-proc)
1941 (##cons new-proc lst2)
1942 (##fixnum.+ arg-num 1))))
1943 (##fail-check-interpreted-procedure arg-num '() prim args))))
1944 (##fail-check-interpreted-procedure arg-num '() prim args)))
1946 (##for-each fn (##reverse lst2))
1949 (define-fail-check-type interpreted-procedure 'interpreted-procedure)
1951 (define-prim ##interp-procedure-wrapper
1952 (macro-make-cprc ;; this is never actually called to evaluate code
1958 (rte (macro-make-rte rte proc args)))
1959 ;;;********* (break-if-stepping-level>= 0)
1960 (##apply (^ 1) args)))
1962 (let ((entry-hook (^ 0)))
1967 (lambda () (execute)))
1971 (define-prim (##make-interp-procedure proc)
1977 (##current-stepper))
1979 (macro-make-code ##interp-procedure-wrapper cte src stepper ()
1984 (##interp-procedure-wrapper $code rte)))
1986 (define-prim (##remove elem lst)
1987 (let loop ((lst1 lst) (lst2 '()))
1989 (let ((x (##car lst1)))
1991 (##append (##reverse lst2) (##cdr lst1))
1992 (loop (##cdr lst1) (##cons x lst2))))
1995 ;;;============================================================================
1997 ;;; Read eval print loop channels.
1999 (implement-type-repl-channel)
2001 (define-prim (##thread-repl-channel-get! thread)
2002 (or (macro-thread-repl-channel thread)
2003 (let ((repl-channel (##thread-make-repl-channel thread)))
2004 (macro-thread-repl-channel-set! thread repl-channel)
2005 (macro-thread-repl-channel thread))))
2007 (define (##default-thread-make-repl-channel thread)
2008 ##stdio/console-repl-channel)
2010 (define ##thread-make-repl-channel #f)
2011 (set! ##thread-make-repl-channel ##default-thread-make-repl-channel)
2013 (define ##stdio/console-repl-channel
2015 (##set-debug-settings! 0 0))
2017 (##fixnum.arithmetic-shift-right
2018 (##fixnum.bitwise-and
2020 (macro-debug-settings-repl-mask))
2021 (macro-debug-settings-repl-shift))))
2022 (cond ((##fixnum.= x (macro-debug-settings-repl-stdio))
2023 (##make-repl-channel-ports ##stdin-port ##stdout-port))
2025 (##make-repl-channel-ports ##console-port ##console-port)))))
2027 (define-prim (##repl-input-port)
2028 (let* ((ct (macro-current-thread))
2029 (channel (##thread-repl-channel-get! ct)))
2030 (macro-repl-channel-input-port channel)))
2032 (define-prim (repl-input-port)
2033 (##repl-input-port))
2035 (define-prim (##repl-output-port)
2036 (let* ((ct (macro-current-thread))
2037 (channel (##thread-repl-channel-get! ct)))
2038 (macro-repl-channel-output-port channel)))
2040 (define-prim (repl-output-port)
2041 (##repl-output-port))
2043 (define-prim (##repl-channel-acquire-ownership!)
2044 (let* ((ct (macro-current-thread))
2045 (channel (##thread-repl-channel-get! ct)))
2046 (macro-mutex-lock! (macro-repl-channel-owner-mutex channel) #f ct)
2047 (if (##not (##eq? (macro-repl-channel-last-owner channel) ct))
2049 (macro-repl-channel-last-owner-set! channel ct)
2050 (##repl-channel-display-monoline-message
2051 (lambda (output-port)
2052 (##write-string "------------- REPL is now in " output-port)
2053 (##write ct output-port)
2054 (##write-string " -------------" output-port)))
2058 (define-prim (##repl-channel-release-ownership!)
2059 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2060 (macro-mutex-unlock! (macro-repl-channel-owner-mutex channel))))
2062 (define-prim (##repl-channel-input-port)
2063 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2064 (macro-repl-channel-input-port channel)))
2066 (define-prim (##repl-channel-output-port)
2067 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2068 (macro-repl-channel-output-port channel)))
2070 (define-prim (##repl-channel-read-command level depth)
2071 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2072 ((macro-repl-channel-read-command channel) channel level depth)))
2074 (define-prim (##repl-channel-write-results results)
2075 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2076 ((macro-repl-channel-write-results channel) channel results)))
2078 (define-prim (##repl-channel-display-monoline-message writer)
2079 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2080 ((macro-repl-channel-display-monoline-message channel) channel writer)))
2082 (define-prim (##repl-channel-display-multiline-message writer)
2083 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2084 ((macro-repl-channel-display-multiline-message channel) channel writer)))
2086 (define-prim (##repl-channel-display-continuation cont depth)
2087 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2088 ((macro-repl-channel-display-continuation channel) channel cont depth)))
2090 (define-prim (##repl-channel-pinpoint-continuation cont)
2091 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2092 ((macro-repl-channel-pinpoint-continuation channel) channel cont)))
2094 (define-prim (##repl-channel-really-exit?)
2095 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2096 ((macro-repl-channel-really-exit? channel) channel)))
2098 (define-prim (##repl-channel-newline)
2099 (let ((channel (##thread-repl-channel-get! (macro-current-thread))))
2100 ((macro-repl-channel-newline channel) channel)))
2102 (##define-macro (macro-repl-result-history-max-max-length)
2105 (##define-macro (macro-repl-result-history-default-max-length)
2108 (define-prim (##make-empty-repl-result-history)
2109 (##vector (macro-repl-result-history-default-max-length)))
2111 (##define-macro (macro-repl-result-history-length result-history)
2112 `(##fixnum.- (##vector-length ,result-history) 1))
2114 (##define-macro (macro-repl-result-history-max-length result-history)
2115 `(##vector-ref ,result-history 0))
2117 (##define-macro (macro-repl-result-history-ref result-history i)
2118 `(##vector-ref ,result-history (##fixnum.+ ,i 1)))
2120 (define-prim (##repl-channel-result-history-add channel result)
2122 (let* ((result-history (macro-repl-channel-result-history channel))
2123 (len (macro-repl-result-history-length result-history))
2124 (max-len (macro-repl-result-history-max-length result-history))
2125 (new-len (##fixnum.min (##fixnum.+ len 1) max-len)))
2126 (if (##fixnum.< 0 new-len)
2127 (let ((v (##make-vector (##fixnum.+ new-len 1) max-len)))
2128 (##subvector-move! result-history 1 new-len v 2)
2129 (##vector-set! v 1 result)
2131 (##declare (not interrupts-enabled))
2132 (if (##not (##eq? (macro-repl-channel-result-history channel)
2134 (loop) ;; some other thread changed it before us... try again
2136 (macro-repl-channel-result-history-set! channel v)
2140 (define-prim (##repl-channel-result-history-max-length-set! channel max-len)
2142 (let* ((result-history (macro-repl-channel-result-history channel))
2143 (len (macro-repl-result-history-length result-history))
2144 (new-len (##fixnum.min len max-len))
2145 (v (##make-vector (##fixnum.+ new-len 1) max-len)))
2146 (##subvector-move! result-history 1 (##fixnum.+ new-len 1) v 1)
2148 (##declare (not interrupts-enabled))
2149 (if (##not (##eq? (macro-repl-channel-result-history channel)
2151 (loop) ;; some other thread changed it before us... try again
2153 (macro-repl-channel-result-history-set! channel v)
2156 (define-prim (##repl-result-history-ref index)
2157 (let* ((channel (##thread-repl-channel-get! (macro-current-thread)))
2158 (result-history (macro-repl-channel-result-history channel)))
2159 (macro-check-fixnum-range
2163 (macro-repl-result-history-length result-history)
2164 (repl-result-history-ref index)
2165 (macro-repl-result-history-ref result-history index))))
2167 (define-prim (repl-result-history-ref index)
2168 (##repl-result-history-ref index))
2170 (define-prim (##repl-result-history-max-length-set! max-len)
2171 (let* ((channel (##thread-repl-channel-get! (macro-current-thread)))
2172 (result-history (macro-repl-channel-result-history channel)))
2173 (macro-check-fixnum-range-incl
2177 (macro-repl-result-history-max-max-length)
2178 (repl-result-history-max-length-set! max-len)
2179 (##repl-channel-result-history-max-length-set! channel max-len))))
2181 (define-prim (repl-result-history-max-length-set! max-len)
2182 (##repl-result-history-max-length-set! max-len))
2184 (implement-type-repl-channel-ports)
2186 (define-prim (##make-repl-channel-ports input-port output-port)
2187 (macro-make-repl-channel-ports
2189 (##make-mutex 'channel-arbiter)
2190 (macro-current-thread)
2193 (##make-empty-repl-result-history)
2195 ##repl-channel-ports-read-command
2196 ##repl-channel-ports-write-results
2197 ##repl-channel-ports-display-monoline-message
2198 ##repl-channel-ports-display-multiline-message
2199 ##repl-channel-ports-display-continuation
2200 ##repl-channel-ports-pinpoint-continuation
2201 ##repl-channel-ports-really-exit?
2202 ##repl-channel-ports-newline
2204 (let ((history-initialized? #f))
2207 (if (##not history-initialized?)
2208 (let ((input-port (macro-repl-channel-input-port channel)))
2210 (define (in-homedir filename)
2211 (let ((homedir (##path-expand "~")))
2212 (##string-append homedir filename)))
2214 (set! history-initialized? #t)
2216 (if (##tty? input-port)
2217 (let ((path-or-settings
2219 (in-homedir ".gambc_history")
2223 (##open-file-generic
2224 (macro-direction-in)
2228 (let ((history (##read-line port #f #f ##max-fixnum)))
2230 (if (##string? history)
2231 (##tty-history-set! input-port history)))))
2233 (##cons eol-encoding: (##cons 'cr-lf path-or-settings)))
2237 (##open-file-generic
2238 (macro-direction-out)
2242 (let ((history (##tty-history input-port)))
2243 (##display history port)
2244 (##close-port port))))
2246 path-or-settings)))))))
2249 (let ((input-port (macro-repl-channel-input-port channel)))
2250 (##read-expr-from-port input-port))))
2251 (let ((output-port (macro-repl-channel-output-port channel)))
2252 (##output-port-column-set! output-port 1))
2255 (define-prim (##repl-channel-ports-read-command channel level depth)
2257 (define prompt "> ")
2259 (let ((output-port (macro-repl-channel-output-port channel)))
2260 (if (##fixnum.< 0 level)
2261 (##write level output-port))
2262 (if (##fixnum.< 0 depth)
2264 (##write-string "\\" output-port)
2265 (##write depth output-port)))
2266 (##write-string prompt output-port)
2267 (##force-output output-port))
2269 ((macro-repl-channel-ports-read-expr channel) channel))
2271 (define-prim (##repl-channel-ports-write-results channel results)
2272 (let ((output-port (macro-repl-channel-output-port channel)))
2275 (if (##not (##eq? obj (##void)))
2277 (##repl-channel-result-history-add channel obj)
2278 (##pretty-print obj output-port))))
2281 (define-prim (##repl-channel-ports-display-monoline-message channel writer)
2282 (let ((output-port (macro-repl-channel-output-port channel)))
2283 (writer output-port)
2284 (##newline output-port)))
2286 (define-prim (##repl-channel-ports-display-multiline-message channel writer)
2287 (let ((output-port (macro-repl-channel-output-port channel)))
2288 (writer output-port)))
2290 (define-prim (##repl-channel-ports-display-continuation channel cont depth)
2291 (if (##repl-display-environment?)
2292 (##repl-channel-display-multiline-message
2293 (lambda (output-port)
2294 (##cmd-e cont output-port #t)))))
2296 (define-prim (##repl-channel-ports-pinpoint-continuation channel cont)
2299 (define-prim (##repl-channel-ports-really-exit? channel)
2300 (let ((input-port (macro-repl-channel-input-port channel))
2301 (output-port (macro-repl-channel-output-port channel)))
2302 (##write-string "*** EOF again to exit" output-port)
2303 (##newline output-port)
2304 (##force-output output-port)
2305 (##not (##char? (##peek-char input-port)))))
2307 (define-prim (##repl-channel-ports-newline channel)
2308 (let ((output-port (macro-repl-channel-output-port channel)))
2309 (##newline output-port)))
2311 ;;;============================================================================
2313 ;;; Read eval print loop.
2315 ;;;----------------------------------------------------------------------------
2317 ;;; Evaluation within a specific continuation.
2319 (implement-type-repl-context)
2321 (define-prim (##thread-repl-context-get!)
2322 (or (macro-current-repl-context)
2324 (##make-initial-repl-context)))
2325 (macro-current-repl-context-set! repl-context)
2326 (macro-current-repl-context))))
2328 (define-prim (##make-initial-repl-context)
2329 (macro-make-repl-context -1 0 #f #f #f #f #f))
2333 (lambda (#!optional (write-reason #f) (reason #f) (toplevel? #f))
2336 (##continuation-capture
2338 (##repl-within cont write-reason reason))))
2341 (##with-no-result-expected-toplevel (lambda () (repl)))
2344 (define-prim (##repl-debug #!optional (write-reason #f) (toplevel? #f))
2346 (##set-debug-settings!
2347 (##fixnum.+ (macro-debug-settings-error-mask)
2348 (macro-debug-settings-user-intr-mask))
2349 (##fixnum.+ (macro-debug-settings-error-repl)
2350 (macro-debug-settings-user-intr-repl))))
2352 (##repl write-reason #f toplevel?)))
2353 (##set-debug-settings!
2354 (macro-debug-settings-error-mask)
2358 (define-prim (##repl-debug-main)
2360 (##current-input-port (##repl-input-port))
2361 (##current-output-port (##repl-output-port))
2362 (##current-error-port (##repl-output-port))
2365 (lambda (first output-port)
2367 (##define-macro (attrs kind)
2369 (define style-normal 0)
2370 (define style-bold 1)
2371 (define style-underline 2)
2372 (define style-reverse 4)
2374 (define color-black 0)
2375 (define color-red 1)
2376 (define color-green 2)
2377 (define color-yellow 3)
2378 (define color-blue 4)
2379 (define color-magenta 5)
2380 (define color-cyan 6)
2381 (define color-white 7)
2382 (define default-color 8)
2384 (define (make-text-attr style fg bg)
2385 (+ (* style 256) fg (* bg 16)))
2389 (make-text-attr style-bold default-color color-cyan))
2391 (make-text-attr style-bold default-color default-color))
2393 (make-text-attr style-normal default-color default-color))))
2395 (if (##tty? output-port)
2396 (##tty-text-attributes-set! output-port (attrs input) (attrs banner)))
2398 (##write-string "Gambit " output-port)
2399 (##write-string (##system-version-string) output-port)
2401 (if (##tty? output-port)
2402 (##tty-text-attributes-set! output-port (attrs input) (attrs output)))
2404 (##newline output-port)
2405 (##newline output-port)
2411 (define-prim (##repl-context-display-continuation repl-context)
2412 (##repl-channel-display-continuation
2413 (macro-repl-context-cont repl-context)
2414 (macro-repl-context-depth repl-context)))
2416 (define-prim (##repl-within cont write-reason reason)
2417 (let* ((prev-repl-context
2418 (##thread-repl-context-get!))
2420 (macro-make-repl-context
2421 (##fixnum.+ (macro-repl-context-level prev-repl-context) 1)
2429 (##repl-channel-acquire-ownership!)
2431 (if (and (##procedure? write-reason)
2432 (##repl-context-with-clean-exception-handling
2435 (##repl-channel-display-multiline-message
2436 (lambda (output-port)
2437 (let ((first (##repl-first-interesting cont)))
2438 (##declare (not safe)) ;; avoid procedure check on the call
2439 ;; write-reason returns #f if REPL is to be started
2440 (write-reason first output-port)))))))
2442 (##repl-channel-release-ownership!)
2444 (##repl-context-restart-pinpointing-continuation repl-context #f))))
2446 (define-prim (##repl-context-restart-pinpointing-continuation
2449 (##repl-context-restart-exec
2453 (##repl-first-interesting
2454 (macro-repl-context-cont repl-context))))
2455 (if (and (##not (##repl-channel-pinpoint-continuation cont))
2457 (##repl-channel-display-multiline-message
2458 (lambda (output-port)
2462 (macro-repl-context-depth repl-context)))))
2463 (##repl-context-display-continuation repl-context)))))
2465 (define-prim (##repl-context-restart repl-context)
2466 (##repl-context-restart-exec
2469 (##repl-context-display-continuation repl-context))))
2471 (define-prim (##repl-context-restart-exec repl-context thunk)
2472 (##continuation-graft ;; get rid of any useless continuation frames
2473 (macro-repl-context-cont repl-context)
2475 (##repl-context-with-clean-exception-handling
2479 ##current-user-interrupt-handler
2480 ##void ;; ignore user interrupts
2482 (macro-dynamic-bind repl-context
2486 (##repl-context-prompt repl-context))))))))))
2488 (define-prim (##default-repl-context-prompt repl-context)
2490 (define (read-command)
2492 (##repl-channel-read-command
2493 (macro-repl-context-level repl-context)
2494 (macro-repl-context-depth repl-context))))
2495 (cond ((##eof-object? src)
2498 (let ((code (##source-code src)))
2499 (if (and (##pair? code)
2500 (##eq? (##source-code (##car code)) 'six.prefix))
2501 (let ((rest (##cdr code)))
2502 (if (and (##pair? rest)
2503 (##null? (##cdr rest)))
2508 (##step-off) ;; turn off single-stepping
2510 (##repl-context-command repl-context (read-command)))
2512 (define ##repl-context-prompt #f)
2513 (set! ##repl-context-prompt ##default-repl-context-prompt)
2515 (define-prim (##default-repl-context-command repl-context src)
2516 (cond ((##eof-object? src)
2517 (##repl-channel-newline)
2518 (if (##fixnum.< 0 (macro-repl-context-level repl-context))
2519 (##repl-cmd-d repl-context))
2520 (if (##repl-channel-really-exit?)
2521 (##repl-cmd-q repl-context))
2522 (##repl-context-prompt repl-context))
2524 (let ((code (##source-code src)))
2525 (if (and (##pair? code)
2526 (##eq? (##source-code (##car code)) 'unquote)
2527 (##pair? (##cdr code))
2528 (##null? (##cddr code)))
2529 (let* ((cmd-src (##cadr code))
2530 (cmd (##source-code cmd-src))
2531 (x (##assq cmd ##repl-commands-no-args))
2532 (handler (and x (##cdr x))))
2535 (handler repl-context))
2536 ((and (##fixnum? cmd)
2537 (##not (##fixnum.< cmd 0)))
2538 (##repl-context-goto-depth repl-context cmd))
2540 (##pair? (##cdr cmd))
2541 (##null? (##cddr cmd)))
2542 (let* ((cmd2-src (##car cmd))
2543 (cmd2 (##source-code cmd2-src))
2544 (x (##assq cmd2 ##repl-commands-with-1-arg))
2545 (handler (and x (##cdr x))))
2548 (handler (##cadr cmd) repl-context))
2550 (##repl-cmd-unknown src repl-context)))))
2552 (let* ((s (##symbol->string cmd))
2553 (len (##string-length s))
2554 (c (and (##fixnum.< 0 len)
2555 (##string-ref s (##fixnum.- len 1)))))
2557 (define (move-frame n)
2558 (##repl-context-goto-depth
2561 (macro-repl-context-depth repl-context)
2562 (if (##char=? c #\+)
2564 (##fixnum.- 0 n)))))
2566 (if (or (##char=? c #\+)
2568 (cond ((##fixnum.= len 1)
2570 ((and (##fixnum.= len 2)
2571 (##char=? c (##string-ref s 0)))
2572 (move-frame ##backtrace-default-max-head))
2574 (let ((n (##string->number
2579 (if (and (##fixnum? n)
2580 (##not (##fixnum.< n 0)))
2582 (##repl-cmd-unknown src repl-context)))))
2583 (##repl-cmd-unknown src repl-context))))
2585 (##repl-cmd-unknown src repl-context))))
2586 (##repl-cmd-eval-print src repl-context))))))
2588 (define ##repl-context-command #f)
2589 (set! ##repl-context-command ##default-repl-context-command)
2591 (define-prim (##repl-context-goto-depth repl-context n)
2592 (##repl-context-restart-pinpointing-continuation
2593 (##repl-context-get-context repl-context n)
2596 (define-prim (##repl-context-get-context repl-context n)
2597 (let loop ((context repl-context))
2598 (let ((depth (macro-repl-context-depth context)))
2599 (cond ((##fixnum.< n depth)
2600 (let ((prev-depth (macro-repl-context-prev-depth context)))
2604 ((##fixnum.< depth n)
2606 (##repl-first-interesting
2607 (macro-repl-context-cont context)))
2609 (##continuation-next-frame cont #f)))
2611 (loop (macro-make-repl-context
2612 (macro-repl-context-level context)
2613 (##fixnum.+ depth 1)
2615 (macro-repl-context-initial-cont context)
2616 (macro-repl-context-reason context)
2617 (macro-repl-context-prev-level context)
2623 (define-prim (##repl-context-cont-in-step-handler? repl-context)
2624 (let ((cont (macro-repl-context-cont repl-context)))
2625 (##step-handler-continuation? cont)))
2627 (define-prim (##repl-context-cont-in-with-no-result-expected? repl-context)
2628 (let ((cont (macro-repl-context-cont repl-context)))
2629 (or (##with-no-result-expected-continuation? cont)
2630 (##with-no-result-expected-toplevel-continuation? cont))))
2632 (define-prim (##repl-context-with-clean-exception-handling repl-context thunk)
2633 (##with-exception-catcher
2635 (##continuation-graft ;; get rid of any useless continuation frames
2636 (macro-repl-context-cont repl-context)
2638 (##repl-channel-release-ownership!)
2639 (macro-raise exc))))
2642 (define-prim (##repl-context-return repl-context results)
2643 (##repl-channel-release-ownership!)
2644 (##continuation-return
2645 (macro-repl-context-cont repl-context)
2648 (define-prim (##repl-first-interesting cont)
2649 (##continuation-first-frame cont #f))
2651 (define-prim (##repl-cmd-eval-print src repl-context)
2653 (##repl-channel-release-ownership!)
2655 (##continuation-capture
2659 (macro-repl-context-cont repl-context)
2666 (##repl-channel-write-results results)
2667 (##continuation-return return #f)))))))
2669 (##repl-channel-acquire-ownership!)
2671 (##repl-context-prompt repl-context))
2673 (define-prim (##repl-cmd-unknown src repl-context)
2674 (##repl-channel-display-monoline-message
2675 (lambda (output-port)
2676 (##write (##desourcify src) output-port)
2677 (##write-string " is an unknown command" output-port)))
2678 (##repl-context-prompt repl-context))
2680 (define-prim (##repl-cmd-invalid msg repl-context)
2681 (##repl-channel-display-monoline-message
2682 (lambda (output-port)
2683 (##write-string msg output-port)))
2684 (##repl-context-prompt repl-context))
2686 (define-prim (##repl-cmd-? repl-context)
2687 (##repl-channel-display-multiline-message ##cmd-?)
2688 (##repl-context-prompt repl-context))
2690 (define-prim (##repl-cmd-h repl-context)
2692 (macro-repl-context-reason repl-context))
2695 (##exception-procedure-and-arguments reason)))
2698 (##car proc-and-args))))
2701 (##repl-context-prompt repl-context))
2703 (define-prim (##repl-cmd-d repl-context)
2704 (if (##fixnum.< 0 (macro-repl-context-level repl-context))
2705 (##repl-context-restart (macro-repl-context-prev-level repl-context))
2706 (##repl-context-prompt repl-context)))
2708 (define-prim (##repl-cmd-t repl-context)
2709 (let loop ((context repl-context))
2710 (if (##fixnum.< 0 (macro-repl-context-level context))
2711 (loop (macro-repl-context-prev-level context))
2712 (##repl-context-restart context))))
2714 (define-prim (##repl-cmd-q repl-context)
2715 (##repl-channel-release-ownership!)
2716 (##continuation-graft
2717 (macro-repl-context-cont repl-context)
2721 (define-prim (##repl-cmd-qt repl-context)
2722 (##repl-channel-release-ownership!)
2723 (##continuation-graft
2724 (macro-repl-context-cont repl-context)
2726 (##thread-terminate! (macro-current-thread)))))
2728 (define-prim (##repl-cmd-st repl-context)
2729 (##repl-channel-display-multiline-message
2730 (lambda (output-port)
2731 (##cmd-st (macro-thread-tgroup (macro-current-thread))
2733 (##repl-context-prompt repl-context))
2735 (define-prim (##repl-cmd-b repl-context)
2736 (##repl-cmd-b-be-bed #f repl-context))
2738 (define-prim (##repl-cmd-be repl-context)
2739 (##repl-cmd-b-be-bed #t repl-context))
2741 (define-prim (##repl-cmd-bed repl-context)
2742 (##repl-cmd-b-be-bed 'dynamic repl-context))
2744 (define-prim (##repl-cmd-b-be-bed display-env? repl-context)
2745 (##repl-channel-display-multiline-message
2746 (lambda (output-port)
2747 (##cmd-b (##repl-first-interesting
2748 (macro-repl-context-cont repl-context))
2750 (macro-repl-context-depth repl-context)
2752 (##repl-context-prompt repl-context))
2754 (define-prim (##repl-cmd-i repl-context)
2755 (##repl-channel-display-multiline-message
2756 (lambda (output-port)
2757 (##cmd-i (##repl-first-interesting
2758 (macro-repl-context-cont repl-context))
2760 (##repl-context-prompt repl-context))
2762 (define-prim (##repl-cmd-y repl-context)
2763 (##repl-channel-display-multiline-message
2764 (lambda (output-port)
2765 (##cmd-y (##repl-first-interesting
2766 (macro-repl-context-cont repl-context))
2769 (macro-repl-context-depth repl-context))))
2770 (##repl-context-prompt repl-context))
2772 (define-prim (##repl-cmd-e repl-context)
2773 (##repl-cmd-e-ed #t repl-context))
2775 (define-prim (##repl-cmd-ed repl-context)
2776 (##repl-cmd-e-ed 'dynamic repl-context))
2778 (define-prim (##repl-cmd-e-ed display-env? repl-context)
2779 (##repl-channel-display-multiline-message
2780 (lambda (output-port)
2781 (##cmd-e (macro-repl-context-cont repl-context)
2784 (##repl-context-prompt repl-context))
2786 (define-prim (##repl-cmd-c repl-context)
2787 (##repl-cmd-c-s-l 'c repl-context))
2789 (define-prim (##repl-cmd-s repl-context)
2790 (##repl-cmd-c-s-l 's repl-context))
2792 (define-prim (##repl-cmd-l repl-context)
2793 (##repl-cmd-c-s-l 'l repl-context))
2795 (define-prim (##repl-cmd-c-s-l cmd repl-context)
2796 (if (or (##repl-context-cont-in-step-handler? repl-context)
2797 (##repl-context-cont-in-with-no-result-expected? repl-context))
2798 (##repl-context-return repl-context cmd)
2800 "Continuation expects a result -- use ,(c X) or ,(s X) or ,(l X)"
2803 (define ##repl-commands-no-args #f)
2804 (set! ##repl-commands-no-args
2805 (##list (##cons '? ##repl-cmd-?)
2806 (##cons 'h ##repl-cmd-h)
2807 (##cons 'd ##repl-cmd-d)
2808 (##cons 't ##repl-cmd-t)
2809 (##cons 'q ##repl-cmd-q)
2810 (##cons 'qt ##repl-cmd-qt)
2811 (##cons 'st ##repl-cmd-st)
2812 (##cons 'b ##repl-cmd-b)
2813 (##cons 'be ##repl-cmd-be)
2814 (##cons 'bed ##repl-cmd-bed)
2815 (##cons 'i ##repl-cmd-i)
2816 (##cons 'y ##repl-cmd-y)
2817 (##cons 'e ##repl-cmd-e)
2818 (##cons 'ed ##repl-cmd-ed)
2819 (##cons 'c ##repl-cmd-c)
2820 (##cons 's ##repl-cmd-s)
2821 (##cons 'l ##repl-cmd-l)
2824 (define-prim (##repl-cmd-h-with-1-arg arg repl-context)
2825 (##help (##source-code arg))
2826 (##repl-context-prompt repl-context))
2828 (define-prim (##repl-cmd-c-with-1-arg arg repl-context)
2829 (##repl-cmd-c-s-l-with-1-arg 'c arg repl-context))
2831 (define-prim (##repl-cmd-s-with-1-arg arg repl-context)
2832 (##repl-cmd-c-s-l-with-1-arg 's arg repl-context))
2834 (define-prim (##repl-cmd-l-with-1-arg arg repl-context)
2835 (##repl-cmd-c-s-l-with-1-arg 'l arg repl-context))
2837 (define-prim (##repl-cmd-c-s-l-with-1-arg cmd arg repl-context)
2838 (if (##repl-context-cont-in-with-no-result-expected? repl-context)
2840 "Continuation expects no result -- use ,c or ,s or ,l"
2843 (##repl-channel-release-ownership!)
2846 (macro-repl-context-cont repl-context)
2848 (if (##repl-context-cont-in-step-handler? repl-context)
2850 (##repl-channel-acquire-ownership!)
2851 (##repl-context-return
2853 (##vector results)))
2855 (##repl-channel-acquire-ownership!)
2856 (##repl-context-return
2860 (define-prim (##repl-cmd-b-with-1-arg arg repl-context)
2861 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'b arg repl-context))
2863 (define-prim (##repl-cmd-be-with-1-arg arg repl-context)
2864 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'be arg repl-context))
2866 (define-prim (##repl-cmd-bed-with-1-arg arg repl-context)
2867 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'bed arg repl-context))
2869 (define-prim (##repl-cmd-e-with-1-arg arg repl-context)
2870 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'e arg repl-context))
2872 (define-prim (##repl-cmd-ed-with-1-arg arg repl-context)
2873 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'ed arg repl-context))
2875 (define-prim (##repl-cmd-v-with-1-arg arg repl-context)
2876 (##repl-cmd-b-be-bed-e-ed-v-with-1-arg 'v arg repl-context))
2878 (define-prim (##repl-cmd-b-be-bed-e-ed-v-with-1-arg cmd arg repl-context)
2879 (##repl-channel-release-ownership!)
2882 (macro-repl-context-cont repl-context)
2885 (let ((val results))
2887 (define (handle proc-or-cont depth)
2889 (if (##continuation? proc-or-cont)
2891 (##repl-first-interesting
2893 (##repl-within cont #f #f))
2898 (macro-repl-context-cont
2901 (##repl-channel-display-multiline-message
2902 (lambda (output-port)
2903 (if (or (##eq? cmd 'e)
2905 (##cmd-e proc-or-cont
2911 (##repl-first-interesting
2916 (if (##eq? cmd 'bed)
2918 (##eq? cmd 'be)))))))
2919 (##repl-channel-acquire-ownership!)
2920 (##repl-context-prompt repl-context))))
2922 (cond ((and (##fixnum? val)
2923 (##not (##fixnum.< val 0)))
2925 (##repl-context-get-context
2929 (macro-repl-context-depth rc))
2931 (macro-repl-context-cont rc)))
2932 (handle cont depth)))
2933 ((##continuation? val)
2935 ((and (##not (or (##eq? cmd 'b)
2940 ((macro-thread? val)
2943 (##thread-interrupt!
2946 (##handle-interrupt #f)))
2948 (##repl-channel-acquire-ownership!)
2949 (##repl-context-prompt repl-context))
2951 (##thread-continuation-capture
2955 (##repl-channel-acquire-ownership!)
2957 (cond ((or (##eq? cmd 'b)
2960 "CONTINUATION or THREAD expected")
2962 "PROCEDURE, CONTINUATION or THREAD expected"))
2965 (define-prim (##repl-cmd-st-with-1-arg arg repl-context)
2966 (##repl-channel-release-ownership!)
2969 (macro-repl-context-cont repl-context)
2972 (let ((val results))
2974 (define (handle thread-or-tgroup)
2975 (##repl-channel-acquire-ownership!)
2976 (##repl-channel-display-multiline-message
2977 (lambda (output-port)
2978 (##cmd-st thread-or-tgroup
2980 (##repl-context-prompt repl-context))
2982 (cond ((macro-tgroup? val)
2984 ((macro-thread? val)
2987 (##repl-channel-acquire-ownership!)
2989 "THREAD or THREAD-GROUP expected"
2992 (define ##repl-commands-with-1-arg #f)
2993 (set! ##repl-commands-with-1-arg
2994 (##list (##cons 'h ##repl-cmd-h-with-1-arg)
2995 (##cons 'c ##repl-cmd-c-with-1-arg)
2996 (##cons 's ##repl-cmd-s-with-1-arg)
2997 (##cons 'l ##repl-cmd-l-with-1-arg)
2998 (##cons 'b ##repl-cmd-b-with-1-arg)
2999 (##cons 'be ##repl-cmd-be-with-1-arg)
3000 (##cons 'bed ##repl-cmd-bed-with-1-arg)
3001 (##cons 'e ##repl-cmd-e-with-1-arg)
3002 (##cons 'ed ##repl-cmd-ed-with-1-arg)
3003 (##cons 'v ##repl-cmd-v-with-1-arg)
3004 (##cons 'st ##repl-cmd-st-with-1-arg)
3007 (define-prim (##repl-within-proc proc cont)
3008 (cond ((##interp-procedure? proc)
3009 (##continuation-capture
3013 (##continuation-capture
3015 (##continuation-graft
3018 (##repl-within cont3 #f #f))))))
3020 (##continuation-graft
3023 (let* (($code (##interp-procedure-code proc))
3024 (rte (##interp-procedure-rte proc)))
3025 (##declare (not interrupts-enabled) (environment-map))
3026 (let ((result (repl)))
3027 (##first-argument result $code rte))))))))
3029 (error "Can't access compiled procedure's environment"))));;;;;;;;
3031 (define-prim (##eval-within src cont repl-context receiver)
3034 (##continuation-graft
3037 (macro-dynamic-bind repl-context
3042 (macro-code-run c))))))))
3044 (let ((src2 (##sourcify src (##make-source #f #f))))
3045 (cond ((##interp-continuation? cont)
3046 (let* (($code (##interp-continuation-code cont))
3047 (cte (macro-code-cte $code))
3048 (rte (##interp-continuation-rte cont)))
3049 (run (##compile-inner cte src2) rte)))
3050 ((##with-no-result-expected-toplevel-continuation? cont)
3051 (run (##compile-top ##interaction-cte src2) #f))
3053 (let* ((locals (##continuation-locals cont))
3054 (cte (##cte-frame (##cte-top-cte ##interaction-cte)
3055 (##map ##car locals)))
3056 (rte (macro-make-rte-from-list #f (##map ##cdr locals))))
3057 (run (##compile-inner cte src2) rte))))))
3059 ;;;----------------------------------------------------------------------------
3061 (define-prim (##repl-exception-handler-hook exc other-handler)
3062 (##declare (not interrupts-enabled))
3063 (let ((settings (##set-debug-settings! 0 0)))
3064 (if (and (##not (##eq? (macro-current-thread) (macro-primordial-thread)))
3065 (##fixnum.= (macro-debug-settings-uncaught-primordial)
3066 (macro-debug-settings-uncaught settings)))
3069 (lambda (first output-port)
3070 (let ((quit? (##fixnum.= (macro-debug-settings-error settings)
3071 (macro-debug-settings-error-quit))))
3073 (##fixnum.= (macro-debug-settings-level settings) 0))
3074 (##exit-with-exception exc)
3076 (##display-exception-in-context exc first output-port)
3078 (##exit-with-exception exc)
3082 (define-prim (##default-user-interrupt-handler)
3083 (let* ((settings (##set-debug-settings! 0 0))
3084 (settings-user-intr (macro-debug-settings-user-intr settings))
3085 (defer? (##fixnum.= settings-user-intr
3086 (macro-debug-settings-user-intr-defer))))
3088 (set! ##deferred-user-interrupt? #t)
3089 (let ((quit? (##fixnum.= settings-user-intr
3090 (macro-debug-settings-user-intr-quit))))
3092 (##fixnum.= (macro-debug-settings-level settings) 0))
3094 (##handle-interrupt quit?))))))
3096 (define-prim (##handle-interrupt quit?)
3097 (##with-no-result-expected
3100 (lambda (first output-port)
3101 (##display-situation
3103 (##continuation-creator first)
3104 (##continuation-locat first)
3106 (##newline output-port)
3111 (set! ##primordial-exception-handler-hook ##repl-exception-handler-hook)
3113 (if (##fixnum.= (macro-debug-settings-error (##set-debug-settings! 0 0))
3114 (macro-debug-settings-error-single-step))
3117 (##current-user-interrupt-handler ##default-user-interrupt-handler)
3119 (define-prim (##exception->kind exc)
3120 (cond (#f;;;;;;;;;;;;;;
3125 (define-prim (##exception->procedure exc cont)
3126 (cond ((macro-expression-parsing-exception? exc)
3128 ((macro-datum-parsing-exception? exc)
3130 ((and (macro-nonprocedure-operator-exception? exc)
3131 (macro-nonprocedure-operator-exception-code exc))
3132 (##extract-container
3133 (macro-nonprocedure-operator-exception-code exc)
3134 (macro-nonprocedure-operator-exception-rte exc)))
3136 (##continuation-creator cont))))
3138 (define-prim (##exception->locat exc cont)
3140 (define (source-loc source)
3141 (##source-locat source))
3143 (define (code-loc code)
3144 (##code-locat code))
3146 (cond ((macro-expression-parsing-exception? exc)
3147 (source-loc (macro-expression-parsing-exception-source exc)))
3148 ((macro-datum-parsing-exception? exc)
3149 (let ((re (macro-datum-parsing-exception-readenv exc)))
3150 (##readenv->locat re)))
3151 ((and (macro-nonprocedure-operator-exception? exc)
3152 (macro-nonprocedure-operator-exception-code exc))
3156 (##continuation-locat cont))))
3158 (define-prim (##display-situation kind proc locat port)
3159 (##write-string "*** " port)
3160 (##write-string kind port)
3162 (##write-string " IN " port))
3164 (##write (##procedure-friendly-name proc) port))
3168 (##write-string ", " port))
3169 (##display-locat locat #t port))))
3171 (define-prim (##display-exception-in-context exc cont port)
3172 (##display-situation
3173 (##exception->kind exc)
3174 (##exception->procedure exc cont)
3175 (##exception->locat exc cont)
3177 (##write-string " -- " port)
3178 (##display-exception exc port))
3180 (define-prim (display-exception-in-context
3184 (port (macro-absent-obj)))
3185 (macro-force-vars (exc cont port)
3187 (if (##eq? port (macro-absent-obj))
3188 (macro-current-output-port)
3190 (macro-check-continuation cont 2 (display-exception-in-context exc cont port)
3191 (macro-check-character-output-port p 3 (display-exception-in-context exc cont p)
3192 (##display-exception-in-context exc cont p))))))
3194 (define-prim (##default-display-exception exc port)
3196 (define max-displayed-args 15)
3198 (define (display-call)
3199 (let* ((proc-and-args
3200 (##exception-procedure-and-arguments exc))
3202 (and proc-and-args (##car proc-and-args))))
3204 (display-call* proc (##cdr proc-and-args)))))
3206 (define (display-call* proc args)
3208 (##make-call-form proc args max-displayed-args))
3210 (##output-port-width port))
3212 (##object->string call width)))
3213 (if (##fixnum.< (##string-length str) width)
3215 (##write-string str port)
3217 (let loop ((i 0) (lst call))
3218 (##write-string (if (##fixnum.= i 0) "(" " ") port)
3220 (##null? (##cdr lst)))
3222 (##fixnum.- width 2))
3224 (##object->string (##car lst) w)))
3225 (##write-string s port)
3228 (if (##fixnum.= (##string-length s) w) (##newline port))
3229 (##write-string ")" port)
3233 (loop (##fixnum.+ i 1) (##cdr lst)))))))))
3235 (define-prim (write-items items)
3236 (let loop ((lst items))
3239 (##write-string " " port)
3240 (##write (##car lst) port)
3241 (loop (##cdr lst))))))
3243 (define-prim (display-arg-num arg-num)
3244 (if (##fixnum.< 0 arg-num)
3246 (##write-string "(Argument " port)
3247 (##write arg-num port)
3248 (##write-string ") " port))))
3250 (define-prim (display-exception exc)
3252 (define (err-code->string code)
3253 (let ((x (##os-err-code->string code)))
3256 "Error code could not be converted to a string")))
3258 (cond ((macro-abandoned-mutex-exception? exc)
3259 (##write-string "MUTEX was abandoned" port)
3262 ((macro-sfun-conversion-exception? exc)
3264 (or (macro-sfun-conversion-exception-message exc)
3266 (macro-sfun-conversion-exception-code exc)))
3271 ((macro-cfun-conversion-exception? exc)
3273 (or (macro-cfun-conversion-exception-message exc)
3275 (macro-cfun-conversion-exception-code exc)))
3280 ((macro-datum-parsing-exception? exc)
3282 (##assq (macro-datum-parsing-exception-kind exc)
3283 ##datum-parsing-exception-names)))
3285 (if x (##cdr x) "Unknown datum parsing exception")
3287 (write-items (macro-datum-parsing-exception-parameters exc))
3290 ((macro-deadlock-exception? exc)
3291 (##write-string "Deadlock detected" port)
3294 ((macro-divide-by-zero-exception? exc)
3295 (##write-string "Divide by zero" port)
3299 ((macro-fixnum-overflow-exception? exc)
3300 (##write-string "FIXNUM overflow" port)
3304 ((macro-error-exception? exc)
3305 (##display (macro-error-exception-message exc) port)
3307 (##output-port-width port))
3312 (let ((s (##object->truncated-string p width)))
3313 (if (##fixnum.= (##string-length s) width)
3316 (##string->limited-string
3318 (##fixnum.- width 1)))
3320 (macro-error-exception-parameters exc))))
3323 (##write-string sep port)
3324 (##write-string param port))
3328 ((macro-invalid-hash-number-exception? exc)
3329 (##write-string "Invalid hash number" port)
3333 ((macro-unbound-table-key-exception? exc)
3334 (##write-string "Unbound table key" port)
3338 ((macro-unbound-serial-number-exception? exc)
3339 (##write-string "Unbound serial number" port)
3343 ((macro-unbound-os-environment-variable-exception? exc)
3344 (##write-string "Unbound OS environment variable" port)
3348 ((macro-unterminated-process-exception? exc)
3349 (##write-string "Process not terminated" port)
3353 ((macro-nonempty-input-port-character-buffer-exception? exc)
3354 (##write-string "Input port character buffer is not empty" port)
3358 ((macro-expression-parsing-exception? exc)
3360 (##assq (macro-expression-parsing-exception-kind exc)
3361 ##expression-parsing-exception-names)))
3363 (if x (##cdr x) "Unknown expression parsing exception")
3365 (write-items (macro-expression-parsing-exception-parameters exc))
3367 (let* ((source (macro-expression-parsing-exception-source exc))
3368 (locat (##source-locat source)))
3370 (##pretty-print (##desourcify source) port))))
3372 ((macro-heap-overflow-exception? exc)
3373 (##write-string "Heap overflow" port)
3376 ((macro-improper-length-list-exception? exc)
3377 (display-arg-num (macro-improper-length-list-exception-arg-num exc))
3378 (##write-string "List is not of proper length" port)
3382 ((macro-join-timeout-exception? exc)
3383 (##write-string "'thread-join!' timed out" port)
3387 ((macro-mailbox-receive-timeout-exception? exc)
3388 (##write-string "mailbox receive timed out" port)
3392 ((macro-rpc-remote-error-exception? exc)
3393 (##write-string "RPC failed; remote error message follows" port)
3396 (##write-string (macro-rpc-remote-error-exception-message exc) port))
3398 ((macro-keyword-expected-exception? exc)
3400 "Keyword argument expected"
3405 ((macro-multiple-c-return-exception? exc)
3407 "Attempt to return to a C function that has already returned"
3411 ((macro-noncontinuable-exception? exc)
3412 (##write-string "Computation cannot be continued" port)
3415 ((macro-nonprocedure-operator-exception? exc)
3417 "Operator is not a PROCEDURE"
3422 ((macro-number-of-arguments-limit-exception? exc)
3424 "Number of arguments exceeds implementation limit"
3429 ((macro-os-exception? exc)
3430 (let ((message (macro-os-exception-message exc))
3431 (code (macro-os-exception-code exc)))
3434 (if code (err-code->string code) "Unknown OS exception"))
3439 ((macro-no-such-file-or-directory-exception? exc)
3440 (##write-string "No such file or directory" port)
3444 ((macro-range-exception? exc)
3445 (display-arg-num (macro-range-exception-arg-num exc))
3446 (##write-string "Out of range" port)
3450 ((macro-scheduler-exception? exc)
3451 (##write-string "Scheduler reported the exception: " port)
3452 (##write (macro-scheduler-exception-reason exc) port)
3455 ((macro-stack-overflow-exception? exc)
3456 (##write-string "Stack overflow" port)
3459 ((macro-initialized-thread-exception? exc)
3460 (##write-string "Thread is initialized" port)
3464 ((macro-uninitialized-thread-exception? exc)
3465 (##write-string "Thread is not initialized" port)
3469 ((macro-inactive-thread-exception? exc)
3470 (##write-string "Thread is not active" port)
3474 ((macro-started-thread-exception? exc)
3475 (##write-string "Thread is started" port)
3479 ((macro-terminated-thread-exception? exc)
3480 (##write-string "Thread is terminated" port)
3484 ((macro-type-exception? exc)
3485 (display-arg-num (macro-type-exception-arg-num exc))
3487 (macro-type-exception-type-id exc)))
3488 (if (##type? type-id)
3490 (##write-string "Instance of " port)
3491 (##write type-id port))
3493 (##assq (macro-type-exception-type-id exc)
3494 ##type-exception-names)))
3495 (##write-string (if x (##cdr x) "Unknown type") port))))
3496 (##write-string " expected" port)
3500 ((macro-unbound-global-exception? exc)
3501 (##write-string "Unbound variable: " port)
3502 (##write (macro-unbound-global-exception-variable exc) port)
3505 ((macro-uncaught-exception? exc)
3506 (##write-string "Uncaught exception: " port)
3507 (##write (macro-uncaught-exception-reason exc) port)
3511 ((macro-unknown-keyword-argument-exception? exc)
3513 "Unknown keyword argument passed to procedure"
3518 ((macro-wrong-number-of-arguments-exception? exc)
3520 "Wrong number of arguments passed to procedure"
3526 (##write-string "This object was raised: " port)
3530 (display-exception exc))
3532 (define-prim (##exception-procedure-and-arguments exc)
3533 (cond ((macro-sfun-conversion-exception? exc)
3535 (macro-sfun-conversion-exception-procedure exc)
3536 (macro-sfun-conversion-exception-arguments exc)))
3538 ((macro-cfun-conversion-exception? exc)
3540 (macro-cfun-conversion-exception-procedure exc)
3541 (macro-cfun-conversion-exception-arguments exc)))
3543 ((macro-divide-by-zero-exception? exc)
3545 (macro-divide-by-zero-exception-procedure exc)
3546 (macro-divide-by-zero-exception-arguments exc)))
3548 ((macro-fixnum-overflow-exception? exc)
3550 (macro-fixnum-overflow-exception-procedure exc)
3551 (macro-fixnum-overflow-exception-arguments exc)))
3553 ((macro-invalid-hash-number-exception? exc)
3555 (macro-invalid-hash-number-exception-procedure exc)
3556 (macro-invalid-hash-number-exception-arguments exc)))
3558 ((macro-unbound-table-key-exception? exc)
3560 (macro-unbound-table-key-exception-procedure exc)
3561 (macro-unbound-table-key-exception-arguments exc)))
3563 ((macro-unbound-serial-number-exception? exc)
3565 (macro-unbound-serial-number-exception-procedure exc)
3566 (macro-unbound-serial-number-exception-arguments exc)))
3568 ((macro-unbound-os-environment-variable-exception? exc)
3570 (macro-unbound-os-environment-variable-exception-procedure exc)
3571 (macro-unbound-os-environment-variable-exception-arguments exc)))
3573 ((macro-unterminated-process-exception? exc)
3575 (macro-unterminated-process-exception-procedure exc)
3576 (macro-unterminated-process-exception-arguments exc)))
3578 ((macro-nonempty-input-port-character-buffer-exception? exc)
3580 (macro-nonempty-input-port-character-buffer-exception-procedure exc)
3581 (macro-nonempty-input-port-character-buffer-exception-arguments exc)))
3583 ((macro-improper-length-list-exception? exc)
3585 (macro-improper-length-list-exception-procedure exc)
3586 (macro-improper-length-list-exception-arguments exc)))
3588 ((macro-join-timeout-exception? exc)
3590 (macro-join-timeout-exception-procedure exc)
3591 (macro-join-timeout-exception-arguments exc)))
3593 ((macro-mailbox-receive-timeout-exception? exc)
3595 (macro-mailbox-receive-timeout-exception-procedure exc)
3596 (macro-mailbox-receive-timeout-exception-arguments exc)))
3598 ((macro-rpc-remote-error-exception? exc)
3600 (macro-rpc-remote-error-exception-procedure exc)
3601 (macro-rpc-remote-error-exception-arguments exc)))
3603 ((macro-keyword-expected-exception? exc)
3605 (macro-keyword-expected-exception-procedure exc)
3606 (macro-keyword-expected-exception-arguments exc)))
3608 ((macro-nonprocedure-operator-exception? exc)
3610 (macro-nonprocedure-operator-exception-operator exc)
3611 (macro-nonprocedure-operator-exception-arguments exc)))
3613 ((macro-number-of-arguments-limit-exception? exc)
3615 (macro-number-of-arguments-limit-exception-procedure exc)
3616 (macro-number-of-arguments-limit-exception-arguments exc)))
3618 ((macro-os-exception? exc)
3620 (macro-os-exception-procedure exc)
3621 (macro-os-exception-arguments exc)))
3623 ((macro-no-such-file-or-directory-exception? exc)
3625 (macro-no-such-file-or-directory-exception-procedure exc)
3626 (macro-no-such-file-or-directory-exception-arguments exc)))
3628 ((macro-range-exception? exc)
3630 (macro-range-exception-procedure exc)
3631 (macro-range-exception-arguments exc)))
3633 ((macro-initialized-thread-exception? exc)
3635 (macro-initialized-thread-exception-procedure exc)
3636 (macro-initialized-thread-exception-arguments exc)))
3638 ((macro-uninitialized-thread-exception? exc)
3640 (macro-uninitialized-thread-exception-procedure exc)
3641 (macro-uninitialized-thread-exception-arguments exc)))
3643 ((macro-inactive-thread-exception? exc)
3645 (macro-inactive-thread-exception-procedure exc)
3646 (macro-inactive-thread-exception-arguments exc)))
3648 ((macro-started-thread-exception? exc)
3650 (macro-started-thread-exception-procedure exc)
3651 (macro-started-thread-exception-arguments exc)))
3653 ((macro-terminated-thread-exception? exc)
3655 (macro-terminated-thread-exception-procedure exc)
3656 (macro-terminated-thread-exception-arguments exc)))
3658 ((macro-type-exception? exc)
3660 (macro-type-exception-procedure exc)
3661 (macro-type-exception-arguments exc)))
3663 ((macro-uncaught-exception? exc)
3665 (macro-uncaught-exception-procedure exc)
3666 (macro-uncaught-exception-arguments exc)))
3668 ((macro-unknown-keyword-argument-exception? exc)
3670 (macro-unknown-keyword-argument-exception-procedure exc)
3671 (macro-unknown-keyword-argument-exception-arguments exc)))
3673 ((macro-wrong-number-of-arguments-exception? exc)
3675 (macro-wrong-number-of-arguments-exception-procedure exc)
3676 (macro-wrong-number-of-arguments-exception-arguments exc)))
3681 (define ##display-exception-hook #f)
3682 (set! ##display-exception-hook ##default-display-exception)
3684 (define-prim (##display-exception exc port)
3685 (##display-exception-hook exc port))
3687 (define-prim (display-exception
3690 (port (macro-absent-obj)))
3691 (macro-force-vars (exc port)
3693 (if (##eq? port (macro-absent-obj))
3694 (macro-current-output-port)
3696 (macro-check-character-output-port p 2 (display-exception exc p)
3697 (##display-exception exc p)))))
3699 (define ##type-exception-names #f)
3700 (set! ##type-exception-names
3702 ;; from "_kernel.scm":
3703 (foreign . "FOREIGN object")
3705 ;; from "_system.scm":
3706 (hash-algorithm . "HASH ALGORITHM")
3708 ;; from "_thread.scm":
3709 (continuation . "CONTINUATION")
3710 (time . "TIME object")
3711 (absrel-time . "REAL or TIME object")
3712 (absrel-time-or-false . "#f or REAL or TIME object")
3715 (convar . "CONDITION VARIABLE")
3716 (tgroup . "THREAD GROUP")
3717 (deadlock-exception . "DEADLOCK-EXCEPTION object")
3718 (join-timeout-exception . "JOIN-TIMEOUT-EXCEPTION object")
3719 (mailbox-receive-timeout-exception . "MAILBOX-RECEIVE-TIMEOUT-EXCEPTION object")
3720 (abandoned-mutex-exception . "ABANDONED-MUTEX-EXCEPTION object")
3721 (initialized-thread-exception . "INITIALIZED-THREAD-EXCEPTION object")
3722 (uninitialized-thread-exception . "UNINITIALIZED-THREAD-EXCEPTION object")
3723 (started-thread-exception . "STARTED-THREAD-EXCEPTION object")
3724 (terminated-thread-exception . "TERMINATED-THREAD-EXCEPTION object")
3725 (uncaught-exception . "UNCAUGHT-EXCEPTION object")
3726 (scheduler-exception . "SCHEDULER-EXCEPTION object")
3727 (noncontinuable-exception . "NONCONTINUABLE-EXCEPTION object")
3728 (low-level-exception . "LOW-LEVEL-EXCEPTION object")
3731 (mutable . "MUTABLE object")
3733 (pair-list . "PAIR LIST")
3734 (char . "CHARACTER")
3735 (char-list . "CHARACTER LIST")
3737 (string-list . "STRING LIST")
3740 (keyword . "KEYWORD")
3742 (vector-list . "VECTOR LIST")
3743 (s8vector . "S8VECTOR")
3744 (s8vector-list . "S8VECTOR LIST")
3745 (u8vector . "U8VECTOR")
3746 (u8vector-list . "U8VECTOR LIST")
3747 (s16vector . "S16VECTOR")
3748 (s16vector-list . "S16VECTOR LIST")
3749 (u16vector . "U16VECTOR")
3750 (u16vector-list . "U16VECTOR LIST")
3751 (s32vector . "S32VECTOR")
3752 (s32vector-list . "S32VECTOR LIST")
3753 (u32vector . "U32VECTOR")
3754 (u32vector-list . "U32VECTOR LIST")
3755 (s64vector . "S64VECTOR")
3756 (s64vector-list . "S64VECTOR LIST")
3757 (u64vector . "U64VECTOR")
3758 (u64vector-list . "U64VECTOR LIST")
3759 (f32vector . "F32VECTOR")
3760 (f32vector-list . "F32VECTOR LIST")
3761 (f64vector . "F64VECTOR")
3762 (f64vector-list . "F64VECTOR LIST")
3763 (procedure . "PROCEDURE")
3766 (exact-signed-int8 . "Signed 8 bit exact INTEGER")
3767 (exact-signed-int8-list . "Signed 8 bit exact INTEGER LIST")
3768 (exact-unsigned-int8 . "Unsigned 8 bit exact INTEGER")
3769 (exact-unsigned-int8-list . "Unsigned 8 bit exact INTEGER LIST")
3770 (exact-signed-int16 . "Signed 16 bit exact INTEGER")
3771 (exact-signed-int16-list . "Signed 16 bit exact INTEGER LIST")
3772 (exact-unsigned-int16 . "Unsigned 16 bit exact INTEGER")
3773 (exact-unsigned-int16-list . "Unsigned 16 bit exact INTEGER LIST")
3774 (exact-signed-int32 . "Signed 32 bit exact INTEGER")
3775 (exact-signed-int32-list . "Signed 32 bit exact INTEGER LIST")
3776 (exact-unsigned-int32 . "Unsigned 32 bit exact INTEGER")
3777 (exact-unsigned-int32-list . "Unsigned 32 bit exact INTEGER LIST")
3778 (exact-signed-int64 . "Signed 64 bit exact INTEGER")
3779 (exact-signed-int64-list . "Signed 64 bit exact INTEGER LIST")
3780 (exact-unsigned-int64 . "Unsigned 64 bit exact INTEGER")
3781 (exact-unsigned-int64-list . "Unsigned 64 bit exact INTEGER LIST")
3782 (inexact-real . "Inexact REAL")
3783 (inexact-real-list . "Inexact REAL LIST")
3786 (finite-real . "Finite REAL")
3787 (rational . "RATIONAL")
3788 (integer . "INTEGER")
3789 (exact-integer . "Exact INTEGER")
3792 (random-source-state . "RANDOM-SOURCE state")
3794 ;; from "_nonstd.scm":
3795 (string-or-nonnegative-fixnum . "STRING or nonnegative fixnum")
3798 (unterminated-process-exception . "UNTERMINATED-PROCESS-EXCEPTION object")
3801 (string-or-ip-address . "STRING or IP address")
3802 (settings . "Port settings")
3803 (vector-or-settings . "VECTOR or port settings")
3804 (string-or-settings . "STRING or port settings")
3805 (u8vector-or-settings . "U8VECTOR or port settings")
3806 (exact-integer-or-string-or-settings . "Exact INTEGER or STRING or port settings")
3808 (input-port . "INPUT PORT")
3809 (output-port . "OUTPUT PORT")
3810 (character-input-port . "Character INPUT PORT")
3811 (character-output-port . "Character OUTPUT PORT")
3812 (byte-input-port . "Byte INPUT PORT")
3813 (byte-output-port . "Byte OUTPUT PORT")
3814 (device-input-port . "Device INPUT PORT")
3815 (device-output-port . "Device OUTPUT PORT")
3816 (vector-input-port . "Vector INPUT PORT")
3817 (vector-output-port . "Vector OUTPUT PORT")
3818 (string-input-port . "String INPUT PORT")
3819 (string-output-port . "String OUTPUT PORT")
3820 (u8vector-input-port . "U8vector INPUT PORT")
3821 (u8vector-output-port . "U8vector OUTPUT PORT")
3822 (file-port . "File PORT")
3823 (tty-port . "Tty PORT")
3824 (tcp-client-port . "Tcp client PORT")
3825 (tcp-server-port . "Tcp server PORT")
3826 (pipe-port . "Pipe PORT")
3827 (serial-port . "Serial PORT")
3828 (directory-port . "Directory PORT")
3829 (event-queue-port . "Event-queue PORT")
3830 (timer-port . "Timer PORT")
3831 (readtable . "READTABLE")
3832 (hostent . "HOSTENT")
3833 (datum-parsing-exception . "DATUM PARSING EXCEPTION object")
3834 (network-family . "NETWORK FAMILY")
3835 (network-socket-type . "NETWORK SOCKET-TYPE")
3836 (network-protocol . "NETWORK PROTOCOL")
3838 ;; from "_eval.scm":
3839 (expression-parsing-exception . "EXPRESSION PARSING EXCEPTION object")
3841 ;; from "_repl.scm":
3842 (interpreted-procedure . "Interpreted PROCEDURE")
3845 ;;;;;;; (psettings . "Invalid port settings")
3846 ;;;;;;; (open-file . "Can't open file")
3849 (define ##datum-parsing-exception-names #f)
3850 (set! ##datum-parsing-exception-names
3852 (datum-or-eof-expected . "Datum or EOF expected")
3853 (datum-expected . "Datum expected")
3854 (improperly-placed-dot . "Improperly placed dot")
3855 (incomplete-form-eof-reached . "Incomplete form, EOF reached")
3856 (incomplete-form . "Incomplete form")
3857 (character-out-of-range . "Character out of range")
3858 (invalid-character-name . "Invalid '#\\' name:")
3859 (illegal-character . "Illegal character:")
3860 (s8-expected . "Signed 8 bit exact integer expected")
3861 (u8-expected . "Unsigned 8 bit exact integer expected")
3862 (s16-expected . "Signed 16 bit exact integer expected")
3863 (u16-expected . "Unsigned 16 bit exact integer expected")
3864 (s32-expected . "Signed 32 bit exact integer expected")
3865 (u32-expected . "Unsigned 32 bit exact integer expected")
3866 (s64-expected . "Signed 64 bit exact integer expected")
3867 (u64-expected . "Unsigned 64 bit exact integer expected")
3868 (inexact-real-expected . "Inexact real expected")
3869 (invalid-hex-escape . "Invalid hexadecimal escape")
3870 (invalid-escaped-character . "Invalid escaped character:")
3871 (open-paren-expected . "'(' expected")
3872 (invalid-token . "Invalid token")
3873 (invalid-sharp-bang-name . "Invalid '#!' name:")
3874 (duplicate-label-definition . "Duplicate definition for label:")
3875 (missing-label-definition . "Missing definition for label:")
3876 (illegal-label-definition . "Illegal definition of label:")
3877 (invalid-infix-syntax-character . "Invalid infix syntax character")
3878 (invalid-infix-syntax-number . "Invalid infix syntax number")
3879 (invalid-infix-syntax . "Invalid infix syntax")
3882 (define ##expression-parsing-exception-names #f)
3883 (set! ##expression-parsing-exception-names
3885 (id-expected . "Identifier expected")
3886 (invalid-module-name . "Invalid module name")
3887 (ill-formed-namespace . "Ill-formed namespace")
3888 (ill-formed-namespace-prefix . "Ill-formed namespace prefix")
3889 (namespace-prefix-must-be-string . "Namespace prefix must be a string")
3890 (macro-used-as-variable . "Macro name can't be used as a variable:")
3891 (variable-is-immutable . "Variable is immutable:")
3892 (ill-formed-macro-transformer . "Macro transformer must be a lambda expression")
3893 (reserved-used-as-variable . "Reserved identifier can't be used as a variable:")
3894 (ill-formed-special-form . "Ill-formed special form:")
3895 (cannot-open-file . "Can't open file")
3896 (filename-expected . "Filename expected")
3897 (ill-placed-define . "Ill-placed 'define'")
3898 (ill-placed-include . "Ill-placed 'include'")
3899 (ill-placed-define-macro . "Ill-placed 'define-macro'")
3900 (ill-placed-define-syntax . "Ill-placed 'define-syntax'")
3901 (ill-placed-declare . "Ill-placed 'declare'")
3902 (ill-placed-namespace . "Ill-placed 'namespace'")
3903 ;; (ill-placed-library . "Ill-placed 'library'")
3904 ;; (ill-placed-export . "Ill-placed 'export'")
3905 ;; (ill-placed-import . "Ill-placed 'import'")
3906 (unknown-location . "Unknown location")
3907 (ill-formed-expression . "Ill-formed expression")
3908 (unsupported-special-form . "Interpreter does not support")
3909 (parameter-must-be-id . "Parameter must be an identifier")
3910 (parameter-must-be-id-or-default . "Parameter must be an identifier or default binding")
3911 (duplicate-parameter . "Duplicate parameter in parameter list")
3912 (duplicate-rest-parameter . "Duplicate rest parameter in parameter list")
3913 (parameter-expected-after-rest . "#!rest must be followed by a parameter")
3914 (rest-parm-must-be-last . "Rest parameter must be last")
3915 (ill-formed-default . "Ill-formed default binding")
3916 (ill-placed-optional . "Ill-placed #!optional")
3917 (ill-placed-key . "Ill-placed #!key")
3918 (key-expected-after-rest . "#!key expected after rest parameter")
3919 (ill-placed-default . "Ill-placed default binding")
3920 (duplicate-variable-definition . "Duplicate definition of a variable")
3921 (empty-body . "Body must contain at least one expression")
3922 (else-clause-not-last . "Else clause must be last")
3923 (ill-formed-selector-list . "Ill-formed selector list")
3924 (duplicate-variable-binding . "Duplicate variable in bindings")
3925 (ill-formed-binding-list . "Ill-formed binding list")
3926 (ill-formed-call . "Ill-formed procedure call")
3927 (ill-formed-cond-expand . "Ill-formed 'cond-expand'")
3928 (unfulfilled-cond-expand . "Unfulfilled 'cond-expand'")
3931 ;;;----------------------------------------------------------------------------
3933 (define-prim (##gambc-doc . args)
3935 (define (gambc-doc args)
3937 (define (gen-args args i)
3940 (##cons (arg (##string-append "ARG" (##number->string i 10))
3942 (gen-args (##cdr args) (##fixnum.+ i 1)))))
3944 (define (arg name val)
3945 (##string-append "GAMBC_DOC_" name "=" val))
3947 (define (install-dir path)
3949 ((##current-directory
3950 (##path-expand path)))
3951 (##current-directory)))
3953 (let* ((gambcdir-bin
3954 (install-dir "~~bin"))
3956 (install-dir "~~doc")))
3957 (##open-process-generic
3958 (macro-direction-inout)
3961 (let ((status (##process-status port)))
3966 (##string-append gambcdir-bin
3968 ##os-bat-extension-string-saved)
3973 (let ((env (##os-environ)))
3974 (if (##fixnum? env) '() env))
3975 (##cons (arg "GAMBCDIR_BIN"
3976 (##path-strip-trailing-directory-separator
3978 (##cons (arg "GAMBCDIR_DOC"
3979 (##path-strip-trailing-directory-separator
3981 (gen-args args 1))))
3982 stdin-redirection: #f
3983 stdout-redirection: #f
3984 stderr-redirection: #f))))
3986 (let ((exit-status (gambc-doc args)))
3987 (if (##fixnum.= exit-status 0)
3989 (##raise-error-exception
3990 "failed to display the document"
3993 (define-prim (##escape-link str)
3994 (##apply ##string-append
3996 (cond ((##char=? c #\space) "_")
3997 ((##char=? c #\#) "%E2%99%AF")
3998 ((##char=? c #\%) "%25")
3999 ((##char=? c #\*) "%2A")
4000 ((##char=? c #\+) "%2B")
4001 ((##char=? c #\<) "%3C")
4002 ((##char=? c #\>) "%3E")
4003 (else (##string c))))
4004 (##string->list str))))
4006 (define-prim (##show-help prefix subject)
4010 (##escape-link (##string-append prefix subject))))
4012 (define ##help-browser
4016 (macro-check-string val 1 (##help-browser val)
4019 (define help-browser
4022 (define-prim (##show-definition-of subject)
4024 (cond ((##procedure? subject)
4025 (##object->string (##procedure-name subject)))
4027 (##object->string subject)))))
4028 (##show-help "Definition of " s)))
4030 (define-prim (##default-help subject)
4031 (##show-definition-of subject))
4033 (define ##help-hook #f)
4034 (set! ##help-hook ##default-help)
4036 (define-prim (##help subject)
4037 (##help-hook subject))
4039 (define-prim (help subject)
4040 (macro-force-vars (subject)
4043 ;;;----------------------------------------------------------------------------
4045 (define-runtime-macro (time expr)
4046 `(##time (lambda () ,expr) ',expr))
4048 (define-prim (##time thunk expr)
4049 (let ((at-start (##process-statistics)))
4050 (let ((result (thunk)))
4051 (let ((at-end (##process-statistics)))
4053 (define (secs->msecs x)
4054 (##inexact->exact (##round (##* x 1000))))
4057 (lambda (first output-port)
4060 (##- (##f64vector-ref at-end 0)
4061 (##f64vector-ref at-start 0))))
4064 (##- (##f64vector-ref at-end 1)
4065 (##f64vector-ref at-start 1))))
4067 (##+ user-time sys-time))
4070 (##- (##f64vector-ref at-end 2)
4071 (##f64vector-ref at-start 2))))
4074 (##- (##f64vector-ref at-end 3)
4075 (##f64vector-ref at-start 3))))
4078 (##- (##f64vector-ref at-end 4)
4079 (##f64vector-ref at-start 4))))
4082 (##- (##f64vector-ref at-end 5)
4083 (##f64vector-ref at-start 5))))
4085 (##flonum.->exact-int
4086 (##- (##f64vector-ref at-end 6)
4087 (##f64vector-ref at-start 6))))
4089 (##flonum.->exact-int
4090 (##- (##f64vector-ref at-end 10)
4091 (##f64vector-ref at-start 10))))
4093 (##flonum.->exact-int
4094 (##- (##f64vector-ref at-end 11)
4095 (##f64vector-ref at-start 11))))
4097 (##flonum.->exact-int
4098 (##- (##- (##f64vector-ref at-end 7)
4099 (##f64vector-ref at-start 7))
4100 (##+ (if (##interp-procedure? thunk)
4101 (##f64vector-ref at-end 8) ;; thunk call frame space
4103 (##f64vector-ref at-end 9)))))) ;; at-end structure space
4105 (define (pluralize n msg)
4106 (##write-string " " output-port)
4108 (##write-string "no" output-port)
4109 (##write n output-port))
4110 (##write-string msg output-port)
4111 (if (##not (##= n 1))
4112 (##write-string "s" output-port)))
4114 (##write (##list 'time expr) output-port)
4115 (##newline output-port)
4117 (##write-string " " output-port)
4118 (##write real-time output-port)
4119 (##write-string " ms real time" output-port)
4120 (##newline output-port)
4122 (##write-string " " output-port)
4123 (##write cpu-time output-port)
4124 (##write-string " ms cpu time (" output-port)
4125 (##write user-time output-port)
4126 (##write-string " user, " output-port)
4127 (##write sys-time output-port)
4128 (##write-string " system)" output-port)
4129 (##newline output-port)
4131 (pluralize nb-gcs " collection")
4132 (if (##not (##= nb-gcs 0))
4134 (##write-string " accounting for " output-port)
4135 (##write gc-real-time output-port)
4136 (##write-string " ms real time (" output-port)
4137 (##write gc-user-time output-port)
4138 (##write-string " user, " output-port)
4139 (##write gc-sys-time output-port)
4140 (##write-string " system)" output-port)))
4141 (##newline output-port)
4143 (pluralize bytes-allocated " byte")
4144 (##write-string " allocated" output-port)
4145 (##newline output-port)
4147 (pluralize minflt " minor fault")
4148 (##newline output-port)
4150 (pluralize majflt " major fault")
4151 (##newline output-port)
4157 ;;;----------------------------------------------------------------------------
4159 ;; enable processing of heartbeat interrupts, user interrupts, GC
4162 (##enable-interrupts!)
4164 ;;;============================================================================