Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
concat (".") and repeat ("x") operators for strings
  • Loading branch information
prakashk committed Mar 11, 2013
2 parents db20661 + f7d363a commit 5207a2b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/org/moe/parser/Expressions.scala
Expand Up @@ -25,11 +25,11 @@ trait Expressions extends Literals with JavaTokenParsers with PackratParsers {
case left ~ op ~ right => BinaryOpNode(left, op, right)
} | addOp

lazy val addOp: PackratParser[AST] = addOp ~ "[-+]".r ~ mulOp ^^ {
lazy val addOp: PackratParser[AST] = addOp ~ "[-+.]".r ~ mulOp ^^ {
case left ~ op ~ right => BinaryOpNode(left, op, right)
} | mulOp

lazy val mulOp: PackratParser[AST] = mulOp ~ "[*/%]".r ~ expOp ^^ {
lazy val mulOp: PackratParser[AST] = mulOp ~ "[*/%x]".r ~ expOp ^^ {
case left ~ op ~ right => BinaryOpNode(left, op, right)
} | expOp

Expand Down
37 changes: 30 additions & 7 deletions src/main/scala/org/moe/runtime/builtins/StrClass.scala
Expand Up @@ -23,9 +23,9 @@ object StrClass {
strClass.addMethod(
new MoeMethod(
"prefix:<++>",
new MoeSignature(),
env,
{ (e) =>
new MoeSignature(),
env,
{ (e) =>
val inv = e.getCurrentInvocant.get.asInstanceOf[MoeStrObject]
inv.increment(r)
inv
Expand All @@ -36,9 +36,9 @@ object StrClass {
strClass.addMethod(
new MoeMethod(
"postfix:<++>",
new MoeSignature(),
env,
{ (e) =>
new MoeSignature(),
env,
{ (e) =>
val inv = e.getCurrentInvocant.get.asInstanceOf[MoeStrObject]
val old = getStr(inv.unboxToString.get)
inv.increment(r)
Expand Down Expand Up @@ -147,9 +147,32 @@ object StrClass {
)
)

// concatenation

strClass.addMethod(
new MoeMethod(
"infix:<.>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
(e) => e.getCurrentInvocant.get.asInstanceOf[MoeStrObject].concat(r, e.get("$other").get)
)
)

// repetition

strClass.addMethod(
new MoeMethod(
"infix:<x>",
new MoeSignature(List(new MoeParameter("$other"))),
env,
(e) => e.getCurrentInvocant.get.asInstanceOf[MoeStrObject].repeat(r, e.get("$other").get)
)
)

/**
* List of Operators to support:
* - infix:<.>
* - infix:<.>
* - infix:<x>
*
* List of Methods to support:
* - index ($substring, ?$position)
Expand Down
12 changes: 9 additions & 3 deletions src/main/scala/org/moe/runtime/nativeobjects/MoeStrObject.scala
Expand Up @@ -46,10 +46,10 @@ class MoeStrObject(
)

def concat (r: MoeRuntime, x: MoeObject): MoeStrObject = x match {
case s: MoeStrObject => r.NativeObjects.getStr( getNativeValue + s.unboxToString.get )
case a: MoeArrayObject => r.NativeObjects.getStr(
getNativeValue + a.unboxToArrayBuffer.get.map(_.unboxToString.get).mkString
)
case s: MoeObject => r.NativeObjects.getStr( getNativeValue + s.unboxToString.get )
}

def index (r: MoeRuntime): Unit = {} //(r: MoeRuntime): Unit = {} // ($substring, ?$position)
Expand All @@ -58,16 +58,22 @@ class MoeStrObject(
def substr (r: MoeRuntime): Unit = {} // ($offset, ?$length)
def quotemeta (r: MoeRuntime): Unit = {}

def repeat (r: MoeRuntime, other: MoeObject): MoeStrObject = {
val str = getNativeValue
val n = other.unboxToInt.get
r.NativeObjects.getStr(List.fill(n)(str).mkString)
}

// MoeObject overrides

override def isFalse: Boolean = getNativeValue match {
case "" | "0" => true
case _ => false
}
override def toString = "\"" + getNativeValue + "\""

// unboxing

override def unboxToString: Try[String] = Success(getNativeValue)
override def unboxToInt: Try[Int] = Try(getNativeValue.toInt)
override def unboxToDouble: Try[Double] = Try(getNativeValue.toDouble)
Expand Down
44 changes: 44 additions & 0 deletions src/test/scala/org/moe/parser/SimpleExpressionStrTestSuite.scala
@@ -0,0 +1,44 @@
package org.moe.parser

import org.scalatest.FunSuite
import org.scalatest.BeforeAndAfter
import org.scalatest.matchers.ShouldMatchers

import org.moe.runtime._
import org.moe.interpreter._
import org.moe.ast._
import org.moe.parser._

class SimpleExpressionStrTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils with ShouldMatchers {

test("... literal string concatenation ... [\"Hello \" . \"Moe\"]") {
val result = interpretCode(""""Hello " . "Moe"""")
result.unboxToString.get should equal ("Hello Moe")
}

test("... literal string concatenation ... ['foo' . 'bar']") {
val result = interpretCode("'foo' . 'bar'")
result.unboxToString.get should equal ("foobar")
}

test("... literal string concatenation ... ['1' . 2]") {
val result = interpretCode("'1' . 2")
result.unboxToString.get should equal ("12")
}

test("... literal string concatenation ... ['1' . 2 * 3]") {
val result = interpretCode("'1' . 2 * 3")
result.unboxToString.get should equal ("16")
}

test("""... literal string repetition ... ["Moe" x 5]""") {
val result = interpretCode(""""Moe" x 5""")
result.unboxToString.get should equal ("MoeMoeMoeMoeMoe")
}

test("""... literal string repetition ... ["Moe" x "5"]""") {
val result = interpretCode(""""Moe" x "5"""")
result.unboxToString.get should equal ("MoeMoeMoeMoeMoe")
}

}

0 comments on commit 5207a2b

Please sign in to comment.