Example #1
0
 public Tipo(Tipos tipo, string tipoId = "", SimboloStruct symStruct = null, int dimension = 0)
 {
     this.tipo      = tipo;
     this.tipoId    = tipoId;
     this.symStruct = symStruct;
     this.dimension = dimension;
 }
Example #2
0
 public void validateType(Entorno ent)
 {
     if (this.type.tipo == Tipos.STRUCT)
     {
         SimboloStruct @struct = ent.searchStruct(this.type.tipoId);
         if (@struct == null)
         {
             throw new Error("Semántico", "No existe el object: " + this.type.tipoId, ent.obtenerAmbito(), linea, columna);
         }
         this.type.symStruct = @struct;
     }
 }
Example #3
0
        public Retorno compilar(Entorno ent)
        {
            SimboloStruct symStruct = ent.searchStruct(this.id);
            Generator     generator = Generator.getInstance();

            if (symStruct == null)
            {
                throw new Error("Semántico", "No existe el object " + this.id + " en este entorno", ent.obtenerAmbito(), linea, columna);
            }
            string temp = generator.newTemporal();

            generator.addExpression(temp, "HP", "", "");
            //Llenamos de valores por defecto
            foreach (Param attribute in symStruct.attributes)
            {
                switch (attribute.type.tipo)
                {
                case Tipos.INTEGER:
                case Tipos.REAL:
                case Tipos.BOOLEAN:
                    generator.addSetHeap("HP", "0");
                    generator.nextHeap();
                    break;

                case Tipos.STRING:
                    generator.addSetHeap("HP", "-1");
                    generator.nextHeap();
                    break;

                case Tipos.STRUCT:
                    generator.addComment("Inicia substruct");
                    compilarSubStruct(attribute);
                    generator.addComment("Finaliza substruct");
                    break;

                default:
                    generator.addSetHeap("HP", "-1");
                    generator.nextHeap();
                    break;
                }
            }
            return(new Retorno(temp, true, new Tipo(Tipos.STRUCT, symStruct.identifier, symStruct)));
        }
Example #4
0
        private void validateParams(Entorno ent)
        {
            LinkedList <string> set = new LinkedList <string>();

            foreach (Param param in attributes)
            {
                if (set.Contains(param.id.ToLower()))
                {
                    throw new Error("Semántico", "Ya existe un atributo con el nombre: " + param.id + " en el object: " + this.id, ent.obtenerAmbito(), linea, columna);
                }
                if (param.type.tipo == Tipos.STRUCT)
                {
                    SimboloStruct @struct = ent.structExists(param.type.tipoId);
                    if (@struct == null)
                    {
                        throw new Error("Semántico", "No existe el object: " + param.type.tipoId + "para el atributo: " + param.id, ent.obtenerAmbito(), linea, columna);
                    }
                    param.type.symStruct = @struct;
                }
                set.AddLast(param.id.ToLower());
            }
        }
Example #5
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)));
            }
        }
Example #6
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);
            }
        }