Merge pull request #217 from dubek/lua-interop
[jackhill/mal.git] / mal / step6_file.mal
CommitLineData
31690700 1(load-file "../mal/env.mal")
ea81a808 2(load-file "../mal/core.mal")
31690700
JM
3
4;; read
5(def! READ (fn* [strng]
6 (read-string strng)))
7
8
9;; eval
10(def! eval-ast (fn* [ast env] (do
11 ;;(do (prn "eval-ast" ast "/" (keys env)) )
12 (cond
13 (symbol? ast) (env-get env ast)
14
15 (list? ast) (map (fn* [exp] (EVAL exp env)) ast)
16
17 (vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
18
19 (map? ast) (apply hash-map
20 (apply concat
21 (map (fn* [k] [k (EVAL (get ast k) env)])
22 (keys ast))))
23
24 "else" ast))))
25
26(def! LET (fn* [env args]
27 (if (> (count args) 0)
28 (do
29 (env-set env (nth args 0) (EVAL (nth args 1) env))
30 (LET env (rest (rest args)))))))
31
32(def! EVAL (fn* [ast env] (do
33 ;;(do (prn "EVAL" ast "/" (keys @env)) )
34 (if (not (list? ast))
35 (eval-ast ast env)
36
37 ;; apply list
38 (let* [a0 (first ast)]
39 (cond
3178009c
DM
40 (nil? a0)
41 ast
42
31690700
JM
43 (= 'def! a0)
44 (env-set env (nth ast 1) (EVAL (nth ast 2) env))
45
46 (= 'let* a0)
47 (let* [let-env (new-env env)]
48 (do
49 (LET let-env (nth ast 1))
50 (EVAL (nth ast 2) let-env)))
51
52 (= 'do a0)
53 (let* [el (eval-ast (rest ast) env)]
54 (nth el (- (count el) 1)))
55
56 (= 'if a0)
57 (let* [cond (EVAL (nth ast 1) env)]
58 (if (or (= cond nil) (= cond false))
59 (if (> (count ast) 3)
60 (EVAL (nth ast 3) env)
61 nil)
62 (EVAL (nth ast 2) env)))
a2849f89 63
31690700
JM
64 (= 'fn* a0)
65 (fn* [& args]
66 (EVAL (nth ast 2) (new-env env (nth ast 1) args)))
67
68 "else"
69 (let* [el (eval-ast ast env)
70 f (first el)
71 args (rest el)]
72 (apply f args))))))))
73
74
75;; print
76(def! PRINT (fn* [exp] (pr-str exp)))
77
78;; repl
79(def! repl-env (new-env))
80(def! rep (fn* [strng]
1617910a 81 (PRINT (EVAL (READ strng) repl-env))))
31690700 82
8cb5cda4
JM
83;; core.mal: defined directly using mal
84(map (fn* [data] (env-set repl-env (nth data 0) (nth data 1))) core_ns)
85(env-set repl-env 'eval (fn* [ast] (EVAL ast repl-env)))
86b689f3 86(env-set repl-env '*ARGV* (rest *ARGV*))
31690700 87
8cb5cda4 88;; core.mal: defined using the new language itself
31690700 89(rep "(def! not (fn* [a] (if a false true)))")
1617910a 90(rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))")
31690700 91
86b689f3
JM
92;; repl loop
93(def! repl-loop (fn* []
31690700
JM
94 (let* [line (readline "mal-user> ")]
95 (if line
96 (do
97 (if (not (= "" line))
98 (try*
86b689f3 99 (println (rep line))
31690700
JM
100 (catch* exc
101 (println "Uncaught exception:" exc))))
86b689f3
JM
102 (repl-loop))))))
103
104(def! -main (fn* [& args]
105 (if (> (count args) 0)
106 (rep (str "(load-file \"" (first args) "\")"))
107 (repl-loop))))
108(apply -main *ARGV*)