Skip to content

Commit

Permalink
Merge pull request #103 from MoeOrganization/prakashk/misc-stuff-2
Browse files Browse the repository at this point in the history
Various things (sans the REPL-scope commit)
  • Loading branch information
Stevan Little committed May 6, 2013
2 parents 1f0e138 + 6a06a0c commit 9da56d8
Show file tree
Hide file tree
Showing 21 changed files with 2,490 additions and 43 deletions.
4 changes: 2 additions & 2 deletions lib/Test-More/lib/Test/More.mo
Expand Up @@ -14,7 +14,7 @@ package Test {

class Builder {

has $!output = ^Test::TAP.new;
has $!output = Test::TAP.new;
has $!count = 0;

method plan ($count) { $!output.plan($count) }
Expand Down Expand Up @@ -96,7 +96,7 @@ package Test {

package More {

my $builder = ^Test::Builder.new;
my $builder = Test::Builder.new;

sub plan ($count) is export { $builder.plan($count) }
sub done_testing is export { $builder.done_testing }
Expand Down
28 changes: 14 additions & 14 deletions lib/Tree/t/001-basic.t
@@ -1,26 +1,26 @@

use Tree;

my $t = ^Tree::NAry.new(node => "0.0", children => [
^Tree::NAry.new(node => "1.0", children => [
^Tree::NAry.new(node => "1.1"),
^Tree::NAry.new(node => "1.2", children => [
^Tree::NAry.new(node => "1.2.1"),
^Tree::NAry.new(node => "1.2.2"),
my $t = Tree::NAry.new(node => "0.0", children => [
Tree::NAry.new(node => "1.0", children => [
Tree::NAry.new(node => "1.1"),
Tree::NAry.new(node => "1.2", children => [
Tree::NAry.new(node => "1.2.1"),
Tree::NAry.new(node => "1.2.2"),
])
]),
^Tree::NAry.new(node => "2.0", children => [
^Tree::NAry.new(node => "2.1", children => [
^Tree::NAry.new(node => "2.1.1", children => [
^Tree::NAry.new(node => "2.1.1.1"),
Tree::NAry.new(node => "2.0", children => [
Tree::NAry.new(node => "2.1", children => [
Tree::NAry.new(node => "2.1.1", children => [
Tree::NAry.new(node => "2.1.1.1"),
]),
^Tree::NAry.new(node => "2.1.2", children => [
^Tree::NAry.new(node => "2.1.2.1"),
^Tree::NAry.new(node => "2.1.2.2"),
Tree::NAry.new(node => "2.1.2", children => [
Tree::NAry.new(node => "2.1.2.1"),
Tree::NAry.new(node => "2.1.2.2"),
])
])
]),
^Tree::NAry.new(node => "3.0"),
Tree::NAry.new(node => "3.0"),
]);

$t.traverse(-> ($c) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/org/moe/parser/MoeProductions.scala
Expand Up @@ -219,7 +219,7 @@ trait MoeProductions extends MoeLiterals with JavaTokenParsers with PackratParse

def parameterName = """([$@%&])([a-zA-Z_][a-zA-Z0-9_]*)""".r

def classAccess = "^" ~> namespacedIdentifier ^^ ClassAccessNode
def classAccess = namespacedIdentifier ^^ ClassAccessNode

// declaration

Expand Down
9 changes: 9 additions & 0 deletions src/main/scala/org/moe/runtime/builtins/HashClass.scala
Expand Up @@ -86,6 +86,15 @@ object HashClass {
hashClass.addMethod(new MoeMethod("kv", new MoeSignature(), env, (e) => self(e).kv(r)))
hashClass.addMethod(new MoeMethod("pairs", new MoeSignature(), env, (e) => self(e).pairs(r)))

hashClass.addMethod(
new MoeMethod(
"eqv",
new MoeSignature(List(new MoePositionalParameter("%that"))),
env,
(e) => self(e).equal_to(r, e.getAs[MoeHashObject]("%that").get)
)
)

/**
* List of Methods to support:
* - each ($callback)
Expand Down
Expand Up @@ -114,7 +114,7 @@ class MoeArrayObject(
f.execute(new MoeArguments(List(i))).isFalse
})
f.getDeclarationEnvironment.clearCurrentTopic
result.head
if (result.isEmpty) r.NativeObjects.getUndef else result.head
}

def reduce (r: MoeRuntime, f: MoeCode, init: Option[MoeObject]): MoeObject = init match {
Expand Down
13 changes: 13 additions & 0 deletions src/main/scala/org/moe/runtime/nativeobjects/MoeHashObject.scala
Expand Up @@ -55,6 +55,19 @@ class MoeHashObject(
}).toArray:_*
)

// equality
def equal_to (r: MoeRuntime, that: MoeHashObject): MoeBoolObject = {
val k1 = hash.keys.toList.sortWith(_ < _)
val k2 = that.getNativeValue.keys.toList.sortWith(_ < _)
r.NativeObjects.getBool(
k1.length == k2.length
&&
k1 == k2
&&
((k1.map(k => hash(k)), k1.map(k => that.getNativeValue(k))).zipped.forall( (a, b) => a.equal_to(b) ))
)
}

// MoeNativeObject overrides

override def copy = new MoeHashObject(HashMap(getNativeValue.toSeq:_*), getAssociatedType)
Expand Down
5 changes: 5 additions & 0 deletions src/test/scala/org/moe/parser/ArrayMethodTestSuite.scala
Expand Up @@ -56,6 +56,11 @@ class ArrayMethodTestSuite extends FunSuite with BeforeAndAfter with ParserTestU
result.unboxToString.get should equal ("bar")
}

test("... basic test with array.first -- non-matching case") {
val result = interpretCode("my @a = ['foo', 'bar', 'baz']; @a.first(-> ($_) { $_ eq 'bazz' } )")
result.unboxToString.get should equal ("undef")
}

test("... basic test with array.max") {
val result = interpretCode("my @a = [3, 12, 9]; @a.max")
result.unboxToInt.get should equal (12)
Expand Down
20 changes: 10 additions & 10 deletions src/test/scala/org/moe/parser/ClassTestSuite.scala
Expand Up @@ -42,18 +42,18 @@ class ClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils w
}

test("... a basic class w/ instance creation") {
val result = interpretCode("class Foo {} ^Foo.new")
val result = interpretCode("class Foo {} Foo.new")
result.asInstanceOf[MoeOpaque].isInstanceOf("Foo") should be (true)
result.asInstanceOf[MoeOpaque].getAssociatedClass.get.getName should be ("Foo")
}

test("... a basic class w/ instance creation and method calling") {
val result = interpretCode("class Foo { method bar { 10 } } ^Foo.new.bar")
val result = interpretCode("class Foo { method bar { 10 } } Foo.new.bar")
result.unboxToInt.get should be (10)
}

test("... a basic class w/ instance creation and attribute init and access") {
val result = interpretCode("class Foo { has $!bar = 10; method bar { $!bar } } ^Foo.new.bar")
val result = interpretCode("class Foo { has $!bar = 10; method bar { $!bar } } Foo.new.bar")
result.unboxToInt.get should be (10)
}

Expand All @@ -66,7 +66,7 @@ class ClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils w
"""

test("... test that attribute defaults are cloned properly") {
val result = interpretCode(attrDefault + " my $f1 = ^Foo.new; my $f2 = ^Foo.new; [ $f1.bar, $f1.baz, $f2.bar, $f2.baz ]")
val result = interpretCode(attrDefault + " my $f1 = Foo.new; my $f2 = Foo.new; [ $f1.bar, $f1.baz, $f2.bar, $f2.baz ]")
result.toString should be ("[5, [0, 1, 2, 3, 4], 5, [0, 1, 2, 3, 4]]")
}

Expand All @@ -86,17 +86,17 @@ class ClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils w
"""

test("... a complex class (take 1)") {
val result = interpretCode(pointClass + " my $p = ^Point.new; $p.x")
val result = interpretCode(pointClass + " my $p = Point.new; $p.x")
result.unboxToInt.get should be (0)
}

test("... a complex class (take 2)") {
val result = interpretCode(pointClass + " my $p = ^Point.new; $p.x(10); $p.x")
val result = interpretCode(pointClass + " my $p = Point.new; $p.x(10); $p.x")
result.unboxToInt.get should be (10)
}

test("... a complex class (take 3)") {
val result = interpretCode(pointClass + " my $p = ^Point.new(x => 10, y => 20); $p.x")
val result = interpretCode(pointClass + " my $p = Point.new(x => 10, y => 20); $p.x")
result.unboxToInt.get should be (10)
}

Expand All @@ -110,12 +110,12 @@ class ClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils w
}
"""
test("... a complex class v3 (take 1)") {
val result = interpretCode(greeterClass + " ^Greater.new.greet(\"World\").uc")
val result = interpretCode(greeterClass + " Greater.new.greet(\"World\").uc")
result.unboxToString.get should be ("HELLO WORLD")
}

test("... make sure $?SELF and $?CLASS work") {
val result = interpretCode("class Foo { method bar { [ $?SELF, $?CLASS ] } }; ^Foo.new.bar")
val result = interpretCode("class Foo { method bar { [ $?SELF, $?CLASS ] } }; Foo.new.bar")
val array = result.unboxToArrayBuffer.get
val obj = array(0).asInstanceOf[MoeObject]
val cls = array(1).asInstanceOf[MoeClass]
Expand All @@ -142,7 +142,7 @@ class ClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils w
"""

test("... submethod test") {
val result = interpretCode(submethodTest + "; my $b = ^Bar.new; [ $b.get_foo, $b.get_bar ]")
val result = interpretCode(submethodTest + "; my $b = Bar.new; [ $b.get_foo, $b.get_bar ]")
val array = result.unboxToArrayBuffer.get

assert(array(0).unboxToString.get === "FOO")
Expand Down
14 changes: 7 additions & 7 deletions src/test/scala/org/moe/parser/IOClassTestSuite.scala
Expand Up @@ -19,37 +19,37 @@ class IOClassTestSuite extends FunSuite with BeforeAndAfter with ParserTestUtils
private val badPath = """my $path = "t/000-load.x";"""

test("... basic IO test -- .new") {
val result = interpretCode(goodPath + """my $io = ^IO.new($path); $io.isa("IO")""")
val result = interpretCode(goodPath + """my $io = IO.new($path); $io.isa("IO")""")
result.unboxToBoolean.get should equal (true)
}

test("... basic IO test -- existence") {
val result = interpretCode(goodPath + """my $io = ^IO.new($path); -e $io""")
val result = interpretCode(goodPath + """my $io = IO.new($path); -e $io""")
result.unboxToBoolean.get should equal (true)
}

test("... basic IO test -- existence with invalid file") {
val result = interpretCode(badPath + """my $io = ^IO.new($path); -e $io""")
val result = interpretCode(badPath + """my $io = IO.new($path); -e $io""")
result.unboxToBoolean.get should equal (false)
}

test("... basic IO test -- readable") {
val result = interpretCode(goodPath + """my $io = ^IO.new($path); -r $io""")
val result = interpretCode(goodPath + """my $io = IO.new($path); -r $io""")
result.unboxToBoolean.get should equal (true)
}

test("... basic IO test -- readable with invalid file") {
val result = interpretCode(badPath + """my $io = ^IO.new($path); -r $io""")
val result = interpretCode(badPath + """my $io = IO.new($path); -r $io""")
result.unboxToBoolean.get should equal (false)
}

test("... basic IO test -- readline") {
val result = interpretCode(goodPath + """my $io = ^IO.new($path); $io.readline""")
val result = interpretCode(goodPath + """my $io = IO.new($path); $io.readline""")
result.unboxToString.get should equal ("use Test::More;")
}

test("... basic IO test -- readlines") {
val result = interpretCode(goodPath + """my $io = ^IO.new($path); $io.readlines""")
val result = interpretCode(goodPath + """my $io = IO.new($path); $io.readlines""")
val lines = result.unboxToArrayBuffer.get
lines(0).unboxToString.get should equal ("use Test::More;")
lines(1).unboxToString.get should equal ("")
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/org/moe/parser/MultiAssignmentTestSuite.scala
Expand Up @@ -97,29 +97,29 @@ class MultiAssignmentTestSuite extends FunSuite with BeforeAndAfter with ParserT
"""

test("... basic multi-attribute-assign") {
val result = interpretCode(testClass + "; my $x = ^Foo.new; $x.test1; $x.get")
val result = interpretCode(testClass + "; my $x = Foo.new; $x.test1; $x.get")
var a = result.unboxToArrayBuffer.get
a(0).unboxToInt.get should equal (1)
a(1).unboxToInt.get should equal (2)
}

test("... basic multi-attribute-assign w/ extra var") {
val result = interpretCode(testClass + "; my $x = ^Foo.new; $x.test2; $x.get")
val result = interpretCode(testClass + "; my $x = Foo.new; $x.test2; $x.get")
var a = result.unboxToArrayBuffer.get
a(0).unboxToInt.get should equal (1)
a(1).unboxToInt.get should equal (2)
a(2) should equal (runtime.NativeObjects.getUndef)
}

test("... basic multi-attribute-assign w/ extra element") {
val result = interpretCode(testClass + "; my $x = ^Foo.new; $x.test3; $x.get")
val result = interpretCode(testClass + "; my $x = Foo.new; $x.test3; $x.get")
var a = result.unboxToArrayBuffer.get
a(0).unboxToInt.get should equal (1)
a(1).unboxToInt.get should equal (2)
}

test("... basic multi-attribute-assign w/ swap") {
val result = interpretCode(testClass + "; my $x = ^Foo.new; $x.test4; $x.get")
val result = interpretCode(testClass + "; my $x = Foo.new; $x.test4; $x.get")
var a = result.unboxToArrayBuffer.get
a(0).unboxToInt.get should equal (2)
a(1).unboxToInt.get should equal (1)
Expand Down
8 changes: 4 additions & 4 deletions src/test/scala/org/moe/runtime/MoeRuntimeTestSuite.scala
Expand Up @@ -89,11 +89,11 @@ class MoeRuntimeTestSuite extends FunSuite with BeforeAndAfter with ShouldMatche
val msg = runtime.NativeObjects.getStr("HELLO PRINT WORLD");
val msgs = List("HELLO", "PRINT", "WORLD").map(runtime.NativeObjects.getStr(_))

var out = msg.unboxToString.get + "\n"
var out = msg.unboxToString.get + util.Properties.lineSeparator
runtime.warn(msg)
assert(outStream.toString() === out)

out += msgs.map(_.unboxToString.get).mkString + "\n"
out += msgs.map(_.unboxToString.get).mkString + util.Properties.lineSeparator
runtime.warn(msgs:_*)
assert(outStream.toString() === out)
}
Expand Down Expand Up @@ -137,11 +137,11 @@ class MoeRuntimeTestSuite extends FunSuite with BeforeAndAfter with ShouldMatche
val msg = runtime.NativeObjects.getStr("HELLO PRINT WORLD");
val msgs = List("HELLO", "PRINT", "WORLD").map(runtime.NativeObjects.getStr(_))

var out = msg.unboxToString.get + "\n"
var out = msg.unboxToString.get + util.Properties.lineSeparator
runtime.say(msg)
assert(outStream.toString() === out)

out += msgs.map(_.unboxToString.get).mkString + "\n"
out += msgs.map(_.unboxToString.get).mkString + util.Properties.lineSeparator
runtime.say(msgs:_*)
assert(outStream.toString() === out)
}
Expand Down
19 changes: 19 additions & 0 deletions t/001-literals/008-hashes.t
Expand Up @@ -39,8 +39,27 @@ use Test::More;
is_deeply(%x.kv, [['one', 1], ['three', 3], ['four', 4], ['two', 2]], '... got the expected values from &kv');
is_deeply(%x.pairs, ['one' => 1, 'three' => 3, 'four' => 4, 'two' => 2], '... got the expected values from &pairs');

# the next four test do not depend on hash ordering consistency,
# but they do depend on array.sort method

is_deeply(%x.keys.sort(-> ($a, $b) { %x{$a} <=> %x{$b} }), ['one', 'two', 'three', 'four'], '... got the expected values from &keys');
is_deeply(%x.values.sort(-> ($a, $b) { $a <=> $b }), [1, 2, 3, 4], '... got the expected values from &values');

is_deeply(%x.kv.sort(-> (@a, @b) { @a[1] <=> @b[1] }), [['one', 1], ['two', 2], ['three', 3], ['four', 4]], '... got the expected values from &kv');
is_deeply(%x.pairs.sort(-> ($a, $b) { $a.value <=> $b.value }), ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4], '... got the expected values from &pairs');

is(%x.clear, undef, '... got the expected value from &clear');
is_deeply(%x.kv, [], '... got the expected values from &kv (after &clear)');

# hash.eqv with nested hashes
my %x = { one => 1, two => 2, three => 3, four => {four => 4, FOUR => 4}, five => [5, "five"] };
my %y = { one => 1, two => 2, three => 3, four => {four => 4, FOUR => 4}, five => [5, "five"] };

ok(%x.eqv(%y), '... got the expected result (true) from &eqv');

%y{'six'} = 6;
ok(!(%x.eqv(%y)), '... got the expected result (false) from &eqv, after modifying the second hash');

}

done_testing();
54 changes: 54 additions & 0 deletions t/099-problems/26.t
@@ -0,0 +1,54 @@
# P26 (**) Generate the combinations of K distinct objects chosen from the N elements of a list.

# In how many ways can a committee of 3 be chosen from a group
# of 12 people? We all know that there are C(12,3) = 220
# possibilities (C(N,K) denotes the well-known binomial
# coefficient). For pure mathematicians, this result may be
# great. But we want to really generate all the possibilities.

# Example:

# moe> combinations(3, ['a', 'b', 'c', 'd', 'e', 'f'])
# [['a', 'b', 'c'], ['a', 'b', 'd'], ['a', 'b', 'e'], ...]

use Test::More;

sub concat(@a, @b) {
@b.each(-> ($x) { @a.push($x) });
@a
}

sub combinations($n, @list) {
if ($n == 1) {
@list.map(-> ($x) { [$x] });
}
elsif (@list.length <= $n) {
[@list];
}
else {
concat(
combinations($n - 1, @list.tail)
.map(
-> (@c) {
[@list.head, @c].flatten
}
),
combinations($n, @list.tail)
)
}
}

ok(combinations(3, ['a', 'b', 'c', 'd', 'e', 'f'])
.eqv([["a", "b", "c"], ["a", "b", "d"], ["a", "b", "e"], ["a", "b", "f"],
["a", "c", "d"], ["a", "c", "e"], ["a", "c", "f"],
["a", "d", "e"], ["a", "d", "f"],
["a", "e", "f"],
["b", "c", "d"], ["b", "c", "e"], ["b", "c", "f"],
["b", "d", "e"], ["b", "d", "f"],
["b", "e", "f"],
["c", "d", "e"], ["c", "d", "f"],
["c", "e", "f"],
["d", "e", "f"]]),
"... P26");

done_testing();

0 comments on commit 9da56d8

Please sign in to comment.