/// <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); } } } }
/// <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); } }
/// <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; } } }
/// <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"); } } } } } }