Merge pull request #795 from zackmdavis/infix_matrix_multiplication

add support for Python 3.5 infix matrix multiplication
This commit is contained in:
Berker Peksag 2015-04-26 12:21:56 +03:00
commit 5106789f17
4 changed files with 68 additions and 2 deletions

View File

@ -42,6 +42,7 @@ PY27 = sys.version_info >= (2, 7)
PY3 = sys.version_info[0] >= 3
PY33 = sys.version_info >= (3, 3)
PY34 = sys.version_info >= (3, 4)
PY35 = sys.version_info >= (3, 5)
if PY3:
str_type = str

View File

@ -38,7 +38,8 @@ from hy.models.cons import HyCons
from hy.errors import HyCompileError, HyTypeError
import hy.macros
from hy._compat import str_type, long_type, PY27, PY33, PY3, PY34, raise_empty
from hy._compat import (
str_type, long_type, PY27, PY33, PY3, PY34, PY35, raise_empty)
from hy.macros import require, macroexpand, reader_macroexpand
import hy.importer
@ -121,6 +122,13 @@ def builds(_type):
return _dec
def builds_if(_type, condition):
if condition:
return builds(_type)
else:
return lambda fn: fn
class Result(object):
"""
Smart representation of the result of a hy->AST compilation
@ -1638,6 +1646,7 @@ class HyASTCompiler(object):
@builds("|")
@builds("^")
@builds("&")
@builds_if("@", PY35)
@checkargs(min=2)
def compile_maths_expression(self, expression):
ops = {"+": ast.Add,
@ -1652,6 +1661,8 @@ class HyASTCompiler(object):
"|": ast.BitOr,
"^": ast.BitXor,
"&": ast.BitAnd}
if PY35:
ops.update({"@": ast.MatMult})
inv = expression.pop(0)
op = ops[inv]
@ -1711,6 +1722,7 @@ class HyASTCompiler(object):
@builds("|=")
@builds("^=")
@builds("&=")
@builds_if("@=", PY35)
@checkargs(2)
def compile_augassign_expression(self, expression):
ops = {"+=": ast.Add,
@ -1725,6 +1737,8 @@ class HyASTCompiler(object):
"|=": ast.BitOr,
"^=": ast.BitXor,
"&=": ast.BitAnd}
if PY35:
ops.update({"@=": ast.MatMult})
op = ops[expression[0]]

View File

@ -45,7 +45,7 @@ long_description = """Hy is a Python <--> Lisp layer. It helps
make things work nicer, and lets Python and the Hy lisp variant play
nice together. """
install_requires = ['rply>=0.7.0', 'astor>=0.3', 'clint>=0.4']
install_requires = ['rply>=0.7.0', 'astor>=0.5', 'clint>=0.4']
if sys.version_info[:2] < (2, 7):
install_requires.append('argparse>=1.2.1')
install_requires.append('importlib>=1.0.2')

View File

@ -1,3 +1,5 @@
(import [hy._compat [PY35]])
(setv square (fn [x]
(* x x)))
@ -140,3 +142,52 @@
(defn overflow-int-to-long []
"NATIVE: test if int does not raise an overflow exception"
(assert (integer? (+ 1 1000000000000000000000000))))
(defclass HyTestMatrix [list]
[[--matmul--
(fn [self other]
(let [[n (len self)]
[m (len (. other [0]))]
[result []]]
(for [i (range m)]
(let [[result-row []]]
(for [j (range n)]
(let [[dot-product 0]]
(for [k (range (len (. self [0])))]
(+= dot-product (* (. self [i] [k])
(. other [k] [j]))))
(.append result-row dot-product)))
(.append result result-row)))
result))]])
(def first-test-matrix (HyTestMatrix [[1 2 3]
[4 5 6]
[7 8 9]]))
(def second-test-matrix (HyTestMatrix [[2 0 0]
[0 2 0]
[0 0 2]]))
(def product-of-test-matrices (HyTestMatrix [[ 2 4 6]
[ 8 10 12]
[14 16 18]]))
(defn test-matmul []
"NATIVE: test matrix multiplication"
(if PY35
(assert (= (@ first-test-matrix second-test-matrix)
product-of-test-matrices))
;; Python <= 3.4
(let [[matmul-attempt (try (@ first-test-matrix second-test-matrix)
(catch [e [Exception]] e))]]
(assert (isinstance matmul-attempt NameError)))))
(defn test-augassign-matmul []
"NATIVE: test augmented-assignment matrix multiplication"
(let [[matrix first-test-matrix]
[matmul-attempt (try (@= matrix second-test-matrix)
(catch [e [Exception]] e))]]
(if PY35
(assert (= product-of-test-matrices matrix))
(assert (isinstance matmul-attempt NameError)))))