1 ;;; Read-Eval-Print Loop
3 ;; Copyright (C) 2001 Free Software Foundation, Inc.
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;; GNU General Public License for more details.
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program; see the file COPYING. If not, write to
17 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 ;; Boston, MA 02111-1307, USA.
22 (define-module (system repl repl)
23 :use-syntax (system base syntax)
24 :use-module (system base pmatch)
25 :use-module (system base compile)
26 :use-module (system base language)
27 :use-module (system repl common)
28 :use-module (system repl command)
29 :use-module (system vm core)
30 :use-module (ice-9 rdelim)
33 (define meta-command-token (cons 'meta 'command))
35 (define (meta-reader read)
38 (if (pair? read-args) (car read-args) (current-input-port))
40 (if (eqv? (next-char #t) #\,)
41 (begin (read-char) meta-command-token)
44 ;; repl-reader is a function defined in boot-9.scm, and is replaced by
45 ;; something else if readline has been activated. much of this hoopla is
46 ;; to be able to re-use the existing readline machinery.
47 (define (prompting-meta-read repl)
48 (let ((prompt (lambda () (repl-prompt repl)))
49 (lread (language-reader (repl-language repl))))
50 (with-fluid* current-reader (meta-reader lread)
51 (lambda () (repl-reader (lambda () (repl-prompt repl)))))))
53 (define (default-pre-unwind-handler key . args)
54 (save-stack default-pre-unwind-handler)
55 (apply throw key args))
57 (define (default-catch-handler . args)
61 ((vm-error ,fun ,msg ,args)
62 (display "VM error: ")
63 (apply format #t msg args)
65 ((,key ,subr ,msg ,args . ,rest)
66 (let ((cep (current-error-port)))
67 (cond ((not (stack? (fluid-ref the-last-stack))))
68 ((memq 'backtrace (debug-options-interface))
69 (let ((highlights (if (or (eq? key 'wrong-type-arg)
70 (eq? key 'out-of-range))
73 (run-hook before-backtrace-hook)
75 (display "Backtrace:\n")
76 (display-backtrace (fluid-ref the-last-stack) cep
79 (run-hook after-backtrace-hook))))
80 (run-hook before-error-hook)
81 (apply display-error (fluid-ref the-last-stack) cep subr msg args rest)
82 (run-hook after-error-hook)
83 (set! stack-saved? #f)
86 (apply bad-throw args))))
90 (define-macro (start-stack tag expr)
93 (define (start-repl lang)
94 (let ((repl (make-repl lang)))
97 (let ((exp (prompting-meta-read repl)))
99 ((eq? exp meta-command-token)
100 (meta-command repl (read-line)))
106 (call-with-values (lambda ()
107 (run-hook before-eval-hook exp)
108 (start-stack repl-eval
109 (repl-eval repl exp)))
111 (for-each (lambda (v)
112 (run-hook before-print-hook v)
115 default-catch-handler
116 default-pre-unwind-handler)))
117 (next-char #f) ;; consume trailing whitespace
120 (define (next-char wait)
121 (if (or wait (char-ready?))
122 (let ((ch (peek-char)))
123 (cond ((eof-object? ch) (throw 'quit))
124 ((char-whitespace? ch) (read-char) (next-char wait))