Skip to content

Commit

Permalink
Rudimentary support for string ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
prakashk committed Feb 13, 2013
1 parent ee66b6b commit c9fa8f4
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
34 changes: 29 additions & 5 deletions src/main/scala/org/moe/interpreter/Interpreter.scala
Expand Up @@ -137,11 +137,35 @@ object Interpreter {
}

case RangeLiteralNode(start, end) => {
val range_start = Utils.objToInteger(eval(runtime, env, start))
val range_end = Utils.objToInteger(eval(runtime, env, end))
val range: Range = new Range(range_start, range_end + 1, 1)
val array: List[MoeObject] = range.toList.map(runtime.NativeObjects.getInt(_))
runtime.NativeObjects.getArray(array)
val s = eval(runtime, env, start)
val e = eval(runtime, env, end)
(s, e) match {
case (s: MoeIntObject, e: MoeIntObject) => {
val range_start = Utils.objToInteger(s)
val range_end = Utils.objToInteger(e)
val range: Range = new Range(range_start, range_end + 1, 1)
val array: List[MoeObject] = range.toList.map(runtime.NativeObjects.getInt(_))
runtime.NativeObjects.getArray(array)
}
case (s: MoeStringObject, e: MoeStringObject) => {
val range_start = Utils.objToString(s)
val range_end = Utils.objToString(e)

// return the successor of the string ("abc" => "abd")
def succ(str: String) = str.init + (str.last.toInt + 1).toChar

// this is totally non-functional, imperative style code,
// not in Scala spirit; but will do, for now
var elems: List[String] = List()
var str = range_start
while (str <= range_end) {
elems = elems :+ str
str = succ(str)
}
runtime.NativeObjects.getArray(elems.map(runtime.NativeObjects.getString(_)))
}
case _ => throw new MoeErrors.UnexpectedType("Pair of MoeIntObject or MoeStringObject expected")
}
}

// unary operators
Expand Down
Expand Up @@ -7,7 +7,7 @@ import org.scalatest.FunSuite

class RangeLiteralNodeTestSuite extends FunSuite with InterpreterTestUtils {

test("... basic test with Range") {
test("... basic test with Integer Range") {
val ast = wrapSimpleAST(
List(
RangeLiteralNode(
Expand All @@ -26,4 +26,23 @@ class RangeLiteralNodeTestSuite extends FunSuite with InterpreterTestUtils {
assert(array(2).asInstanceOf[MoeIntObject].getNativeValue === 3)
}

test("... basic test with String Range") {
val ast = wrapSimpleAST(
List(
RangeLiteralNode(
StringLiteralNode("a"),
StringLiteralNode("c")
)
)
)
val result = Interpreter.eval(runtime, runtime.getRootEnv, ast)

val array: List[MoeObject] = result.asInstanceOf[MoeArrayObject].getNativeValue

assert(array.size === 3)
assert(array(0).asInstanceOf[MoeStringObject].getNativeValue === "a")
assert(array(1).asInstanceOf[MoeStringObject].getNativeValue === "b")
assert(array(2).asInstanceOf[MoeStringObject].getNativeValue === "c")
}

}
13 changes: 12 additions & 1 deletion src/test/scala/org/moe/parser/RangeLiteralTestSuite.scala
Expand Up @@ -10,7 +10,7 @@ import org.moe.parser._

class RangeLiteralTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils {

test("... basic test with a simple range") {
test("... basic test with a simple integer range") {
val result = interpretCode("1 .. 3")

val array: List[MoeObject] = result.asInstanceOf[MoeArrayObject].getNativeValue
Expand All @@ -21,4 +21,15 @@ class RangeLiteralTestSuite extends FunSuite with BeforeAndAfter with ParserTest
assert(array(2).asInstanceOf[MoeIntObject].getNativeValue === 3)
}

test("... basic test with a simple string range") {
val result = interpretCode(""" "a" .. "c" """)

val array: List[MoeObject] = result.asInstanceOf[MoeArrayObject].getNativeValue

assert(array.size === 3)
assert(array(0).asInstanceOf[MoeStringObject].getNativeValue === "a")
assert(array(1).asInstanceOf[MoeStringObject].getNativeValue === "b")
assert(array(2).asInstanceOf[MoeStringObject].getNativeValue === "c")
}

}

0 comments on commit c9fa8f4

Please sign in to comment.