Skip to content

Commit

Permalink
Merge pull request #70 from MoeOrganization/prakashk/repl-multiline-2
Browse files Browse the repository at this point in the history
REPL multi-line and history support (take 2)
  • Loading branch information
Stevan Little committed Mar 15, 2013
2 parents f446010 + 0446b1c commit fe43f09
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 22 deletions.
55 changes: 34 additions & 21 deletions src/main/scala/org/moe/Moe.scala
Expand Up @@ -112,35 +112,43 @@ object Moe {
"modify it under the terms specified in the LICENSE file.\n"
)

/*
TODO:
- would be nice to have line editing capabilities
- this presents a problem under sbt since sbt wants
to own the line editing capabilities
*/
object EvalResult extends Enumeration {
val Success, Partial, Failure = Value
}

object REPL {
def enter (interpreter: Interpreter, runtime: MoeRuntime, dumpAST: Boolean = false): Unit = {
import jline.ConsoleReader
import jline.{ConsoleReader, History}

val cReader: ConsoleReader = new ConsoleReader
val prompt = "moe> "
def isReplCommand(input: String) = input(0) == ':'

var replOptions = Map(
"printOutput" -> true,
"dumpAST" -> dumpAST,
"prettyPrintAST" -> false
"prettyPrintAST" -> true
)

val historyFile = new File(System.getProperty("user.home") + File.separator + ".moereplhist")
val cReader: ConsoleReader = new ConsoleReader
cReader.setHistory(new History(historyFile))

val prompt = "moe> "
val continuationPrompt = "...| "

var partialInput: String = ""
while (true) {
val line = cReader readLine prompt
if (line != null && line.length > 0 && line != "exit") {
if (line(0) == ':')
replOptions = processReplCommand(line, replOptions)
else
evalLine(interpreter, runtime, line, replOptions)
}
else {
if (line != "exit") println()
return
val line = cReader readLine (if (partialInput == "") prompt else continuationPrompt)
line match {
case null => { println(); return }
case "exit" => return
case "" => ""
case _ => if (isReplCommand(line))
replOptions = processReplCommand(line, replOptions)
else
evalLine(interpreter, runtime, partialInput + line, replOptions) match {
case EvalResult.Partial => partialInput += line
case _ => partialInput = ""
}
}
}
}
Expand All @@ -161,9 +169,14 @@ object Moe {
if( options("printOutput") ) {
println(result.toString)
}
EvalResult.Success
}
catch {
case e: Exception => System.err.println(e)
case i: MoeErrors.ParserInputIncomplete => EvalResult.Partial
case e: Exception => {
System.err.println(e)
EvalResult.Failure
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/scala/org/moe/parser/Parser.scala
Expand Up @@ -3,6 +3,7 @@ package org.moe.parser
import scala.util.parsing.combinator._
// import scala.util.matching.Regex
import org.moe.ast._
import org.moe.runtime._

import ParserUtils._

Expand All @@ -13,7 +14,10 @@ object MoeParsers extends Statements {
def parseFromEntry(input: String): StatementsNode =
parseAll(getEntryPoint, input) match {
case Success(result, _) => result.asInstanceOf[StatementsNode]
case failure : NoSuccess => scala.sys.error(failure.msg)
case failure : NoSuccess => if (failure.next.atEnd)
throw new MoeErrors.ParserInputIncomplete(failure.msg)
else
throw new MoeErrors.ParserInputError(failure.msg)
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/org/moe/runtime/MoeErrors.scala
Expand Up @@ -45,4 +45,8 @@ object MoeErrors {
class TypeError (msg: String) extends MoeProblems(msg)
class UnexpectedType (msg: String) extends TypeError(msg)
class IncompatibleType (msg: String) extends TypeError(msg)

// Parser errors
class ParserInputIncomplete (msg: String) extends MoeException(msg)
class ParserInputError (msg: String) extends MoeException(msg)
}

0 comments on commit fe43f09

Please sign in to comment.