Skip to content

Commit 42ba9d7

Browse files
AnsonYeungLPTK
andauthored
Fix while loop rewriting (hkust-taco#403)
Co-authored-by: Lionel Parreaux <lionel.parreaux@gmail.com>
1 parent 1857fda commit 42ba9d7

4 files changed

Lines changed: 9 additions & 8 deletions

File tree

hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/Normalization.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,6 @@ class Normalization(lowering: Lowering)(using tl: TL)(using Raise, Ctx, State) e
454454
val loopEnd: Path =
455455
Select(Value.Ref(State.runtimeSymbol), Tree.Ident("LoopEnd"))(S(State.loopEndSymbol))
456456
val blk = blockBuilder
457-
.assign(l, Value.Lit(Tree.UnitLit(false)))
458457
.define(FunDefn(N, f, tSym, PlainParamList(Nil) :: Nil, Begin(body, Return(loopEnd, false)))(forceTailRec = false))
459458
.assign(loopResult, Call(Value.Ref(f, S(tSym)), Nil)(true, true, false))
460459
if summon[LoweringCtx].mayRet then
@@ -463,9 +462,9 @@ class Normalization(lowering: Lowering)(using tl: TL)(using Raise, Ctx, State) e
463462
loopResult.asPath.asArg :: loopEnd.asArg :: Nil)(true, false, false))
464463
.ifthen(Value.Ref(isReturned), Case.Lit(Tree.BoolLit(true)),
465464
Return(Value.Ref(loopResult), false),
466-
S(rest)
465+
N
467466
)
468-
.end
467+
.rest(rest)
469468
else
470469
blk.rest(rest)
471470
else

hkmc2/shared/src/test/mlscript-compile/Runtime.mls

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ module Runtime with ...
1010
object Unit with
1111
fun toString() = "()"
1212

13+
// This object is used as a marker for the end of a while loop in the compiled codegen.
14+
// It is possible for the loop body to contain a return statement,
15+
// in which case we want to distinguish between returning from the loop body and loop termination.
1316
object LoopEnd
1417
val short_and = RuntimeJS.short_and
1518
val short_or = RuntimeJS.short_or

hkmc2/shared/src/test/mlscript/codegen/ScopedBlocks.mls

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,7 @@ fun f(x) =
169169
//│ JS (unsanitized):
170170
//│ let f7;
171171
//│ f7 = function f(x1) {
172-
//│ let while1, tmp2, tmp3, tmp4;
173-
//│ tmp4 = undefined;
172+
//│ let while1, tmp2, tmp3;
174173
//│ while1 = (undefined, function () {
175174
//│ let y1;
176175
//│ if (x1 === true) {
@@ -182,7 +181,8 @@ fun f(x) =
182181
//│ });
183182
//│ tmp2 = while1();
184183
//│ tmp3 = tmp2 !== runtime.LoopEnd;
185-
//│ if (tmp3 === true) { return tmp2 } else { return tmp4 }
184+
//│ if (tmp3 === true) { return tmp2 }
185+
//│ return runtime.Unit
186186
//│ };
187187

188188

hkmc2/shared/src/test/mlscript/codegen/While.mls

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,11 +359,10 @@ while
359359

360360

361361
// * https://github.com/hkust-taco/mlscript/issues/401
362-
:fixme
363362
// :sjs
364363
:rewriteWhile
365364
fun f = while false do ()
366365
print(f)
367-
//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value.
366+
//│ > ()
368367

369368

0 commit comments

Comments
 (0)