Common Lisp: Implement step 0
[jackhill/mal.git] / common-lisp / step0_repl.lisp
1 (defpackage :mal
2 (:use :common-lisp
3 :uiop)
4 (:export :main))
5
6 (in-package :mal)
7
8 (defun mal-read (string)
9 string)
10
11 (defun mal-eval (ast)
12 ast)
13
14 (defun mal-print (expression)
15 expression)
16
17 (defun rep (string)
18 (mal-print (mal-eval (mal-read string))))
19
20 (defvar *use-readline-p* nil)
21
22 (defun raw-input (prompt)
23 (format *standard-output* prompt)
24 (force-output *standard-output*)
25 (read-line *standard-input* nil))
26
27 (defun mal-readline (prompt)
28 (if *use-readline-p*
29 (cl-readline:readline :prompt prompt
30 :add-history t
31 :novelty-check (lambda (old new)
32 (not (string= old new))))
33 (raw-input prompt)))
34
35 (defun mal-writeline (string)
36 (when string
37 (write-line string)
38 (force-output *standard-output*)))
39
40 (defun main (&optional (argv nil argv-provided-p))
41 (declare (ignorable argv argv-provided-p))
42 (setf *use-readline-p* (not (or (string= (uiop:getenv "PERL_RL") "false")
43 (string= (uiop:getenv "TERM") "dumb"))))
44 (loop do (let ((line (mal-readline "user> ")))
45 (if line (mal-writeline (rep line)) (return)))))