From a7cd70c84a61d2e4d103d3af2c5321d343a1c5ea Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 12 Jan 2013 00:50:08 +0100 Subject: [PATCH] compiler: Make maps and lists able to look up their params As a neat syntactic sugar, it's very neat if maps and lists are able to work as if they were functions, and look up their arguments. This implements just that, by translating (map key) to (index map key) internally, and (list idx) to (index list idx). Signed-off-by: Gergely Nagy --- hy/compiler/ast27.py | 14 ++++++++++++++ tests/lang/colls.hy | 5 +++++ tests/lang/test_types_as_fn.py | 7 +++++++ 3 files changed, 26 insertions(+) create mode 100644 tests/lang/colls.hy create mode 100644 tests/lang/test_types_as_fn.py diff --git a/hy/compiler/ast27.py b/hy/compiler/ast27.py index 9cec38e..af8e745 100644 --- a/hy/compiler/ast27.py +++ b/hy/compiler/ast27.py @@ -163,6 +163,10 @@ class AST27Converter(object): "for": self._ast_for, "kwapply": self._ast_kwapply, } + self.special_types = { + HYMap: self._ast_fn_index, + HYList: self._ast_fn_index, + } self.in_fn = False def _ast_index(self, node): @@ -176,6 +180,13 @@ class AST27Converter(object): ast.Index(value=self.render(tar), ctx=ast.Load()), ast.Load()) + def _ast_fn_index(self, node): + i = node.get_invocation() + cmd = ["index"] + cmd.append(i['function']) + cmd.extend(i['args']) + return self.render_expression(HYExpression(cmd)) + def _ast_dot(self, node): inv = node.get_invocation() args = inv['args'] @@ -370,6 +381,9 @@ class AST27Converter(object): inv = node.get_invocation() + if type(inv['function']) in self.special_types: + return self.special_types[type(inv['function'])](node) + if inv['function'] in self.native_cases: return self.native_cases[inv['function']](node) diff --git a/tests/lang/colls.hy b/tests/lang/colls.hy new file mode 100644 index 0000000..3369b0e --- /dev/null +++ b/tests/lang/colls.hy @@ -0,0 +1,5 @@ +(defn test-map-index [] + ({"foo" "bar"} "foo")) + +(defn test-list-index [] + (["first" "second"] 1)) diff --git a/tests/lang/test_types_as_fn.py b/tests/lang/test_types_as_fn.py new file mode 100644 index 0000000..d942d5a --- /dev/null +++ b/tests/lang/test_types_as_fn.py @@ -0,0 +1,7 @@ +import tests.lang.colls + +def test_map_index(): + assert tests.lang.colls.test_map_index() == "bar" + +def test_list_index(): + assert tests.lang.colls.test_list_index() == "second"