-
-
Save SethTisue/2011854 to your computer and use it in GitHub Desktop.
quick interpreter for nescala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package necsala.embedded | |
import scala.tools.nsc.interpreter.AbstractFileClassLoader | |
import scala.tools.nsc.{Global, Settings} | |
import scala.tools.nsc.util.BatchSourceFile | |
import scala.tools.nsc.io.{AbstractFile, VirtualDirectory} | |
import java.io.File | |
import java.util.jar.JarFile | |
import java.net.URLClassLoader | |
class Interpreter private () { | |
/** Evaluate a string of Scala source. Apart from compiler execution all bets are off. */ | |
def evaluate[A](code: String): A = { | |
val (name, prepared) = asInterpreterClass(code) | |
val compiler = new global.Run | |
compiler.compileSources(List(new BatchSourceFile("<text>", prepared))) | |
try { | |
val clazz = classLoader.loadClass(name) | |
val instance = clazz.newInstance() | |
val f0Any = instance.asInstanceOf[() => Any] | |
f0Any().asInstanceOf[A] | |
} catch { | |
case e => throw e //TODO coherent exception | |
} | |
} | |
/** Given raw source, generate a complete class as a subtype of () => Any. */ | |
private def asInterpreterClass(source: String): (String, String) = { | |
val name = "Interpreted_%s" format (math.abs(scala.util.Random.nextLong)) | |
name -> ("class %s extends (() => Any) { def apply() = { %s }}" format (name, source)) | |
} | |
private val target = new VirtualDirectory("<memory>", None) | |
private val classLoader = new AbstractFileClassLoader(target, this.getClass.getClassLoader) | |
private val settings = { | |
val s = new Settings() | |
s.outputDirs.setSingleOutput(target) | |
s.usejavacp.value = true | |
s | |
} | |
private val global = new Global(settings /*, reporter*/ ) | |
} | |
object Interpreter { | |
/** Create a new interpreter with the current classpath. */ | |
def local = new Interpreter | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment