1
1
mirror of https://github.com/kanaka/mal.git synced 2024-08-16 17:20:23 +03:00

mal: rename macro? to _macro?. Also rename bool-and in lib/equality.mal.

This commit is contained in:
Nicolas Boulenguez 2019-05-30 19:27:45 +02:00
parent 26ced15b31
commit b1a8dbd55f
6 changed files with 47 additions and 46 deletions

View File

@ -10,30 +10,30 @@
(def! scalar-equal? =)
;; A faster `and` macro which doesn't use `=` internally.
(defmacro! and2 ; boolean
(defmacro! bool-and ; boolean
(fn* [& xs] ; interpreted as logical values
(if (empty? xs)
true
`(if ~(first xs) (and2 ~@(rest xs)) false))))
(defmacro! or2 ; boolean
`(if ~(first xs) (bool-and ~@(rest xs)) false))))
(defmacro! bool-or ; boolean
(fn* [& xs] ; interpreted as logical values
(if (empty? xs)
false
`(if ~(first xs) true (or2 ~@(rest xs))))))
`(if ~(first xs) true (bool-or ~@(rest xs))))))
(def! starts-with?
(fn* [a b]
(or2 (empty? a)
(and2 (mal-equal? (first a) (first b))
(starts-with? (rest a) (rest b))))))
(bool-or (empty? a)
(bool-and (mal-equal? (first a) (first b))
(starts-with? (rest a) (rest b))))))
(def! hash-map-vals-equal?
(fn* [a b map-keys]
(or2 (empty? map-keys)
(let* [key (first map-keys)]
(and2 (contains? b key)
(mal-equal? (get a key) (get b key))
(hash-map-vals-equal? a b (rest map-keys)))))))
(bool-or (empty? map-keys)
(let* [key (first map-keys)]
(bool-and (contains? b key)
(mal-equal? (get a key) (get b key))
(hash-map-vals-equal? a b (rest map-keys)))))))
;; This implements = in pure mal (using only scalar-equal? as native impl)
(def! mal-equal?
@ -41,15 +41,15 @@
(cond
(sequential? a)
(and2 (sequential? b)
(scalar-equal? (count a) (count b))
(starts-with? a b))
(bool-and (sequential? b)
(scalar-equal? (count a) (count b))
(starts-with? a b))
(map? a)
(let* [keys-a (keys a)]
(and2 (map? b)
(scalar-equal? (count keys-a) (count (keys b)))
(hash-map-vals-equal? a b keys-a)))
(bool-and (map? b)
(scalar-equal? (count keys-a) (count (keys b)))
(hash-map-vals-equal? a b keys-a)))
true
(scalar-equal? a b))))
@ -57,20 +57,21 @@
(def! hash-map-equality-correct?
(fn* []
(try*
(and2 (= {:a 1} {:a 1})
(not (= {:a 1} {:a 1 :b 2})))
(bool-and (= {:a 1} {:a 1})
(not (= {:a 1} {:a 1 :b 2})))
(catch* _ false))))
(def! sequence-equality-correct?
(fn* []
(try*
(and2 (= [:a :b] (list :a :b))
(not (= [:a :b] [:a :b :c])))
(bool-and (= [:a :b] (list :a :b))
(not (= [:a :b] [:a :b :c])))
(catch* _ false))))
;; If the native `=` implementation doesn't support sequences or hash-maps
;; correctly, replace it with the pure mal implementation
(if (not (and2 (hash-map-equality-correct?) (sequence-equality-correct?)))
(if (not (bool-and (hash-map-equality-correct?)
(sequence-equality-correct?)))
(do
(def! = mal-equal?)
(println "equality.mal: Replaced = with pure mal implementation")))

View File

@ -3,7 +3,7 @@
(not (get (meta x) "ismacro"))
false)))
(def! macro? (fn* [x]
(def! _macro? (fn* [x]
(if (fn? x)
(if (get (meta x) "ismacro")
true
@ -23,7 +23,7 @@
['keyword keyword]
['keyword? keyword?]
['fn? _fn?]
['macro? macro?]
['macro? _macro?]
['pr-str pr-str]
['str str]

View File

@ -29,7 +29,7 @@
(let* [a0 (first ast)]
(if (symbol? a0)
(if (env-find env a0)
(macro? (env-get env a0))))))))
(_macro? (env-get env a0))))))))
(def! MACROEXPAND (fn* [ast env]
(if (is-macro-call ast env)

View File

@ -29,7 +29,7 @@
(let* [a0 (first ast)]
(if (symbol? a0)
(if (env-find env a0)
(macro? (env-get env a0))))))))
(_macro? (env-get env a0))))))))
(def! MACROEXPAND (fn* [ast env]
(if (is-macro-call ast env)

View File

@ -29,7 +29,7 @@
(let* [a0 (first ast)]
(if (symbol? a0)
(if (env-find env a0)
(macro? (env-get env a0))))))))
(_macro? (env-get env a0))))))))
(def! MACROEXPAND (fn* [ast env]
(if (is-macro-call ast env)

View File

@ -4,42 +4,42 @@
(load-file "../lib/equality.mal")
;=>nil
;; Testing and2
(and2)
;; Testing bool-and
(bool-and)
;=>true
(and2 true)
(bool-and true)
;=>true
(and2 false)
(bool-and false)
;=>false
(and2 nil)
(bool-and nil)
;=>false
(and2 1)
(bool-and 1)
;=>true
(and2 1 2)
(bool-and 1 2)
;=>true
(and2 nil (nth () 1))
(bool-and nil (nth () 1))
;=>false
;; Testing or2
(or2)
;; Testing bool-or
(bool-or)
;=>false
(or2 true)
(bool-or true)
;=>true
(or2 false)
(bool-or false)
;=>false
(or2 nil)
(bool-or nil)
;=>false
(or2 1)
(bool-or 1)
;=>true
(or2 1 (nth () 1))
(bool-or 1 (nth () 1))
;=>true
(or2 1 2)
(bool-or 1 2)
;=>true
(or2 false nil)
(bool-or false nil)
;=>false
;; Breaking equality.
(def! = (fn* [a b] (and2 (orig= a b) (cond (list? a) (list? b) (vector? a) (vector? b) true true))))
(def! = (fn* [a b] (bool-and (orig= a b) (cond (list? a) (list? b) (vector? a) (vector? b) true true))))
(= [] ())
;=>false