Skip to content

Commit

Permalink
add server mode with repl reading stdio no jline
Browse files Browse the repository at this point in the history
  • Loading branch information
bjornregnell committed May 18, 2017
1 parent a5d5dec commit 07e7451
Show file tree
Hide file tree
Showing 3 changed files with 356 additions and 308 deletions.
2 changes: 2 additions & 0 deletions src/reqT/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ object Main {
println("test -t <file> Run test script with Model in file")
println("meta -m [<from>] Generate metamodel [<from>] to file: GENERATED-metamodel.scala")
println("flex -f Print jflex clauses to file: reqT-flex-clauses.txt")
println("serv -s Server mode interpreting from stdio without jline")
}

def main(args : Array[String]) : Unit = {
Expand All @@ -35,6 +36,7 @@ object Main {
case a if Set("flex", "-f")(a) => genJFlex(args.drop(1))
case a if Set("meta", "-m")(a) => genMeta(args.drop(1))
case a if Set("test", "-t")(a) => test(args.drop(1))
case a if Set("serv", "-s")(a) => repl.loopInterpreterFromStandardIO()
case _ =>
println("ERROR Unknown arg: " + args.mkString(" ")); help()
}
Expand Down
161 changes: 102 additions & 59 deletions src/reqT/ReadEvaluatePrintLoop.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/***
** _______
** |__ __| reqT - a requirements engineering tool
** _ __ ___ __ _ | | (c) 2011-2014, Lund University
/***
** _______
** |__ __| reqT - a requirements engineering tool
** _ __ ___ __ _ | | (c) 2011-2014, Lund University
** | __|/ _ \ / _ || | http://reqT.org
** | | | __/| (_| || |
** |_| \___| \__ ||_|
** | |
** |_|
** reqT is open source, licensed under the BSD 2-clause license:
** http://opensource.org/licenses/bsd-license.php
** | | | __/| (_| || |
** |_| \___| \__ ||_|
** | |
** |_|
** reqT is open source, licensed under the BSD 2-clause license:
** http://opensource.org/licenses/bsd-license.php
**************************************************************************/

package reqT
Expand All @@ -18,30 +18,30 @@ import interpreter._
import java.io._
import java.lang.{System => JSystem}

object repl {
val helpOnReqT =
object repl {
val helpOnReqT =
"** Type edit to start model editor gui" +
"\n** Type :help for help on the Scala interpreter" +
"\n** Type :pa to enter paste mode" +
"\n** Type :q to exit when all sub-threads are done" +
"\n** Type sys.exit to exit and terminate all threads" +
"\n** Type Feature? to get help on a concept, e.g. Feature"
val versionMsg = s"\n** Welcome to reqT version $reqT_VERSION" +
s"\n** Snapshot build number: $reqT_BUILD" +
s"\n** Scala $SCALA_VERSION" +
"\n** Java version " + JSystem.getProperty("java.version") +
s"\n** Snapshot build number: $reqT_BUILD" +
s"\n** Scala $SCALA_VERSION" +
"\n** Java version " + JSystem.getProperty("java.version") +
" " + JSystem.getProperty("java.vm.name")
val startMsg = versionMsg +
s"\n$PREAMBLE\n$helpOnReqT"
s"\n$PREAMBLE\n$helpOnReqT"

@volatile
var interpreter: Option[ReqTILoop] = None
def checkIntp() {
if (interpreter == None)
throw new Error("No interpreter available. Try reqT.initInterpreter() ")
}
def checkIntp() {
if (interpreter == None)
throw new Error("No interpreter available. Try reqT.initInterpreter() ")
}

def reset() {
def reset() {
/*
//the idea was that this should avoid the memory leak bug:
//https://issues.scala-lang.org/browse/SI-4331
Expand All @@ -56,15 +56,15 @@ object repl {
}
$intp.interpret("""i += 1;println(i + ":" + new java.util.Date)""")
j += 1
}
}
*/
interpreter.map { i =>
interpreter.map { i =>
i.intp.reset
i.initReqT
reqT.initInterpreter()
}
}

class ReqTILoop(out : PrintWriter) extends ILoop(None, out) {
override def createInterpreter() {
super.createInterpreter()
Expand All @@ -85,24 +85,24 @@ object repl {
out.flush()
}
}

class FileRunner(out : PrintWriter, fileName: String) extends ReqTILoop(out : PrintWriter) {
override def createInterpreter() {
super.createInterpreter()
intp.quietRun(reqT.load(fileName))
intp.quietRun(reqT.load(fileName))
}
override def printWelcome(): Unit = { out.flush() }
}

class CodeRunner(out : PrintWriter, code: String) extends ReqTILoop(out : PrintWriter) {
override def createInterpreter() {
super.createInterpreter()
intp.quietRun(s"{$code}")
intp.quietRun(s"{$code}")
}
override def printWelcome(): Unit = { out.flush() }
}
class EditorLauncher(out : PrintWriter, args : Array[String])

class EditorLauncher(out : PrintWriter, args : Array[String])
extends ReqTILoop(out : PrintWriter) {
override def createInterpreter() {
super.createInterpreter()
Expand All @@ -112,27 +112,27 @@ object repl {
val f = args(i)
println("f = "+f)
intp.interpret(s"println($i)")
val code = s"""val editor$i = edit(repl.interpretModel(load("$f")).getOrElse(Model(Spec(s"ERROR loading Model from file $f")))"""
val code = s"""val editor$i = edit(repl.interpretModel(load("$f")).getOrElse(Model(Spec(s"ERROR loading Model from file $f")))"""
println("code = " + code)
intp.interpret(code)
}
}
}

def startInterpreting() {
val out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(JSystem.out) ) )
val settings = new GenericRunnerSettings(out.println)
settings.usejavacp.value = true
interpreter = Some( new ReqTILoop(out) )
interpreter.map(_.process(settings))
interpreter.map(_.process(settings))
}

def interpretFile(fileName: String) {
val out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(JSystem.out) ) )
val settings = new GenericRunnerSettings(out.println)
settings.usejavacp.value = true
interpreter = Some( new FileRunner(out, fileName) )
interpreter.map(_.process(settings))
interpreter.map(_.process(settings))
}

def initInterpreterAndRun(code: String) {
Expand All @@ -142,50 +142,93 @@ object repl {
interpreter = Some( new CodeRunner(out, code) )
interpreter.map(_.process(settings))
}

def initInterpreterAndEdit(args : Array[String]) {
val out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(JSystem.out) ) )
val settings = new GenericRunnerSettings(out.println)
settings.usejavacp.value = true
interpreter = Some(new EditorLauncher(out, args) )
interpreter.map(_.process(settings))
interpreter.map(_.process(settings))
}
def quietRun(code: String) {
checkIntp()

def quietRun(code: String) {
checkIntp()
interpreter .map { i => i.quietRun(code) }
}
def run(code: String): Option[IR.Result] = {
checkIntp()

def run(code: String): Option[IR.Result] = {
checkIntp()
interpreter .map { i => i.interpret(code) }
}
def interpret(code: String): Option[Any] = {
checkIntp()

def interpret(code: String): Option[Any] = {
checkIntp()
interpreter .map { i =>
val result = Array[Any](null)
i.beQuietDuring(i.bind("result", "Array[Any]", result))
val verdict = i.quietRun(s"""{result(0) = $code}""")
if (verdict == scala.tools.nsc.interpreter.IR.Success)
Some(result(0))
else None
Some(result(0))
else None
} .getOrElse(None)
}
def interpretInt(code: String): Option[Int] =

def interpretInt(code: String): Option[Int] =
interpret(s"""{$code}: Int""").map(_.asInstanceOf[Int])
def interpretString(code: String): Option[String] =

def interpretString(code: String): Option[String] =
interpret(s"""{$code}: String""").map(_.asInstanceOf[String])

def interpretBoolean(code: String): Option[Boolean] =
interpret(s"""{$code}: Boolean""").map(_.asInstanceOf[Boolean])
def interpretModel(code: String): Option[Model] =
def interpretBoolean(code: String): Option[Boolean] =
interpret(s"""{$code}: Boolean""").map(_.asInstanceOf[Boolean])

def interpretModel(code: String): Option[Model] =
interpret(s"""{$code}: reqT.Model""").map(_.asInstanceOf[Model])

def interpretTransformer(code: String): Option[Model => Model] =
def interpretTransformer(code: String): Option[Model => Model] =
interpret(s"""{$code}: reqT.Model => reqT.Model""").map(_.asInstanceOf[Model => Model])



// SERVER MODE reading from stdio, no jline, no string print truncate
// http://docs.scala-lang.org/overviews/repl/embedding


@volatile
var isServerMode = false

class ServerILoop(in: BufferedReader, out : PrintWriter) extends ILoop(in, out) {
override def createInterpreter() {
super.createInterpreter()
initReqTServer()
}

override val prompt = "\n<!-- reqT server ready for input -->\n"

def initReqTServer() {
intp.quietRun("import scala.language._")
intp.quietRun("import reqT._")
intp.isettings.maxPrintString = Int.MaxValue
isServerMode = true
}

override def printWelcome(): Unit = {
val jvm = JSystem.getProperty("java.version")
val scla = scala.util.Properties.versionNumberString
out.println(s"reqT v$reqT_VERSION running in server mode with Scala $scla on JVM $jvm ")
out.flush()
}
}

def loopInterpreterFromStandardIO(): Unit = {
val out = new PrintWriter(scala.Console.out, true)
val settings = new scala.tools.nsc.Settings
settings.usejavacp.value = true
val iloop = new ServerILoop(scala.Console.in, out)
isServerMode = true
while (true) {
iloop.process(settings)
println("<!-- Exit issued. Restarting reqT in server mode... -->")
}
}

}
Loading

0 comments on commit 07e7451

Please sign in to comment.