Skip to content

Commit 0cfaefd

Browse files
nicolasstuckibiboudis
authored andcommitted
Interpret method calls (not only static ones)
1 parent 467d9af commit 0cfaefd

File tree

5 files changed

+60
-24
lines changed

5 files changed

+60
-24
lines changed

tests/run-with-compiler-custom-args/tasty-interpreter/InterpretedMain.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,18 @@ object IntepretedMain {
5353
println(x6.isInstanceOf[Int])
5454
println(x6.isInstanceOf[Long])
5555
println(x6.asInstanceOf[Int])
56+
57+
58+
val bar = new Bar
59+
println(bar.meth() + 5)
60+
println(bar.methA(66))
61+
62+
val ibar = new InterpretedBar
63+
println(ibar.meth() + 5)
64+
println(ibar.methA(67))
5665
}
66+
67+
def foo(x: Int): Unit = println(x)
5768
}
5869

5970
class InterpretedBar extends IFace {

tests/run-with-compiler-custom-args/tasty-interpreter/Test.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ object Test {
4848
|true
4949
|false
5050
|64
51+
|65
52+
|66
53+
|67
54+
|68
5155
|""".stripMargin
5256

5357
val actualOutput = ps.toString

tests/run-with-compiler-custom-args/tasty-interpreter/interpreter/TreeInterpreter.scala

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ abstract class TreeInterpreter[R <: Reflection & Singleton](val reflect: R) {
1313
/** Representation of objects and values in the interpreter */
1414
type AbstractAny
1515

16-
def interpretCall(fn: Tree, argss: List[List[Term]])(implicit env: Env): AbstractAny = {
16+
def interpretCall(fn: Term, argss: List[List[Term]])(implicit env: Env): AbstractAny = {
17+
val env0 = fn match {
18+
case Term.Select(prefix, _) =>
19+
val pre = eval(prefix)
20+
env // FIXME add pre to the env as `this`
21+
case _ => env
22+
}
1723
fn.symbol match {
1824
case IsDefSymbol(sym) =>
1925
val evaluatedArgs = argss.flatten.map(arg => LocalValue.valFrom(eval(arg)))
20-
val env1 = env ++ sym.tree.paramss.headOption.getOrElse(Nil).map(_.symbol).zip(evaluatedArgs)
26+
val env1 = env0 ++ sym.tree.paramss.headOption.getOrElse(Nil).map(_.symbol).zip(evaluatedArgs)
2127
eval(sym.tree.rhs.get)(env1)
2228
case _ =>
23-
env(fn.symbol).get
29+
env0(fn.symbol).get
2430
}
2531
}
2632

@@ -163,9 +169,9 @@ abstract class TreeInterpreter[R <: Reflection & Singleton](val reflect: R) {
163169

164170

165171
private object Call {
166-
def unapply(arg: Tree): Option[(Tree, List[TypeTree], List[List[Term]])] = arg match {
167-
case fn@ Term.Select(_, _) => Some((fn, Nil, Nil))
168-
case fn@ Term.Ident(_) => Some((fn, Nil, Nil))
172+
def unapply(arg: Tree): Option[(Term, List[TypeTree], List[List[Term]])] = arg match {
173+
case Term.IsSelect(fn) => Some((fn, Nil, Nil))
174+
case Term.IsIdent(fn) => Some((fn, Nil, Nil))
169175
case Term.Apply(Call(fn, targs, args1), args2) => Some((fn, targs, args1 :+ args2))
170176
case Term.TypeApply(Call(fn, _, _), targs) => Some((fn, targs, Nil))
171177
case _ => None

tests/run-with-compiler-custom-args/tasty-interpreter/interpreter/jvm/Interpreter.scala

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,37 @@ class Interpreter[R <: Reflection & Singleton](reflect0: R) extends TreeInterpre
5050
else jvmReflection.interpretNew(fn.symbol, evaluatedArgss(argss))
5151
}
5252

53-
override def interpretCall(fn: Tree, argss: List[List[Term]])(implicit env: Env): Any = {
53+
override def interpretCall(fn: Term, argss: List[List[Term]])(implicit env: Env): Any = {
5454
if (fn.symbol.isDefinedInCurrentRun) super.interpretCall(fn, argss)
5555
else {
5656
import Term._
57-
// println(fn.show)
58-
fn.symbol match {
59-
// TODO: obviously
60-
case IsDefSymbol(sym) =>
61-
val argss2 = evaluatedArgss(argss)
62-
// argss2.foreach(println)
63-
jvmReflection.interpretStaticMethodCall(fn.symbol.owner, fn.symbol, argss2)
64-
case _ =>
65-
if (fn.symbol.flags.isObject) {
66-
jvmReflection.loadModule(fn.symbol.asVal.moduleClass.get)
57+
fn match {
58+
case Select(prefix, _) =>
59+
fn.symbol match {
60+
case IsDefSymbol(sym) =>
61+
val pre = eval(prefix).asInstanceOf[Object]
62+
val argss2 = evaluatedArgss(argss)
63+
jvmReflection.interpretMethodCall(pre, fn.symbol, argss2)
64+
case _ =>
65+
// TODO not necesarly static?
66+
jvmReflection.interpretStaticVal(fn.symbol.owner, fn.symbol)
6767
}
68-
// call to a static val
69-
else {
70-
jvmReflection.interpretStaticVal(fn.symbol.owner, fn.symbol)
68+
case _ =>
69+
// println(fn.show)
70+
fn.symbol match {
71+
// TODO: obviously
72+
case IsDefSymbol(sym) =>
73+
val argss2 = evaluatedArgss(argss)
74+
// argss2.foreach(println)
75+
jvmReflection.interpretStaticMethodCall(fn.symbol.owner, fn.symbol, argss2)
76+
case _ =>
77+
if (fn.symbol.flags.isObject) {
78+
jvmReflection.loadModule(fn.symbol.asVal.moduleClass.get)
79+
}
80+
// call to a static val
81+
else {
82+
jvmReflection.interpretStaticVal(fn.symbol.owner, fn.symbol)
83+
}
7184
}
7285
}
7386
}

tests/run-with-compiler-custom-args/tasty-interpreter/interpreter/jvm/JVMReflection.scala

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ class JVMReflection[R <: Reflection & Singleton](val reflect: R) {
5454
}
5555

5656
def interpretStaticMethodCall(moduleClass: Symbol, fn: Symbol, args: List[Object]): Object = {
57+
// TODO can we use interpretMethodCall instead?
5758
val instance = loadModule(moduleClass)
5859
val method = getMethod(instance.getClass, fn.name, paramsSig(fn))
59-
// println(">>>>>>")
60-
// println(moduleClass)
61-
// println(fn)
62-
// println(method)
60+
method.invoke(instance, args: _*)
61+
}
62+
63+
def interpretMethodCall(instance: Object, fn: Symbol, args: List[Object]): Object = {
64+
val method = getMethod(instance.getClass, fn.name, paramsSig(fn))
6365
method.invoke(instance, args: _*)
6466
}
6567

0 commit comments

Comments
 (0)