From 82219e17afb204f53fa63d1b3569b8060864ce40 Mon Sep 17 00:00:00 2001 From: AmauriPC Date: Thu, 24 Nov 2022 05:08:33 -0600 Subject: [PATCH] comments --- Class.py | 6 +-- ClassesTable.py | 7 ++-- Function.py | 1 + FunctionsTable.py | 5 ++- MemoryManager.py | 17 ++++---- Parameter.py | 3 +- Program.py | 3 +- QuadruplesList.py | 101 ++++++++++++++++++++++++++++++---------------- SemanticCube.py | 1 + Var.py | 1 + VarsTable.py | 1 + VirtualMemory.py | 68 ++++++++----------------------- main.py | 96 +++++++++++++++++++++++++++---------------- ovejota.txt | 61 +++++++++++++++++----------- testcase.c | 32 +++++++++++++++ 15 files changed, 241 insertions(+), 162 deletions(-) create mode 100644 testcase.c diff --git a/Class.py b/Class.py index 8ddeb2d..663cda2 100644 --- a/Class.py +++ b/Class.py @@ -1,8 +1,6 @@ -class Class: +#clase para objeto de clase +class Class: def __init__(self, functionsTable, varsTable, variablesCount): self.functionsTable = functionsTable self.varsTable = varsTable self.variablesCount = variablesCount - - - diff --git a/ClassesTable.py b/ClassesTable.py index 949c61a..deb9dcc 100644 --- a/ClassesTable.py +++ b/ClassesTable.py @@ -1,3 +1,4 @@ +#tabla de clases from Error import Error from Class import Class @@ -5,19 +6,19 @@ class ClassesTable: def __init__(self): self.table = {} self.tempGlobalVars = None - + #añadir a la tabla de clases def add(self,name,functionsTable,varsTable): variablesCount = [0,0,0,0,0,0,0,0] for func in functionsTable.table: variablesCount = [sum(x) for x in zip(variablesCount, functionsTable.table[func].variablesCount)] - + currentClass = Class(functionsTable,varsTable,variablesCount) if name in self.table: return Error("Class already declared") else: self.table[name] = currentClass return None - + def search(self,name): if name in self.table: return self.table[name], None diff --git a/Function.py b/Function.py index 6b82423..5a8b1b4 100644 --- a/Function.py +++ b/Function.py @@ -1,3 +1,4 @@ +#clase de objeto de funcion from VarsTable import VarsTable class Function: diff --git a/FunctionsTable.py b/FunctionsTable.py index 20316d0..5af25f6 100644 --- a/FunctionsTable.py +++ b/FunctionsTable.py @@ -1,3 +1,4 @@ +#tabla de funciones from Function import Function from Error import Error from VarsTable import VarsTable @@ -5,12 +6,12 @@ class FunctionsTable: def __init__(self): self.table = {} - + #añadir funcion si es que aun no existe en la tabla con sus cantidad de temporales y variables necesarias para su llamada a memoria def add(self,name,type,parameters,varsTable,quadrupleStart, tempTable=[]): if name in self.table: print(f"Function {name} already declared") exit() - + # I,F,C,B variablesCount = [0,0,0,0] for var in varsTable.table: diff --git a/MemoryManager.py b/MemoryManager.py index ab5e415..0f1c81e 100644 --- a/MemoryManager.py +++ b/MemoryManager.py @@ -1,5 +1,7 @@ +#Memory manager es donde guardamos una pila de memorias y donde podemos crear una memoria apartir de VirtualMemory from VirtualMemory import VirtualMemory - +#se inicia una memoria global solo una ya que solo puede existir una al igual que de constantes +#una pila de memorias locales ya que puede ir a "dormir" alguna de ellas en el transcurso del programa class MemoryManager(): def __init__(self): self.global_memory = None @@ -13,22 +15,23 @@ def __init__(self): - + #aqui es donde creamos una memoria global def initGlobalMemory(self, size, scope): self.global_memory = VirtualMemory(size, scope) - + #aqui es donde creamos una memoria de constantes def initConstantsMemory(self, size, scope): self.constants_memory = VirtualMemory(size, scope) - + #aqui es donde creamos una memoria local y como podemos tener varias, se hace un push a la pila de memorias locales def initLocalMemory(self, size, scope): self.local_memories.append(VirtualMemory(size, scope)) - + #una vez finalizada su uso se saca de la pila, se destruye esa memoria ya que no podemos tener 2 funciones corriendo a la vez def destroyLocalMemory(self): self.local_memories.pop() - + #con la direccion de memoria como uno de los parametros y el valor que se añade, dependiendo del rango se agrega en la memoria + #global,local,constantes o pointers def add(self, address, value): address = int(address) if address>= self.global_range[0] and address <= self.global_range[1]: @@ -47,7 +50,7 @@ def add(self, address, value): self.local_memories[-1].add(address, value) - + #al hacer get se hace get del valor dependiendo igualmente del rango es a donde va a buscar def get(self, address): address = int(address) diff --git a/Parameter.py b/Parameter.py index 77c94e6..c74274c 100644 --- a/Parameter.py +++ b/Parameter.py @@ -1,4 +1,5 @@ +#objeto parametro class Parameter: def __init__(self, type, id): self.type = type - self.id = id \ No newline at end of file + self.id = id diff --git a/Program.py b/Program.py index 452c4e8..79fc35a 100644 --- a/Program.py +++ b/Program.py @@ -1,3 +1,4 @@ +#clase programa que programa tiene tabla de funciones y las funciones a su vez tienen tablas de variables class Program: def __init__(self, classesTable, varsTable, functionsTable): self.classesTable = classesTable @@ -8,7 +9,7 @@ def __init__(self, classesTable, varsTable, functionsTable): for func in functionsTable.table: self.variablesCount = [sum(x) for x in zip(self.variablesCount, functionsTable.table[func].variablesCount)] - # for var in varsTable = + # for var in varsTable = def toString(self): print("---------- Program ----------") diff --git a/QuadruplesList.py b/QuadruplesList.py index c4651a3..e85e86d 100644 --- a/QuadruplesList.py +++ b/QuadruplesList.py @@ -4,6 +4,7 @@ class QuadruplesList: def __init__(self): + #creacion de todas las pilas necesarias para la manipulacion de cuadruplos self.operatorsStack = [] self.typesStack = [] self.operandsStack = [] @@ -11,6 +12,7 @@ def __init__(self): self.jumpsStack = [] self.quadruples = [] + #pila de variables controladas y variables finales, es decir para el ciclo for self.controlledVar=[] self.finalVars=[] @@ -18,6 +20,7 @@ def __init__(self): self.cont = 1 #siempre al cuadruplo siguiente self.temporals = 1 #t1--tn + #contador de temporales para cuadruplos self.counter_tInt = 0 self.counter_tFloat = 0 self.counter_tChar = 0 @@ -26,6 +29,7 @@ def __init__(self): self.scope = "LOCAL" + #temporales globales con sus rangos para aumentar la direccion base a los contadores if self.scope == "GLOBAL": self.TI = [5000,5999] self.TF = [6000,6999] @@ -34,7 +38,7 @@ def __init__(self): self.TP = [30000,30999] - + #temporales locales con sus rangos para aumentar la direccion base a los contadores elif self.scope == "LOCAL": self.TI = [14000, 14999] self.TF = [15000, 15999] @@ -42,18 +46,18 @@ def __init__(self): self.TB = [17000, 17999] self.TP = [31000,31999] - + #generar cuadruplo gotoMain def generateGoToMainQuad(self): current_quadruple= Quadruple('goto','','',None) self.quadruples.append(current_quadruple) self.jumpsStack.append(self.cont) self.cont +=1 - + #rellena el cuadruplo gotoMain poppeando de la pila de saltos def fillGoToMainQuad(self): self.quadruples[self.jumpsStack.pop()-1].temporal=self.cont - + #añade un nuevo cuadruplo y esta es la adición mas general, ya que tiene temporal y dependiendo del tipo de temporal se asigna de acuerdo a la dirBase y a los contadores def addQuadruple(self,operator,leftOperand,rightOperand,temporal, typeTemp): - current_temp_memory_address = 0 + current_temp_memory_address = 0 #si no es una asignacion tiene un temporal nuevo asi que se debe checar el tipo y asignar temporaless if typeTemp == "int": if operator != "=" : current_temp_memory_address = self.TI[0] + self.counter_tInt @@ -79,62 +83,67 @@ def addQuadruple(self,operator,leftOperand,rightOperand,temporal, typeTemp): else: current_quadruple= Quadruple(operator,leftOperand,rightOperand,temporal) + #se mete el cuadruplo generado a la pila de operadores self.quadruples.append(current_quadruple) if current_quadruple.operator != "=" : - + #si no es una asignación se pushea el temporal y su tipos self.temporals +=1 self.operandsStack.append(current_temp_memory_address) self.typesStack.append(typeTemp) - + #se aumenta el numero de cuadruplos que hay self.cont +=1 if current_quadruple.operator != "=" : return typeTemp - #if else + #if else con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleCondition(self,operator,leftOperand,rightOperand,temporal): current_quadruple= Quadruple(operator,leftOperand,rightOperand,temporal) self.quadruples.append(current_quadruple) self.cont +=1 - #readWrite + #readWrite con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleReadWrite(self,operator,leftOperand,rightOperand,temporal): current_quadruple= Quadruple(operator,leftOperand,rightOperand,temporal) self.quadruples.append(current_quadruple) self.cont +=1 - #añade cuadruplo para ciclos while goto y gotof y for + #añade cuadruplo para ciclos while goto y gotof y for y se añade a la pila de cuadruplos y aumenta contador def addQuadrupleCycles(self,operator,leftOperand,rightOperand,temporal): current_quadruple= Quadruple(operator,leftOperand,rightOperand,temporal) self.quadruples.append(current_quadruple) self.cont +=1 - + #genera cuadruplo ENDFUNC con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos + # y tambien se añade el contador de cuadruplo para saber en que cuadruplo termina def addQuadrupleEndFuncModule(self): current_quadruple= Quadruple('ENDFUNC','','','') self.quadruples.append(current_quadruple) self.endFuncQuads.append(self.cont) self.cont +=1 - + #genera cuadruplo ERA con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleERAFuncCall(self,funcName): current_quadruple= Quadruple('ERA',funcName,'','') self.quadruples.append(current_quadruple) self.cont +=1 - + #genera cuadruplo goSUB con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleGoSubFuncCall(self,funcName,initialQuad): current_quadruple= Quadruple('goSub',funcName,'',initialQuad) self.quadruples.append(current_quadruple) self.cont +=1 + #genera cuadruplo param con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleParamFuncCall(self,paramName,paramNumber): current_quadruple= Quadruple('param',paramName,'',paramNumber) self.quadruples.append(current_quadruple) self.cont +=1 - + #genera cuadruplo verify con el cual solo se aumenta el contador de cuadruplos y se añade a la pila de cuadruplos def addQuadrupleVerifyArray(self,exp,LIdim,LSdim): current_quadruple= Quadruple('verify',exp,LIdim,LSdim) self.quadruples.append(current_quadruple) self.cont +=1 - + #checa si el tope de la pila de operandos es + o - para resolver + #hace pop de pila de operadores para el izq y derecho, junto con sus tipos + #se hace pop de la pila de operandos para saber cual de los 2 simbolos es def checkOperatorPlusMinus(self): if len(self.operatorsStack) != 0: if self.operatorsStack[-1] == "+" or self.operatorsStack[-1] == "-": @@ -145,7 +154,7 @@ def checkOperatorPlusMinus(self): RType = self.typesStack.pop() LType = self.typesStack.pop() - typeTemp, err = semanticCube.semantic(RType, LType, operator) + typeTemp, err = semanticCube.semantic(RType, LType, operator) #cubo semantico para saber si el "baila mija con el señor" if err != None: print(f"Type miss match between in plus/minus {LOperand} ({LType}) and {Roperand} ({RType})") exit() @@ -153,7 +162,9 @@ def checkOperatorPlusMinus(self): - + #checa si el tope de la pila de operandos es * o / para resolver + #hace pop de pila de operadores para el izq y derecho, junto con sus tipos + #se hace pop de la pila de operandos para saber cual de los 2 simbolos es def checkOperatorTimesDivide(self): if len(self.operatorsStack) != 0: if self.operatorsStack[-1] == "*" or self.operatorsStack[-1] == "/": @@ -164,13 +175,15 @@ def checkOperatorTimesDivide(self): RType = self.typesStack.pop() LType = self.typesStack.pop() - typeTemp, err = semanticCube.semantic(RType, LType, operator) + typeTemp, err = semanticCube.semantic(RType, LType, operator) #"¿baila mija con el señor?" if err != None: print(f"Type miss match between {LOperand} ({LType}) and {Roperand} ({RType})") exit() - #print(f"{LOperand} ({LType}) and {Roperand} ({RType})") - return self.addQuadruple(operator,LOperand,Roperand,temporal, typeTemp) + return self.addQuadruple(operator,LOperand,Roperand,temporal, typeTemp) + #checa si el tope de la pila de operandos es = para resolver + #hace pop de pila de operadores para el izq y derecho, junto con sus tipos para saber a cual se le asigna a cual + #se hace pop de la pila de operandos para sacar el = def makeAssignationResult(self): if len(self.operatorsStack) != 0: if self.operatorsStack[-1] == "=": @@ -191,7 +204,9 @@ def makeAssignationResult(self): - + #checa si el tope de la pila de operandos es alguno de los operadores de s_exp para resolver + #hace pop de pila de operadores para el izq y derecho, junto con sus tipos para si se pueden combinar en una exp + #se hace pop de la pila de operandos para sacar el operador correspondiente def generate_sExp_quad(self,leftOperator): listOperandsSexp = ["<",">","<=",">=","<>","=="] if len(self.operatorsStack) != 0: @@ -204,13 +219,17 @@ def generate_sExp_quad(self,leftOperator): RType = self.typesStack.pop() LType = self.typesStack.pop() - typeTemp, err = semanticCube.semantic(RType, LType, operator) + typeTemp, err = semanticCube.semantic(RType, LType, operator) #"¿baila mija con el señor?" if err != None: print(f"Type miss match between {LOperand} ({LType}) and {ROperand} ({RType})") exit() return self.addQuadruple(operator,LOperand,ROperand,temporal, typeTemp) + + #checa si el tope de la pila de operandos es alguno de los operadores de h_exp para resolver + #hace pop de pila de operadores para el izq y derecho, junto con sus tipos para si se pueden combinar en una exp + #se hace pop de la pila de operandos para sacar el operador correspondiente def generate_hExp_quad(self,leftOperator): listOperandsHexp = ["&&","||"] if len(self.operatorsStack) != 0: @@ -222,7 +241,7 @@ def generate_hExp_quad(self,leftOperator): RType = self.typesStack.pop() LType = self.typesStack.pop() - typeTemp, err = semanticCube.semantic(RType, LType, operator) + typeTemp, err = semanticCube.semantic(RType, LType, operator) #¿baila mija con el señor? if err != None: print(f"Type miss match between {LOperand} ({LType}) and {ROperand} ({RType})") exit() @@ -231,22 +250,24 @@ def generate_hExp_quad(self,leftOperator): #######################fondo falso####################### + #elimina el fondo falso haciendo pop de pila de operadores para sacar el ( def eliminateFakeVoid(self): self.operatorsStack.pop() ######################condition########################## + #genera gotoF, si no es de tipo bool entonces no se puede evaluar el condicional def generateGoToFCondition(self): if self.typesStack.pop() != "bool": print(f"Conditional not bool") exit() - condition = self.operandsStack.pop() + condition = self.operandsStack.pop() #hacer pop de pila de operadores para saber que se va a evaluar self.addQuadrupleCondition("gotoF",condition,'',None) - self.jumpsStack.append(self.cont-1) - + self.jumpsStack.append(self.cont-1) #pushear a pila de saltos para despues volver a rellenar + #rellenar gotoF haciendo pop de la pila de saltos def fillgotoF_IF(self): self.quadruples[self.jumpsStack.pop()-1].temporal=self.cont - + #generar goto y meter en pila de saltos y rellenar gotoF ya que esto viene si hay un else def generateGoToCondition(self): false = self.jumpsStack.pop() self.addQuadrupleCondition("goto",'','',None) @@ -254,12 +275,15 @@ def generateGoToCondition(self): self.quadruples[false-1].temporal=self.cont ######################while########################## + #genera gotoF de while def generateGoToFWhile(self): condition = self.operandsStack.pop() #tipos self.addQuadrupleCycles("gotoF",condition,'',None) - self.jumpsStack.append(self.cont-1) + self.jumpsStack.append(self.cont-1) #pushear a pila de saltos para despues volver a rellenar + #generar goto y rellenar gotoF ya que de aqui seguiria el cuadruplo fuera del while y hacemos doble pop en pila de saltos + #uno para rellenar el gotoF con cont y retorno para saber a que cuadruplo regresar para volver a evaluar exp de while def generateGoToWhile(self): false = self.jumpsStack.pop() retorno = self.jumpsStack.pop() @@ -283,26 +307,27 @@ def generateVControlQuadruple(self): controlType= self.typesStack[-1] current_temp_memory_address = 0 #tipos con semantica - + # ver si se puede asignar el tipo del id a asignar y la exp que se le quiere asignar typeTemp, err = semanticCube.semantic(expType, controlType, "=") if err != None: print(f"Type miss match between for assignation") exit() - + #crear cuadruplo para asignar a la que sera variable de control quad=Quadruple("=",exp,'',Vcontrol) self.quadruples.append(quad) self.cont+=1 + #checar su tipo para saber que temporal usar con direccion base if expType == "int": current_temp_memory_address = self.TI[0] + self.counter_tInt self.counter_tInt+=1 elif expType == "float": current_temp_memory_address = self.TF[0] + self.counter_tFloat self.counter_tFloat+=1 - + #agregar la variable de control a un temporal para saber cual es y poder acceder a ella quad=Quadruple("=",Vcontrol,'',current_temp_memory_address) self.quadruples.append(quad) self.cont+=1 - + # y para poder acceder a la variabel de control se coloca en una pila de variables controladas self.controlledVar.append(self.quadruples[-1].temporal) def generateVFinalQuadruple(self): @@ -345,9 +370,12 @@ def forChangeVC(self,oneConstant): elif self.typesStack[-1] == "float": current_temp_memory_address = self.TF[0] + self.counter_tFloat self.counter_tFloat+=1 + #despues de checar el tipo de variable que es la variable de control se le suma uno para que siga el ciclo for y dejarlo en el temporal correcto self.addQuadrupleCycles("+",self.controlledVar[-1],oneConstant,current_temp_memory_address) + #despues iguala dicho resultado del temporal a la variable de control para que se cumpla que vaya sumando de 1 en 1 self.addQuadrupleCycles("=",current_temp_memory_address,'',self.controlledVar[-1]) self.addQuadrupleCycles("=",current_temp_memory_address,'',self.operandsStack[-1]) + #hace pop en pila de saltos 2 veces, el primero para rellenar gotoF afuera del ciclo y el siguiente es para saber el cuadruplo que hay que regresar generando un goTo FIN = self.jumpsStack.pop() Retorno = self.jumpsStack.pop() self.addQuadrupleCycles("goto",'','',Retorno) @@ -358,20 +386,24 @@ def forChangeVC(self,oneConstant): self.typesStack.pop() #######################funciones####################### + #generar cuadruplo ENDFUNC def generateEndFuncModule(self): self.addQuadrupleEndFuncModule() + #generar cuadruplo ERA con el nombre de la funcion def generateERAFuncCall(self,funcName): self.addQuadrupleERAFuncCall(funcName) - + #generar cuadruplo goSub con el nombre de la funcion y su cuaddruplo inicial def generateGoSubFuncCall(self,funcName,initialQuad): self.addQuadrupleGoSubFuncCall(funcName,initialQuad) + #generar cuadruplo de RETURN def generateFuncReturnQuad(self,funcName): operator="Ret" exp=self.operandsStack.pop() type=self.typesStack.pop() self.addQuadruple(operator,funcName,'',exp, type) + # cuadruplo para generar igualación de variable de retorno a un temporal para poder usar en operaciones futuras def assignGlobalFuncCall(self,varGlobal,typeVar): current_temp_address = 0 if typeVar == "int": @@ -421,12 +453,13 @@ def typeStackToString(self): for type in self.typesStack: print(f"{type}") ###################### Temporals management ###################### + #reinicio de temporales que se llama despues del fin de la funcion def resetTemporalsCounter(self): self.counter_tInt = 0 self.counter_tFloat = 0 self.counter_tChar = 0 self.counter_tBool = 0 - + #cambio de scope locales de temporales a globales def changeScope(self): self.TI = [5000,5999] self.TF = [6000,6999] diff --git a/SemanticCube.py b/SemanticCube.py index 676bac5..836463e 100644 --- a/SemanticCube.py +++ b/SemanticCube.py @@ -1,3 +1,4 @@ +#cubo semantico para saber quien puede "bailar" con quien y con que operador y que tipo genera dicha operacion from Error import Error diff --git a/Var.py b/Var.py index fd0b8ba..2a0092c 100644 --- a/Var.py +++ b/Var.py @@ -1,3 +1,4 @@ +#clase de objeto variable class Var: def __init__(self, type, scope, address,dim): self.type = type diff --git a/VarsTable.py b/VarsTable.py index be6a81e..7b5d474 100644 --- a/VarsTable.py +++ b/VarsTable.py @@ -1,3 +1,4 @@ +#tabla de variables from Var import Var from Error import Error from Var import Var diff --git a/VirtualMemory.py b/VirtualMemory.py index c7f8be8..1a974c1 100644 --- a/VirtualMemory.py +++ b/VirtualMemory.py @@ -1,7 +1,9 @@ class VirtualMemory(): def __init__(self, size, scope): self.scope = scope - + #mapeo de memoria que se trato de realizar de la manera mas general posible + #dependiendo si el scope es global o local, los rangos de memoria cambian + #tanto para variables como temporales if scope == "GLOBAL" : self.I = [1000, 1999] self.F = [2000, 2999] @@ -24,13 +26,14 @@ def __init__(self, size, scope): self.CT = [16000, 16999] self.BT = [17000, 17999] self.PT = [31000,31999] - + #rango de direcciones virtuales constantes elif scope == "CONSTANTS": self.I = [18000, 18999] self.F = [19000, 19999] self.C = [20000, 20999] self.B = [21000, 21999] - + #dependiendo de cualquiera de los scopes se crea la memoria con arreglos de temporales y locales + #con el tamaño de cada uno de los espacios con valor none inicial if scope == "GLOBAL" or scope == "LOCAL": self.m_int = [None] * size[0] self.m_float = [None] * size[1] @@ -40,23 +43,22 @@ def __init__(self, size, scope): self.m_tFloat = [None] * size[5] self.m_tChar = [None] * size[6] self.m_tBool = [None] * size[7] - + #igualmente dependiendo del tamaño de cada uno de los locales constantes se crean sus arreglos respectivos elif scope == "CONSTANTS": self.m_int = [None] * size[0] self.m_float = [None] * size[1] self.m_char = [None] * size[2] self.m_bool = [None] * size[3] - + #fuera de todo siempre se crean los temporales pointer que pueden estar localmente o globalmente self.m_PT = [None] * 1000 - #meter fuera de los ifs los temporal pointers y colocar - #self.m_tp = none *size + + #metodo add con el cual dependiendo del rango en el que este la direccion, se añade al arreglo correspondiente de memorias + # en el cual dependiendo de en cual caiga, se le resta la direccion base def add(self, address, value): - #print("----->", address) address = int(address) - + #rangos de locales de cada tipo if address>= self.I[0] and address <= self.I[1]: - #print("ddddddd",address - self.I[0]) self.m_int[address - self.I[0]] = value elif address>= self.F[0] and address <= self.F[1]: @@ -68,6 +70,7 @@ def add(self, address, value): elif address>= self.B[0] and address <= self.B[1]: self.m_bool[address - self.B[0]] = value + #rangos de temporales que deben de estar en el rango de direccion y que no sean direcciones constantes elif address>= self.IT[0] and address <= self.IT[1] and self.scope != "CONSTANTS": self.m_tInt[address - self.IT[0]] = value @@ -82,17 +85,15 @@ def add(self, address, value): self.m_tBool[address - self.BT[0]] = value elif address>= self.PT[0] and address <= self.PT[1] and self.scope != "CONSTANTS": - # print("bbbbbb", [value, type(value), address]) if type(value) == str: jump = self.m_PT[address - self.PT[0]] self.add(jump, value) - #print("add11", self.m_int) else: self.m_PT[address - self.PT[0]] = value - # print("add12", [address, value, self.m_PT]) - + #igualmente dependiendo del rango de direccion en el que este, se accede a la casilla del arreglo + #restandole la direccion base se llega a esa direccion de memoria que estamos buscando su valor def get(self, address): address = int(address) @@ -121,42 +122,5 @@ def get(self, address): return self.m_tBool[address - self.BT[0]] elif address>= self.PT[0] and address <= self.PT[1] and self.scope != "CONSTANTS": - # print("gettttt1", [address, self.get(self.m_PT[address - self.PT[0]])]) - #print("gettttt2", self.get(self.m_PT[address - self.PT[0]]) - - + #el unico caso donde se hace un doble salto es en temporal pointer ya que los temporales pointer almacenan una direccion de memoria return self.get(self.m_PT[address - self.PT[0]]) - - - - - - - - - - - - - - - # LI_BA = [5000, 5999] - # LF_BA = [6000, 6999] - # LC_BA = [7000, 7999] - # LB_BA = [8000, 8999] - - # TI_BA = [9000, 9999] - # TF_BA = [10000, 10999] - # TC_BA = [11000, 11999] - # TB_BA = [12000, 12999] - - - -# memory -# variables -# temp - -# localMemoriesPile = [] - -# global = memory() -# loccal = memory() diff --git a/main.py b/main.py index 7115f06..18c746e 100644 --- a/main.py +++ b/main.py @@ -673,7 +673,7 @@ def p_np_save_var(p): if global_memory_counter_flag: #si es global con esta bandera se verifica - + #variables para los contadores de memoria global global current_var_type global global_memory_counter_int global global_memory_counter_float @@ -697,12 +697,13 @@ def p_np_save_var(p): global_memory_counter_bool += 1 + varAddDimensional else: #de lo contrario se hace lo mismo pero con contadores y direcciones base locales + #variables para los contadores de memoria local global local_memory_counter_int global local_memory_counter_float global local_memory_counter_char global local_memory_counter_bool - + #dependiendo del tipo de variable se le suma la dirección base y se aumenta el contador local de ese tipo de variable if current_var_type == "int": current_varsTable.add(current_var_name, current_var_type, current_var_scope, LI[0] + local_memory_counter_int,DIM) local_memory_counter_int += 1 @@ -980,13 +981,15 @@ def p_np_push_operator_hexp(p): global operPush operPush = p[-1] quadrupleList.operatorsStack.append(operPush) -#definir operando izquierdo de s_exp +#definir operando izquierdo de s_exp es decir Loperand < ROperand como ejemplo def p_np_define_LOperand_sexp(p): ''' np_define_LOperand_sexp : empty ''' global LOperandSexp LOperandSexp = quadrupleList.operandsStack.pop() + +#definir operando derecho de s_exp es decir Loperand < ROperand como ejemplo def p_np_define_ROperand_sexp(p): ''' np_define_ROperand_sexp : empty @@ -994,12 +997,15 @@ def p_np_define_ROperand_sexp(p): temporalType = quadrupleList.generate_sExp_quad(LOperandSexp) registerTempVariable(temporalType) +#definir operando izquierdo de h_exp es decir Loperand && ROperand como ejemplo def p_np_define_LOperand_hexp(p): ''' np_define_LOperand_hexp : empty ''' global LOperandHexp LOperandHexp = quadrupleList.operandsStack.pop() + +#definir operando derecho de h_exp es decir Loperand && ROperand como ejemplo def p_np_define_ROperand_hexp(p): ''' np_define_ROperand_hexp : empty @@ -1010,6 +1016,8 @@ def p_np_define_ROperand_hexp(p): #############################if############################# + +#Crear cuadruplo sinn saber aun a donde ir de gotoF para despues de evaluar exp del parentesis de if def p_np_generate_gotoF_condition(p): ''' np_generate_gotoF_condition : empty @@ -1017,14 +1025,14 @@ def p_np_generate_gotoF_condition(p): quadrupleList.generateGoToFCondition() -#fill de condicion if sola +#fill de gotoF de condicion if def p_np_fill_gotoF_condition_if(p): ''' np_fill_gotoF_condition_if : empty ''' quadrupleList.fillgotoF_IF() -#else +#generar goto despues de encontrar un else def p_np_generate_goto_condition(p): ''' np_generate_goto_condition : empty @@ -1035,7 +1043,7 @@ def p_np_generate_goto_condition(p): #############################write############################# - +#pushear letrero a pila de operadores def p_np_push_signboard(p): ''' np_push_signboard : empty @@ -1044,7 +1052,7 @@ def p_np_push_signboard(p): oper=p[-1] quadrupleList.operandsStack.append(oper) - +#generar cuadruplo write con el pop de pilaOperadores def p_np_generate_write_quadruple(p): ''' np_generate_write_quadruple : empty @@ -1055,6 +1063,7 @@ def p_np_generate_write_quadruple(p): #############################write############################# #############################read############################# +#generar cuadruplo read con operando que viene antes def p_np_generate_read_quadruple(p): ''' np_generate_read_quadruple : empty @@ -1077,12 +1086,14 @@ def p_np_generate_read_quadruple(p): #############################read############################# #############################while############################# +#pushear actual cuadruplo a la pila de saltos para regresar despues para llenarlo def p_np_while_push_jumpStack(p): ''' np_while_push_jumpStack : empty ''' quadrupleList.jumpsStack.append(quadrupleList.cont) +#generar gotoF despues de while def p_np_while_generate_gotoF(p): ''' @@ -1091,6 +1102,7 @@ def p_np_while_generate_gotoF(p): quadrupleList.generateGoToFWhile() +#generar goto para regresar a inicio de evaluacion de exp de while def p_np_while_generate_goto(p): ''' np_while_generate_goto : empty @@ -1101,6 +1113,7 @@ def p_np_while_generate_goto(p): #############################for############################# +#pushear la variable a la que se le va asignar una exp para saber si ya esta declarada def p_np_for_push_id(p): ''' np_for_push_id : empty @@ -1133,19 +1146,21 @@ def p_np_for_push_id(p): print(f"Variable {idPush} not declared") exit() - +#resolver la primera exp a la cual vamos a asignar al id anterior y asignarlo como la VC def p_np_for_FIRSTexp(p): ''' np_for_FIRSTexp : empty ''' quadrupleList.generateVControlQuadruple() +#resolver la exp que va despues de TO para saber hasta donde se tiene que llegar def p_np_for_SECONDexp(p): ''' np_for_SECONDexp : empty ''' quadrupleList.generateVFinalQuadruple() +#hacer el cambio en la variable de control del for def p_np_for_changesVC(p): ''' np_for_changesVC : empty @@ -1155,6 +1170,7 @@ def p_np_for_changesVC(p): #############################for############################# #############################functions call############################# +#checar que el id antes de () exista para saber si la funcion existe en la tabla de funciones def p_np_check_func_exists(p): ''' np_check_func_exists : empty @@ -1172,6 +1188,7 @@ def p_np_check_func_exists(p): global parameter_counter parameter_counter = 0 +#checar la cantidad de parametros respecto a los que tenemos en lista para saber si coincide el numero def p_np_check_func_params(p): ''' np_check_func_params : empty @@ -1192,7 +1209,7 @@ def p_np_check_func_params(p): del globals()["parameter_counter"] - +#aumentar el numero de parametros que se llevan en la llamada es decir cada que encuentre un parametro en la llamada aumenta el contador def p_np_check_func_params_counter(p): ''' np_check_func_params_counter : empty @@ -1200,7 +1217,7 @@ def p_np_check_func_params_counter(p): global parameter_counter parameter_counter +=1 - +#despues de declarar una clase se verifica que no este duplicada def p_np_check_class_exists(p): ''' np_check_class_exists : empty @@ -1210,7 +1227,7 @@ def p_np_check_class_exists(p): print(f"Class {className} already exists") exit() - +#se crea el arreglo con la cantidad de temporales de una funcion para llevar su conteo def p_np_init_func_tempTable(p): ''' np_init_func_tempTable : empty @@ -1218,13 +1235,14 @@ def p_np_init_func_tempTable(p): global current_funcTempTable current_funcTempTable = [0,0,0,0] +#hacer pop de la pila de tabla de variables para destruirla despues de su uso def p_np_pop_varsTable(p): ''' np_pop_varsTable : empty ''' varsTablesPile.pop(-1) ############ Helper Functions ############ - +#aumentar el contador de cada tipo de temporal para irlo registrando en la lista de cantidad de temporales que ocupa una funcion def registerTempVariable(tempType): @@ -1242,25 +1260,28 @@ def registerTempVariable(tempType): current_funcTempTable[3]+=1 ######################Quadruples function call Amauri################ +#generar cuadruplo de ENDFUNC despues del final de una funcion def p_np_generate_endfunc_quad(p): ''' np_generate_endfunc_quad : empty ''' quadrupleList.generateEndFuncModule() +#generar cuadruplo ERA de la llamada def p_np_generate_ERA_quad_func_call(p): ''' np_generate_ERA_quad_func_call : empty ''' quadrupleList.generateERAFuncCall(idVerify) +#generar cuadruplo de goSub del id de llamada y con su cuadruplo de inicio def p_np_generate_goSub_function_call(p): ''' np_generate_goSub_function_call : empty ''' quadrupleList.generateGoSubFuncCall(idVerify,current_functionsTable.table[idVerify].quadrupleStart) - +#generar cuadruplo RET ya que en todas nuestras funciones tienen RET def p_np_generate_return_func(p): ''' np_generate_return_func : empty @@ -1268,6 +1289,7 @@ def p_np_generate_return_func(p): quadrupleList.generateFuncReturnQuad(current_func_name) +#despues de pasar por una función si es que se llama se asigna el valor de la variable que se encuentra en variables globales, asignar su valor nuevo en un temporal para futuras operacioes def p_np_assign_global_to_temporal_func_call(p): ''' np_assign_global_to_temporal_func_call : empty @@ -1279,7 +1301,7 @@ def p_np_assign_global_to_temporal_func_call(p): #########################################Memory################################################## - +#iniciar los contadores de memoria global para al contador al declarar una variable sumarle su direccion base correspondientes def p_np_start_global_memory_counter(p): ''' np_start_global_memory_counter : empty @@ -1307,7 +1329,7 @@ def p_np_start_global_memory_counter(p): quadrupleList.resetTemporalsCounter() - +#iniciar los contadores de memoria local para al contador al declarar una variable sumarle su direccion base correspondientes def p_np_start_local_memory_counter(p): ''' np_start_local_memory_counter : empty @@ -1324,14 +1346,14 @@ def p_np_start_local_memory_counter(p): global local_memory_counter_bool local_memory_counter_bool = 0 - +#despues de acabar con las variables globales se detiene el contador de globales para usar ahora los contadores de locales def p_np_stop_global_memory_counter(p): ''' np_stop_global_memory_counter : empty ''' global global_memory_counter_flag global_memory_counter_flag = False - +#generar cuadruplo por cada parametro en llamada a funcion def p_np_generate_quad_parameter(p): ''' np_generate_quad_parameter : empty @@ -1340,7 +1362,7 @@ def p_np_generate_quad_parameter(p): paramPop = quadrupleList.operandsStack.pop() quadrupleList.addQuadrupleParamFuncCall(paramPop,parameter_counter) ########################################################################################### - +#rellenar cuadruplo de goto a main def p_np_fill_goto_main_quad(p): ''' np_fill_goto_main_quad : empty @@ -1348,6 +1370,7 @@ def p_np_fill_goto_main_quad(p): quadrupleList.fillGoToMainQuad() ############Constants############ +#guardar constante def p_np_saveConstantI(p): ''' np_saveConstantI : empty @@ -1358,7 +1381,7 @@ def p_np_saveConstantI(p): if constant not in constantsTable: constantsTable[constant] = CI[0] + ci_counter ci_counter += 1 - +#guardar constante flotante def p_np_saveConstantF(p): ''' np_saveConstantF : empty @@ -1374,13 +1397,15 @@ def p_np_saveConstantF(p): ###########################arrays########################### +# en esta parte se crean los cuadruplos para variables dimensionadas def p_np_create_dimensional_quads(p): ''' np_create_dimensional_quads : empty ''' + #bool para saber si es una variable global para saber si buscar en tabla actual o en la primer tabla de variables global isGlobalDimensional isGlobalDimensional =False - + #bool para saber si es un arreglo si es falso, significa que es una matriz global isArrayCall isArrayCall = True @@ -1388,10 +1413,10 @@ def p_np_create_dimensional_quads(p): - ## sacar el limite superior + ## sacar el limite superior de variable global idArray idArray = quadrupleList.dimensionalOperandsStack[-1] - + # se saca el limite superior para las operaciones y se checa si es un arreglo o matriz y si es global o no la variable para saber donde buscar exactamente if idArray in current_varsTable.table: Lsuperior= current_varsTable.table[idArray].dim[DIMid-1] @@ -1410,14 +1435,15 @@ def p_np_create_dimensional_quads(p): addConstantsTable(Lsuperior) - + #generarr cuadruplo de verify para saber si esta dentro del limite del arreglo quadrupleList.addQuadrupleVerifyArray(quadrupleList.operandsStack[-1],constantsTable[0],constantsTable[Lsuperior]) - + #si la dimension es 1 y no es un arreglo, significa que primero se debe multiplicar por d2 porque es una matriz if DIMid == 1 and not isArrayCall: aux= quadrupleList.operandsStack.pop() type= quadrupleList.typesStack.pop() + #y se checa si es una variable global o local y dependiendo de eso es donde se busca if isGlobalDimensional: addConstantsTable(varsTablesPile[0].table[quadrupleList.dimensionalOperandsStack[-1]].dim[DIMid-1]+1) quadrupleList.addQuadruple("*",aux,constantsTable[varsTablesPile[0].table[quadrupleList.dimensionalOperandsStack[-1]].dim[DIMid-1]+1],0,type) @@ -1425,7 +1451,7 @@ def p_np_create_dimensional_quads(p): addConstantsTable(current_varsTable.table[quadrupleList.dimensionalOperandsStack[-1]].dim[DIMid-1]+1) quadrupleList.addQuadruple("*",aux,constantsTable[current_varsTable.table[quadrupleList.dimensionalOperandsStack[-1]].dim[DIMid-1]+1],0,type) - + #despues de eso se debe sumar s2 con el temporal anterior que es s1*d2 if DIMid>1: aux2= quadrupleList.operandsStack.pop() type2= quadrupleList.typesStack.pop() @@ -1434,7 +1460,7 @@ def p_np_create_dimensional_quads(p): typeSC, err = semanticCube.semantic(type1, type2, "+") quadrupleList.addQuadruple("+",aux1,aux2,0,typeSC) - +#se aumenta la dimension despues de encontrarse que hay un indice extra es decir, que es matriz def p_np_DIM_plus(p): ''' np_DIM_plus : empty @@ -1442,7 +1468,7 @@ def p_np_DIM_plus(p): global DIMid DIMid=DIMid+1 - +#suma la dirección base que es la operacion final y se busca la dirección base de la variable en la tabla de variables def p_np_sum_baseA_array(p): ''' np_sum_baseA_array : empty @@ -1458,36 +1484,38 @@ def p_np_sum_baseA_array(p): addConstantsTable(baseAdd) - + # se crea el cuadruplo de suma de direccion base y se almacena en un temporal pointer quadrupleList.addQuadruple("+",quadrupleList.operandsStack.pop(),constantsTable[baseAdd],0,"pointer") quadrupleList.typesStack.pop() quadrupleList.eliminateFakeVoid() ###########################arrays########################### ############################################################ - +# se resetea el contador de temporales despues de cada funcion def p_np_reset_temp_counter(p): ''' np_reset_temp_counter : empty ''' quadrupleList.resetTemporalsCounter() - +# se cambia el scope de las variables para saber si es global o local def p_np_set_temp_global_flag(p): ''' np_set_temp_global_flag : empty ''' quadrupleList.changeScope() ############################################################ - +#se parsea con yacc parser = yacc() -f = open('arithmetic_exp_TC.c', 'r') - +#archivo en donde esta todo nuestro codigo +f = open('matrixMultiplications.c', 'r') +# se lee el archivo y se hace parse content = f.read() case_correct_01 = parser.parse(content) +#en esta sección se mete al ovejota: constantes y sus direcciones, cuadruplos y todas las funciones f = open("ovejota.txt","w+") for key in constantsTable: f.write(f"{key}|{constantsTable[key]},") @@ -1520,4 +1548,4 @@ def p_np_set_temp_global_flag(p): -#program.toString() +program.toString() diff --git a/ovejota.txt b/ovejota.txt index 04b8f58..5c412b2 100644 --- a/ovejota.txt +++ b/ovejota.txt @@ -1,43 +1,56 @@ -0|18000,5|18001,6|18002,1007|18003,10|18004,1|18005, +0|18000,3|18001,4|18002,1004|18003,9|18004,1013|18005,1022|18006,1|18007, goto,,,2 =,18000,,1000 =,18000,,1001 =,18001,,1002 +=,18001,,1003 <,1000,1002,8000 -gotoF,8000,,22 +gotoF,8000,,52 <,1001,1002,8001 -gotoF,8001,,18 +gotoF,8001,,48 verify,1000,18000,18001 *,1000,18002,5000 verify,1001,18000,18001 +,5000,1001,5001 +,5001,18003,30000 =,18004,,30000 -+,1001,18005,5002 -=,5002,,1001 -goto,,,7 -=,18000,,1001 -+,1000,18005,5003 -=,5003,,1000 -goto,,,5 -=,18000,,1000 -=,18000,,1001 -<,1000,1002,8002 -gotoF,8002,,41 -<,1001,1002,8003 -gotoF,8003,,37 +verify,1000,18000,18001 +*,1000,18002,5002 +verify,1001,18000,18001 ++,5002,1001,5003 ++,5003,18005,30001 +=,1003,,30001 verify,1000,18000,18001 *,1000,18002,5004 verify,1001,18000,18001 +,5004,1001,5005 -+,5005,18003,30001 -WRITE,30001,, -+,1001,18005,5006 -=,5006,,1001 -goto,,,26 ++,5005,18006,30002 +verify,1000,18000,18001 +*,1000,18002,5006 +verify,1001,18000,18001 ++,5006,1001,5007 ++,5007,18003,30003 +verify,1000,18000,18001 +*,1000,18002,5008 +verify,1001,18000,18001 ++,5008,1001,5009 ++,5009,18005,30004 +*,30003,30004,5010 +=,5010,,30002 +verify,1000,18000,18001 +*,1000,18002,5011 +verify,1001,18000,18001 ++,5011,1001,5012 ++,5012,18006,30005 +WRITE,30005,, ++,1001,18007,5013 +=,5013,,1001 +goto,,,8 +=,18000,,1001 ++,1000,18007,5014 +=,5014,,1000 +goto,,,6 +=,18000,,1000 =,18000,,1001 -+,1000,18005,5007 -=,5007,,1000 -goto,,,24 diff --git a/testcase.c b/testcase.c new file mode 100644 index 0000000..f399c02 --- /dev/null +++ b/testcase.c @@ -0,0 +1,32 @@ +class main { + global vars{ + var int num; + } + classes { + } + functions{ + + func int fibo(int nn){ + vars{ + var int value, valueTwo, valueThree; + } + { + if(nn<=1){ + value = nn + } + else{ + valueTwo = fibo(nn-1) + valueThree = fibo(nn-2) + value = valueTwo + valueThree + }; + } + return value + } + } + { + num = fibo(5) + write(num) + + + } +}