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)
Exemple #2
0
    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()
Exemple #3
0
    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_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)
Exemple #5
0
 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()
Exemple #6
0
 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 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)
Exemple #9
0
 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_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)
Exemple #11
0
    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))
Exemple #12
0
    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)
Exemple #13
0
    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
Exemple #14
0
 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 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"]))
Exemple #16
0
    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
Exemple #17
0
 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
Exemple #18
0
 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)
Exemple #20
0
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())
Exemple #21
0
    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")