CODEGEN: support for labeled break-continue implemented
This commit is contained in:
committed by
KonstantinAnisimov
parent
9afdfc316b
commit
b193ade131
+61
-53
@@ -103,9 +103,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
fun genReturn(target: CallableDescriptor, value: LLVMValueRef?)
|
fun genReturn(target: CallableDescriptor, value: LLVMValueRef?)
|
||||||
|
|
||||||
fun genBreak()
|
fun genBreak(destination: IrBreak)
|
||||||
|
|
||||||
fun genContinue()
|
fun genContinue(destination: IrContinue)
|
||||||
|
|
||||||
fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef
|
fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?): LLVMValueRef
|
||||||
|
|
||||||
@@ -141,9 +141,9 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) = unsupported(target)
|
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) = unsupported(target)
|
||||||
|
|
||||||
override fun genBreak() = unsupported()
|
override fun genBreak(destination: IrBreak) = unsupported()
|
||||||
|
|
||||||
override fun genContinue() = unsupported()
|
override fun genContinue(destination: IrContinue) = unsupported()
|
||||||
|
|
||||||
override fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?) = unsupported(function)
|
override fun genCall(function: LLVMValueRef, args: List<LLVMValueRef>, result: String?) = unsupported(function)
|
||||||
|
|
||||||
@@ -216,70 +216,44 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
val loopCheck = codegen.basicBlock()
|
val loopCheck = codegen.basicBlock()
|
||||||
val loopExit = codegen.basicBlock()
|
val loopExit = codegen.basicBlock()
|
||||||
|
|
||||||
override fun genBreak() {
|
override fun genBreak(destination: IrBreak) {
|
||||||
codegen.br(loopExit)
|
if (destination.label == loop.label)
|
||||||
|
codegen.br(loopExit)
|
||||||
|
else
|
||||||
|
super.genBreak(destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genContinue() {
|
override fun genContinue(destination: IrContinue) {
|
||||||
codegen.br(loopCheck)
|
if (destination.label == loop.label)
|
||||||
|
codegen.br(loopCheck)
|
||||||
|
else
|
||||||
|
super.genContinue(destination)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitWhileLoop(loop: IrWhileLoop) {
|
override fun visitWhileLoop(loop: IrWhileLoop) {
|
||||||
|
evaluateWhileLoop(loop)
|
||||||
using(LoopScope(loop)) {
|
|
||||||
val loopScope = currentCodeContext as LoopScope
|
|
||||||
val loopBody = codegen.basicBlock()
|
|
||||||
|
|
||||||
codegen.br(loopScope.loopCheck)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopScope.loopCheck)
|
|
||||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
|
||||||
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopBody)
|
|
||||||
evaluateExpression(codegen.newVar(), loop.body)
|
|
||||||
|
|
||||||
codegen.br(loopScope.loopCheck)
|
|
||||||
codegen.positionAtEnd(loopScope.loopExit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
|
override fun visitDoWhileLoop(loop: IrDoWhileLoop) {
|
||||||
|
evaluateDoWhileLoop(loop)
|
||||||
using(LoopScope(loop)) {
|
|
||||||
val loopScope = currentCodeContext as LoopScope
|
|
||||||
val loopBody = codegen.basicBlock()
|
|
||||||
|
|
||||||
codegen.br(loopBody)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopBody)
|
|
||||||
evaluateExpression(codegen.newVar(), loop.body)
|
|
||||||
codegen.br(loopScope.loopCheck)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopScope.loopCheck)
|
|
||||||
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
|
||||||
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
|
||||||
|
|
||||||
codegen.positionAtEnd(loopScope.loopExit)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
fun evaluateBreak(): LLVMValueRef? {
|
fun evaluateBreak(destination: IrBreak): LLVMValueRef? {
|
||||||
(currentCodeContext as LoopScope).genBreak()
|
currentCodeContext.genBreak(destination)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
fun evaluateContinue(): LLVMValueRef? {
|
fun evaluateContinue(destination: IrContinue): LLVMValueRef? {
|
||||||
(currentCodeContext as LoopScope).genContinue()
|
currentCodeContext.genContinue(destination)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,9 +604,10 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value)
|
is IrStringConcatenation -> return evaluateStringConcatenation(tmpVariableName, value)
|
||||||
is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer)
|
is IrBlockBody -> return evaluateBlock (tmpVariableName, value as IrStatementContainer)
|
||||||
is IrWhileLoop -> return evaluateWhileLoop ( value)
|
is IrWhileLoop -> return evaluateWhileLoop ( value)
|
||||||
|
is IrDoWhileLoop -> return evaluateDoWhileLoop ( value)
|
||||||
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
is IrVararg -> return evaluateVararg (tmpVariableName, value)
|
||||||
is IrBreak -> return evaluateBreak ( )
|
is IrBreak -> return evaluateBreak ( value)
|
||||||
is IrContinue -> return evaluateContinue ( )
|
is IrContinue -> return evaluateContinue ( value)
|
||||||
null -> return null
|
null -> return null
|
||||||
else -> {
|
else -> {
|
||||||
TODO("${ir2string(value)}")
|
TODO("${ir2string(value)}")
|
||||||
@@ -914,9 +889,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
jump(block, value)
|
jump(block, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun genBreak() = TODO()
|
|
||||||
override fun genContinue() = TODO()
|
|
||||||
|
|
||||||
// When an exception is caught, finalize the scope and rethrow the exception.
|
// When an exception is caught, finalize the scope and rethrow the exception.
|
||||||
override fun genHandler(exception: LLVMValueRef) {
|
override fun genHandler(exception: LLVMValueRef) {
|
||||||
genFinalize()
|
genFinalize()
|
||||||
@@ -1019,9 +991,45 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef? {
|
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef? {
|
||||||
visitWhileLoop(loop)
|
val loopScope = LoopScope(loop)
|
||||||
// TODO: incorrect!
|
using(loopScope) {
|
||||||
|
val loopBody = codegen.basicBlock()
|
||||||
|
codegen.br(loopScope.loopCheck)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopScope.loopCheck)
|
||||||
|
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||||
|
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopBody)
|
||||||
|
evaluateExpression(codegen.newVar(), loop.body)
|
||||||
|
|
||||||
|
codegen.br(loopScope.loopCheck)
|
||||||
|
codegen.positionAtEnd(loopScope.loopExit)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun evaluateDoWhileLoop(loop: IrDoWhileLoop): LLVMValueRef? {
|
||||||
|
val loopScope = LoopScope(loop)
|
||||||
|
using(loopScope) {
|
||||||
|
val loopBody = codegen.basicBlock()
|
||||||
|
codegen.br(loopBody)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopBody)
|
||||||
|
evaluateExpression(codegen.newVar(), loop.body)
|
||||||
|
codegen.br(loopScope.loopCheck)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopScope.loopCheck)
|
||||||
|
val condition = evaluateExpression(codegen.newVar(), loop.condition)
|
||||||
|
codegen.condBr(condition, loopBody, loopScope.loopExit)
|
||||||
|
|
||||||
|
codegen.positionAtEnd(loopScope.loopExit)
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user