;;; intro

(define examples
  `("  (log \"hello, world!\")"
    "  (list 'foo 3 \"bar\" (cons 1 2) (lambda (x) x))"
    "  `(a ,(+ 5 6) b)"
    "  (set pongballcolor 'lred)"
    "  (set pongballcolor 'dgreen)"
    "  (disassemble length)"
    "  (backtrace (self))"
    "  (compile '(+ 1 2))"
    "  (showglobals)"
    "  (showprocs)"
    ,(strcat
      "  (begin\n"
      "    (http 'get \"repl.lisp\")\n"
      "    (receive\n"
      "     ((response code text)\n"
      "      (when (= code 200) (log text)))))")))

(define showexamples
  (lambda ()
    (log "Here are some examples to try out:")
    (log "")
    (dolist (e examples)
      (log e))))

(doc 'put '(textin value)
     (strcat ";; Press the \"evaluate\" button to..\n"
	     "\n"
	     "(showexamples)\n"
	     "\n"
	     ";; Or press the \"i'm feeling lucky\" button to\n"
	     ";; evaluate a random example."))

;;; repl

(define replslave
  (lambda (pid text)
    (lambda ()
      (let ((output (map eval (readall text))))
	(send pid (result output))))))

(define repl
  (lambda ()
    (receive
     ((click id)
      (cond
       ((= id 'evaluate)
	(let ((text (doc 'get '(textin value))))
	  (spawnlink (replslave (self) text))))
       ((= id 'clear)
	(doc 'put '(textout value) ""))
       ((= id 'lucky)
	(log "A lucky result:")
	(let ((text (nth (floor (* (rand) (length examples)))
			 examples)))
	  (doc 'put '(textin value) text)
	  (spawnlink (replslave (self) text))))))
     ((result exps)
      (dolist (e exps)
	(log (write e))))
     ((exit pid snap reason)
      (unless (= reason 'normal)
	(showsnapshot snap)
	(log (strcat "proc " (write pid)
		     " died: " (write reason))))))
    (repl)))

(define startrepl
  (lambda ()
    (set replpid
	 (spawn
	  (lambda ()
	    (doc 'post '(evaluate listeners) 'click)
	    (doc 'post '(clear listeners) 'click)
	    (doc 'post '(lucky listeners) 'click)
	    (trapexits)
	    (repl))))))

(define replpid nil)
