Exemplo n.º 1
0
        public Retorno compilar(Entorno ent)
        {
            Generator generator = Generator.getInstance();

            generator.addComment("Inicia AsignacionId");
            if (this.anterior == null)
            {
                Simbolo symbol = ent.getVar(id, linea, columna);
                if (symbol.isRef)
                {
                    string tempAux = generator.newTemporal();
                    string temp    = generator.newTemporal();
                    generator.freeTemp(tempAux);
                    generator.addExpression(tempAux, "SP", "" + symbol.position, "+");
                    generator.addExpression(temp, tempAux, "1", "+");
                    generator.addGetStack(temp, temp);

                    this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                    this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                    generator.addIf(temp, "1", "==", this.trueLabel);
                    generator.addGoto(this.falseLabel);

                    string templabel = generator.newLabel();
                    generator.addLabel(this.trueLabel);
                    generator.addGetStack(temp, tempAux);
                    generator.addGoto(templabel);
                    generator.addLabel(this.falseLabel);
                    generator.addGetHeap(temp, tempAux);
                    generator.addLabel(templabel);
                    generator.addComment("Finaliza AsignacionId");
                    return(new Retorno(temp, true, symbol.type, symbol)); //OBTENGO LA COORDENADA DE LA VARIABLE POR REFERENCIA
                }
                else if (symbol.isGlobal)
                {
                    generator.addComment("Finaliza AsignacionId");
                    return(new Retorno("" + symbol.position, false, symbol.type, symbol));
                }
                else //isHeap
                {
                    string temp = generator.newTemporal();
                    generator.addExpression(temp, "SP", "" + symbol.position, "+");
                    generator.addComment("Finaliza AsignacionId");
                    return(new Retorno(temp, true, symbol.type, symbol));
                }
            }
            else
            {
                Retorno anterior = this.anterior.compilar(ent);
                if (anterior.type.tipo != Tipos.STRUCT)
                {
                    throw new Error("Semántico", "Acceso no valido para el tipo: " + anterior.type.tipo, ent.obtenerAmbito(), linea, columna);
                }

                SimboloStruct symStruct = anterior.type.symStruct;
                Jackson       attribute = symStruct.getAttribute(this.id);
                if (attribute.value == null)
                {
                    throw new Error("Semántico", "El object " + symStruct.identifier + "no tiene el atributo" + this.id, ent.obtenerAmbito(), linea, columna);
                }

                string tempAux = generator.newTemporal();
                generator.freeTemp(tempAux);
                string temp = generator.newTemporal();
                if (anterior.symbol != null && !anterior.symbol.isHeap)
                {
                    //TODO variables por referencia
                    generator.addGetStack(tempAux, anterior.getValue());
                }
                else
                {
                    generator.addGetHeap(tempAux, anterior.getValue());
                }
                generator.addExpression(temp, tempAux, "" + attribute.index, "+");
                generator.addComment("Finaliza AsignacionId");
                return(new Retorno(temp, true, attribute.value.type, new Simbolo(attribute.value.type, this.id, attribute.index, false, false, true, linea, columna)));
            }
        }
Exemplo n.º 2
0
        public Retorno compilar(Entorno ent)
        {
            Generator generator = Generator.getInstance();

            generator.addComment("Inicia AccessId");
            if (this.anterior == null)
            {
                Simbolo symbol = ent.getVar(this.id, linea, columna);
                string  temp   = generator.newTemporal();
                if (symbol.isRef)
                {
                    string tempAux = generator.newTemporal();
                    generator.freeTemp(tempAux);
                    generator.addExpression(tempAux, "SP", "" + symbol.position, "+");
                    generator.addExpression(temp, tempAux, "1", "+");
                    generator.addGetStack(temp, temp);

                    this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                    this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                    generator.addIf(temp, "1", "==", this.trueLabel);
                    generator.addGoto(this.falseLabel);

                    string templabel = generator.newLabel();
                    generator.addLabel(this.trueLabel);
                    generator.addGetStack(temp, tempAux);
                    generator.addGoto(templabel);
                    generator.addLabel(this.falseLabel);
                    generator.addGetHeap(temp, tempAux);
                    generator.addLabel(templabel);     //TENGO LA DIRECCION DE LA VARIABLE POR REFERENCIA

                    generator.addGetStack(temp, temp); //OBTENGO SU VALOR Y LO GUARDO EN EL MISMO TEMPORAL
                    if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT)
                    {
                        generator.addComment("Finaliza AccessId");
                        return(new Retorno(temp, true, symbol.type, symbol));
                    }
                    if (symbol.type.tipo == Tipos.BOOLEAN)
                    {
                        if (vieneDeRelacional)
                        {
                            return(new Retorno(temp, true, symbol.type, symbol));
                        }
                        Retorno retorno = new Retorno("", false, symbol.type, symbol);
                        this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        generator.addIf(temp, "1", "==", this.trueLabel);
                        generator.addGoto(this.falseLabel);
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                    else //STRUCT
                    {
                        Retorno retorno = new Retorno(temp, true, symbol.type, symbol);
                        this.trueLabel     = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel    = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                }
                else if (symbol.isGlobal)
                {
                    generator.addGetStack(temp, "" + symbol.position);
                    if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT)
                    {
                        generator.addComment("Finaliza AccessId");
                        return(new Retorno(temp, true, symbol.type, symbol));
                    }
                    //MI MODIFICACION
                    if (symbol.type.tipo == Tipos.BOOLEAN)
                    {
                        if (vieneDeRelacional)
                        {
                            return(new Retorno(temp, true, symbol.type, symbol));
                        }
                        Retorno retorno = new Retorno("", false, symbol.type, symbol);
                        this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        generator.addIf(temp, "1", "==", this.trueLabel);
                        generator.addGoto(this.falseLabel);
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                    else   //STRUCT
                    {
                        Retorno retorno = new Retorno(temp, true, symbol.type, symbol);
                        this.trueLabel     = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel    = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                }
                else //isHeap
                {
                    string tempAux = generator.newTemporal();
                    generator.freeTemp(tempAux);
                    generator.addExpression(tempAux, "SP", "" + symbol.position, "+");
                    generator.addGetStack(temp, tempAux);
                    if (symbol.type.tipo != Tipos.BOOLEAN && symbol.type.tipo != Tipos.STRUCT)
                    {
                        generator.addComment("Finaliza AccessId");
                        return(new Retorno(temp, true, symbol.type, symbol));
                    }
                    //MI MODIFICACION
                    if (symbol.type.tipo == Tipos.BOOLEAN)
                    {
                        if (vieneDeRelacional)
                        {
                            return(new Retorno(temp, true, symbol.type, symbol));
                        }
                        Retorno retorno = new Retorno("", false, symbol.type, symbol);
                        this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        generator.addIf(temp, "1", "==", this.trueLabel);
                        generator.addGoto(this.falseLabel);
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                    else //STRUCT
                    {
                        Retorno retorno = new Retorno(temp, true, symbol.type, symbol);
                        this.trueLabel     = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                        this.falseLabel    = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                        retorno.trueLabel  = this.trueLabel;
                        retorno.falseLabel = this.falseLabel;
                        generator.addComment("Finaliza AccessId");
                        return(retorno);
                    }
                }
            }
            else
            {
                Retorno       anterior  = this.anterior.compilar(ent);
                SimboloStruct symStruct = anterior.type.symStruct;
                if (anterior.type.tipo != Tipos.STRUCT || symStruct == null)
                {
                    throw new Error("Semántico", "Acceso no valido para el tipo: " + anterior.type.tipo, ent.obtenerAmbito(), linea, columna);
                }
                Jackson attribute = symStruct.getAttribute(this.id);
                if (attribute.value == null)
                {
                    throw new Error("Semántico", "El object no tiene el atributo: " + this.id, ent.obtenerAmbito(), linea, columna);
                }

                string tempAux = generator.newTemporal();
                generator.freeTemp(tempAux);
                string temp = generator.newTemporal();

                generator.addExpression(tempAux, anterior.getValue(), "" + attribute.index, "+"); //Busca la posicion del atributo
                generator.addGetHeap(temp, tempAux);                                              //Trae el valor del heap

                Retorno retorno = new Retorno(temp, true, attribute.value.type, null, true);
                retorno.trueLabel  = anterior.trueLabel;
                retorno.falseLabel = anterior.falseLabel;
                generator.addComment("Finaliza AccessId");
                return(retorno);
            }
        }