Created
February 7, 2010 05:19
-
-
Save huynhjl/297230 to your computer and use it in GitHub Desktop.
code with scalac -print output at the end
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The continuation code is from an answer by Rich posted at StackOverflow | |
// http://stackoverflow.com/questions/2201882/implementing-yield-yield-return-using-scala-continuations/2215182#2215182 | |
import scala.continuations._ | |
import scala.continuations.ControlContext.{shift,reset} | |
sealed trait Iteration[+R] | |
case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R] | |
case object Done extends Iteration[Nothing] | |
object YieldTest { | |
def trampoline[R](body: => Iteration[R]): Iterator[R] = { | |
def loop(thunk: () => Iteration[R]): Stream[R] = { | |
thunk.apply match { | |
case Yield(result, next) => Stream.cons(result, loop(next)) | |
case Done => Stream.empty | |
} | |
} | |
loop(() => body).iterator | |
} | |
def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] = | |
trampoline { | |
reset[Iteration[R],Iteration[R]] { body ; Done } | |
} | |
def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] = | |
shift((k: Unit => Iteration[R]) => Yield(result, () => k(()))) | |
def main(args:Array[String]): Unit = { | |
val itr2 = iterator[Int] { | |
yld(1) | |
yld(2) | |
yld(3) | |
} | |
for (i <- itr2) { println(i) } | |
} | |
} | |
/** OUTPUT of scalac -print *************************************/ | |
[[syntax trees at end of cleanup]]// Scala source: Yield.scala | |
package <empty> { | |
sealed abstract trait Iteration extends java.lang.Object; | |
@serializable | |
case class Yield extends java.lang.Object with Iteration with ScalaObject with Product { | |
def productIterator(): Iterator = scala.Product$class.productIterator(Yield.this); | |
@deprecated("use productIterator instead") | |
def productElements(): Iterator = scala.Product$class.productElements(Yield.this); | |
<synthetic> def copy$default$2(): Function0 = Yield.this.next(); | |
<synthetic> def copy$default$1(): java.lang.Object = Yield.this.result(); | |
<caseaccessor> <paramaccessor> private[this] val result: java.lang.Object = _; | |
<stable> <caseaccessor> <accessor> <paramaccessor> def result(): java.lang.Object = Yield.this.result; | |
<caseaccessor> <paramaccessor> private[this] val next: Function0 = _; | |
<stable> <caseaccessor> <accessor> <paramaccessor> def next(): Function0 = Yield.this.next; | |
<synthetic> def copy(result: java.lang.Object = result, next: Function0 = next): Yield = new Yield(result, next); | |
override def hashCode(): Int = ScalaRunTime.this._hashCode(Yield.this); | |
override def toString(): java.lang.String = ScalaRunTime.this._toString(Yield.this); | |
override def equals(x$1: java.lang.Object): Boolean = Yield.this.eq(x$1).||({ | |
{ | |
var temp1: java.lang.Object = x$1; | |
if (temp1.$isInstanceOf[Yield]()) | |
{ | |
{ | |
var temp2: Yield = temp1.$asInstanceOf[Yield](); | |
{ | |
var temp3: java.lang.Object = temp2.result(); | |
{ | |
var temp4: Function0 = temp2.next(); | |
{ | |
{ | |
val next$1: Function0 = temp4; | |
{ | |
val result$1: java.lang.Object = temp3; | |
if (Yield.this.gd1$1(result$1, next$1)) | |
{ | |
{ | |
val result$1: java.lang.Object = temp3; | |
{ | |
{ | |
x$1.$asInstanceOf[Yield]().canEqual(Yield.this) | |
} | |
} | |
} | |
} | |
else | |
{ | |
false | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
else | |
{ | |
false | |
} | |
} | |
}); | |
override def productPrefix(): java.lang.String = "Yield"; | |
override def productArity(): Int = 2; | |
override def productElement(x$1: Int): java.lang.Object = { | |
var temp5: Int = x$1; | |
(temp5: Int) match { | |
case 0 => { | |
Yield.this.result() | |
} | |
case 1 => { | |
Yield.this.next() | |
} | |
case _ => { | |
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString()) | |
} | |
} | |
}; | |
override def canEqual(x$1: java.lang.Object): Boolean = x$1.$isInstanceOf[Yield](); | |
final <synthetic> private[this] def gd1$1(x$1: java.lang.Object, x$2: Function0): Boolean = x$1.==(Yield.this.result()).&&(x$2.==(Yield.this.next())); | |
def this(result: java.lang.Object, next: Function0): Yield = { | |
Yield.this.result = result; | |
Yield.this.next = next; | |
Yield.super.this(); | |
scala.Product$class./*Product$class*/$init$(Yield.this); | |
() | |
} | |
}; | |
@serializable | |
final case class Done extends java.lang.Object with Iteration with ScalaObject with Product { | |
def productIterator(): Iterator = scala.Product$class.productIterator(Done.this); | |
@deprecated("use productIterator instead") | |
def productElements(): Iterator = scala.Product$class.productElements(Done.this); | |
final override def toString(): java.lang.String = "Done"; | |
override def productPrefix(): java.lang.String = "Done"; | |
override def productArity(): Int = 0; | |
override def productElement(x$1: Int): java.lang.Object = { | |
var temp6: Int = x$1; | |
{ | |
throw new java.lang.IndexOutOfBoundsException(scala.Int.box(x$1).toString()) | |
} | |
}; | |
override def canEqual(x$1: java.lang.Object): Boolean = x$1.$isInstanceOf[object Done](); | |
protected def readResolve(): java.lang.Object = Done; | |
def this(): object Done = { | |
Done.super.this(); | |
scala.Product$class./*Product$class*/$init$(Done.this); | |
() | |
} | |
}; | |
final class YieldTest extends java.lang.Object with ScalaObject { | |
def trampoline(body: Function0): Iterator = YieldTest.this.loop$1(body).iterator(); | |
def iterator(body$1: Function0): Iterator = YieldTest.this.trampoline({ | |
(new YieldTest$$anonfun$iterator$1(body$1): Function0) | |
}); | |
def yld(result$2: java.lang.Object): scala.continuations.ControlContext = ControlContext.this.shiftR({ | |
(new YieldTest$$anonfun$yld$1(result$2): Function1) | |
}); | |
def main(args: Array[java.lang.String]): Unit = { | |
val itr2: Iterator = YieldTest.this.iterator({ | |
(new YieldTest$$anonfun$1(): Function0) | |
}); | |
itr2.foreach({ | |
(new YieldTest$$anonfun$main$1(): Function1) | |
}) | |
}; | |
final def loop$1(thunk: Function0): scala.collection.immutable.Stream = { | |
val temp7: Iteration = thunk.apply().$asInstanceOf[Iteration](); | |
if (temp7.$isInstanceOf[Yield]()) | |
{ | |
{ | |
var temp8: Yield = temp7.$asInstanceOf[Yield](); | |
{ | |
var temp9: java.lang.Object = temp8.result(); | |
{ | |
var temp10: Function0 = temp8.next(); | |
{ | |
{ | |
val result: java.lang.Object = temp9; | |
{ | |
{ | |
val next$2: Function0 = temp10; | |
scala.collection.immutable.Stream$cons.apply(result, { | |
(new YieldTest$$anonfun$loop$1$1(next$2): Function0) | |
}) | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
else | |
if (Done.==(temp7)) | |
{ | |
{ | |
{ | |
scala.package.Stream().empty() | |
} | |
} | |
} | |
else | |
throw new MatchError(temp7.toString()) | |
}; | |
def this(): object YieldTest = { | |
YieldTest.super.this(); | |
() | |
} | |
}; | |
final <synthetic> class Yield extends java.lang.Object with ScalaObject { | |
case <synthetic> def unapply(x$0: Yield): Some = new Some(new Tuple2(x$0.result(), x$0.next())); | |
case <synthetic> def apply(result: java.lang.Object, next: Function0): Yield = new Yield(result, next); | |
def this(): object Yield = { | |
Yield.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$loop$1$1 extends scala.runtime.AbstractFunction0 { | |
final def apply(): scala.collection.immutable.Stream = YieldTest.loop$1(YieldTest$$anonfun$loop$1$1.this.next$2); | |
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$loop$1$1.this.apply(); | |
<synthetic> <paramaccessor> private[this] val next$2: Function0 = _; | |
def this(next$2: Function0): YieldTest$$anonfun$loop$1$1 = { | |
YieldTest$$anonfun$loop$1$1.this.next$2 = next$2; | |
YieldTest$$anonfun$loop$1$1.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2 extends scala.runtime.AbstractFunction1 { | |
final def apply(tmp1: scala.runtime.BoxedUnit): object Done = { | |
tmp1; | |
Done | |
}; | |
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]()); | |
def this($outer: YieldTest$$anonfun$iterator$1$$anonfun$apply$1): YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2 = { | |
YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$iterator$1$$anonfun$apply$1 extends scala.runtime.AbstractFunction0 { | |
final def apply(): scala.continuations.ControlContext = YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.$outer.body$1.apply().$asInstanceOf[scala.continuations.ControlContext]().map({ | |
(new YieldTest$$anonfun$iterator$1$$anonfun$apply$1$$anonfun$apply$2(YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this): Function1) | |
}); | |
<synthetic> <paramaccessor> private[this] val $outer: YieldTest$$anonfun$iterator$1 = _; | |
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.apply(); | |
def this($outer: YieldTest$$anonfun$iterator$1): YieldTest$$anonfun$iterator$1$$anonfun$apply$1 = { | |
if ($outer.eq(null)) | |
throw new java.lang.NullPointerException() | |
else | |
YieldTest$$anonfun$iterator$1$$anonfun$apply$1.this.$outer = $outer; | |
YieldTest$$anonfun$iterator$1$$anonfun$apply$1.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$iterator$1 extends scala.runtime.AbstractFunction0 { | |
final def apply(): Iteration = scala.continuations.ControlContext.reset({ | |
(new YieldTest$$anonfun$iterator$1$$anonfun$apply$1(YieldTest$$anonfun$iterator$1.this): Function0) | |
}).$asInstanceOf[Iteration](); | |
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$iterator$1.this.apply(); | |
<synthetic> <paramaccessor> val body$1: Function0 = _; | |
def this(body$1: Function0): YieldTest$$anonfun$iterator$1 = { | |
YieldTest$$anonfun$iterator$1.this.body$1 = body$1; | |
YieldTest$$anonfun$iterator$1.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$yld$1$$anonfun$apply$3 extends scala.runtime.AbstractFunction0 { | |
final def apply(): Iteration = YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.k$1.apply(scala.runtime.BoxedUnit.UNIT).$asInstanceOf[Iteration](); | |
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.apply(); | |
<synthetic> <paramaccessor> private[this] val k$1: Function1 = _; | |
def this($outer: YieldTest$$anonfun$yld$1, k$1: Function1): YieldTest$$anonfun$yld$1$$anonfun$apply$3 = { | |
YieldTest$$anonfun$yld$1$$anonfun$apply$3.this.k$1 = k$1; | |
YieldTest$$anonfun$yld$1$$anonfun$apply$3.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$yld$1 extends scala.runtime.AbstractFunction1 { | |
final def apply(k$1: Function1): Yield = new Yield(YieldTest$$anonfun$yld$1.this.result$2, { | |
(new YieldTest$$anonfun$yld$1$$anonfun$apply$3(YieldTest$$anonfun$yld$1.this, k$1): Function0) | |
}); | |
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$yld$1.this.apply(v1.$asInstanceOf[Function1]()); | |
<synthetic> <paramaccessor> private[this] val result$2: java.lang.Object = _; | |
def this(result$2: java.lang.Object): YieldTest$$anonfun$yld$1 = { | |
YieldTest$$anonfun$yld$1.this.result$2 = result$2; | |
YieldTest$$anonfun$yld$1.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5 extends scala.runtime.AbstractFunction1 { | |
final def apply(tmp3: scala.runtime.BoxedUnit): scala.continuations.ControlContext = { | |
tmp3; | |
YieldTest.this.yld(scala.Int.box(3)) | |
}; | |
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]()); | |
def this($outer: YieldTest$$anonfun$1$$anonfun$apply$4): YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5 = { | |
YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$1$$anonfun$apply$4 extends scala.runtime.AbstractFunction1 { | |
final def apply(tmp2: scala.runtime.BoxedUnit): scala.continuations.ControlContext = { | |
tmp2; | |
YieldTest.this.yld(scala.Int.box(2)).flatMap({ | |
(new YieldTest$$anonfun$1$$anonfun$apply$4$$anonfun$apply$5(YieldTest$$anonfun$1$$anonfun$apply$4.this): Function1) | |
}) | |
}; | |
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = YieldTest$$anonfun$1$$anonfun$apply$4.this.apply(v1.$asInstanceOf[scala.runtime.BoxedUnit]()); | |
def this($outer: YieldTest$$anonfun$1): YieldTest$$anonfun$1$$anonfun$apply$4 = { | |
YieldTest$$anonfun$1$$anonfun$apply$4.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$1 extends scala.runtime.AbstractFunction0 { | |
final def apply(): scala.continuations.ControlContext = YieldTest.this.yld(scala.Int.box(1)).flatMap({ | |
(new YieldTest$$anonfun$1$$anonfun$apply$4(YieldTest$$anonfun$1.this): Function1) | |
}); | |
final <bridge> def apply(): java.lang.Object = YieldTest$$anonfun$1.this.apply(); | |
def this(): YieldTest$$anonfun$1 = { | |
YieldTest$$anonfun$1.super.this(); | |
() | |
} | |
}; | |
@SerialVersionUID(0) @serializable | |
final <synthetic> class YieldTest$$anonfun$main$1 extends scala.runtime.AbstractFunction1 { | |
final def apply(i: Int): Unit = scala.this.Predef.println(scala.Int.box(i)); | |
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = { | |
YieldTest$$anonfun$main$1.this.apply(scala.Int.unbox(v1)); | |
scala.runtime.BoxedUnit.UNIT | |
}; | |
def this(): YieldTest$$anonfun$main$1 = { | |
YieldTest$$anonfun$main$1.super.this(); | |
() | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment