(yreq "Scheduler/scheduler")
(yreq "Scheduler/nonblocking-io")
(yreq "Utilities/yenta-utils")

(define srepl:start 'set!-below)

(let ()
  (define prev-exp '())
  (define prev-val '())

  (define (repl)
    (scheduler:let* ((exp (sch-read-exp #f)))
      (scheduler:split
       (set! exp (tree-replace '@prev prev-exp
			       (tree-replace '@val prev-val exp)))
       (format t "REPL exp: ~A~&" exp)
       (set! prev-exp exp)
       (when (equal? exp '(quit))	; Special-case an obvious one, for convenience.
	 (format t "You meant (scheduler:quit).  Quitting...~&")
	 (set! exp '(scheduler:quit)))
       (let* ((stuff (prot:capturing-errors (lambda () (eval exp))))
	      (result (car stuff))
	      (backtrace (cdr stuff)))
	 (cond ((eq? result 'protected:error)
		(format t "~&+++ Error evaluating form.  ~:[~*No backtrace available.~;Backtrace:~&~A~]---~&"
			(positive? (string-length backtrace)) backtrace))
	       (t
		(when (positive? (string-length backtrace))
		  (format t "~&+++ The form wrote to (current-error-port):~&~S---~&"
			  backtrace))
		(set! prev-val result)
		(format t "REPL response: ~S~&" prev-val)))))))

  (define (start)
    ;; Run the repl loop at very high priority, so we can investigate even
    ;; if some other process tries to run all the time.  As long as it yields
    ;; eventually, we'll be able to see what's going on.
    (scheduler:add-task! "Repl" 10 scheduler:always repl)
    (scheduler:add-once-task! "Print Repl notice" 10 scheduler:always
			      (lambda () 
				(display 
				 "Scheduled Read-Eval-Print Loop started")
				(newline))))

  (set! srepl:start start))

(define (srepl:restart)
  (unless (scheduler:task-exists? "Repl")
    (srepl:start))
  (scheduler:remove-task! '("Repl" "Child"))
  (scheduler:initialize!))

;;; End of file.
