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 IrCatch -> interpretCatch(this, data)
|
||||
is IrThrow -> interpretThrow(this, data)
|
||||
is IrStringConcatenation -> interpretStringConcatenation(this, data)
|
||||
|
||||
else -> TODO("${this.javaClass} not supported")
|
||||
}
|
||||
|
||||
return when (code) {
|
||||
Code.RETURN -> when (this) { // TODO check label
|
||||
is IrCall, is IrReturnableBlock -> Code.NEXT
|
||||
is IrCall, is IrReturnableBlock, is IrFunctionImpl -> Code.NEXT
|
||||
else -> Code.RETURN
|
||||
}
|
||||
Code.BREAK_WHEN -> when (this) {
|
||||
@@ -510,4 +511,28 @@ class IrInterpreter(irModule: IrModuleFragment) {
|
||||
expression.value.interpret(data)
|
||||
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 } }
|
||||
}
|
||||
|
||||
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 {
|
||||
return Complex(irClass, fields).apply {
|
||||
this@apply.superType = this@Complex.superType
|
||||
|
||||
Reference in New Issue
Block a user