Implement string concatenation interpretation
This commit is contained in:
+26
-1
@@ -89,13 +89,14 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
is IrTry -> interpretTry(this, data)
|
is IrTry -> interpretTry(this, data)
|
||||||
is IrCatch -> interpretCatch(this, data)
|
is IrCatch -> interpretCatch(this, data)
|
||||||
is IrThrow -> interpretThrow(this, data)
|
is IrThrow -> interpretThrow(this, data)
|
||||||
|
is IrStringConcatenation -> interpretStringConcatenation(this, data)
|
||||||
|
|
||||||
else -> TODO("${this.javaClass} not supported")
|
else -> TODO("${this.javaClass} not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (code) {
|
return when (code) {
|
||||||
Code.RETURN -> when (this) { // TODO check label
|
Code.RETURN -> when (this) { // TODO check label
|
||||||
is IrCall, is IrReturnableBlock -> Code.NEXT
|
is IrCall, is IrReturnableBlock, is IrFunctionImpl -> Code.NEXT
|
||||||
else -> Code.RETURN
|
else -> Code.RETURN
|
||||||
}
|
}
|
||||||
Code.BREAK_WHEN -> when (this) {
|
Code.BREAK_WHEN -> when (this) {
|
||||||
@@ -510,4 +511,28 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
|||||||
expression.value.interpret(data)
|
expression.value.interpret(data)
|
||||||
return Code.EXCEPTION
|
return Code.EXCEPTION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun interpretStringConcatenation(expression: IrStringConcatenation, data: Frame): Code {
|
||||||
|
val result = StringBuilder()
|
||||||
|
expression.arguments.forEach {
|
||||||
|
it.interpret(data).also { code -> if (code != Code.NEXT) return code }
|
||||||
|
result.append(
|
||||||
|
when (val returnValue = data.popReturnValue()) {
|
||||||
|
is Primitive<*> -> returnValue.value.toString()
|
||||||
|
is Wrapper -> returnValue.value.toString()
|
||||||
|
is Complex -> {
|
||||||
|
val toStringFun = returnValue.getToStringFunction()
|
||||||
|
val newFrame = InterpreterFrame(mutableListOf(Variable(toStringFun.symbol.getReceiver()!!, returnValue)))
|
||||||
|
val code = toStringFun.body?.let { toStringFun.interpret(newFrame) } ?: calculateOverridden(toStringFun, newFrame)
|
||||||
|
if (code != Code.NEXT) return code
|
||||||
|
(newFrame.popReturnValue() as Primitive<*>).value.toString()
|
||||||
|
}
|
||||||
|
else -> throw AssertionError("$returnValue cannot be used in StringConcatenation expression")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.pushReturnValue(result.toString().toState(expression.type))
|
||||||
|
return Code.NEXT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -122,6 +122,12 @@ open class Complex(override var irClass: IrClass, override val fields: MutableLi
|
|||||||
.firstOrNull { it.descriptor.valueParameters.map { it.type } == descriptor.valueParameters.map { it.type } }
|
.firstOrNull { it.descriptor.valueParameters.map { it.type } == descriptor.valueParameters.map { it.type } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getToStringFunction(): IrFunctionImpl {
|
||||||
|
return irClass.declarations.filterIsInstance<IrFunction>()
|
||||||
|
.filter { it.descriptor.name.asString() == "toString" }
|
||||||
|
.first { it.descriptor.valueParameters.isEmpty() } as IrFunctionImpl
|
||||||
|
}
|
||||||
|
|
||||||
override fun copy(): State {
|
override fun copy(): State {
|
||||||
return Complex(irClass, fields).apply {
|
return Complex(irClass, fields).apply {
|
||||||
this@apply.superType = this@Complex.superType
|
this@apply.superType = this@Complex.superType
|
||||||
|
|||||||
Reference in New Issue
Block a user