public override void EnterRollGroup([NotNull] DiceGrammarParser.RollGroupContext context) { // add GroupPartialNode to act as a sentinel and accumulator for all group stuff // note that there might be a node after GroupPartialNode on the stack to indicate NumTimes // (said node is rolled into the GroupPartialNode upon parsing the inner group contents) Stack.Push(new GroupPartialNode()); }
public override void ExitRollGroup([NotNull] DiceGrammarParser.RollGroupContext context) { // our stack looks like a GroupPartialNode followed by all group_extras and group_functions List <DiceAST> groupNodes = new List <DiceAST>(); for (int i = 0; i < context.grouped_extras().Length + context.group_function().Length; i++) { groupNodes.Add(Stack.Pop()); } groupNodes.Reverse(); var partial = (GroupPartialNode)Stack.Pop(); foreach (var node in groupNodes) { if (node is RerollNode) { partial.AddReroll((RerollNode)node); } else if (node is KeepNode) { partial.AddKeep((KeepNode)node); } else if (node is SuccessNode) { partial.AddSuccess((SuccessNode)node); } else if (node is SortNode) { partial.AddSort((SortNode)node); } else if (node is FunctionNode) { partial.AddFunction((FunctionNode)node); } else { throw new InvalidOperationException("Unexpected node type when resolving group node"); } } Stack.Push(partial.CreateGroupNode()); }