internal override void Interpret(IInterpretContext ctx) { // lookup the object we are foreach-ing object obj = this.Expression.Evaluate(ctx); // create the variable by adding the expression value to the bag as "Within" ctx.Bag[this.Expression.Within] = obj; ctx.MoveNext(); }
internal override void Interpret(IInterpretContext ctx) { if (!ctx.State.ContainsKey("CurrentIf")) { ctx.State.Add( "CurrentIf", new Stack<bool>() ); } Stack<bool> CurrentIf = (Stack<bool>)ctx.State["CurrentIf"]; Stack<object> CurrentTag = ctx.CurrentTag; IfTagType? currentIfTagType = CurrentTag.Count > 0 && CurrentTag.Peek() is IfTagType ? (IfTagType?)CurrentTag.Peek() : null; bool val = false; int ifDepth = 0; bool found = false; switch (this.TagType) { case IfTagType.If: val = this.Expression.EvaluateAsBoolean(ctx); CurrentTag.Push(IfTagType.If); CurrentIf.Push(val); if (val) { ctx.MoveNext(); } else { // move forward to the next ELSE or ELSE IF or ENDIF found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup) m).TagType; if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = ( loopIfTagType == IfTagType.ElseIf || loopIfTagType == IfTagType.Else || loopIfTagType == IfTagType.EndIf ); } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); } break; case IfTagType.ElseIf: // make sure we have a logically correct parent if (currentIfTagType == null || ( currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf ) ) { throw new ImpressionInterpretException("Expected an IF or ELSEIF before ELSE", this); } // if the current IF was false, process this ELSEIF if (!CurrentIf.Peek()) { val = this.Expression.EvaluateAsBoolean(ctx); // remove current tag, add "elseif" CurrentTag.Pop(); CurrentTag.Push(IfTagType.ElseIf); if (val) { // add us to the if CurrentIf.Pop(); CurrentIf.Push(val); ctx.MoveNext(); return; } } // move forward to the next ELSE IF or ENDIF found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup) m).TagType; // if its an if, then increment the ifDepth if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = (loopIfTagType == IfTagType.ElseIf || loopIfTagType == IfTagType.Else || loopIfTagType == IfTagType.EndIf); } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); break; case IfTagType.Else: // make sure we have a logically correct parent if (currentIfTagType == null || (currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf)) { throw new ImpressionInterpretException("Expected an IF or ELSEIF before ELSE", this); } // if the last if wasn't true then check this otherwise, just skip if (!CurrentIf.Peek()) { // rejig the if CurrentIf.Push(!CurrentIf.Pop()); // remove current tag, add "else" CurrentTag.Pop(); CurrentTag.Push(IfTagType.Else); // move to the next markup ctx.MoveNext(); } else { // move to the next markup //ctx.MoveNext(); // move forward to the next ENDIF at this level found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup)m).TagType; // if its an if, then increment the ifDepth if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = loopIfTagType == IfTagType.EndIf; } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); } break; case IfTagType.EndIf: // make sure we have a logically correct parent if (currentIfTagType == null || (currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf && currentIfTagType != IfTagType.Else)) { throw new ImpressionInterpretException("Expected an IF, ELSEIF or ELSE before ENDIF", this); } // rejig the if CurrentIf.Pop(); // remove current tag CurrentTag.Pop(); ctx.MoveNext(); break; } }
internal override void Interpret(IInterpretContext ctx) { // this is a literal, simply append our content and increment position in parselist ctx.Builder.Append(this.EvaluateAsString(ctx)); ctx.MoveNext(); }
internal override void Interpret(IInterpretContext ctx) { Stack<object> CurrentTag = ctx.CurrentTag; ForEachTagType? currentForEachTagType = CurrentTag.Count > 0 && CurrentTag.Peek() is ForEachTagType ? (ForEachTagType?)CurrentTag.Peek() : null; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorKey")) { ctx.State.Add("CurrentForEach_EnumeratorKey", new Stack<String>()); } Stack<String> currentEnumeratorKey = (Stack<String>)ctx.State["CurrentForEach_EnumeratorKey"]; if (!ctx.State.ContainsKey("CurrentForEach_Enumerator")) { ctx.State.Add("CurrentForEach_Enumerator", new Stack<IEnumerator>()); } Stack<IEnumerator> currentEnumerator = (Stack<IEnumerator>)ctx.State["CurrentForEach_Enumerator"]; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorIndex")) { ctx.State.Add("CurrentForEach_EnumeratorIndex", new Stack<int>()); } Stack<int> currentEnumeratorIndex = (Stack<int>)ctx.State["CurrentForEach_EnumeratorIndex"]; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorStartIndex")) { ctx.State.Add("CurrentForEach_EnumeratorStartIndex", new Stack<int>()); } Stack<int> currentEnumeratorStartIndex = (Stack<int>)ctx.State["CurrentForEach_EnumeratorStartIndex"]; switch (this.TagType) { case ForEachTagType.ForEach: // lookup the object we are foreach-ing object obj = this.Expression.Evaluate(ctx); // make sure the obj inherits IEnumerable if (obj != null && obj.GetType().GetInterface("IEnumerable") != null) { // get an enumerator to loop with IEnumerator en = ((IEnumerable)obj).GetEnumerator(); // move to first item if (en.MoveNext()) { // add the current iteration to the bag as "Within" ctx.Bag[this.Expression.Within] = en.Current; // save the current within currentEnumeratorKey.Push(this.Expression.Within); currentEnumeratorIndex.Push(1); ctx.Bag[currentEnumeratorKey.Peek() + ".Position"] = 1; // add the enumerator to the stack currentEnumerator.Push(en); // save the position this enumeration starts at ctx.MoveNext(); currentEnumeratorStartIndex.Push(ctx.ListPosition); CurrentTag.Push(ForEachTagType.ForEach); return; } //// add the enumerator to the stack //currentEnumerator.Push(en); //// save the position this enumeration starts at //ctx.MoveNext(); //currentEnumeratorStartIndex.Push(ctx.ListPosition); //CurrentTag.Push(ForEachTagType.ForEach); //return; } // not enumerable, null enumerator or unable to move next indicates no items in data // find the next "NEXT" but track how many foreach's there were int toFind = 1; int found = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is ForEachTagMarkup) { ForEachTagType loopForEachTagType = ((ForEachTagMarkup)m).TagType; if (loopForEachTagType == ForEachTagType.Next) { found++; } else if (loopForEachTagType == ForEachTagType.ForEach) { toFind++; } } } while (found < toFind || ctx.ListPosition >= ctx.ParseList.Count); ctx.MoveNext(); break; case ForEachTagType.Next: IEnumerator enumerator = (currentEnumerator.Count > 0 ? currentEnumerator.Peek() : null); string key = (currentEnumeratorKey.Count > 0 ? currentEnumeratorKey.Peek() : null); // make sure that the current tag is a foreach if (currentForEachTagType == null || currentForEachTagType != ForEachTagType.ForEach) { throw new ImpressionInterpretException("NEXT tag detected without a corresponding FOREACH Tag", this); } // get the current enumerator if (enumerator != null) { if (enumerator.MoveNext()) { // there is another record in the enumerator ctx.Bag[currentEnumeratorKey.Peek()] = enumerator.Current; int position = currentEnumeratorIndex.Pop() + 1; currentEnumeratorIndex.Push(position); ctx.Bag[currentEnumeratorKey.Peek() + ".Position"] = position; //ctx.Bag["Position"] = position; ctx.MoveTo(currentEnumeratorStartIndex.Peek()); } else { // we're finished the enumeration, clean up // but make sure there is something on the stacks first, a list of // nothing will not get a position or key pushed onto stack if (currentEnumeratorKey.Count > 0) { string currentKey = currentEnumeratorKey.Peek(); string positionKey = currentKey + ".Position"; ctx.Bag.Remove(positionKey); ctx.Bag.Remove(currentKey); currentEnumeratorIndex.Pop(); currentEnumeratorKey.Pop(); } currentEnumerator.Pop(); currentEnumeratorStartIndex.Pop(); CurrentTag.Pop(); ctx.MoveNext(); } } else { throw new ImpressionInterpretException("Next tag detected without a corresponding Enumerator", this); } break; } }
internal override void Interpret(IInterpretContext ctx) { Stack <object> CurrentTag = ctx.CurrentTag; ForEachTagType?currentForEachTagType = CurrentTag.Count > 0 && CurrentTag.Peek() is ForEachTagType ? (ForEachTagType?)CurrentTag.Peek() : null; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorKey")) { ctx.State.Add("CurrentForEach_EnumeratorKey", new Stack <String>()); } Stack <String> currentEnumeratorKey = (Stack <String>)ctx.State["CurrentForEach_EnumeratorKey"]; if (!ctx.State.ContainsKey("CurrentForEach_Enumerator")) { ctx.State.Add("CurrentForEach_Enumerator", new Stack <IEnumerator>()); } Stack <IEnumerator> currentEnumerator = (Stack <IEnumerator>)ctx.State["CurrentForEach_Enumerator"]; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorIndex")) { ctx.State.Add("CurrentForEach_EnumeratorIndex", new Stack <int>()); } Stack <int> currentEnumeratorIndex = (Stack <int>)ctx.State["CurrentForEach_EnumeratorIndex"]; if (!ctx.State.ContainsKey("CurrentForEach_EnumeratorStartIndex")) { ctx.State.Add("CurrentForEach_EnumeratorStartIndex", new Stack <int>()); } Stack <int> currentEnumeratorStartIndex = (Stack <int>)ctx.State["CurrentForEach_EnumeratorStartIndex"]; switch (this.TagType) { case ForEachTagType.ForEach: // lookup the object we are foreach-ing object obj = this.Expression.Evaluate(ctx); // make sure the obj inherits IEnumerable if (obj != null && obj.GetType().GetInterface("IEnumerable") != null) { // get an enumerator to loop with IEnumerator en = ((IEnumerable)obj).GetEnumerator(); // move to first item if (en.MoveNext()) { // add the current iteration to the bag as "Within" ctx.Bag[this.Expression.Within] = en.Current; // save the current within currentEnumeratorKey.Push(this.Expression.Within); currentEnumeratorIndex.Push(1); ctx.Bag[currentEnumeratorKey.Peek() + ".Position"] = 1; // add the enumerator to the stack currentEnumerator.Push(en); // save the position this enumeration starts at ctx.MoveNext(); currentEnumeratorStartIndex.Push(ctx.ListPosition); CurrentTag.Push(ForEachTagType.ForEach); return; } //// add the enumerator to the stack //currentEnumerator.Push(en); //// save the position this enumeration starts at //ctx.MoveNext(); //currentEnumeratorStartIndex.Push(ctx.ListPosition); //CurrentTag.Push(ForEachTagType.ForEach); //return; } // not enumerable, null enumerator or unable to move next indicates no items in data // find the next "NEXT" but track how many foreach's there were int toFind = 1; int found = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is ForEachTagMarkup) { ForEachTagType loopForEachTagType = ((ForEachTagMarkup)m).TagType; if (loopForEachTagType == ForEachTagType.Next) { found++; } else if (loopForEachTagType == ForEachTagType.ForEach) { toFind++; } } } while (found < toFind || ctx.ListPosition >= ctx.ParseList.Count); ctx.MoveNext(); break; case ForEachTagType.Next: IEnumerator enumerator = (currentEnumerator.Count > 0 ? currentEnumerator.Peek() : null); string key = (currentEnumeratorKey.Count > 0 ? currentEnumeratorKey.Peek() : null); // make sure that the current tag is a foreach if (currentForEachTagType == null || currentForEachTagType != ForEachTagType.ForEach) { throw new ImpressionInterpretException("NEXT tag detected without a corresponding FOREACH Tag", this); } // get the current enumerator if (enumerator != null) { if (enumerator.MoveNext()) { // there is another record in the enumerator ctx.Bag[currentEnumeratorKey.Peek()] = enumerator.Current; int position = currentEnumeratorIndex.Pop() + 1; currentEnumeratorIndex.Push(position); ctx.Bag[currentEnumeratorKey.Peek() + ".Position"] = position; //ctx.Bag["Position"] = position; ctx.MoveTo(currentEnumeratorStartIndex.Peek()); } else { // we're finished the enumeration, clean up // but make sure there is something on the stacks first, a list of // nothing will not get a position or key pushed onto stack if (currentEnumeratorKey.Count > 0) { string currentKey = currentEnumeratorKey.Peek(); string positionKey = currentKey + ".Position"; ctx.Bag.Remove(positionKey); ctx.Bag.Remove(currentKey); currentEnumeratorIndex.Pop(); currentEnumeratorKey.Pop(); } currentEnumerator.Pop(); currentEnumeratorStartIndex.Pop(); CurrentTag.Pop(); ctx.MoveNext(); } } else { throw new ImpressionInterpretException("Next tag detected without a corresponding Enumerator", this); } break; } }
internal override void Interpret(IInterpretContext ctx) { if (!ctx.State.ContainsKey("CurrentIf")) { ctx.State.Add("CurrentIf", new Stack <bool>()); } Stack <bool> CurrentIf = (Stack <bool>)ctx.State["CurrentIf"]; Stack <object> CurrentTag = ctx.CurrentTag; IfTagType? currentIfTagType = CurrentTag.Count > 0 && CurrentTag.Peek() is IfTagType ? (IfTagType?)CurrentTag.Peek() : null; bool val = false; int ifDepth = 0; bool found = false; switch (this.TagType) { case IfTagType.If: val = this.Expression.EvaluateAsBoolean(ctx); CurrentTag.Push(IfTagType.If); CurrentIf.Push(val); if (val) { ctx.MoveNext(); } else { // move forward to the next ELSE or ELSE IF or ENDIF found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup)m).TagType; if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = ( loopIfTagType == IfTagType.ElseIf || loopIfTagType == IfTagType.Else || loopIfTagType == IfTagType.EndIf ); } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); } break; case IfTagType.ElseIf: // make sure we have a logically correct parent if (currentIfTagType == null || ( currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf ) ) { throw new ImpressionInterpretException("Expected an IF or ELSEIF before ELSE", this); } // if the current IF was false, process this ELSEIF if (!CurrentIf.Peek()) { val = this.Expression.EvaluateAsBoolean(ctx); // remove current tag, add "elseif" CurrentTag.Pop(); CurrentTag.Push(IfTagType.ElseIf); if (val) { // add us to the if CurrentIf.Pop(); CurrentIf.Push(val); ctx.MoveNext(); return; } } // move forward to the next ELSE IF or ENDIF found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup)m).TagType; // if its an if, then increment the ifDepth if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = (loopIfTagType == IfTagType.ElseIf || loopIfTagType == IfTagType.Else || loopIfTagType == IfTagType.EndIf); } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); break; case IfTagType.Else: // make sure we have a logically correct parent if (currentIfTagType == null || (currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf)) { throw new ImpressionInterpretException("Expected an IF or ELSEIF before ELSE", this); } // if the last if wasn't true then check this otherwise, just skip if (!CurrentIf.Peek()) { // rejig the if CurrentIf.Push(!CurrentIf.Pop()); // remove current tag, add "else" CurrentTag.Pop(); CurrentTag.Push(IfTagType.Else); // move to the next markup ctx.MoveNext(); } else { // move to the next markup //ctx.MoveNext(); // move forward to the next ENDIF at this level found = false; ifDepth = 0; do { ctx.MoveNext(); MarkupBase m = ctx.CurrentMarkup; if (m is IfTagMarkup) { IfTagType loopIfTagType = ((IfTagMarkup)m).TagType; // if its an if, then increment the ifDepth if (loopIfTagType == IfTagType.If) { ifDepth++; } else { if (ifDepth > 0) { // ignore tags that are either an elseif or else // if its an endif, then decrement the ifDepth if (loopIfTagType == IfTagType.EndIf) { ifDepth--; } } else { found = loopIfTagType == IfTagType.EndIf; } } } } while (!found || ctx.ListPosition >= ctx.ParseList.Count); } break; case IfTagType.EndIf: // make sure we have a logically correct parent if (currentIfTagType == null || (currentIfTagType != IfTagType.If && currentIfTagType != IfTagType.ElseIf && currentIfTagType != IfTagType.Else)) { throw new ImpressionInterpretException("Expected an IF, ELSEIF or ELSE before ENDIF", this); } // rejig the if CurrentIf.Pop(); // remove current tag CurrentTag.Pop(); ctx.MoveNext(); break; } }