def doEndCycleOperations(p): global quadCounter # Obtiene el número pendiente de cuadruplo a llenar end = jumpsStack.pop() # Obtiene el número de cuadruplo a regresar retrn = jumpsStack.pop() # Obtiene la posición del cuadruplo a llenar quadNumber = (quadQueue.size() - 1) - end # Obtiene la posición del cuadruplo a regresar returnJump = (quadQueue.size() - 1) - retrn # Obtiene el cuadruplo a llenar endQuad = quadQueue.get(quadNumber) # Crea el cuadruplo a regresar quad = Quadruple(quadCounter, 'goto', None, None, end) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 # Agrega el salto al cuadruplo endQuad.addJump(quadCounter) print("doEndCycleOperation", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def doAssignOperation(p): global semanticCube global quadCounter # Obtiene el operando derecho rightOperand = operandsStack.pop() # Obtiene el tipo derecho rightType = typesStack.pop() # Obtiene el operando izquierdo leftOperand = operandsStack.pop() # Obtiene el tipo derecho leftType = typesStack.pop() # Obtiene el operador operator = operatorsStack.pop() if rightType == 'void': errorNotReturnFunction(p) else: # Obtener el resultado del cubo semántico con tipo izquierdo, tipo derecho y el operador resultType = semanticCube.getType(leftType, rightType, operator) # Checa el resultado que mandó el cubo semántico if resultType == 'Error': errorTypeMismatch(p) else: # Crea el cuadruplo de la asignación quad = Quadruple(quadCounter, operator, rightOperand, None, leftOperand) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa el contador quadCounter += 1 print("doAssignOperation", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " +str(p.lexer.lineno))
def doCycleOperations(p): global quadCounter # Obtiene el tipo de la expresión expressionType = typesStack.pop() # Obtiene el resultado de la expresión expressionResult = operandsStack.pop() # Checa si la expresión es booleana if expressionType != 'bool': # Despliega el error de type mismatch errorTypeMismatch(p) else: # Crea el cuadruplo de gotof de la condición false vacío quad = Quadruple(quadCounter, 'gotof', expressionResult, None, None) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Agrega el número del cuadrúplo a ser rellenado después jumpsStack.push(quadCounter - 1) print('doCycleOperations', jumpsStack.top()) print('doCycleOperations', jumpsStack.items) # Incrementa el contador quadCounter += 1 print("doCycleOperations", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def endProcess(p): global quadCounter global returns print('returns.........', returns) # Obtiene el tipo de la función functionType = functionsDirectory.getFunctionType(currentScope) funcReturn[currentScope] = quadCounter endprocnumber = quadCounter #Ciclo para la cantidad de retorno for i in range(0, returns): # Obtiene el número del cuadruplo pendiente a llenar end = returnStack.pop() # Obtiene la posición del cuadruplo quadNumber = (quadQueue.size()) - end # Obtiene el cuadruplo a llenar quad = quadQueue.get(quadNumber) # Llena el cuadruplo con el salto correspondiente quad.addJump(quadCounter) print("endProcess", currentScope, ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno)) # Checa si la función es void if functionType != 'void': # Checa si la función tiene un return if not functionWithReturn: errorFunctionNoReturn(p) else: # Crea cuadruplo con ENDPROC quad = Quadruple(quadCounter, 'ENDPROC', None, None, None) # AAgrega cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 else: # Crea cuadruplo con ENDPROC quad = Quadruple(quadCounter, 'ENDPROC', None, None, None) # Agrega cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 #Resetea variable de retornos returns = 0 # Cuando termina la función se limpia la memoria temporal memory.clearTempMemory()
def drawPolyChart(p): global predefParamStack global quadCounter # Crea el cuadruplo de DRAWPOLYCHART quad = Quadruple(quadCounter, 'DRAWPOLYCHART', predefParamStack.items, None, None) # Inserta el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 # Resetea el stack de parametros predefParamStack = Stack()
def validateIndex(p): global quadCounter # Obtiene el index de la variable dimensionada index = operandsStack.pop() # Obtiene el tipo de la variable dimensionada indexType = typesStack.pop() print memory.memoryBlock[index] # Checa si el index es int if indexType != 'int': errorArgumentsMissmatch(p) else: # Crea el cuadruplo de VER quad = Quadruple(quadCounter, 'VER', index, 0, dimenSupLim) # Inserta el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 # Obtiene la dirección base de la variable dimensionada dimenVarBaseAddress = operandsStack.pop() # Obtiene el tipo de la variable dimensionada dimenVarType = typesStack.pop() # Guarda la variable en memoria temporal y obtiene la dirección base baseAddress = memory.storeTempToMemory(dimenVarBaseAddress, 'int') # Guarda la variable en memoria temporal y obtiene la dirección virtual virtualAddress = memory.storeTempToMemory(dimenVarBaseAddress, dimenVarType) # Crea el cuadruplo de + después de la verificación quad = Quadruple(quadCounter, '+', index, baseAddress, virtualAddress) # Inserta el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 # Inserta la direccion en operandStack operandsStack.push([virtualAddress]) # Inserta el tipo en typeStack typesStack.push(dimenVarType) print( "validateIndex", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def doElseOperation(p): global quadCounter # Crear el cuadruplo del goto vacío al final del else quad = Quadruple(quadCounter, 'goto', None, None, None) # Agregar el cuadruplo a la queue quadQueue.enqueue(quad) # Obtiene el número pendiente del salto a llenar num = jumpsStack.pop() # Obtiene el numero del último cuadruplo quadNumber = (quadQueue.size() - 1) - num # Inserta el numero del cuadruplo a ser llenado jumpsStack.push(quadCounter - 1) # Incrementa el contador quadCounter += 1 # Obtiene el cuadruplo de la queue quad = quadQueue.get(quadNumber) # Le agrega el salto al cuadruplo correspondiente quad.addJump(quadCounter) print("doElseOperation", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " +str(p.lexer.lineno))
def generateEra(p): global quadCounter # Obtiene el nombre de la función funcId = p[-3] # Crea el cuadruplo de ERA quad = Quadruple(quadCounter,'ERA', funcId, None, None) # Agrega cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 print("generateEra", currentScope, ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def doOperations(p): global semanticCube global quadCounter # Obtiene el operando derecho rightOperand = operandsStack.pop() # Obtiene el tipo derecho rightType = typesStack.pop() # Obtiene el operando izquierdo leftOperand = operandsStack.pop() # Obtiene el tipo izquierdo leftType = typesStack.pop() # Obtiene el operador correspondiente operator = operatorsStack.pop() # Obtener el resultado del cubo semántico con tipo izquierdo, tipo derecho y el operador resultType = semanticCube.getType(leftType, rightType, operator) # Asignar el valor por default dependiendo del tipo if resultType == 'int': value = defaultInt elif resultType == 'float': value = defaultFloat elif resultType == 'bool': value = defaultBool elif resultType == 'string': value = defaultString # Checa si el resultado del cubo semántico es error if resultType == 'Error': #Ejecuta error type missmatch errorTypeMismatch(p) else: # Guarda la variable en memoria temporal y obtiene la dirección virtual virtualAddress = memory.storeTempToMemory(value, resultType) # Crea el cuadruplo quad = Quadruple(quadCounter, operator, leftOperand, rightOperand, virtualAddress) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Inserta la dirección en el operandStack operandsStack.push(virtualAddress) # Inserta el tipo resultante en el typeStack typesStack.push(resultType) # Incrementa el contador quadCounter += 1 print("doOperation", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result))
def gotoMain(p): global quadCounter # Agrega a JumpsStack el número del cuadruplo a ser llenado jumpsStack.push(quadCounter) # Crea el cuadruplo gotomain quad = Quadruple(quadCounter, 'goto', None, None, None) # Agrega el cuadruplo a la queue de Cuadruplos quadQueue.enqueue(quad) # Incrementa el contador de cuadruplos quadCounter += 1 print("gotoMain", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def doWriteOperation(p): global quadCounter # Obtiene el operando de operandStack operand = operandsStack.pop() # Obtiene el tipo de typesStack popType = typesStack.pop() # Crea el cuadruplo para el write quad = Quadruple(quadCounter, 'WRITE', operand, None, None) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa el contador quadCounter += 1 print("write", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def endProgram(p): global quadQueue # Crea el cuadruplo de END quad = Quadruple(quadCounter, "END", None, None, None) # Inserta el cuadruplo a la queue quadQueue.enqueue(quad) print("endProgram", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result)) print("Correct Sintax.\n\n") #Crea Maquina Virtual con quadruplos, bloque de memoria y directorio de funciones vm = virtual_Machine(quadQueue, memory, functionsDirectory)
def doNotOperation(p): global semanticCube global quadCounter # Checa que el operatorStack no esté vacio if not operatorsStack.isEmpty(): # Checa que el operador de arriba sea un '!' if operatorsStack.top() == '!': # Obtener el operando operand = operandsStack.pop() # Obtener el tipo type = typesStack.pop() # Obtener el operador operator = operatorsStack.pop() # Checa que el tipo sea bool if type != 'bool': resultType = 'Error' else: resultType = 'bool' #Cambia el valor a false value = defaultBool # Checa si el resultado del tipo es bool if resultType != 'bool': # Despliega el error typeMismatch errorTypeMismatch(p) else: # Guarda el valor en memoria temporal y obtiene su dirección virtualAddress = memory.storeTempToMemory(value, resultType) # Crea el cuadruplo de la negación quad = Quadruple(quadCounter, operator, operand, None, virtualAddress) # Last parameter should be the VirtualAddress # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Inserta la variable temporal al operandsStack operandsStack.push(virtualAddress) # Inserta el tipo temporal al typesStack typesStack.push(resultType) # Incrementa el contador de cuadruplos quadCounter += 1 print("doNotOperation",("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), str(p.lexer.lineno))
def returnOperation(p): global quadCounter global functionWithReturn global endprocnumber global returns # Obtiene el tipo de la función functionType = functionsDirectory.getFunctionType(currentScope) # Checa si la función es void if functionType == 'void': errorVoidFunction(p) else: # Cambiar la variable que identifica que una función tiene valor de retorno functionWithReturn = True # Obtiene el operando operand = operandsStack.pop() # Obtiene el tipo de retorno type = typesStack.pop() functionVariable = functionsDirectory.getFunctionVariable(globalScope, currentScope) funcVirtualAddress = functionVariable[1][1] # Checa si el tipo de retorno es diferente al de la función if type != functionType: errorReturnWrongType(p) else: #Contador de retornos para recursividad returns += 1 returnStack.push(quadCounter) # Crea cuadruplo para el return quad = Quadruple(quadCounter, 'RETURN', operand, funcVirtualAddress, None) # Agrega cuadruplo a la queue quadQueue.enqueue(quad) # Inserta la dirección virtual al operandsStack operandsStack.push(funcVirtualAddress) # Inserta el tipo al typeStack typesStack.push(functionType) # Incrementa el contador quadCounter += 1 print("returnOperation", currentScope, ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno))
def doConditionOperation(p): global quadCounter # Obtener el tipo de la expresión expressionType = typesStack.pop() # Obtener el resultado de la expresión expressionResult = operandsStack.pop() # Checa si la expresión es bool if expressionType != 'bool': # Despliega el error de type mismatch errorTypeMismatch(p) else: # Crea el cuadruplo de gotof quad = Quadruple(quadCounter, 'gotof', expressionResult, None, None) # Agrega el cuadruplo a la queue quadQueue.enqueue(quad) # Inserta el cuadruplo anterior a ser llenado a la jumpStack jumpsStack.push(quadCounter - 1) # Incrementa el contador quadCounter += 1 print("doConditionOperation", ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " +str(p.lexer.lineno))
def validateArguments(p): global argumentQueue global argumTypeQueue global calledFunction global quadCounter global argumCounter # Lista de direcciones de parámetros paramAddresses = functionsDirectory.getParameterAddresses(calledFunction) # Checa si los parámetros son del mismo tipo que lo que son declarados if not functionsDirectory.validateParameters(calledFunction, argumTypeQueue.items): errorArgumentsMissmatch(p) else: while not argumentQueue.isEmpty(): # Crea el cuadruplo de PARAM quad = Quadruple(quadCounter, 'PARAM', argumentQueue.dequeue(), None, paramAddresses[argumCounter]) # Agrega cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 # Incrementa contador de argumentos argumCounter += 1 print("validateArguments 1", currentScope, ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno)) startQuad = functionsDirectory.getStartQuadNumber(calledFunction) # Crea el cuadruplo de gosub quad = Quadruple(quadCounter, 'gosub', calledFunction, None, startQuad) # Agrega cuadruplo a la queue quadQueue.enqueue(quad) # Incrementa contador quadCounter += 1 print("validateArguments 2", currentScope, ("Quad " + str(quad.quad_number), quad.operator, quad.left_operand, quad.right_operand, quad.result), "line: " + str(p.lexer.lineno)) # Obtiene el tipo de la función functionType = functionsDirectory.getFunctionType(calledFunction) # Checa si la función es void if functionType == 'void': # Inserta error en la operandStack para tratar después operandsStack.push('Error') # Inserta el tipo a la typeStack typesStack.push(functionType) else: # Obtiene la variable de retorno de la función funcVar = functionsDirectory.getFunctionVariable(globalScope, calledFunction) # Obtiene la direcciñon virtual de la variable varVirtualAddress = funcVar[1][1] # Inserta el nombre de la variable operandsStack.push(varVirtualAddress) # Inserta el tipo de la variable typesStack.push(functionType) print("validateArguments 3", currentScope, "line: " + str(p.lexer.lineno)) # Limpia las variables y contadores argumentQueue = Queue() argumTypeQueue = Queue() calledFunction = "" argumCounter = 0