Common Lisp: Add documentation
[jackhill/mal.git] / clisp / step0_repl.lisp
1 (defpackage :mal
2 (:use :common-lisp
3 :readline))
4
5 (in-package :mal)
6
7 (defun mal-read (string)
8 string)
9
10 (defun mal-eval (ast env)
11 ast)
12
13 (defun mal-print (expression)
14 expression)
15
16 (defun rep (string)
17 (mal-print (mal-eval (mal-read string)
18 (make-hash-table :test #'equal))))
19
20 ;; Readline setup
21 ;;; The test runner sets this environment variable, in which case we do
22 ;;; use readline since tests do not work with the readline interface
23 (defvar use-readline-p (not (string= (ext:getenv "PERL_RL") "false")))
24
25 (defvar *history-file* (namestring (merge-pathnames (user-homedir-pathname)
26 ".mal-clisp-history")))
27
28 (defun load-history ()
29 (readline:read-history *history-file*))
30
31 (defun save-history ()
32 (readline:write-history *history-file*))
33
34 ;; Setup history
35 (when use-readline-p
36 (load-history))
37
38 (defun raw-input (prompt)
39 (format *standard-output* prompt)
40 (force-output *standard-output*)
41 (read-line *standard-input* nil))
42
43 (defun mal-readline (prompt)
44 (let ((input (if use-readline-p
45 (readline:readline prompt)
46 (raw-input prompt))))
47 (when (and use-readline-p
48 input
49 (not (zerop (length input))))
50 (readline:add-history input))
51 input))
52
53 (defun mal-writeline (string)
54 (when string
55 (write-line string)))
56
57 (defun main ()
58 (loop do (let ((line (mal-readline "user> ")))
59 (if line
60 (mal-writeline (rep line))
61 (return))))
62 (when use-readline-p
63 (save-history)))
64
65 ;; Do not start REPL inside Emacs
66 (unless (member :swank *features*)
67 (main))