Skip to content

Commit

Permalink
add in named params (also rename MoeNamedParameter to MoePositionalPa…
Browse files Browse the repository at this point in the history
…rameter cause that is a better name) then add the support for named parameters to the parser and the runtime (and add some tests too)
  • Loading branch information
Stevan Little committed Mar 30, 2013
1 parent 37412d0 commit 60bf7dd
Show file tree
Hide file tree
Showing 22 changed files with 188 additions and 93 deletions.
7 changes: 6 additions & 1 deletion src/main/scala/org/moe/ast/AST.scala
Expand Up @@ -60,7 +60,12 @@ case class TernaryOpNode(cond: AST, trueExpr: AST, falseExpr: AST) extends AST

// value lookup, assignment and declaration

case class ParameterNode(name: String, optional: Boolean = false, slurpy: Boolean = false) extends AST
case class ParameterNode(
name : String,
optional : Boolean = false,
slurpy : Boolean = false,
named : Boolean = false
) extends AST

case class SignatureNode(params: List[ParameterNode]) extends AST

Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/org/moe/ast/Serializer.scala
Expand Up @@ -124,11 +124,12 @@ object Serializer {
)
)

case ParameterNode(name, optional, slurpy) => JSONObject(
case ParameterNode(name, optional, slurpy, named) => JSONObject(
Map(
"name" -> name,
"optional" -> optional.toString,
"slurpy" -> slurpy.toString
"slurpy" -> slurpy.toString,
"named" -> named.toString
)
)
case SignatureNode(params) => JSONArray(params.map(toJSON(_)))
Expand Down
11 changes: 6 additions & 5 deletions src/main/scala/org/moe/interpreter/Interpreter.scala
Expand Up @@ -260,11 +260,12 @@ class Interpreter {
}
}

case ParameterNode(name, optional, slurpy) => (optional, slurpy) match {
case (false, false) => new MoeNamedParameter(name)
case (true, false) => new MoeOptionalParameter(name)
case (false, true) => new MoeSlurpyParameter(name)
case (true, true) => throw new MoeErrors.InvalidParameter("parameter cannot be slurpy and optional")
case 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 _ => throw new MoeErrors.InvalidParameter("parameter must be one of slurpy, optional or named")
}

case SignatureNode(params) => new MoeSignature(
Expand Down
9 changes: 5 additions & 4 deletions src/main/scala/org/moe/parser/Statements.scala
Expand Up @@ -27,10 +27,11 @@ trait Statements extends Expressions {
def doBlock: Parser[StatementsNode] = "do".r ~> block
def scopeBlock: Parser[ScopeNode] = block ^^ { ScopeNode(_) }

def parameter = "*".? ~ sigil ~ namespacedIdentifier ~ "?".? ^^ {
case None ~ a ~ b ~ None => ParameterNode(a + b)
case Some(_) ~ a ~ b ~ None => ParameterNode(a + b, slurpy = true)
case None ~ a ~ b ~ Some(_) => ParameterNode(a + b, optional = true)
def parameter = ("[*:]".r).? ~ sigil ~ namespacedIdentifier ~ "?".? ^^ {
case None ~ a ~ b ~ None => ParameterNode(a + b)
case Some("*") ~ a ~ b ~ None => ParameterNode(a + b, slurpy = true)
case None ~ a ~ b ~ Some(_) => ParameterNode(a + b, optional = true)
case Some(":") ~ a ~ b ~ None => ParameterNode(a + b, named = true)
}

def subroutineDecl: Parser[SubroutineDeclarationNode] = ("sub" ~> namespacedIdentifier ~ ("(" ~> repsep(parameter, ",") <~ ")").?) ~ block ^^ {
Expand Down
10 changes: 6 additions & 4 deletions src/main/scala/org/moe/runtime/MoeParameter.scala
@@ -1,9 +1,11 @@
package org.moe.runtime

sealed abstract class MoeParameter(private val name: String) extends MoeObject {
def getName = name
def getName = name
def getKeyName = name.drop(1)
}

case class MoeNamedParameter (val n: String) extends MoeParameter(n)
case class MoeOptionalParameter (val n: String) extends MoeParameter(n)
case class MoeSlurpyParameter (val n: String) extends MoeParameter(n)
case class MoePositionalParameter (val n: String) extends MoeParameter(n)
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)
45 changes: 39 additions & 6 deletions src/main/scala/org/moe/runtime/MoeSignature.scala
@@ -1,25 +1,58 @@
package org.moe.runtime

import scala.collection.mutable.{HashMap,Map}

import org.moe.runtime.nativeobjects.MoePairObject

class MoeSignature(
private val params: List[MoeParameter] = List()
) extends MoeObject {

lazy val arity = params.length
lazy val namedParameterMap: Map[String,MoeParameter] = Map(
params.filter(_ match {
case (x: MoeNamedParameter) => true
case _ => false
}).map(
p => p.getKeyName -> p
):_*
)

def getParams = params
def getArity = params.length

def bindArgsToEnv (args: MoeArguments, env: MoeEnvironment) = {
for (i <- 0.until(getArity)) {

val r = env.getCurrentRuntime.get

var extra: List[MoeObject] = List()

for (i <- 0.until(arity)) {
params(i) match {
case MoeNamedParameter(name) => env.create(name, args.getArgAt(i).get)
case MoePositionalParameter(name) => env.create(name, args.getArgAt(i).get)
case MoeOptionalParameter(name) => args.getArgAt(i) match {
case Some(a) => env.create(name, a)
case None => env.create(name, env.getCurrentRuntime.get.NativeObjects.getUndef)
case None => env.create(name, r.NativeObjects.getUndef)
}
case MoeSlurpyParameter(name) => env.create(
case MoeSlurpyParameter(name) => env.create(
name,
env.getCurrentRuntime.get.NativeObjects.getArray(args.slurpArgsAt(i):_*)
r.NativeObjects.getArray(args.slurpArgsAt(i):_*)
)
case _ => extra = args.getArgAt(i).get :: extra
}
}

for (arg <- extra) {
arg match {
case (a: MoePairObject) => {
val k = a.key(r).unboxToString.get
val p = namedParameterMap.get(k).getOrElse(
throw new MoeErrors.MoeProblems("Could not find matching key for " + k)
)
env.create(p.getName, a.value(r))
}
case _ => throw new MoeErrors.MoeProblems("extra argument was not a pair")
}
}

}
}
4 changes: 2 additions & 2 deletions src/main/scala/org/moe/runtime/builtins/AnyClass.scala
Expand Up @@ -72,7 +72,7 @@ object AnyClass {
anyClass.addMethod(
new MoeMethod(
"infix:<&&>",
new MoeSignature(List(new MoeNamedParameter("$other"))),
new MoeSignature(List(new MoePositionalParameter("$other"))),
env,
{ (e) =>
val inv = self(e)
Expand All @@ -90,7 +90,7 @@ object AnyClass {
anyClass.addMethod(
new MoeMethod(
"infix:<||>",
new MoeSignature(List(new MoeNamedParameter("$other"))),
new MoeSignature(List(new MoePositionalParameter("$other"))),
env,
{ (e) =>
val inv = self(e)
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/org/moe/runtime/builtins/ArrayClass.scala
Expand Up @@ -35,7 +35,7 @@ object ArrayClass {
arrayClass.addMethod(
new MoeMethod(
"postcircumfix:<[]>",
new MoeSignature(List(new MoeNamedParameter("$i"))),
new MoeSignature(List(new MoePositionalParameter("$i"))),
env,
{ (e) =>
var index = e.get("$i").get.unboxToInt.get
Expand All @@ -54,7 +54,7 @@ object ArrayClass {
arrayClass.addMethod(
new MoeMethod(
"at_pos",
new MoeSignature(List(new MoeNamedParameter("$i"))),
new MoeSignature(List(new MoePositionalParameter("$i"))),
env,
(e) => self(e).at_pos(r, e.getAs[MoeIntObject]("$i").get)
)
Expand All @@ -63,7 +63,7 @@ object ArrayClass {
arrayClass.addMethod(
new MoeMethod(
"bind_pos",
new MoeSignature(List(new MoeNamedParameter("$i"), new MoeNamedParameter("$v"))),
new MoeSignature(List(new MoePositionalParameter("$i"), new MoePositionalParameter("$v"))),
env,
(e) => self(e).bind_pos(
r,
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/org/moe/runtime/builtins/BoolClass.scala
Expand Up @@ -38,7 +38,7 @@ object BoolClass {
boolClass.addMethod(
new MoeMethod(
"infix:<?:>",
new MoeSignature(List(new MoeNamedParameter("$trueExpr"), new MoeNamedParameter("$falseExpr"))),
new MoeSignature(List(new MoePositionalParameter("$trueExpr"), new MoePositionalParameter("$falseExpr"))),
env,
{ (e) =>
val inv = self(e)
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/org/moe/runtime/builtins/HashClass.scala
Expand Up @@ -31,7 +31,7 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"postcircumfix:<{}>",
new MoeSignature(List(new MoeNamedParameter("$key"))),
new MoeSignature(List(new MoePositionalParameter("$key"))),
env,
{ (e) =>
val hash = self(e)
Expand All @@ -43,7 +43,7 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"at_key",
new MoeSignature(List(new MoeNamedParameter("$key"))),
new MoeSignature(List(new MoePositionalParameter("$key"))),
env,
(e) => self(e).at_key(r, e.getAs[MoeStrObject]("$key").get)
)
Expand All @@ -52,7 +52,7 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"bind_key",
new MoeSignature(List(new MoeNamedParameter("$key"), new MoeNamedParameter("$value"))),
new MoeSignature(List(new MoePositionalParameter("$key"), new MoePositionalParameter("$value"))),
env,
(e) => self(e).bind_key(r, e.getAs[MoeStrObject]("$key").get, e.get("$value").get)
)
Expand All @@ -61,7 +61,7 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"exists",
new MoeSignature(List(new MoeNamedParameter("$key"))),
new MoeSignature(List(new MoePositionalParameter("$key"))),
env,
(e) => self(e).exists(r, e.getAs[MoeStrObject]("$key").get)
)
Expand Down

0 comments on commit 60bf7dd

Please sign in to comment.