Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
attempt at implementing default-value parameters
  • Loading branch information
prakashk committed May 8, 2013
1 parent 702a489 commit 1c2ec00
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 18 deletions.
7 changes: 4 additions & 3 deletions src/main/scala/org/moe/ast/AST.scala
Expand Up @@ -56,9 +56,10 @@ case class TernaryOpNode(cond: AST, trueExpr: AST, falseExpr: AST) extends AST

case class ParameterNode(
name : String,
optional : Boolean = false,
slurpy : Boolean = false,
named : Boolean = false
optional : Boolean = false,
slurpy : Boolean = false,
named : Boolean = false,
default : Option[AST] = None
) extends AST

case class SignatureNode(params: List[ParameterNode]) extends AST
Expand Down
11 changes: 10 additions & 1 deletion src/main/scala/org/moe/ast/Serializer.scala
Expand Up @@ -140,7 +140,16 @@ object Serializer {
)
)

case ParameterNode(name, optional, slurpy, named) => JSONObject(
case ParameterNode(name, optional, slurpy, named, Some(default)) => JSONObject(
Map(
"name" -> name,
"optional" -> optional.toString,
"slurpy" -> slurpy.toString,
"named" -> named.toString,
"default" -> toJSON(default)
)
)
case ParameterNode(name, optional, slurpy, named, None) => JSONObject(
Map(
"name" -> name,
"optional" -> optional.toString,
Expand Down
17 changes: 9 additions & 8 deletions src/main/scala/org/moe/interpreter/guts/Signatures.scala
Expand Up @@ -7,17 +7,18 @@ import org.moe.ast._
object Signatures {

def declaration (i: MoeInterpreter, r: MoeRuntime): PartialFunction[(MoeEnvironment, AST), MoeObject] = {
case (env, ParameterNode(name, optional, slurpy, named)) => (optional, slurpy, named) match {
case (false, false, false) => new MoePositionalParameter(name)
case (true, false, false) => new MoeOptionalParameter(name)
case (false, true, false) => new MoeSlurpyParameter(name)
case (false, false, true) => new MoeNamedParameter(name)
case (false, true, true) => new MoeSlurpyNamedParameter(name)
case _ => throw new MoeErrors.InvalidParameter("parameter must be one of slurpy, optional or named")
case (env, ParameterNode(name, optional, slurpy, named, default)) => (optional, slurpy, named, default) match {
case (false, false, false, None) => new MoePositionalParameter(name)
case (true, false, false, None) => new MoeOptionalParameter(name)
case (false, true, false, None) => new MoeSlurpyParameter(name)
case (false, false, true, None) => new MoeNamedParameter(name)
case (false, true, true, None) => new MoeSlurpyNamedParameter(name)
case (false, false, false, Some(def_val)) => new MoeDefaultValueParameter(name, i.evaluate(env, def_val))
case _ => throw new MoeErrors.InvalidParameter("parameter must be one of slurpy, optional, named or default-value")
}

case (env, SignatureNode(params)) => new MoeSignature(
params.map(i.compile(env, _).asInstanceOf[MoeParameter])
)
}
}
}
11 changes: 6 additions & 5 deletions src/main/scala/org/moe/parser/MoeProductions.scala
Expand Up @@ -310,17 +310,18 @@ trait MoeProductions extends MoeLiterals with JavaTokenParsers with PackratParse

// Parameters

def parameter = ("[*:]".r).? ~ parameterName ~ "?".? ^^ {
case None ~ a ~ None => ParameterNode(a)
case None ~ a ~ Some("?") => ParameterNode(a, optional = true)
case Some(":") ~ a ~ None => ParameterNode(a, named = true)
case Some("*") ~ a ~ None => {
def parameter = ("[*:]".r).? ~ parameterName ~ "?".? ~ opt("=" ~> expression) ^^ {
case None ~ a ~ None ~ None => ParameterNode(a)
case None ~ a ~ Some("?") ~ None => ParameterNode(a, optional = true)
case Some(":") ~ a ~ None ~ None => ParameterNode(a, named = true)
case Some("*") ~ a ~ None ~ None => {
a.take(1) match {
case "@" => ParameterNode(a, slurpy = true)
case "%" => ParameterNode(a, slurpy = true, named = true)
case _ => throw new Exception("slurpy parameters must be either arrays or hashes")
}
}
case None ~ a ~ None ~ defVal => ParameterNode(a, default = defVal)
}

// Code literals
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/org/moe/runtime/MoeParameter.scala
Expand Up @@ -10,6 +10,7 @@ case class MoeOptionalParameter (val n: String) extends MoeParameter(n)
case class MoeSlurpyParameter (val n: String) extends MoeParameter(n)
case class MoeNamedParameter (val n: String) extends MoeParameter(n)
case class MoeSlurpyNamedParameter (val n: String) extends MoeParameter(n)
case class MoeDefaultValueParameter(val n: String, val default: MoeObject) extends MoeParameter(n)

/**
Expand All @@ -32,4 +33,4 @@ package Moe::Runtime {
class MoeSlurpyNamedParameter with MoeParameter {}
}
**/
**/
9 changes: 9 additions & 0 deletions src/main/scala/org/moe/runtime/MoeSignature.scala
Expand Up @@ -60,6 +60,15 @@ class MoeSignature(
name,
r.NativeObjects.getHash(args.slurpArgsAt(i).map(_.unboxToTuple.get):_*)
)
case MoeDefaultValueParameter(name, value) => args.getArgAt(i) match {
case Some(a) => {
checkType(name, a)
env.create(name, a)
}
case None => {
env.create(name, value)
}
}
case _ => extra = args.getArgAt(i).get :: extra
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/test/scala/org/moe/parser/SubroutineTestSuite.scala
Expand Up @@ -93,6 +93,31 @@ class SubroutineTestSuite extends FunSuite with BeforeAndAfter with ParserTestUt
result.toString should equal ("[5, 10, 20]")
}

test("... a basic subroutine w/ default-value params") {
val result = interpretCode("sub foo ($x, $y = 2) { $x + $y } foo(5)")
result.unboxToInt.get should equal (7)
}

test("... a basic subroutine w/ default-value params (take 2)") {
val result = interpretCode("sub foo ($x = 1, $y = 2) { $x + $y } foo(5)")
result.unboxToInt.get should equal (7)
}

test("... a basic subroutine w/ default-value params (take 3)") {
val result = interpretCode("sub foo ($x = 1, $y = 2) { $x + $y } foo(5, 5)")
result.unboxToInt.get should equal (10)
}

test("... a basic subroutine w/ default-value params (take 4)") {
val result = interpretCode("sub foo ($x = 1, $y = 2) { $x + $y } foo()")
result.unboxToInt.get should equal (3)
}

test("... a basic subroutine w/ default-value params (satisified)") {
val result = interpretCode("sub foo ($x, $y = 2) { $x + $y } foo(5, 5)")
result.unboxToInt.get should equal (10)
}

private val sum = """
sub sum (@x, $acc?) {
@x.length == 0
Expand Down

0 comments on commit 1c2ec00

Please sign in to comment.