- added interact implementation
- added wait-task and close-task
This commit is contained in:
parent
b7f45aec49
commit
c966d7d3d2
|
@ -42,6 +42,17 @@
|
|||
(define (make-task process in out)
|
||||
(really-make-task process in out "" #f))
|
||||
|
||||
;;; Wait written for tasks.
|
||||
|
||||
(define (wait-task task) (wait (task:process task)))
|
||||
|
||||
;;; Close all ports associated with a task.
|
||||
|
||||
(define (close-task task)
|
||||
(close (task:out task))
|
||||
(close (task:in task)))
|
||||
|
||||
|
||||
(define (tsend task fmt . args)
|
||||
(apply format (task:out task) fmt args))
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
(define-syntax interact-clause-test
|
||||
(syntax-rules (filter eof)
|
||||
((interact-clause-test char break) #t)
|
||||
((interact-clause-test eof break (eof body ...) clause2 ...)
|
||||
(begin body ...))
|
||||
((interact-clause-test eof break clause1 clause2 ...)
|
||||
(interact-clause-test eof break clause2 ...))
|
||||
((interact-clause-test char break (eof body ...) clause2 ...)
|
||||
(interact-clause-test char break clause2 ...))
|
||||
((interact-clause-test char break (filter filter-proc) clause2 ...)
|
||||
(and (filter-proc char break)
|
||||
(interact-clause-test char break clause2 ...)))
|
||||
((interact-clause-test char break (test-char k body ...) clause2 ...)
|
||||
(if (eq? char test-char)
|
||||
(and (let ((k break)) body ...)
|
||||
(interact-clause-test char break clause2 ...))
|
||||
(interact-clause-test char break clause2 ...)))))
|
||||
|
||||
;;; Allow user to interact with program (sometimes there's just no other way)
|
||||
;;; (interact task) simply switches the user into interact mode with the task.
|
||||
;;;
|
||||
;;; (interact task clause ...) filters the input. The clause can either be a
|
||||
;;; character clause (character continuation-variable exp ...) or a filter
|
||||
;;; clause (filter proc). A character clause matches the character given,
|
||||
;;; links the continuation variable to the continuation out of the
|
||||
;;; interaction, and runs the expressions. A filter clause runs the given
|
||||
;;; filter-function with two arguments: the character entered and the
|
||||
;;; continuation out of the interaction. In both cases, if the filter returns
|
||||
;;; true, the expression falls through. If the expression falls through to
|
||||
;;; the bottom, the character is printed. Note that the interaction will
|
||||
;;; continue anyway, unless the continuation was explicitly called.
|
||||
|
||||
(define-syntax interact
|
||||
(syntax-rules ()
|
||||
|
||||
;; If there is just one argument, simply enable transfer.
|
||||
((interact with)
|
||||
(call-with-current-continuation
|
||||
(lambda (break)
|
||||
(let ((ivec (make-vector 2))
|
||||
(ivec0 (current-input-port))
|
||||
(ivec1 (task:in with)))
|
||||
(with-errno-handler ((e p) ((errno/io) #f))
|
||||
(let lp ()
|
||||
(vector-set! ivec 0 ivec0)
|
||||
(vector-set! ivec 1 ivec1)
|
||||
(select! ivec '#() '#())
|
||||
(if (char-ready? ivec0)
|
||||
(write-string (read-string/partial 256 ivec0)
|
||||
(task:out with)))
|
||||
(if (char-ready? ivec1)
|
||||
(write-string (read-string/partial 256 ivec1)))
|
||||
(lp)))))))
|
||||
|
||||
;; If there is more than one argument,
|
||||
;;enable transfer and allow escape keys.
|
||||
((interact with clauses ...)
|
||||
(call-with-current-continuation
|
||||
(lambda (break)
|
||||
(let ((ivec (make-vector 2))
|
||||
(ivec0 (current-input-port))
|
||||
(ivec1 (task:in with)))
|
||||
(with-errno-handler ((e p)
|
||||
((errno/io)
|
||||
(interact-clause-test eof #f clauses ...)))
|
||||
(let lp ()
|
||||
(vector-set! ivec 0 ivec0)
|
||||
(vector-set! ivec 1 ivec1)
|
||||
(select! ivec '#() '#())
|
||||
(if (char-ready? (current-input-port))
|
||||
(for-each (lambda (transfer)
|
||||
;; Test for indicated escape keys.
|
||||
(and (interact-clause-test transfer break
|
||||
clauses ...)
|
||||
;; Only write if all clauses "fell through"
|
||||
(write-char transfer (task:out with))))
|
||||
(string->list (read-string/partial 256 (current-inpu
|
||||
t-port)))))
|
||||
(if (char-ready? (task:in with))
|
||||
(write-string (read-string/partial 256 (task:in with))))
|
||||
(lp)))))))))
|
|
@ -21,16 +21,18 @@
|
|||
port->monitor
|
||||
|
||||
user-task file->task ports->task close-task
|
||||
wait-task close-task
|
||||
spawn* (spawn :syntax)
|
||||
tsend tsend-line
|
||||
(expect :syntax))
|
||||
(expect :syntax)
|
||||
(interact :syntax))
|
||||
(for-syntax (open expect-syntax-support scheme))
|
||||
|
||||
(open scsh formats structure-refs
|
||||
receiving srfi-9 scheme srfi-13)
|
||||
(access signals) ; for ERROR
|
||||
|
||||
(files expect))
|
||||
(files expect interact))
|
||||
|
||||
(define-structure chat
|
||||
(export chat-abort chat-timeout chat-monitor
|
||||
|
|
Loading…
Reference in New Issue