Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
adding the runtime methods into the MoeHashObject
  • Loading branch information
Stevan Little committed Feb 22, 2013
1 parent 54ce606 commit ce2bf40
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 30 deletions.
39 changes: 9 additions & 30 deletions src/main/scala/org/moe/runtime/builtins/HashClass.scala
@@ -1,6 +1,7 @@
package org.moe.runtime.builtins

import org.moe.runtime._
import org.moe.runtime.nativeobjects._

/**
* setup class Hash
Expand Down Expand Up @@ -29,9 +30,9 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"postcircumfix:<{}>",
{ (invocant, args) =>
{ (self, args) =>
val key = args(0).unboxToString.get
val hash = invocant.unboxToMap.get
val hash = self.unboxToMap.get
hash.get(key).getOrElse(r.NativeObjects.getUndef)
}
)
Expand All @@ -40,46 +41,24 @@ object HashClass {
hashClass.addMethod(
new MoeMethod(
"at_key", // ($key)
{ (invocant, args) =>
val key = args(0).unboxToString.get
val hash = invocant.unboxToMap.get
hash.get(key).getOrElse(r.NativeObjects.getUndef)
}
(self, args) => self.asInstanceOf[MoeHashObject].at_key(args(0).asInstanceOf[MoeStrObject])
)
)

hashClass.addMethod(
new MoeMethod(
"bind_key", // ($key, $value)
{ (invocant, args) =>
val key = args(0).unboxToString.get
val value = args(1)
val hash = invocant.unboxToMap.get
hash.put(key, value)
value
}
(self, args) => self.asInstanceOf[MoeHashObject].bind_key(args(0).asInstanceOf[MoeStrObject], args(1))
)
)

hashClass.addMethod(new MoeMethod("keys", { (invocant, _) =>
getArray(invocant.unboxToMap.get.keys.map(getString(_)).toList)
}))
hashClass.addMethod(new MoeMethod("keys", (self, _) => self.asInstanceOf[MoeHashObject].keys))

hashClass.addMethod(new MoeMethod("values",{ (invocant, _) =>
getArray(invocant.unboxToMap.get.values.map(x => x).toList)
}))
hashClass.addMethod(new MoeMethod("values", (self, _) => self.asInstanceOf[MoeHashObject].values))

hashClass.addMethod(new MoeMethod("kv",{ (invocant, _) =>
getArray(invocant.unboxToMap.get.toList.map(
p => getArray(List(getString(p._1), p._2))
))
}))
hashClass.addMethod(new MoeMethod("kv", (self, _) => self.asInstanceOf[MoeHashObject].kv))

hashClass.addMethod(new MoeMethod("pairs",{ (invocant, _) =>
getArray(invocant.unboxToMap.get.toList.map(
p => getPair(getString(p._1) -> p._2)
))
}))
hashClass.addMethod(new MoeMethod("pairs", (self, _) => self.asInstanceOf[MoeHashObject].pairs))

/**
* List of Methods to support:
Expand Down
26 changes: 26 additions & 0 deletions src/main/scala/org/moe/runtime/nativeobjects/MoeHashObject.scala
@@ -1,6 +1,7 @@
package org.moe.runtime.nativeobjects

import org.moe.runtime._
import org.moe.runtime.nativeobjects._

import scala.collection.mutable.HashMap
import scala.util.{Try, Success, Failure}
Expand All @@ -10,6 +11,31 @@ class MoeHashObject(
klass : Option[MoeClass] = None
) extends MoeNativeObject[HashMap[String, MoeObject]](v, klass) {

private def hash = getNativeValue

// Runtime methods

def at_key(k: MoeStrObject): MoeObject = {
hash.get(k.unboxToString.get).getOrElse(new MoeUndefObject())
}

def bind_key(k: MoeStrObject, v: MoeObject): MoeObject = {
hash.put(k.unboxToString.get, v)
v
}

def keys: MoeObject = new MoeArrayObject(hash.keys.map(s => new MoeStrObject(s)).toList)

def values: MoeObject = new MoeArrayObject(hash.values.map(x => x).toList)

def kv: MoeObject = new MoeArrayObject(
hash.toList.map(
p => new MoeArrayObject(List(new MoeStrObject(p._1), p._2))
)
)

def pairs: MoeObject = new MoeArrayObject(hash.toList.map(p => new MoePairObject(p)))

// MoeObject overrides

override def isFalse: Boolean = getNativeValue.size == 0
Expand Down
99 changes: 99 additions & 0 deletions src/test/scala/org/moe/interpreter/HashLiteralNodeTestSuite.scala
Expand Up @@ -69,4 +69,103 @@ class HashLiteralNodeTestSuite extends FunSuite with InterpreterTestUtils {
val result = interpreter.eval(runtime, runtime.getRootEnv, ast)
assert(result.unboxToInt.get === 10)
}

test("... basic test with calling at_key method on hash") {
val ast = wrapSimpleAST(
List(
VariableDeclarationNode(
"%hash",
HashLiteralNode(
List(
PairLiteralNode(StringLiteralNode("foo"), IntLiteralNode(10)),
PairLiteralNode(StringLiteralNode("bar"), IntLiteralNode(20))
)
)
),
MethodCallNode(
VariableAccessNode("%hash"),
"at_key",
List(StringLiteralNode("foo"))
)
)
)
val result = interpreter.eval(runtime, runtime.getRootEnv, ast)
assert(result.unboxToInt.get === 10)
}

test("... basic test with calling at_key method on hash (with miss)") {
val ast = wrapSimpleAST(
List(
VariableDeclarationNode(
"%hash",
HashLiteralNode(
List(
PairLiteralNode(StringLiteralNode("foo"), IntLiteralNode(10)),
PairLiteralNode(StringLiteralNode("bar"), IntLiteralNode(20))
)
)
),
MethodCallNode(
VariableAccessNode("%hash"),
"at_key",
List(StringLiteralNode("baz"))
)
)
)
val result = interpreter.eval(runtime, runtime.getRootEnv, ast)
assert(result.isUndef)
}

test("... basic test with calling bind_key method on hash") {
val ast = wrapSimpleAST(
List(
VariableDeclarationNode(
"%hash",
HashLiteralNode(
List(
PairLiteralNode(StringLiteralNode("foo"), IntLiteralNode(10)),
PairLiteralNode(StringLiteralNode("bar"), IntLiteralNode(20))
)
)
),
MethodCallNode(
VariableAccessNode("%hash"),
"bind_key",
List(StringLiteralNode("bar"), IntLiteralNode(30))
),
HashElementAccessNode(
"%hash",
StringLiteralNode("bar")
)
)
)
val result = interpreter.eval(runtime, runtime.getRootEnv, ast)
assert(result.unboxToInt.get === 30)
}

test("... basic test with calling keys method on hash") {
val ast = wrapSimpleAST(
List(
VariableDeclarationNode(
"%hash",
HashLiteralNode(
List(
PairLiteralNode(StringLiteralNode("foo"), IntLiteralNode(10)),
PairLiteralNode(StringLiteralNode("bar"), IntLiteralNode(20))
)
)
),
MethodCallNode(
VariableAccessNode("%hash"),
"keys",
List()
)
)
)
val result = interpreter.eval(runtime, runtime.getRootEnv, ast)
val keys = result.unboxToList.get
assert(keys(0).unboxToString.get === "foo")
assert(keys(1).unboxToString.get === "bar")
}

}

0 comments on commit ce2bf40

Please sign in to comment.