Esempio n. 1
0
        /// <summary>
        ///		Ejecuta una sentencia for
        /// </summary>
        private void ExecuteFor(SentenceFor sentence)
        {
            if (string.IsNullOrWhiteSpace(sentence.Variable))
            {
                AddError("Cant find the variable name for loop index");
            }
            else if (string.IsNullOrWhiteSpace(sentence.StartExpression))
            {
                AddError("Cant find the start expression for loop index");
            }
            else if (string.IsNullOrWhiteSpace(sentence.EndExpression))
            {
                AddError("Cant find the end expression for loop index");
            }
            else
            {
                VariableModel start = GetVariableValue($"StartIndex_Context{Context.Actual.ScopeIndex}", sentence.StartExpression);
                VariableModel end   = GetVariableValue($"EndIndex_Context{Context.Actual.ScopeIndex}", sentence.EndExpression);

                if (start.Type != end.Type)
                {
                    AddError("The types of start and end variable at for loop are distinct");
                }
                else if (start.Type != VariableModel.VariableType.Numeric && start.Type != VariableModel.VariableType.Date)
                {
                    AddError("The value of start and end at for loop must be numeric or date");
                }
                else
                {
                    VariableModel step = GetVariableValue($"StepIndex_Context{Context.Actual.ScopeIndex}", NormalizeStepExpression(sentence.StepExpression));

                    if (step.Value == null)
                    {
                        AddError("Cant find any value to step in for loop");
                    }
                    else
                    {
                        VariableModel index          = new VariableModel(sentence.Variable, start.Value);
                        bool          isPositiveStep = step.IsGreaterThan(0);

                        // Abre un nuevo contexto
                        Context.Add();
                        // Añade la variable al contexto
                        Context.Actual.VariablesTable.Add(sentence.Variable, index.Value);
                        // Ejecuta las sentencias
                        while (!IsEndForLoop(index, end, isPositiveStep))
                        {
                            // Ejecuta las sentencias
                            Execute(sentence.Sentences);
                            // Incrementa / decrementa el valor al índice (el step debería ser -x si es negativo, por tanto, siempre se suma)
                            index.Sum(step);
                            // y lo ajusta en el contexto
                            Context.Actual.VariablesTable.Add(index);
                        }
                        // Elimina el contexto
                        Context.Pop();
                    }
                }
            }
        }
        /// <summary>
        ///		Ejecuta el contenido de un bucle for
        /// </summary>
        private async Task ExecuteForLoopAsync(SentenceFor sentence, VariableModel start, VariableModel end, VariableModel step, CancellationToken cancellationToken)
        {
            VariableModel index          = new VariableModel(sentence.Variable.Name, ConvertSymbolType(sentence.Variable.Type));
            bool          isPositiveStep = step.IsGreaterThan(0);

            // Asigna el valor inicial a la variable de índice
            index.Value = start.Value;
            // Abre un nuevo contexto
            Context.Add();
            // Añade la variable al contexto
            Context.Actual.VariablesTable.Add(index);
            // Ejecuta las sentencias
            while (!IsEndForLoop(index, end, isPositiveStep) && !Stopped)
            {
                // Ejecuta las sentencias
                await ExecuteAsync(sentence.Sentences, cancellationToken);

                // Incrementa / decrementa el valor al índice (el step debería ser -x si es negativo, por tanto, siempre se suma)
                index.Sum(step);
                // y lo ajusta en el contexto
                Context.Actual.VariablesTable.Add(index);
            }
            // Elimina el contexto
            Context.Pop();
        }
        /// <summary>
        ///		Carga una sentencia for
        /// </summary>
        private SentenceBase LoadSentenceFor(MLNode rootML, string pathBase)
        {
            SentenceFor sentence = new SentenceFor();

            // Asigna las propiedades
            sentence.Variable        = rootML.Attributes[TagVariable].Value;
            sentence.StartExpression = rootML.Attributes[TagStart].Value;
            sentence.EndExpression   = rootML.Attributes[TagEnd].Value;
            sentence.StepExpression  = rootML.Attributes[TagStep].Value;
            // Carga las sentencias
            sentence.Sentences.AddRange(LoadSentences(rootML.Nodes, pathBase));
            // Devuelve la sentencia
            return(sentence);
        }
        /// <summary>
        ///		Ejecuta una sentencia for
        /// </summary>
        private async Task ExecuteForAsync(SentenceFor sentence, CancellationToken cancellationToken)
        {
            if (string.IsNullOrWhiteSpace(sentence.Variable.Name))
            {
                AddError("Cant find the variable name for loop index");
            }
            else if (sentence.StartExpression.Count == 0)
            {
                AddError("Cant find the start expression for loop index");
            }
            else if (sentence.EndExpression.Count == 0)
            {
                AddError("Cant find the end expression for loop index");
            }
            else
            {
                VariableModel start = await GetVariableValueAsync($"StartIndex_Context_{Context.Actual.ScopeIndex}", sentence.StartExpression, cancellationToken);

                VariableModel end = await GetVariableValueAsync($"EndIndex_Context_{Context.Actual.ScopeIndex}", sentence.EndExpression, cancellationToken);

                // Si se han podido evaluar las expresiones de inicio y fin
                if (!Stopped)
                {
                    if (start.Type != end.Type)
                    {
                        AddError("The types of start and end variable at for loop are distinct");
                    }
                    else if (start.Type != VariableModel.VariableType.Numeric && start.Type != VariableModel.VariableType.Date)
                    {
                        AddError("The value of start and end at for loop must be numeric or date");
                    }
                    else
                    {
                        VariableModel step = await GetVariableValueAsync($"StepIndex_Context_{Context.Actual.ScopeIndex}", sentence.StepExpression, cancellationToken);

                        // Asigna el valor a la expresión si no tenía
                        if (step.Value == null)
                        {
                            step.Value = 1;
                        }
                        // Ejecuta el bucle for
                        await ExecuteForLoopAsync(sentence, start, end, step, cancellationToken);
                    }
                }
            }
        }
 /// <summary>
 ///		Transforma una sentencia for: como en python se utiliza un rango pero en un script SQL tenemos un for con inicio, fin y paso, lo transformamos
 ///	en una sentencia while
 /// </summary>
 private void TransformFor(SentenceFor sentence)
 {
     // Añade la declaración del índice
     AddSentence(string.Empty);
     AddSentence(sentence.Variable.Name + " = " + TransformExpressions(sentence.StartExpression));
     // Añade la sentencia while (con <=)
     AddSentence("while " + sentence.Variable.Name + " <= " + TransformExpressions(sentence.EndExpression) + ":");
     // Añade las sentencias hija
     AddIndent();
     Transform(sentence.Sentences);
     // Añade el step
     if (sentence.StepExpression.Count == 0)
     {
         AddSentence($"{sentence.Variable.Name} = {sentence.Variable.Name} + 1");
     }
     else
     {
         AddSentence($"{sentence.Variable.Name} = {sentence.Variable.Name} + {TransformExpressions(sentence.StepExpression)}");
     }
     // Y quita la indentación
     RemoveIndent();
 }