def p_draw_line(p): ''' DRAW_LINE : ''' global operandsList global quadruples y2 = operandsList.pop() x2 = operandsList.pop() y1 = operandsList.pop() x1 = operandsList.pop() point1 = Operand("point1", (x1.value, y1.value), (x1.type, y1.type), (x1.vAddress, y1.vAddress)) point2 = Operand("point2", (x2.value, y2.value), (x2.type, y2.type), (x2.vAddress, y2.vAddress)) if ((y2.type != "int") and (y2.type != "float")) or ( (x2.type != "int") and (x2.type != "float")) or ( (y1.type != "int") and (y1.type != "float")) or ((x1.type != "int") and (x1.type != "float")): errorQueue.append( "Error: " + "Failed operation, int or float type parameters expected.") print("Error: " + "Failed operation, int or float type parameters expected. ") else: quadruples.addDrawLineCuadruple(point1, point2)
def test_shifting_c_code(self) -> None: hex_insn = PluginInfo.HEX_INSTR_VAR_SYNTAX self.assertEqual( "((({}) & 0x1fe0) >> 5)".format(hex_insn), Operand.make_sparse_mask( InstructionEncoding(self.json["A2_combineii"]["Inst"]).operand_masks[ "Ii" ] ), ) self.assertEqual( "(((({}) & 0x7f0000) >> 15) | ((({}) & 0x2000) >> 13))".format( hex_insn, hex_insn ), Operand.make_sparse_mask( InstructionEncoding(self.json["A2_combineii"]["Inst"]).operand_masks[ "II" ] ), ) self.assertEqual( "(((({}) & 0xfff0000) >> 2) | ((({}) & 0x3fff) >> 0))".format( hex_insn, hex_insn ), Operand.make_sparse_mask( InstructionEncoding(self.json["A4_ext"]["Inst"]).operand_masks["Ii"] ), )
def randomOperand(self): operand = Operand() for digit in self.digits.keys(): operand.addDigit(digit, self.digits[digit].randomInt()) if (self.explicitRange == []): return operand elif (self.explicitRange != [] and operand.value() in self.explicitRange): return operand else: return self.randomOperand()
def p_cte(p): ''' CTE : cte_i | cte_f | cte_c | null ''' global cteValue global cteType global operandsList global dirAddresses global funcName cteValue = p[1] if isinstance(p[1], int): cteType = "int" elif isinstance(p[1], float): cteType = "float" elif p[1] == "null": cteType = "string" elif isinstance(p[1], str): cteType = "char" addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None) vAddress = dirAddresses[addressTableKey].getAnAddress() dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType) #print (str(vAddress) + " : " + str(dirAddresses[addressTableKey].getAddressData(vAddress)["value"])) if p[1] == "null": cteType = "null" consOperand = Operand(None, cteValue, cteType, vAddress) operandsList.append(consOperand)
def validate_function_call(self): if self.param_count != self.AT.funcs[ self.current_function_call].num_params: raise NameError( f"Wrong number of parameters passed. Expected {self.AT.funcs[self.current_function_call].num_params}. {self.param_count} were given." ) else: self.generate_quadruple( Operator.GOSUB, self.current_function_call, None, self.AT.funcs[self.current_function_call].first_quadruple) func = self.AT.get_func(self.current_function_call) func_return_type = func.get_return_type() if func_return_type is not Type.VOID: tmp_address = self.memory_manager.set_temp_address( func_return_type) temp = Operand(address=tmp_address) func_address = self.AT.get_global_var( self.current_function_call).get_address() self.generate_quadruple(Operator.ASSIGN, func_address, None, tmp_address) self.operands.append(temp) self.types.append(func_return_type) self.operators.pop()
def ver_index(self): var, dim_num = self.arrays.pop() if dim_num == 0: self.current_array_address = 0 self.current_array_dim_number = var.get_dim_count() if self.current_dim == self.current_array_dim_number: raise NameError(f'Trying to access a non-existent dimension') s_address = self.operands.pop().get_address() self.types.pop() dim = var.get_dim(dim_num) lim_inf = self.AT.get_constant_address(dim.get_lim_inf(), Type.INT) lim_sup = self.AT.get_constant_address(dim.get_lim_sup(), Type.INT) self.generate_quadruple(Operator.VER, s_address, lim_inf, lim_sup) # Following the formula s1*m1 + s2 + (-k).... tmp_address = self.memory_manager.set_temp_address(Type.INT) t = Operand(address=tmp_address, op_type=Type.INT) m = dim.get_m() m_address = self.AT.get_constant_address(m, Type.INT) # If it doesn't exist, create a new constant address for it. if m_address == -1: m_address = self.memory_manager.set_constant_address(Type.INT) self.AT.add_constant_address(m, Type.INT, m_address) # Multiply m of the current Dim node if it's not the last dim if dim_num < self.current_array_dim_number - 1: self.generate_quadruple(Operator.TIMES, s_address, m_address, tmp_address) # Add (-k) if it's the last Dim node else: k_address = m_address self.generate_quadruple(Operator.PLUS, s_address, k_address, tmp_address) if dim_num != 0: aux = self.operands.pop() self.types.pop() tmp_address_2 = self.memory_manager.set_temp_address(Type.INT) self.generate_quadruple(Operator.PLUS, aux.get_address(), tmp_address, tmp_address_2) t.set_address(tmp_address_2) self.operands.append(t) self.types.append(Type.INT) self.arrays.append((var, dim_num + 1))
def maybe_solve_sign(self): operator = self.get_top_operator() if operator in (Operator.POSITIVE_SIGN, Operator.NEGATIVE_SIGN, Operator.NOT): operand = self.operands.pop() operand_type = self.types.pop() operator = self.operators.pop() result_type = semantic_cube[operand_type][operator] if result_type == Type.ERROR: raise NameError(f'Type mismatch {operand_type} {operator}') temp = Operand(op_type=result_type) address = self.memory_manager.set_temp_address(result_type) temp.set_address(address) self.curr_t_count += 1 self.generate_quadruple(operator, operand.get_address(), None, temp.get_address()) self.operands.append(temp) self.types.append(result_type)
def addExpressionCuadruple(self, operator, leftOperand, rightOperand, dirAddresses): result_type = SC[leftOperand.type][rightOperand.type][operator] if result_type == "error": return "Failed operation. type missmatch: cannot do " + operator + " operation between " + leftOperand.type + " and " + rightOperand.type else: self.resultsCounter += 1 resultName = "result" + str(self.resultsCounter) addressTableKey = determineTypeAddressTable(None,result_type,None,True) vAddress = dirAddresses[addressTableKey].getAnAddress() resultOperand = Operand(resultName, None, result_type, vAddress) self.quadruples.append( (operator, leftOperand, rightOperand, resultOperand) ) return resultOperand
def maybe_solve_operation(self, operations): operator = self.get_top_operator() if operator in operations: r_operand = self.operands.pop() r_type = self.types.pop() l_operand = self.operands.pop() l_type = self.types.pop() operator = self.operators.pop() result_type = semantic_cube[l_type][r_type][operator] if result_type == Type.ERROR: raise NameError(f"Type mismatch {l_type} {operator} {r_type}") temp = Operand() temp.set_type(result_type) address = self.memory_manager.set_temp_address(result_type) temp.set_address(address) self.curr_t_count += 1 self.operands.append(temp) self.types.append(result_type) self.generate_quadruple(operator, l_operand.get_address(), r_operand.get_address(), address)
def p_sem_add_gosub(p): ''' SEM_ADD_GOSUB : ''' global funcCall global quadruples global operandsList global funcDirec quadruples.addGosubFuncQuadruple(funcCall) funcCallType = funcDirec.getFuncReturnType(funcCall) if not funcCallType == "void": operandsList.append(Operand(funcCall, None, funcCallType, funcCall))
def p_do_color(p): ''' DO_COLOR : cte_s ''' global dirAddresses global operandsList global quadruples cteValue = p[1] cteType = "string" addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None) vAddress = dirAddresses[addressTableKey].getAnAddress() colorOperand = Operand(None, cteValue, cteType, vAddress) dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType) quadruples.addColorQuadruple(colorOperand)
def p_sem_add_print_cte_s(p): ''' SEM_ADD_PRINT_CTE_S : cte_s ''' global operandsList global quadruples global dirAddresses global funcName cteValue = p[1] cteType = "string" addressTableKey = determineTypeAddressTable(None, cteType, cteValue, None) vAddress = dirAddresses[addressTableKey].getAnAddress() consOperand = Operand(None, cteValue, cteType, vAddress) dirAddresses[addressTableKey].saveAddressData(vAddress, cteValue, cteType) quadruples.addPrintCuadruple(consOperand)
def get_array_dir(self): operand = self.operands.pop() var, _ = self.arrays.pop() self.types.pop() # To make things easy, our tp are normal temporary address but with negative address value tmp_address = self.memory_manager.set_temp_address(Type.INT) * -1 t = Operand(address=tmp_address) # Add base address base_address = var.get_address() const_address = self.AT.get_constant_address(base_address, Type.INT) if const_address == -1: # It doesn't exist. const_address = self.memory_manager.set_constant_address(Type.INT) self.AT.add_constant_address(base_address, Type.INT, const_address) self.generate_quadruple(Operator.PLUS, operand.get_address(), const_address, tmp_address * -1) self.operands.append(t) self.types.append(Type.INT)
def p_variable(p): ''' VARIABLE : SEM_ID_FOR_ARRAY '[' EXPRESION SEM_CHECK_ARRAY ']' | id ''' global varName global funcDirec global operandsList global funcDirec global dirAddresses global funcName #es una variable en una expresion, no un arreglo if len(p) < 3: varName = p[1] retrievedVar = funcDirec.getVariableInFunc(funcName, varName) if isinstance(retrievedVar, str): errorQueue.append("Error: " + retrievedVar) print("Error: ", retrievedVar) else: operandsList.append( Operand(varName, None, retrievedVar["varType"], retrievedVar["vAddress"]))
def add_var(self, var_name, is_param=False, is_array=False): func = None operand = Operand(name=var_name, op_type=types[self.last_var_type], is_array=is_array) if self.is_global: self.AT.add_global_address(operand) else: func = self.get_current_func() func.add_var(operand) if is_param: func.num_params += 1 func.param_names.append(var_name) if is_array: func.current_var_name = var_name self.r = 1 else: # Address is only set for non-arrays for now. Address for arrays should be set after knowing the total needed memory space for the array. scope = Scope.GLOBAL if self.is_global else Scope.LOCAL var_address = self.memory_manager.set_address( scope=scope, var_type=types[self.last_var_type]) var = self.find_var_in_address_table(var_name) var.set_address(var_address)
def parse(self) -> RecordList: record_list = RecordList() with open(self.src) as fd: for line in fd.readlines(): line = line.replace('=>', ' ') line = line.replace(',', ' ') operator, *operand = line.split() if operator.startswith("//"): # this is comment line continue # remove inline comment i = 0 for i, _ in enumerate(operand): op = operand[i] if op == '//': break operand = operand[:i + 1] if operator in Operator.NOP_OPERATOR: record_list.append(Record(Operator(operator))) elif operator in Operator.UNARY_OPERATOR: record_list.append( Record(Operator(operator), Operand(operand[0]))) elif operator in Operator.BINARY_OPERATOR: if len(operand) != 2: raise ValueError("invalid operand: {}".format(operand)) record_list.append( Record(Operator(operator), operand_one=Operand(operand[0]), operand_three=Operand(operand[1]))) elif operator in Operator.TRIPLE_OPERATOR: record_list.append( Record(Operator(operator), Operand(operand[0]), Operand(operand[1]), Operand(operand[2]))) else: raise ValueError("invalid operator: {}".format(operator)) return record_list
def parse_instruction(self) -> None: """Parses all operands of the instruction which are encoded.""" # TODO A lot of duplicate code with Instruction::parse:instruction() # Operand names seen during parsing the encoding. Twin operands (Operands which appear in high and low instr.) # were renamed. all_ops = deepcopy( self.high_instr.llvm_in_out_operands + self.low_instr.llvm_in_out_operands ) self.llvm_filtered_operands = self.remove_invisible_in_out_regs( self.llvm_syntax, all_ops ) self.operand_indices = self.get_syntax_operand_indices( self.llvm_syntax, self.llvm_filtered_operands ) # Update syntax indices if self.has_new_non_predicate: op_name = self.llvm_in_out_operands[self.new_operand_index][1] self.new_operand_index = self.operand_indices[op_name] # log("{}\n new: {}".format(self.llvm_syntax, self.new_operand_index), LogLevel.DEBUG) if self.has_extendable_imm: op_name = self.llvm_in_out_operands[self.ext_operand_index][1] self.ext_operand_index = self.operand_indices[op_name] # log("{}\n ext: {}".format(self.llvm_syntax, self.ext_operand_index), LogLevel.DEBUG) if len(self.llvm_filtered_operands) > PluginInfo.MAX_OPERANDS: warning = "{} instruction struct can only hold {} operands. This instruction has {} operands.".format( PluginInfo.FRAMEWORK_NAME, PluginInfo.MAX_OPERANDS, len(self.llvm_filtered_operands), ) raise ImplementationException(warning) for in_out_operand in self.llvm_filtered_operands: op_name = in_out_operand[1] op_type = in_out_operand[0]["def"] index = self.operand_indices[op_name] # Parse register operand if Operand.get_operand_type(op_type) is OperandType.REGISTER: # Indices of new values (stored in "opNewValue") are only for non predicates. is_new_value = ( self.new_operand_index == index and self.has_new_non_predicate ) operand = Register(op_name, op_type, is_new_value, index) # Whether the predicate registers holds a new value is denoted in "isPredicatedNew". if self.predicate_info.new_value and operand.is_predicate: operand.is_new_value = True # Parse immediate operands elif Operand.get_operand_type(op_type) is OperandType.IMMEDIATE: extendable = self.has_extendable_imm and self.ext_operand_index == index if self.extendable_alignment > 0: log(str(self.extendable_alignment), op_type) operand = Immediate( op_name, op_type, extendable, self.extendable_alignment, index ) else: raise ImplementationException( "Unknown operand type: {}, op_name: {}".format(op_type, op_name) ) # Use lower() because we can get RX16in and Rx16in but constraints are always Rx16in. if op_name.lower() in self.constraints.lower(): operand.is_in_out_operand = True operand.is_out_operand = True operand.is_in_operand = True elif in_out_operand in self.llvm_in_operands: operand.is_in_operand = True elif in_out_operand in self.llvm_out_operands: operand.is_out_operand = True # Add opcode extraction code if ( operand.type == OperandType.IMMEDIATE and operand.is_constant ): # Constants have no parsing code. pass else: if ( operand.is_in_out_operand and op_name[-2:] == "in" ): # In/Out Register mask = self.encoding.operand_masks[op_name[:-2]] # Ends with "in" else: mask = self.encoding.operand_masks[op_name] operand.opcode_mask = mask operand.add_code_for_opcode_parsing(Operand.make_sparse_mask(mask)) # On the fly check whether the new values have been assigned correctly. if op_name + ".new" in self.llvm_syntax: if not operand.is_new_value: raise ImplementationException( "Register has new value in syntax but not as object." + "It has been parsed incorrectly! Are the indices correctly set?" + "Affected instruction: {}".format(self.llvm_syntax) ) # log("Add operand: {}".format(op_name), LogLevel.DEBUG) # TODO This uses the llvm name as key. Maybe use normalized name? Rs16 -> Rs? self.operands[op_name] = operand
def addParamFuncQuadruple(self, param, paramsCounter): resultName = "param" + str(paramsCounter) resultOperand = Operand(resultName, None, param.type, param.vAddress) self.quadruples.append( ("parameter", param, None, resultOperand) )
def p_sem_check_array(p): ''' SEM_CHECK_ARRAY : ''' global idForArray global funcDirec global operandsList global operatorsList global funcDirec global dirAddresses global funcName global quadruples #checa si existe el arreglo retrievedArrayData = funcDirec.getVariableInFunc(funcName, idForArray) if isinstance(retrievedArrayData, str): errorQueue.append("Error: " + retrievedArrayData) print("Error: ", retrievedArrayData) elif not retrievedArrayData["isArray"]: errorQueue.append("Error: Failed operation. " + "variable " + idForArray + " is not an array") print("Error: Failed operation. " + "variable " + idForArray + " is not an array") else: arrayIndexExpression = operandsList.pop() #print (arrayIndexExpression.value) #print (arrayIndexExpression.type) #checa que el index del arreglo sea tipo int if arrayIndexExpression.type != "int": errorQueue.append( "Error: Failed operation. Int type index expected for array " + idForArray + ". " + arrayIndexExpression.type + "type was received instead.") print("Error: ", retrievedVar) #si ya recibi un index que es una constante if isinstance(arrayIndexExpression.value, int): actualAddress = retrievedArrayData[ "vAddress"] + arrayIndexExpression.value #checa que el index tipo int del arreglo se encuentre en el rango de direcciones validas para el arreglo if (actualAddress < retrievedArrayData["vAddress"]) or ( actualAddress > retrievedArrayData["sLimit"]): errorQueue.append("Error: Failed operation. Index " + arrayIndexExpression.value + " is out of bounds for array " + idForArray) print("Error: ", retrievedVar) else: operandsList.append( Operand(idForArray, None, retrievedArrayData["varType"], actualAddress)) #oh sorpresa, el index es una expresion cuyo valor solo se puede conocer en ejecucion, por lo tanto no sabemos el address del arreglo else: #Guarda la direccion base del arreglo en una direccion temporal addressTableKey = determineTypeAddressTable( None, "int", retrievedArrayData["vAddress"], None) vAddress = dirAddresses[addressTableKey].getAnAddress() dirAddresses[addressTableKey].saveAddressData( vAddress, retrievedArrayData["vAddress"], "int") #Crea un operando que represente la direccion base del arreglo baseAddressOperand = Operand(None, retrievedArrayData["vAddress"], "int", vAddress) #Suma el operando de la direccion base con el operando del indicie del arreglo para obtener la verdadera direccion realAdressOperand = quadruples.addExpressionCuadruple( "+", baseAddressOperand, arrayIndexExpression, dirAddresses) funcDirec.addTempVarCountInFunc(funcName, realAdressOperand.type) #baseArrayInfo = Operand(idForArray, None, retrievedArrayData["varType"],retrievedArrayData["vAddress"]) #resultOperand = quadruples.addArrayIndexCuadruple(baseArrayInfo,realAdressOperand) #Crea un operando de resultado con la informacion basica del arreglo (nombre, funcion, direccion base) resultOperand = Operand(idForArray, funcName, retrievedArrayData["varType"], realAdressOperand.vAddress) #y ademas, agregale al operando de resultado la info del operando tipo apuntador que tiene guardada su verdadera direccion (la migaja de pan para encontrar al operando del arreglo en los cuadruplos siguientes y resolver su address correcta en ejecucion) resultOperand.fakeAddress = realAdressOperand.vAddress quadruples.addArrayIndexCuadruple(resultOperand) copyResultOperand = Operand(resultOperand.name, resultOperand.value, resultOperand.type, resultOperand.vAddress) copyResultOperand.fakeAddress = realAdressOperand.vAddress operandsList.append(copyResultOperand)
def parse_instruction(self) -> None: """Parses all operands of the instruction which are encoded.""" self.llvm_filtered_operands = self.remove_invisible_in_out_regs( self.llvm_syntax, deepcopy(self.llvm_in_out_operands) ) self.operand_indices = self.get_syntax_operand_indices( self.llvm_syntax, self.llvm_filtered_operands ) # Update syntax indices if self.has_new_non_predicate: op_name = self.llvm_in_out_operands[self.new_operand_index][1] self.new_operand_index = self.operand_indices[op_name] # log("{}\nnew: {}".format(self.llvm_syntax, self.new_operand_index), LogLevel.DEBUG) if self.has_extendable_imm: op_name = self.llvm_in_out_operands[self.ext_operand_index][1] self.ext_operand_index = self.operand_indices[op_name] # log("{}\next: {}".format(self.llvm_syntax, self.ext_operand_index), LogLevel.DEBUG) if len(self.llvm_filtered_operands) > PluginInfo.MAX_OPERANDS: warning = "{} instruction struct can only hold {} operands. This instruction has {} operands.".format( PluginInfo.FRAMEWORK_NAME, PluginInfo.MAX_OPERANDS, len(self.llvm_filtered_operands), ) raise ImplementationException(warning) # TODO Some instructions encode some register explicitly in the syntax. At the moment we do not, # but maybe should add them here somehow as registers. Example: J4_cmpeq_fp0_jump_t # But note that they don't seem to have an index attached to them. # TODO Parse high/low access of registers. for in_out_operand in self.llvm_filtered_operands: op_name = in_out_operand[1] op_type = in_out_operand[0]["def"] syntax_index = self.operand_indices[op_name] # Parse register operand if Operand.get_operand_type(op_type) is OperandType.REGISTER: # Indices of new values (stored in "opNewValue") are only for non predicates. is_new_value = ( self.new_operand_index == syntax_index and self.has_new_non_predicate ) operand = Register(op_name, op_type, is_new_value, syntax_index) # Whether the predicate registers holds a new value is denoted in "isPredicatedNew". if self.predicate_info.new_value and operand.is_predicate: operand.is_new_value = True # Parse immediate operands elif Operand.get_operand_type(op_type) is OperandType.IMMEDIATE: extendable = ( self.has_extendable_imm and self.ext_operand_index == syntax_index ) operand = Immediate( op_name, op_type, extendable, self.extendable_alignment, syntax_index, ) else: raise ImplementationException( "Unknown operand type: {}, op_name: {}".format(op_type, op_name) ) if op_name in self.constraints: operand.is_in_out_operand = True operand.is_out_operand = True operand.is_in_operand = True elif in_out_operand in self.llvm_in_operands: operand.is_in_operand = True elif in_out_operand in self.llvm_out_operands: operand.is_out_operand = True # Add opcode extraction code if ( operand.type == OperandType.IMMEDIATE and operand.is_constant ): # Constants have no parsing code. pass else: if ( operand.is_in_out_operand and op_name[-2:] == "in" ): # In/Out Register mask = self.encoding.operand_masks[op_name[:-2]] # Ends with "in" else: mask = self.encoding.operand_masks[op_name] operand.opcode_mask = mask operand.add_code_for_opcode_parsing(Operand.make_sparse_mask(mask)) # On the fly check whether the new values have been assigned correctly. if op_name + ".new" in self.llvm_syntax: if not operand.is_new_value: raise ImplementationException( "Register has new value in syntax but not as object." + "It has been parsed incorrectly! Are the indices correctly set?" + "Affected instruction: {}".format(self.llvm_syntax) ) self.operands[op_name] = operand
def build_operand_object(self, name, is_function_call=False): t = type(name) operand = Operand(name, is_function_call=is_function_call) if t == int: operand.set_type(Type.INT) address = self.AT.get_constant_address(name, Type.INT) if address == -1: # It doesn't exist. address = self.memory_manager.set_constant_address(Type.INT) self.AT.add_constant_address(name, Type.INT, address) operand.set_address(address) elif t == float: operand.set_type(Type.FLOAT) address = self.AT.get_constant_address(name, Type.FLOAT) if address == -1: # It doesn't exist. address = self.memory_manager.set_constant_address(Type.FLOAT) self.AT.add_constant_address(name, Type.FLOAT, address) operand.set_address(address) elif t == str: # if constant if name[0] == "\"" and name[-1] == "\"": operand.set_type(Type.STRING) address = self.AT.get_constant_address(name, Type.STRING) if address == -1: # It doesn't exist. address = self.memory_manager.set_constant_address( Type.STRING) self.AT.add_constant_address(name, Type.STRING, address) operand.set_address(address) else: # Variable var = self.find_var_in_address_table(name) if var == -1: raise NameError(f'Undeclared variable {name}') operand.set_address(var.get_address()) operand_type = self.get_type_from_address(var.get_address()) operand.set_type(operand_type) return operand
from Composite import Composite from Operand import Operand from Add import Add from Multiply import Multiply #(10 + 25) * 4 + 52 * (3 + 6) expression = Composite(0) first_brackets = Add(Operand(10), Operand(25)) mul = Multiply(first_brackets, Operand(4)) second_brackets = Add(Operand(3), Operand(6)) mul2 = Multiply(second_brackets, Operand(52)) add = Add(mul, mul2) expression.add(add) print(expression.operation())
def addReturnCuadruple(self,funcName, operand, dirAddresses): #addressTableKey = determineTypeAddressTable("global",operand.type,None,None) #vAddress = dirAddresses[addressTableKey].getAnAddress() resultOperand = Operand(funcName, None, operand.type, funcName) self.quadruples.append( ("return", operand, None, resultOperand) ) return resultOperand
def __instructions_operands_init__(self): self.loopSize = self.xmldoc.getElementsByTagName( 'loopSize')[0].attributes['value'].value print("loop Size: " + self.loopSize) self.percentage_clue = self.xmldoc.getElementsByTagName( 'instruction_percentage_clue')[0].attributes['value'].value print("Percentage clue? :" + self.percentage_clue) self.instruction_types = {} #a dictionary of instruction type and the amount of each instruction in loop.. Note useful only when percentage clue is True self.instructions = {} #a dictionay that has for keeps an array of instructions for every instruction type self.allInstructionArray = [] #An array which hold all instructions self.operands = {} self.toggleInstructionsList = {} itemList = self.xmldoc.getElementsByTagName("instruction_type") for instruction_type in itemList: name = instruction_type.attributes["id"].value perc = instruction_type.attributes["perc"].value self.instruction_types[name] = int( float(perc) * float(self.loopSize)) '''calculate how many of these instructions will be in the loop''' if (self.percentage_clue == "True"): print("amount per instruction type in the loop:") print(self.instruction_types) sum = 0 for value in list(self.instruction_types.values()): sum += value self.loopSize = sum print("actual loop size is " + str(self.loopSize)) itemList = self.xmldoc.getElementsByTagName("operand") print("Available operands\n") for operandDesc in itemList: ins_type = operandDesc.attributes["type"].value if (ins_type == "immediate" or ins_type == "constant" or ins_type == "automatically_incremented_operand"): anOperand = Operand( id=operandDesc.attributes["id"].value, type=operandDesc.attributes["type"].value, values=[], min=operandDesc.attributes["min"].value, max=operandDesc.attributes["max"].value, stride=operandDesc.attributes["stride"].value, toggleable=operandDesc.attributes["toggle"].value) #elif ins_type=="branch_label": # anOperand = BranchLabel(id=operandDesc.attributes["id"].value,ins_type=operandDesc.attributes["type"].value,values=operandDesc.attributes["values"].value.split(),min=operandDesc.attributes["min"].value,max=operandDesc.attributes["max"].value,stride=operandDesc.attributes["stride"].value,toggleable=operandDesc.attributes["toggle"].value); else: anOperand = Operand( id=operandDesc.attributes["id"].value, type=operandDesc.attributes["type"].value, values=operandDesc.attributes["values"].value.split(), toggleable=operandDesc.attributes["toggle"].value) print("id " + anOperand.id.__str__()) print("values ") print(anOperand.values) print("max " + anOperand.max.__str__()) print("min " + anOperand.min.__str__()) print("stride " + anOperand.stride.__str__() + "\n") self.operands[anOperand.id] = anOperand print("End of available operands\n") itemList = self.xmldoc.getElementsByTagName("instruction") print("Available instructions\n") for instructionDesc in itemList: name = instructionDesc.attributes["name"].value ins_type = instructionDesc.attributes["type"].value numOfOperands = instructionDesc.attributes["num_of_operands"].value if "format" in instructionDesc.attributes: anInstruction = Instruction( name, ins_type, numOfOperands, format=instructionDesc.attributes["format"].value, toggleable=instructionDesc.attributes["toggle"].value) else: print( "Instruction " + name + "doesnt have format specified.. All instructions must have format... Exitting" ) sys.exit() #anInstruction = Instruction(name,ins_type,numOfOperands,toggleable=instructionDesc.attributes["toggle"].value); if (instructionDesc.attributes["toggle"].value == "True"): self.toggleInstructionsList[ instructionDesc.attributes["name"].value] = 1 operands = [] #TODO fix this source of bugs.. It's irritating when the num of operands does not match the operands specified in the xml file. and in general is stupid to how the operands specified and the number of operands at the same time.. this redundancy leads to bugs for i in range(1, int(anInstruction.numOfOperands) + 1): operands.append(self.operands[( instructionDesc.attributes["operand" + i.__str__()].value)].copy()) anInstruction.setOperands(operands) print(anInstruction) ##for debugging self.instructions.setdefault(anInstruction.ins_type, []).append(anInstruction) #print (self.instructions); print("End of available instructions\n") for array in list(self.instructions.values()): for ins in array: self.allInstructionArray.append(ins) print("register initialization")