Skip to content

Commit 47eaa7f

Browse files
Merge pull request #38 from lampepfl/real-while-loops
Add support for the WhileDo loops of dotty.
2 parents 0e7ec5d + 762ba18 commit 47eaa7f

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
204204

205205
val hasElse = !elsep.isEmpty && (elsep match {
206206
case Literal(value) if value.tag == UnitTag => false
207-
case _ => true
207+
case _ => true
208208
})
209209
val postIf = if (hasElse) new asm.Label else failure
210210

@@ -308,6 +308,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
308308
genReturn(r)
309309
generatedType = expectedType
310310

311+
case t @ WhileDo(_, _) =>
312+
generatedType = genWhileDo(t)
313+
311314
case t @ Try(_, _, _) =>
312315
generatedType = genLoadTry(t)
313316

@@ -599,6 +602,45 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
599602
}
600603
} // end of genReturn()
601604

605+
def genWhileDo(tree: WhileDo): BType = tree match{
606+
case WhileDo(cond, body) =>
607+
608+
val isInfinite = cond match {
609+
case Literal(value) if value.tag == BooleanTag => value.booleanValue
610+
case _ => false
611+
}
612+
613+
val loop = new asm.Label
614+
markProgramPoint(loop)
615+
616+
if (isInfinite) {
617+
genLoad(body, UNIT)
618+
bc goTo loop
619+
} else {
620+
val hasBody = cond match {
621+
case Literal(value) if value.tag == UnitTag => false
622+
case _ => true
623+
}
624+
625+
if (hasBody) {
626+
val success = new asm.Label
627+
val failure = new asm.Label
628+
genCond(cond, success, failure, targetIfNoJump = success)
629+
markProgramPoint(success)
630+
genLoad(body, UNIT)
631+
bc goTo loop
632+
markProgramPoint(failure)
633+
} else {
634+
// this is the shape of do..while loops, so do something smart about them
635+
val failure = new asm.Label
636+
genCond(cond, loop, failure, targetIfNoJump = failure)
637+
markProgramPoint(failure)
638+
}
639+
}
640+
641+
UNIT
642+
}
643+
602644
def genTypeApply(t: TypeApply): BType = t match {
603645
case TypeApply(fun@Select(obj, _), targs) =>
604646

src/compiler/scala/tools/nsc/backend/jvm/BackendInterface.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
3333
type Throw >: Null <: Tree
3434
type Labeled >: Null <: Tree
3535
type Return >: Null <: Tree
36+
type WhileDo >: Null <: Tree
3637
type Literal >: Null <: Tree
3738
type Block >: Null <: Tree
3839
type Typed >: Null <: Tree
@@ -69,6 +70,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
6970
implicit val ThrowTag: ClassTag[Throw]
7071
implicit val LabeledTag: ClassTag[Labeled]
7172
implicit val ReturnTag: ClassTag[Return]
73+
implicit val WhileDoTag: ClassTag[WhileDo]
7274
implicit val LiteralTag: ClassTag[Literal]
7375
implicit val BlockTag: ClassTag[Block]
7476
implicit val TypedTag: ClassTag[Typed]
@@ -205,6 +207,7 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
205207
val Try: TryDeconstructor
206208
val Labeled: LabeledDeconstructor
207209
val Return: ReturnDeconstructor
210+
val WhileDo: WhileDoDeconstructor
208211
val LabelDef: LabelDeconstructor
209212
val Literal: LiteralDeconstructor
210213
val Typed: TypedDeconstrutor
@@ -302,6 +305,11 @@ abstract class BackendInterface extends BackendInterfaceDefinitions {
302305
def _2: Symbol // target label, NoSymbol if return to method
303306
}
304307

308+
abstract class WhileDoDeconstructor extends DeconstructorCommon[WhileDo]{
309+
def _1: Tree // cond
310+
def _2: Tree // body
311+
}
312+
305313
abstract class ThrownException {
306314
def unapply(a: Annotation): Option[Symbol]
307315
}

0 commit comments

Comments
 (0)