make assoc accept multiple values, also added a even/odd check for checkargs

This commit is contained in:
Guillermo Vaya 2013-07-16 14:35:57 +02:00
parent df7bb1d29a
commit dda291cfb5
2 changed files with 31 additions and 15 deletions

View File

@ -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)

View File

@ -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"