Exemplo n.º 1
0
    def __init__(self, name, parent):
        self.name = name
        self.parent = parent

        # public stuff
        self.publicMetodos = [] #lista de funciones
        self.publicAtributos = [] #lista de atributos

        # private stuff
        self.privateMetodos = [] # lista de funciones privadas
        self.privateAtributos = [] # lista de atributos privados


        # tratar memoria virtual
        if name != 'global':
            self.memoriaGlobal = memoria(91000, 101000, 111000)
            self.offSet = self.contador[0]
            self.contador[0] = self.contador[0] + 1
        else:
            self.memoriaGlobal = memoria(1000, 11000, 21000)
            self.offSet = 0




        #size
        self.size = 0
Exemplo n.º 2
0
    def __init__(self, name, tipoRetorno, ip):
        self.name = name
        self.tipoRetorno = tipoRetorno
        self.numberParams = 0
        self.params = []  # lista de variables de parametros
        self.vars = []  # lista de variables declarados
        self.size = 0
        # local memory for this scope
        # will be handled by the virtual machine
        # enteros, float, char, clases
        self.memory = memoria(31000, 41000, 51000)
        self.ip = ip

        # my class offset
        self.classOffset = 30000
Exemplo n.º 3
0
def era(cuad, contProg):
  global cuadLlamada
  global funcParams
  global newMemory
  funcName = cuad.result
  funcion = dirFuncs.get(funcName, False)
  if (funcion != False) :
    funcParams = dirFuncs[funcion.id].params
    cuadLlamada.append(dirFuncs[funcion.id].di)
    eraSize = dirFuncs[funcion.id].tam
    #eraSize = (eraSize.split(','))
    newMemory = mem.memoria(eraSize[0],eraSize[1],eraSize[2],eraSize[3],eraSize[4],eraSize[5],eraSize[6])
  else:
    print("No deberia entrar aqui porque el chequeo semantico de que la funcion este declarada está en el compilador")
    sys.exit()
  return contProg + 1
Exemplo n.º 4
0
class PPCDSALVCCustomListener(PPCDSALVCListener):
    #enteras #flotantes #chars
    #la memoria de constantes?
    constantes = memoria(61000, 71000, 81000)
    #vamo a usar un dic para mapear las dir ya declaradas
    myCte = {}

    #a conseguir el valor back
    myCteB = {}

    # CTES
    offSetClass = 5000

    #Boleanos
    isClass = False
    isFunction = False
    isParameter = False
    isPublic = True

    # ints
    numberParams = 0
    arrSize = 0

    offSetI = 0
    offSetf = 0
    offSetc = 0

    offSet = 0

    # Strings
    nameFunction = None
    lastType = None
    returnType = None
    mClass = None

    # stacks para cuadruplos
    expStack = []
    tipoStack = []
    opStack = []
    jmpStack = []
    jmpLoop = []
    assStack = []

    parameters = []
    tipos = []
    methodStack = []

    # stack para clases y funciones
    classStack = []
    funcStack = []

    def exitEntrada(self, ctx):
        #attr
        if (ctx.attr() is not None):
            # ID is an instance, and its attr
            claseName = str(ctx.ID())
            varName = str(ctx.attr().ID())

            cls = self.tope(self.classStack)
            func = self.tope(self.funcStack).name

            left = self.semantica.existVariable(cls, func, claseName)
            if left is None:
                self.pushError(claseName, "var is not defined", ctx.start.line,
                               401)
                sys.exit(1)
            right = self.semantica.existInClass(
                self.semantica.getClase(left.tipo), varName)
            if right is None:
                self.pushError(right, "var is not defined", ctx.start.line,
                               401)
                sys.exit(1)
            direccion = left.direccion + right.direccion
            self.pushCuadruplo('READ', None, None, direccion)
        else:
            elemento = self.semantica.existVariable(
                self.tope(self.classStack),
                self.tope(self.funcStack).name, str(ctx.ID()))
            if elemento == None:
                self.err.push(
                    "\'" + str(fToken) + "\' is not defined | line : " +
                    str(ctx.start.line), 401)
                sys.exit(1)
            else:
                direccion = elemento.direccion
                if (ctx.arreglo() is not None):
                    # getting array size ? arr[exp]

                    if elemento.isArray is False:
                        self.pushError(elemento, "is not an array",
                                       ctx.start.line, 513)
                        sys.exit(1)

                    size = elemento.array.getSize()
                    # lo que apunet a esa direccion bro
                    self.pushCuadruplo('VALID', 0, size,
                                       self.tope(self.expStack))
                    # sz to check

                    pos = -1

                    # dentro del rango de ctes enteras
                    if self.tope(self.expStack) >= 61000 and self.tope(
                            self.expStack) <= 71000:
                        #  pos es el valor original de la cte
                        pos = direccion + int(self.myCteB[self.tope(
                            self.expStack)])
                        self.pop(self.expStack)
                    else:
                        # i need to sum to elemento.direccion + X equivalent
                        # i need a temporal address
                        resultAddress = self.getAddress('int')
                        # what is in this address  sumaselo a esto  to this one y ponlo aqui
                        self.pushCuadruplo('+_val_address',
                                           self.tope(self.expStack),
                                           elemento.direccion, resultAddress)
                        self.pop(self.expStack)
                        pos = -resultAddress

                    self.pushCuadruplo('READ', None, None, pos)
                else:
                    self.pushCuadruplo('READ', None, None, elemento.direccion)

    def exitEntradaaux(self, ctx):
        #attr
        if (ctx.ID() is None):
            return
        if (ctx.attr() is not None):
            # ID is an instance, and its attr
            claseName = str(ctx.ID())
            varName = str(ctx.attr().ID())

            cls = self.tope(self.classStack)
            func = self.tope(self.funcStack).name

            left = self.semantica.existVariable(cls, func, claseName)
            if left is None:
                self.pushError(claseName, "var is not defined", ctx.start.line,
                               401)
                sys.exit(1)
            right = self.semantica.existInClass(
                self.semantica.getClase(left.tipo), varName)
            if right is None:
                self.pushError(right, "var is not defined", ctx.start.line,
                               401)
                sys.exit(1)
            direccion = left.direccion + right.direccion
            self.pushCuadruplo('READ', None, None, direccion)
        else:
            elemento = self.semantica.existVariable(
                self.tope(self.classStack),
                self.tope(self.funcStack).name, str(ctx.ID()))
            if elemento == None:
                fToken = ctx.ID()
                self.err.push(
                    "\'" + str(fToken) + "\' is not defined | line : " +
                    str(ctx.start.line), 401)
                sys.exit(1)
            else:
                direccion = elemento.direccion
                if (ctx.arreglo() is not None):
                    # getting array size ? arr[exp]

                    if elemento.isArray is False:
                        self.pushError(elemento, "is not an array",
                                       ctx.start.line, 513)
                        sys.exit(1)

                    size = elemento.array.getSize()
                    # lo que apunet a esa direccion bro
                    self.pushCuadruplo('VALID', 0, size,
                                       self.tope(self.expStack))
                    # sz to check

                    pos = -1

                    # dentro del rango de ctes enteras
                    if self.tope(self.expStack) >= 61000 and self.tope(
                            self.expStack) <= 71000:
                        #  pos es el valor original de la cte
                        pos = direccion + int(self.myCteB[self.tope(
                            self.expStack)])
                        self.pop(self.expStack)
                    else:
                        # i need to sum to elemento.direccion + X equivalent
                        # i need a temporal address
                        resultAddress = self.getAddress('int')
                        # what is in this address  sumaselo a esto  to this one y ponlo aqui
                        self.pushCuadruplo('+_val_address',
                                           self.tope(self.expStack),
                                           elemento.direccion, resultAddress)
                        self.pop(self.expStack)
                        pos = -resultAddress

                    self.pushCuadruplo('READ', None, None, pos)
                else:
                    self.pushCuadruplo('READ', None, None, elemento.direccion)

    def enterAssignment(self, ctx):
        #meter todos los ids
        self.push(self.assStack, str(ctx.ID()))

    def exitAssignment(self, ctx):
        if ctx.IGUAL() is not None:
            # clase en donde empieza a buscar
            cls = self.tope(self.classStack)

            # en que funcion estas
            func = self.tope(self.funcStack).name

            # x.y.z = exp
            # this is X
            # x = exp
            #TODO(check?)
            left = self.semantica.existVariable(cls, func, self.assStack[0])
            if left is None:
                self.pushError(self.assStack[0], "is not declared",
                               ctx.start.line, 499)
                sys.exit(1)

            direccion = left.direccion  # direccion Base
            # cls will contain the final class to get the variable
            cls = self.semantica.getClase(left.tipo)

            if left.tipo == 'int' or left.tipo == 'char' or left.tipo == 'float':
                cls = self.tope(self.classStack)

            for i in range(len(self.assStack) - 2):
                left = self.semantica.existVariable(cls, func,
                                                    self.assStack[i + 1],
                                                    False)
                if left == None:
                    self.pushError(self.assStack[i + 1], "is not declared",
                                   ctx.start.line, 499)
                    sys.exit(1)
                elif left.tipo == 'int' or left.tipo == 'char' or left.tipo == 'float':
                    self.pushError(self.assStack[i + 1], "is not a class",
                                   ctx.start.line, 501)
                    sys.exit(1)

                direccion = direccion + left.direccion
                cls = self.semantica.getClase(left.tipo)

            left = self.semantica.existVariable(cls, func,
                                                self.tope(self.assStack),
                                                False)
            if left is None:
                self.pushError(self.tope(self.assStack), "is not declared",
                               ctx.start.line, 499)
                sys.exit(1)
            elif left.tipo != 'int' and left.tipo != 'char' and left.tipo != 'float':
                self.pushError(self.tope(self.assStack), "is not an attribute",
                               ctx.start.line, 502)

            tipazo = self.tope(self.tipoStack)
            if (len(self.assStack) > 1):
                # get the direction
                direccion = direccion + left.direccion

            if ctx.LB() is not None:
                #variable
                rightValue = self.tope(self.expStack)
                self.pop(self.expStack)
                self.pop(self.tipoStack)

                #var[sz]
                sz = self.tope(self.expStack)
                self.pop(self.expStack)
                tip = self.tope(self.tipoStack)
                self.pop(self.tipoStack)

                if left.isArray is False:
                    self.pushError(elemento, "is not an array", ctx.start.line,
                                   513)
                    sys.exit(1)

                if tip != 'int':
                    self.pushError(sz, "is not int", ctx.start.line, 515)
                    sys.exit(1)

                resultAddress = -1
                size = -1
                mult = 1
                if sz >= 61000 and sz <= 71000:
                    aux = sz
                    sz = int(self.myCteB[sz])
                    resultAddress = direccion + sz
                else:
                    resultAddress = self.getAddress('int')
                    aux = sz
                    self.pushCuadruplo('+_val_address', sz, direccion,
                                       resultAddress)
                    mult = -1

                size = left.array.getSize()
                self.pushCuadruplo('VALID', 0, size, aux)

                self.push(self.expStack, rightValue)
                self.push(self.tipoStack, 'void')
                direccion = resultAddress * mult

        # print(left, left.tipo, tipazo)
            resultT = self.semantica.cube[left.tipo][tipazo]['=']
            if resultT == "err":
                self.err.push(
                    "type mismatch : " + left.tipo + " and " + tipazo +
                    " | line " + str(ctx.start.line), 403)
                sys.exit(1)

            self.pushCuadruplo('=', None, self.tope(self.expStack), direccion)

            # saco el EXP del stack
            self.pop(self.expStack)
            self.pop(self.tipoStack)

            self.assStack = []

    # simbolos especiales
    condicionales = ['<', '<=', '>', '>=', '==', '!=']
    logical = ['&&', '||']

    def enterPrograma(self, ctx):
        self.push(self.classStack, self.semantica.addClass("global", None))
        self.pushCuadruplo('goto', None, None, -1)

    def exitPrograma(self, ctx):
        pass

    def enterCiclo(self, ctx):
        self.push(self.jmpLoop, len(self.cuadruplos))

    def exitWhilecond(self, ctx):
        expType = self.tope(self.tipoStack)
        if expType != 'int':
            self.pushError(expType, "is returned instead of an int",
                           ctx.start.line, 411)
            sys.exit(1)
        else:
            result = self.tope(self.expStack)
            self.pop(self.expStack)
            self.pop(self.tipoStack)
            self.pushCuadruplo('gotof', result, None, -1)
            self.push(self.jmpLoop, len(self.cuadruplos) - 1)

    def exitCiclo(self, ctx):
        jmp = self.tope(self.jmpLoop)
        self.pop(self.jmpLoop)

        jmp2 = self.tope(self.jmpLoop)
        self.pop(self.jmpLoop)

        self.pushCuadruplo('goto', None, None, jmp2)
        self.cuadruplos[jmp].result = len(self.cuadruplos)

    #quiero sacar de la pila a donde empieza la cond
    def exitFciclo(self, ctx):
        self.pop(self.jmpLoop)

    def enterFciclocond(self, ctx):
        self.push(self.jmpLoop, len(self.cuadruplos))

    def exitFciclocond(self, ctx):
        expType = self.tope(self.tipoStack)
        if expType != 'int':
            self.pushError(expType, "is returned instead of an int",
                           ctx.start.line, 411)
            sys.exit(1)
        else:
            result = self.tope(self.expStack)
            self.pop(self.expStack)
            self.pop(self.tipoStack)
            self.pushCuadruplo('gotof', result, None, -1)
            self.push(self.jmpLoop, len(self.cuadruplos) - 1)

            #goto to the body
            self.pushCuadruplo('goto', None, None, -1)
            self.push(self.jmpLoop, len(self.cuadruplos) - 1)

    def enterFcicloupd(self, ctx):
        #a donde debe ir el body
        self.push(self.jmpLoop, len(self.cuadruplos))

    def exitFcicloupd(self, ctx):
        jmp = self.jmpLoop[len(self.jmpLoop) - 4]
        self.pushCuadruplo('goto', None, None, jmp)
        del self.jmpLoop[-4]

    def enterFciclobody(self, ctx):
        jmp = self.jmpLoop[len(self.jmpLoop) - 2]
        del self.jmpLoop[-2]

        self.cuadruplos[jmp].result = len(self.cuadruplos)

    def exitFciclobody(self, ctx):
        jmp = self.jmpLoop[len(self.jmpLoop) - 1]
        self.pop(self.jmpLoop)
        self.pushCuadruplo('goto', None, None, jmp)

        jmp = self.jmpLoop[len(self.jmpLoop) - 1]
        self.cuadruplos[jmp].result = len(self.cuadruplos)

    def getReturnAddrs(self, funcName, clase):
        funcName = 'r_' + funcName
        return self.semantica.existVariable(clase,
                                            self.tope(self.funcStack).name,
                                            funcName).direccion

    def getActualIP(self):
        return len(self.cuadruplos)

    def exitFunctionbloque(self, ctx):
        if ctx.rt() is not None:
            if self.returnType == 'void':
                self.pushError('return', "was found but the function is void",
                               ctx.start.line, 477)
                sys.exit(1)
            tipo = self.tope(self.tipoStack)
            if tipo != self.returnType:
                self.pushError(
                    tipo,
                    f"was found but the function is expecting to return {self.returnType}",
                    ctx.start.line, 488)
                sys.exit(1)

            addr = self.getReturnAddrs(
                self.tope(self.funcStack).name, self.tope(self.classStack))
            right = self.tope(self.expStack)
            self.pop(self.expStack)
            self.pop(self.tipoStack)

            self.pushCuadruplo('=', None, right, addr)

    def getCteDir(self, val, tipo):
        if self.myCte.get(val) is None and tipo == 'int':
            op = 'CI'
            self.myCte[val] = self.constantes.getEntera()
        elif self.myCte.get(val) is None and tipo == 'float':
            op = 'CF'
            self.myCte[val] = self.constantes.getFlotante()
        elif self.myCte.get(val) is None and tipo == 'char':
            op = 'CC'
            self.myCte[val] = self.constantes.getChar()

        if tipo == 'int':
            op = 'CI'
        elif tipo == 'float':
            op = 'CF'
        elif tipo == 'char':
            op = 'CC'

        self.pushCuadruplo(op, None, val, self.myCte[val])
        self.myCteB[self.myCte[val]] = val
        return self.myCte[val]

    # check that the method being call is valid
    def exitMcall(self, ctx):
        if self.semantica.checkFunctionExists(
                self.semantica.getClase(self.mClass), str(ctx.ID())) == False:
            fToken = ctx.ID()
            self.err.push(
                "\'" + str(fToken) + "\' function not declared | line : " +
                str(ctx.start.line), 402)
            sys.exit(1)
        else:
            myFunc = self.semantica.getFunc(
                self.semantica.getClase(self.mClass), str(ctx.ID()))
            # ERA
            self.pushCuadruplo('ERA', None, myFunc.size, myFunc.name)
            self.pushCuadruplo('SET', None, self.mClass, self.offSet)
            if self.compareFunctions(myFunc) == False:
                self.pushError(str(ctx.ID()), "the function doesnt not match",
                               ctx.start.line, 409)
                sys.exit(1)

            #TODO(execute all here)
            if myFunc.tipoRetorno == 'void':
                return

            resultAddress = self.getAddress('int')
            self.pushCuadruplo(
                'sume_address_set', None,
                self.getReturnAddrs(myFunc.name,
                                    self.semantica.getClase(self.mClass)),
                resultAddress)
            self.push(self.expStack, -resultAddress)  # myFunc.getReturnDir())
            self.push(self.tipoStack, myFunc.tipoRetorno)
            self.pushCuadruplo('UNSET', None, None, None)

    # check that all the subclases exists for the method
    def enterMethod(self, ctx):
        if ctx.mcall() is not None:
            self.push(self.methodStack, str(ctx.ID()))
            #do something
            self.offSet = 0

            myVar = self.semantica.existVariable(
                self.tope(self.classStack),
                self.tope(self.funcStack).name, self.methodStack[0])
            self.offSet = myVar.direccion

            if myVar is None:
                self.pushError(self.methodStack[0], "var is not defined",
                               ctx.start.line, 401)
                sys.exit(1)
            for i in range(len(self.methodStack) - 1):
                myVar = self.semantica.existInClass(
                    self.semantica.getClase(myVar.tipo),
                    self.methodStack[i + 1])
                if myVar is None:
                    self.pushError(self.methodStack[i + 1],
                                   "var is not defined", ctx.start.line, 401)
                    sys.exit(1)
                self.offSet = self.offSet + myVar.direccion

            #checa que el ultimo sea un metodo definido
            if self.semantica.checkFunctionExists(
                    self.semantica.getClase(myVar.tipo), str(ctx.mcall().ID()),
                    False) == False:
                self.pushError(str(ctx.mcall().ID()), "method is not defined",
                               ctx.start.line, 407)
                sys.exit(1)
            self.mClass = myVar.tipo

            self.methodStack = []

        else:
            self.push(self.methodStack, str(ctx.ID()))

    def enterPv(self, ctx):
        self.isPublic = False

    def exitPv(self, ctx):
        self.isPublic = True

    def enterCondition(self, ctx):
        self.push(self.jmpStack, 'F')

    def enterConditionsecond(self, ctx):
        expType = self.tope(self.tipoStack)
        if expType != 'int':
            self.pushError(expType, "is returned instead of an int",
                           ctx.start.line, 411)
            sys.exit(1)
        else:
            result = self.tope(self.expStack)
            self.pop(self.expStack)
            self.pop(self.tipoStack)

            self.pushCuadruplo('gotof', result, None, -1)
            self.push(self.jmpStack, len(self.cuadruplos) - 1)

    # entrando al elseif es cuando ya sabes cual es la exp, es cuando termina de hacer los statements, ya sabemos a donde va el primer if
    def enterElseif(self, ctx):
        #goto from the last condition
        #terminaste el primer if, ya salta al final
        self.pushCuadruplo('goto', None, None, -1)

        #goto from the first if( if it's false, move here)
        #lo que siga despues del goto ya no esta dentro de lif, so yeah
        jmp = self.tope(self.jmpStack)
        self.pop(self.jmpStack)
        self.cuadruplos[jmp].result = len(self.cuadruplos)

        #mete el goto que tenias pendiente a la pila de saltos
        #aun necesitamos saber a donde va
        self.push(self.jmpStack, len(self.cuadruplos) - 1)

    # ok tenemos un elseif
    def enterConditionthird(self, ctx):
        expType = self.tope(self.tipoStack)
        if expType != 'int':
            self.pushError(expType, "is returned instead of an int",
                           ctx.start.line, 411)
            sys.exit(1)
        else:
            # el gotof del elseif
            result = self.tope(self.expStack)
            #sacamos la exp y el tipo
            self.pop(self.expStack)
            self.pop(self.tipoStack)

            self.pushCuadruplo('gotof', result, None, -1)
            self.push(self.jmpStack, len(self.cuadruplos) - 1)

    def enterElseotr(self, ctx):
        #goto from the else if
        #ya terminaste el elseif, salte hasta el final de la condicional
        self.pushCuadruplo('goto', None, None, -1)

        # jmp en falso
        jmp = self.tope(self.jmpStack)
        self.pop(self.jmpStack)
        self.cuadruplos[jmp].result = len(self.cuadruplos)

        self.push(self.jmpStack, len(self.cuadruplos) - 1)

    def exitCondition(self, ctx):
        while (self.tope(self.jmpStack) != 'F'):
            #goto del if/ goto del elseif
            jmp = self.tope(self.jmpStack)
            self.pop(self.jmpStack)
            self.cuadruplos[jmp].result = len(self.cuadruplos)
        self.pop(self.jmpStack)

    def insertVariablesPadres(self, ctx):
        cl = self.tope(self.classStack)
        parent = cl.parent
        if (parent == 'global'):
            return
        cl = self.semantica.getClase(parent)
        while (cl.name != 'global'):
            for variable in cl.publicAtributos:
                sz = -1
                if variable.array is not None:
                    sz = variable.array.getSize()
                self.lastType = variable.tipo
                self.insertVar(variable.name, ctx, variable.isArray, sz)
                if cl.parent == None:
                    return
            cl = self.semantica.getClase(cl.parent)

    def enterClasses(self, ctx):
        self.isClass = True
        name = str(ctx.ID(0))
        if ctx.PP() is not None:
            parent = str(ctx.ID(1))
            cl = self.tope(self.classStack)
            self.push(self.classStack, self.semantica.addClass(name, parent))
            self.insertVariablesPadres(ctx)
        else:
            cl = self.tope(self.classStack)
            self.push(self.classStack, self.semantica.addClass(
                name,
                "global",
            ))

    def exitClasses(self, ctx):
        self.isClass = False
        self.pop(self.classStack)

    def enterParameters(self, ctx):
        self.isParameter = True

    def exitParameters(self, ctx):
        self.isParameter = False

    def insertReturn(self, varName, tipo):
        #should be global
        add = self.semantica.getAddressGlobal(tipo, self.classStack[0])
        self.semantica.addAtributo(self.classStack[0], varName, tipo, add,
                                   False, True, -1)

    def insertVar(self, varName, ctx, isArray=False, arrSize=-1):
        tipo = self.lastType
        if tipo != 'int' and tipo != 'char' and tipo != 'float':
            #check the class exists
            if self.semantica.getClase(tipo) is None:
                self.pushError(tipo, "class doesnt exists", ctx.start.line,
                               506)
                sys.exit(1)

        if self.isFunction:
            if self.semantica.existVariable(self.tope(self.classStack),
                                            self.tope(self.funcStack).name,
                                            varName) is not None:
                self.pushError(varName, "is already declared", ctx.start.line,
                               455)
                sys.exit(1)

            if self.isParameter:
                self.semantica.addParameter(self.tope(self.funcStack), varName,
                                            tipo, self.getAddress(tipo), False)
            else:
                self.semantica.addVarFunc(
                    self.tope(self.funcStack), varName, tipo,
                    self.getAddress(tipo, isArray, arrSize), isArray, arrSize)
        else:
            topeClase = self.tope(self.classStack)
            if self.semantica.existInClass(topeClase, varName,
                                           False) is not None:
                self.pushError(varName, "is already declared", ctx.start.line,
                               455)
                sys.exit(1)
            #TODO(arreglar isArray)
            self.semantica.addAtributo(self.tope(self.classStack), varName,
                                       tipo,
                                       self.getAddress(tipo, isArray, arrSize),
                                       isArray, self.isPublic, arrSize)
        return

    def enterImprimir(self, ctx):
        self.push(self.expStack, 'P')

    #TODO(crear quad)
    def exitImprimir(self, ctx):
        myExps = []
        while len(self.expStack) > 0 and self.tope(self.expStack) != 'P':
            self.push(myExps, self.tope(self.expStack))
            self.pop(self.expStack)
            self.pop(self.tipoStack)

        if len(self.expStack) > 0 and self.tope(self.expStack) == 'P':
            self.pop(self.expStack)

        while len(myExps) > 0:
            self.pushCuadruplo('print', None, None, self.tope(myExps))
            self.pop(myExps)

    def tope(self, stack):
        return stack[len(stack) - 1]

    def push(self, stack, val):
        stack.append(val)

    def pop(self, stack):
        stack.pop()

    def enterCte(self, ctx):
        tipos = 'void'
        if ctx.INT() is not None:
            val = ctx.INT()
            tipos = 'int'
        elif ctx.FLOAT() is not None:
            val = ctx.FLOAT()
            tipos = 'float'
        elif ctx.CHAR() is not None:
            val = ctx.CHAR()
            tipos = 'char'

        cteDir = self.getCteDir(str(val), tipos)
        self.push(self.expStack, cteDir)
        self.push(self.tipoStack, tipos)

    def exitFactor(self, ctx):
        if ctx.signosunarios() is not None:
            op = str(ctx.signosunarios().getChild(0))
            tope = self.tope(self.expStack)
            tmp = self.getAddress(self.tope(self.tipoStack))
            if op == '!':
                self.pushCuadruplo('not', None, tope, tmp)
            elif op == '-':
                self.pushCuadruplo('negate', None, tope, tmp)
            self.pop(self.expStack)
            self.push(self.expStack, tmp)

    def getAddress(self, tipo, isArray=False, arraySize=0):
        if len(self.funcStack) == 0:
            #should be global
            add = self.semantica.getAddressGlobal(tipo,
                                                  self.tope(self.classStack))
            for i in range(arraySize):
                self.semantica.getAddressGlobal(tipo,
                                                self.tope(self.classStack))
            return add
        else:
            add = self.semantica.getAddressFunc(str(tipo),
                                                self.tope(self.funcStack))
            for i in range(arraySize):
                self.semantica.getAddressFunc(str(tipo),
                                              self.tope(self.funcStack))
            return add

    def resolveExp(self, ctx):
        if len(self.opStack) > 0:
            operando = self.tope(self.opStack)
            if operando == '+' or operando == '-':
                self.pop(self.opStack)
                left = self.tope(self.expStack)
                self.pop(self.expStack)
                right = self.tope(self.expStack)
                self.pop(self.expStack)

                leftT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)
                rightT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)

                left, right = right, left
                leftT, rightT = rightT, leftT

                resultT = self.semantica.cube[leftT][rightT][operando]
                if resultT != "err":
                    resultAddress = self.getAddress(resultT)
                    self.pushCuadruplo(operando, left, right, resultAddress)
                    self.push(self.expStack, resultAddress)
                    self.push(self.tipoStack, resultT)
                else:
                    self.err.push(
                        "type mismatch : " + leftT + " and " + rightT +
                        " | line " + str(ctx.start.line), 403)
                    sys.exit(1)

    def resolveTerm(self, ctx):
        if len(self.opStack) > 0:
            operando = self.tope(self.opStack)
            if operando == '*' or operando == '/':
                self.pop(self.opStack)

                left = self.tope(self.expStack)
                self.pop(self.expStack)
                right = self.tope(self.expStack)
                self.pop(self.expStack)

                leftT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)
                rightT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)

                left, right = right, left
                leftT, rightT = rightT, leftT

                #TODO(TEMPORAL ERROR)
                # error because ? mhm not sure why, guess cause of bad operands?
                #are we considering leftT and righT to actually be address?
                try:
                    resultT = self.semantica.cube[leftT][rightT][operando]
                except:
                    self.err.push("tmp, err", 404)
                    sys.exit(1)

                if resultT != "err":
                    resultAddress = self.getAddress(resultT)
                    self.pushCuadruplo(operando, left, right, resultAddress)
                    self.push(self.expStack, resultAddress)
                    self.push(self.tipoStack, resultT)
                else:
                    self.err.push(
                        "type mismatch : " + leftT + " and " + rightT +
                        " | line " + str(ctx.start.line), 403)
                    sys.exit(1)

    def resolveSuperExp(self, ctx):
        if len(self.opStack) > 0:
            operando = self.tope(self.opStack)
            if operando in self.condicionales:
                self.pop(self.opStack)

                left = self.tope(self.expStack)
                self.pop(self.expStack)
                right = self.tope(self.expStack)
                self.pop(self.expStack)

                leftT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)
                rightT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)

                left, right = right, left
                leftT, rightT = rightT, leftT

                resultT = self.semantica.cube[leftT][rightT][operando]
                if resultT != "err":
                    resultAddress = self.getAddress(resultT)
                    self.pushCuadruplo(operando, left, right, resultAddress)
                    self.push(self.expStack, resultAddress)
                    self.push(self.tipoStack, resultT)
                else:
                    self.err.push(
                        "type mismatch : " + leftT + " and " + rightT +
                        " | line " + str(ctx.start.line), 403)
                    sys.exit(1)

    def resolveHyperExp(self, ctx):
        if len(self.opStack) > 0:
            operando = self.tope(self.opStack)
            if operando in self.logical:
                self.pop(self.opStack)

                left = self.tope(self.expStack)
                self.pop(self.expStack)
                right = self.tope(self.expStack)
                self.pop(self.expStack)

                leftT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)
                rightT = self.tope(self.tipoStack)
                self.pop(self.tipoStack)

                left, right = right, left
                leftT, rightT = rightT, leftT

                resultT = self.semantica.cube[leftT][rightT][operando]
                if resultT != "err":
                    resultAddress = self.getAddress(resultT)
                    self.pushCuadruplo(operando, left, right, resultAddress)
                    self.push(self.expStack, resultAddress)
                    self.push(self.tipoStack, resultT)
                else:
                    self.err.push(
                        "type mismatch : " + leftT + " and " + rightT +
                        " | line " + str(ctx.start.line), 403)
                    sys.exit(1)

    def imprimeErrores(self):
        for elem in self.err.errors:
            print(elem.msg)

    def exitTermaux(self, ctx):
        self.resolveTerm(ctx)

    def exitTerm(self, ctx):
        self.resolveTerm(ctx)

    def enterParent(self, ctx):
        self.push(self.opStack, '$')

    def exitParent(self, ctx):
        self.pop(self.opStack)

    def enterSuperexpaux(self, ctx):
        self.push(self.opStack, str(ctx.relationalop().getChild(0)))

    def exitSuperexpaux(self, ctx):
        self.resolveSuperExp(ctx)

    # este deberia dar un resultado booleano, segun yo..?
    # va a regresar int, no?
    def enterHyperexpaux(self, ctx):
        self.push(self.opStack, str(ctx.logicop().getChild(0)))

    def exitHyperexpaux(self, ctx):
        self.resolveHyperExp(ctx)

    def enterExpaux(self, ctx):
        self.push(self.opStack, str(ctx.binbasico().getChild(0)))

    def exitExpaux(self, ctx):
        self.resolveExp(ctx)

    def exitExp(self, ctx):
        self.resolveExp(ctx)

    def enterTermaux(self, ctx):
        self.push(self.opStack, str(ctx.bincomplejo().getChild(0)))

    def pushError(self, fToken, msg, line, code):
        linea = str(line)
        self.err.push("\'" + str(fToken) + "\' " + msg + " | line : " + linea,
                      code)

    def enterFparam(self, ctx):
        self.push(self.expStack, '#')
        self.push(self.opStack, '#')
        self.push(self.parameters, 'T')
        self.push(self.tipos, 'T')

    def exitFparam(self, ctx):
        while len(self.expStack) > 0 and self.tope(
                self.expStack) != '#' and len(self.tipoStack) > 0:
            param1 = self.tope(self.expStack)
            tipo1 = self.tope(self.tipoStack)
            self.pop(self.expStack)
            self.pop(self.tipoStack)
            self.push(self.parameters, param1)
            self.push(self.tipos, tipo1)

        if len(self.expStack) > 0 and self.tope(self.expStack) == '#':
            self.pop(self.expStack)

        if len(self.opStack) > 0 and self.tope(self.opStack) == '#':
            self.pop(self.opStack)

    def compareFunctions(self, funcA):
        myParameters = []
        myTypes = []

        while len(self.parameters) > 0 and self.tope(self.parameters) != 'T':
            param1 = self.tope(self.parameters)
            tipo1 = self.tope(self.tipos)

            self.push(myParameters, param1)
            self.push(myTypes, tipo1)

            self.pop(self.parameters)
            self.pop(self.tipos)

        if len(self.parameters) > 0 and self.tope(self.parameters) == 'T':
            self.pop(self.parameters)

        if self.semantica.canUseFunction(funcA, myParameters, myTypes):
            for i in range(len(myParameters)):
                self.pushCuadruplo(
                    'param', myParameters[i], None,
                    funcA.params[len(myParameters) - i - 1].direccion)

            self.pushCuadruplo('gosub', funcA.name, None, funcA.ip)
            return True

        return False

    def exitFunccall(self, ctx):
        if self.semantica.checkFunctionExists(self.tope(self.classStack),
                                              str(ctx.ID())) == False:
            fToken = ctx.ID()
            self.err.push(
                "\'" + str(fToken) + "\' function not declared | line : " +
                str(ctx.start.line), 402)
            sys.exit(1)
        else:
            #create function
            myFunc = self.semantica.getFunc(self.tope(self.classStack),
                                            str(ctx.ID()))
            self.pushCuadruplo('ERA', None, myFunc.size, myFunc.name)

            #dirr = self.tope(self.classStack).dirr
            # set offset back to zero
            #self.pushCuadruplo('SET', None , self.tope(self.classStack).name, dirr)

            if self.compareFunctions(myFunc) == False:
                self.pushError(str(ctx.ID()), "the function doesnt not match",
                               ctx.start.line, 409)
                sys.exit(1)

    def exitFactorclases(self, ctx):
        # func call
        if ctx.PA() is not None and ctx.PUNTO() is None:
            if self.semantica.checkFunctionExists(self.tope(self.classStack),
                                                  str(ctx.ID(0))) == False:
                fToken = ctx.ID(0)
                self.pushError(fToken, "function not declared", ctx.start.line,
                               402)
                sys.exit(1)
            else:
                #ok, it does exist, but is it the same?
                myFunc = self.semantica.getFunc(self.tope(self.classStack),
                                                str(ctx.ID(0)))
                self.pushCuadruplo('ERA', None, myFunc.size, myFunc.name)
                #self.pushCuadruplo('SET', None , self.tope(self.classStack).name, self.offSet)
                if self.compareFunctions(myFunc) == False:
                    self.pushError(str(ctx.ID(0)),
                                   "the function doesnt not match",
                                   ctx.start.line, 409)
                    sys.exit(1)

                #set offset to the going function

                if myFunc.tipoRetorno == 'void':
                    self.pushError(str(ctx.ID(0)),
                                   "the function has type return void",
                                   ctx.start.line, 408)
                    sys.exit(1)
                else:
                    #put the result from r_funcName into a temp
                    resultAddress = self.getAddress(myFunc.tipoRetorno)
                    rtn = self.getReturnAddrs(myFunc.name,
                                              self.tope(self.classStack))
                    self.pushCuadruplo('=', None, rtn, resultAddress)
                    self.push(self.expStack, resultAddress)
                    self.push(self.tipoStack, myFunc.tipoRetorno)

                #atributos && metodos de clases
        elif ctx.PUNTO() is not None:
            varName = str(ctx.ID(0))

            myVar = self.semantica.existVariable(
                self.tope(self.classStack),
                self.tope(self.funcStack).name, varName)

            if myVar is None:
                self.pushError(varName, "variable not declared",
                               ctx.start.line, 401)
                sys.exit(1)

            className = myVar.tipo
            myFunc = self.semantica.getFunc(self.semantica.getClase(className),
                                            str(ctx.ID(1)))

            cls = self.semantica.getClase(className)
            if cls == None:
                #throw error
                self.pushError(className, "class not declared", ctx.start.line,
                               405)
                sys.exit(1)
                #metodos

            if ctx.PA() != None:
                metodoName = str(ctx.ID(1))
                if self.semantica.checkFunctionExists(cls, metodoName,
                                                      False) == False:
                    self.pushError(metodoName, "method not declared",
                                   ctx.start.line, 407)
                    sys.exit(1)
                else:
                    #ok, it does exist, but is it the same?
                    myFunc = self.semantica.getFunc(cls, metodoName)

                    self.pushCuadruplo('ERA', None, myFunc.size, myFunc.name)
                    self.pushCuadruplo('SET', None, cls.name, myVar.direccion)
                    if self.compareFunctions(myFunc) == False:
                        self.pushError(metodoName,
                                       "the function doesnt not match",
                                       ctx.start.line, 409)
                        sys.exit(1)

                    if myFunc.tipoRetorno == 'void':
                        self.pushError(metodoName,
                                       "the method has type return void",
                                       ctx.start.line, 408)
                        sys.exit(1)
                    else:

                        resultAddress = self.getAddress('int')
                        self.pushCuadruplo(
                            'sume_address_set', None,
                            self.getReturnAddrs(myFunc.name, cls),
                            resultAddress)
                        self.push(self.expStack, -resultAddress)
                        self.push(self.tipoStack, myFunc.tipoRetorno)

                        self.pushCuadruplo('UNSET', None, None, None)
            else:
                #atributo
                attrName = str(ctx.ID(1))

                elem = self.semantica.existVariable(
                    cls,
                    self.tope(self.funcStack).name, attrName, False)
                if elem == None:
                    #throw error
                    self.pushError(attrName,
                                   "attribute not declared inside the class",
                                   ctx.start.line, 406)
                    sys.exit(1)
                    # clase + atributos direcciones
                self.push(self.expStack, myVar.direccion + elem.direccion)
                self.push(self.tipoStack, elem.tipo)

        # variable
        else:
            elemento = self.semantica.existVariable(
                self.tope(self.classStack),
                self.tope(self.funcStack).name, str(ctx.ID(0)))
            if elemento == None:
                fToken = ctx.ID(0)
                self.err.push(
                    "\'" + str(fToken) + "\' is not defined | line : " +
                    str(ctx.start.line), 401)
                sys.exit(1)
            else:
                direccion = elemento.direccion
                if (ctx.arreglo() is not None):
                    # getting array size ? arr[exp]

                    if elemento.isArray is False:
                        self.pushError(elemento, "is not an array",
                                       ctx.start.line, 513)
                        sys.exit(1)

                    size = elemento.array.getSize()
                    # lo que apunet a esa direccion bro
                    self.pushCuadruplo('VALID', 0, size,
                                       self.tope(self.expStack))
                    # sz to check

                    pos = -1

                    # dentro del rango de ctes enteras
                    if self.tope(self.expStack) >= 61000 and self.tope(
                            self.expStack) <= 71000:
                        #  pos es el valor original de la cte
                        pos = direccion + int(self.myCteB[self.tope(
                            self.expStack)])
                        self.pop(self.expStack)
                    else:
                        # i need to sum to elemento.direccion + X equivalent
                        # i need a temporal address
                        resultAddress = self.getAddress('int')
                        # what is in this address  sumaselo a esto  to this one y ponlo aqui
                        self.pushCuadruplo('+_val_address',
                                           self.tope(self.expStack),
                                           elemento.direccion, resultAddress)
                        self.pop(self.expStack)
                        pos = -resultAddress

                    self.push(self.expStack, pos)  # str(ctx.ID(0)))
                    self.push(self.tipoStack, elemento.tipo)

                else:
                    self.push(self.expStack,
                              elemento.direccion)  # str(ctx.ID(0)))
                    self.push(self.tipoStack, elemento.tipo)

    def insertScope(self, scopeStyle, scope):
        pass
        #self.semantica.

    def pushCuadruplo(self, op, left, right, result):
        self.cuadruplos.append(cuadruplo(op, left, right, result))

    def enterTypesvar(self, ctx):
        sonArreglos = []
        if ctx.TYPES() is not None:
            self.lastType = str(ctx.TYPES())
        else:
            self.lastType = str(ctx.ID())
        indices = []

        indices.append(str(ctx.typesvaraux().ID()))
        if ctx.typesvaraux().LB() is not None:
            sonArreglos.append(ctx.typesvaraux().scte().INT())
        else:
            sonArreglos.append(-1)

        for act in ctx.secondType():
            indices.append(str(act.ID()))
            if act.LB() is not None:
                sonArreglos.append(act.scte().INT())
            else:
                sonArreglos.append(-1)

        i = 0
        while i < len(indices):
            vr = indices[i]
            tope = int(str((sonArreglos[i])))
            self.insertVar(vr, ctx, tope != -1, tope)
            i = i + 1

    def enterMain(self, ctx):
        self.cuadruplos[0].result = len(self.cuadruplos)
        self.isFunction = True
        #        self.push(self.funcStack, funcion('main', 'void'))
        self.push(
            self.funcStack,
            self.semantica.addFunction(self.tope(self.classStack), True,
                                       'main', 'void', self.getActualIP()))

        #        self.semantica.appendFuncs("main")

    def exitMain(self, ctx):
        self.isFunction = False
        self.pop(self.funcStack)

    def enterFunctions(self, ctx):
        nameFunction = str(ctx.ID())
        self.returnType = str(ctx.returntypes().getChild(0))
        if self.returnType != 'void':
            #i need a global variable named the same
            self.lastType = self.returnType
            self.insertReturn('r_' + nameFunction, self.lastType)
        self.isFunction = True
        self.push(
            self.funcStack,
            self.semantica.addFunction(self.tope(self.classStack),
                                       self.isPublic, nameFunction,
                                       self.returnType, self.getActualIP()))

    def exitFunctions(self, ctx):
        self.pushCuadruplo('endproc', None, None, None)
        self.isFunction = False
        self.pop(self.funcStack)

    def exitParamfirst(self, ctx):

        self.numberParams = self.numberParams + 1
        if ctx.TYPES() is not None:
            self.lastType = str(ctx.TYPES())
            self.insertVar(str(ctx.ID(0)), ctx)
        else:
            self.lastType = str(ctx.ID(0))
            self.insertVar(str(ctx.ID(1)), ctx)

    def exitParams(self, ctx):
        self.numberParams = self.numberParams + 1
        if ctx.TYPES() is not None:
            self.lastType = str(ctx.TYPES())
            self.insertVar(str(ctx.ID(0)), ctx)
        else:
            self.lastType = str(ctx.ID(0))
            self.insertVar(str(ctx.ID(1)), ctx)

    def __init__(self, semantica, errores):
        self.semantica = semantica
        self.err = errores
        self.cuadruplos = []

    def exitTypesvar(self, ctx):
        pass
Exemplo n.º 5
0
  }
  func = dict_Ind.get(cuadr.action, 'False')
  if func != 'False':
    position = func(cuadr, contProg)
    return position
  return contProg + 1


#!---------------------------------------------------
#! EJECUCION
#!---------------------------------------------------

reader.readFile()
#? Inicializa Memoria Global
globSize = dirFuncs[reader.programa].tam
mem.memGlob.append(mem.memoria(globSize[0], globSize[1], globSize[2], 0, 0, 0, 0))
memoriaGlob = mem.memGlob[-1]
#? Inicializa Primera Memoria Local, contexto : Main
mainSize = dirFuncs["Main"].tam
mem.memStack.append(mem.memoria(mainSize[0], mainSize[1], mainSize[2], mainSize[3], mainSize[4], mainSize[5], mainSize[6]))
memoriaMain = mem.memStack[-1]

while cuad[contProg].action != 'ENDProgram':
  contProg = indicador(cuad[contProg], contProg)

memoriaGlob.printMem()
memoriaMain.printMem()
print('\n')
print("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒")
print("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ FINALIZANDO C CUAK CUAK ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒")
print("▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒", '\n')