mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 10:37:58 +03:00
Hy: step3
This commit is contained in:
parent
cadde2db98
commit
5d2813209a
19
hy/env.hy
Normal file
19
hy/env.hy
Normal file
@ -0,0 +1,19 @@
|
||||
(defn env-new [&optional [outer None] [binds None] [exprs None]]
|
||||
{:outer outer})
|
||||
|
||||
(defn env-find [env k]
|
||||
(if
|
||||
(.has_key env k) env
|
||||
(.has_key env ':outer) (env-find (get env ':outer) k)
|
||||
True None))
|
||||
|
||||
(defn env-get [env k]
|
||||
(setv e (env-find env k))
|
||||
(if-not e
|
||||
(raise (Exception (+ "'" k "' not found"))))
|
||||
(get e k))
|
||||
|
||||
(defn env-set [env k v]
|
||||
(assoc env k v)
|
||||
v)
|
||||
|
74
hy/step3_env.hy
Executable file
74
hy/step3_env.hy
Executable file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env hy
|
||||
|
||||
(import [hy.models [HyDict :as Map HySymbol :as Sym]])
|
||||
(import sys traceback)
|
||||
(import [reader [read-str Blank]])
|
||||
(import [printer [pr-str]])
|
||||
(import [env [env-new env-get env-set]])
|
||||
|
||||
;; read
|
||||
(defn READ [str]
|
||||
(read-str str))
|
||||
|
||||
;; eval
|
||||
(defn eval-ast [ast env]
|
||||
;;(print "eval-ast:" ast (type ast))
|
||||
(if
|
||||
(symbol? ast) (env-get env ast)
|
||||
(instance? Map ast) (Map (map (fn [x] (EVAL x env)) ast))
|
||||
(instance? tuple ast) (tuple (map (fn [x] (EVAL x env)) ast))
|
||||
(instance? list ast) (list (map (fn [x] (EVAL x env)) ast))
|
||||
True ast))
|
||||
|
||||
(defn EVAL [ast env]
|
||||
;;(print "EVAL:" ast (type ast) (instance? tuple ast))
|
||||
(if (not (instance? tuple ast))
|
||||
(eval-ast ast env)
|
||||
|
||||
;; apply list
|
||||
(do
|
||||
(setv [a0 a1 a2] [(nth ast 0) (nth ast 1) (nth ast 2)])
|
||||
(if
|
||||
(none? a0)
|
||||
ast
|
||||
|
||||
(= (Sym "def!") a0)
|
||||
(env-set env a1 (EVAL a2 env))
|
||||
|
||||
(= (Sym "let*") a0)
|
||||
(do
|
||||
(setv let-env (env-new env))
|
||||
(for [[b e] (partition a1 2)]
|
||||
(env-set let-env b (EVAL e let-env)))
|
||||
(EVAL a2 let-env))
|
||||
|
||||
;; apply
|
||||
(do
|
||||
(setv el (eval-ast ast env)
|
||||
f (first el)
|
||||
args (rest el))
|
||||
(apply f args))))))
|
||||
|
||||
;; print
|
||||
(defn PRINT [exp]
|
||||
(pr-str exp True))
|
||||
|
||||
;; repl
|
||||
|
||||
(def repl-env {'+ +
|
||||
'- -
|
||||
'* *
|
||||
'/ (fn [a b] (int (/ a b)))})
|
||||
|
||||
(defn REP [str]
|
||||
(PRINT (EVAL (READ str) repl-env)))
|
||||
|
||||
(while True
|
||||
(try
|
||||
(do (setv line (raw_input "user> "))
|
||||
(if (= "" line) (continue))
|
||||
(print (REP line)))
|
||||
(except [EOFError] (break))
|
||||
(except [Blank])
|
||||
(except []
|
||||
(print (.join "" (apply traceback.format_exception (.exc_info sys)))))))
|
Loading…
Reference in New Issue
Block a user