public override object Execute(Ambit ambit)
        {
            //INSTANCIA GENERADOR C3D
            var generator   = C3DController.Instance;
            var label_print = "";
            var write_Str   = "";

            write_Str += generator.save_comment("Inicia Print PRINTTEMP", cant_tabs, false);

            //FOREACH DE LAS EXPRESIONES A HACER PRINT
            foreach (Expresion el in value)
            {
                if (el is Literal)
                {
                    if (((Literal)el).Type == 3)
                    {
                        var res = ((Literal)el).Value.ToString();
                        write_Str += generator.print_boolean(cant_tabs, res);
                        continue;
                    }
                    if (((Literal)el).Type == 2)
                    {
                        var res = ((Literal)el).Value.ToString();
                        if (res.ToLower().Equals("true") || res.ToLower().Equals("false"))
                        {
                            write_Str += generator.print_boolean(cant_tabs, res);
                            continue;
                        }
                    }
                }
                if (el is Access)
                {
                    label_print = ":" + ((Access)el).Id;
                }

                var element = el.Execute(ambit);
                if (element.IsTemporal)
                {
                    ambit.free_temp(element.getValue());
                }

                write_Str += element.Texto_anterior;

                if (element.getDataType == DataType.ERROR)
                {
                    return(null);
                }
                switch (element.getDataType)
                {
                case DataType.INTEGER:
                    write_Str += generator.generate_print("i", element.getValue(), "(int)", cant_tabs);
                    break;

                case DataType.STRING:

                    generator.Native_str = true;

                    var temp_stack = element.getValue();
                    write_Str += generator.addExpression("T1", temp_stack, "", "", cant_tabs);

                    write_Str += generator.save_code("native_print_str();", cant_tabs);

                    /*var label_temp = generator.newLabel();
                     * generator.addLabel(label_temp, cant_tabs);
                     * var temp_heap = generator.newTemporal();
                     *
                     * generator.get_Heap(temp_heap, temp_stack, cant_tabs);
                     *
                     * var true_label = generator.newLabel();
                     *
                     * generator.add_If(temp_heap, "-1", "==", true_label, cant_tabs);
                     *
                     * generator.generate_print("c", temp_heap, "(int)", cant_tabs);
                     *
                     * generator.addExpression(temp_stack, temp_stack, "1", "+", cant_tabs);
                     *
                     * generator.add_Goto(label_temp, cant_tabs);
                     * generator.addLabel(true_label, cant_tabs);*/

                    break;

                case DataType.BOOLEAN:

                    write_Str += generator.addLabel(element.TrueLabel, cant_tabs);
                    write_Str += generator.addLabel(element.FalseLabel, cant_tabs);
                    write_Str += generator.print_boolean(cant_tabs, element.Valor_original);
                    break;

                case DataType.REAL:
                    write_Str += generator.generate_print("f", element.getValue(), "(float)", cant_tabs);
                    break;

                default:
                    break;
                }
            }
            if (this.isln)
            {
                write_Str += generator.generate_print("c", "10", "(int)", cant_tabs);
            }
            write_Str += generator.save_comment("Fin Print PRINTTEMP", cant_tabs, true);
            write_Str  = generator.replace_temp(label_print, "PRINTTEMP", write_Str);
            return(write_Str);
        }
Beispiel #2
0
        public override object Execute(Ambit ambit)
        {
            try
            {
                var val = this.value.Execute(ambit);

                Identifier variableAmbit = ambit.getVariable(id);
                var        generator     = C3DController.Instance;



                /**
                 * VALIDAR EXISTENCIA
                 */
                if (!variableAmbit.IsNull)
                {
                    /**
                     * VERIFICA QUE NO SEA CONSTABTE
                     */
                    if (variableAmbit.Esconstante)
                    {
                        setError("No se puede cambiar el valor a una constante", row, column);
                        return(null);
                    }
                    else
                    {
                        assignation_string += val.Texto_anterior;

                        if (val == null || val.getDataType == DataType.ERROR)
                        {
                            return(null);
                        }

                        /**
                         * VALIDAR VALOR: VERIFICA SI EL TIPO DE LA VARIABLE ES IGUAL AL DEL VALOR A ASIGNAR
                         */
                        if (variableAmbit.DataType == val.getDataType)
                        {
                            if (val.IsTemporal)
                            {
                                ambit.free_temp(val.Value);
                            }

                            if (variableAmbit.IsGlobal)
                            {
                                if (variableAmbit.DataType == DataType.BOOLEAN)
                                {
                                    var templabel = generator.newLabel();
                                    assignation_string += generator.addLabel(val.TrueLabel, tabs);
                                    assignation_string += generator.set_stack(variableAmbit.Position.ToString(), "1", tabs);
                                    assignation_string += generator.add_Goto(templabel, tabs + 1);
                                    assignation_string += generator.addLabel(val.FalseLabel, tabs);
                                    assignation_string += generator.set_stack(variableAmbit.Position.ToString(), "0", tabs);
                                    assignation_string += generator.addLabel(templabel, tabs);
                                }
                                else
                                {
                                    var tempAux = variableAmbit.Position_global.ToString();
                                    if (variableAmbit.IsReference)
                                    {
                                        var temp = generator.newTemporal();
                                        assignation_string += generator.get_stack(temp, variableAmbit.Position_global.ToString(), tabs);
                                        generator.freeTemp(temp);
                                        tempAux = temp;
                                    }


                                    assignation_string += generator.set_stack(tempAux, val.getValue(), tabs);
                                }
                            }
                            else
                            {
                                var temp = generator.newTemporal();
                                ambit.set_temp(temp);
                                assignation_string += generator.addExpression(temp, "SP", variableAmbit.Position.ToString(), "+", tabs);


                                if (variableAmbit.IsReference)
                                {
                                    var newTemp = generator.newTemporal();
                                    ambit.set_temp(newTemp);
                                    ambit.free_temp(temp);
                                    generator.freeTemp(temp);
                                    assignation_string += generator.get_stack(newTemp, temp, tabs);
                                    temp = newTemp;
                                }



                                if (variableAmbit.DataType == DataType.BOOLEAN)
                                {
                                    generator.freeTemp(temp);
                                    var templabel = generator.newLabel();
                                    assignation_string += generator.addLabel(val.TrueLabel, tabs);
                                    assignation_string += generator.set_stack(temp, "1", tabs);
                                    assignation_string += generator.add_Goto(templabel, tabs + 1);
                                    assignation_string += generator.addLabel(val.FalseLabel, tabs);
                                    assignation_string += generator.set_stack(temp, "0", tabs);
                                    assignation_string += generator.addLabel(templabel, tabs);
                                }
                                else
                                {
                                    generator.freeTemp(temp);
                                    assignation_string += generator.set_stack(temp, val.getValue(), tabs);
                                }
                            }


                            return(assignation_string);
                        }
                        else
                        {
                            setError("El tipo " + val.getDataType + " no es asignable con " + variableAmbit.DataType, row, column);
                            return(null);
                        }
                    }
                }
                else
                {
                    Function function = ambit.getFuncion(id);
                    if (function != null)
                    {
                        if (function.IsProcedure)
                        {
                            setError("No puede asignarse ningun valor al procedimiento '" + id + "' ", row, column);
                            return(null);
                        }

                        /**
                         * VALIDAR VALOR: VERIFICA SI EL TIPO DE LA VARIABLE ES IGUAL AL DEL VALOR A ASIGNAR
                         */
                        if (function.Tipe == val.getDataType)
                        {
                            function.Retorno = val.getValue();
                            ambit.setFunction(Id, function);

                            assignation_string += val.Texto_anterior;
                            assignation_string += generator.set_stack("T13", function.Retorno, tabs);
                        }
                        else
                        {
                            setError("El tipo " + val.getDataType + " no es asignable con " + function.Tipo, row, column);
                            return(null);
                        }
                    }
                    else
                    {
                        setError("La variable '" + id + "' no esta declara", row, column);
                        return(null);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                ConsolaController.Instance.Add("Recuperado de error, Row:" + row + " Col: " + column);
                return(null);
            }
            return(assignation_string);
        }
        public override Returned Execute(Ambit ambit)
        {
            var relational_Str = "";
            var valIz          = this.left.Execute(ambit);

            relational_Str += valIz.Texto_anterior;

            var result = new Returned();

            var generator = C3DController.Instance;

            var op = GetType(this.type);

            switch (op)
            {
            case OpRelational.EQUALS:
                relational_Str += generator.save_comment("Empieza EQUALS", cant_tabs, false);
                //VERIFICA SI EL IZQUIERDO ES REAL O INT
                if (valIz.getDataType == DataType.REAL || valIz.getDataType == DataType.INTEGER)
                {
                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    if (valDer.getDataType == DataType.INTEGER || valDer.getDataType == DataType.REAL)
                    {
                        if (this.TrueLabel == "")
                        {
                            this.TrueLabel = generator.newLabel();
                        }
                        if (this.FalseLabel == "")
                        {
                            this.FalseLabel = generator.newLabel();
                        }
                        ambit.free_temp(valIz.getValue());
                        ambit.free_temp(valDer.getValue());

                        relational_Str += generator.add_If(valIz.getValue(), valDer.getValue(), "==", this.TrueLabel, cant_tabs);
                        relational_Str += generator.add_Goto(this.FalseLabel, cant_tabs);
                        relational_Str += generator.save_comment("Termina EQUALS", cant_tabs, true);

                        result = new Returned("", DataType.BOOLEAN, false, this.TrueLabel, this.FalseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }
                //VERIFICA SI EL IZQUIERDO ES BOOLEAN
                else if (valIz.getDataType == DataType.BOOLEAN)
                {
                    var trueLabel  = generator.newLabel();
                    var falseLabel = generator.newLabel();
                    relational_Str       += generator.addLabel(valIz.TrueLabel, cant_tabs);
                    this.right.TrueLabel  = trueLabel;
                    this.right.FalseLabel = falseLabel;
                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    relational_Str += generator.addLabel(valIz.FalseLabel, cant_tabs);

                    this.right.TrueLabel  = falseLabel;
                    this.right.FalseLabel = trueLabel;
                    valDer          = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    //VERIFICA QUE EL DERECHO SEA BOOLEAN
                    if (valDer.getDataType == DataType.BOOLEAN)
                    {
                        relational_Str += generator.save_comment("Termina EQUALS", cant_tabs, true);
                        ambit.free_temp(valIz.getValue());
                        ambit.free_temp(valDer.getValue());
                        result = new Returned("", DataType.BOOLEAN, false, trueLabel, falseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }
                ////VERIFICA QUE EL IZQUIERDO SEA STRING
                else if (valIz.getDataType == DataType.STRING)
                {
                    generator.Native_equals = true;

                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;


                    if (valDer.getDataType == DataType.STRING)
                    {
                        if (this.TrueLabel == "")
                        {
                            this.TrueLabel = generator.newLabel();
                        }
                        if (this.FalseLabel == "")
                        {
                            this.FalseLabel = generator.newLabel();
                        }



                        var tempo_izq = valIz.Value.ToString();
                        var tempo_der = valDer.Value.ToString();

                        relational_Str += generator.addExpression("T3", tempo_izq, "", "", cant_tabs);
                        relational_Str += generator.addExpression("T4", tempo_der, "", "", cant_tabs);
                        relational_Str += generator.addExpression("T8", "native_cmp_str()", "", "", cant_tabs);
                        relational_Str += generator.add_If("T8", "1", "==", this.TrueLabel, cant_tabs);
                        relational_Str += generator.add_Goto(this.FalseLabel, cant_tabs);

                        ambit.free_temp(tempo_der);
                        ambit.free_temp(tempo_izq);

                        relational_Str += generator.save_comment("Termina EQUALS", cant_tabs, true);

                        result = new Returned("", DataType.BOOLEAN, false, this.TrueLabel, this.FalseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }

                else
                {
                    set_error("Operador '" + this.type + "' NO puede ser aplicado al tipo " + valIz.getDataType, row, column);
                    return(result);
                }


                break;

            case OpRelational.DISCTINCT:
                relational_Str += generator.save_comment("Empieza DISTICT", cant_tabs, false);

                //VERIFICA QUE EL IZQUIERDO ESA REAL O INTEGER
                if (valIz.getDataType == DataType.REAL || valIz.getDataType == DataType.INTEGER)
                {
                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    if (valDer.getDataType == DataType.INTEGER || valDer.getDataType == DataType.REAL)
                    {
                        if (this.TrueLabel == "")
                        {
                            this.TrueLabel = generator.newLabel();
                        }
                        if (this.FalseLabel == "")
                        {
                            this.FalseLabel = generator.newLabel();
                        }
                        ambit.free_temp(valIz.getValue());
                        ambit.free_temp(valDer.getValue());
                        relational_Str += generator.add_If(valIz.getValue(), valDer.getValue(), "!=", this.TrueLabel, cant_tabs);
                        relational_Str += generator.add_Goto(this.FalseLabel, cant_tabs);
                        relational_Str += generator.save_comment("Termina DISTICT", cant_tabs, true);
                        result          = new Returned("", DataType.BOOLEAN, false, this.TrueLabel, this.FalseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }
                else if (valIz.getDataType == DataType.BOOLEAN)
                {
                    var trueLabel  = generator.newLabel();
                    var falseLabel = generator.newLabel();
                    relational_Str       += generator.addLabel(valIz.TrueLabel, cant_tabs);
                    this.right.TrueLabel  = falseLabel;
                    this.right.FalseLabel = trueLabel;
                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    relational_Str += generator.addLabel(valIz.FalseLabel, cant_tabs);

                    this.right.TrueLabel  = trueLabel;
                    this.right.FalseLabel = falseLabel;
                    valDer          = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    //VERIFICA QUE EL DERECHO SEA BOOLEAN
                    if (valDer.getDataType == DataType.BOOLEAN)
                    {
                        ambit.free_temp(valIz.getValue());
                        ambit.free_temp(valDer.getValue());
                        relational_Str += generator.save_comment("Termina DISTICT", cant_tabs, true);
                        result          = new Returned("", DataType.BOOLEAN, false, trueLabel, falseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }
                else
                {
                    set_error("Operador '" + this.type + "' NO puede ser aplicado al tipo " + valIz.getDataType, row, column);
                    return(result);
                }

                break;

            case OpRelational.LESS:
            case OpRelational.LESS_EQUALS:
            case OpRelational.HIGHER:
            case OpRelational.HIGHER_EQUALS:
                relational_Str += generator.save_comment("Empieza " + op, cant_tabs, false);
                if (valIz.getDataType == DataType.REAL || valIz.getDataType == DataType.INTEGER)
                {
                    var valDer = this.right.Execute(ambit);
                    relational_Str += valDer.Texto_anterior;

                    if (valDer.getDataType == DataType.REAL || valDer.getDataType == DataType.INTEGER)
                    {
                        if (this.TrueLabel == "")
                        {
                            this.TrueLabel = generator.newLabel();
                        }
                        if (this.FalseLabel == "")
                        {
                            this.FalseLabel = generator.newLabel();
                        }
                        ambit.free_temp(valIz.getValue());
                        ambit.free_temp(valDer.getValue());
                        relational_Str += generator.add_If(valIz.getValue(), valDer.getValue(), this.type, this.TrueLabel, cant_tabs);
                        relational_Str += generator.add_Goto(this.FalseLabel, cant_tabs);
                        relational_Str += generator.save_comment("Termina " + op, cant_tabs, true);
                        result          = new Returned("", DataType.BOOLEAN, false, this.TrueLabel, this.FalseLabel, relational_Str, "", 0, 0);
                    }
                    else
                    {
                        set_error("Operador '" + this.type + "' NO puede ser aplicado a los tipos " + valIz.getDataType + " con " + valDer.getDataType, row, column);
                        return(result);
                    }
                }
                else
                {
                    set_error("Operador '" + this.type + "' NO puede ser aplicado al tipo " + valIz.getDataType, row, column);
                    return(result);
                }

                break;

            default:
                return(result);
            }

            return(result);
        }