Catrobat.IDE.Core.Formulas.FormulaInterpreter.InterpretOperators C# (CSharp) Method

InterpretOperators() private method

Attaches the children of FormulaNodePrefixOperator and FormulaNodeInfixOperator.
private InterpretOperators ( IEnumerable tokens, IEnumerable lookAhead ) : IEnumerable
tokens IEnumerable
lookAhead IEnumerable
return IEnumerable
        private IEnumerable<IFormulaToken> InterpretOperators(IEnumerable<IFormulaToken> tokens, IEnumerable<IFormulaToken> lookAhead)
        {
            var pending = new Stack<FormulaTree>();
            lookAhead = InterpretMinusTokenForward(lookAhead);
            var lookAhead2 = lookAhead.GetEnumerator();
            foreach (var context in tokens.WithContext())
            {
                if (IsCancellationRequested) yield break;
                var previousToken = context[0];
                var token = context[1];
                if (token == null) yield break;

                // yield parameter separators
                if (token is FormulaTokenParameterSeparator)
                {
                    yield return token;
                    continue;
                }
                var token2 = (FormulaTree) token;
                var operatorToken = token2 as IFormulaOperator;

                // advance lookAhead parallel to tokens
                var nextIndex = GetOrigin(token).End;
                var nextToken = lookAhead2.FirstOrDefault(token3 => GetOrigin(token3).Start == nextIndex);

                // stash operators
                if (operatorToken != null)
                {
                    if ((previousToken == null || previousToken is FormulaTokenParameterSeparator) && operatorToken is FormulaNodeInfixOperator)
                    {
                        SetParsingError(
                            source: Range.Empty(GetOrigin(token2).Start),
                            message: AppResourcesHelper.Get("FormulaInterpreter_Operator_LeftEmptyInfixOperator"));
                        yield break;
                    }
                    if (nextToken == null || nextToken is FormulaTokenParameterSeparator || nextToken is FormulaNodeInfixOperator)
                    {
                        SetParsingError(
                            source: Range.Empty(GetOrigin(token2).End),
                            message: operatorToken is FormulaNodePrefixOperator
                                ? AppResourcesHelper.Get("FormulaInterpreter_Operator_EmptyPrefixOperator")
                                : AppResourcesHelper.Get("FormulaInterpreter_Operator_RightEmptyInfixOperator"));
                        yield break;
                    }

                    pending.Push(token2);
                    continue;
                }

                // merge with pending tokens (regarding operator order)
                var nextInfixOperatorToken = nextToken as FormulaNodeInfixOperator;
                if (nextInfixOperatorToken == null || (pending.Count != 0 && ((IFormulaOperator) pending.Peek()).Order >= nextInfixOperatorToken.Order))
                {
                    while (pending.Count != 0)
                    {
                        var pendingOperator = pending.Pop();

                        // attach token to prefix operator
                        var pendingPrefixOperator = pendingOperator as FormulaNodePrefixOperator;
                        if (pendingPrefixOperator != null)
                        {
                            var numberToken = token2 as FormulaNodeNumber;

                            // merge negative sign and number
                            if (numberToken != null && pendingPrefixOperator is FormulaNodeNegativeSign)
                            {
                                numberToken.Value *= -1;
                                SetOrigin(token2, new[] {pendingOperator, token2});
                            }
                            else
                            {
                                pendingPrefixOperator.Child = token2;
                                SetOrigin(pendingPrefixOperator, new[] {pendingOperator, token2});
                                token2 = pendingOperator;
                            }
                        }

                        // attach token to infix operator
                        var pendingInfixOperator = pendingOperator as FormulaNodeInfixOperator;
                        if (pendingInfixOperator != null)
                        {
                            pendingInfixOperator.LeftChild = pending.Pop();
                            pendingInfixOperator.RightChild = token2;
                            SetOrigin(pendingInfixOperator,
                                new[] {pendingInfixOperator.LeftChild, pendingOperator, token2});
                            token2 = pendingOperator;
                        }
                    }
                }

                // stash to infix operator attached tokens
                if (nextInfixOperatorToken != null)
                {
                    pending.Push(token2);
                    continue;
                }

                // yield finished or unattached tokens
                yield return token2;
            }
        }