diff --git a/ts2panda/src/statement/labelTarget.ts b/ts2panda/src/statement/labelTarget.ts index 1c6cf17fa8277c965fe1714c926ba5dac3f23155..bfd71326a865e3aedc3d1bc36e800d1b28167497 100644 --- a/ts2panda/src/statement/labelTarget.ts +++ b/ts2panda/src/statement/labelTarget.ts @@ -22,9 +22,11 @@ import { Label } from "../irnodes"; export class LabelTarget { private static name2LabelTarget: Map = new Map(); private static labelTargetStack: LabelTarget[] = []; + private static curLoopLabelTarget: LabelTarget | undefined = undefined; private node: ts.Node; private breakTargetLabel: Label; private continueTargetLabel: Label | undefined; + private preLoopLabelTarget: LabelTarget | undefined = undefined; private hasLoopEnv: boolean; private loopEnvLevel: number; private tryStatement: TryStatement | undefined; @@ -36,6 +38,10 @@ export class LabelTarget { this.hasLoopEnv = hasLoopEnv; this.loopEnvLevel = hasLoopEnv ? 1 : 0; this.tryStatement = TryStatement.getCurrentTryStatement(); + if (continueTargetLabel) { + this.preLoopLabelTarget = LabelTarget.curLoopLabelTarget; + LabelTarget.curLoopLabelTarget = this; + } } containLoopEnv() { @@ -58,6 +64,10 @@ export class LabelTarget { return this.tryStatement; } + getPreLoopLabelTarget() { + return this.preLoopLabelTarget; + } + getCorrespondingNode() { return this.node; } @@ -84,15 +94,6 @@ export class LabelTarget { return undefined; } - // this API used for get uplevel continueLabel when compile switchStatement - static getCloseContinueTarget(): Label | undefined { - let labelTarget = LabelTarget.getCloseLabelTarget(); - if (labelTarget) { - return labelTarget.continueTargetLabel; - } - return undefined; - } - static pushLabelTarget(labelTarget: LabelTarget) { if (labelTarget.hasLoopEnv) { if (TryStatement.getCurrentTryStatement()) { @@ -104,11 +105,17 @@ export class LabelTarget { } static popLabelTarget() { - if (!LabelTarget.isLabelTargetsEmpty() && LabelTarget.labelTargetStack.pop().hasLoopEnv) { - if (TryStatement.getCurrentTryStatement()) { - TryStatement.getCurrentTryStatement().decreaseLoopEnvLevel(); + if (!LabelTarget.isLabelTargetsEmpty()) { + let popedLabelTarget = LabelTarget.labelTargetStack.pop(); + if (popedLabelTarget.containLoopEnv()) { + if (TryStatement.getCurrentTryStatement()) { + TryStatement.getCurrentTryStatement().decreaseLoopEnvLevel(); + } + LabelTarget.labelTargetStack.forEach(lt => lt.decreaseLoopEnvLevel()); + } + if (popedLabelTarget.getContinueTargetLabel()) { + LabelTarget.curLoopLabelTarget = popedLabelTarget.getPreLoopLabelTarget(); } - LabelTarget.labelTargetStack.forEach(lt => lt.decreaseLoopEnvLevel()); } } @@ -131,13 +138,18 @@ export class LabelTarget { LabelTarget.name2LabelTarget.delete(labelName); } + static getCurLoopLabelTarget() { + return LabelTarget.curLoopLabelTarget; + } + static getLabelTarget(stmt: ts.BreakOrContinueStatement): LabelTarget { let labelTarget: LabelTarget; if (stmt.label) { let labelName = jshelpers.getTextOfIdentifierOrLiteral(stmt.label); labelTarget = LabelTarget.name2LabelTarget.get(labelName)!; } else { - labelTarget = LabelTarget.getCloseLabelTarget()!; + labelTarget = + ts.isContinueStatement(stmt) ? LabelTarget.getCurLoopLabelTarget() : LabelTarget.getCloseLabelTarget()!; } return labelTarget; } diff --git a/ts2panda/src/statement/switchStatement.ts b/ts2panda/src/statement/switchStatement.ts index 438bf7b7a570b8b77ec70e5c80bfb7411cb3bae5..f964b12928a1b4e5d61c9bee8a1f86e9deeea4b9 100644 --- a/ts2panda/src/statement/switchStatement.ts +++ b/ts2panda/src/statement/switchStatement.ts @@ -41,14 +41,7 @@ export class SwitchBase { let caseLabel = new Label(); this.caseLabels.push(caseLabel); } - /** - * switchStatements doesn't have continue target - * so we use the uplevel continue label as it's continue target. - */ - let continueLabel = LabelTarget.getCloseContinueTarget(); - let closeLabelTarget = LabelTarget.getCloseLabelTarget(); - let hasLoopEnv = closeLabelTarget ? closeLabelTarget.containLoopEnv() : false; - let labelTarget = new LabelTarget(stmt, switchEndLabel, continueLabel, hasLoopEnv); + let labelTarget = new LabelTarget(stmt, switchEndLabel, undefined); LabelTarget.pushLabelTarget(labelTarget); LabelTarget.updateName2LabelTarget(stmt.parent, labelTarget); }