2016-10-03 01:31:43 +03:00
|
|
|
(de load-relative (Path)
|
|
|
|
(load (pack (car (file)) Path)) )
|
|
|
|
|
|
|
|
(load-relative "readline.l")
|
|
|
|
(load-relative "types.l")
|
|
|
|
(load-relative "reader.l")
|
|
|
|
(load-relative "printer.l")
|
|
|
|
(load-relative "env.l")
|
|
|
|
|
|
|
|
(de READ (String)
|
|
|
|
(read-str String) )
|
|
|
|
|
2016-10-14 10:40:19 +03:00
|
|
|
(def '*ReplEnv (MAL-env NIL))
|
|
|
|
(set> *ReplEnv '+ '((A B) (MAL-number (+ (MAL-value A) (MAL-value B)))))
|
|
|
|
(set> *ReplEnv '- '((A B) (MAL-number (- (MAL-value A) (MAL-value B)))))
|
|
|
|
(set> *ReplEnv '* '((A B) (MAL-number (* (MAL-value A) (MAL-value B)))))
|
|
|
|
(set> *ReplEnv '/ '((A B) (MAL-number (/ (MAL-value A) (MAL-value B)))))
|
2016-10-03 01:31:43 +03:00
|
|
|
|
|
|
|
(de EVAL (Ast Env)
|
2022-01-10 02:15:40 +03:00
|
|
|
(when (and (get> Env 'DEBUG-EVAL)
|
|
|
|
(not (memq (MAL-type @) '(nil false))))
|
|
|
|
(prinl "EVAL: " (pr-str Ast T)))
|
|
|
|
|
|
|
|
(case (MAL-type Ast)
|
|
|
|
(list
|
2016-10-03 01:31:43 +03:00
|
|
|
(let (Ast* (MAL-value Ast)
|
|
|
|
A0* (MAL-value (car Ast*))
|
|
|
|
A1* (MAL-value (cadr Ast*))
|
|
|
|
A2 (caddr Ast*))
|
|
|
|
(cond
|
2022-01-10 02:15:40 +03:00
|
|
|
((not Ast*)
|
|
|
|
Ast)
|
2016-10-03 01:31:43 +03:00
|
|
|
((= A0* 'def!)
|
|
|
|
(set> Env A1* (EVAL A2 Env)) )
|
|
|
|
((= A0* 'let*)
|
|
|
|
(let Env* (MAL-env Env)
|
|
|
|
(for (Bindings A1* Bindings)
|
|
|
|
(let (Key (MAL-value (pop 'Bindings))
|
|
|
|
Value (EVAL (pop 'Bindings) Env*))
|
|
|
|
(set> Env* Key Value) ) )
|
|
|
|
(EVAL A2 Env*) ) )
|
2022-01-10 02:15:40 +03:00
|
|
|
(T (let Value (mapcar '((Form) (EVAL Form Env)) Ast*)
|
2016-10-03 01:31:43 +03:00
|
|
|
(apply (car Value) (cdr Value)) ) ) ) ) )
|
2022-01-10 02:15:40 +03:00
|
|
|
(symbol
|
|
|
|
(let (Key (MAL-value Ast))
|
|
|
|
(or (get> Env Key)
|
|
|
|
(throw 'err (MAL-error (MAL-string (pack "'" Key "' not found")))))))
|
|
|
|
(vector (MAL-vector (mapcar '((Form) (EVAL Form Env)) (MAL-value Ast))))
|
|
|
|
(map (MAL-map (mapcar '((Form) (EVAL Form Env)) (MAL-value Ast))))
|
|
|
|
(T Ast)))
|
2016-10-03 01:31:43 +03:00
|
|
|
|
|
|
|
(de PRINT (Ast)
|
|
|
|
(pr-str Ast T) )
|
|
|
|
|
2016-10-14 11:16:44 +03:00
|
|
|
(de rep (String)
|
|
|
|
(PRINT (EVAL (READ String) *ReplEnv)) )
|
2016-10-03 01:31:43 +03:00
|
|
|
|
|
|
|
(load-history ".mal_history")
|
|
|
|
|
|
|
|
(use Eof
|
|
|
|
(until Eof
|
|
|
|
(let Input (readline "user> ")
|
|
|
|
(if (=0 Input)
|
|
|
|
(setq Eof T)
|
2016-10-14 11:16:44 +03:00
|
|
|
(let Output (catch 'err (rep Input))
|
2016-10-03 01:31:43 +03:00
|
|
|
(if (isa '+MALError Output)
|
|
|
|
(let Message (MAL-value Output)
|
2016-10-22 13:37:24 +03:00
|
|
|
(unless (= (MAL-value Message) "end of token stream")
|
|
|
|
(prinl "[error] " (pr-str Message)) ) )
|
2016-10-03 01:31:43 +03:00
|
|
|
(prinl Output) ) ) ) ) ) )
|
|
|
|
|
|
|
|
(prinl)
|
|
|
|
(bye)
|