Пример #1
0
        public object compilar(Entorno ent, Errores errores)
        {
            try
            {
                Generator generator = Generator.getInstance();
                Retorno   value     = this.value.compilar(ent);
                Simbolo   newVar    = ent.addVar(id, value.type, true, false, linea, columna);
                if (newVar.isGlobal)
                {
                    if (newVar.type.tipo == Tipos.BOOLEAN)
                    {
                        if (value.getValue().Equals("1"))
                        {
                            generator.addGoto(value.trueLabel);
                        }
                        else
                        {
                            generator.addGoto(value.falseLabel);
                        }

                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addSetStack("" + newVar.position, "1");
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addSetStack("" + newVar.position, "0");
                        generator.addLabel(templabel);
                    }
                    else
                    {
                        generator.addSetStack("" + newVar.position, value.getValue());
                    }
                }
            } catch (Error ex)
            {
                errores.agregarError(ex);
            }
            return(null);
        }
Пример #2
0
        public Retorno compilar(Entorno ent)
        {
            Retorno unario = this.unario.compilar(ent);

            if (!(unario.type.tipo == Tipos.INTEGER || unario.type.tipo == Tipos.REAL))
            {
                throw new Error("Semántico", "No se puede evaluar una resta unaria con un " + unario.type.tipoToString(), ent.obtenerAmbito(), linea, columna);
            }
            Generator generator = Generator.getInstance();
            string    temp      = generator.newTemporal();

            //INTEGER, REAL
            generator.addExpression(temp, "0", unario.getValue(), "-");
            return(new Retorno(temp, true, unario.type));
        }
Пример #3
0
        public Retorno compilar(Entorno ent)
        {
            Retorno left          = this.left.compilar(ent);
            Retorno right         = this.right.compilar(ent);
            Tipos   tipoResultado = TablaTipos.obtenerTipo("-", left.type, right.type);

            if (tipoResultado == Tipos.ERROR)
            {
                throw new Error("Semántico", "No se puede evaluar una resta entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna);
            }
            Tipo      tipo      = new Tipo(tipoResultado);
            Generator generator = Generator.getInstance();
            string    temp      = generator.newTemporal();

            //INTEGER, REAL
            generator.addExpression(temp, left.getValue(), right.getValue(), "-");
            return(new Retorno(temp, true, tipo));
        }
Пример #4
0
        public Retorno compilar(Entorno ent)
        {
            Retorno left          = this.left.compilar(ent);
            Retorno right         = this.right.compilar(ent);
            Tipos   tipoResultado = TablaTipos.obtenerTipo("mod", left.type, right.type);

            if (tipoResultado == Tipos.ERROR)
            {
                throw new Error("Semántico", "No se puede evaluar un modulo entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna);
            }
            Tipo      tipo      = new Tipo(tipoResultado);
            Generator generator = Generator.getInstance();
            string    temp      = generator.newTemporal();

            //INTEGER
            if (right.valorToString().Equals("0"))
            {
                throw new Error("Semántico", "Resultado indefinido, no se puede realizar un modulo entre 0", ent.obtenerAmbito(), linea, columna);
            }
            generator.addExpression(temp, left.getValue(), right.getValue(), "%");
            return(new Retorno(temp, true, tipo));
        }
Пример #5
0
        public Retorno compilar(Entorno ent)
        {
            //Mi modificacion
            if (this.left is AccessId)
            {
                AccessId access = (AccessId)this.left;
                access.vieneDeRelacional = true;
            }
            Retorno   left = this.left.compilar(ent);
            Retorno   right;
            Generator generator = Generator.getInstance();

            switch (left.type.tipo)
            {
            case Tipos.INTEGER:
            case Tipos.REAL:
                right = this.right.compilar(ent);
                switch (right.type.tipo)
                {
                case Tipos.INTEGER:
                case Tipos.REAL:
                    this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                    this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                    if (this.isLessEqual)
                    {
                        generator.addIf(left.getValue(), right.getValue(), "<=", this.trueLabel);
                    }
                    else
                    {
                        generator.addIf(left.getValue(), right.getValue(), "<", this.trueLabel);
                    }
                    generator.addGoto(this.falseLabel);
                    Retorno retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN));
                    retorno.trueLabel  = this.trueLabel;
                    retorno.falseLabel = this.falseLabel;
                    return(retorno);

                default: break;
                }
                break;

            case Tipos.BOOLEAN:
                //Mi modificacion
                if (this.right is AccessId)
                {
                    AccessId access = (AccessId)this.right;
                    access.vieneDeRelacional = true;
                }
                right           = this.right.compilar(ent);
                this.trueLabel  = this.trueLabel == "" ? generator.newLabel() : this.trueLabel;
                this.falseLabel = this.falseLabel == "" ? generator.newLabel() : this.falseLabel;
                if (isLessEqual)
                {
                    generator.addIf(left.getValue(), right.getValue(), "<=", trueLabel);
                }
                else
                {
                    generator.addIf(left.getValue(), right.getValue(), "<=", trueLabel);
                }
                generator.addGoto(falseLabel);
                if (right.type.tipo == Tipos.BOOLEAN)
                {
                    Retorno retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN));
                    retorno.trueLabel  = this.trueLabel;
                    retorno.falseLabel = this.falseLabel;
                    return(retorno);
                }
                break;

            case Tipos.STRING:
                right = this.right.compilar(ent);
                if (right.type.tipo == Tipos.STRING)
                {
                    string temp    = generator.newTemporal();
                    string tempAux = generator.newTemporal();
                    generator.freeTemp(tempAux);
                    generator.addExpression(tempAux, "SP", "" + (ent.getSize() + 1), "+");
                    generator.addSetStack(tempAux, left.getValue());
                    generator.addExpression(tempAux, tempAux, "1", "+");
                    generator.addSetStack(tempAux, right.getValue());
                    generator.addNextEnv(ent.getSize());
                    if (this.isLessEqual)
                    {
                        generator.addCall("native_lessEq_str");
                    }
                    else
                    {
                        generator.addCall("native_less_str");
                    }
                    generator.addGetStack(temp, "SP");
                    generator.addAntEnv(ent.getSize());

                    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 retorno = new Retorno("", false, new Tipo(Tipos.BOOLEAN));
                    retorno.trueLabel  = this.trueLabel;
                    retorno.falseLabel = this.falseLabel;
                    return(retorno);
                }
                break;

            default: right = new Retorno("", false, new Tipo(Tipos.ERROR)); break;    //ERROR
            }
            throw new Error("Semántico", "No se puede evaluar un < o <= entre un " + left.type.tipoToString() + " y un " + right.type.tipoToString(), ent.obtenerAmbito(), linea, columna);
        }
Пример #6
0
        public object compilar(Entorno ent, Errores errores)
        {
            Generator generator = Generator.getInstance();

            generator.addComment("Inicia Writeln");
            try
            {
                foreach (Expresion expresion in expresiones)
                {
                    Retorno value = expresion.compilar(ent);
                    switch (value.type.tipo)
                    {
                    case Tipos.INTEGER:
                        if (value.isTemp)
                        {
                            generator.addPrint("d", "(int)" + value.getValue());
                        }
                        else
                        {
                            generator.addPrint("d", value.getValue());
                        }
                        break;

                    case Tipos.REAL:
                        generator.addPrint("f", value.getValue());
                        break;

                    case Tipos.BOOLEAN:
                        if (value.vieneDesdeObjeto)
                        {
                            generator.addIf(value.getValue(), "1", "==", value.trueLabel);
                            generator.addGoto(value.falseLabel);
                        }
                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addPrintTrue();
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addPrintFalse();
                        generator.addLabel(templabel);
                        break;

                    case Tipos.STRING:
                        generator.addNextEnv(ent.getSize());
                        generator.addSetStack("SP", value.getValue());
                        generator.addCall("native_print_str");
                        generator.addAntEnv(ent.getSize());
                        break;

                    default:
                        throw new Error("Semántico", "Tipo de dato no soportado en un writeln", ent.obtenerAmbito(), linea, columna);
                    }
                }
                if (isLine)
                {
                    generator.addPrint("c", "10");
                }
            }
            catch (Error ex)
            {
                errores.agregarError(ex);
            }
            generator.addComment("Finaliza Writeln");
            return(null);
        }
Пример #7
0
        public object compilar(Entorno ent, Errores errores)
        {
            try
            {
                Generator generator = Generator.getInstance();
                generator.addComment("Inicia Asignacion");

                if (ent.ambito.Equals("FUNCTION"))
                {
                    SimboloFunction symFunc = ent.actualFunc;
                    if (symFunc != null)
                    {
                        AsignacionId mytarget = (AsignacionId)this.target;
                        if (mytarget.id.ToLower().Equals(symFunc.id.ToLower())) //Es un Return
                        {
                            Return @return = new Return(this.value, linea, columna);
                            @return.isAsignacion = true;
                            return(@return.compilar(ent, errores));
                        }
                    }
                }

                Retorno target = this.target.compilar(ent);
                Retorno value  = this.value.compilar(ent);

                Simbolo symbol = target.symbol;
                if (symbol.isConst)
                {
                    throw new Error("Semántico", "No se puede cambiar el valor de una constante", ent.obtenerAmbito(), linea, columna);
                }
                if (!sameType(target.type, value.type))
                {
                    throw new Error("Semántico", "No coincide el tipo de dato de la variable con el tipo de valor a asignar", ent.obtenerAmbito(), linea, columna);
                }
                if (symbol.isHeap == false) //ES GLOBAL
                {
                    if (target.type.tipo == Tipos.BOOLEAN)
                    {
                        //Mi modificacion
                        if (value.getValue().Equals("1"))
                        {
                            generator.addGoto(value.trueLabel);
                        }
                        else
                        {
                            generator.addGoto(value.falseLabel);
                        }

                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addSetStack(target.getValue(), "1");
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addSetStack(target.getValue(), "0");
                        generator.addLabel(templabel);
                    }
                    else
                    {
                        generator.addSetStack(target.getValue(), value.getValue());
                    }
                }
                else if (symbol.isHeap)
                {
                    if (target.type.tipo == Tipos.BOOLEAN)
                    {
                        //Mi modificacion
                        if (value.getValue().Equals("1"))
                        {
                            generator.addGoto(value.trueLabel);
                        }
                        else
                        {
                            generator.addGoto(value.falseLabel);
                        }

                        string templabel = generator.newLabel();
                        generator.addLabel(value.trueLabel);
                        generator.addSetHeap(target.getValue(), "1");
                        generator.addGoto(templabel);
                        generator.addLabel(value.falseLabel);
                        generator.addSetHeap(target.getValue(), "0");
                        generator.addLabel(templabel);
                    }
                    else
                    {
                        generator.addSetHeap(target.getValue(), value.getValue());
                    }
                }
                generator.addComment("Finaliza Asignacion");
            } catch (Error ex)
            {
                errores.agregarError(ex);
            }
            return(null);
        }
Пример #8
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)));
            }
        }
Пример #9
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);
            }
        }