private bool HandleDoWhileStatement(JsDoWhileStatement stmt, StackEntry location, ImmutableStack <StackEntry> stack, ImmutableStack <Tuple <string, State> > breakStack, ImmutableStack <Tuple <string, State> > continueStack, State currentState, State returnState, IList <JsStatement> currentBlock, bool isFirstStatement) { if (!isFirstStatement) { // We have to create a new block for the statement. var topOfLoopState = CreateNewStateValue(currentState.FinallyStack); Enqueue(stack.Push(location), breakStack, continueStack, topOfLoopState, returnState); currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState)); return(false); } else { var beforeConditionState = CreateNewStateValue(currentState.FinallyStack); StateAfterStatement afterLoopState; string currentName = GetLabelForState(currentState); if (new ContainsBreakVisitor().Analyze(stmt.Body, currentName)) { afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState); breakStack = breakStack.Push(Tuple.Create(currentName, afterLoopState.State)); } else { afterLoopState = new StateAfterStatement(returnState, false); } currentBlock.AddRange(Handle(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(stmt.Body, 0)), breakStack, continueStack.Push(Tuple.Create(GetLabelForState(currentState), beforeConditionState)), currentState, beforeConditionState, false, false)); if (afterLoopState.NeedEnqueue) { Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.State, returnState); Enqueue(stack.Push(new StackEntry(JsStatement.Block(JsStatement.If(stmt.Condition, new JsGotoStateStatement(currentState, currentState), null)), 0)), breakStack, continueStack, beforeConditionState, afterLoopState.State); } else { Enqueue(PushFollowing(stack, location).Push(new StackEntry(JsStatement.Block(JsStatement.If(stmt.Condition, new JsGotoStateStatement(currentState, currentState), null)), 0)), breakStack, continueStack, beforeConditionState, returnState); } return(false); } }
private bool HandleDoWhileStatement(JsDoWhileStatement stmt, StackEntry location, ImmutableStack<StackEntry> stack, ImmutableStack<Tuple<string, State>> breakStack, ImmutableStack<Tuple<string, State>> continueStack, State currentState, State returnState, IList<JsStatement> currentBlock, bool isFirstStatement) { if (!isFirstStatement) { // We have to create a new block for the statement. var topOfLoopState = CreateNewStateValue(currentState.FinallyStack); Enqueue(stack.Push(location), breakStack, continueStack, topOfLoopState, returnState); currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState)); return false; } else { var beforeConditionState = CreateNewStateValue(currentState.FinallyStack); StateAfterStatement afterLoopState; string currentName = GetLabelForState(currentState); if (new ContainsBreakVisitor().Analyze(stmt.Body, currentName)) { afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState); breakStack = breakStack.Push(Tuple.Create(currentName, afterLoopState.State)); } else { afterLoopState = new StateAfterStatement(returnState, false); } currentBlock.AddRange(Handle(ImmutableStack<StackEntry>.Empty.Push(new StackEntry(stmt.Body, 0)), breakStack, continueStack.Push(Tuple.Create(GetLabelForState(currentState), beforeConditionState)), currentState, beforeConditionState, false, false)); if (afterLoopState.NeedEnqueue) { Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.State, returnState); Enqueue(stack.Push(new StackEntry(JsStatement.Block(JsStatement.If(stmt.Condition, new JsGotoStateStatement(currentState, currentState), null)), 0)), breakStack, continueStack, beforeConditionState, afterLoopState.State); } else { Enqueue(PushFollowing(stack, location).Push(new StackEntry(JsStatement.Block(JsStatement.If(stmt.Condition, new JsGotoStateStatement(currentState, currentState), null)), 0)), breakStack, continueStack, beforeConditionState, returnState); } return false; } }