1
1
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:
Nicolas Boulenguez 2019-07-14 17:07:44 +02:00
parent cb9b0654fe
commit 809d74cba7
6 changed files with 36 additions and 42 deletions

View File

@ -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]

View File

@ -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))

View File

@ -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))

View File

@ -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))

View File

@ -177,6 +177,7 @@
(map? :abc)
;=>false
;;
;; Testing hash-maps
(hash-map "a" 1)
@ -377,3 +378,5 @@
(= [] {})
;=>false
(map? cond)
;=>false

View File

@ -163,6 +163,8 @@
;=>false
(macro? :+)
;=>false
(macro? {})
;=>false
;;