Exemplo n.º 1
0
 def matmul(self, other: 'Matrix') -> 'Matrix':
     """Multiply two matrices."""
     if self._cols != other._rows:
         raise YovecError('cannot mulitply matrices with mismatching sizes')
     vecs = []
     for i in range(self._rows):
         nums = []
         for j in range(other._cols):
             n = Number(0)
             for k in range(other._rows):
                 n = n.binary(
                     'add',
                     self.vecs[i].nums[k].binary('mul',
                                                 other.vecs[k].nums[j]))
             nums.append(n)
         vecs.append(Vector(nums))
     return Matrix(vecs)
Exemplo n.º 2
0
 def assign(self, index: int) -> Tuple[List[Node], 'Vector']:
     """Generate YOLOL assignment statements."""
     assignments = []
     nums = []
     expressions = [n.evaluate() for n in self.nums]
     for i, expr in enumerate(expressions):
         ident = '{}{}_e{}'.format(Vector.PREFIX, index, i)
         var = Node(kind='variable', value=ident)
         asn = Node(kind='assignment', children=[var, expr])
         assignments.append(asn)
         nums.append(Number(ident))
     return assignments, Vector(nums)
Exemplo n.º 3
0
 def assign(self, index: int) -> Tuple[List[Node], 'Matrix']:
     """Generate YOLOL assignment statements."""
     assignments = []
     vecs = []
     for i, v in enumerate(self.vecs):
         nums = []
         for j, n in enumerate(v.nums):
             expr = n.evaluate()
             ident = '{}{}_r{}c{}'.format(Matrix.PREFIX, index, i, j)
             var = Node(kind='variable', value=ident)
             asn = Node(kind='assignment', children=[var, expr])
             assignments.append(asn)
             nums.append(Number(ident))
         vecs.append(Vector(nums))
     return assignments, Matrix(vecs)
Exemplo n.º 4
0
 def len(self) -> Number:
     """Return the length of the vector."""
     return Number(self.length)
Exemplo n.º 5
0
 def dot(self, other: 'Vector') -> Number:
     """Calculate the dot product of two vectors."""
     n = Number(0)
     for ln, rn in zip(self.nums, other.nums):
         n = n.binary('add', ln.binary('mul', rn))
     return n
Exemplo n.º 6
0
 def postmap(self, other: Number, op: str) -> 'Vector':
     """Postmap a binary operation to a vector."""
     return Vector([other.binary(op, n) for n in self.nums])
Exemplo n.º 7
0
 def cols(self) -> Number:
     """Return the number of columns in the matrix."""
     return Number(self._cols)
Exemplo n.º 8
0
 def rows(self) -> Number:
     """Return the number of rows in the matrix."""
     return Number(self._rows)
Exemplo n.º 9
0
 def postmap(self, other: Number, op: str) -> 'Matrix':
     """Postmap a binary operation to a matrix."""
     vecs = []
     for v in self.vecs:
         vecs.append(Vector([other.binary(op, n) for n in v.nums]))
     return Matrix(vecs)
Exemplo n.º 10
0
    def nexpr(self, env: Env, nexpr: Node) -> Tuple[Env, Number]:
        """Transpile a number expression to YOLOL."""
        logger.debug('transpiling number expression - {}'.format(nexpr))

        if not is_nexpr(nexpr.kind):
            raise YovecError('expected number expression, but got {}'.format(
                nexpr.kind))

        elif nexpr.kind == 'num_binary':
            env, lnum = self.nexpr(env, nexpr.children[0])
            ops = nexpr.children[1::2]
            rnums = nexpr.children[2::2]
            for op, rnum in zip(ops, rnums):
                env, rnum = self.nexpr(env, rnum)
                lnum = lnum.binary(op.kind, rnum)
            return env, lnum

        elif nexpr.kind == 'num_unary':
            env, num = self.nexpr(env, nexpr.children[-1])
            for op in reversed(nexpr.children[:-1]):
                num = num.unary(op.kind)
            return env, num

        elif nexpr.kind == 'reduce':
            op = nexpr.children[0]
            env, vec = self.vexpr(env, nexpr.children[1])
            return env, vec.reduce(op.kind)

        elif nexpr.kind == 'dot':
            env, lvec = self.vexpr(env, nexpr.children[0])
            env, rvec = self.vexpr(env, nexpr.children[1])
            return env, lvec.dot(rvec)

        elif nexpr.kind == 'len':
            env, vec = self.vexpr(env, nexpr.children[0])
            return env, vec.len()

        elif nexpr.kind == 'rows':
            env, mat = self.mexpr(env, nexpr.children[0])
            return env, mat.rows()

        elif nexpr.kind == 'cols':
            env, mat = self.mexpr(env, nexpr.children[0])
            return env, mat.cols()

        elif nexpr.kind == 'vec_elem':
            env, vec = self.vexpr(env, nexpr.children[0])
            index = nexpr.children[1].value
            try:
                return env, vec.elem(int(index))
            except ValueError:
                raise YovecError('invalid element index: {}'.format(index))

        elif nexpr.kind == 'mat_elem':
            env, mat = self.mexpr(env, nexpr.children[0])
            row = nexpr.children[1].value
            col = nexpr.children[2].value
            try:
                return env, mat.elem(int(row), int(col))
            except ValueError:
                raise YovecError('invalid element indices: {}, {}'.format(
                    row, col))

        elif nexpr.kind == 'external':
            ident = nexpr.value
            _ = env.target(ident)
            return env, Number(ident)

        elif nexpr.kind == 'variable':
            ident = nexpr.value
            value, _ = env.var(ident)
            if type(value) != Number:
                raise YovecError(
                    'expected variable {} to be number, but got {}'.format(
                        ident, value.class_name))
            return env, value

        elif nexpr.kind == 'call':
            ident = nexpr.children[0].value
            macro = env.macro(ident)
            if macro.return_type != 'number':
                raise YovecError(
                    'expected macro to return number expression, but got {} expression'
                    .format(macro.return_type))
            args = nexpr.children[1].children
            return self.nexpr(env, macro.call(args))

        elif nexpr.kind == 'number':
            try:
                return env, Number(int(nexpr.value))
            except ValueError:
                return env, Number(float(nexpr.value))

        else:
            raise AssertionError('nexpr fallthough: {}'.format(nexpr))