Merge branch 'master' into pr/439
This commit is contained in:
commit
1b435a9a2a
2
AUTHORS
2
AUTHORS
@ -35,3 +35,5 @@
|
|||||||
* Thom Neale <twneale@gmail.com>
|
* Thom Neale <twneale@gmail.com>
|
||||||
* Tuukka Turto <tuukka.turto@oktaeder.net>
|
* Tuukka Turto <tuukka.turto@oktaeder.net>
|
||||||
* Vasudev Kamath <kamathvasudev@gmail.com>
|
* Vasudev Kamath <kamathvasudev@gmail.com>
|
||||||
|
* Yuval Langer <yuval.langer@gmail.com>
|
||||||
|
* Fatih Kadir Akın <fka@fatihak.in>
|
||||||
|
BIN
docs/_static/cuddles-transparent-small.png
vendored
Normal file
BIN
docs/_static/cuddles-transparent-small.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
BIN
docs/_static/cuddles-transparent.png
vendored
Normal file
BIN
docs/_static/cuddles-transparent.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
@ -12,3 +12,4 @@
|
|||||||
* `Nicolas Dandrimont <https://github.com/olasd>`_
|
* `Nicolas Dandrimont <https://github.com/olasd>`_
|
||||||
* `Bob Tolbert <https://github.com/rwtolbert>`_
|
* `Bob Tolbert <https://github.com/rwtolbert>`_
|
||||||
* `Berker Peksag <https://github.com/berkerpeksag>`_
|
* `Berker Peksag <https://github.com/berkerpeksag>`_
|
||||||
|
* `Clinton N. Dreisbach <https://github.com/cndreisbach>`_
|
||||||
|
@ -97,7 +97,7 @@ core team. Additional review is clearly welcome, but we need a minimum of
|
|||||||
2 signoffs for any change.
|
2 signoffs for any change.
|
||||||
|
|
||||||
If a core member is sending in a PR, please find 2 core members that don't
|
If a core member is sending in a PR, please find 2 core members that don't
|
||||||
include them PR submitter. The idea here is that one can work with the PR
|
include the PR submitter. The idea here is that one can work with the PR
|
||||||
author, and a second acks the entire change set.
|
author, and a second acks the entire change set.
|
||||||
|
|
||||||
If the change is adding documentation, feel free to just merge after one
|
If the change is adding documentation, feel free to just merge after one
|
||||||
|
@ -36,7 +36,7 @@ languages.
|
|||||||
Builtins
|
Builtins
|
||||||
========
|
========
|
||||||
|
|
||||||
Hy features a number special forms that are used to help generate
|
Hy features a number of special forms that are used to help generate
|
||||||
correct Python AST. The following are "special" forms, which may have
|
correct Python AST. The following are "special" forms, which may have
|
||||||
behavior that's slightly unexpected in some situations.
|
behavior that's slightly unexpected in some situations.
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ The following code demonstrates this:
|
|||||||
---
|
---
|
||||||
|
|
||||||
`->>` or `threading tail macro` is similar to `threading macro` but instead of
|
`->>` or `threading tail macro` is similar to `threading macro` but instead of
|
||||||
inserting each expression into the next expression’s first argument place it
|
inserting each expression into the next expression’s first argument place, it
|
||||||
appends it as the last argument. The following code demonstrates this:
|
appends it as the last argument. The following code demonstrates this:
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
@ -110,6 +110,7 @@ Usage: `(apply fn-name [args] [kwargs])`
|
|||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
(defn thunk []
|
(defn thunk []
|
||||||
"hy there")
|
"hy there")
|
||||||
|
|
||||||
@ -282,7 +283,7 @@ do / progn
|
|||||||
the `do` and `progn` forms are used to evaluate each of their arguments and
|
the `do` and `progn` forms are used to evaluate each of their arguments and
|
||||||
return the last one. Return values from every other than the last argument are
|
return the last one. Return values from every other than the last argument are
|
||||||
discarded. It can be used in `lambda` or `list-comp` to perform more complex
|
discarded. It can be used in `lambda` or `list-comp` to perform more complex
|
||||||
logic as show by one of the examples.
|
logic as shown by one of the examples.
|
||||||
|
|
||||||
Some example usage:
|
Some example usage:
|
||||||
|
|
||||||
@ -429,7 +430,7 @@ defmacro
|
|||||||
`defmacro` is used to define macros. The general format is
|
`defmacro` is used to define macros. The general format is
|
||||||
`(defmacro [parameters] expr)`.
|
`(defmacro [parameters] expr)`.
|
||||||
|
|
||||||
Following example defines a macro that can be used to swap order of elements in
|
The following example defines a macro that can be used to swap order of elements in
|
||||||
code, allowing the user to write code in infix notation, where operator is in
|
code, allowing the user to write code in infix notation, where operator is in
|
||||||
between the operands.
|
between the operands.
|
||||||
|
|
||||||
@ -1166,7 +1167,7 @@ yield
|
|||||||
The generator is iterable and therefore can be used in loops, list
|
The generator is iterable and therefore can be used in loops, list
|
||||||
comprehensions and other similar constructs.
|
comprehensions and other similar constructs.
|
||||||
|
|
||||||
Especially the second example shows how generators can be used to generate
|
The function random-numbers shows how generators can be used to generate
|
||||||
infinite series without consuming infinite amount of memory.
|
infinite series without consuming infinite amount of memory.
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
@ -9,7 +9,7 @@ Core Functions
|
|||||||
.. _is-coll-fn:
|
.. _is-coll-fn:
|
||||||
|
|
||||||
coll?
|
coll?
|
||||||
----
|
-----
|
||||||
|
|
||||||
.. versionadded:: 0.9.13
|
.. versionadded:: 0.9.13
|
||||||
|
|
||||||
|
@ -2,20 +2,20 @@
|
|||||||
Quickstart
|
Quickstart
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. image:: _static/cuddles.png
|
.. image:: _static/cuddles-transparent-small.png
|
||||||
:alt: Karen Rustard's Cuddles
|
:alt: Karen Rustard's Cuddles
|
||||||
|
|
||||||
(thanks to Karen Rustad for Cuddles!)
|
(Thanks to Karen Rustad for Cuddles!)
|
||||||
|
|
||||||
|
|
||||||
HOW TO GET HY REAL FAST:
|
**HOW TO GET HY REAL FAST**:
|
||||||
|
|
||||||
1. create a `Python virtual environment
|
1. Create a `Virtual Python Environment
|
||||||
<https://pypi.python.org/pypi/virtualenv>`_
|
<https://pypi.python.org/pypi/virtualenv>`_
|
||||||
2. activate your Python virtual environment
|
2. Activate your Virtual Python Environment
|
||||||
3. ``pip install hy``
|
3. Install `hy from PyPI <https://pypi.python.org/pypi/hy>`_ with ``pip install hy``
|
||||||
4. start a REPL with ``hy``
|
4. Start a REPL with ``hy``
|
||||||
5. type stuff in the REPL::
|
5. Type stuff in the REPL::
|
||||||
|
|
||||||
=> (print "Hy!")
|
=> (print "Hy!")
|
||||||
Hy!
|
Hy!
|
||||||
@ -25,20 +25,19 @@ HOW TO GET HY REAL FAST:
|
|||||||
|
|
||||||
etc
|
etc
|
||||||
|
|
||||||
6. hit CTRL-D when you're done
|
6. Hit CTRL-D when you're done
|
||||||
|
|
||||||
OMG! That's amazing! I want to write a hy program.
|
OMG! That's amazing! I want to write a hy program.
|
||||||
|
|
||||||
7. open up an elite programming editor
|
7. Open up an elite programming editor and type::
|
||||||
8. type::
|
|
||||||
|
|
||||||
(print "i was going to code in python syntax, but then i got hy")
|
(print "I was going to code in python syntax, but then I got hy.")
|
||||||
|
|
||||||
9. save as ``test_program_of_awesome.hy``
|
8. Save as ``awesome.hy``
|
||||||
10. run::
|
9. And run your first Hy program::
|
||||||
|
|
||||||
hy test_program_of_awesome.hy
|
hy awesome.hy
|
||||||
|
|
||||||
11. take a deep breath so as to not hyperventilate
|
10. Take a deep breath so as to not hyperventilate
|
||||||
12. smile villainously and sneak off to your hydeaway and do
|
11. Smile villainously and sneak off to your hydeaway and do
|
||||||
unspeakable things
|
unspeakable things
|
||||||
|
@ -406,7 +406,7 @@ The same thing in Hy::
|
|||||||
...
|
...
|
||||||
[3, 2, 1, 4]
|
[3, 2, 1, 4]
|
||||||
|
|
||||||
See how we use kwapply to handle the fancy pssing? :)
|
See how we use kwapply to handle the fancy passing? :)
|
||||||
|
|
||||||
There's also a dictionary-style keyword arguments construction that
|
There's also a dictionary-style keyword arguments construction that
|
||||||
looks like:
|
looks like:
|
||||||
|
@ -38,6 +38,7 @@ except ImportError:
|
|||||||
(x >> 24) & 0xff]))
|
(x >> 24) & 0xff]))
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
PY27 = sys.version_info >= (2, 7)
|
||||||
PY3 = sys.version_info[0] >= 3
|
PY3 = sys.version_info[0] >= 3
|
||||||
PY33 = sys.version_info >= (3, 3)
|
PY33 = sys.version_info >= (3, 3)
|
||||||
PY34 = sys.version_info >= (3, 4)
|
PY34 = sys.version_info >= (3, 4)
|
||||||
|
113
hy/compiler.py
113
hy/compiler.py
@ -39,7 +39,7 @@ from hy.errors import HyCompileError, HyTypeError
|
|||||||
|
|
||||||
import hy.macros
|
import hy.macros
|
||||||
from hy.macros import require, macroexpand
|
from hy.macros import require, macroexpand
|
||||||
from hy._compat import str_type, long_type, PY33, PY3, PY34
|
from hy._compat import str_type, long_type, PY27, PY33, PY3, PY34
|
||||||
import hy.importer
|
import hy.importer
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
@ -1265,41 +1265,114 @@ class HyASTCompiler(object):
|
|||||||
ctx=ast.Load())
|
ctx=ast.Load())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _compile_generator_iterables(self, trailers):
|
||||||
|
"""Helper to compile the "trailing" parts of comprehensions:
|
||||||
|
generators and conditions"""
|
||||||
|
|
||||||
|
generators = trailers.pop(0)
|
||||||
|
|
||||||
|
cond = self.compile(trailers.pop(0)) if trailers != [] else Result()
|
||||||
|
|
||||||
|
gen_it = iter(generators)
|
||||||
|
paired_gens = zip(gen_it, gen_it)
|
||||||
|
|
||||||
|
gen_res = Result()
|
||||||
|
gen = []
|
||||||
|
for target, iterable in paired_gens:
|
||||||
|
comp_target = self.compile(target)
|
||||||
|
target = self._storeize(comp_target)
|
||||||
|
gen_res += self.compile(iterable)
|
||||||
|
gen.append(ast.comprehension(
|
||||||
|
target=target,
|
||||||
|
iter=gen_res.force_expr,
|
||||||
|
ifs=[]))
|
||||||
|
|
||||||
|
if cond.expr:
|
||||||
|
gen[-1].ifs.append(cond.expr)
|
||||||
|
|
||||||
|
return gen_res + cond, gen
|
||||||
|
|
||||||
@builds("list_comp")
|
@builds("list_comp")
|
||||||
@checkargs(min=2, max=3)
|
@checkargs(min=2, max=3)
|
||||||
def compile_list_comprehension(self, expr):
|
def compile_list_comprehension(self, expr):
|
||||||
# (list-comp expr (target iter) cond?)
|
# (list-comp expr (target iter) cond?)
|
||||||
expr.pop(0)
|
expr.pop(0)
|
||||||
expression = expr.pop(0)
|
expression = expr.pop(0)
|
||||||
tar_it = iter(expr.pop(0))
|
|
||||||
targets = zip(tar_it, tar_it)
|
|
||||||
|
|
||||||
cond = self.compile(expr.pop(0)) if expr != [] else Result()
|
gen_res, gen = self._compile_generator_iterables(expr)
|
||||||
|
|
||||||
generator_res = Result()
|
|
||||||
generators = []
|
|
||||||
for target, iterable in targets:
|
|
||||||
comp_target = self.compile(target)
|
|
||||||
target = self._storeize(comp_target)
|
|
||||||
generator_res += self.compile(iterable)
|
|
||||||
generators.append(ast.comprehension(
|
|
||||||
target=target,
|
|
||||||
iter=generator_res.force_expr,
|
|
||||||
ifs=[]))
|
|
||||||
|
|
||||||
if cond.expr:
|
|
||||||
generators[-1].ifs.append(cond.expr)
|
|
||||||
|
|
||||||
compiled_expression = self.compile(expression)
|
compiled_expression = self.compile(expression)
|
||||||
ret = compiled_expression + generator_res + cond
|
ret = compiled_expression + gen_res
|
||||||
ret += ast.ListComp(
|
ret += ast.ListComp(
|
||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
col_offset=expr.start_column,
|
col_offset=expr.start_column,
|
||||||
elt=compiled_expression.force_expr,
|
elt=compiled_expression.force_expr,
|
||||||
generators=generators)
|
generators=gen)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@builds("set_comp")
|
||||||
|
@checkargs(min=2, max=3)
|
||||||
|
def compile_set_comprehension(self, expr):
|
||||||
|
if PY27:
|
||||||
|
ret = self.compile_list_comprehension(expr)
|
||||||
|
expr = ret.expr
|
||||||
|
ret.expr = ast.SetComp(
|
||||||
|
lineno=expr.lineno,
|
||||||
|
col_offset=expr.col_offset,
|
||||||
|
elt=expr.elt,
|
||||||
|
generators=expr.generators)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
expr[0] = HySymbol("list_comp").replace(expr[0])
|
||||||
|
expr = HyExpression([HySymbol("set"), expr]).replace(expr)
|
||||||
|
return self.compile(expr)
|
||||||
|
|
||||||
|
@builds("dict_comp")
|
||||||
|
@checkargs(min=3, max=4)
|
||||||
|
def compile_dict_comprehension(self, expr):
|
||||||
|
if PY27:
|
||||||
|
expr.pop(0) # dict-comp
|
||||||
|
key = expr.pop(0)
|
||||||
|
value = expr.pop(0)
|
||||||
|
|
||||||
|
gen_res, gen = self._compile_generator_iterables(expr)
|
||||||
|
|
||||||
|
compiled_key = self.compile(key)
|
||||||
|
compiled_value = self.compile(value)
|
||||||
|
ret = compiled_key + compiled_value + gen_res
|
||||||
|
ret += ast.DictComp(
|
||||||
|
lineno=expr.start_line,
|
||||||
|
col_offset=expr.start_column,
|
||||||
|
key=compiled_key.force_expr,
|
||||||
|
value=compiled_value.force_expr,
|
||||||
|
generators=gen)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
# In Python 2.6, turn (dict-comp key value [foo]) into
|
||||||
|
# (dict (list-comp (, key value) [foo]))
|
||||||
|
|
||||||
|
expr[0] = HySymbol("list_comp").replace(expr[0])
|
||||||
|
expr[1:3] = [HyExpression(
|
||||||
|
[HySymbol(",")] +
|
||||||
|
expr[1:3]
|
||||||
|
).replace(expr[1])]
|
||||||
|
expr = HyExpression([HySymbol("dict"), expr]).replace(expr)
|
||||||
|
return self.compile(expr)
|
||||||
|
|
||||||
|
@builds("genexpr")
|
||||||
|
def compile_genexpr(self, expr):
|
||||||
|
ret = self.compile_list_comprehension(expr)
|
||||||
|
expr = ret.expr
|
||||||
|
ret.expr = ast.GeneratorExp(
|
||||||
|
lineno=expr.lineno,
|
||||||
|
col_offset=expr.col_offset,
|
||||||
|
elt=expr.elt,
|
||||||
|
generators=expr.generators)
|
||||||
|
return ret
|
||||||
|
|
||||||
@builds("apply")
|
@builds("apply")
|
||||||
@checkargs(min=1, max=3)
|
@checkargs(min=1, max=3)
|
||||||
def compile_apply_expression(self, expr):
|
def compile_apply_expression(self, expr):
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
;;; Hy tail-call optimization
|
;;; Hy tail-call optimization
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2014 Clinton Dreisbach <clinton@dreisbach.us>
|
;; Copyright (c) 2014 Clinton Dreisbach <clinton@dreisbach.us>
|
||||||
|
;; Copyright (c) 2014 Paul R. Tagliamonte <tag@pault.ag>
|
||||||
;;
|
;;
|
||||||
;; Permission is hereby granted, free of charge, to any person obtaining a
|
;; Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
;; copy of this software and associated documentation files (the "Software"),
|
;; copy of this software and associated documentation files (the "Software"),
|
||||||
@ -55,7 +56,24 @@
|
|||||||
(recursive-replace old-term new-term term)]
|
(recursive-replace old-term new-term term)]
|
||||||
[True term]) [term body])))
|
[True term]) [term body])))
|
||||||
|
|
||||||
(defmacro loop [bindings &rest body]
|
|
||||||
|
(defmacro/g! fnr [signature &rest body]
|
||||||
|
(let [[new-body (recursive-replace 'recur g!recur-fn body)]]
|
||||||
|
`(do
|
||||||
|
(import [hy.contrib.loop [--trampoline--]])
|
||||||
|
(with-decorator
|
||||||
|
--trampoline--
|
||||||
|
(def ~g!recur-fn (fn [~@signature] ~@new-body)))
|
||||||
|
~g!recur-fn)))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro defnr [name lambda-list &rest body]
|
||||||
|
(if (not (= (type name) HySymbol))
|
||||||
|
(macro-error name "defnr takes a name as first argument"))
|
||||||
|
`(setv ~name (fnr ~lambda-list ~@body)))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro/g! loop [bindings &rest body]
|
||||||
;; Use inside functions like so:
|
;; Use inside functions like so:
|
||||||
;; (defun factorial [n]
|
;; (defun factorial [n]
|
||||||
;; (loop [[i n]
|
;; (loop [[i n]
|
||||||
@ -67,13 +85,7 @@
|
|||||||
;; If recur is used in a non-tail-call position, None is returned, which
|
;; 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
|
;; causes chaos. Fixing this to detect if recur is in a tail-call position
|
||||||
;; and erroring if not is a giant TODO.
|
;; and erroring if not is a giant TODO.
|
||||||
(with-gensyms [recur-fn]
|
(let [[fnargs (map (fn [x] (first x)) bindings)]
|
||||||
(let [[fnargs (map (fn [x] (first x)) bindings)]
|
[initargs (map second bindings)]]
|
||||||
[initargs (map second bindings)]
|
`(do (defnr ~g!recur-fn [~@fnargs] ~@body)
|
||||||
[new-body (recursive-replace 'recur recur-fn body)]]
|
(~g!recur-fn ~@initargs))))
|
||||||
`(do
|
|
||||||
(import [hy.contrib.loop [--trampoline--]])
|
|
||||||
(def ~recur-fn
|
|
||||||
(--trampoline-- (fn [~@fnargs]
|
|
||||||
~@new-body)))
|
|
||||||
(~recur-fn ~@initargs)))))
|
|
||||||
|
@ -242,14 +242,19 @@ def t_identifier(p):
|
|||||||
if obj.startswith("&"):
|
if obj.startswith("&"):
|
||||||
return HyLambdaListKeyword(obj)
|
return HyLambdaListKeyword(obj)
|
||||||
|
|
||||||
if obj.startswith("*") and obj.endswith("*") and obj not in ("*", "**"):
|
def mangle(p):
|
||||||
obj = obj[1:-1].upper()
|
if p.startswith("*") and p.endswith("*") and p not in ("*", "**"):
|
||||||
|
p = p[1:-1].upper()
|
||||||
|
|
||||||
if "-" in obj and obj != "-":
|
if "-" in p and p != "-":
|
||||||
obj = obj.replace("-", "_")
|
p = p.replace("-", "_")
|
||||||
|
|
||||||
if obj.endswith("?") and obj != "?":
|
if p.endswith("?") and p != "?":
|
||||||
obj = "is_%s" % (obj[:-1])
|
p = "is_%s" % (p[:-1])
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
obj = ".".join([mangle(part) for part in obj.split(".")])
|
||||||
|
|
||||||
return HySymbol(obj)
|
return HySymbol(obj)
|
||||||
|
|
||||||
|
@ -266,3 +266,39 @@ def test_lex_comment_382():
|
|||||||
"""Ensure that we can tokenize sources with a comment at the end"""
|
"""Ensure that we can tokenize sources with a comment at the end"""
|
||||||
entry = tokenize("foo ;bar\n;baz")
|
entry = tokenize("foo ;bar\n;baz")
|
||||||
assert entry == [HySymbol("foo")]
|
assert entry == [HySymbol("foo")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_lex_mangling_star():
|
||||||
|
"""Ensure that mangling starred identifiers works according to plan"""
|
||||||
|
entry = tokenize("*foo*")
|
||||||
|
assert entry == [HySymbol("FOO")]
|
||||||
|
entry = tokenize("*")
|
||||||
|
assert entry == [HySymbol("*")]
|
||||||
|
entry = tokenize("*foo")
|
||||||
|
assert entry == [HySymbol("*foo")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_lex_mangling_hyphen():
|
||||||
|
"""Ensure that hyphens get translated to underscores during mangling"""
|
||||||
|
entry = tokenize("foo-bar")
|
||||||
|
assert entry == [HySymbol("foo_bar")]
|
||||||
|
entry = tokenize("-")
|
||||||
|
assert entry == [HySymbol("-")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_lex_mangling_qmark():
|
||||||
|
"""Ensure that identifiers ending with a question mark get mangled ok"""
|
||||||
|
entry = tokenize("foo?")
|
||||||
|
assert entry == [HySymbol("is_foo")]
|
||||||
|
entry = tokenize("?")
|
||||||
|
assert entry == [HySymbol("?")]
|
||||||
|
entry = tokenize("im?foo")
|
||||||
|
assert entry == [HySymbol("im?foo")]
|
||||||
|
entry = tokenize(".foo?")
|
||||||
|
assert entry == [HySymbol(".is_foo")]
|
||||||
|
entry = tokenize("foo.bar?")
|
||||||
|
assert entry == [HySymbol("foo.is_bar")]
|
||||||
|
entry = tokenize("foo?.bar")
|
||||||
|
assert entry == [HySymbol("is_foo.bar")]
|
||||||
|
entry = tokenize(".foo?.bar.baz?")
|
||||||
|
assert entry == [HySymbol(".is_foo.bar.is_baz")]
|
||||||
|
@ -525,7 +525,7 @@
|
|||||||
(assert (= x 3))))
|
(assert (= x 3))))
|
||||||
|
|
||||||
|
|
||||||
(defn test-comprehensions []
|
(defn test-list-comprehensions []
|
||||||
"NATIVE: test list comprehensions"
|
"NATIVE: test list comprehensions"
|
||||||
(assert (= (list-comp (* x 2) (x (range 2))) [0 2]))
|
(assert (= (list-comp (* x 2) (x (range 2))) [0 2]))
|
||||||
(assert (= (list-comp (* x 2) (x (range 4)) (% x 2)) [2 6]))
|
(assert (= (list-comp (* x 2) (x (range 4)) (% x 2)) [2 6]))
|
||||||
@ -536,6 +536,41 @@
|
|||||||
(assert (= (list-comp j (j [1 2])) [1 2])))
|
(assert (= (list-comp j (j [1 2])) [1 2])))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-set-comprehensions []
|
||||||
|
"NATIVE: test set comprehensions"
|
||||||
|
(assert (instance? set (set-comp x [x (range 2)])))
|
||||||
|
(assert (= (set-comp (* x 2) (x (range 2))) (set [0 2])))
|
||||||
|
(assert (= (set-comp (* x 2) (x (range 4)) (% x 2)) (set [2 6])))
|
||||||
|
(assert (= (set-comp (* y 2) ((, x y) (.items {"1" 1 "2" 2})))
|
||||||
|
(set [2 4])))
|
||||||
|
(assert (= (set-comp (, x y) (x (range 2) y (range 2)))
|
||||||
|
(set [(, 0 0) (, 0 1) (, 1 0) (, 1 1)])))
|
||||||
|
(assert (= (set-comp j (j [1 2])) (set [1 2]))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-dict-comprehensions []
|
||||||
|
"NATIVE: test dict comprehensions"
|
||||||
|
(assert (instance? dict (dict-comp x x [x (range 2)])))
|
||||||
|
(assert (= (dict-comp x (* x 2) (x (range 2))) {1 2 0 0}))
|
||||||
|
(assert (= (dict-comp x (* x 2) (x (range 4)) (% x 2)) {3 6 1 2}))
|
||||||
|
(assert (= (dict-comp x (* y 2) ((, x y) (.items {"1" 1 "2" 2})))
|
||||||
|
{"2" 4 "1" 2}))
|
||||||
|
(assert (= (dict-comp (, x y) (+ x y) (x (range 2) y (range 2)))
|
||||||
|
{(, 0 0) 0 (, 1 0) 1 (, 0 1) 1 (, 1 1) 2})))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-generator-expressions []
|
||||||
|
"NATIVE: test generator expressions"
|
||||||
|
(assert (not (instance? list (genexpr x [x (range 2)]))))
|
||||||
|
(assert (= (list (genexpr (* x 2) (x (range 2)))) [0 2]))
|
||||||
|
(assert (= (list (genexpr (* x 2) (x (range 4)) (% x 2))) [2 6]))
|
||||||
|
(assert (= (list (sorted (genexpr (* y 2) ((, x y) (.items {"1" 1 "2" 2})))))
|
||||||
|
[2 4]))
|
||||||
|
(assert (= (list (genexpr (, x y) (x (range 2) y (range 2))))
|
||||||
|
[(, 0 0) (, 0 1) (, 1 0) (, 1 1)]))
|
||||||
|
(assert (= (list (genexpr j (j [1 2]))) [1 2])))
|
||||||
|
|
||||||
|
|
||||||
(defn test-defn-order []
|
(defn test-defn-order []
|
||||||
"NATIVE: test defn evaluation order"
|
"NATIVE: test defn evaluation order"
|
||||||
(setv acc [])
|
(setv acc [])
|
||||||
|
Loading…
Reference in New Issue
Block a user