'while' and 'do-while' loop generator fixes.

Generate 'do-while' loop body as IrComposite, because variables declared
in loop body should be visible in loop condition.
Wrap 'do-while' loop in IrBlock so that variables declared in loop body
are not visible outside of the loop.

Generate 'while' and 'do-while' loops as expressions of type Unit.
This commit is contained in:
Dmitry Petrov
2017-03-06 19:02:52 +03:00
parent cb61c358ea
commit d096f1d381
6 changed files with 105 additions and 70 deletions
@@ -7,7 +7,7 @@ FILE /badBreakContinue.kt
BLOCK_BODY
WHILE label=L1 origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
ERROR_EXPR 'Loop not found for break expression: break@ERROR' type=kotlin.Nothing
ERROR_EXPR 'Loop not found for continue expression: continue@ERROR' type=kotlin.Nothing
FUN public fun test3(): kotlin.Unit
+18 -16
View File
@@ -3,37 +3,39 @@ FILE /breakContinue.kt
BLOCK_BODY
WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
BREAK label=null loop.label=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
BREAK label=null loop.label=null
condition: CONST Boolean type=kotlin.Boolean value='true'
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: COMPOSITE type=kotlin.Unit origin=null
BREAK label=null loop.label=null
condition: CONST Boolean type=kotlin.Boolean value='true'
WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
CONTINUE label=null loop.label=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
CONTINUE label=null loop.label=null
condition: CONST Boolean type=kotlin.Boolean value='true'
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: COMPOSITE type=kotlin.Unit origin=null
CONTINUE label=null loop.label=null
condition: CONST Boolean type=kotlin.Boolean value='true'
FUN public fun test2(): kotlin.Unit
BLOCK_BODY
WHILE label=OUTER origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
WHILE label=INNER origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
BREAK label=INNER loop.label=INNER
BREAK label=OUTER loop.label=OUTER
BREAK label=OUTER loop.label=OUTER
WHILE label=OUTER origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
WHILE label=INNER origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
CONTINUE label=INNER loop.label=INNER
CONTINUE label=OUTER loop.label=OUTER
CONTINUE label=OUTER loop.label=OUTER
@@ -41,17 +43,17 @@ FILE /breakContinue.kt
BLOCK_BODY
WHILE label=L origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
WHILE label=L origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
BREAK label=L loop.label=L
BREAK label=L loop.label=L
WHILE label=L origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
WHILE label=L origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value='true'
body: BLOCK type=kotlin.Nothing origin=null
body: BLOCK type=kotlin.Unit origin=null
CONTINUE label=L loop.label=L
CONTINUE label=L loop.label=L
+38 -34
View File
@@ -26,8 +26,8 @@ FILE /whileDoWhile.kt
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='10'
body: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=null
body: BLOCK type=kotlin.Unit origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp1: kotlin.Int
GET_VAR 'x: Int' type=kotlin.Int origin=POSTFIX_INCR
@@ -35,38 +35,41 @@ FILE /whileDoWhile.kt
CALL 'inc(): Int' type=kotlin.Int origin=POSTFIX_INCR
$this: GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
GET_VAR 'tmp1: Int' type=kotlin.Int origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='0'
DO_WHILE label=null origin=DO_WHILE_LOOP
body: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp2: kotlin.Int
GET_VAR 'x: Int' type=kotlin.Int origin=POSTFIX_INCR
SET_VAR 'x: Int' type=kotlin.Unit origin=POSTFIX_INCR
CALL 'inc(): Int' type=kotlin.Int origin=POSTFIX_INCR
$this: GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='15'
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='0'
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp3: kotlin.Int
VAR IR_TEMPORARY_VARIABLE val tmp2: kotlin.Int
GET_VAR 'x: Int' type=kotlin.Int origin=POSTFIX_INCR
SET_VAR 'x: Int' type=kotlin.Unit origin=POSTFIX_INCR
CALL 'inc(): Int' type=kotlin.Int origin=POSTFIX_INCR
$this: GET_VAR 'tmp3: Int' type=kotlin.Int origin=null
GET_VAR 'tmp3: Int' type=kotlin.Int origin=null
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='20'
$this: GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
GET_VAR 'tmp2: Int' type=kotlin.Int origin=null
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='15'
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: COMPOSITE type=kotlin.Unit origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp3: kotlin.Int
GET_VAR 'x: Int' type=kotlin.Int origin=POSTFIX_INCR
SET_VAR 'x: Int' type=kotlin.Unit origin=POSTFIX_INCR
CALL 'inc(): Int' type=kotlin.Int origin=POSTFIX_INCR
$this: GET_VAR 'tmp3: Int' type=kotlin.Int origin=null
GET_VAR 'tmp3: Int' type=kotlin.Int origin=null
condition: CALL 'LT0(Int): Boolean' type=kotlin.Boolean origin=LT
arg0: CALL 'compareTo(Int): Int' type=kotlin.Int origin=LT
$this: GET_VAR 'x: Int' type=kotlin.Int origin=null
other: CONST Int type=kotlin.Int value='20'
FUN public fun testSmartcastInCondition(): kotlin.Unit
BLOCK_BODY
VAR val a: kotlin.Any? = null
@@ -80,7 +83,8 @@ FILE /whileDoWhile.kt
condition: TYPE_OP type=kotlin.Boolean origin=IMPLICIT_CAST typeOperand=kotlin.Boolean
GET_VAR 'a: Any?' type=kotlin.Any? origin=null
body: BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: BLOCK type=kotlin.Unit origin=null
condition: TYPE_OP type=kotlin.Boolean origin=IMPLICIT_CAST typeOperand=kotlin.Boolean
GET_VAR 'a: Any?' type=kotlin.Any? origin=null
BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP
body: COMPOSITE type=kotlin.Unit origin=null
condition: TYPE_OP type=kotlin.Boolean origin=IMPLICIT_CAST typeOperand=kotlin.Boolean
GET_VAR 'a: Any?' type=kotlin.Any? origin=null
+15 -15
View File
@@ -12,21 +12,21 @@ FILE /coercionInLoop.kt
WHILE label=null origin=WHILE_LOOP
condition: CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=null
$this: GET_VAR 'x: DoubleIterator' type=kotlin.collections.DoubleIterator origin=null
body: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=null
WHEN type=kotlin.Unit origin=null
BRANCH
if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'get(Int): Double' type=kotlin.Double origin=GET_ARRAY_ELEMENT
$this: GET_VAR 'a: DoubleArray' type=kotlin.DoubleArray origin=null
index: GET_VAR 'i: Int' type=kotlin.Int origin=null
arg1: CALL 'next(): Double' type=kotlin.Double origin=null
$this: GET_VAR 'x: DoubleIterator' type=kotlin.collections.DoubleIterator origin=null
then: RETURN type=kotlin.Nothing from='box(): String'
STRING_CONCATENATION type=kotlin.String
CONST String type=kotlin.String value='Fail '
GET_VAR 'i: Int' type=kotlin.Int origin=null
body: BLOCK type=kotlin.Unit origin=null
WHEN type=kotlin.Unit origin=null
BRANCH
if: CALL 'NOT(Boolean): Boolean' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'EQEQ(Any?, Any?): Boolean' type=kotlin.Boolean origin=EXCLEQ
arg0: CALL 'get(Int): Double' type=kotlin.Double origin=GET_ARRAY_ELEMENT
$this: GET_VAR 'a: DoubleArray' type=kotlin.DoubleArray origin=null
index: GET_VAR 'i: Int' type=kotlin.Int origin=null
arg1: CALL 'next(): Double' type=kotlin.Double origin=null
$this: GET_VAR 'x: DoubleIterator' type=kotlin.collections.DoubleIterator origin=null
then: RETURN type=kotlin.Nothing from='box(): String'
STRING_CONCATENATION type=kotlin.String
CONST String type=kotlin.String value='Fail '
GET_VAR 'i: Int' type=kotlin.Int origin=null
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp0: kotlin.Int
GET_VAR 'i: Int' type=kotlin.Int origin=POSTFIX_INCR