Merge pull request #898 from algernon/glc/DOWN-WITH-THEM-BRACKETS
A big let and with change
This commit is contained in:
commit
7904632b05
@ -213,17 +213,17 @@ Examples of usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=>(let [[collection {}]]
|
||||
=>(let [collection {}]
|
||||
... (assoc collection "Dog" "Bark")
|
||||
... (print collection))
|
||||
{u'Dog': u'Bark'}
|
||||
|
||||
=>(let [[collection {}]]
|
||||
=>(let [collection {}]
|
||||
... (assoc collection "Dog" "Bark" "Cat" "Meow")
|
||||
... (print collection))
|
||||
{u'Cat': u'Meow', u'Dog': u'Bark'}
|
||||
|
||||
=>(let [[collection [1 2 3 4]]]
|
||||
=>(let [collection [1 2 3 4]]
|
||||
... (assoc collection 2 None)
|
||||
... (print collection))
|
||||
[1, 2, None, 4]
|
||||
@ -463,8 +463,8 @@ Parameters may have the following keywords in front of them:
|
||||
.. code-block:: clj
|
||||
|
||||
=> (defn zig-zag-sum [&rest numbers]
|
||||
(let [[odd-numbers (list-comp x [x numbers] (odd? x))]
|
||||
[even-numbers (list-comp x [x numbers] (even? x))]]
|
||||
(let [odd-numbers (list-comp x [x numbers] (odd? x))
|
||||
even-numbers (list-comp x [x numbers] (even? x))]
|
||||
(- (sum odd-numbers) (sum even-numbers))))
|
||||
|
||||
=> (zig-zag-sum)
|
||||
@ -486,7 +486,7 @@ Parameters may have the following keywords in front of them:
|
||||
.. code-block:: clj
|
||||
|
||||
=> (defn compare [a b &kwonly keyfn [reverse false]]
|
||||
... (let [[result (keyfn a b)]]
|
||||
... (let [result (keyfn a b)]
|
||||
... (if (not reverse)
|
||||
... result
|
||||
... (- result))))
|
||||
@ -786,8 +786,8 @@ list. Example usage:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (let [[animals {"dog" "bark" "cat" "meow"}]
|
||||
... [numbers ["zero" "one" "two" "three"]]]
|
||||
=> (let [animals {"dog" "bark" "cat" "meow"}
|
||||
... numbers ["zero" "one" "two" "three"]]
|
||||
... (print (get animals "dog"))
|
||||
... (print (get numbers 2)))
|
||||
bark
|
||||
@ -988,30 +988,24 @@ example showcases this behaviour:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (let [[x 5]] (print x)
|
||||
... (let [[x 6]] (print x))
|
||||
=> (let [x 5] (print x)
|
||||
... (let [x 6] (print x))
|
||||
... (print x))
|
||||
5
|
||||
6
|
||||
5
|
||||
|
||||
The ``let`` macro takes two parameters: a vector defining *variables* and the
|
||||
*body* which gets executed. *variables* is a vector where each element is either
|
||||
a single variable or a vector defining a variable value pair. In the case of a
|
||||
single variable, it is assigned value ``None``; otherwise, the supplied value is
|
||||
used.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (let [x [y 5]] (print x y))
|
||||
None 5
|
||||
The ``let`` macro takes two parameters: a vector defining *variables*
|
||||
and the *body* which gets executed. *variables* is a vector of
|
||||
variable and value pairs.
|
||||
|
||||
Note that the variable assignments are executed one by one, from left to right.
|
||||
The following example takes advantage of this:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
=> (let [[x 5] [y (+ x 1)]] (print x y))
|
||||
=> (let [x 5
|
||||
y (+ x 1)] (print x y))
|
||||
5 6
|
||||
|
||||
|
||||
@ -1050,15 +1044,15 @@ to modify variables through nested ``let`` or ``fn`` scopes:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(for [y (range 10)]
|
||||
(let [[z (inc y)]]
|
||||
(let [z (inc y)]
|
||||
(nonlocal x) ; allow the setv to "jump scope" to resolve x
|
||||
(setv x (+ x y))))
|
||||
x)
|
||||
|
||||
(defn some-function []
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(register-some-callback
|
||||
(fn [stuff]
|
||||
(nonlocal x)
|
||||
@ -1369,18 +1363,18 @@ manner. The archetypical example of using ``with`` is when processing files.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(with [[arg (expr)]] block)
|
||||
(with [arg (expr)] block)
|
||||
|
||||
(with [[(expr)]] block)
|
||||
(with [(expr)] block)
|
||||
|
||||
(with [[arg (expr)] [(expr)]] block)
|
||||
(with [arg (expr) (expr)] block)
|
||||
|
||||
The following example will open the ``NEWS`` file and print its content to the
|
||||
screen. The file is automatically closed after it has been processed.
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(with [[f (open "NEWS")]] (print (.read f)))
|
||||
(with [f (open "NEWS")] (print (.read f)))
|
||||
|
||||
|
||||
with-decorator
|
||||
@ -1467,9 +1461,9 @@ expands to:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
(let [[a (gensym)
|
||||
[b (gensym)
|
||||
[c (gensym)]]
|
||||
(let [a (gensym)
|
||||
b (gensym)
|
||||
c (gensym)]
|
||||
...)
|
||||
|
||||
.. seealso::
|
||||
|
@ -1100,10 +1100,10 @@ if *from-file* ends before a complete expression can be parsed.
|
||||
=> ; assuming "example.hy" contains:
|
||||
=> ; (print "hello")
|
||||
=> ; (print "hyfriends!")
|
||||
=> (with [[f (open "example.hy")]]
|
||||
=> (with [f (open "example.hy")]
|
||||
... (try
|
||||
... (while true
|
||||
... (let [[exp (read f)]]
|
||||
... (let [exp (read f)]
|
||||
... (do
|
||||
... (print "OHY" exp)
|
||||
... (eval exp))))
|
||||
|
@ -381,7 +381,7 @@ A first pass might be something like:
|
||||
.. code-block:: hy
|
||||
|
||||
(defmacro nif [expr pos-form zero-form neg-form]
|
||||
`(let [[obscure-name ~expr]]
|
||||
`(let [obscure-name ~expr]
|
||||
(cond [(pos? obscure-name) ~pos-form]
|
||||
[(zero? obscure-name) ~zero-form]
|
||||
[(neg? obscure-name) ~neg-form])))
|
||||
@ -396,8 +396,8 @@ such an occasion. A much better version of ``nif`` would be:
|
||||
.. code-block:: hy
|
||||
|
||||
(defmacro nif [expr pos-form zero-form neg-form]
|
||||
(let [[g (gensym)]]
|
||||
`(let [[~g ~expr]]
|
||||
(let [g (gensym)]
|
||||
`(let [~g ~expr]
|
||||
(cond [(pos? ~g) ~pos-form]
|
||||
[(zero? ~g) ~zero-form]
|
||||
[(neg? ~g) ~neg-form]))))
|
||||
@ -415,9 +415,9 @@ expands to:
|
||||
|
||||
.. code-block:: hy
|
||||
|
||||
(let [[a (gensym)
|
||||
[b (gensym)
|
||||
[c (gensym)]]
|
||||
(let [a (gensym)
|
||||
b (gensym)
|
||||
c (gensym)]
|
||||
...)
|
||||
|
||||
so our re-written ``nif`` would look like:
|
||||
@ -426,7 +426,7 @@ so our re-written ``nif`` would look like:
|
||||
|
||||
(defmacro nif [expr pos-form zero-form neg-form]
|
||||
(with-gensyms [g]
|
||||
`(let [[~g ~expr]]
|
||||
`(let [~g ~expr]
|
||||
(cond [(pos? ~g) ~pos-form]
|
||||
[(zero? ~g) ~zero-form]
|
||||
[(neg? ~g) ~neg-form]))))
|
||||
@ -440,7 +440,7 @@ Our final version of ``nif``, built with ``defmacro/g!`` becomes:
|
||||
.. code-block:: hy
|
||||
|
||||
(defmacro/g! nif [expr pos-form zero-form neg-form]
|
||||
`(let [[~g!res ~expr]]
|
||||
`(let [~g!res ~expr]
|
||||
(cond [(pos? ~g!res) ~pos-form]
|
||||
[(zero? ~g!res) ~zero-form]
|
||||
[(neg? ~g!res) ~neg-form]))))
|
||||
|
@ -105,8 +105,8 @@ Layout & Indentation
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(let [[foo (bar)]
|
||||
[qux (baz)]]
|
||||
(let [foo (bar)]
|
||||
qux (baz)]
|
||||
(foo qux))
|
||||
|
||||
|
||||
|
@ -335,7 +335,7 @@ Python's context managers (``with`` statements) are used like this:
|
||||
|
||||
.. code-block:: clj
|
||||
|
||||
(with [[f (open "/tmp/data.in")]]
|
||||
(with [f (open "/tmp/data.in")]
|
||||
(print (.read f)))
|
||||
|
||||
which is equivalent to::
|
||||
|
@ -27,7 +27,7 @@
|
||||
(reactor.stop))
|
||||
|
||||
(defn get-page [url]
|
||||
(let [[d (getPage url)]]
|
||||
(let [d (getPage url)]
|
||||
(d.addCallback get-page-size)
|
||||
(d.addErrback log-error)
|
||||
(d.addCallback finish)))
|
||||
|
@ -30,8 +30,8 @@
|
||||
|
||||
(defmacro defn-alias [names lambda-list &rest body]
|
||||
"define one function with several names"
|
||||
(let [[main (first names)]
|
||||
[aliases (rest names)]]
|
||||
(let [main (first names)
|
||||
aliases (rest names)]
|
||||
(setv ret `(do (defn ~main ~lambda-list ~@body)))
|
||||
(for* [name aliases]
|
||||
(.append ret
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
(defmacro ap-if (test-form &rest args)
|
||||
`(let [[it ~test-form]] (if it ~@args)))
|
||||
`(let [it ~test-form] (if it ~@args)))
|
||||
|
||||
|
||||
(defmacro ap-each [lst &rest body]
|
||||
@ -37,7 +37,7 @@
|
||||
(defmacro ap-each-while [lst form &rest body]
|
||||
"Evalutate the body form for each element in the list while the
|
||||
predicate form evaluates to True."
|
||||
`(let [[p (lambda [it] ~form)]]
|
||||
`(let [p (lambda [it] ~form)]
|
||||
(for [it ~lst]
|
||||
(if (p it)
|
||||
~@body
|
||||
@ -46,8 +46,9 @@
|
||||
|
||||
(defmacro ap-map [form lst]
|
||||
"Yield elements evaluated in the form for each element in the list."
|
||||
(let [[v (gensym 'v)] [f (gensym 'f)]]
|
||||
`(let [[~f (lambda [it] ~form)]]
|
||||
(let [v (gensym 'v)
|
||||
f (gensym 'f)]
|
||||
`(let [~f (lambda [it] ~form)]
|
||||
(for [~v ~lst]
|
||||
(yield (~f ~v))))))
|
||||
|
||||
@ -55,7 +56,7 @@
|
||||
(defmacro ap-map-when [predfn rep lst]
|
||||
"Yield elements evaluated for each element in the list when the
|
||||
predicate function returns True."
|
||||
`(let [[f (lambda [it] ~rep)]]
|
||||
`(let [f (lambda [it] ~rep)]
|
||||
(for [it ~lst]
|
||||
(if (~predfn it)
|
||||
(yield (f it))
|
||||
@ -64,7 +65,7 @@
|
||||
|
||||
(defmacro ap-filter [form lst]
|
||||
"Yield elements returned when the predicate form evaluates to True."
|
||||
`(let [[pred (lambda [it] ~form)]]
|
||||
`(let [pred (lambda [it] ~form)]
|
||||
(for [val ~lst]
|
||||
(if (pred val)
|
||||
(yield val)))))
|
||||
@ -85,7 +86,7 @@
|
||||
(defmacro ap-first [predfn lst]
|
||||
"Yield the first element that passes `predfn`"
|
||||
(with-gensyms [n]
|
||||
`(let [[~n None]]
|
||||
`(let [~n None]
|
||||
(ap-each ~lst (when ~predfn (setv ~n it) (break)))
|
||||
~n)))
|
||||
|
||||
@ -93,7 +94,7 @@
|
||||
(defmacro ap-last [predfn lst]
|
||||
"Yield the last element that passes `predfn`"
|
||||
(with-gensyms [n]
|
||||
`(let [[~n None]]
|
||||
`(let [~n None]
|
||||
(ap-each ~lst (none? ~n)
|
||||
(when ~predfn
|
||||
(setv ~n it)))
|
||||
@ -103,10 +104,10 @@
|
||||
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
||||
"Anaphoric form of reduce, `acc' and `it' can be used for a form"
|
||||
(if (none? initial-value)
|
||||
`(let [[acc (car ~lst)]]
|
||||
`(let [acc (car ~lst)]
|
||||
(ap-each (cdr ~lst) (setv acc ~form))
|
||||
acc)
|
||||
`(let [[acc ~initial-value]]
|
||||
`(let [acc ~initial-value]
|
||||
(ap-each ~lst (setv acc ~form))
|
||||
acc)))
|
||||
|
||||
@ -115,7 +116,7 @@
|
||||
"Pushes a value through several forms.
|
||||
(Anaphoric version of -> and ->>)"
|
||||
(if (empty? forms) var
|
||||
`(ap-pipe (let [[it ~var]] ~(first forms)) ~@(rest forms))))
|
||||
`(ap-pipe (let [it ~var] ~(first forms)) ~@(rest forms))))
|
||||
|
||||
|
||||
(defmacro ap-compose [&rest forms]
|
||||
|
@ -26,8 +26,8 @@
|
||||
(do
|
||||
(import [requests])
|
||||
|
||||
(let [[r (requests.get
|
||||
"https://raw.githubusercontent.com/hylang/hy/master/AUTHORS")]]
|
||||
(let [r (requests.get
|
||||
"https://raw.githubusercontent.com/hylang/hy/master/AUTHORS")]
|
||||
(repeat r.text)))
|
||||
(except [e ImportError]
|
||||
(repeat "Botsbuildbots requires `requests' to function."))))
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
|
||||
(defn curry [func]
|
||||
(let [[sig (.getargspec inspect func)]
|
||||
[count (len sig.args)]]
|
||||
(let [sig (.getargspec inspect func)
|
||||
count (len sig.args)]
|
||||
|
||||
(fn [&rest args]
|
||||
(if (< (len args) count)
|
||||
|
@ -58,7 +58,7 @@
|
||||
|
||||
|
||||
(defmacro/g! fnr [signature &rest body]
|
||||
(let [[new-body (recursive-replace 'recur g!recur-fn body)]]
|
||||
(let [new-body (recursive-replace 'recur g!recur-fn body)]
|
||||
`(do
|
||||
(import [hy.contrib.loop [--trampoline--]])
|
||||
(with-decorator
|
||||
@ -85,7 +85,7 @@
|
||||
;; If recur is used in a non-tail-call position, None is returned, which
|
||||
;; causes chaos. Fixing this to detect if recur is in a tail-call position
|
||||
;; and erroring if not is a giant TODO.
|
||||
(let [[fnargs (map (fn [x] (first x)) bindings)]
|
||||
[initargs (map second bindings)]]
|
||||
(let [fnargs (map (fn [x] (first x)) bindings)
|
||||
initargs (map second bindings)]
|
||||
`(do (defnr ~g!recur-fn [~@fnargs] ~@body)
|
||||
(~g!recur-fn ~@initargs))))
|
||||
|
@ -3,11 +3,11 @@
|
||||
|
||||
(defmacro route-with-methods [name path methods params &rest code]
|
||||
"Same as route but with an extra methods array to specify HTTP methods"
|
||||
`(let [[deco (apply app.route [~path]
|
||||
{"methods" ~methods})]]
|
||||
(with-decorator deco
|
||||
(defn ~name ~params
|
||||
(do ~@code)))))
|
||||
`(let [deco (apply app.route [~path]
|
||||
{"methods" ~methods})]
|
||||
(with-decorator deco
|
||||
(defn ~name ~params
|
||||
(do ~@code)))))
|
||||
|
||||
;; Some macro examples
|
||||
(defmacro route [name path params &rest code]
|
||||
|
@ -42,22 +42,14 @@
|
||||
|
||||
(defmacro let [variables &rest body]
|
||||
"Execute `body` in the lexical context of `variables`"
|
||||
(setv macroed_variables [])
|
||||
(if (not (isinstance variables HyList))
|
||||
(macro-error variables "let lexical context must be a list"))
|
||||
(for* [variable variables]
|
||||
(if (isinstance variable HyList)
|
||||
(do
|
||||
(if (!= (len variable) 2)
|
||||
(macro-error variable "let variable assignments must contain two items"))
|
||||
(.append macroed-variables `(setv ~(get variable 0) ~(get variable 1))))
|
||||
(if (isinstance variable HySymbol)
|
||||
(.append macroed-variables `(setv ~variable None))
|
||||
(macro-error variable "let lexical context element must be a list or symbol"))))
|
||||
`((fn []
|
||||
~@macroed-variables
|
||||
~@body)))
|
||||
|
||||
(if (= (len variables) 0)
|
||||
`((fn []
|
||||
~@body))
|
||||
`((fn []
|
||||
(setv ~@variables)
|
||||
~@body))))
|
||||
|
||||
(defmacro if-python2 [python2-form python3-form]
|
||||
"If running on python2, execute python2-form, else, execute python3-form"
|
||||
|
@ -84,12 +84,13 @@
|
||||
(defn distinct [coll]
|
||||
"Return a generator from the original collection with duplicates
|
||||
removed"
|
||||
(let [[seen (set)] [citer (iter coll)]]
|
||||
(for* [val citer]
|
||||
(if (not_in val seen)
|
||||
(do
|
||||
(yield val)
|
||||
(.add seen val))))))
|
||||
(let [seen (set)
|
||||
citer (iter coll)]
|
||||
(for* [val citer]
|
||||
(if (not_in val seen)
|
||||
(do
|
||||
(yield val)
|
||||
(.add seen val))))))
|
||||
|
||||
(if-python2
|
||||
(def
|
||||
@ -158,7 +159,7 @@
|
||||
|
||||
(defn drop-last [n coll]
|
||||
"Return a sequence of all but the last n elements in coll."
|
||||
(let [[iters (tee coll)]]
|
||||
(let [iters (tee coll)]
|
||||
(map first (apply zip [(get iters 0)
|
||||
(drop n (get iters 1))]))))
|
||||
|
||||
@ -210,7 +211,7 @@
|
||||
(setv _gensym_lock (Lock))
|
||||
|
||||
(defn gensym [&optional [g "G"]]
|
||||
(let [[new_symbol None]]
|
||||
(let [new_symbol None]
|
||||
(global _gensym_counter)
|
||||
(global _gensym_lock)
|
||||
(.acquire _gensym_lock)
|
||||
@ -310,15 +311,16 @@
|
||||
from the latter (left-to-right) will be combined with the mapping in
|
||||
the result by calling (f val-in-result val-in-latter)."
|
||||
(if (any maps)
|
||||
(let [[merge-entry (fn [m e]
|
||||
(let [[k (get e 0)] [v (get e 1)]]
|
||||
(if (in k m)
|
||||
(assoc m k (f (get m k) v))
|
||||
(assoc m k v)))
|
||||
m)]
|
||||
[merge2 (fn [m1 m2]
|
||||
(reduce merge-entry (.items m2) (or m1 {})))]]
|
||||
(reduce merge2 maps))))
|
||||
(let [merge-entry (fn [m e]
|
||||
(let [k (get e 0)
|
||||
v (get e 1)]
|
||||
(if (in k m)
|
||||
(assoc m k (f (get m k) v))
|
||||
(assoc m k v)))
|
||||
m)
|
||||
merge2 (fn [m1 m2]
|
||||
(reduce merge-entry (.items m2) (or m1 {})))]
|
||||
(reduce merge2 maps))))
|
||||
|
||||
(defn neg? [n]
|
||||
"Return true if n is < 0"
|
||||
@ -402,12 +404,13 @@
|
||||
"Return every nth member of coll
|
||||
raises ValueError for (not (pos? n))"
|
||||
(if (pos? n)
|
||||
(let [[citer (iter coll)] [skip (dec n)]]
|
||||
(for* [val citer]
|
||||
(yield val)
|
||||
(for* [_ (range skip)]
|
||||
(next citer))))
|
||||
(raise (ValueError "n must be positive"))))
|
||||
(let [citer (iter coll)
|
||||
skip (dec n)]
|
||||
(for* [val citer]
|
||||
(yield val)
|
||||
(for* [_ (range skip)]
|
||||
(next citer))))
|
||||
(raise (ValueError "n must be positive"))))
|
||||
|
||||
(defn zero? [n]
|
||||
"Return true if n is 0"
|
||||
|
@ -33,21 +33,21 @@
|
||||
|
||||
(defmacro with [args &rest body]
|
||||
"shorthand for nested with* loops:
|
||||
(with [[x foo] [y bar]] baz) ->
|
||||
(with [x foo y bar] baz) ->
|
||||
(with* [x foo]
|
||||
(with* [y bar]
|
||||
baz))"
|
||||
|
||||
(if (not (empty? args))
|
||||
(let [[primary (.pop args 0)]]
|
||||
(if (isinstance primary HyList)
|
||||
;;; OK. if we have a list, we can go ahead and unpack that
|
||||
;;; as the argument to with.
|
||||
`(with* [~@primary] (with ~args ~@body))
|
||||
;;; OK, let's just give it away. This may not be something we
|
||||
;;; can do, but that's really the programmer's problem.
|
||||
`(with* [~primary] (with ~args ~@body))))
|
||||
`(do ~@body)))
|
||||
(do
|
||||
(if (>= (len args) 2)
|
||||
(do
|
||||
(setv p1 (.pop args 0)
|
||||
p2 (.pop args 0)
|
||||
primary [p1 p2])
|
||||
`(with* [~@primary] (with ~args ~@body)))
|
||||
`(with* [~@args] ~@body)))
|
||||
`(do ~@body)))
|
||||
|
||||
|
||||
(defmacro car [thing]
|
||||
@ -115,7 +115,7 @@
|
||||
[(empty? args) `(do ~@body ~@belse)]
|
||||
[(= (len args) 2) `(for* [~@args] (do ~@body) ~@belse)]
|
||||
[true
|
||||
(let [[alist (cut args 0 nil 2)]]
|
||||
(let [alist (cut args 0 nil 2)]
|
||||
`(for* [(, ~@alist) (genexpr (, ~@alist) [~@args])] (do ~@body) ~@belse))]))
|
||||
|
||||
|
||||
@ -138,7 +138,7 @@
|
||||
(if (isinstance expression HyExpression)
|
||||
`(~(first expression) ~f ~@(rest expression))
|
||||
`(~expression ~f)))
|
||||
`(let [[~f ~form]]
|
||||
`(let [~f ~form]
|
||||
~@(map build-form expressions)
|
||||
~f))
|
||||
|
||||
@ -180,14 +180,25 @@
|
||||
|
||||
|
||||
(defmacro with-gensyms [args &rest body]
|
||||
`(let ~(HyList (map (fn [x] `[~x (gensym '~x)]) args))
|
||||
~@body))
|
||||
(setv syms [])
|
||||
(for* [arg args]
|
||||
(.extend syms `[~arg (gensym '~arg)]))
|
||||
`(let ~syms
|
||||
~@body))
|
||||
|
||||
(defmacro defmacro/g! [name args &rest body]
|
||||
(let [[syms (list (distinct (filter (fn [x] (and (hasattr x "startswith") (.startswith x "g!"))) (flatten body))))]]
|
||||
(let [syms (list
|
||||
(distinct
|
||||
(filter (fn [x]
|
||||
(and (hasattr x "startswith")
|
||||
(.startswith x "g!")))
|
||||
(flatten body))))
|
||||
gensyms []]
|
||||
(for* [sym syms]
|
||||
(.extend gensyms `[~sym (gensym (cut '~sym 2))]))
|
||||
`(defmacro ~name [~@args]
|
||||
(let ~(HyList (map (fn [x] `[~x (gensym (cut '~x 2))]) syms))
|
||||
~@body))))
|
||||
(let ~gensyms
|
||||
~@body))))
|
||||
|
||||
|
||||
(if-python2
|
||||
@ -211,9 +222,9 @@
|
||||
|
||||
(defmacro defmain [args &rest body]
|
||||
"Write a function named \"main\" and do the if __main__ dance"
|
||||
(let [[retval (gensym)]
|
||||
[mainfn `(fn [~@args]
|
||||
~@body)]]
|
||||
(let [retval (gensym)
|
||||
mainfn `(fn [~@args]
|
||||
~@body)]
|
||||
`(when (= --name-- "__main__")
|
||||
(import sys)
|
||||
(setv ~retval (apply ~mainfn sys.argv))
|
||||
@ -222,6 +233,6 @@
|
||||
|
||||
|
||||
(defreader @ [expr]
|
||||
(let [[decorators (cut expr nil -1)]
|
||||
[fndef (get expr -1)]]
|
||||
(let [decorators (cut expr nil -1)
|
||||
fndef (get expr -1)]
|
||||
`(with-decorator ~@decorators ~fndef)))
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
(defn + [&rest args]
|
||||
"Shadow + operator for when we need to import / map it against something"
|
||||
(let [[count (len args)]]
|
||||
(let [count (len args)]
|
||||
(if (zero? count)
|
||||
(raise (TypeError "Need at least 1 argument to add/concatenate"))
|
||||
(if (= count 1)
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
(defn - [&rest args]
|
||||
"Shadow - operator for when we need to import / map it against something"
|
||||
(let [[count (len args)]]
|
||||
(let [count (len args)]
|
||||
(if (= count 0)
|
||||
(raise (TypeError "Need at least 1 argument to subtract"))
|
||||
(if (= count 1)
|
||||
@ -53,7 +53,7 @@
|
||||
|
||||
(defn / [&rest args]
|
||||
"Shadow / operator for when we need to import / map it against something"
|
||||
(let [[count (len args)]]
|
||||
(let [count (len args)]
|
||||
(if (= count 0)
|
||||
(raise (TypeError "Need at least 1 argument to divide"))
|
||||
(if (= count 1)
|
||||
|
@ -8,22 +8,22 @@
|
||||
" -- Alexander Artemenko <svetlyak.40wt@gmail.com> Thu, 30 Sep 2014 13:06:09 +0400")
|
||||
|
||||
(defn read-lines-from-file [filename]
|
||||
(let [[f (codecs.open filename "r" "utf-8")]]
|
||||
(fn [] (let [[line (.readline f) ]]
|
||||
line))))
|
||||
(let [f (codecs.open filename "r" "utf-8")]
|
||||
(fn [] (let [line (.readline f) ]
|
||||
line))))
|
||||
|
||||
|
||||
(defn get-version-number [line]
|
||||
(let [[match (re.search r"Changes from.*(\d+\.\d+\.\d+)$" line)]]
|
||||
(if match
|
||||
(let [[version (.group match (int 1))]
|
||||
[numbered (list (map int (.split version "."))) ]
|
||||
[explicit-mapping {"0.9.12" "0.10.0"
|
||||
"0.8.2" "0.9.0"}]]
|
||||
(assoc numbered 2 (+ (get numbered 2) 1))
|
||||
(.get explicit-mapping
|
||||
version
|
||||
(.join "." (map str numbered)))))))
|
||||
(let [match (re.search r"Changes from.*(\d+\.\d+\.\d+)$" line)]
|
||||
(if match
|
||||
(let [version (.group match (int 1))
|
||||
numbered (list (map int (.split version ".")))
|
||||
explicit-mapping {"0.9.12" "0.10.0"
|
||||
"0.8.2" "0.9.0"}]
|
||||
(assoc numbered 2 (+ (get numbered 2) 1))
|
||||
(.get explicit-mapping
|
||||
version
|
||||
(.join "." (map str numbered)))))))
|
||||
|
||||
|
||||
(defn read-version-content [reader]
|
||||
@ -36,14 +36,14 @@
|
||||
|
||||
|
||||
(defn read-versions-from-file [filename]
|
||||
(let [[reader (read-lines-from-file filename)]]
|
||||
(read-versions-rec (reader)
|
||||
reader)))
|
||||
(let [reader (read-lines-from-file filename)]
|
||||
(read-versions-rec (reader)
|
||||
reader)))
|
||||
|
||||
(defn read-versions-rec [line reader]
|
||||
(if line
|
||||
(let [[version (get-version-number line)]
|
||||
[[content next-line] (read-version-content reader)]]
|
||||
(let [version (get-version-number line)
|
||||
[content next-line] (read-version-content reader)]
|
||||
|
||||
(+ [{"from" version
|
||||
"content" content}]
|
||||
@ -61,6 +61,6 @@
|
||||
|
||||
|
||||
(defmain [&rest args]
|
||||
(let ((versions (read-versions-from-file "NEWS")))
|
||||
(let [versions (read-versions-from-file "NEWS")]
|
||||
(for [version versions]
|
||||
(print (.encode (format-deb-version version) "utf-8")))))
|
||||
(print (.encode (format-deb-version version) "utf-8")))))
|
||||
|
@ -33,5 +33,5 @@
|
||||
(setv filename (os.path.abspath (os.path.join os.path.pardir
|
||||
"docs" "coreteam.rst")))
|
||||
|
||||
(with [[fobj (open filename "w+")]]
|
||||
(with [fobj (open filename "w+")]
|
||||
(fobj.write (+ (.join "\n" result) "\n")))
|
||||
|
@ -321,20 +321,18 @@ def test_ast_invalid_for():
|
||||
|
||||
def test_ast_valid_let():
|
||||
"Make sure AST can compile valid let"
|
||||
can_compile("(let [])")
|
||||
can_compile("(let [a b])")
|
||||
can_compile("(let [[a 1]])")
|
||||
can_compile("(let [[a 1] b])")
|
||||
can_compile("(let [a 1])")
|
||||
can_compile("(let [a 1 b nil])")
|
||||
|
||||
|
||||
def test_ast_invalid_let():
|
||||
"Make sure AST can't compile invalid let"
|
||||
cant_compile("(let 1)")
|
||||
cant_compile("(let [1])")
|
||||
cant_compile("(let [[a 1 2]])")
|
||||
cant_compile("(let [[]])")
|
||||
cant_compile("(let [[a]])")
|
||||
cant_compile("(let [[1]])")
|
||||
cant_compile("(let [a 1 2])")
|
||||
cant_compile("(let [a])")
|
||||
cant_compile("(let [1])")
|
||||
|
||||
|
||||
def test_ast_expression_basics():
|
||||
|
@ -55,7 +55,7 @@
|
||||
[3 6 9])
|
||||
(assert-equal (list (ap-map (* it 3) []))
|
||||
[])
|
||||
(assert-equal (let [[v 1] [f 1]] (list (ap-map (it v f) [(fn [a b] (+ a b))])))
|
||||
(assert-equal (let [v 1 f 1] (list (ap-map (it v f) [(fn [a b] (+ a b))])))
|
||||
[2]))
|
||||
|
||||
(defn test-ap-map-when []
|
||||
@ -79,9 +79,9 @@
|
||||
|
||||
(defn test-ap-dotimes []
|
||||
"NATIVE: testing anaphoric dotimes"
|
||||
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n 3)) n)
|
||||
(assert-equal (let [n []] (ap-dotimes 3 (.append n 3)) n)
|
||||
[3 3 3])
|
||||
(assert-equal (let [[n []]] (ap-dotimes 3 (.append n it)) n)
|
||||
(assert-equal (let [n []] (ap-dotimes 3 (.append n it)) n)
|
||||
[0 1 2]))
|
||||
|
||||
(defn test-ap-first []
|
||||
|
@ -9,44 +9,44 @@
|
||||
f)))
|
||||
|
||||
(defn test_route []
|
||||
(let [[app (FakeMeth)]]
|
||||
(let [app (FakeMeth)]
|
||||
(route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [[(, rule-fun rule-opt) (get app-rules "/")]]
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "GET" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_post_route []
|
||||
(let [[app (FakeMeth)]]
|
||||
(let [app (FakeMeth)]
|
||||
(post-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [[(, rule-fun rule-opt) (get app-rules "/")]]
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "POST" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_put_route []
|
||||
(let [[app (FakeMeth)]]
|
||||
(let [app (FakeMeth)]
|
||||
(put-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [[(, rule-fun rule-opt) (get app-rules "/")]]
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "PUT" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
(assert (= "Hy world!" (rule-fun))))))
|
||||
|
||||
(defn test_delete_route []
|
||||
(let [[app (FakeMeth)]]
|
||||
(let [app (FakeMeth)]
|
||||
(delete-route get-index "/" [] (str "Hy world!"))
|
||||
(setv app-rules (getattr app "rules"))
|
||||
(assert (in "/" app-rules))
|
||||
(let [[(, rule-fun rule-opt) (get app-rules "/")]]
|
||||
(let [(, rule-fun rule-opt) (get app-rules "/")]
|
||||
(assert (not (empty? rule-opt)))
|
||||
(assert (in "DELETE" (get rule-opt "methods")))
|
||||
(assert (= (getattr rule-fun "__name__") "get_index"))
|
||||
|
@ -15,21 +15,21 @@
|
||||
walk-form)))
|
||||
|
||||
(defn test-walk []
|
||||
(let [[acc '()]]
|
||||
(let [acc '()]
|
||||
(assert (= (walk (partial collector acc) identity walk-form)
|
||||
[nil nil]))
|
||||
(assert (= acc walk-form)))
|
||||
(let [[acc []]]
|
||||
(let [acc []]
|
||||
(assert (= (walk identity (partial collector acc) walk-form)
|
||||
nil))
|
||||
(assert (= acc [walk-form]))))
|
||||
|
||||
(defn test-walk-iterators []
|
||||
(let [[acc []]]
|
||||
(let [acc []]
|
||||
(assert (= (walk (fn [x] (* 2 x)) (fn [x] x)
|
||||
(drop 1 [1 [2 [3 [4]]]]))
|
||||
[[2 [3 [4]] 2 [3 [4]]]]))))
|
||||
|
||||
(defn test-macroexpand-all []
|
||||
(assert (= (macroexpand-all '(with [a b c] (for [d c] foo)))
|
||||
'(with* [a] (with* [b] (with* [c] (do (for* [d c] (do foo)))))))))
|
||||
(assert (= (macroexpand-all '(with [a 1 b 2 c 3] (for [d c] foo)))
|
||||
'(with* [a 1] (with* [b 2] (with* [c 3] (do (for* [d c] (do foo)))))))))
|
||||
|
@ -592,7 +592,7 @@
|
||||
(setv res (list (take-nth 3 [1 2 3 None 5 6])))
|
||||
(assert-equal res [1 None])
|
||||
;; using 0 should raise ValueError
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(setv res (list (take-nth 0 [1 2 3 4 5 6 7])))
|
||||
(except [ValueError] (setv passed true)))
|
||||
|
@ -36,7 +36,7 @@
|
||||
(+ self.x value))])
|
||||
(assert (= B.x 42))
|
||||
(assert (= (.y (B) 5) 47))
|
||||
(let [[b (B)]]
|
||||
(let [b (B)]
|
||||
(setv B.x 0)
|
||||
(assert (= (.y b 1) 1))))
|
||||
|
||||
|
@ -355,7 +355,7 @@
|
||||
(try (do) (except [IOError]) (except))
|
||||
|
||||
;; Test correct (raise)
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(try
|
||||
(raise IndexError)
|
||||
@ -365,7 +365,7 @@
|
||||
(assert passed))
|
||||
|
||||
;; Test incorrect (raise)
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(raise)
|
||||
;; Python 2 raises TypeError
|
||||
@ -374,16 +374,15 @@
|
||||
(setv passed true)))
|
||||
(assert passed))
|
||||
|
||||
|
||||
;; Test (finally)
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(do)
|
||||
(finally (setv passed true)))
|
||||
(assert passed))
|
||||
|
||||
;; Test (finally) + (raise)
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(raise Exception)
|
||||
(except)
|
||||
@ -392,8 +391,8 @@
|
||||
|
||||
|
||||
;; Test (finally) + (raise) + (else)
|
||||
(let [[passed false]
|
||||
[not-elsed true]]
|
||||
(let [passed false
|
||||
not-elsed true]
|
||||
(try
|
||||
(raise Exception)
|
||||
(except)
|
||||
@ -460,13 +459,13 @@
|
||||
(setv foobar42ofthebaz 42)
|
||||
(assert (= foobar42ofthebaz 42))))
|
||||
|
||||
(let [[passed false]]
|
||||
(let [passed false]
|
||||
(try
|
||||
(try (do) (except) (else (bla)))
|
||||
(except [NameError] (setv passed true)))
|
||||
(assert passed))
|
||||
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(try
|
||||
(raise IOError)
|
||||
(except [IOError]
|
||||
@ -474,7 +473,7 @@
|
||||
(else (setv x 44)))
|
||||
(assert (= x 45)))
|
||||
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(try
|
||||
(raise KeyError)
|
||||
(except []
|
||||
@ -482,7 +481,7 @@
|
||||
(else (setv x 44)))
|
||||
(assert (= x 45)))
|
||||
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(try
|
||||
(try
|
||||
(raise KeyError)
|
||||
@ -561,7 +560,7 @@
|
||||
(defn test-yield-in-try []
|
||||
"NATIVE: test yield in try"
|
||||
(defn gen []
|
||||
(let [[x 1]]
|
||||
(let [x 1]
|
||||
(try (yield x)
|
||||
(finally (print x)))))
|
||||
(setv output (list (gen)))
|
||||
@ -608,14 +607,14 @@
|
||||
|
||||
(defn test-context []
|
||||
"NATIVE: test with"
|
||||
(with [[fd (open "README.md" "r")]] (assert fd))
|
||||
(with [[(open "README.md" "r")]] (do)))
|
||||
(with [fd (open "README.md" "r")] (assert fd))
|
||||
(with [(open "README.md" "r")] (do)))
|
||||
|
||||
|
||||
(defn test-with-return []
|
||||
"NATIVE: test that with returns stuff"
|
||||
(defn read-file [filename]
|
||||
(with [[fd (open filename "r")]] (.read fd)))
|
||||
(with [fd (open filename "r")] (.read fd)))
|
||||
(assert (!= 0 (len (read-file "README.md")))))
|
||||
|
||||
|
||||
@ -631,13 +630,13 @@
|
||||
|
||||
(defn test-for-else []
|
||||
"NATIVE: test for else"
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(for* [a [1 2]]
|
||||
(setv x (+ x a))
|
||||
(else (setv x (+ x 50))))
|
||||
(assert (= x 53)))
|
||||
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(for* [a [1 2]]
|
||||
(setv x (+ x a))
|
||||
(else))
|
||||
@ -751,28 +750,28 @@
|
||||
(defn test-let []
|
||||
"NATIVE: test let works rightish"
|
||||
;; TODO: test sad paths for let
|
||||
(assert (= (let [[x 1] [y 2] [z 3]] (+ x y z)) 6))
|
||||
(assert (= (let [[x 1] a [y 2] b] (if a 1 2)) 2))
|
||||
(assert (= (let [x] x) nil))
|
||||
(assert (= (let [[x "x not bound"]] (setv x "x bound by setv") x)
|
||||
(assert (= (let [x 1 y 2 z 3] (+ x y z)) 6))
|
||||
(assert (= (let [x 1 a nil y 2 b nil] (if a 1 2)) 2))
|
||||
(assert (= (let [x nil] x) nil))
|
||||
(assert (= (let [x "x not bound"] (setv x "x bound by setv") x)
|
||||
"x bound by setv"))
|
||||
(assert (= (let [[x "let nests scope correctly"]]
|
||||
(let [y] x))
|
||||
(assert (= (let [x "let nests scope correctly"]
|
||||
(let [y nil] x))
|
||||
"let nests scope correctly"))
|
||||
(assert (= (let [[x 999999]]
|
||||
(let [[x "x being rebound"]] x))
|
||||
(assert (= (let [x 999999]
|
||||
(let [x "x being rebound"] x))
|
||||
"x being rebound"))
|
||||
(assert (= (let [[x "x not being rebound"]]
|
||||
(let [[x 2]] nil)
|
||||
(assert (= (let [x "x not being rebound"]
|
||||
(let [x 2] nil)
|
||||
x)
|
||||
"x not being rebound"))
|
||||
(assert (= (let [[x (set [3 2 1 3 2])] [y x] [z y]] z) (set [1 2 3])))
|
||||
(assert (= (let [x (set [3 2 1 3 2]) y x z y] z) (set [1 2 3])))
|
||||
(import math)
|
||||
(let [[cos math.cos]
|
||||
[foo-cos (fn [x] (cos x))]]
|
||||
(let [cos math.cos
|
||||
foo-cos (fn [x] (cos x))]
|
||||
(assert (= (cos math.pi) -1.0))
|
||||
(assert (= (foo-cos (- math.pi)) -1.0))
|
||||
(let [[cos (fn [_] "cos has been locally rebound")]]
|
||||
(let [cos (fn [_] "cos has been locally rebound")]
|
||||
(assert (= (cos cos) "cos has been locally rebound"))
|
||||
(assert (= (-> math.pi (/ 3) foo-cos (round 2)) 0.5)))
|
||||
(setv cos (fn [_] "cos has been rebound by setv"))
|
||||
@ -792,9 +791,9 @@
|
||||
(defn test-let-scope []
|
||||
"NATIVE: test let works rightish"
|
||||
(setv y 123)
|
||||
(assert (= (let [[x 1]
|
||||
[y 2]
|
||||
[z 3]]
|
||||
(assert (= (let [x 1
|
||||
y 2
|
||||
z 3]
|
||||
(+ x y z))
|
||||
6))
|
||||
(try
|
||||
@ -805,31 +804,31 @@
|
||||
|
||||
(defn test-symbol-utf-8 []
|
||||
"NATIVE: test symbol encoded"
|
||||
(let [[♥ "love"]
|
||||
[⚘ "flower"]]
|
||||
(let [♥ "love"
|
||||
⚘ "flower"]
|
||||
(assert (= (+ ⚘ ♥) "flowerlove"))))
|
||||
|
||||
|
||||
(defn test-symbol-dash []
|
||||
"NATIVE: test symbol encoded"
|
||||
(let [[♥-♥ "doublelove"]
|
||||
[-_- "what?"]]
|
||||
(let [♥-♥ "doublelove"
|
||||
-_- "what?"]
|
||||
(assert (= ♥-♥ "doublelove"))
|
||||
(assert (= -_- "what?"))))
|
||||
|
||||
|
||||
(defn test-symbol-question-mark []
|
||||
"NATIVE: test foo? -> is_foo behavior"
|
||||
(let [[foo? "nachos"]]
|
||||
(let [foo? "nachos"]
|
||||
(assert (= is_foo "nachos"))))
|
||||
|
||||
|
||||
(defn test-and []
|
||||
"NATIVE: test the and function"
|
||||
(let [[and123 (and 1 2 3)]
|
||||
[and-false (and 1 False 3)]
|
||||
[and-true (and)]
|
||||
[and-single (and 1)]]
|
||||
(let [and123 (and 1 2 3)
|
||||
and-false (and 1 False 3)
|
||||
and-true (and)
|
||||
and-single (and 1)]
|
||||
(assert (= and123 3))
|
||||
(assert (= and-false False))
|
||||
(assert (= and-true True))
|
||||
@ -842,11 +841,11 @@
|
||||
|
||||
(defn test-or []
|
||||
"NATIVE: test the or function"
|
||||
(let [[or-all-true (or 1 2 3 True "string")]
|
||||
[or-some-true (or False "hello")]
|
||||
[or-none-true (or False False)]
|
||||
[or-false (or)]
|
||||
[or-single (or 1)]]
|
||||
(let [or-all-true (or 1 2 3 True "string")
|
||||
or-some-true (or False "hello")
|
||||
or-none-true (or False False)
|
||||
or-false (or)
|
||||
or-single (or 1)]
|
||||
(assert (= or-all-true 1))
|
||||
(assert (= or-some-true "hello"))
|
||||
(assert (= or-none-true False))
|
||||
@ -861,12 +860,12 @@
|
||||
(defn test-if-return-branching []
|
||||
"NATIVE: test the if return branching"
|
||||
; thanks, algernon
|
||||
(assert (= 1 (let [[x 1]
|
||||
[y 2]]
|
||||
(assert (= 1 (let [x 1
|
||||
y 2]
|
||||
(if true
|
||||
2)
|
||||
1)))
|
||||
(assert (= 1 (let [[x 1] [y 2]]
|
||||
(assert (= 1 (let [x 1 y 2]
|
||||
(do)
|
||||
(do)
|
||||
((fn [] 1))))))
|
||||
@ -915,9 +914,9 @@
|
||||
(defn test-eval-globals []
|
||||
"NATIVE: test eval with explicit global dict"
|
||||
(assert (= 'bar (eval (quote foo) {'foo 'bar})))
|
||||
(assert (= 1 (let [[d {}]] (eval '(setv x 1) d) (eval (quote x) d))))
|
||||
(let [[d1 {}]
|
||||
[d2 {}]]
|
||||
(assert (= 1 (let [d {}] (eval '(setv x 1) d) (eval (quote x) d))))
|
||||
(let [d1 {}
|
||||
d2 {}]
|
||||
(eval '(setv x 1) d1)
|
||||
(try
|
||||
(do
|
||||
@ -998,7 +997,7 @@
|
||||
|
||||
(defn test-if-let-mixing []
|
||||
"NATIVE: test that we can now mix if and let"
|
||||
(assert (= 0 (if true (let [[x 0]] x) 42))))
|
||||
(assert (= 0 (if true (let [x 0] x) 42))))
|
||||
|
||||
(defn test-if-in-if []
|
||||
"NATIVE: test that we can use if in if"
|
||||
|
@ -69,73 +69,73 @@
|
||||
|
||||
(defn test-augassign-add []
|
||||
"NATIVE: test augassign add"
|
||||
(let [[x 1]]
|
||||
(let [x 1]
|
||||
(+= x 41)
|
||||
(assert (= x 42))))
|
||||
|
||||
(defn test-augassign-sub []
|
||||
"NATIVE: test augassign sub"
|
||||
(let [[x 1]]
|
||||
(let [x 1]
|
||||
(-= x 41)
|
||||
(assert (= x -40))))
|
||||
|
||||
(defn test-augassign-mult []
|
||||
"NATIVE: test augassign mult"
|
||||
(let [[x 1]]
|
||||
(let [x 1]
|
||||
(*= x 41)
|
||||
(assert (= x 41))))
|
||||
|
||||
(defn test-augassign-div []
|
||||
"NATIVE: test augassign div"
|
||||
(let [[x 42]]
|
||||
(let [x 42]
|
||||
(/= x 2)
|
||||
(assert (= x 21))))
|
||||
|
||||
(defn test-augassign-floordiv []
|
||||
"NATIVE: test augassign floordiv"
|
||||
(let [[x 42]]
|
||||
(let [x 42]
|
||||
(//= x 2)
|
||||
(assert (= x 21))))
|
||||
|
||||
(defn test-augassign-mod []
|
||||
"NATIVE: test augassign mod"
|
||||
(let [[x 42]]
|
||||
(let [x 42]
|
||||
(%= x 2)
|
||||
(assert (= x 0))))
|
||||
|
||||
(defn test-augassign-pow []
|
||||
"NATIVE: test augassign pow"
|
||||
(let [[x 2]]
|
||||
(let [x 2]
|
||||
(**= x 3)
|
||||
(assert (= x 8))))
|
||||
|
||||
(defn test-augassign-lshift []
|
||||
"NATIVE: test augassign lshift"
|
||||
(let [[x 2]]
|
||||
(let [x 2]
|
||||
(<<= x 2)
|
||||
(assert (= x 8))))
|
||||
|
||||
(defn test-augassign-rshift []
|
||||
"NATIVE: test augassign rshift"
|
||||
(let [[x 8]]
|
||||
(let [x 8]
|
||||
(>>= x 1)
|
||||
(assert (= x 4))))
|
||||
|
||||
(defn test-augassign-bitand []
|
||||
"NATIVE: test augassign bitand"
|
||||
(let [[x 8]]
|
||||
(let [x 8]
|
||||
(&= x 1)
|
||||
(assert (= x 0))))
|
||||
|
||||
(defn test-augassign-bitor []
|
||||
"NATIVE: test augassign bitand"
|
||||
(let [[x 0]]
|
||||
(let [x 0]
|
||||
(|= x 2)
|
||||
(assert (= x 2))))
|
||||
|
||||
(defn test-augassign-bitxor []
|
||||
"NATIVE: test augassign bitand"
|
||||
(let [[x 1]]
|
||||
(let [x 1]
|
||||
(^= x 1)
|
||||
(assert (= x 0))))
|
||||
|
||||
@ -147,13 +147,13 @@
|
||||
(defclass HyTestMatrix [list]
|
||||
[--matmul--
|
||||
(fn [self other]
|
||||
(let [[n (len self)]
|
||||
[m (len (. other [0]))]
|
||||
[result []]]
|
||||
(let [n (len self)
|
||||
m (len (. other [0]))
|
||||
result []]
|
||||
(for [i (range m)]
|
||||
(let [[result-row []]]
|
||||
(let [result-row []]
|
||||
(for [j (range n)]
|
||||
(let [[dot-product 0]]
|
||||
(let [dot-product 0]
|
||||
(for [k (range (len (. self [0])))]
|
||||
(+= dot-product (* (. self [i] [k])
|
||||
(. other [k] [j]))))
|
||||
@ -179,15 +179,15 @@
|
||||
(assert (= (@ first-test-matrix second-test-matrix)
|
||||
product-of-test-matrices))
|
||||
;; Python <= 3.4
|
||||
(let [[matmul-attempt (try (@ first-test-matrix second-test-matrix)
|
||||
(except [e [Exception]] e))]]
|
||||
(let [matmul-attempt (try (@ first-test-matrix second-test-matrix)
|
||||
(except [e [Exception]] e))]
|
||||
(assert (isinstance matmul-attempt NameError)))))
|
||||
|
||||
(defn test-augassign-matmul []
|
||||
"NATIVE: test augmented-assignment matrix multiplication"
|
||||
(let [[matrix first-test-matrix]
|
||||
[matmul-attempt (try (@= matrix second-test-matrix)
|
||||
(except [e [Exception]] e))]]
|
||||
(let [matrix first-test-matrix
|
||||
matmul-attempt (try (@= matrix second-test-matrix)
|
||||
(except [e [Exception]] e))]
|
||||
(if PY35
|
||||
(assert (= product-of-test-matrices matrix))
|
||||
(assert (isinstance matmul-attempt NameError)))))
|
||||
|
@ -107,8 +107,8 @@
|
||||
(import [astor.codegen [to_source]])
|
||||
(import [hy.importer [import_buffer_to_ast]])
|
||||
(setv macro1 "(defmacro nif [expr pos zero neg]
|
||||
(let [[g (gensym)]]
|
||||
`(let [[~g ~expr]]
|
||||
(let [g (gensym)]
|
||||
`(let [~g ~expr]
|
||||
(cond [(pos? ~g) ~pos]
|
||||
[(zero? ~g) ~zero]
|
||||
[(neg? ~g) ~neg]))))
|
||||
@ -133,7 +133,7 @@
|
||||
(import [hy.importer [import_buffer_to_ast]])
|
||||
(setv macro1 "(defmacro nif [expr pos zero neg]
|
||||
(with-gensyms [a]
|
||||
`(let [[~a ~expr]]
|
||||
`(let [~a ~expr]
|
||||
(cond [(pos? ~a) ~pos]
|
||||
[(zero? ~a) ~zero]
|
||||
[(neg? ~a) ~neg]))))
|
||||
@ -155,7 +155,7 @@
|
||||
(import [astor.codegen [to_source]])
|
||||
(import [hy.importer [import_buffer_to_ast]])
|
||||
(setv macro1 "(defmacro/g! nif [expr pos zero neg]
|
||||
`(let [[~g!res ~expr]]
|
||||
`(let [~g!res ~expr]
|
||||
(cond [(pos? ~g!res) ~pos]
|
||||
[(zero? ~g!res) ~zero]
|
||||
[(neg? ~g!res) ~neg])))
|
||||
|
@ -15,14 +15,14 @@
|
||||
(defn test-kwonly []
|
||||
"NATIVE: test keyword-only arguments"
|
||||
;; keyword-only with default works
|
||||
(let [[kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]]
|
||||
(let [kwonly-foo-default-false (fn [&kwonly [foo false]] foo)]
|
||||
(assert (= (apply kwonly-foo-default-false) false))
|
||||
(assert (= (apply kwonly-foo-default-false [] {"foo" true}) true)))
|
||||
;; keyword-only without default ...
|
||||
(let [[kwonly-foo-no-default (fn [&kwonly foo] foo)]
|
||||
[attempt-to-omit-default (try
|
||||
(kwonly-foo-no-default)
|
||||
(except [e [Exception]] e))]]
|
||||
(let [kwonly-foo-no-default (fn [&kwonly foo] foo)
|
||||
attempt-to-omit-default (try
|
||||
(kwonly-foo-no-default)
|
||||
(except [e [Exception]] e))]
|
||||
;; works
|
||||
(assert (= (apply kwonly-foo-no-default [] {"foo" "quux"}) "quux"))
|
||||
;; raises TypeError with appropriate message if not supplied
|
||||
@ -30,9 +30,9 @@
|
||||
(assert (in "missing 1 required keyword-only argument: 'foo'"
|
||||
(. attempt-to-omit-default args [0]))))
|
||||
;; keyword-only with other arg types works
|
||||
(let [[function-of-various-args
|
||||
(fn [a b &rest args &kwonly foo &kwargs kwargs]
|
||||
(, a b args foo kwargs))]]
|
||||
(let [function-of-various-args
|
||||
(fn [a b &rest args &kwonly foo &kwargs kwargs]
|
||||
(, a b args foo kwargs))]
|
||||
(assert (= (apply function-of-various-args
|
||||
[1 2 3 4] {"foo" 5 "bar" 6 "quux" 7})
|
||||
(, 1 2 (, 3 4) 5 {"bar" 6 "quux" 7})))))
|
||||
|
@ -1,6 +1,6 @@
|
||||
(defn test-shadow-addition []
|
||||
"NATIVE: test shadow addition"
|
||||
(let [[x +]]
|
||||
(let [x +]
|
||||
(assert (try
|
||||
(x)
|
||||
(except [TypeError] True)
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
(defn test-shadow-subtraction []
|
||||
"NATIVE: test shadow subtraction"
|
||||
(let [[x -]]
|
||||
(let [x -]
|
||||
(assert (try
|
||||
(x)
|
||||
(except [TypeError] True)
|
||||
@ -33,7 +33,7 @@
|
||||
|
||||
(defn test-shadow-multiplication []
|
||||
"NATIVE: test shadow multiplication"
|
||||
(let [[x *]]
|
||||
(let [x *]
|
||||
(assert (= (x) 1))
|
||||
(assert (= (x 3) 3))
|
||||
(assert (= (x 3 3) 9))))
|
||||
@ -41,7 +41,7 @@
|
||||
|
||||
(defn test-shadow-division []
|
||||
"NATIVE: test shadow division"
|
||||
(let [[x /]]
|
||||
(let [x /]
|
||||
(assert (try
|
||||
(x)
|
||||
(except [TypeError] True)
|
||||
@ -71,12 +71,12 @@
|
||||
[1 1]
|
||||
[2 2]]]
|
||||
(assert (= (apply x args) (not (apply y args))))))
|
||||
(let [[s-lt <]
|
||||
[s-gt >]
|
||||
[s-le <=]
|
||||
[s-ge >=]
|
||||
[s-eq =]
|
||||
[s-ne !=]]
|
||||
(let [s-lt <
|
||||
s-gt >
|
||||
s-le <=
|
||||
s-ge >=
|
||||
s-eq =
|
||||
s-ne !=]
|
||||
(assert (apply s-lt [1 2 3]))
|
||||
(assert (not (apply s-lt [3 2 1])))
|
||||
(assert (apply s-gt [3 2 1]))
|
||||
|
@ -11,31 +11,31 @@
|
||||
|
||||
(defn test-single-with []
|
||||
"NATIVE: test a single with"
|
||||
(with [[t (WithTest 1)]]
|
||||
(assert (= t 1))))
|
||||
(with [t (WithTest 1)]
|
||||
(assert (= t 1))))
|
||||
|
||||
(defn test-two-with []
|
||||
"NATIVE: test two withs"
|
||||
(with [[t1 (WithTest 1)]
|
||||
[t2 (WithTest 2)]]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))))
|
||||
(with [t1 (WithTest 1)
|
||||
t2 (WithTest 2)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))))
|
||||
|
||||
(defn test-thrice-with []
|
||||
"NATIVE: test three withs"
|
||||
(with [[t1 (WithTest 1)]
|
||||
[t2 (WithTest 2)]
|
||||
[t3 (WithTest 3)]]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))
|
||||
(with [t1 (WithTest 1)
|
||||
t2 (WithTest 2)
|
||||
t3 (WithTest 3)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))
|
||||
|
||||
(defn test-quince-with []
|
||||
"NATIVE: test four withs, one with no args"
|
||||
(with [[t1 (WithTest 1)]
|
||||
[t2 (WithTest 2)]
|
||||
[t3 (WithTest 3)]
|
||||
[(WithTest 4)]]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))
|
||||
(defn test-quince-with []
|
||||
"NATIVE: test four withs, one with no args"
|
||||
(with [t1 (WithTest 1)
|
||||
t2 (WithTest 2)
|
||||
t3 (WithTest 3)
|
||||
_ (WithTest 4)]
|
||||
(assert (= t1 1))
|
||||
(assert (= t2 2))
|
||||
(assert (= t3 3))))
|
||||
|
Loading…
Reference in New Issue
Block a user