refactor: move benchmark directory under test and update all references

The benchmark directory is relocated from the project root into the test directory, and all scripts, documentation links, and gitignore paths are updated accordingly. The test runner is also refactored to explicitly walk subdirectories (core, io, language, limit) instead of using a single test root, and a new test/README.md is added to document the test suite structure. Additionally, the constructor test for the Foo class is updated to add a zero-arity constructor and adjust expected output strings.
This commit is contained in:
Bob Nystrom
2015-03-14 19:45:56 +00:00
parent af58528e88
commit c4ef964f92
562 changed files with 32 additions and 8 deletions
@@ -0,0 +1,9 @@
var a = "a"
var b = "b"
var c = "c"
// Assignment is right-associative.
a = b = c
IO.print(a) // expect: c
IO.print(b) // expect: c
IO.print(c) // expect: c
+8
View File
@@ -0,0 +1,8 @@
var a = "before"
IO.print(a) // expect: before
a = "after"
IO.print(a) // expect: after
IO.print(a = "arg") // expect: arg
IO.print(a) // expect: arg
+2
View File
@@ -0,0 +1,2 @@
var a = "a"
(a) = "value" // expect error
@@ -0,0 +1,3 @@
var a = "a"
var b = "b"
a + b = "value" // expect error
+3
View File
@@ -0,0 +1,3 @@
var a = "a"
var b = "b"
b is a = "value" // expect error
+10
View File
@@ -0,0 +1,10 @@
new Fn {
var a = "before"
IO.print(a) // expect: before
a = "after"
IO.print(a) // expect: after
IO.print(a = "arg") // expect: arg
IO.print(a) // expect: arg
}.call()
@@ -0,0 +1,2 @@
var a = "a"
!a = "value" // expect error
+11
View File
@@ -0,0 +1,11 @@
// Chained assignment.
var a = "a"
var b = "b"
a = b = "chain"
IO.print(a) // expect: chain
IO.print(a) // expect: chain
// Assignment on RHS of variable.
var c = a = "var"
IO.print(a) // expect: var
IO.print(c) // expect: var
+1
View File
@@ -0,0 +1 @@
unknown = "what" // expect error
+23
View File
@@ -0,0 +1,23 @@
// << have higher precedence than |.
IO.print(2 | 1 << 1) // expect: 2
IO.print(1 << 1 | 2) // expect: 2
// << has higher precedence than &.
IO.print(2 & 1 << 1) // expect: 2
IO.print(1 << 1 & 2) // expect: 2
// << has higher precedence than ^.
IO.print(2 ^ 1 << 1) // expect: 0
IO.print(1 << 1 ^ 2) // expect: 0
// & has higher precedence than |.
IO.print(1 & 1 | 2) // expect: 3
IO.print(2 | 1 & 1) // expect: 3
// & has higher precedence than ^.
IO.print(1 & 1 ^ 2) // expect: 3
IO.print(2 ^ 1 & 1) // expect: 3
// ^ has higher precedence than |.
IO.print(1 ^ 1 | 1) // expect: 1
IO.print(1 | 1 ^ 1) // expect: 1
+9
View File
@@ -0,0 +1,9 @@
var f
for (i in [1, 2, 3]) {
var j = 4
f = new Fn { IO.print(i + j) }
break
}
f.call()
// expect: 5
@@ -0,0 +1,9 @@
var f
while (true) {
var i = "i"
f = new Fn { IO.print(i) }
break
}
f.call()
// expect: i
@@ -0,0 +1,18 @@
for (i in 0..10) {
IO.print(i)
{
var a = "a"
{
var b = "b"
{
var c = "c"
if (i > 1) break
}
}
}
}
// expect: 0
// expect: 1
// expect: 2
+10
View File
@@ -0,0 +1,10 @@
for (i in [1, 2, 3, 4, 5]) {
IO.print(i)
if (i > 2) break
IO.print(i)
}
// expect: 1
// expect: 1
// expect: 2
// expect: 2
// expect: 3
@@ -0,0 +1,7 @@
var done = false
while (!done) {
new Fn {
break // expect error
}
done = true
}
@@ -0,0 +1,9 @@
var done = false
while (!done) {
class Foo {
method {
break // expect error
}
}
done = true
}
+12
View File
@@ -0,0 +1,12 @@
var i = 0
while (true) {
i = i + 1
IO.print(i)
if (i > 2) break
IO.print(i)
}
// expect: 1
// expect: 1
// expect: 2
// expect: 2
// expect: 3
+19
View File
@@ -0,0 +1,19 @@
for (i in 0..2) {
IO.print("outer ", i)
if (i > 1) break
for (j in 0..2) {
IO.print("inner ", j)
if (j > 1) break
}
}
// expect: outer 0
// expect: inner 0
// expect: inner 1
// expect: inner 2
// expect: outer 1
// expect: inner 0
// expect: inner 1
// expect: inner 2
// expect: outer 2
@@ -0,0 +1,25 @@
var i = 0
while (true) {
IO.print("outer ", i)
if (i > 1) break
var j = 0
while (true) {
IO.print("inner ", j)
if (j > 1) break
j = j + 1
}
i = i + 1
}
// expect: outer 0
// expect: inner 0
// expect: inner 1
// expect: inner 2
// expect: outer 1
// expect: inner 0
// expect: inner 1
// expect: inner 2
// expect: outer 2
+1
View File
@@ -0,0 +1 @@
break // expect error
+14
View File
@@ -0,0 +1,14 @@
class Foo {
static sayName {
IO.print(Foo)
}
sayName {
IO.print(Foo)
}
static toString { "Foo!" }
}
Foo.sayName // expect: Foo!
(new Foo).sayName // expect: Foo!
+6
View File
@@ -0,0 +1,6 @@
class Foo {}
var foo = new Foo
IO.print(foo is Foo) // expect: true
// TODO: Test precedence and grammar of what follows "new".
@@ -0,0 +1,2 @@
class // expect error
Foo {}
@@ -0,0 +1,6 @@
class Foo {
static // expect error
method {} // expect error
}
// The second error is cascaded.
+11
View File
@@ -0,0 +1,11 @@
// Empty body.
class A {}
// Newline body.
class B {
}
// No newline after last method.
class C {
method {} }
@@ -0,0 +1,25 @@
var f = null
var g = null
{
var local = "local"
f = new Fn {
IO.print(local)
local = "after f"
IO.print(local)
}
g = new Fn {
IO.print(local)
local = "after g"
IO.print(local)
}
}
f.call()
// expect: local
// expect: after f
g.call()
// expect: after f
// expect: after g
@@ -0,0 +1,9 @@
var f = null
new Fn {|param|
f = new Fn {
IO.print(param)
}
}.call("param")
f.call() // expect: param
@@ -0,0 +1,13 @@
// This is a regression test. There was a bug where if an upvalue for an
// earlier local (here "a") was captured *after* a later one ("b"), then Wren
// would crash because it walked to the end of the upvalue list (correct), but
// then didn't handle not finding the variable.
new Fn {
var a = "a"
var b = "b"
new Fn {
IO.print(b) // expect: b
IO.print(a) // expect: a
}.call()
}.call()
@@ -0,0 +1,12 @@
var F = null
class Foo {
method(param) {
F = new Fn {
IO.print(param)
}
}
}
(new Foo).method("param")
F.call() // expect: param
@@ -0,0 +1,10 @@
var f = null
{
var local = "local"
f = new Fn {
IO.print(local)
}
}
f.call() // expect: local
@@ -0,0 +1,14 @@
var foo = null
{
var local = "local"
class Foo {
method {
IO.print(local)
}
}
foo = new Foo
}
foo.method // expect: local
+21
View File
@@ -0,0 +1,21 @@
var f = null
new Fn {
var a = "a"
new Fn {
var b = "b"
new Fn {
var c = "c"
f = new Fn {
IO.print(a)
IO.print(b)
IO.print(c)
}
}.call()
}.call()
}.call()
f.call()
// expect: a
// expect: b
// expect: c
@@ -0,0 +1,6 @@
{
var local = "local"
new Fn {
IO.print(local) // expect: local
}.call()
}
@@ -0,0 +1,10 @@
{
var local = "local"
class Foo {
method {
IO.print(local)
}
}
(new Foo).method // expect: local
}
@@ -0,0 +1,13 @@
var f = null
{
var a = "a"
f = new Fn {
IO.print(a)
IO.print(a)
}
}
f.call()
// expect: a
// expect: a
@@ -0,0 +1,17 @@
{
var f = null
{
var a = "a"
f = new Fn { IO.print(a) }
}
{
// Since a is out of scope, the local slot will be reused by b. Make sure
// that f still closes over a.
var b = "b"
f.call() // expect: a
}
}
// TODO: Maximum number of closed-over variables (directly and/or indirect).
@@ -0,0 +1,11 @@
{
var foo = "closure"
new Fn {
{
IO.print(foo) // expect: closure
var foo = "shadow"
IO.print(foo) // expect: shadow
}
IO.print(foo) // expect: closure
}.call()
}
+5
View File
@@ -0,0 +1,5 @@
// In middle of line.
IO.print/* ... */(/* */"ok"/* */) // expect: ok
// Nested.
IO.print(/* in /* nest */ out */"ok") // expect: ok
+2
View File
@@ -0,0 +1,2 @@
IO.print("ok") // expect: ok
/* comment */
+2
View File
@@ -0,0 +1,2 @@
IO.print("ok") // expect: ok
// comment
@@ -0,0 +1 @@
// comment
@@ -0,0 +1 @@
// comment
+11
View File
@@ -0,0 +1,11 @@
// Unicode characters are allowed in comments.
//
// Latin 1 Supplement: £§¶ÜÞ
// Latin Extended-A: ĐĦŋœ
// Latin Extended-B: ƂƢƩǁ
// Other stuff: ឃᢆ᯽₪ℜ↩⊗┺░
// Emoji: ☃☺♣
// TODO: What about combining characters?
IO.print("ok") // expect: ok
@@ -0,0 +1,3 @@
// expect error line 3
IO.print("nope") /*
oops
@@ -0,0 +1,4 @@
// expect error line 4
IO.print("nope") /* /* /*
*/
oops
@@ -0,0 +1 @@
1 ? 2 ? 3 : 4 : 5 // expect error
@@ -0,0 +1,2 @@
true ? 1 // expect error
"next expression"
@@ -0,0 +1 @@
? 1 : 2 // expect error
@@ -0,0 +1 @@
(true ? 1 :) // expect error
@@ -0,0 +1 @@
true 1 : 2 // expect error
@@ -0,0 +1 @@
(true ? : 2) // expect error
+7
View File
@@ -0,0 +1,7 @@
// Newline after '?'.
IO.print(true ?
"yes" : "no") // expect: yes
// Newline after ':'.
IO.print(false ? "yes" :
"no") // expect: no
+55
View File
@@ -0,0 +1,55 @@
class Foo {
static bar { true }
static baz { 1 }
}
// Condition precedence.
IO.print(true ? 1 : 2) // expect: 1
IO.print((true) ? 1 : 2) // expect: 1
IO.print([true][0] ? 1 : 2) // expect: 1
IO.print(Foo.bar ? 1 : 2) // expect: 1
IO.print(3..4 ? 1 : 2) // expect: 1
IO.print(3 * 4 ? 1 : 2) // expect: 1
IO.print(3 + 4 ? 1 : 2) // expect: 1
IO.print(true || false ? 1 : 2) // expect: 1
IO.print(!false ? 1 : 2) // expect: 1
IO.print(~0 ? 1 : 2) // expect: 1
IO.print(3 is Num ? 1 : 2) // expect: 1
IO.print(new Foo ? 1 : 2) // expect: 1
var a = 0
IO.print(a = 3 ? 1 : 2) // expect: 1
IO.print(a) // expect: 1
// Then branch precedence.
IO.print(true ? (1) : 2) // expect: 1
IO.print(true ? [1][0] : 2) // expect: 1
IO.print(true ? Foo.baz : 2) // expect: 1
IO.print(true ? 3..4 : 2) // expect: 3..4
IO.print(true ? 3 * 4 : 2) // expect: 12
IO.print(true ? 3 + 4 : 2) // expect: 7
IO.print(true ? 1 || false : 2) // expect: 1
IO.print(true ? !true : 2) // expect: false
IO.print(true ? ~0 : 2) // expect: 4294967295
IO.print(true ? 3 is Bool : 2) // expect: false
IO.print(true ? new Foo : 2) // expect: instance of Foo
IO.print(true ? a = 5 : 2) // expect: 5
IO.print(a) // expect: 5
// Else branch precedence.
IO.print(false ? 1 : (2)) // expect: 2
IO.print(false ? 1 : [2][0]) // expect: 2
IO.print(false ? 2 : Foo.baz) // expect: 1
IO.print(false ? 1 : 3..4) // expect: 3..4
IO.print(false ? 1 : 3 * 4) // expect: 12
IO.print(false ? 1 : 3 + 4) // expect: 7
IO.print(false ? 1 : 2 || false) // expect: 2
IO.print(false ? 1 : !false) // expect: true
IO.print(false ? 1 : ~0) // expect: 4294967295
IO.print(false ? 1 : 3 is Num) // expect: true
IO.print(false ? 1 : new Foo) // expect: instance of Foo
// Associativity.
IO.print(true ? 2 : true ? 4 : 5) // expect: 2
IO.print(false ? 2 : true ? 4 : 5) // expect: 4
@@ -0,0 +1,2 @@
true ? IO.print("ok") : IO.print("no") // expect: ok
false ? IO.print("no") : IO.print("ok") // expect: ok
+8
View File
@@ -0,0 +1,8 @@
class Foo {
toString { "Foo" }
}
// Classes inherit the argument-less "new" one by default.
var foo = new Foo
IO.print(foo is Foo) // expect: true
IO.print(foo.toString) // expect: Foo
@@ -0,0 +1,7 @@
class Foo {
+(other) { "Foo " + other }
}
IO.print(new Foo + "value") // expect: Foo value
// TODO: Other expressions following a constructor, like new Foo.bar("arg").
+19
View File
@@ -0,0 +1,19 @@
class Foo {
new { IO.print("none") }
new() { IO.print("zero") }
new(a) { IO.print(a) }
new(a, b) { IO.print(a + b) }
toString { "Foo" }
}
// Can overload by arity.
new Foo // expect: none
new Foo() // expect: zero
new Foo("one") // expect: one
new Foo("one", "two") // expect: onetwo
// Returns the new instance.
var foo = new Foo // expect: none
IO.print(foo is Foo) // expect: true
IO.print(foo.toString) // expect: Foo
+40
View File
@@ -0,0 +1,40 @@
class A {
new(arg) {
IO.print("new A ", arg)
_field = arg
}
aField { _field }
}
class B is A {
new(arg1, arg2) {
super(arg2)
IO.print("new B ", arg1)
_field = arg1
}
bField { _field }
}
class C is B {
new {
super("one", "two")
IO.print("new C")
_field = "c"
}
cField { _field }
}
var c = new C
// expect: new A two
// expect: new B one
// expect: new C
IO.print(c is A) // expect: true
IO.print(c is B) // expect: true
IO.print(c is C) // expect: true
IO.print(c.aField) // expect: two
IO.print(c.bField) // expect: one
IO.print(c.cField) // expect: c
+7
View File
@@ -0,0 +1,7 @@
{} // By itself.
// In a statement.
if (true) {}
if (false) {} else {}
IO.print("ok") // expect: ok
View File
+25
View File
@@ -0,0 +1,25 @@
var fiber
var closure
{
var a = "before"
fiber = new Fiber {
IO.print(a)
Fiber.yield()
a = "after"
Fiber.yield()
IO.print(a)
a = "final"
}
closure = new Fn {
IO.print(a)
}
}
fiber.call() // expect: before
closure.call() // expect: before
fiber.call()
closure.call() // expect: after
fiber.call() // expect: after
closure.call() // expect: final
+16
View File
@@ -0,0 +1,16 @@
class Foo {
new { _field = "Foo field" }
closeOverGet {
return new Fn { _field }
}
closeOverSet {
return new Fn { _field = "new value" }
}
}
var foo = new Foo
IO.print(foo.closeOverGet.call()) // expect: Foo field
foo.closeOverSet.call()
IO.print(foo.closeOverGet.call()) // expect: new value
+5
View File
@@ -0,0 +1,5 @@
class Foo {
write { IO.print(_field) }
}
(new Foo).write // expect: null
@@ -0,0 +1,5 @@
class Foo {
static bar {
new Fn { _field = "wat" } // expect error
}
}
@@ -0,0 +1,5 @@
class Foo {
static bar {
_field = "wat" // expect error
}
}
@@ -0,0 +1,14 @@
// Refering to an instance method in a nested static class should *not* walk
// out to find the nearest enclosing instance method. We could make that work,
// but it's confusing to users, and would require some tricky work to make sure
// the enclosing instance is closed over.
class Outer {
foo {
class Inner {
static bar {
_field = "nope" // expect error
}
}
}
}
+26
View File
@@ -0,0 +1,26 @@
class Foo {
set(a, b, c, d, e) {
_a = a
_b = b
_c = c
_d = d
_e = e
}
write {
IO.print(_a)
IO.print(_b)
IO.print(_c)
IO.print(_d)
IO.print(_e)
}
}
var foo = new Foo
foo.set(1, 2, 3, 4, 5)
foo.write
// expect: 1
// expect: 2
// expect: 3
// expect: 4
// expect: 5
+18
View File
@@ -0,0 +1,18 @@
class Outer {
method {
_field = "outer"
IO.print(_field) // expect: outer
class Inner {
method {
_field = "inner"
IO.print(_field) // expect: inner
}
}
(new Inner).method
IO.print(_field) // expect: outer
}
}
(new Outer).method
+37
View File
@@ -0,0 +1,37 @@
// This test exists mainly to make sure the GC traces instance fields.
class Node {
set(left, value, right) {
_left = left
_value = value
_right = right
}
write {
if (_left is Node) {
_left.write
}
IO.print(_value)
if (_right is Node) {
_right.write
}
}
}
var a = new Node
a.set(null, "a", null)
var b = new Node
b.set(null, "b", null)
var c = new Node
c.set(a, "c", b)
a = null
b = null
var d = new Node
d.set(c, "d", null)
c = null
d.write
// expect: a
// expect: c
// expect: b
// expect: d
+1
View File
@@ -0,0 +1 @@
_field = "wat" // expect error
+9
View File
@@ -0,0 +1,9 @@
class Foo {
write { IO.print(_field) } // Compile a use of the field...
init { _field = "value" } // ...before an assignment to it.
}
var foo = new Foo
// But invoke them in the right order.
foo.init
foo.write // expect: value
@@ -0,0 +1,10 @@
var list = []
for (i in [1, 2, 3]) {
list.add(new Fn { IO.print(i) })
}
for (f in list) f.call()
// expect: 1
// expect: 2
// expect: 3
+11
View File
@@ -0,0 +1,11 @@
var list = []
for (i in [1, 2, 3]) {
var j = i + 1
list.add(new Fn { IO.print(j) })
}
for (f in list) f.call()
// expect: 2
// expect: 3
// expect: 4
+2
View File
@@ -0,0 +1,2 @@
for // expect error
(i in [1, 2, 3]) IO.print(i)
+2
View File
@@ -0,0 +1,2 @@
for (i // expect error
in [1]) IO.print(i)
@@ -0,0 +1,10 @@
var f = new Fn {
IO.print("evaluate sequence")
return [1, 2, 3]
}
for (i in f.call()) IO.print(i)
// expect: evaluate sequence
// expect: 1
// expect: 2
// expect: 3
+9
View File
@@ -0,0 +1,9 @@
var f = new Fn {
for (i in [1, 2, 3]) {
return new Fn { IO.print(i) }
}
}
var g = f.call()
g.call()
// expect: 1
+8
View File
@@ -0,0 +1,8 @@
var f = new Fn {
for (i in [1, 2, 3]) {
return i
}
}
IO.print(f.call())
// expect: 1
+14
View File
@@ -0,0 +1,14 @@
// Single-expression body.
for (i in [1]) IO.print(i)
// expect: 1
// Block body.
for (i in [1]) {
IO.print(i)
}
// expect: 1
// Newline after "in".
for (i in
[1]) IO.print(i)
// expect: 1
+32
View File
@@ -0,0 +1,32 @@
class Iter {
new(value) { _value = value }
iterate(iterator) { _value }
iteratorValue(iterator) { "value" }
}
// False and null are false.
for (n in new Iter(false)) {
IO.print("bad")
break
}
for (n in new Iter(null)) {
IO.print("bad")
break
}
// Everything else is true.
for (n in new Iter(true)) {
IO.print("true") // expect: true
break
}
for (n in new Iter(0)) {
IO.print(0) // expect: 0
break
}
for (n in new Iter("")) {
IO.print("string") // expect: string
break
}
+2
View File
@@ -0,0 +1,2 @@
var f = new Fn {}
IO.print(f.call()) // expect: null
+4
View File
@@ -0,0 +1,4 @@
var f = new Fn {
// Hi.
}
IO.print(f.call()) // expect: null
@@ -0,0 +1,5 @@
new Fn { IO.print("ok") // expect error
}.call() // expect error
// The second error is cascaded here. If it starts failing, just remove that
// expectation.
@@ -0,0 +1,2 @@
new Fn {
IO.print("ok") } // expect error
@@ -0,0 +1 @@
new Fn {|| null } // expect error
+50
View File
@@ -0,0 +1,50 @@
var f0 = new Fn { 0 }
IO.print(f0.call()) // expect: 0
var f1 = new Fn {|a| a }
IO.print(f1.call(1)) // expect: 1
var f2 = new Fn {|a, b| a + b }
IO.print(f2.call(1, 2)) // expect: 3
var f3 = new Fn {|a, b, c| a + b + c }
IO.print(f3.call(1, 2, 3)) // expect: 6
var f4 = new Fn {|a, b, c, d| a + b + c + d }
IO.print(f4.call(1, 2, 3, 4)) // expect: 10
var f5 = new Fn {|a, b, c, d, e| a + b + c + d + e }
IO.print(f5.call(1, 2, 3, 4, 5)) // expect: 15
var f6 = new Fn {|a, b, c, d, e, f| a + b + c + d + e + f }
IO.print(f6.call(1, 2, 3, 4, 5, 6)) // expect: 21
var f7 = new Fn {|a, b, c, d, e, f, g| a + b + c + d + e + f + g }
IO.print(f7.call(1, 2, 3, 4, 5, 6, 7)) // expect: 28
var f8 = new Fn {|a, b, c, d, e, f, g, h| a + b + c + d + e + f + g + h }
IO.print(f8.call(1, 2, 3, 4, 5, 6, 7, 8)) // expect: 36
var f9 = new Fn {|a, b, c, d, e, f, g, h, i| a + b + c + d + e + f + g + h + i }
IO.print(f9.call(1, 2, 3, 4, 5, 6, 7, 8, 9)) // expect: 45
var f10 = new Fn {|a, b, c, d, e, f, g, h, i, j| a + b + c + d + e + f + g + h + i + j }
IO.print(f10.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)) // expect: 55
var f11 = new Fn {|a, b, c, d, e, f, g, h, i, j, k| a + b + c + d + e + f + g + h + i + j + k }
IO.print(f11.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)) // expect: 66
var f12 = new Fn {|a, b, c, d, e, f, g, h, i, j, k, l| a + b + c + d + e + f + g + h + i + j + k + l }
IO.print(f12.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)) // expect: 78
var f13 = new Fn {|a, b, c, d, e, f, g, h, i, j, k, l, m| a + b + c + d + e + f + g + h + i + j + k + l + m }
IO.print(f13.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)) // expect: 91
var f14 = new Fn {|a, b, c, d, e, f, g, h, i, j, k, l, m, n| a + b + c + d + e + f + g + h + i + j + k + l + m + n }
IO.print(f14.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)) // expect: 105
var f15 = new Fn {|a, b, c, d, e, f, g, h, i, j, k, l, m, n, o| a + b + c + d + e + f + g + h + i + j + k + l + m + n + o }
IO.print(f15.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) // expect: 120
var f16 = new Fn {|a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p| a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p }
IO.print(f16.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)) // expect: 136
+25
View File
@@ -0,0 +1,25 @@
// Single expression body.
new Fn { IO.print("ok") }.call() // expect: ok
// Curly body.
new Fn {
IO.print("ok") // expect: ok
}.call()
// Multiple statements.
new Fn {
IO.print("1") // expect: 1
IO.print("2") // expect: 2
}.call()
// Extra newlines.
new Fn {
IO.print("1") // expect: 1
IO.print("2") // expect: 2
}.call()
+3
View File
@@ -0,0 +1,3 @@
// A dangling else binds to the right-most if.
if (true) if (false) IO.print("bad") else IO.print("good") // expect: good
if (false) if (true) IO.print("bad") else IO.print("bad")
+6
View File
@@ -0,0 +1,6 @@
// Evaluate the 'else' expression if the condition is false.
if (true) IO.print("good") else IO.print("bad") // expect: good
if (false) IO.print("bad") else IO.print("good") // expect: good
// Allow block body.
if (false) null else { IO.print("block") } // expect: block
+10
View File
@@ -0,0 +1,10 @@
// Evaluate the 'then' expression if the condition is true.
if (true) IO.print("good") // expect: good
if (false) IO.print("bad")
// Allow block body.
if (true) { IO.print("block") } // expect: block
// Assignment in if condition.
var a = false
if (a = true) IO.print(a) // expect: true
+1
View File
@@ -0,0 +1 @@
if (true) "ok" else // expect error
+2
View File
@@ -0,0 +1,2 @@
if // expect error
(true) IO.print("bad")
+8
View File
@@ -0,0 +1,8 @@
// False and null are false.
if (false) IO.print("bad") else IO.print("false") // expect: false
if (null) IO.print("bad") else IO.print("null") // expect: null
// Everything else is true.
if (true) IO.print(true) // expect: true
if (0) IO.print(0) // expect: 0
if ("") IO.print("empty") // expect: empty
@@ -0,0 +1,6 @@
// Sprinkle some carriage returns to ensure they are ignored anywhere:
IO␍.print("one"␍)
IO.print␍("two")
// Generate a compile error so we can test that the line number is correct.
+ * // expect error
@@ -0,0 +1,23 @@
class Foo {
getter {
IO.print("getter")
}
setter=(value) {
IO.print("setter")
}
method(a) {
IO.print("method")
}
}
class Bar is Foo {
test {
getter // expect: getter
setter = "value" // expect: setter
method("arg") // expect: method
}
}
(new Bar).test
@@ -0,0 +1,23 @@
class Foo {
getter {
IO.print("getter")
}
setter=(value) {
IO.print("setter")
}
method(a) {
IO.print("method")
}
test {
getter // expect: getter
setter = "value" // expect: setter
method("arg") // expect: method
}
}
(new Foo).test
// TODO: Need to decide how these interact with globals.
@@ -0,0 +1,17 @@
class Foo {
bar { "getter" }
test {
IO.print(bar) // expect: getter
{
IO.print(bar) // expect: getter
var bar = "local"
IO.print(bar) // expect: local
}
IO.print(bar) // expect: getter
}
}
(new Foo).test
@@ -0,0 +1,20 @@
class Foo {
bar=(value) {
IO.print("setter")
return value
}
test {
bar = "value" // expect: setter
{
bar = "value" // expect: setter
var bar = "local"
bar = "value" // no expectation
}
bar = "value" // expect: setter
}
}
(new Foo).test
@@ -0,0 +1,47 @@
class Outer {
getter {
IO.print("outer getter")
}
setter=(value) {
IO.print("outer setter")
}
method(a) {
IO.print("outer method")
}
test {
getter // expect: outer getter
setter = "value" // expect: outer setter
method("arg") // expect: outer method
class Inner {
getter {
IO.print("inner getter")
}
setter=(value) {
IO.print("inner setter")
}
method(a) {
IO.print("inner method")
}
test {
getter // expect: inner getter
setter = "value" // expect: inner setter
method("arg") // expect: inner method
}
}
(new Inner).test
getter // expect: outer getter
setter = "value" // expect: outer setter
method("arg") // expect: outer method
}
}
(new Outer).test
@@ -0,0 +1,21 @@
class Foo {
static getter {
IO.print("getter")
}
static setter=(value) {
IO.print("setter")
}
static method(a) {
IO.print("method")
}
static test {
getter // expect: getter
setter = "value" // expect: setter
method("arg") // expect: method
}
}
Foo.test

Some files were not shown because too many files have changed in this diff Show More