Skip to content

Commit

Permalink
Implement macros with maps instead of vectors.
Browse files Browse the repository at this point in the history
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 cb9b065.
  • Loading branch information
asarhaddon committed Jul 14, 2019
1 parent cb9b065 commit 809d74c
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 41 deletions.
32 changes: 9 additions & 23 deletions mal/core.mal
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
(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! _map? (fn* [x]
(if (map? x)
(not (= (keys x) '(:__MAL_MACRO__)))
false)))

(def! _macro? (fn* [x]
(if (_macro_unwrap x)
true
(if (map? x)
(= (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! core_ns
[['= =]
['throw throw]
Expand Down Expand Up @@ -57,17 +43,17 @@
['list list]
['list? list?]
['vector vector]
['vector? _vector?]
['vector? vector?]
['hash-map hash-map]
['map? map?]
['map? _map?]
['assoc assoc]
['dissoc dissoc]
['get get]
['contains? contains?]
['keys keys]
['vals vals]

['sequential? _sequential?]
['sequential? sequential?]
['cons cons]
['concat concat]
['nth nth]
Expand Down
13 changes: 7 additions & 6 deletions mal/step8_macros.mal
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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))))
Expand Down Expand Up @@ -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)
Expand All @@ -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))
Expand Down
13 changes: 7 additions & 6 deletions mal/step9_try.mal
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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))))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
13 changes: 7 additions & 6 deletions mal/stepA_mal.mal
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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))))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
3 changes: 3 additions & 0 deletions tests/step9_try.mal
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@
(map? :abc)
;=>false


;;
;; Testing hash-maps
(hash-map "a" 1)
Expand Down Expand Up @@ -377,3 +378,5 @@
(= [] {})
;=>false

(map? cond)
;=>false
2 changes: 2 additions & 0 deletions tests/stepA_mal.mal
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@
;=>false
(macro? :+)
;=>false
(macro? {})
;=>false


;;
Expand Down

0 comments on commit 809d74c

Please sign in to comment.