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 <sean@miscoranda.com>
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
This commit is contained in:
Gergely Nagy 2013-12-30 12:04:40 +01:00
parent f189f0a457
commit 62522a5f86
3 changed files with 26 additions and 11 deletions

View File

@ -1086,18 +1086,25 @@ class HyASTCompiler(object):
return rimports return rimports
@builds("get") @builds("get")
@checkargs(2) @checkargs(min=2)
def compile_index_expression(self, expr): def compile_index_expression(self, expr):
expr.pop(0) # index expr.pop(0) # index
val = self.compile(expr.pop(0)) # target
sli = self.compile(expr.pop(0)) # slice
return val + sli + ast.Subscript( val = self.compile(expr.pop(0))
lineno=expr.start_line, slices, ret = self._compile_collect(expr)
col_offset=expr.start_column,
value=val.force_expr, if val.stmts:
slice=ast.Index(value=sli.force_expr), ret += val
ctx=ast.Load())
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") @builds("del")
@checkargs(min=1) @checkargs(min=1)

View File

@ -253,7 +253,6 @@ def test_ast_bad_get():
"Make sure AST can't compile invalid get" "Make sure AST can't compile invalid get"
cant_compile("(get)") cant_compile("(get)")
cant_compile("(get 1)") cant_compile("(get 1)")
cant_compile("(get 1 2 3)")
def test_ast_good_slice(): def test_ast_good_slice():

View File

@ -129,7 +129,16 @@
(defn test-index [] (defn test-index []
"NATIVE: Test that dict access works" "NATIVE: Test that dict access works"
(assert (= (get {"one" "two"} "one") "two")) (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 [] (defn test-lambda []