mirror of
https://github.com/kanaka/mal.git
synced 2024-09-11 13:55:55 +03:00
Merge pull request #442 from asarhaddon/mal-macro-env
Mal: cosmetic improvements for envs and macros
This commit is contained in:
commit
d5061dccb9
10
mal/env.mal
10
mal/env.mal
@ -12,16 +12,18 @@
|
||||
(atom (apply bind-env {:outer (first args)} (rest args))))))
|
||||
|
||||
(def! env-find (fn* [env k]
|
||||
(env-find-str env (str k))))
|
||||
|
||||
(def! env-find-str (fn* [env ks]
|
||||
(if env
|
||||
(let* [ks (str k)
|
||||
data @env]
|
||||
(let* [data @env]
|
||||
(if (contains? data ks)
|
||||
env
|
||||
(env-find (get data :outer) ks))))))
|
||||
(env-find-str (get data :outer) ks))))))
|
||||
|
||||
(def! env-get (fn* [env k]
|
||||
(let* [ks (str k)
|
||||
e (env-find env ks)]
|
||||
e (env-find-str env ks)]
|
||||
(if e
|
||||
(get @e ks)
|
||||
(throw (str "'" ks "' not found"))))))
|
||||
|
@ -14,9 +14,9 @@
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
|
||||
"else" ast)))
|
||||
|
||||
|
@ -15,9 +15,9 @@
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
|
||||
"else" ast)))
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
|
||||
"else" ast)))
|
||||
|
||||
|
@ -16,9 +16,9 @@
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
|
||||
"else" ast)))
|
||||
|
||||
|
@ -34,9 +34,9 @@
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
|
||||
"else" ast)))
|
||||
|
||||
|
@ -24,19 +24,12 @@
|
||||
"else"
|
||||
(list 'cons (QUASIQUOTE a0) (QUASIQUOTE (rest ast))))))))
|
||||
|
||||
(def! is-macro-call (fn* [ast env]
|
||||
(if (list? ast)
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(let* [m (env-get env a0)]
|
||||
(if (_macro? m)
|
||||
(get m :__MAL_MACRO__)))))))))
|
||||
|
||||
(def! MACROEXPAND (fn* [ast env]
|
||||
(let* [m (is-macro-call ast env)]
|
||||
(if m
|
||||
(MACROEXPAND (apply m (rest ast)) env)
|
||||
(let* [a0 (if (list? ast) (first ast))
|
||||
e (if (symbol? a0) (env-find env a0))
|
||||
m (if e (env-get e a0))]
|
||||
(if (_macro? m)
|
||||
(MACROEXPAND (apply (get m :__MAL_MACRO__) (rest ast)) env)
|
||||
ast))))
|
||||
|
||||
(def! eval-ast (fn* [ast env]
|
||||
|
@ -24,19 +24,12 @@
|
||||
"else"
|
||||
(list 'cons (QUASIQUOTE a0) (QUASIQUOTE (rest ast))))))))
|
||||
|
||||
(def! is-macro-call (fn* [ast env]
|
||||
(if (list? ast)
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(let* [m (env-get env a0)]
|
||||
(if (_macro? m)
|
||||
(get m :__MAL_MACRO__)))))))))
|
||||
|
||||
(def! MACROEXPAND (fn* [ast env]
|
||||
(let* [m (is-macro-call ast env)]
|
||||
(if m
|
||||
(MACROEXPAND (apply m (rest ast)) env)
|
||||
(let* [a0 (if (list? ast) (first ast))
|
||||
e (if (symbol? a0) (env-find env a0))
|
||||
m (if e (env-get e a0))]
|
||||
(if (_macro? m)
|
||||
(MACROEXPAND (apply (get m :__MAL_MACRO__) (rest ast)) env)
|
||||
ast))))
|
||||
|
||||
(def! eval-ast (fn* [ast env]
|
||||
|
@ -24,19 +24,12 @@
|
||||
"else"
|
||||
(list 'cons (QUASIQUOTE a0) (QUASIQUOTE (rest ast))))))))
|
||||
|
||||
(def! is-macro-call (fn* [ast env]
|
||||
(if (list? ast)
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(let* [m (env-get env a0)]
|
||||
(if (_macro? m)
|
||||
(get m :__MAL_MACRO__)))))))))
|
||||
|
||||
(def! MACROEXPAND (fn* [ast env]
|
||||
(let* [m (is-macro-call ast env)]
|
||||
(if m
|
||||
(MACROEXPAND (apply m (rest ast)) env)
|
||||
(let* [a0 (if (list? ast) (first ast))
|
||||
e (if (symbol? a0) (env-find env a0))
|
||||
m (if e (env-get e a0))]
|
||||
(if (_macro? m)
|
||||
(MACROEXPAND (apply (get m :__MAL_MACRO__) (rest ast)) env)
|
||||
ast))))
|
||||
|
||||
(def! eval-ast (fn* [ast env]
|
||||
|
@ -200,6 +200,13 @@ bit bad about it.
|
||||
|
||||
## The Make-A-Lisp Process
|
||||
|
||||
Feel free to follow the guide as literally or as loosely as you
|
||||
like. You are here to learn; wandering off the beaten path may be the
|
||||
way you learn best. However, each step builds on the previous steps,
|
||||
so if you are new to Lisp or new to your implementation language then
|
||||
you may want to stick more closely to the guide your first time
|
||||
through to avoid frustration at later steps.
|
||||
|
||||
In the steps that follow the name of the target language is "quux" and
|
||||
the file extension for that language is "qx".
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user