def eval_dim(self): """ Function to evaluate the expression for each dimension. Generates the quadruple of VER (Verification of dimension) and the multiplication of the expression times the m value """ exp = self._operand.pop() dim = self._top_dim() if exp.type_var != Types.INT: raise BigError.invalid_value( "The value of the array {} is not an Integer".format( exp.id_var)) if exp is not None: dimS = FluffyVariable(None, Types.INT, addr=dim.size) dimM = self.add_constants(dim.m, Types.INT) # m dim self._operand.pop() dimInf = self.add_constants(0, Types.INT) # Dimension inferior self._operand.pop() tem = FluffyVariable(None, exp.type_var, addr=address.set_addr(exp.type_var)) # Validate dim and generate VER self._quadruple.add(QuadruplePack(Operator.VER, exp, dimInf, dimS)) self._quadruple.add(QuadruplePack(Operator.TIMES, exp, dimM, tem)) # x m self._operand.append(tem) else: raise BigError("Error in array expression")
def eval_array(self): """ Function to evaluate the array for each dimension. Generates the quadruples for the sum of each dimension, and generates the quadruple for sum of the BASE """ dim = self._dim_stack.pop() if self._top_dim() is not None: while (self._top_dim().var == dim.var) if self._top_dim() is not None else False: _ = self._dim_stack.pop() op = self._operand.pop() op2 = self._operand.pop() addr = address.set_addr(op.type_var) temp = FluffyVariable(None, op.type_var, addr=addr) q = QuadruplePack(Operator.PLUS, op, op2, temp) self._quadruple.add(q) self._operand.append(temp) # (Index + k ) + BASE base_add_var = self.add_constants(dim.var.addr, dim.var.type_var) self._operand.pop() base = FluffyVariable(None, dim.var.type_var, addr=base_add_var.addr) dim = self._operand.pop() temp = FluffyVariable(None, Types.INT, addr=address.set_addr(Types.INT), access=Access.Indirect) self._quadruple.add(QuadruplePack(Operator.PLUS, base, dim, temp)) self._operand.append(temp)
def gosub(self): self._era.append(self._quadruple.index) function_dir = FluffyVariable(None, None, addr=self.active_function.start_position) self._quadruple.add( QuadruplePack(Operator.GOSUB, None, None, function_dir)) if self.active_function.return_type is not None: temp = FluffyVariable(None, self.active_function.return_type, addr=address.set_addr( self.active_function.return_type)) self._operand.append(temp) self._quadruple.add( QuadruplePack(Operator.GETRET, None, None, temp))
def function_validate_params(self, empty_params=False): fun = self.find_function(self.active_function.id) if empty_params: if self.active_function.params_size != 0: raise BigError.no_empty_params( "The function {} required {} parameters, {} given".format( fun.id_function, self.active_function.params_size, self._count_params + 1)) argument = self._operand.pop() if self._count_params + 1 > self.active_function.params_size: raise BigError.no_empty_params( "The function {} required {} parameters, {} given".format( fun.id_function, self.active_function.params_size, self._count_params + 1)) if argument.type_var != fun.params[self._count_params].type_var: raise BigError.mismatch_params( "The parameter {} doesn't match the type of parameter in function" .format(self._count_params)) param = FluffyVariable(None, None, addr=self._count_params) self._quadruple.add( QuadruplePack(Operator.PARAM, argument, None, param)) self._count_params += 1
def function_return(self): return_value = self._operand.pop() if return_value is None: raise BigError("Error on retrun data") check_data = cube.compare_types(Operator.RETURN, return_value.type_var, self.active_function.return_type) if check_data: result = FluffyVariable( None, type_var=self.active_function.return_type, addr=address.set_addr(kind=self.active_function.return_type)) quadruple = QuadruplePack(Operator.RETURN, l_value=return_value, r_value=None, result=result) self._quadruple.add(quadruple) else: raise BigError.mismatch_operator( "Return type {} does't correspond to the return type of function {} " .format(return_value.type_var, self.active_function.return_type))
def _check_top(self): # len(self._operator)> 0 r_operand = self._operand.pop() r_type = r_operand.type_var l_operand = self._operand.pop() l_type = l_operand.type_var oper = self._operator.pop() check_types = cube.compare_types(oper, l_type, r_type) if check_types: val_result = address.set_addr(check_types) result = FluffyVariable(None, type_var=check_types, addr=val_result) # Generate Quadruple quadruple = QuadruplePack(oper, l_operand, r_operand, result) # Push _quadruple to list self._quadruple.add(quadruple) # Add result position of _quadruple to the operand list self._operand.append(result) else: raise BigError.mismatch_operator("{} {} {} ".format( l_type.name, oper.name, r_type.name))
def _jump(self, stack=False): if stack: jump = self._jumps.pop() addr = FluffyVariable(None, None, addr=jump) self._quadruple.add(QuadruplePack(Operator.GOTO, result=addr)) else: self._jumps.append(self._quadruple.index) self._quadruple.add(QuadruplePack(Operator.GOTO, None, None))
def _fill(self, line=0): actual_quadruple = self._jumps.pop() if actual_quadruple is None: raise BigError("Error, pending quadruples") else: available_quadruple = self._quadruple.index + line address_quadruple = FluffyVariable(None, None, addr=available_quadruple) self._quadruple.fill(actual_quadruple, address_quadruple)
def add_constants(self, value, var_type): if value not in self._constants: self._constants[value] = self._next_const_addr self._next_const_addr += 1 const = FluffyVariable("CONST-" + str(value), type_var=var_type, addr=self._constants[value]) quadruple = QuadruplePack(operation=Operator.CONST, l_value=FluffyVariable(None, None, addr=value), r_value=None, result=const) self.add_operand(const) self._quadruple.add(quadruple) else: const = FluffyVariable("CONST-" + str(value), type_var=var_type, addr=self._constants[value]) self.add_operand(const) return const
def function_create_era(self): size_era = FluffyVariable(None, None, addr=address.calculate_era()) self._quadruple.add(QuadruplePack(Operator.ERA, None, None, size_era))
def fill_era_main(self): size_era = FluffyVariable(None, None, addr=address.calculate_era()) self._quadruple.fill(0, size_era)