2006-12-03 09:17:28 -05:00
|
|
|
#|procedure:new-cafe
|
|
|
|
synopsis:
|
|
|
|
(new-cafe [eval])
|
|
|
|
description:
|
|
|
|
The procedure new-cafe starts a new read-eval-print loop inside
|
|
|
|
the current cafe (if one exists). It prompts the user for an
|
|
|
|
expression, evaluates it, prints the result back, and repeats the
|
|
|
|
process. If new-cafe is called with an argument, eval, then that
|
|
|
|
argument must be a procedure that takes a single argument. The
|
|
|
|
eval procedure will be used to evaluate the expressions.
|
|
|
|
|
|
|
|
Every time a new cafe is started, the prompt is changed to reflect
|
|
|
|
the depth of the current cafe (i.e. how many eof objects is takes
|
|
|
|
to exit the outermost cafe).
|
|
|
|
|
|
|
|
Input and output performed by the cafe can be changed by the
|
|
|
|
console-input-port and console-output-port parameters.
|
|
|
|
|
|
|
|
If an error occurs during reading, evaluating, or printing an
|
|
|
|
expression, then the error is printed to the error-port and the
|
|
|
|
operations of the cafe resume as normal.|#
|
|
|
|
#|FIXME:new-cafe
|
|
|
|
Be specific about what the error-port is |#
|
2007-04-29 18:35:18 -04:00
|
|
|
|
|
|
|
(library (ikarus cafe)
|
2007-05-05 22:09:41 -04:00
|
|
|
(export new-cafe)
|
2007-05-06 20:29:58 -04:00
|
|
|
(import
|
2007-10-09 08:54:28 -04:00
|
|
|
(only (psyntax expander) eval-top-level)
|
2007-05-06 20:43:56 -04:00
|
|
|
(except (ikarus) new-cafe))
|
2007-04-29 18:35:18 -04:00
|
|
|
|
2006-11-23 19:33:45 -05:00
|
|
|
(define with-error-handler
|
|
|
|
(lambda (p thunk)
|
2006-12-02 06:26:05 -05:00
|
|
|
(let ([old-error-handler (error-handler)])
|
2006-11-23 19:33:45 -05:00
|
|
|
(dynamic-wind
|
|
|
|
(lambda ()
|
2006-12-02 06:26:05 -05:00
|
|
|
(error-handler
|
2006-11-23 19:33:45 -05:00
|
|
|
(lambda args
|
2006-12-02 06:26:05 -05:00
|
|
|
(error-handler old-error-handler)
|
2006-11-23 19:33:45 -05:00
|
|
|
(apply p args)
|
|
|
|
(apply error args))))
|
|
|
|
thunk
|
|
|
|
(lambda ()
|
2006-12-02 06:26:05 -05:00
|
|
|
(error-handler old-error-handler))))))
|
2006-11-23 19:33:45 -05:00
|
|
|
|
|
|
|
(define eval-depth 0)
|
|
|
|
|
|
|
|
(define display-prompt
|
|
|
|
(lambda (i)
|
|
|
|
(if (fx= i eval-depth)
|
|
|
|
(display " " (console-output-port))
|
|
|
|
(begin
|
|
|
|
(display ">" (console-output-port))
|
|
|
|
(display-prompt (fx+ i 1))))))
|
|
|
|
|
2006-12-24 04:53:01 -05:00
|
|
|
(define my-read
|
|
|
|
(lambda (k)
|
|
|
|
(parameterize ([interrupt-handler
|
|
|
|
(lambda ()
|
|
|
|
(flush-output-port (console-output-port))
|
|
|
|
(reset-input-port! (console-input-port))
|
|
|
|
(newline (console-output-port))
|
|
|
|
(k))])
|
|
|
|
(read (console-input-port)))))
|
|
|
|
|
2006-11-23 19:33:45 -05:00
|
|
|
(define wait
|
2007-05-03 00:38:42 -04:00
|
|
|
(lambda (eval-proc escape-k)
|
2006-11-23 19:33:45 -05:00
|
|
|
(call/cc
|
|
|
|
(lambda (k)
|
|
|
|
(with-error-handler
|
|
|
|
(lambda args
|
|
|
|
(reset-input-port! (console-input-port))
|
|
|
|
(apply print-error args)
|
|
|
|
(k (void)))
|
|
|
|
(lambda ()
|
|
|
|
(display-prompt 0)
|
2006-12-24 04:53:01 -05:00
|
|
|
(let ([x (my-read k)])
|
2006-11-23 19:33:45 -05:00
|
|
|
(cond
|
|
|
|
[(eof-object? x)
|
|
|
|
(newline (console-output-port))
|
|
|
|
(escape-k (void))]
|
|
|
|
[else
|
|
|
|
(call-with-values
|
2007-05-03 00:38:42 -04:00
|
|
|
(lambda () (eval-proc x))
|
2006-11-23 19:33:45 -05:00
|
|
|
(lambda v*
|
|
|
|
(unless (andmap (lambda (v) (eq? v (void))) v*)
|
|
|
|
(for-each
|
|
|
|
(lambda (v)
|
2007-01-13 21:33:04 -05:00
|
|
|
(pretty-print v (console-output-port)))
|
2006-11-23 19:33:45 -05:00
|
|
|
v*))))]))))))
|
2007-05-03 00:38:42 -04:00
|
|
|
(wait eval-proc escape-k)))
|
2006-11-23 19:33:45 -05:00
|
|
|
|
2007-04-29 21:59:06 -04:00
|
|
|
(define do-new-cafe
|
2007-05-03 00:38:42 -04:00
|
|
|
(lambda (eval-proc)
|
2006-11-23 19:40:06 -05:00
|
|
|
(dynamic-wind
|
|
|
|
(lambda () (set! eval-depth (fxadd1 eval-depth)))
|
|
|
|
(lambda ()
|
|
|
|
(call/cc
|
|
|
|
(lambda (k)
|
2007-05-03 00:38:42 -04:00
|
|
|
(wait eval-proc k))))
|
2006-11-23 19:40:06 -05:00
|
|
|
(lambda () (set! eval-depth (fxsub1 eval-depth))))))
|
|
|
|
|
2007-05-03 00:38:42 -04:00
|
|
|
(define default-cafe-eval
|
|
|
|
(lambda (x)
|
2007-05-03 01:19:50 -04:00
|
|
|
(eval-top-level x)))
|
2007-05-03 00:38:42 -04:00
|
|
|
|
2007-05-05 22:09:41 -04:00
|
|
|
(define new-cafe
|
2006-11-23 19:40:06 -05:00
|
|
|
(case-lambda
|
2007-05-03 00:38:42 -04:00
|
|
|
[() (do-new-cafe default-cafe-eval)]
|
2006-11-23 19:40:06 -05:00
|
|
|
[(p)
|
2007-04-29 18:35:18 -04:00
|
|
|
(unless (procedure? p)
|
2006-11-23 19:40:06 -05:00
|
|
|
(error 'new-cafe "~s is not a procedure" p))
|
2007-04-29 21:59:06 -04:00
|
|
|
(do-new-cafe p)]))
|
2006-11-23 19:40:06 -05:00
|
|
|
)
|
2006-11-23 19:33:45 -05:00
|
|
|
|