1 (require "dependencies")
13 (defvar *repl-env
* (make-instance 'env
:mal-environment
))
15 (dolist (binding core
:ns
)
16 (env:set-env
*repl-env
*
20 (defvar mal-def
! (make-mal-symbol "def!"))
21 (defvar mal-let
* (make-mal-symbol "let*"))
22 (defvar mal-do
(make-mal-symbol "do"))
23 (defvar mal-if
(make-mal-symbol "if"))
24 (defvar mal-fn
* (make-mal-symbol "fn*"))
26 (defun eval-sequence (sequence env
)
28 (lambda (ast) (mal-eval ast env
))
29 (mal-data-value sequence
)))
31 (defun eval-hash-map (hash-map env
)
32 (let ((hash-map-value (mal-data-value hash-map
))
33 (new-hash-table (make-hash-table :test
'types
:mal-value
=)))
35 for key being the hash-keys of hash-map-value
36 do
(setf (gethash key new-hash-table
)
37 (mal-eval (gethash key hash-map-value
) env
)))
38 (make-mal-hash-map new-hash-table
)))
40 (defun eval-ast (ast env
)
42 (types:symbol
(env:get-env env ast
))
43 (types:list
(eval-sequence ast env
))
44 (types:vector
(make-mal-vector (apply 'vector
(eval-sequence ast env
))))
45 (types:hash-map
(eval-hash-map ast env
))
48 (defun mal-read (string)
49 (reader:read-str string
))
51 (defun mal-eval (ast env
)
54 ((null ast
) (return types
:mal-nil
))
55 ((not (types:mal-list-p ast
)) (return (eval-ast ast env
)))
56 ((zerop (length (mal-data-value ast
))) (return ast
))
57 (t (let ((forms (mal-data-value ast
)))
59 ((mal-value= mal-def
! (first forms
))
60 (return (env:set-env env
(second forms
) (mal-eval (third forms
) env
))))
62 ((mal-value= mal-let
* (first forms
))
63 (let ((new-env (make-instance 'env
:mal-environment
65 ;; Convert a potential vector to a list
68 (mal-data-value (second forms
)))))
70 (mapcar (lambda (binding)
73 (mal-eval (or (cdr binding
)
77 for
(symbol value
) on bindings
79 collect
(cons symbol value
)))
80 (setf ast
(third forms
)
83 ((mal-value= mal-do
(first forms
))
84 (mapc (lambda (form) (mal-eval form env
))
85 (butlast (cdr forms
)))
86 (setf ast
(car (last forms
))))
88 ((mal-value= mal-if
(first forms
))
89 (let ((predicate (mal-eval (second forms
) env
)))
90 (setf ast
(if (or (mal-value= predicate types
:mal-nil
)
91 (mal-value= predicate types
:mal-false
))
95 ((mal-value= mal-fn
* (first forms
))
96 (return (let ((arglist (second forms
))
98 (types:make-mal-fn
(lambda (&rest args
)
99 (mal-eval body
(make-instance 'env
:mal-environment
103 (mal-data-value arglist
))
105 :attrs
(list (cons 'params arglist
)
109 (t (let* ((evaluated-list (eval-ast ast env
))
110 (function (car evaluated-list
)))
111 ;; If first element is a mal function unwrap it
112 (if (not (types:mal-fn-p function
))
113 (return (apply (mal-data-value function
)
114 (cdr evaluated-list
)))
115 (let* ((attrs (types:mal-data-attrs function
)))
116 (setf ast
(cdr (assoc 'ast attrs
))
117 env
(make-instance 'env
:mal-environment
118 :parent
(cdr (assoc 'env attrs
))
121 (mal-data-value (cdr (assoc 'params attrs
))))
122 :exprs
(cdr evaluated-list
)))))))))))))
124 (defun mal-print (expression)
125 (printer:pr-str expression
))
129 (mal-print (mal-eval (mal-read string
)
131 (reader:eof
(condition)
135 (env:undefined-symbol
(condition)
144 (rep "(def! not (fn* (a) (if a false true)))")
146 (defun readline (prompt &optional
(in-stream *standard-input
*) (out-stream *standard-output
*))
147 (format out-stream prompt
)
148 (force-output out-stream
)
149 (read-line in-stream nil
))
151 (defun writeline (string)
153 (write-line string
)))
156 (loop do
(let ((line (readline "user> ")))
157 (if line
(writeline (rep line
)) (return)))))