def visit_IDAt(self, node): type_index1 = self.visit(node.index1) type_index2 = self.visit(node.index2) index1 = None index2 = None if not type_index1.is_integer: print(f"Error in line {node.line}: first index is not an integer!") else: index1 = node.index1.value if not type_index2.is_integer: print(f"Error in line {node.line}: second index is not an integer!") else: index2 = node.index2.value id = self.visit_ID(node) if id.is_id(): print(f"Error in line {node.line}: variable {node.id} not known!") elif not id.is_matrix(): print(f"Error in line {node.line}: variable {node.id} not a matrix!") else: if index1 < id.x and index2 < id.y: return id.element_type() else: print(f"Error in line {node.line}: index out of bounds!") return types_.Int()
def visit_List2D(self, node): list_of_vectors = node.get_value() list_of_length = [] list_of_type = [] for vector in list_of_vectors: l_type = self.visit(vector) list_of_length.append(l_type.length) list_of_type.append(l_type.element_type) ok = True diff = False for i in range(len(list_of_length) - 1): if list_of_length[i] != list_of_length[i + 1]: ok = False if type(list_of_type[i]) != type(list_of_type[i + 1]): diff = True if None in list_of_type: diff = True if not ok: print(f"Error in line {node.line}: Vectors of different lengths!") if diff: print(f"Error in line {node.line}: All variables in a matrix has to be of one type!") return types_.Matrix(len(list_of_length), list_of_length[0], types_.Int()) return types_.Matrix(len(list_of_length), list_of_length[0], list_of_type[0])
def visit_BinaryOperation(self, node): right = self.visit(node.right) left = self.visit(node.left) if node.operator in ['.+', '.-', '.*', './']: if left.is_matrix() and right.is_matrix() \ and (left.x != right.x or left.y != right.y): print(f"Error in line {node.line}: Matrix binary operation require equal dimensions!") return right elif node.operator in ['+', '-', '*', '/']: if not right.is_numeric(): print(f"Error in line {node.line}: {node.operator} require number arguments!") return types_.Int() if not left.is_numeric(): print(f"Error in line {node.line}: {node.operator} require number arguments!") return types_.Int() return TypeChecker.result_types[node.operator][(left.__class__,right.__class__)]()
def visit_Matrix(self, node): if node.type == None: return self.visit(node.content) elif node.type == 'zeros': node.matrix = [0 for i in range(node.dim)] * node.dim elif node.type == 'ones': node.matrix = [1 for i in range(node.dim)] * node.dim elif node.type == 'eye': node.matrix = [[1 if i == j else 0 for i in range(node.dim)] for j in range(node.dim)] return types_.Matrix(node.dim, node.dim, types_.Int())
def visit_UnaryOperation(self, node): arg = self.visit(node.arg) if node.operator == '\'': if not arg.is_matrix(): print(f"Error in line {node.line}: Wrong transpose argument (of matrix type required)!") else: return types_.Matrix(-1,-1,None) if node.operator == '.-': if not arg.is_matrix(): print(f"Error in line {node.line}: Wrong .- argument (of matrix type required)!") else: return types_.Matrix(-1, -1, None) if node.operator == '-': if not arg.is_numeric(): print(f"Error in line {node.line}: Wrong - argument (of number type required)!") return types_.Int() else: return arg
def visit_Number(self, node): if node.type == 'integer': return types_.Int() return types_.Float()