def visit_Gen(self, node): if node.func == "eye": type1 = self.visit(node.arg) if type1 == "int": size = node.arg.value return VectorType(width=size, height=size, type="int") else: print("Error at line {0}: Function {1} argument must be int". format(node.line, node.func)) return None else: if isinstance(node.arg, list): if len(node.arg) == 2: type2 = self.visit(node.arg[0]) type3 = self.visit(node.arg[1]) if type2 == "int" and type3 == "int": return VectorType(width=node.arg[0].value, height=node.arg[1].value, type="int") else: print( "Error at line {0}: Function {1} arguments must be int" .format(node.line, node.func)) return None else: print( "Error at line {0}: Function {1} must have 2 arguments" .format(node.line, node.func)) return None else: print("Error at line {0}: Function {1} must have 2 arguments". format(node.line, node.func)) return None
def checkMatrixType(type1, type2, lineno): if checkType(type1, VectorType) and checkType(type2, VectorType): if type1.size is None or type2.size is None: return VectorType() elif type1.size != type2.size: print("different vector sizes: ", lineno) return UndefinedType() else: return VectorType(size=type1.size) elif checkType(type1, MatrixType) and checkType(type2, MatrixType): if type1.width is None or type2.width is None or type1.height is None or type2.height is None: return MatrixType() elif type1.width != type2.width or type1.height != type2.height: print("different matrix sizes: ", lineno) return UndefinedType() else: return MatrixType(width=type1.width, height=type1.height) elif checkType(type1, VectorType) and (checkType(type2, TFloat) or checkType(type2, TInt)): if type1.size is not None: return VectorType(size=type1.size) else: return VectorType() elif checkType(type1, MatrixType) and (checkType(type2, TFloat) or checkType(type2, TInt)): if type1.width is None or type2.width is None: return MatrixType() else: return MatrixType(width=type1.width, height=type1.height) print("different sizes: ", lineno) return None
def visit_MatrixFunction(self, node): type = self.visit(node.arg) if type == 'int': return VectorType([node.arg.value, node.arg.value], 'int', 2) else: print(f"Error in line {node.line}. Wrong type in matrix function {node.func_name}") return ErrorType()
def visit_BinopMat(self, node): type1 = self.visit(node.left) type2 = self.visit(node.right) if type1 is None or type2 is None: return None if not isinstance(type1, VectorType) or not isinstance( type2, VectorType): print( "Error at line {0}: Binary operation can only be done for matrices" .format(node.line)) return None if type1.width != type2.width or type1.height != type1.width: print("Error at line {0}: Matrices of incompatible sizes".format( node.line)) return None if type1.type != type2.type: print("Error at line {0}: Matrices of incompatible types".format( node.line)) return None return VectorType(width=type1.width, height=type1.height, type=type1.type)
def visit_Binop(self, node): type1 = self.visit(node.left) type2 = self.visit(node.right) if type1 is None or type2 is None: return None if isinstance(type1, VectorType): if not isinstance(type2, VectorType): print("Error at line {0}: Variables of incompatible types". format(node.line)) return None # Both matrix: if node.op in ["+", "-"]: if type1.width != type2.width or type1.height != type1.width: print("Error at line {0}: Matrices of incompatible sizes". format(node.line)) return None if type1.type != type2.type: print("Error at line {0}: Matrices of incompatible types". format(node.line)) return None return VectorType(width=type1.width, height=type1.height, type=type1.type) if node.op == "*": if type1.width != type2.height: print("Error at line {0}: Matrices of incompatible sizes". format(node.line)) if type1.type != type2.type: print("Error at line {0}: Matrices of incompatible types". format(node.line)) return None return VectorType(width=type2.width, height=type1.height, type=type1.type) if node.op == "/": print("Error at line {0}: Matrices can not be divided") return None if isinstance(type2, VectorType): print("Error at line {0}: Variables of incompatible types".format( node.line)) return None if type1 == "float" or type2 == "float": return "float" return "int"
def visit_Vector(self, node): elements = node.elements first_element = elements[0] if type(first_element) == AST.Vector: for vector in elements: if len(vector.elements) != len(first_element.elements): print(f"Error in line {node.line}. Different length") return ErrorType() for el in vector.elements: if type(el) != type(first_element.elements[0]): print(f"Error in line {node.line}.Wrong type in vector") return ErrorType() return VectorType([len(elements), len(first_element.elements)], type(first_element), 2) else: for element in elements: if type(element) != type(first_element): print(f"Error in line {node.line}. Different types") return ErrorType() return VectorType([len(elements)], type(first_element), 1)
def visit_Transposition(self, node): type1 = self.visit(node.mat) if isinstance(type1, VectorType): return VectorType(width=type1.height, height=type1.width, type=type1) else: print("Error at line {0}: Can only transpose matrix".format( node.line)) return None
def visit_Matrix(self, node): rows_count = len(node.mat) row_len = len(node.mat[0]) m_type = self.visit(node.mat[0][0]) for row in node.mat: if len(row) != row_len: print( "Error at line {0}: Matrix rows must have the same length " .format(node.line)) return None for element in row: if self.visit(element) != m_type: print( "Error at line {0}: Matrix elements must be of the same type" .format(node.line)) return None return VectorType(width=row_len, height=rows_count, type=m_type)
def visit_Sequence(self, node): values = [] for val in node.values: values.append(self.visit(val)) return VectorType(values)