make assoc accept multiple values, also added a even/odd check for checkargs
This commit is contained in:
parent
df7bb1d29a
commit
dda291cfb5
@ -318,7 +318,7 @@ def _raise_wrong_args_number(expression, error):
|
|||||||
len(expression)))
|
len(expression)))
|
||||||
|
|
||||||
|
|
||||||
def checkargs(exact=None, min=None, max=None):
|
def checkargs(exact=None, min=None, max=None, even=None):
|
||||||
def _dec(fn):
|
def _dec(fn):
|
||||||
def checker(self, expression):
|
def checker(self, expression):
|
||||||
if exact is not None and (len(expression) - 1) != exact:
|
if exact is not None and (len(expression) - 1) != exact:
|
||||||
@ -334,6 +334,11 @@ def checkargs(exact=None, min=None, max=None):
|
|||||||
_raise_wrong_args_number(
|
_raise_wrong_args_number(
|
||||||
expression,
|
expression,
|
||||||
"`%%s' needs at most %d arguments, got %%d" % (max))
|
"`%%s' needs at most %d arguments, got %%d" % (max))
|
||||||
|
|
||||||
|
is_even = not((len(expression) - 1) % 2)
|
||||||
|
if even is not None and is_even!=even:
|
||||||
|
even_str = "even" if even else "odd"
|
||||||
|
_raise_wrong_args_number(expression, "`%%s' needs an %s number of arguments, got %%d" % (even_str))
|
||||||
|
|
||||||
return fn(self, expression)
|
return fn(self, expression)
|
||||||
|
|
||||||
@ -1130,25 +1135,31 @@ class HyASTCompiler(object):
|
|||||||
ctx=ast.Load())
|
ctx=ast.Load())
|
||||||
|
|
||||||
@builds("assoc")
|
@builds("assoc")
|
||||||
@checkargs(3)
|
@checkargs(min=3, even=False)
|
||||||
def compile_assoc_expression(self, expr):
|
def compile_assoc_expression(self, expr):
|
||||||
expr.pop(0) # assoc
|
expr.pop(0) # assoc
|
||||||
# (assoc foo bar baz) => foo[bar] = baz
|
# (assoc foo bar baz) => foo[bar] = baz
|
||||||
target = self.compile(expr.pop(0))
|
target = self.compile(expr.pop(0))
|
||||||
key = self.compile(expr.pop(0))
|
ret = target
|
||||||
val = self.compile(expr.pop(0))
|
while expr != []:
|
||||||
|
key = self.compile(expr.pop(0))
|
||||||
|
try:
|
||||||
|
val = self.compile(expr.pop(0))
|
||||||
|
except IndexError:
|
||||||
|
raise HyCompileError("Key {key} has no value to associate".format(key))
|
||||||
|
|
||||||
return target + key + val + ast.Assign(
|
ret += key + val + ast.Assign(
|
||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
col_offset=expr.start_column,
|
col_offset=expr.start_column,
|
||||||
targets=[
|
targets=[
|
||||||
ast.Subscript(
|
ast.Subscript(
|
||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
col_offset=expr.start_column,
|
col_offset=expr.start_column,
|
||||||
value=target.force_expr,
|
value=target.force_expr,
|
||||||
slice=ast.Index(value=key.force_expr),
|
slice=ast.Index(value=key.force_expr),
|
||||||
ctx=ast.Store())],
|
ctx=ast.Store())],
|
||||||
value=val.force_expr)
|
value=val.force_expr)
|
||||||
|
return ret
|
||||||
|
|
||||||
@builds("with_decorator")
|
@builds("with_decorator")
|
||||||
@checkargs(min=1)
|
@checkargs(min=1)
|
||||||
|
@ -348,6 +348,11 @@
|
|||||||
(assoc vals "two" "three")
|
(assoc vals "two" "three")
|
||||||
(assert (= (get vals "two") "three")))
|
(assert (= (get vals "two") "three")))
|
||||||
|
|
||||||
|
(defn test-multiassoc []
|
||||||
|
"NATIVE: test assoc multiple values"
|
||||||
|
(setv vals {"one" "two"})
|
||||||
|
(assoc vals "two" "three" "four" "five")
|
||||||
|
(assert (and (= (get vals "two") "three") (= (get vals "four") "five"))))
|
||||||
|
|
||||||
(defn test-pass []
|
(defn test-pass []
|
||||||
"NATIVE: Test pass worksish"
|
"NATIVE: Test pass worksish"
|
||||||
|
Loading…
Reference in New Issue
Block a user