diff --git a/hy/compiler.py b/hy/compiler.py index ca8c0e9..d663d58 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -1910,7 +1910,6 @@ class HyASTCompiler(object): col_offset=child.start_column) return ret - @builds("+") @builds("*") @builds("/") @builds("//") @@ -1918,8 +1917,7 @@ class HyASTCompiler(object): if len(expression) > 2: return self.compile_maths_expression(expression) else: - id_op = {"+": HyInteger(0), "*": HyInteger(1), "/": HyInteger(1), - "//": HyInteger(1)} + id_op = {"*": HyInteger(1), "/": HyInteger(1), "//": HyInteger(1)} op = expression.pop(0) arg = expression.pop(0) if expression else id_op[op] @@ -1930,20 +1928,34 @@ class HyASTCompiler(object): ]).replace(expression) return self.compile_maths_expression(expr) - @builds("-") - @checkargs(min=1) - def compile_maths_expression_sub(self, expression): + def compile_maths_expression_additive(self, expression): if len(expression) > 2: return self.compile_maths_expression(expression) else: - arg = expression[1] + op = {"+": ast.UAdd, "-": ast.USub}[expression.pop(0)]() + arg = expression.pop(0) ret = self.compile(arg) - ret += ast.UnaryOp(op=ast.USub(), + ret += ast.UnaryOp(op=op, operand=ret.force_expr, lineno=arg.start_line, col_offset=arg.start_column) return ret + @builds("+") + def compile_maths_expression_add(self, expression): + if len(expression) == 1: + # Nullary + + return ast.Num(n=long_type(0), + lineno=expression.start_line, + col_offset=expression.start_column) + else: + return self.compile_maths_expression_additive(expression) + + @builds("-") + @checkargs(min=1) + def compile_maths_expression_sub(self, expression): + return self.compile_maths_expression_additive(expression) + @builds("+=") @builds("/=") @builds("//=") diff --git a/hy/core/shadow.hy b/hy/core/shadow.hy index b63219d..e66d075 100644 --- a/hy/core/shadow.hy +++ b/hy/core/shadow.hy @@ -30,7 +30,7 @@ (if (zero? count) (raise (TypeError "Need at least 1 argument to add/concatenate")) (if (= count 1) - (get args 0) + (operator.pos (get args 0)) (reduce operator.add args))))) diff --git a/tests/native_tests/mathematics.hy b/tests/native_tests/mathematics.hy index 58c5457..5ab90c4 100644 --- a/tests/native_tests/mathematics.hy +++ b/tests/native_tests/mathematics.hy @@ -28,6 +28,18 @@ (assert (= 0 (+))))) +(defn test-add-unary [] + "NATIVE: test that unary + calls __pos__" + + (defclass X [object] + [__pos__ (fn [self] "called __pos__")]) + (assert (= (+ (X)) "called __pos__")) + + ; Make sure the shadowed version works, too. + (setv f +) + (assert (= (f (X)) "called __pos__"))) + + (setv test_div (fn [] "NATIVE: Test division" (assert (= 25 (/ 100 2 2))) diff --git a/tests/native_tests/shadow.hy b/tests/native_tests/shadow.hy index 0ca08ba..ce578bf 100644 --- a/tests/native_tests/shadow.hy +++ b/tests/native_tests/shadow.hy @@ -8,13 +8,9 @@ (assert (= (x 1 2 3 4) 10)) (assert (= (x 1 2 3 4 5) 15)) ; with strings - (assert (= (x "a") - "a")) (assert (= (x "a" "b" "c") "abc")) ; with lists - (assert (= (x ["a"]) - ["a"])) (assert (= (x ["a"] ["b"] ["c"]) ["a" "b" "c"]))))