;; using continuations to allow program-state ;; to 'buffer' input instead of manual buffering (define-record async-input-port input-port continuation) (define (new-async-input-port input-port proc) (define new-aip (make-async-input-port input-port #f)) (define reset-proc (lambda (ret) (begin (let [(final-return-value (proc))] (async-input-port-continuation-set! new-aip reset-proc) final-return-value)))) (async-input-port-continuation-set! new-aip reset-proc) new-aip) ;; (define (read-async-input-port async-input-port) (assert (async-input-port? async-input-port)) (assert (procedure? (async-input-port-continuation async-input-port))) (call/cc (lambda (return) (let* [(my-read (lambda () (print "enter read") (call/cc (lambda (cc) (async-input-port-continuation-set! async-input-port cc))) (print "cc saved") (if (char-ready? (async-input-port-input-port async-input-port)) (read-char i) (return #f )))) ; not ready jet (my-ready (lambda () (char-ready? i))) (my-close (lambda () (close-input-port i))) (p (make-input-port my-read my-ready my-close))] (with-input-from-port p (lambda () ((async-input-port-continuation async-input-port) #f) )))))) (define aip (new-async-input-port i (lambda () (read)))) ; will not block! returns #f is still waiting, otherwise returns what lambda above returns(read) (read-async-input-port aip)