@@ -654,10 +654,9 @@ object Pull extends PullLowPriority {
654
654
def cont (r : Terminal [Unit ]): Pull [Pure , INothing , Unit ] = r
655
655
}
656
656
657
- private abstract class Bind [+ F [_], + O , X , + R ](misstep : Pull [F , O , X ])
657
+ private abstract class Bind [+ F [_], + O , X , + R ](val step : Pull [F , O , X ])
658
658
extends Pull [F , O , R ]
659
659
with ContP [X , F , O , R ] {
660
- def step : Pull [F , O , X ] = misstep
661
660
def cont (r : Terminal [X ]): Pull [F , O , R ]
662
661
def delegate : Bind [F , O , X , R ] = this
663
662
}
@@ -694,12 +693,12 @@ object Pull extends PullLowPriority {
694
693
695
694
// This class is not created by combinators in public Pull API, only during compilation
696
695
private class BindBind [F [_], O , X , Y ](
697
- var innerBind : Bind [F , O , X , Y ],
698
- var endBind : Bind [F , O , Y , Unit ]
699
- ) extends Bind [F , O , X , Unit ]( null ) {
700
- override def step : Pull [F , O , X ] = innerBind. step
701
- def cont (xterm : Terminal [X ]): Pull [F , O , Unit ] =
702
- try bindBindAux(xterm, this )
696
+ step : Pull [F , O , X ],
697
+ val bb : Bind [F , O , X , Y ],
698
+ val del : Bind [F , O , Y , Unit ]
699
+ ) extends Bind [F , O , X , Unit ]( step) {
700
+ def cont (tx : Terminal [X ]): Pull [F , O , Unit ] =
701
+ try bindBindAux(bb.cont(tx), del )
703
702
catch { case NonFatal (e) => Fail (e) }
704
703
}
705
704
@@ -712,12 +711,7 @@ object Pull extends PullLowPriority {
712
711
case ty : Terminal [_] =>
713
712
del match {
714
713
case cici : BindBind [F , O , r, Y ] =>
715
- val innerBind = cici.innerBind
716
- val endBind = cici.endBind
717
- cici.innerBind = null
718
- cici.endBind = null
719
- val nextStep = innerBind.cont(ty)
720
- bindBindAux[F , O , r, Y ](nextStep, endBind)
714
+ bindBindAux[F , O , r, Y ](cici.bb.cont(ty), cici.del)
721
715
case _ => del.cont(ty)
722
716
}
723
717
case x => new DelegateBind (x, del)
@@ -871,7 +865,7 @@ object Pull extends PullLowPriority {
871
865
case b : Bind [G , X , y, Unit ] =>
872
866
b.step match {
873
867
case c : Bind [G , X , x, _] =>
874
- viewL(new BindBind [G , X , x, y](c, b.delegate))
868
+ viewL(new BindBind [G , X , x, y](c.step, c.delegate , b.delegate))
875
869
case e : Action [G , X , y2] =>
876
870
contP = b.delegate
877
871
e
@@ -910,6 +904,21 @@ object Pull extends PullLowPriority {
910
904
def interrupted (inter : Interrupted ): End
911
905
def fail (e : Throwable ): End
912
906
}
907
+ type CallRun [+ G [_], + X , End ] = Run [G , X , End ] => End
908
+
909
+ object TheBuildR extends Run [Pure , INothing , F [CallRun [Pure , Nothing , F [INothing ]]]] {
910
+ type TheRun = Run [Pure , INothing , F [INothing ]]
911
+ def fail (e : Throwable ) = F .raiseError(e)
912
+ def done (scope : Scope [F ]) =
913
+ F .pure((cont : TheRun ) => cont.done(scope))
914
+ def out (head : Chunk [INothing ], scope : Scope [F ], tail : Pull [Pure , INothing , Unit ]) =
915
+ F .pure((cont : TheRun ) => cont.out(head, scope, tail))
916
+ def interrupted (i : Interrupted ) =
917
+ F .pure((cont : TheRun ) => cont.interrupted(i))
918
+ }
919
+
920
+ def buildR [G [_], X , End ]: Run [G , X , F [CallRun [G , X , F [End ]]]] =
921
+ TheBuildR .asInstanceOf [Run [G , X , F [CallRun [G , X , F [End ]]]]]
913
922
914
923
def go [G [_], X , End ](
915
924
scope : Scope [F ],
@@ -1205,13 +1214,17 @@ object Pull extends PullLowPriority {
1205
1214
case u : Uncons [G , y] @ unchecked =>
1206
1215
val v = getCont[Option [(Chunk [y], Pull [G , y, Unit ])], G , X ]
1207
1216
// a Uncons is run on the same scope, without shifting.
1208
- F .unit >> go(scope, extendedTopLevelScope, translation, new UnconsRunR (v), u.stream)
1217
+ val runr = buildR[G , y, End ]
1218
+ F .unit >> go(scope, extendedTopLevelScope, translation, runr, u.stream).attempt
1219
+ .flatMap(_.fold(goErr(_, v), _.apply(new UnconsRunR (v))))
1209
1220
1210
1221
case s : StepLeg [G , y] @ unchecked =>
1211
1222
val v = getCont[Option [Stream .StepLeg [G , y]], G , X ]
1223
+ val runr = buildR[G , y, End ]
1212
1224
scope
1213
1225
.shiftScope(s.scope, s.toString)
1214
- .flatMap(go(_, extendedTopLevelScope, translation, new StepLegRunR (v), s.stream))
1226
+ .flatMap(go(_, extendedTopLevelScope, translation, runr, s.stream).attempt)
1227
+ .flatMap(_.fold(goErr(_, v), _.apply(new StepLegRunR (v))))
1215
1228
1216
1229
case _ : GetScope [_] =>
1217
1230
go(scope, extendedTopLevelScope, translation, runner, getCont(Succeeded (scope)))
0 commit comments