Пример #1
0
        public override Tipo GetTipo(Entorno e)
        {
            if (!(Op1 is Operacion) && !(Op2 is Operacion))
            {
                Tipo tip1 = Op1.GetTipo(e);
                Tipo tip2 = Op2.GetTipo(e);

                if (tip1 != Tipo.NULL && tip2 != Tipo.NULL)
                {
                    if ((tip1 == Tipo.DECIMAL || tip1 == Tipo.ENTERO) && (tip2 == Tipo.DECIMAL || tip2 == Tipo.ENTERO))
                    {
                        try
                        {
                            if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                            {
                                double val1 = Convert.ToDouble(Op1.GetValor());
                                double val2 = Convert.ToDouble(Op2.GetValor());

                                switch (Op)
                                {
                                case Operador.MENORQUE:
                                    valor = val1 < val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);

                                case Operador.MAYORQUE:
                                    valor = val1 > val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);

                                case Operador.MENORIGUAL:
                                    valor = val1 <= val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);

                                case Operador.MAYORIGUAL:
                                    valor = val1 >= val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);

                                case Operador.IGUAL:
                                    valor = val1 == val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);

                                case Operador.DIFERENTE:
                                    valor = val1 != val2 ? 1 : 0;
                                    return(Tipo.DECIMAL);
                                }
                            }
                            else
                            {
                                int val1 = Convert.ToInt32(Op1.GetValor());
                                int val2 = Convert.ToInt32(Op2.GetValor());

                                switch (Op)
                                {
                                case Operador.MENORQUE:
                                    valor = val1 < val2 ? 1 : 0;
                                    return(Tipo.ENTERO);

                                case Operador.MAYORQUE:
                                    valor = val1 > val2 ? 1 : 0;
                                    return(Tipo.ENTERO);

                                case Operador.MENORIGUAL:
                                    valor = val1 <= val2 ? 1 : 0;
                                    return(Tipo.ENTERO);

                                case Operador.MAYORIGUAL:
                                    valor = val1 >= val2 ? 1 : 0;
                                    return(Tipo.ENTERO);

                                case Operador.IGUAL:
                                    valor = val1 == val2 ? 1 : 0;
                                    return(Tipo.ENTERO);

                                case Operador.DIFERENTE:
                                    valor = val1 != val2 ? 1 : 0;
                                    return(Tipo.ENTERO);
                                }
                            }
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Error, no se puede realizar la operación relacional. Línea: " + Linea);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error, no se puede realizar la operación relacional. Línea: " + Linea);
                    }
                }
            }
            else
            {
                Console.WriteLine("Error, se esta usando más de 3 direcciones. Línea: " + Linea);
            }
            return(Tipo.NULL);
        }
Пример #2
0
        public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores)
        {
            Result result = new Result();

            Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores);

            if (Op2 != null)
            {
                Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores);

                TipoDominante(Op1.GetTipo(), Op2.GetTipo());

                if (!Tipo.IsIndefinido())
                {
                    result.Codigo += rsOp1.Codigo;
                    result.Codigo += rsOp2.Codigo;

                    if (Tipo.IsString())
                    {
                        if (!Op1.GetTipo().IsString())
                        {
                            ConvertirString(Op1, rsOp1, result);
                        }
                        if (!Op2.GetTipo().IsString())
                        {
                            ConvertirString(Op2, rsOp2, result);
                        }

                        result.EtiquetaV = NuevaEtiqueta();
                        result.EtiquetaF = NuevaEtiqueta();
                        string etqCiclo = NuevaEtiqueta();
                        string tmpCiclo = NuevoTemporal();
                        result.Valor = NuevoTemporal();

                        result.Codigo += result.Valor + " = H;\n";

                        result.Codigo += tmpCiclo + " = heap[" + rsOp1.Valor + "];\n";
                        result.Codigo += etqCiclo + ":\n";
                        result.Codigo += "if (" + tmpCiclo + " == 0) goto " + result.EtiquetaV + ";\n";
                        result.Codigo += "goto " + result.EtiquetaF + ";\n";
                        result.Codigo += result.EtiquetaF + ":\n";
                        result.Codigo += "heap[H] = " + tmpCiclo + ";\n";
                        result.Codigo += "H = H + 1;\n";
                        result.Codigo += rsOp1.Valor + " = " + rsOp1.Valor + " + 1;\n";
                        result.Codigo += tmpCiclo + " = heap[" + rsOp1.Valor + "];\n";
                        result.Codigo += "goto " + etqCiclo + ";\n";
                        result.Codigo += result.EtiquetaV + ":\n";

                        result.EtiquetaV = NuevaEtiqueta();
                        result.EtiquetaF = NuevaEtiqueta();
                        etqCiclo         = NuevaEtiqueta();
                        tmpCiclo         = NuevoTemporal();

                        result.Codigo += tmpCiclo + " = heap[" + rsOp2.Valor + "];\n";
                        result.Codigo += etqCiclo + ":\n";
                        result.Codigo += "if (" + tmpCiclo + " == 0) goto " + result.EtiquetaV + ";\n";
                        result.Codigo += "goto " + result.EtiquetaF + ";\n";
                        result.Codigo += result.EtiquetaF + ":\n";
                        result.Codigo += "heap[H] = " + tmpCiclo + ";\n";
                        result.Codigo += "H = H + 1;\n";
                        result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " + 1;\n";
                        result.Codigo += tmpCiclo + " = heap[" + rsOp2.Valor + "];\n";
                        result.Codigo += "goto " + etqCiclo + ";\n";
                        result.Codigo += result.EtiquetaV + ":\n";

                        result.Codigo += "heap[H] = 0;\n";
                        result.Codigo += "H = H + 1;\n";
                    }
                    else
                    {
                        switch (Op)
                        {
                        case Operador.SUMA:
                            result.Valor   = NuevoTemporal();
                            result.Codigo += result.Valor + " = " + rsOp1.Valor + " + " + rsOp2.Valor + ";\n";
                            break;

                        case Operador.RESTA:
                            result.Valor   = NuevoTemporal();
                            result.Codigo += result.Valor + " = " + rsOp1.Valor + " - " + rsOp2.Valor + ";\n";
                            break;

                        case Operador.MULTIPLICACION:
                            result.Valor   = NuevoTemporal();
                            result.Codigo += result.Valor + " = " + rsOp1.Valor + " * " + rsOp2.Valor + ";\n";
                            break;

                        case Operador.DIVISION:
                            result.Valor   = NuevoTemporal();
                            result.Codigo += result.Valor + " = " + rsOp1.Valor + " / " + rsOp2.Valor + ";\n";
                            break;

                        case Operador.MODULO:
                            result.Valor   = NuevoTemporal();
                            result.Codigo += result.Valor + " = " + rsOp1.Valor + " % " + rsOp2.Valor + ";\n";
                            break;

                        case Operador.FLOOR:
                            result.EtiquetaV = NuevaEtiqueta();
                            string etqSalida = NuevaEtiqueta();

                            if (Op1 is Literal)
                            {
                                string tmpOp1 = NuevoTemporal();
                                result.Codigo += tmpOp1 + " = " + rsOp1.Valor + ";\n";
                                rsOp1.Valor    = tmpOp1;
                            }
                            if (Op2 is Literal)
                            {
                                string tmpOp2 = NuevoTemporal();
                                result.Codigo += tmpOp2 + " = " + rsOp2.Valor + ";\n";
                                rsOp2.Valor    = tmpOp2;
                            }

                            result.Valor = NuevoTemporal();

                            result.Codigo += "if (" + rsOp2.Valor + " != 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo += "goto " + etqSalida + ";\n";
                            result.Codigo += result.EtiquetaV + ":\n";

                            string tmpCond = NuevoTemporal();
                            result.Codigo += tmpCond + " = 0;\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + rsOp2.Valor + " > 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            result.Codigo   += tmpCond + " = 1;\n";
                            string menos = NuevoTemporal();
                            result.Codigo += menos + " = 0 - 1;\n";
                            result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " * " + menos + ";\n";
                            result.Codigo += result.EtiquetaV + ":\n";

                            string tmpCond2 = NuevoTemporal();
                            result.Codigo += tmpCond2 + " = 0;\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + rsOp1.Valor + " >= 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            result.Codigo   += tmpCond2 + " = 1;\n";
                            menos            = NuevoTemporal();
                            result.Codigo   += menos + " = 0 - 1;\n";
                            result.Codigo   += rsOp1.Valor + " = " + rsOp1.Valor + " * " + menos + ";\n";
                            result.Codigo   += result.EtiquetaV + ":\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += result.Valor + " = 1;\n";
                            result.Codigo   += "if (" + rsOp2.Valor + " > " + rsOp1.Valor + ") goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaV + ":\n";
                            result.Codigo   += result.Valor + " = 0;\n";
                            result.Codigo   += result.EtiquetaF + ":\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            string etqCiclo = NuevaEtiqueta();
                            string tmp      = NuevoTemporal();

                            result.Codigo += tmp + " = " + rsOp1.Valor + " - " + rsOp2.Valor + ";\n";
                            result.Codigo += etqCiclo + ":\n";
                            result.Codigo += tmp + " = " + tmp + " - " + rsOp2.Valor + ";\n";
                            result.Codigo += "if (" + tmp + " >= 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo += result.EtiquetaV + ":\n";
                            result.Codigo += result.Valor + " = " + result.Valor + " + 1;\n";
                            result.Codigo += "goto " + etqCiclo + ";\n";
                            result.Codigo += result.EtiquetaF + ":\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + tmpCond + " == 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            string etqVerd = result.EtiquetaV;

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + tmpCond2 + " == 1) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            result.Codigo   += result.Valor + " = " + result.Valor + " + 1;\n";
                            menos            = NuevoTemporal();
                            result.Codigo   += menos + " = 0 - 1;\n";
                            result.Codigo   += result.Valor + " = " + result.Valor + " * " + menos + ";\n";
                            result.Codigo   += etqVerd + ":\n";
                            result.Codigo   += result.EtiquetaV + ":\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + tmpCond2 + " == 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            etqVerd          = result.EtiquetaV;

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            result.Codigo   += "if (" + tmpCond + " == 1) goto " + result.EtiquetaV + ";\n";
                            result.Codigo   += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo   += result.EtiquetaF + ":\n";
                            result.Codigo   += result.Valor + " = " + result.Valor + " + 1;\n";
                            menos            = NuevoTemporal();
                            result.Codigo   += menos + " = 0 - 1;\n";
                            result.Codigo   += result.Valor + " = " + result.Valor + " * " + menos + ";\n";
                            result.Codigo   += etqVerd + ":\n";
                            result.Codigo   += result.EtiquetaV + ":\n";

                            result.Codigo += etqSalida + ":\n";
                            break;

                        case Operador.POTENCIA:

                            if (Op1 is Literal)
                            {
                                string tmpOp1 = NuevoTemporal();
                                result.Codigo += tmpOp1 + " = " + rsOp1.Valor + ";\n";
                                rsOp1.Valor    = tmpOp1;
                            }
                            if (Op2 is Literal)
                            {
                                string tmpOp2 = NuevoTemporal();
                                result.Codigo += tmpOp2 + " = " + rsOp2.Valor + ";\n";
                                rsOp2.Valor    = tmpOp2;
                            }
                            else if (Op2 is Aritmetica)
                            {
                                if (((Aritmetica)Op2).Op2 == null && ((Aritmetica)Op2).Op == Operador.RESTA)
                                {
                                    Tipo.Tip = Tipo.Type.DOUBLE;
                                }
                            }

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            string factorNeg  = NuevoTemporal();
                            string nuevoValor = NuevoTemporal();
                            string etqSalida2 = NuevaEtiqueta();
                            //string etqError = NuevaEtiqueta();

                            result.Codigo += "if (" + rsOp2.Valor + " >= 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo += result.EtiquetaF + ":\n";
                            result.Codigo += factorNeg + " = 0 - 1;\n";
                            result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " * " + factorNeg + ";\n";
                            //result.Codigo += "if (" + rsOp1.Valor + " == 0) goto " + etqError + ";\n";/*0**-num*/
                            result.Codigo += nuevoValor + " = 1.0 / " + rsOp1.Valor + ";\n";
                            result.Codigo += "goto " + etqSalida2 + ";\n";
                            result.Codigo += result.EtiquetaV + ":\n";
                            result.Codigo += nuevoValor + " = " + rsOp1.Valor + ";\n";
                            result.Codigo += etqSalida2 + ":\n";

                            result.EtiquetaV = NuevaEtiqueta();
                            result.EtiquetaF = NuevaEtiqueta();
                            string etqCiclo2 = NuevaEtiqueta();
                            result.Valor = NuevoTemporal();

                            result.Codigo += result.Valor + " = 1;\n";
                            result.Codigo += etqCiclo2 + ":\n";
                            result.Codigo += "if (" + rsOp2.Valor + " <= 0) goto " + result.EtiquetaV + ";\n";
                            result.Codigo += "goto " + result.EtiquetaF + ";\n";
                            result.Codigo += result.EtiquetaF + ":\n";
                            result.Codigo += result.Valor + " = " + result.Valor + " * " + nuevoValor + ";\n";
                            result.Codigo += rsOp2.Valor + " = " + rsOp2.Valor + " - 1;\n";
                            result.Codigo += "goto " + etqCiclo2 + ";\n";
                            result.Codigo += result.EtiquetaV + ":\n";
                            break;
                        }
                    }
                }
                else
                {
                    errores.AddLast(new Error("Semántico", "Error de tipos en operación aritmética.", Linea, Columna));
                }
            }
            else
            {
                Tipo tipOp1 = Op1.GetTipo();
                if (tipOp1.IsNumeric() || tipOp1.IsBoolean())
                {
                    if (tipOp1.IsNumeric())
                    {
                        Tipo = Op1.GetTipo();
                    }
                    else
                    {
                        Tipo = new Tipo(Tipo.Type.INT);
                    }

                    result.Codigo += rsOp1.Codigo;
                    result.Valor   = NuevoTemporal();

                    switch (Op)
                    {
                    case Operador.SUMA:
                        result.Codigo += result.Valor + " = " + rsOp1.Valor + " * 1;\n";
                        break;

                    case Operador.RESTA:
                        result.Codigo += result.Valor + " = 0 - 1;\n";
                        string tmp = result.Valor;
                        result.Valor   = NuevoTemporal();
                        result.Codigo += result.Valor + " = " + rsOp1.Valor + " * " + tmp + ";\n";
                        break;
                    }
                }
                else
                {
                    errores.AddLast(new Error("Semántico", "Error de tipos en operación aritmética.", Linea, Columna));
                }
            }
            return(result);
        }
Пример #3
0
        public override Tipo GetTipo(Entorno e)
        {
            if (!(Op1 is Operacion) && !(Op2 is Operacion))
            {
                Tipo tip1 = Op1.GetTipo(e);
                Tipo tip2 = Op2.GetTipo(e);

                if (tip1 != Tipo.NULL && tip2 != Tipo.NULL)
                {
                    if ((tip1 == Tipo.ENTERO || tip1 == Tipo.DECIMAL) && (tip2 == Tipo.ENTERO || tip2 == Tipo.DECIMAL))
                    {
                        Object val1 = Op1.GetValor();
                        Object val2 = Op2.GetValor();
                        try
                        {
                            switch (Op)
                            {
                            case Operador.MAS:
                                if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                                {
                                    valor = Convert.ToDouble(val1) + Convert.ToDouble(val2);
                                    return(Tipo.DECIMAL);
                                }
                                else
                                {
                                    int val = Convert.ToInt32(val1) + Convert.ToInt32(val2);
                                    valor = val;
                                    return(Tipo.ENTERO);
                                }

                            case Operador.MENOS:
                                if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                                {
                                    valor = Convert.ToDouble(val1) - Convert.ToDouble(val2);
                                    return(Tipo.DECIMAL);
                                }
                                else
                                {
                                    int val = Convert.ToInt32(val1) - Convert.ToInt32(val2);
                                    valor = val;
                                    return(Tipo.ENTERO);
                                }

                            case Operador.POR:
                                if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                                {
                                    valor = Convert.ToDouble(val1) * Convert.ToDouble(val2);
                                    return(Tipo.DECIMAL);
                                }
                                else
                                {
                                    int val = Convert.ToInt32(val1) * Convert.ToInt32(val2);
                                    valor = val;
                                    return(Tipo.ENTERO);
                                }

                            case Operador.DIVIDIO:
                                if (Convert.ToInt32(val2) != 0)
                                {
                                    if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                                    {
                                        valor = Convert.ToDouble(val1) / Convert.ToDouble(val2);
                                        return(Tipo.DECIMAL);
                                    }
                                    else
                                    {
                                        double val = Convert.ToDouble(val1) / Convert.ToDouble(val2);
                                        valor = Math.Truncate(val);
                                        return(Tipo.ENTERO);
                                    }
                                }
                                else
                                {
                                    Console.WriteLine("Division entre 0-> linea: " + Op2.Linea + " columna: " + Op2.Columna);
                                    return(Tipo.NULL);
                                }

                            case Operador.MODULO:
                                if (tip1 == Tipo.DECIMAL || tip2 == Tipo.DECIMAL)
                                {
                                    valor = Math.Truncate(Convert.ToDouble(val1) % Convert.ToDouble(val2));
                                    return(Tipo.DECIMAL);
                                }
                                else
                                {
                                    double val = Convert.ToDouble(val1) % Convert.ToDouble(val2);
                                    valor = Math.Truncate(val);
                                    return(Tipo.ENTERO);
                                }
                            }
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("Error, no se puede realizar la operación aritmética. Línea: " + Linea);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error, no se puede realizar la operación aritmética. Línea: " + Linea);
                    }
                }
            }
            else
            {
                Console.WriteLine("Error, se esta usando más de 3 direcciones. Línea: " + Linea);
            }
            return(Tipo.NULL);
        }
Пример #4
0
        public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores)
        {
            Result result = new Result();

            if (Op1 is Relacional)
            {
                ((Relacional)Op1).Cortocircuito = true;
            }
            else if (Op1 is Logica)
            {
                ((Logica)Op1).Evaluar = true;
            }

            Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores);

            if (Op2 != null)
            {
                if (Op2 is Relacional)
                {
                    ((Relacional)Op2).Cortocircuito = true;
                }
                else if (Op2 is Logica)
                {
                    ((Logica)Op2).Evaluar = true;
                }


                Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores);

                TipoResultante(Op1.GetTipo(), Op2.GetTipo());

                if (!Tipo.IsIndefinido())
                {
                    if (Tipo.IsBoolean()) /*Si los dos son booleanos*/
                    {
                        if (Op1 is Literal)
                        {
                            rsOp1.EtiquetaV = NuevaEtiqueta();
                            rsOp1.EtiquetaF = NuevaEtiqueta();

                            rsOp1.Codigo    += "ifFalse (" + rsOp1.Valor + " == 1) goto " + rsOp1.EtiquetaV + ";\n";
                            rsOp1.Codigo    += "goto " + rsOp1.EtiquetaF + ";\n";
                            rsOp1.EtiquetaV += ":\n";
                            rsOp1.EtiquetaF += ":\n";
                        }

                        if (Op2 is Literal)
                        {
                            rsOp2.EtiquetaV = NuevaEtiqueta();
                            rsOp2.EtiquetaF = NuevaEtiqueta();

                            rsOp2.Codigo    += "ifFalse (" + rsOp2.Valor + " == 1) goto " + rsOp2.EtiquetaV + ";\n";
                            rsOp2.Codigo    += "goto " + rsOp2.EtiquetaF + ";\n";
                            rsOp2.EtiquetaV += ":\n";
                            rsOp2.EtiquetaF += ":\n";
                        }

                        if (Op == Operador.AND)
                        {
                            result.Codigo += rsOp1.Codigo;

                            if (Op1 is Relacional || Op1 is Literal)
                            {
                                result.Codigo  += rsOp1.EtiquetaF;
                                rsOp1.EtiquetaF = rsOp1.EtiquetaV;
                                rsOp1.EtiquetaV = null;
                            }
                            else if (Op1 is Logica)
                            {
                                result.Codigo  += rsOp1.EtiquetaV;
                                rsOp1.EtiquetaV = null;
                            }

                            result.Codigo += rsOp2.Codigo;

                            if (Op2 is Relacional || Op2 is Literal)
                            {
                                string copy = rsOp2.EtiquetaV;
                                rsOp2.EtiquetaV = rsOp2.EtiquetaF;
                                rsOp2.EtiquetaF = copy;
                            }

                            /*
                             * if(Op2 is Relacional)
                             *  result.Codigo += rsOp2.EtiquetaF;*/

                            if (!Evaluar)
                            {
                                result.Valor = NuevoTemporal();
                                string etiquetaS = NuevaEtiqueta();

                                if (rsOp1.EtiquetaV != null)
                                {
                                    result.Codigo += rsOp1.EtiquetaV;
                                }

                                if (rsOp2.EtiquetaV != null)
                                {
                                    result.Codigo += rsOp2.EtiquetaV;
                                }

                                result.Codigo += result.Valor + " = 1;\n";
                                result.Codigo += "goto " + etiquetaS + ";\n";

                                if (rsOp1.EtiquetaF != null)
                                {
                                    result.Codigo += rsOp1.EtiquetaF;
                                }

                                if (rsOp2.EtiquetaF != null)
                                {
                                    result.Codigo += rsOp2.EtiquetaF;
                                }

                                result.Codigo += result.Valor + " = 0;\n";
                                result.Codigo += etiquetaS + ":\n";
                            }
                            else
                            {
                                if (rsOp1.EtiquetaV != null)
                                {
                                    result.EtiquetaV += rsOp1.EtiquetaV;
                                }
                                if (rsOp1.EtiquetaF != null)
                                {
                                    result.EtiquetaF += rsOp1.EtiquetaF;
                                }
                                if (rsOp2.EtiquetaV != null)
                                {
                                    result.EtiquetaV += rsOp2.EtiquetaV;
                                }
                                if (rsOp2.EtiquetaF != null)
                                {
                                    result.EtiquetaF += rsOp2.EtiquetaF;
                                }
                            }
                        }
                        else
                        {
                            result.Codigo += rsOp1.Codigo;

                            if (Op1 is Relacional || Op1 is Literal)
                            {
                                result.Codigo  += rsOp1.EtiquetaV;
                                rsOp1.EtiquetaV = rsOp1.EtiquetaF;
                                rsOp1.EtiquetaF = null;
                            }
                            else if (Op1 is Logica)
                            {
                                result.Codigo  += rsOp1.EtiquetaF;
                                rsOp1.EtiquetaF = null;
                            }

                            result.Codigo += rsOp2.Codigo;

                            if (Op2 is Relacional || Op2 is Literal)
                            {
                                string copy = rsOp2.EtiquetaV;
                                rsOp2.EtiquetaV = rsOp2.EtiquetaF;
                                rsOp2.EtiquetaF = copy;
                            }

                            if (!Evaluar)
                            {
                                result.Valor = NuevoTemporal();
                                string etiquetaS = NuevaEtiqueta();

                                if (rsOp1.EtiquetaV != null)
                                {
                                    result.Codigo += rsOp1.EtiquetaV;
                                }

                                if (rsOp2.EtiquetaV != null)
                                {
                                    result.Codigo += rsOp2.EtiquetaV;
                                }

                                result.Codigo += result.Valor + " = 1;\n";
                                result.Codigo += "goto " + etiquetaS + ";\n";

                                if (rsOp1.EtiquetaF != null)
                                {
                                    result.Codigo += rsOp1.EtiquetaF;
                                }

                                if (rsOp2.EtiquetaF != null)
                                {
                                    result.Codigo += rsOp2.EtiquetaF;
                                }

                                result.Codigo += result.Valor + " = 0;\n";
                                result.Codigo += etiquetaS + ":\n";
                            }
                            else
                            {
                                if (rsOp1.EtiquetaV != null)
                                {
                                    result.EtiquetaV += rsOp1.EtiquetaV;
                                }
                                if (rsOp1.EtiquetaF != null)
                                {
                                    result.EtiquetaF += rsOp1.EtiquetaF;
                                }
                                if (rsOp2.EtiquetaV != null)
                                {
                                    result.EtiquetaV += rsOp2.EtiquetaV;
                                }
                                if (rsOp2.EtiquetaF != null)
                                {
                                    result.EtiquetaF += rsOp2.EtiquetaF;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (Op == Operador.AND)
                        {
                            if (Op2 is Literal && !Op2.GetTipo().IsNone())
                            {
                                result.Valor   = NuevoTemporal();
                                result.Codigo += result.Valor + " = " + rsOp2.Valor + ";\n";
                            }
                            else
                            {
                                result.Codigo += rsOp2.Codigo;
                                result.Valor   = rsOp2.Valor;

                                if (Op2 is Relacional || Op2 is Logica)
                                {
                                    if (!Evaluar)
                                    {
                                        result.Valor = NuevoTemporal();
                                        string etiquetaS = NuevaEtiqueta();

                                        if (rsOp2.EtiquetaV != null)
                                        {
                                            result.Codigo += rsOp2.EtiquetaV;
                                        }

                                        result.Codigo += result.Valor + " = 1;\n";
                                        result.Codigo += "goto " + etiquetaS + ";\n";

                                        if (rsOp2.EtiquetaF != null)
                                        {
                                            result.Codigo += rsOp2.EtiquetaF;
                                        }

                                        result.Codigo += result.Valor + " = 0;\n";
                                        result.Codigo += etiquetaS + ":\n";
                                    }
                                    else
                                    {
                                        result.EtiquetaV = rsOp2.EtiquetaV;
                                        result.EtiquetaF = rsOp2.EtiquetaF;
                                    }
                                }
                            }
                            Tipo = Op2.GetTipo();
                        }
                        else
                        {
                            if (Op1 is Literal && !Op1.GetTipo().IsNone())
                            {
                                result.Valor   = NuevoTemporal();
                                result.Codigo += result.Valor + " = " + rsOp1.Valor + ";\n";
                            }
                            else
                            {
                                result.Codigo += rsOp1.Codigo;
                                result.Valor   = rsOp1.Valor;

                                if (Op1 is Relacional || Op1 is Logica)
                                {
                                    if (!Evaluar)
                                    {
                                        result.Valor = NuevoTemporal();
                                        string etiquetaS = NuevaEtiqueta();

                                        if (rsOp1.EtiquetaV != null)
                                        {
                                            result.Codigo += rsOp1.EtiquetaV;
                                        }

                                        result.Codigo += result.Valor + " = 1;\n";
                                        result.Codigo += "goto " + etiquetaS + ";\n";

                                        if (rsOp1.EtiquetaF != null)
                                        {
                                            result.Codigo += rsOp1.EtiquetaF;
                                        }

                                        result.Codigo += result.Valor + " = 0;\n";
                                        result.Codigo += etiquetaS + ":\n";
                                    }
                                    else
                                    {
                                        result.EtiquetaV = rsOp1.EtiquetaV;
                                        result.EtiquetaF = rsOp1.EtiquetaF;
                                    }
                                }
                            }
                            Tipo = Op1.GetTipo();
                        }
                    }
                }
                else
                {
                    errores.AddLast(new Error("Semántico", "Error de tipos en operación lógica.", Linea, Columna));
                }
            }
            else /*NOT*/
            {
                Tipo.Tip = Tipo.Type.BOOLEAN;

                if (Op1.GetTipo().IsBoolean()) /*Boolean, exp logica y relacional*/
                {
                    if (Op1 is Literal)
                    {
                        rsOp1.EtiquetaV = NuevaEtiqueta();
                        rsOp1.EtiquetaF = NuevaEtiqueta();

                        rsOp1.Codigo    += "ifFalse (" + rsOp1.Valor + " == 1) goto " + rsOp1.EtiquetaV + ";\n";
                        rsOp1.Codigo    += "goto " + rsOp1.EtiquetaF + ";\n";
                        rsOp1.EtiquetaV += ":\n";
                        rsOp1.EtiquetaF += ":\n";
                    }

                    result.Codigo += rsOp1.Codigo;

                    if (!Evaluar)
                    {
                        result.Valor = NuevoTemporal();
                        string etiquetaS = NuevaEtiqueta();

                        if (rsOp1.EtiquetaV != null)
                        {
                            result.Codigo += rsOp1.EtiquetaV;
                        }

                        result.Codigo += result.Valor + " = 1;\n";
                        result.Codigo += "goto " + etiquetaS + ";\n";

                        if (rsOp1.EtiquetaF != null)
                        {
                            result.Codigo += rsOp1.EtiquetaF;
                        }

                        result.Codigo += result.Valor + " = 0;\n";
                        result.Codigo += etiquetaS + ":\n";
                    }
                    else
                    {
                        if (rsOp1.EtiquetaV != null)
                        {
                            result.EtiquetaF = rsOp1.EtiquetaV;
                        }
                        if (rsOp1.EtiquetaF != null)
                        {
                            result.EtiquetaV = rsOp1.EtiquetaF;
                        }
                    }
                }
                else
                {
                    if (Op1 is Literal)
                    {
                        string tmp = NuevoTemporal();
                        rsOp1.Codigo += tmp + " = " + rsOp1.Valor + ";\n";
                        rsOp1.Valor   = tmp;
                    }
                    if (Op1.GetTipo().IsString())
                    {
                        rsOp1.Codigo += rsOp1.Valor + " = 0 - 1;\n";
                    }

                    result.Codigo += rsOp1.Codigo;

                    if (!Evaluar)
                    {
                        result.EtiquetaV = NuevaEtiqueta();
                        result.EtiquetaF = NuevaEtiqueta();
                        result.Valor     = NuevoTemporal();

                        result.Codigo += result.Valor + " = 0;\n";
                        result.Codigo += "ifFalse (" + rsOp1.Valor + " == 0) goto " + result.EtiquetaV + ";\n";
                        result.Codigo += "goto " + result.EtiquetaF + ";\n";
                        result.Codigo += result.EtiquetaF + ":\n";
                        result.Codigo += result.Valor + " = 1;\n";
                        result.Codigo += result.EtiquetaV + ":\n";
                    }
                    else
                    {
                        result.EtiquetaV  = NuevaEtiqueta();
                        result.EtiquetaF  = NuevaEtiqueta();
                        result.Codigo    += "ifFalse (" + rsOp1.Valor + " == 0) goto " + result.EtiquetaF + ";\n";
                        result.Codigo    += "goto " + result.EtiquetaV + ";\n";
                        result.EtiquetaV += ":\n";
                        result.EtiquetaF += ":\n";
                    }
                }
            }

            return(result);
        }
Пример #5
0
        public override Result GetC3D(Ent e, bool funcion, bool ciclo, bool isObjeto, LinkedList <Error> errores)
        {
            Result result = new Result();

            if (Op != Operador.IS && Op != Operador.ISNOT)
            {
                Result rsOp1 = Op1.GetC3D(e, funcion, ciclo, isObjeto, errores);
                Result rsOp2 = Op2.GetC3D(e, funcion, ciclo, isObjeto, errores);

                TipoResultante(Op1.GetTipo(), Op2.GetTipo());

                if (!Tipo.IsIndefinido())
                {
                    if (!Op1.GetTipo().IsObject() && !Op2.GetTipo().IsObject()) /*si los dos no son objetos*/
                    {
                        /*
                         * if (Op == Operador.IGUAL)
                         * {
                         *  if (Op1.GetTipo() != Op2.GetTipo())
                         *  {
                         *      result.Codigo += rsOp1.Codigo;
                         *      result.Codigo += rsOp2.Codigo;
                         *      result.Valor = NuevoTemporal();
                         *      result.Codigo += result.Valor + " = 0;\n";
                         *      return result;
                         *  }
                         * }
                         *
                         * if (Op == Operador.DIFERENTE)
                         * {
                         *  if (Op1.GetTipo() != Op2.GetTipo())
                         *  {
                         *      result.Codigo += rsOp1.Codigo;
                         *      result.Codigo += rsOp2.Codigo;
                         *      result.Valor = NuevoTemporal();
                         *      result.Codigo += result.Valor + " = 1;\n";
                         *      return result;
                         *  }
                         * }
                         */

                        if (Op1.GetTipo().IsNumeric() || Op1.GetTipo().IsString() || Op1.GetTipo().IsBoolean())
                        {
                            if (Op2.GetTipo().IsNumeric() || Op2.GetTipo().IsString() || Op2.GetTipo().IsBoolean())
                            {
                                result.Codigo += rsOp1.Codigo;
                                result.Codigo += rsOp2.Codigo;

                                if (Op1.GetTipo().IsString())
                                {
                                    ObtenerValor(rsOp1, result);
                                }
                                if (Op2.GetTipo().IsString())
                                {
                                    ObtenerValor(rsOp2, result);
                                }

                                result.Valor = NuevoTemporal();

                                string op = "";
                                switch (Op)
                                {
                                case Operador.MAYORQUE:
                                    op = ">";
                                    break;

                                case Operador.MENORQUE:
                                    op = "<";
                                    break;

                                case Operador.MAYORIGUALQUE:
                                    op = ">=";
                                    break;

                                case Operador.MENORIGUALQUE:
                                    op = "<=";
                                    break;

                                case Operador.IGUAL:
                                    op = "==";
                                    break;

                                case Operador.DIFERENTE:
                                    op = "!=";
                                    break;
                                }

                                result.EtiquetaV = NuevaEtiqueta();
                                result.EtiquetaF = NuevaEtiqueta();

                                if (!Cortocircuito)
                                {
                                    result.Codigo += "if (" + rsOp1.Valor + " " + op + " " + rsOp2.Valor + ") goto " + result.EtiquetaV + ";\n";
                                    result.Codigo += "goto " + result.EtiquetaF + ";\n";

                                    string etiquetaS = NuevaEtiqueta();
                                    result.Codigo += result.EtiquetaV + ":\n";
                                    result.Codigo += result.Valor + " = 1;\n";
                                    result.Codigo += "goto " + etiquetaS + ";\n";
                                    result.Codigo += result.EtiquetaF + ":\n";
                                    result.Codigo += result.Valor + " = 0;\n";
                                    result.Codigo += etiquetaS + ":\n";
                                }
                                else
                                {
                                    result.Codigo    += "ifFalse (" + rsOp1.Valor + " " + op + " " + rsOp2.Valor + ") goto " + result.EtiquetaV + ";\n";
                                    result.Codigo    += "goto " + result.EtiquetaF + ";\n";
                                    result.EtiquetaV += ":\n";
                                    result.EtiquetaF += ":\n";
                                }
                            }
                            else
                            {
                                errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna));
                            }
                        }
                        else
                        {
                            errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna));
                        }
                    }
                    else
                    {
                        if (Op == Operador.IGUAL || Op == Operador.DIFERENTE) /*con objetos solo se puede == !=*/
                        {
                            result.Codigo += rsOp1.Codigo;
                            result.Codigo += rsOp2.Codigo;
                            result.Valor   = NuevoTemporal();

                            if (Op == Operador.IGUAL)
                            {
                                if (Op1.GetTipo().Tip == Op2.GetTipo().Tip)
                                {
                                    /*comparar objetos*/
                                }
                                else
                                {
                                    result.Codigo += result.Valor + " = 0;\n";
                                }
                            }
                            else
                            {
                                if (Op1.GetTipo().Tip == Op2.GetTipo().Tip)
                                {
                                    /*comparar objetos*/
                                }
                                else
                                {
                                    result.Codigo += result.Valor + " = 1;\n";
                                }
                            }
                        }
                        else
                        {
                            errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna));
                        }
                    }
                }
                else
                {
                    errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna));
                }
            }
            else
            {
                if (Op1 is Identificador objeto)
                {
                    if (Op2 is Identificador c)
                    {
                        Sim sim = e.GetGlobal(objeto.Id);
                        if (sim != null)
                        {
                            if (sim.Tipo.IsObject())
                            {
                                Sim clase = e.GetClase(c.Id);
                                if (clase != null)
                                {
                                    Tipo.Tip = Tipo.Type.BOOLEAN;

                                    if (sim.Tipo.Objeto.Equals(c.Id))
                                    {
                                        if (Op == Operador.IS)
                                        {
                                            result.Valor = "1";
                                        }
                                        else
                                        {
                                            result.Valor = "0";
                                        }
                                    }
                                    else
                                    {
                                        if (Op == Operador.IS)
                                        {
                                            result.Valor = "0";
                                        }
                                        else
                                        {
                                            result.Valor = "1";
                                        }
                                    }

                                    result.EtiquetaV = NuevaEtiqueta();
                                    result.EtiquetaF = NuevaEtiqueta();

                                    result.Codigo    += "ifFalse (" + result.Valor + " == 1) goto " + result.EtiquetaV + ";\n";
                                    result.Codigo    += "goto " + result.EtiquetaF + ";\n";
                                    result.EtiquetaV += ":\n";
                                    result.EtiquetaF += ":\n";

                                    return(result);
                                }
                            }
                        }
                    }
                }
                errores.AddLast(new Error("Semántico", "Error de tipos en operación relacional.", Linea, Columna));
            }

            return(result);
        }