Add variables support in interpreter
This commit is contained in:
+21
-3
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||||
import org.jetbrains.kotlin.ir.util.statements
|
import org.jetbrains.kotlin.ir.util.statements
|
||||||
@@ -22,12 +23,12 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
private val any = Complex(builtIns.any, mutableListOf())
|
private val any = Complex(builtIns.any, mutableListOf())
|
||||||
|
|
||||||
fun interpret(expression: IrExpression): IrExpression {
|
fun interpret(expression: IrExpression): IrExpression {
|
||||||
return visitExpression(expression, InterpreterFrame()).toIrExpression()
|
return visitExpression(expression, InterpreterFrame()).convertToIrExpression(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun State.toIrExpression(): IrExpression {
|
private fun State.convertToIrExpression(expression: IrExpression): IrExpression {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Primitive<*> -> this.getIrConst()
|
is Primitive<*> -> this.getIrConst().value.toIrConst(expression) // it is necessary to replace ir offsets
|
||||||
else -> TODO("not supported")
|
else -> TODO("not supported")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,4 +130,21 @@ class IrInterpreter : IrElementVisitor<State, Frame> {
|
|||||||
override fun visitGetValue(expression: IrGetValue, data: Frame): State {
|
override fun visitGetValue(expression: IrGetValue, data: Frame): State {
|
||||||
return data.getVar(expression.symbol.descriptor).copy()
|
return data.getVar(expression.symbol.descriptor).copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitVariable(declaration: IrVariable, data: Frame): State {
|
||||||
|
val variable = declaration.initializer?.accept(this, data)?.setDescriptor(declaration.descriptor)
|
||||||
|
variable?.let { data.addVar(it) }
|
||||||
|
return unit
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSetVariable(expression: IrSetVariable, data: Frame): State {
|
||||||
|
if (data.contains(expression.symbol.descriptor)) {
|
||||||
|
val variable = data.getVar(expression.symbol.descriptor)
|
||||||
|
variable.setState(expression.value.accept(this, data))
|
||||||
|
} else {
|
||||||
|
val variable = expression.value.accept(this, data).setDescriptor(expression.symbol.descriptor)
|
||||||
|
data.addVar(variable)
|
||||||
|
}
|
||||||
|
return unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-10
@@ -76,21 +76,27 @@ fun IrFunctionAccessExpression.getBody(): IrBody? {
|
|||||||
return this.symbol.owner.body
|
return this.symbol.owner.body
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Any.toIrConst(expression: IrExpression): IrConst<*> {
|
fun Any?.toIrConst(expression: IrExpression): IrConst<*> {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Boolean -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Boolean, this)
|
is Boolean -> expression.copyParametersTo(IrConstKind.Boolean, this)
|
||||||
is Char -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Char, this)
|
is Char -> expression.copyParametersTo(IrConstKind.Char, this)
|
||||||
is Byte -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Byte, this)
|
is Byte -> expression.copyParametersTo(IrConstKind.Byte, this)
|
||||||
is Short -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Short, this)
|
is Short -> expression.copyParametersTo(IrConstKind.Short, this)
|
||||||
is Int -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Int, this)
|
is Int -> expression.copyParametersTo(IrConstKind.Int, this)
|
||||||
is Long -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Long, this)
|
is Long -> expression.copyParametersTo(IrConstKind.Long, this)
|
||||||
is String -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.String, this)
|
is String -> expression.copyParametersTo(IrConstKind.String, this)
|
||||||
is Float -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Float, this)
|
is Float -> expression.copyParametersTo(IrConstKind.Float, this)
|
||||||
is Double -> IrConstImpl(expression.startOffset, expression.endOffset, expression.type, IrConstKind.Double, this)
|
is Double -> expression.copyParametersTo(IrConstKind.Double, this)
|
||||||
|
null -> expression.copyParametersTo(IrConstKind.Null, this)
|
||||||
else -> throw UnsupportedOperationException("Unsupported const element type $this")
|
else -> throw UnsupportedOperationException("Unsupported const element type $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun <T> IrExpression.copyParametersTo(kind: IrConstKind<T>, value: Any?): IrConst<T> {
|
||||||
|
return IrConstImpl(startOffset, endOffset, type, kind, value as T)
|
||||||
|
}
|
||||||
|
|
||||||
fun <T> IrConst<T>.toPrimitive(): Primitive<T> {
|
fun <T> IrConst<T>.toPrimitive(): Primitive<T> {
|
||||||
return Primitive(this)
|
return Primitive(this)
|
||||||
}
|
}
|
||||||
+5
@@ -12,6 +12,7 @@ interface Frame {
|
|||||||
fun addVar(state: State)
|
fun addVar(state: State)
|
||||||
fun getVar(descriptor: DeclarationDescriptor): State
|
fun getVar(descriptor: DeclarationDescriptor): State
|
||||||
fun getAll(): List<State>
|
fun getAll(): List<State>
|
||||||
|
fun contains(descriptor: DeclarationDescriptor): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
class InterpreterFrame(val pool: MutableList<State> = mutableListOf()) : Frame {
|
class InterpreterFrame(val pool: MutableList<State> = mutableListOf()) : Frame {
|
||||||
@@ -27,4 +28,8 @@ class InterpreterFrame(val pool: MutableList<State> = mutableListOf()) : Frame {
|
|||||||
override fun getAll(): List<State> {
|
override fun getAll(): List<State> {
|
||||||
return pool
|
return pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun contains(descriptor: DeclarationDescriptor): Boolean {
|
||||||
|
return pool.any { it.isTypeOf(descriptor) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user