From 62522a5f8693dfb13f589f520739b1281776e379 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Mon, 30 Dec 2013 12:04:40 +0100 Subject: [PATCH] Allow get with multiple arguments When calling get with more than two arguments, treat the rest as indexes into the expression from the former. That is, (get foo "bar" "baz") would translate to foo["bar"]["baz"], and so on. This fixes #362. Requested-by: Sean B. Palmer Signed-off-by: Gergely Nagy --- hy/compiler.py | 25 ++++++++++++++++--------- tests/compilers/test_ast.py | 1 - tests/native_tests/language.hy | 11 ++++++++++- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/hy/compiler.py b/hy/compiler.py index 9df4fb9..230cdda 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1086,18 +1086,25 @@ class HyASTCompiler(object): return rimports @builds("get") - @checkargs(2) + @checkargs(min=2) def compile_index_expression(self, expr): expr.pop(0) # index - val = self.compile(expr.pop(0)) # target - sli = self.compile(expr.pop(0)) # slice - return val + sli + ast.Subscript( - lineno=expr.start_line, - col_offset=expr.start_column, - value=val.force_expr, - slice=ast.Index(value=sli.force_expr), - ctx=ast.Load()) + val = self.compile(expr.pop(0)) + slices, ret = self._compile_collect(expr) + + if val.stmts: + ret += val + + for sli in slices: + val = Result() + ast.Subscript( + lineno=expr.start_line, + col_offset=expr.start_column, + value=val.force_expr, + slice=ast.Index(value=sli), + ctx=ast.Load()) + + return ret + val @builds("del") @checkargs(min=1) diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index a362d66..98ac7ac 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -253,7 +253,6 @@ def test_ast_bad_get(): "Make sure AST can't compile invalid get" cant_compile("(get)") cant_compile("(get 1)") - cant_compile("(get 1 2 3)") def test_ast_good_slice(): diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 4efe768..65cca5c 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -129,7 +129,16 @@ (defn test-index [] "NATIVE: Test that dict access works" (assert (= (get {"one" "two"} "one") "two")) - (assert (= (get [1 2 3 4 5] 1) 2))) + (assert (= (get [1 2 3 4 5] 1) 2)) + (assert (= (get {"first" {"second" {"third" "level"}}} + "first" "second" "third") + "level")) + (assert (= (get ((fn [] {"first" {"second" {"third" "level"}}})) + "first" "second" "third") + "level")) + (assert (= (get {"first" {"second" {"third" "level"}}} + ((fn [] "first")) "second" "third") + "level"))) (defn test-lambda []