Exemple #1
0
        /// <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");
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        ///		Lee una sentencia for
        /// </summary>
        private InstructionBase ReadCommandFor(Token token)
        {
            InstructionFor instruction = new InstructionFor(token);
            Token          nextToken   = GetToken(true);

            // Lee la variable
            if (nextToken.Type == Token.TokenType.Variable)
            {
                // Asigna la variable
                instruction.IndexVariable = ReadVariableIdentifier(GetToken(), out string error);
                // Comprueba si hay algún error antes de continuar
                if (!string.IsNullOrWhiteSpace(error))
                {
                    instruction.Error = error;
                }
                else
                {
                    // Signo igual
                    nextToken = GetToken(true);
                    if (nextToken.Type != Token.TokenType.Equal)
                    {
                        instruction.Error = "Falta el signo igual en el bucle for";
                    }
                    else
                    {
                        // Quita el igual
                        GetToken();
                        // Lee el valor inicial
                        instruction.StartValue    = ReadExpression(ExpressionReaderMode.Normal, out error);
                        instruction.StartValueRPN = _expressionEvaluator.ConvertToRPN(instruction.StartValue);
                        if (!string.IsNullOrEmpty(error))
                        {
                            instruction.Error = error;
                        }
                        else
                        {
                            // Sentencia to
                            nextToken = GetToken(true);
                            if (nextToken.Type != Token.TokenType.Sentence ||
                                !nextToken.Content.Equals("to", StringComparison.CurrentCultureIgnoreCase))
                            {
                                instruction.Error = "Falta la sentencia to en el bucle for";
                            }
                            else
                            {
                                // Quita el to
                                nextToken = GetToken();
                                // Lee el valor final
                                instruction.EndValue    = ReadExpression(ExpressionReaderMode.Normal, out error);
                                instruction.EndValueRPN = _expressionEvaluator.ConvertToRPN(instruction.EndValue);
                                if (!string.IsNullOrEmpty(error))
                                {
                                    instruction.Error = error;
                                }
                                else
                                {
                                    // Sentencia step
                                    nextToken = GetToken(true);
                                    // Obtiene el valor del incremento (si es necesario)
                                    if (nextToken.Type == Token.TokenType.Sentence &&
                                        nextToken.Content.Equals("step", StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        // Quita el step
                                        GetToken();
                                        // Lee el valor del step
                                        instruction.StepValue    = ReadExpression(ExpressionReaderMode.Normal, out error);
                                        instruction.StepValueRPN = _expressionEvaluator.ConvertToRPN(instruction.StepValue);
                                        // Comprueba el error y lee las instrucciones
                                        if (!string.IsNullOrEmpty(error))
                                        {
                                            instruction.Error = error;
                                        }
                                    }
                                    // Lee las instrucciones del for
                                    if (!instruction.IsError)
                                    {
                                        token = ReadInstructions(instruction.Instructions);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                instruction.Error = "Debe existir una variable después del for";
            }
            // Devuelve la instrucción
            return(instruction);
        }