Implement JSR 223 script template with eval functions, some fixes

This commit is contained in:
Ilya Chernikov
2017-02-11 23:38:45 +01:00
parent 63aae56b11
commit d3682b7f7d
10 changed files with 96 additions and 14 deletions
@@ -55,7 +55,7 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
if (idx < 0) throw java.util.NoSuchElementException("Cannot rest to inexistent line ${id.no}")
if (idx < lastIndex) {
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
removeRange(idx + 1, lastIndex)
removeRange(idx + 1, size)
currentGeneration.incrementAndGet()
return removed
}
@@ -46,7 +46,9 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
aggregatedState.apply {
lock.write {
if (state1.history.size > state2.history.size) {
state2.history.peek()?.let { state1.history.resetTo(it.id) }
state2.history.peek()?.let {
state1.history.resetTo(it.id)
}
assert(state1.history.size == state2.history.size)
}
}
@@ -21,7 +21,8 @@ import java.io.Reader
import java.util.concurrent.locks.ReentrantReadWriteLock
import javax.script.*
val KOTLIN_SCRIPT_STATE_BINDINGS_KEY = "kotlin.script.state"
const val KOTLIN_SCRIPT_STATE_BINDINGS_KEY = "kotlin.script.state"
const val KOTLIN_SCRIPT_ENGINE_BINDINGS_KEY = "kotlin.script.engine"
abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEngineFactory) : AbstractScriptEngine(), ScriptEngine, Compilable {
@@ -36,16 +37,22 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
override fun compile(script: Reader): CompiledScript = compile(script.readText(), getContext())
override fun createBindings(): Bindings = SimpleBindings()
override fun createBindings(): Bindings = SimpleBindings().apply { put(KOTLIN_SCRIPT_ENGINE_BINDINGS_KEY, this) }
override fun getFactory(): ScriptEngineFactory = myFactory
// the parameter could be used in the future when we decide to keep state completely in the context and solve appropriate problems (now e.g. replCompiler keeps separate state)
fun nextCodeLine(context: ScriptContext, code: String) = getCurrentState(context).let { ReplCodeLine(it.getNextLineNo(), it.currentGeneration, code) }
protected open fun createState(lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState<*> = AggregatedReplStageState(replCompiler.createState(lock), replEvaluator.createState(lock), lock)
protected abstract fun createState(lock: ReentrantReadWriteLock = ReentrantReadWriteLock()): IReplStageState<*>
protected fun getCurrentState(context: ScriptContext) = context.getBindings(ScriptContext.ENGINE_SCOPE).getOrPut(KOTLIN_SCRIPT_STATE_BINDINGS_KEY, { replEvaluator.createState() }) as IReplStageState<*>
protected fun getCurrentState(context: ScriptContext) =
context.getBindings(ScriptContext.ENGINE_SCOPE)
.getOrPut(KOTLIN_SCRIPT_STATE_BINDINGS_KEY, {
// TODO: check why createBinding is not called on creating default context, so the engine is not set
context.getBindings(ScriptContext.ENGINE_SCOPE).put(KOTLIN_SCRIPT_ENGINE_BINDINGS_KEY, this@KotlinJsr223JvmScriptEngineBase)
createState()
}) as IReplStageState<*>
open fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes? = null