public override object Execute(Ambit ambit)
        {
            try
            {
                var val = this.value.Execute(ambit);

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

                Identifier variable = ambit.getVariable(id);

                /**
                 * VALIDAR EXISTENCIA
                 */
                if (!variable.IsNull)
                {
                    /**
                     * VERIFICA QUE NO SEA CONSTABTE
                     */
                    if (variable.Esconstante)
                    {
                        setError("No se puede cambiar el valor a una constante", row, column);
                        return(null);
                    }
                    else
                    {
                        /**
                         * VALIDAR VALOR: VERIFICA SI EL TIPO DE LA VARIABLE ES IGUAL AL DEL VALOR A ASIGNAR
                         */
                        if (variable.DataType == val.getDataType)
                        {
                            ambit.setVariable(id, val.Value, val.getDataType, false, "Variable");
                            return(variable.Value);
                        }
                        else
                        {
                            setError("El tipo " + val.getDataType + " no es asignable con " + variable.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.Value.ToString();
                            ambit.setFunction(Id, function);
                            return(new Returned(function.Retorno, function.Tipe));
                        }
                        else
                        {
                            setError("El tipo " + val.getDataType + " no es asignable con " + variable.DataType, 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);
            }
        }
Пример #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 funcion_llamada = ambit.getFuncion(this.id);
                if (funcion_llamada == null)
                {
                    set_error("La funcion '" + this.id + "' no esta definido", row, column);
                    return(new Returned());
                }

                if (funcion_llamada.Parametos.Count != parametros.Count)
                {
                    set_error("La funcion '" + this.id + "' no recibe la misma cantidad de parametros", row, column);
                    return(new Returned());
                }
                //GUARDAR LOS PARAMETROS EN LA TABLA DE SIMBOLOS

                Ambit function_ambit = new Ambit();


                if (funcion_llamada.IsProcedure)
                {
                    set_error("El procedimiento'" + this.id + "' no puede asignarse como valor de retorno", row, column);
                    return(new Returned());
                }
                else
                {
                    function_ambit = new Ambit(ambit, "Function_" + funcion_llamada.Id, "Function", false);
                }



                //FOREACH PARA GUARDAR LOS PARAMETROS EN EL AMBITO,
                //LOS PARAMETROS QUE RECIBE LA FUNCION CUANDO SE DECLARA SON 'DECLARACIONES'
                //POR TANTO AL HACER EL EXECUTE LA VARIABLE SE GUARDA EN EL AMBITO QUE SE ENVIA
                foreach (var param in funcion_llamada.Parametos)
                {
                    param.Execute(function_ambit);
                }
                //SE ASIGNAN LOS VALORES RECIBIDOS A LOS PARAMETROS DE LA FUNCION
                for (int i = 0; i < parametros.Count; i++)
                {
                    var variable = (Declaration)(funcion_llamada.getParameterAt(i));


                    if (variable.Referencia)
                    {
                        if (parametros[i] is Access)
                        {
                            Access acceso = (Access)parametros[i];
                            funcion_llamada.Parametros_referencia.Add(new SimboloReferencia(variable.Id, acceso.Id));
                        }
                        else if (parametros[i] is Access_array)
                        {
                        }
                    }

                    var result = ((Expression)parametros[i]).Execute(ambit);

                    if (variable.getDataType == result.getDataType)
                    {
                        function_ambit.setVariableFuncion(variable.Id, result.Value, result.getDataType, false, "Parametro");
                    }
                    else
                    {
                        set_error("El tipo " + result.getDataType + " no es asignable con " + variable.getDataType, row, column);
                        return(new Returned());
                    }
                }

                //GUARDA LAS VARIABLES QUE ESTEN DECLARADAS EN LA FUNCION

                if (funcion_llamada.Declaraciones.Count > 0)
                {
                    foreach (var declaracion in funcion_llamada.Declaraciones)
                    {
                        declaracion.Execute(function_ambit);
                    }
                }



                //EJECUCION DEL CODIGO

                var funcion_Elementos = funcion_llamada.Sentences.Execute(function_ambit);

                //si viene null significa que viene error
                if (funcion_Elementos == null)
                {
                    return(new Returned());
                }

                else
                {
                    if (funcion_llamada.IsProcedure)
                    {
                        if (funcion_Elementos is Instruction)
                        {
                            var inst = (Instruction)funcion_Elementos;
                            if (inst.Name.Equals("Exit"))
                            {
                                Exit ex = (Exit)funcion_Elementos;
                                set_error("Los procediminetos no pueden retornar ningun valor", ex.Row, ex.Column);
                                return(new Returned());
                            }
                        }
                        if (funcion_Elementos is Break)
                        {
                            var r = (Break)funcion_Elementos;
                            set_error("La sentencia Break solo puede aparece en ciclos o en la sentencia CASE", r.Row, r.Column);
                        }
                        else if (funcion_Elementos is Continue)
                        {
                            var r = (Continue)funcion_Elementos;
                            set_error("La sentencia Continue solo puede aparece en ciclos", r.Row, r.Column);
                        }
                    }
                    else
                    {
                        if (funcion_Elementos is Instruction)
                        {
                            var inst = (Instruction)funcion_Elementos;
                            if (inst.Name.Equals("Exit"))
                            {
                                var response = ((Exit)funcion_Elementos);

                                if (response.Return_func_return)
                                {
                                    GraphController.Instance.getAmbitoGraficar(function_ambit, false);
                                    //SINTETIZA LOS PARAMETROS POR REFERENCIA
                                    sintetizar_referencia(function_ambit, funcion_llamada);

                                    switch (funcion_llamada.Tipe)
                                    {
                                    case DataType.INTEGER:
                                        return(new Returned(int.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));

                                    case DataType.STRING:
                                        return(new Returned((funcion_llamada.Retorno), funcion_llamada.Tipe));

                                    case DataType.BOOLEAN:
                                        return(new Returned(bool.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));

                                    case DataType.REAL:
                                        return(new Returned(double.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));
                                    }
                                }
                                else
                                {
                                    var ext    = (Exit)funcion_Elementos;
                                    var result = (ext).Value.Execute(function_ambit);
                                    //HAY ERROR
                                    if (result.getDataType == DataType.ERROR || result == null)
                                    {
                                        return(new Returned());
                                    }


                                    //VERIFICA QUE EL TIPO DE RETORNO SEA VALIDO
                                    if (result.getDataType == funcion_llamada.Tipe)
                                    {
                                        //SINTETIZA LOS PARAMETROS POR REFERENCIA
                                        sintetizar_referencia(function_ambit, funcion_llamada);
                                        GraphController.Instance.getAmbitoGraficar(function_ambit, false);

                                        switch (funcion_llamada.Tipe)
                                        {
                                        case DataType.INTEGER:
                                            return(new Returned((int)result.Value, result.getDataType));

                                        case DataType.STRING:
                                            return(new Returned((string)result.Value, result.getDataType));

                                        case DataType.BOOLEAN:
                                            return(new Returned((bool)result.Value, result.getDataType));

                                        case DataType.REAL:
                                            return(new Returned((double)result.Value, result.getDataType));
                                        }
                                    }
                                    else
                                    {
                                        set_error("Tipos incompatibles, la funcion '" + funcion_llamada.Id + "' retorna " + funcion_llamada.Tipe + " en lugar de" + result.getDataType, ext.Row, ext.Column);
                                        return(new Returned());
                                    }
                                }
                            }
                        }
                        else if (funcion_Elementos is Returned)
                        {
                            //SINTETIZA LOS PARAMETROS POR REFERENCIA
                            sintetizar_referencia(function_ambit, funcion_llamada);
                            GraphController.Instance.getAmbitoGraficar(function_ambit, false);
                            return((Returned)funcion_Elementos);
                        }
                        else
                        {
                            //SINTETIZA LOS PARAMETROS POR REFERENCIA
                            sintetizar_referencia(function_ambit, funcion_llamada);
                            GraphController.Instance.getAmbitoGraficar(function_ambit, false);


                            switch (funcion_llamada.Tipe)
                            {
                            case DataType.INTEGER:
                                return(new Returned(int.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));

                            case DataType.STRING:
                                return(new Returned((funcion_llamada.Retorno), funcion_llamada.Tipe));

                            case DataType.BOOLEAN:
                                return(new Returned(bool.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));

                            case DataType.REAL:
                                return(new Returned(double.Parse(funcion_llamada.Retorno), funcion_llamada.Tipe));
                            }
                        }
                    }
                }
                return(new Returned());
            }
        }