Skip to content

Commit 67d67ff

Browse files
committed
WIP
1 parent deac2f9 commit 67d67ff

File tree

5 files changed

+64
-20
lines changed

5 files changed

+64
-20
lines changed

compiler/src/dotty/tools/dotc/interpreter/Interpreter.scala

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,16 @@ package interpreter
33

44
import java.io.{PrintWriter, StringWriter}
55

6-
import dotty.tools.dotc.ast.tpd
7-
import dotty.tools.dotc.ast.Trees._
8-
import dotty.tools.dotc.core.Constants._
96
import dotty.tools.dotc.core.Contexts._
107
import dotty.tools.dotc.core.Decorators._
118
import dotty.tools.dotc.core.Flags._
129
import dotty.tools.dotc.core.Names._
10+
import dotty.tools.dotc.core.NameKinds._
1311
import dotty.tools.dotc.core.Symbols._
14-
import dotty.tools.dotc.core.quoted.Quoted
1512
import dotty.tools.dotc.util.Positions.Position
1613

1714
import scala.reflect.ClassTag
1815
import java.net.URLClassLoader
19-
import java.lang.reflect.Constructor
2016
import java.lang.reflect.Method
2117

2218
/** Tree interpreter that can interpret
@@ -28,7 +24,7 @@ import java.lang.reflect.Method
2824
* The interpreter assumes that all calls in the trees are to code that was
2925
* previously compiled and is present in the classpath of the current context.
3026
*/
31-
class Interpreter(implicit ctx: Context) {
27+
class Interpreter(pos: Position)(implicit ctx: Context) {
3228

3329
private[this] val classLoader = {
3430
val urls = ctx.settings.classpath.value.split(':').map(cp => java.nio.file.Paths.get(cp).toUri.toURL)
@@ -38,9 +34,9 @@ class Interpreter(implicit ctx: Context) {
3834
/** Returns the interpreted result of interpreting the code a call to the symbol with default arguments.
3935
* Return Some of the result or None if some error happen during the interpretation.
4036
*/
41-
def interpretCallToSymbol[T](sym: Symbol)(implicit pos: Position, ct: ClassTag[T]): Option[T] = {
37+
def interpretCallToSymbol[T](sym: Symbol)(implicit ct: ClassTag[T]): Option[T] = {
4238
try {
43-
val clazz = loadClass(sym.owner.companionModule.fullName)(pos)
39+
val (clazz, instance) = loadModule(sym.owner)
4440
val paramClasses = paramsSig(sym)
4541
val interpretedArgs = paramClasses.map { clazz =>
4642
if (clazz == classOf[Boolean]) false.asInstanceOf[Object]
@@ -54,9 +50,10 @@ class Interpreter(implicit ctx: Context) {
5450
else null
5551
}
5652

53+
5754
val method = getMethod(clazz, sym.name, paramClasses)
5855

59-
val o = stopIfRuntimeException(method.invoke(null, interpretedArgs: _*))(pos)
56+
val o = stopIfRuntimeException(method.invoke(instance, interpretedArgs: _*))
6057

6158
o match {
6259
case obj: T => Some(obj)
@@ -72,7 +69,18 @@ class Interpreter(implicit ctx: Context) {
7269
}
7370
}
7471

75-
private def loadClass(name: Name)(implicit pos: Position): Class[_] = {
72+
private def loadModule(sym: Symbol): (Class[_], Object) = {
73+
if (sym.owner.is(Package)) {
74+
// is top level object
75+
(loadClass(sym.companionModule.fullName), null)
76+
} else {
77+
// nested object in an object
78+
val clazz = loadClass(sym.fullNameSeparated(FlatName))
79+
(clazz, clazz.newInstance().asInstanceOf[Object])
80+
}
81+
}
82+
83+
private def loadClass(name: Name): Class[_] = {
7684
try classLoader.loadClass(name.toString)
7785
catch {
7886
case _: ClassNotFoundException =>
@@ -81,7 +89,7 @@ class Interpreter(implicit ctx: Context) {
8189
}
8290
}
8391

84-
private def getMethod(clazz: Class[_], name: Name, paramClasses: List[Class[_]])(implicit pos: Position): Method = {
92+
private def getMethod(clazz: Class[_], name: Name, paramClasses: List[Class[_]]): Method = {
8593
try clazz.getMethod(name.toString, paramClasses: _*)
8694
catch {
8795
case _: NoSuchMethodException =>
@@ -90,7 +98,7 @@ class Interpreter(implicit ctx: Context) {
9098
}
9199
}
92100

93-
private def stopIfRuntimeException[T](thunk: => T)(implicit pos: Position): T = {
101+
private def stopIfRuntimeException[T](thunk: => T): T = {
94102
try thunk
95103
catch {
96104
case ex: RuntimeException =>

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
515515
}
516516

517517
val tree1 =
518-
if (level == 0) cpy.Inlined(tree)(call, bindings, Splicer.splice(body, call, bindings).withPos(tree.pos))
518+
if (level == 0) cpy.Inlined(tree)(call, bindings, Splicer.splice(body, call, bindings, tree.pos).withPos(tree.pos))
519519
else seq(stagedBindings, cpy.Select(expansion)(cpy.Inlined(tree)(call, splicedBindings, body), name))
520520
val tree2 = transform(tree1)
521521

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ object Splicer {
2121
* and for `~xyz` the tree of `xyz` is interpreted for which the
2222
* resulting expression is returned as a `Tree`
2323
*/
24-
def splice(tree: Tree, call: Tree, bindings: List[Tree])(implicit ctx: Context): Tree = tree match {
24+
def splice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = tree match {
2525
case Quoted(quotedTree) => quotedTree
26-
case _ => reflectiveSplice(tree, call, bindings)
26+
case _ => reflectiveSplice(tree, call, bindings, pos)
2727
}
2828

29-
private def reflectiveSplice(tree: Tree, call: Tree, bindings: List[Tree])(implicit ctx: Context): Tree = {
29+
private def reflectiveSplice(tree: Tree, call: Tree, bindings: List[Tree], pos: Position)(implicit ctx: Context): Tree = {
3030
val liftedArgs = {
3131
val bindMap = bindings.map {
3232
case vdef: ValDef => (vdef.rhs, ref(vdef.symbol))
@@ -54,13 +54,12 @@ object Splicer {
5454
liftArgs(call.symbol.info, allArgs(call, Nil))
5555
}
5656

57-
implicit val pos: Position = tree.pos
58-
val interpreter = new Interpreter
57+
val interpreter = new Interpreter(pos)
5958
val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol)
60-
interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs)).fold(tree)(PickledQuotes.quotedExprToTree)
59+
interpreted.flatMap(lambda => evaluateLambda(lambda, liftedArgs, pos)).fold(tree)(PickledQuotes.quotedExprToTree)
6160
}
6261

63-
private def evaluateLambda(lambda: Seq[Any] => Object, args: Seq[Any])(implicit pos: Position, ctx: Context): Option[scala.quoted.Expr[_]] = {
62+
private def evaluateLambda(lambda: Seq[Any] => Object, args: Seq[Any], pos: Position)(implicit ctx: Context): Option[scala.quoted.Expr[_]] = {
6463
try Some(lambda(args).asInstanceOf[scala.quoted.Expr[_]])
6564
catch {
6665
case ex: scala.quoted.QuoteError =>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
import scala.quoted._
3+
4+
object Macro {
5+
6+
7+
object Implementation {
8+
9+
inline def plus(inline n: Int, m: Int): Int = ~plus(n, '(m))
10+
11+
def plus(n: Int, m: Expr[Int]): Expr[Int] =
12+
if (n == 0) m
13+
else '{ ~n.toExpr + ~m }
14+
15+
object Implementation2 {
16+
17+
inline def plus(inline n: Int, m: Int): Int = ~plus(n, '(m))
18+
19+
def plus(n: Int, m: Expr[Int]): Expr[Int] =
20+
if (n == 0) m
21+
else '{ ~n.toExpr + ~m }
22+
}
23+
}
24+
25+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object PowerInlined1 {
2+
import Macro.Implementation._
3+
4+
plus(0, 2)
5+
plus(1, 3)
6+
7+
Macro.Implementation.plus(0, 2)
8+
Macro.Implementation.plus(1, 3)
9+
10+
Macro.Implementation.Implementation2.plus(0, 2)
11+
Macro.Implementation.Implementation2.plus(1, 3)
12+
}

0 commit comments

Comments
 (0)