mirror of
https://github.com/kanaka/mal.git
synced 2024-08-16 17:20:23 +03:00
Implement macros with maps instead of vectors.
Output of macros will probably be more readable.
Inline _macro_wrap and _unwrap for efficiency (there are less
primitive operations for maps than for vectors).
Basic check of `map?` and `macro?`. Swap them in order to simplify the
diff with cb9b0654
.
This commit is contained in:
parent
cb9b0654fe
commit
809d74cba7
34
mal/core.mal
34
mal/core.mal
@ -1,26 +1,12 @@
|
||||
(def! _macro_magic
|
||||
:_I_tell_ya_this_is_a_MAL_macro_mark_my_words)
|
||||
|
||||
(def! _macro_wrap (fn* [f]
|
||||
[_macro_magic f]))
|
||||
|
||||
(def! _macro_unwrap (fn* [x]
|
||||
(if (vector? x)
|
||||
(if (= (first x) _macro_magic)
|
||||
(nth x 1)))))
|
||||
|
||||
(def! _macro? (fn* [x]
|
||||
(if (_macro_unwrap x)
|
||||
true
|
||||
(def! _map? (fn* [x]
|
||||
(if (map? x)
|
||||
(not (= (keys x) '(:__MAL_MACRO__)))
|
||||
false)))
|
||||
|
||||
(def! false_on_macro (fn* [f]
|
||||
(fn* [x]
|
||||
(if (_macro_unwrap x)
|
||||
false
|
||||
(f x)))))
|
||||
(def! _sequential? (false_on_macro sequential?))
|
||||
(def! _vector? (false_on_macro vector?))
|
||||
(def! _macro? (fn* [x]
|
||||
(if (map? x)
|
||||
(= (keys x) '(:__MAL_MACRO__))
|
||||
false)))
|
||||
|
||||
(def! core_ns
|
||||
[['= =]
|
||||
@ -57,9 +43,9 @@
|
||||
['list list]
|
||||
['list? list?]
|
||||
['vector vector]
|
||||
['vector? _vector?]
|
||||
['vector? vector?]
|
||||
['hash-map hash-map]
|
||||
['map? map?]
|
||||
['map? _map?]
|
||||
['assoc assoc]
|
||||
['dissoc dissoc]
|
||||
['get get]
|
||||
@ -67,7 +53,7 @@
|
||||
['keys keys]
|
||||
['vals vals]
|
||||
|
||||
['sequential? _sequential?]
|
||||
['sequential? sequential?]
|
||||
['cons cons]
|
||||
['concat concat]
|
||||
['nth nth]
|
||||
|
@ -29,7 +29,9 @@
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(_macro_unwrap (env-get 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)]
|
||||
@ -44,9 +46,9 @@
|
||||
|
||||
(list? ast) (map (fn* [exp] (EVAL exp env)) ast)
|
||||
|
||||
(_vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(_map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
@ -85,7 +87,7 @@
|
||||
(EVAL (QUASIQUOTE (nth ast 1)) env)
|
||||
|
||||
(= 'defmacro! a0)
|
||||
(env-set env (nth ast 1) (_macro_wrap (EVAL (nth ast 2) env)))
|
||||
(env-set env (nth ast 1) {:__MAL_MACRO__ (EVAL (nth ast 2) env)})
|
||||
|
||||
(= 'macroexpand a0)
|
||||
(MACROEXPAND (nth ast 1) env)
|
||||
@ -109,8 +111,7 @@
|
||||
|
||||
|
||||
;; print
|
||||
(def! PRINT (fn* [x]
|
||||
(pr-str (let* [m (_macro_unwrap x)] (if m m x)))))
|
||||
(def! PRINT pr-str)
|
||||
|
||||
;; repl
|
||||
(def! repl-env (new-env))
|
||||
|
@ -29,7 +29,9 @@
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(_macro_unwrap (env-get 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)]
|
||||
@ -44,9 +46,9 @@
|
||||
|
||||
(list? ast) (map (fn* [exp] (EVAL exp env)) ast)
|
||||
|
||||
(_vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(_map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
@ -85,7 +87,7 @@
|
||||
(EVAL (QUASIQUOTE (nth ast 1)) env)
|
||||
|
||||
(= 'defmacro! a0)
|
||||
(env-set env (nth ast 1) (_macro_wrap (EVAL (nth ast 2) env)))
|
||||
(env-set env (nth ast 1) {:__MAL_MACRO__ (EVAL (nth ast 2) env)})
|
||||
|
||||
(= 'macroexpand a0)
|
||||
(MACROEXPAND (nth ast 1) env)
|
||||
@ -118,8 +120,7 @@
|
||||
|
||||
|
||||
;; print
|
||||
(def! PRINT (fn* [x]
|
||||
(pr-str (let* [m (_macro_unwrap x)] (if m m x)))))
|
||||
(def! PRINT pr-str)
|
||||
|
||||
;; repl
|
||||
(def! repl-env (new-env))
|
||||
|
@ -29,7 +29,9 @@
|
||||
(let* [a0 (first ast)]
|
||||
(if (symbol? a0)
|
||||
(if (env-find env a0)
|
||||
(_macro_unwrap (env-get 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)]
|
||||
@ -44,9 +46,9 @@
|
||||
|
||||
(list? ast) (map (fn* [exp] (EVAL exp env)) ast)
|
||||
|
||||
(_vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
(vector? ast) (apply vector (map (fn* [exp] (EVAL exp env)) ast))
|
||||
|
||||
(map? ast) (apply hash-map
|
||||
(_map? ast) (apply hash-map
|
||||
(apply concat
|
||||
(map (fn* [k] [k (EVAL (get ast k) env)])
|
||||
(keys ast))))
|
||||
@ -85,7 +87,7 @@
|
||||
(EVAL (QUASIQUOTE (nth ast 1)) env)
|
||||
|
||||
(= 'defmacro! a0)
|
||||
(env-set env (nth ast 1) (_macro_wrap (EVAL (nth ast 2) env)))
|
||||
(env-set env (nth ast 1) {:__MAL_MACRO__ (EVAL (nth ast 2) env)})
|
||||
|
||||
(= 'macroexpand a0)
|
||||
(MACROEXPAND (nth ast 1) env)
|
||||
@ -118,8 +120,7 @@
|
||||
|
||||
|
||||
;; print
|
||||
(def! PRINT (fn* [x]
|
||||
(pr-str (let* [m (_macro_unwrap x)] (if m m x)))))
|
||||
(def! PRINT pr-str)
|
||||
|
||||
;; repl
|
||||
(def! repl-env (new-env))
|
||||
|
@ -177,6 +177,7 @@
|
||||
(map? :abc)
|
||||
;=>false
|
||||
|
||||
|
||||
;;
|
||||
;; Testing hash-maps
|
||||
(hash-map "a" 1)
|
||||
@ -377,3 +378,5 @@
|
||||
(= [] {})
|
||||
;=>false
|
||||
|
||||
(map? cond)
|
||||
;=>false
|
||||
|
@ -163,6 +163,8 @@
|
||||
;=>false
|
||||
(macro? :+)
|
||||
;=>false
|
||||
(macro? {})
|
||||
;=>false
|
||||
|
||||
|
||||
;;
|
||||
|
Loading…
Reference in New Issue
Block a user