From 9e03e0e6ec796ccb6713a0b8f7dc3c3b014bafc5 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont Date: Tue, 14 May 2013 11:39:20 +0200 Subject: [PATCH] Modify HyDict semantics to allow nesting expressions HyDicts are now HyLists, that get compiled down to dicts only by the compiler. --- hy/compiler.py | 7 ++++--- hy/lex/states.py | 4 +--- hy/macros.py | 8 +------- hy/models/dict.py | 14 +++++--------- tests/lex/test_lex.py | 9 +++------ 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/hy/compiler.py b/hy/compiler.py index ea3c5de..00931db 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -456,7 +456,8 @@ class HyASTCompiler(object): "arguments or one &key argument") # As you can see, Python has a funny way of # defining keyword arguments. - for k, v in expr.items(): + it = iter(expr) + for k, v in zip(it, it): args.append(k) ret += self.compile(v) defaults.append(ret.force_expr) @@ -543,7 +544,7 @@ class HyASTCompiler(object): name = form.__class__.__name__ imports = set([name]) - if isinstance(form, HyList): + if isinstance(form, (HyList, HyDict)): if not form: contents = HyList() else: @@ -1685,7 +1686,7 @@ class HyASTCompiler(object): @builds(HyDict) def compile_dict(self, m): - keyvalues, ret = self._compile_collect(sum(m.items(), ())) + keyvalues, ret = self._compile_collect(m) ret += ast.Dict(lineno=m.start_line, col_offset=m.start_column, diff --git a/hy/lex/states.py b/hy/lex/states.py index 772f8c6..51255bd 100644 --- a/hy/lex/states.py +++ b/hy/lex/states.py @@ -228,9 +228,7 @@ class Dict(ListeyThing): def exit(self): self.commit() - it = iter(self.nodes) - result = dict(zip(it, it)) - self.result = HyDict(result) + self.result = HyDict(self.nodes) end_char = "}" diff --git a/hy/macros.py b/hy/macros.py index b58d0ec..615e2dc 100644 --- a/hy/macros.py +++ b/hy/macros.py @@ -20,7 +20,6 @@ from hy.models.expression import HyExpression from hy.models.string import HyString -from hy.models.dict import HyDict from hy.models.list import HyList _hy_macros = {} @@ -51,13 +50,8 @@ def process(tree): ntree.replace(tree) return ntree - if isinstance(tree, HyDict): - obj = HyDict(dict((process(x), process(tree[x])) for x in tree)) - obj.replace(tree) - return obj - if isinstance(tree, HyList): - obj = HyList([process(x) for x in tree]) # NOQA + obj = tree.__class__([process(x) for x in tree]) # NOQA # flake8 thinks we're redefining from 52. obj.replace(tree) return obj diff --git a/hy/models/dict.py b/hy/models/dict.py index 43384bd..1bf020c 100644 --- a/hy/models/dict.py +++ b/hy/models/dict.py @@ -18,17 +18,13 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. -from hy.models import HyObject +from hy.models.list import HyList -class HyDict(HyObject, dict): +class HyDict(HyList): """ - HyDict (just a dict) + HyDict (just a representation of a dict) """ - def replace(self, other): - for x in self: - self[x].replace(other) - x.replace(other) - - HyObject.replace(self, other) + def __repr__(self): + return "{%s}" % (" ".join([repr(x) for x in self])) diff --git a/tests/lex/test_lex.py b/tests/lex/test_lex.py index 590e51e..490e167 100644 --- a/tests/lex/test_lex.py +++ b/tests/lex/test_lex.py @@ -185,15 +185,12 @@ def test_lex_line_counting_multi_inner(): def test_dicts(): """ Ensure that we can tokenize a dict. """ objs = tokenize("{foo bar bar baz}") - assert objs == [HyDict({ - "foo": "bar", - "bar": "baz" - })] + assert objs == [HyDict(["foo", "bar", "bar", "baz"])] objs = tokenize("(bar {foo bar bar baz})") assert objs == [HyExpression([HySymbol("bar"), - HyDict({"foo": "bar", - "bar": "baz"})])] + HyDict(["foo", "bar", + "bar", "baz"])])] def test_nospace():