Skip to content

Commit

Permalink
1.7.x: add default values for interpreter execute (#1598)
Browse files Browse the repository at this point in the history
Update interpreter API to be more consistent with recent
changes in 1.8.
  • Loading branch information
brharrington authored Jan 10, 2024
1 parent 9a89045 commit 3144d87
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,21 +106,25 @@ case class Interpreter(vocabulary: List[Word]) {
if (s.program.isEmpty) s.context else execute(nextStep(s))
}

final def execute(program: List[Any], context: Context, unfreeze: Boolean = true): Context = {
final def executeProgram(
program: List[Any],
context: Context,
unfreeze: Boolean = true
): Context = {
val result = execute(Step(program, context))
if (unfreeze) result.unfreeze else result
}

final def execute(program: List[Any]): Context = {
execute(program, Context(this, Nil, Map.empty))
final def executeProgram(program: List[Any]): Context = {
executeProgram(program, Context(this, Nil, Map.empty))
}

final def execute(program: String): Context = {
execute(splitAndTrim(program))
}

final def execute(program: String, vars: Map[String, Any], features: Features): Context = {
execute(splitAndTrim(program), Context(this, Nil, vars, vars, features = features))
final def execute(
program: String,
vars: Map[String, Any] = Map.empty,
features: Features = Features.STABLE
): Context = {
executeProgram(splitAndTrim(program), Context(this, Nil, vars, vars, features = features))
}

@scala.annotation.tailrec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ object StandardVocabulary extends Vocabulary {
override def matches(stack: List[Any]): Boolean = true

override def execute(context: Context): Context = {
context.interpreter.execute(body, context, unfreeze = false)
context.interpreter.executeProgram(body, context, unfreeze = false)
}

override def summary: String =
Expand All @@ -81,7 +81,7 @@ object StandardVocabulary extends Vocabulary {
override def execute(context: Context): Context = {
context.stack match {
case (vs: List[_]) :: stack =>
context.interpreter.execute(vs, context.copy(stack = stack), unfreeze = false)
context.interpreter.executeProgram(vs, context.copy(stack = stack), unfreeze = false)
case _ => invalidStack
}
}
Expand Down Expand Up @@ -198,7 +198,7 @@ object StandardVocabulary extends Vocabulary {
context.stack match {
case (f: List[_]) :: (vs: List[_]) :: stack =>
vs.reverse.foldLeft(context.copy(stack = stack)) { (c, v) =>
c.interpreter.execute(f, c.copy(stack = v :: c.stack), unfreeze = false)
c.interpreter.executeProgram(f, c.copy(stack = v :: c.stack), unfreeze = false)
}
case _ => invalidStack
}
Expand Down Expand Up @@ -362,7 +362,8 @@ object StandardVocabulary extends Vocabulary {
val init = context.copy(stack = stack)
val res = vs.foldLeft(List.empty[Any] -> init) {
case ((rs, c), v) =>
val rc = c.interpreter.execute(f, c.copy(stack = v :: c.stack), unfreeze = false)
val rc =
c.interpreter.executeProgram(f, c.copy(stack = v :: c.stack), unfreeze = false)
(rc.stack.head :: rs) -> rc.copy(stack = rc.stack.tail)
}
res._2.copy(stack = res._1.reverse :: res._2.stack)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,82 +40,82 @@ class InterpreterSuite extends FunSuite {
}

test("empty") {
assertEquals(interpreter.execute(Nil), context(Nil))
assertEquals(interpreter.executeProgram(Nil), context(Nil))
}

test("push items") {
assertEquals(interpreter.execute(List("foo", "bar")), context(List("bar", "foo")))
assertEquals(interpreter.executeProgram(List("foo", "bar")), context(List("bar", "foo")))
}

test("execute word") {
assertEquals(interpreter.execute(List(":push-foo")), context(List("foo")))
assertEquals(interpreter.executeProgram(List(":push-foo")), context(List("foo")))
}

test("overloaded word") {
assertEquals(interpreter.execute(List(":overloaded")), context(List("one")))
assertEquals(interpreter.executeProgram(List(":overloaded")), context(List("one")))
}

test("overloaded word and some don't match") {
assertEquals(interpreter.execute(List(":overloaded2")), context(List("two")))
assertEquals(interpreter.executeProgram(List(":overloaded2")), context(List("two")))
}

test("word with no matches") {
val e = intercept[IllegalStateException] {
interpreter.execute(List(":no-match"))
interpreter.executeProgram(List(":no-match"))
}
val expected = "no matches for word ':no-match' with stack [], candidates: [exception]"
assertEquals(e.getMessage, expected)
}

test("using unstable word fails by default") {
val e = intercept[IllegalStateException] {
interpreter.execute(List(":unstable"))
interpreter.executeProgram(List(":unstable"))
}
val expected = "to use :unstable enable unstable features"
assertEquals(e.getMessage, expected)
}

test("unknown word") {
val e = intercept[IllegalStateException] {
interpreter.execute(List("foo", ":unknown"))
interpreter.executeProgram(List("foo", ":unknown"))
}
assertEquals(e.getMessage, "unknown word ':unknown'")
}

test("unmatched closing paren") {
val e = intercept[IllegalStateException] {
interpreter.execute(List(")"))
interpreter.executeProgram(List(")"))
}
assertEquals(e.getMessage, "unmatched closing parenthesis")
}

test("unmatched closing paren 2") {
val e = intercept[IllegalStateException] {
interpreter.execute(List("(", ")", ")"))
interpreter.executeProgram(List("(", ")", ")"))
}
assertEquals(e.getMessage, "unmatched closing parenthesis")
}

test("unmatched opening paren") {
val e = intercept[IllegalStateException] {
interpreter.execute(List("("))
interpreter.executeProgram(List("("))
}
assertEquals(e.getMessage, "unmatched opening parenthesis")
}

test("list") {
val list = List("(", "1", ")")
assertEquals(interpreter.execute(list), context(List(List("1"))))
assertEquals(interpreter.executeProgram(list), context(List(List("1"))))
}

test("nested list") {
val list = List("(", "1", "(", ")", ")")
assertEquals(interpreter.execute(list), context(List(List("1", "(", ")"))))
assertEquals(interpreter.executeProgram(list), context(List(List("1", "(", ")"))))
}

test("multiple lists") {
val list = List("(", "1", ")", "(", "2", ")")
assertEquals(interpreter.execute(list), context(List(List("2"), List("1"))))
assertEquals(interpreter.executeProgram(list), context(List(List("2"), List("1"))))
}

test("debug") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ class ExprApi extends WebApi {
// macros it alwasy returns true. This ensures the operation will actually be successful before
// returning to a user.
private def execWorks(interpreter: Interpreter, w: Word, ctxt: Context): Boolean = {
Try(interpreter.execute(List(s":${w.name}"), ctxt)).isSuccess
Try(interpreter.executeProgram(List(s":${w.name}"), ctxt)).isSuccess
}

private def matches(interpreter: Interpreter, w: Word, ctxt: Context): Boolean = {
Expand Down

0 comments on commit 3144d87

Please sign in to comment.