コード例 #1
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Ejecuta las instrucciones de un bucle foreach
        /// </summary>
        private void Execute(InstructionForEach instruction)
        {
            Variable variable = ExpressionComputer.Search(instruction.IndexVariable, out string error);

            if (!string.IsNullOrEmpty(error))
            {
                Compiler.LocalErrors.Add(instruction.Token, error);
            }
            else
            {
                VariablesCollection variables = ExpressionComputer.Search(instruction.ListVariable, out error).Members;

                if (!string.IsNullOrEmpty(error))
                {
                    Compiler.LocalErrors.Add(instruction.Token, error);
                }
                else
                {
                    // Ordena las variables por su índice
                    variables.SortByIndex();
                    // Recorre las variables ejecutando el código (en realidad puede que no fuera necesario comprobar el número de iteraciones porque
                    // la colección de variables no se va a modificar por mucho que lo intente el código Nhaml)
                    for (int index = 0; index < variables.Count && index < Compiler.MaximumRepetitionsLoop; index++)
                    {
                        // Asigna el contenido a la variable
                        variable.Value = variables[index].Value;
                        // Ejecuta las instrucciones
                        Execute(instruction.Instructions);
                    }
                }
            }
        }
コード例 #2
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Ejecuta una instrucción while
        /// </summary>
        private void Execute(InstructionWhile instruction)
        {
            bool end       = false;
            int  loopIndex = 0;

            // Ejecuta las instrucciones en un bucle
            do
            {
                ValueBase result = ExpressionComputer.Evaluate(instruction.ConditionRPN);

                if (result.HasError)
                {
                    Compiler.LocalErrors.Add(instruction.Token, result.Error);
                    end = true;
                }
                else if (!(result is ValueBool))
                {
                    Compiler.LocalErrors.Add(instruction.Token, "El resultado de calcular la expresión no es un valor lógico");
                    end = true;
                }
                else if (!(result as ValueBool).Value)
                {
                    end = true;
                }
                else
                {
                    Execute(instruction.Instructions);
                }
            }while (!end && ++loopIndex < Compiler.MaximumRepetitionsLoop);
        }
コード例 #3
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Obtiene una variable
        /// </summary>
        private ValueBase GetVariable(InstructionVariableIdentifier instruction)
        {
            Variable variable = ExpressionComputer.Search(instruction.Variable, out string error);

            if (!string.IsNullOrWhiteSpace(error))
            {
                Compiler.LocalErrors.Add(instruction.Token, error);
                return(ValueBase.GetError($"## Error al obtener la variable: {error} ##"));
            }
            else if (variable == null)                     // ... nunca se debería dar
            {
                Compiler.LocalErrors.Add(instruction.Token, $"No se encuentra el valor de la variable {instruction.Variable.Name}");
                return(ValueBase.GetError($"## No se encuentra la variable: {instruction.Variable.Name} ##"));
            }
            else
            {
                return(variable.Value);
            }
        }
コード例 #4
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Ejecuta una instrucción if
        /// </summary>
        private void Execute(InstructionIf instruction)
        {
            ValueBase result = ExpressionComputer.Evaluate(instruction.ConditionRPN);

            if (result.HasError)
            {
                Compiler.LocalErrors.Add(instruction.Token, result.Error);
            }
            else if (!(result is ValueBool))
            {
                Compiler.LocalErrors.Add(instruction.Token, "El resultado de calcular la expresión no es un valor lógico");
            }
            else if ((result as ValueBool).Value)
            {
                Execute(instruction.Instructions);
            }
            else
            {
                Execute(instruction.InstructionsElse);
            }
        }
コード例 #5
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Ejecuta una instrucción de asignación
        /// </summary>
        private void Execute(InstructionLet instruction)
        {
            Variable variable = ExpressionComputer.Search(instruction.Variable, out string error);

            if (!string.IsNullOrWhiteSpace(error))
            {
                Compiler.LocalErrors.Add(instruction.Token, error);
            }
            else
            {
                ValueBase value = ExpressionComputer.Evaluate(instruction.ExpressionsRPN);

                if (value.HasError)
                {
                    Compiler.LocalErrors.Add(instruction.Token, value.Error);
                }
                else
                {
                    variable.Value = value;
                }
            }
        }
コード例 #6
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Obtiene los atributos de una instrucción
        /// </summary>
        private string GetAttributes(InstructionNhaml instruction)
        {
            string attributes = "";

            // Añade los parámetros
            foreach (Parameter parameter in instruction.Attributes)
            {
                ValueBase result = ExpressionComputer.Evaluate(parameter.VariableRPN);

                // Añade el nombre
                attributes += $" {parameter.Name}=";
                // Añade el valor
                if (result.HasError)
                {
                    Compiler.LocalErrors.Add(instruction.Token, result.Error);
                }
                else
                {
                    attributes += $"\"{result.Content}\"";
                }
            }
            // Devuelve los atributos
            return(attributes);
        }
コード例 #7
0
ファイル: Interpreter.cs プロジェクト: jbautistam/Compilers
        /// <summary>
        ///		Ejecuta una instrucción for
        /// </summary>
        private void Execute(InstructionFor instruction)
        {
            Variable variableIndex = ExpressionComputer.Search(instruction.IndexVariable, out string error);

            if (!error.IsEmpty())
            {
                Compiler.LocalErrors.Add(instruction.Token, $"Error al obtener la variable índice: {error}");
            }
            else
            {
                ValueBase valueStart = ExpressionComputer.Evaluate(instruction.StartValueRPN);

                if (valueStart.HasError)
                {
                    Compiler.LocalErrors.Add(instruction.Token, $"Error al obtener el valor de inicio del bucle for {valueStart.Error}");
                }
                else if (!(valueStart is ValueNumeric))
                {
                    Compiler.LocalErrors.Add(instruction.Token, "El valor de inicio del bucle for no es un valor numérico");
                }
                else
                {
                    ValueBase valueEnd = ExpressionComputer.Evaluate(instruction.EndValueRPN);

                    if (valueEnd.HasError)
                    {
                        Compiler.LocalErrors.Add(instruction.Token, $"Error al obtener el valor de fin del bucle for {valueEnd.Error}");
                    }
                    else if (!(valueEnd is ValueNumeric))
                    {
                        Compiler.LocalErrors.Add(instruction.Token, "El valor de fin del bucle for no es un valor numérico");
                    }
                    else
                    {
                        ValueBase valueStep;

                        // Obtiene el valor del paso
                        if (instruction.StepValueRPN == null || instruction.StepValueRPN.Count == 0)
                        {
                            valueStep = ValueBase.GetInstance("1");
                        }
                        else
                        {
                            valueStep = ExpressionComputer.Evaluate(instruction.StepValueRPN);
                        }
                        // Comprueba los errores antes de entrar en el bucle
                        if (valueStep.HasError)
                        {
                            Compiler.LocalErrors.Add(instruction.Token, $"Error al obtener el valor de paso del bucle for {valueEnd.Error}");
                        }
                        else if (!(valueEnd is ValueNumeric))
                        {
                            Compiler.LocalErrors.Add(instruction.Token, "El valor de paso del bucle for no es un valor numérico");
                        }
                        else
                        {
                            int indexLoop = 0;
                            int start     = (int)(valueStart as ValueNumeric).Value;
                            int end       = (int)(valueEnd as ValueNumeric).Value;
                            int intStep   = (int)(valueStep as ValueNumeric).Value;
                            int index     = start;

                            // Cambia el valor de la variable de índice
                            variableIndex.Value = ValueBase.GetInstance(index.ToString());
                            // Ejecuta las instrucciones del bucle
                            while (index <= end && indexLoop < Compiler.MaximumRepetitionsLoop)
                            {
                                // Ejecuta las instrucciones del bucle
                                Execute(instruction.Instructions);
                                // Incrementa la variable índice y cambia el valor de la variable
                                index += intStep;
                                variableIndex.Value = ValueBase.GetInstance(index.ToString());
                                // Incrementa el número de iteraciones
                                indexLoop++;
                            }
                            // Comprueba el número de iteraciones
                            if (indexLoop >= Compiler.MaximumRepetitionsLoop)
                            {
                                Compiler.LocalErrors.Add(instruction.Token, "Se ha sobrepasado el número máximo de iteraciones del bucle for");
                            }
                        }
                    }
                }
            }
        }