private static ScriptResult RunNode(ScriptNode script, Stack <NodeStackItem> nodestack, NodeStackItem current, ProgramCounter programIndex, ProgramData programData) // TODO Change { // Only execute container nodes: if (current.Node.NodeType == NodeType.Script || current.Node.NodeType == NodeType.Page || current.Node.NodeType == NodeType.OptionsChoice || current.Node.NodeType == NodeType.Option || current.Node.NodeType == NodeType.OnceOnly || current.Node.NodeType == NodeType.ConditionalTrue || current.Node.NodeType == NodeType.ConditionalFalse || current.Node.NodeType == NodeType.BlockNode || current.Node.NodeType == NodeType.ParallelNode || current.Node.NodeType == NodeType.ConditionalIf ) { // Run the children if (current.Index >= current.Node.Children.Count) { nodestack.Pop(); return(ScriptResult.Running); } var childNode = current.Node.Children[current.Index]; if (childNode.NodeType == NodeType.Page) { nodestack.Push(new NodeStackItem(current.Node.Children[0], 0)); return(ScriptResult.Running); } var returnResult = childNode.Run(ref programIndex, ref programData); if (returnResult == NodeRunResult.Await) { // return and then re-enter on this node return(ScriptResult.Yielded); } // Result filter if (returnResult == NodeRunResult.NextCommand) { current.Index += 1; if (current.Index >= current.Node.Children.Count) { LevelUp(nodestack); return(ScriptResult.Running); } return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushPage) { nodestack.Push(new NodeStackItem(childNode, current.Index)); // Add a CallNode so we know where to return to. var pageNode = script.FindPageByName(programIndex.ReturnRegisterString); nodestack.Push(new NodeStackItem(pageNode, 0)); // Our new target PageNode return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PopPage) { LevelUp(nodestack); return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushChildN) { nodestack.Push(new NodeStackItem(childNode, programIndex.ReturnRegisterInt32)); // Push current node to return to return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushChildFirst) { nodestack.Push(new NodeStackItem(childNode, 0)); // Push current node to return to return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushChildTrue) { // TODO Find childnode that is true rather than assume first nodestack.Push(new NodeStackItem(childNode, 0)); // Push current node to return to return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushChildFalse) { // TODO Find childnode that is false rather than assume second nodestack.Push(new NodeStackItem(childNode, 1)); return(ScriptResult.Running); } else if (returnResult == NodeRunResult.PushParallel) { // Add all block children to a new parallel stack for (int i = childNode.Children.Count - 1; i >= 0; i--) { var pstack = new Stack <NodeStackItem>(); // TODO From pool var c = childNode.Children[i]; pstack.Push(new NodeStackItem(c, 0)); programIndex.ParallelStack.Add(pstack); } // Go to the next node when we are ready current.Index += 1; if (current.Index >= current.Node.Children.Count) { LevelUp(nodestack); return(ScriptResult.Running); } return(ScriptResult.Running); } else { Console.WriteLine("TODO Implement Return Result: " + returnResult); return(ScriptResult.Running); } } else { Console.WriteLine("TODO Implement NodeType: " + current.Node.NodeType); } return(ScriptResult.Running); }