feat: allow empty argument list methods in calls, definitions, and docs

- Compile empty `()` as a valid method signature distinct from no parentheses
- Update `call()`, `clear()`, `run()`, `try()`, and `yield()` to use empty argument lists
- Revise documentation across multiple files to reflect new signature semantics
This commit is contained in:
Bob Nystrom
2015-02-27 07:08:36 +00:00
parent 94f34367f9
commit 5382fa05d7
94 changed files with 291 additions and 224 deletions
+1 -1
View File
@@ -7,4 +7,4 @@ new Fn {
IO.print(a = "arg") // expect: arg
IO.print(a) // expect: arg
}.call
}.call()
+1 -1
View File
@@ -5,5 +5,5 @@ for (i in [1, 2, 3]) {
break
}
f.call
f.call()
// expect: 5
+1 -1
View File
@@ -5,5 +5,5 @@ while (true) {
break
}
f.call
f.call()
// expect: i
+2 -2
View File
@@ -16,10 +16,10 @@ var g = null
}
}
f.call
f.call()
// expect: local
// expect: after f
g.call
g.call()
// expect: after f
// expect: after g
@@ -6,4 +6,4 @@ new Fn {|param|
}
}.call("param")
f.call // expect: param
f.call() // expect: param
+2 -2
View File
@@ -9,5 +9,5 @@ new Fn {
new Fn {
IO.print(b) // expect: b
IO.print(a) // expect: a
}.call
}.call
}.call()
}.call()
@@ -9,4 +9,4 @@ class Foo {
}
(new Foo).method("param")
F.call // expect: param
F.call() // expect: param
+1 -1
View File
@@ -7,4 +7,4 @@ var f = null
}
}
f.call // expect: local
f.call() // expect: local
+4 -4
View File
@@ -11,11 +11,11 @@ new Fn {
IO.print(b)
IO.print(c)
}
}.call
}.call
}.call
}.call()
}.call()
}.call()
f.call
f.call()
// expect: a
// expect: b
// expect: c
+1 -1
View File
@@ -2,5 +2,5 @@
var local = "local"
new Fn {
IO.print(local) // expect: local
}.call
}.call()
}
@@ -8,6 +8,6 @@ var f = null
}
}
f.call
f.call()
// expect: a
// expect: a
+1 -1
View File
@@ -10,7 +10,7 @@
// 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
f.call() // expect: a
}
}
+1 -1
View File
@@ -7,5 +7,5 @@
IO.print(foo) // expect: shadow
}
IO.print(foo) // expect: closure
}.call
}.call()
}
+1 -1
View File
@@ -2,6 +2,6 @@ var fiber = new Fiber {
Fiber.abort("Error message.")
}
IO.print(fiber.try) // expect: Error message.
IO.print(fiber.try()) // expect: Error message.
IO.print(fiber.isDone) // expect: true
IO.print(fiber.error) // expect: Error message.
+1 -1
View File
@@ -3,5 +3,5 @@ var fiber = new Fiber {
}
IO.print("before") // expect: before
fiber.call // expect: fiber
fiber.call() // expect: fiber
IO.print("after") // expect: after
+2 -2
View File
@@ -1,7 +1,7 @@
var fiber
fiber = new Fiber {
fiber.call // expect runtime error: Fiber has already been called.
fiber.call() // expect runtime error: Fiber has already been called.
}
fiber.call
fiber.call()
+3 -3
View File
@@ -2,11 +2,11 @@ var a
var b
a = new Fiber {
b.call // expect runtime error: Fiber has already been called.
b.call() // expect runtime error: Fiber has already been called.
}
b = new Fiber {
a.call
a.call()
}
b.call
b.call()
+2 -2
View File
@@ -2,5 +2,5 @@ var fiber = new Fiber {
IO.print("fiber")
}
var result = fiber.call // expect: fiber
IO.print(result) // expect: null
var result = fiber.call() // expect: fiber
IO.print(result) // expect: null
+2 -2
View File
@@ -3,5 +3,5 @@ var fiber = new Fiber {
return "result"
}
var result = fiber.call // expect: fiber
IO.print(result) // expect: result
var result = fiber.call() // expect: fiber
IO.print(result) // expect: result
+2 -2
View File
@@ -2,5 +2,5 @@ var fiber = new Fiber {
IO.print("call")
}
fiber.call // expect: call
fiber.call // expect runtime error: Cannot call a finished fiber.
fiber.call() // expect: call
fiber.call() // expect runtime error: Cannot call a finished fiber.
+8 -8
View File
@@ -5,9 +5,9 @@ var closure
var a = "before"
fiber = new Fiber {
IO.print(a)
Fiber.yield
Fiber.yield()
a = "after"
Fiber.yield
Fiber.yield()
IO.print(a)
a = "final"
}
@@ -17,9 +17,9 @@ var closure
}
}
fiber.call // expect: before
closure.call // expect: before
fiber.call
closure.call // expect: after
fiber.call // expect: after
closure.call // expect: final
fiber.call() // expect: before
closure.call() // expect: before
fiber.call()
closure.call() // expect: after
fiber.call() // expect: after
closure.call() // expect: final
+1 -1
View File
@@ -3,5 +3,5 @@ var fiber = new Fiber {
}
IO.print(fiber.error) // expect: null
IO.print(fiber.try) // expect: String does not implement 'unknown'.
IO.print(fiber.try()) // expect: String does not implement 'unknown'.
IO.print(fiber.error) // expect: String does not implement 'unknown'.
+3 -3
View File
@@ -1,11 +1,11 @@
var fiber = new Fiber {
IO.print("1")
Fiber.yield
Fiber.yield()
IO.print("2")
}
IO.print(fiber.isDone) // expect: false
fiber.call // expect: 1
fiber.call() // expect: 1
IO.print(fiber.isDone) // expect: false
fiber.call // expect: 2
fiber.call() // expect: 2
IO.print(fiber.isDone) // expect: true
+1 -1
View File
@@ -2,5 +2,5 @@ var fiber = new Fiber {
"s".unknown
}
fiber.try
fiber.try()
IO.print(fiber.isDone) // expect: true
+2 -2
View File
@@ -4,12 +4,12 @@ var b = new Fiber {
var a = new Fiber {
IO.print("begin fiber a")
b.call
b.call()
IO.print("end fiber a")
}
IO.print("begin main")
a.call
a.call()
IO.print("end main")
// expect: begin main
+1 -1
View File
@@ -3,7 +3,7 @@ var fiber = new Fiber {
}
IO.print("before") // expect: before
fiber.run // expect: fiber
fiber.run() // expect: fiber
// This does not get run since we exit when the run fiber completes.
IO.print("nope")
+2 -2
View File
@@ -2,9 +2,9 @@ var fiber
fiber = new Fiber {
IO.print(1) // expect: 1
fiber.run
fiber.run()
IO.print(2) // expect: 2
}
fiber.call
fiber.call()
IO.print(3) // expect: 3
+3 -3
View File
@@ -3,17 +3,17 @@ var b
a = new Fiber {
IO.print(2)
b.run
b.run()
IO.print("nope")
}
b = new Fiber {
IO.print(1)
a.run
a.run()
IO.print(3)
}
b.call
b.call()
// expect: 1
// expect: 2
// expect: 3
+3 -3
View File
@@ -5,9 +5,9 @@ var a = new Fiber {
// Run a through an intermediate fiber since it will get discarded and we need
// to return to the main one after a completes.
var b = new Fiber {
a.run
a.run()
IO.print("nope")
}
b.call // expect: run
a.run // expect runtime error: Cannot run a finished fiber.
b.call() // expect: run
a.run() // expect runtime error: Cannot run a finished fiber.
@@ -6,5 +6,5 @@ fiber = new Fiber {
IO.print(2) // expect: 2
}
fiber.call
fiber.call()
IO.print(3) // expect: 3
@@ -13,7 +13,7 @@ b = new Fiber {
IO.print(3)
}
b.call
b.call()
// expect: 1
// expect: 2
// expect: 3
+1 -1
View File
@@ -4,7 +4,7 @@ var fiber = new Fiber {
IO.print("after")
}
IO.print(fiber.try)
IO.print(fiber.try())
// expect: before
// expect: Bool does not implement 'unknownMethod'.
IO.print("after try") // expect: after try
+2 -2
View File
@@ -1,7 +1,7 @@
var fiber
fiber = new Fiber {
fiber.try // expect runtime error: Fiber has already been called.
fiber.try() // expect runtime error: Fiber has already been called.
}
fiber.call
fiber.call()
+3 -3
View File
@@ -2,11 +2,11 @@ var a
var b
a = new Fiber {
b.try // expect runtime error: Fiber has already been called.
b.try() // expect runtime error: Fiber has already been called.
}
b = new Fiber {
a.call
a.call()
}
b.call
b.call()
+2 -2
View File
@@ -2,5 +2,5 @@ var fiber = new Fiber {
IO.print("try")
}
fiber.try // expect: try
fiber.try // expect runtime error: Cannot try a finished fiber.
fiber.try() // expect: try
fiber.try() // expect runtime error: Cannot try a finished fiber.
+4 -4
View File
@@ -2,7 +2,7 @@ var fiber = new Fiber {
IO.print("fiber")
}
IO.print("before") // expect: before
IO.print(fiber.try) // expect: fiber
// expect: null
IO.print("after") // expect: after
IO.print("before") // expect: before
IO.print(fiber.try()) // expect: fiber
// expect: null
IO.print("after") // expect: after
+8 -8
View File
@@ -1,14 +1,14 @@
var fiber = new Fiber {
IO.print("fiber 1")
Fiber.yield
Fiber.yield()
IO.print("fiber 2")
Fiber.yield
Fiber.yield()
IO.print("fiber 3")
}
var result = fiber.call // expect: fiber 1
IO.print("main 1") // expect: main 1
result = fiber.call // expect: fiber 2
IO.print("main 2") // expect: main 2
result = fiber.call // expect: fiber 3
IO.print("main 3") // expect: main 3
var result = fiber.call() // expect: fiber 1
IO.print("main 1") // expect: main 1
result = fiber.call() // expect: fiber 2
IO.print("main 2") // expect: main 2
result = fiber.call() // expect: fiber 3
IO.print("main 3") // expect: main 3
+1 -1
View File
@@ -1 +1 @@
Fiber.yield // expect runtime error: No fiber to yield to.
Fiber.yield() // expect runtime error: No fiber to yield to.
+4 -4
View File
@@ -1,14 +1,14 @@
var fiber = new Fiber {
IO.print("fiber 1")
var result = Fiber.yield
var result = Fiber.yield()
IO.print(result)
result = Fiber.yield
result = Fiber.yield()
IO.print(result)
}
fiber.call // expect: fiber 1
fiber.call() // expect: fiber 1
IO.print("main 1") // expect: main 1
fiber.call("call 1") // expect: call 1
IO.print("main 2") // expect: main 2
fiber.call // expect: null
fiber.call() // expect: null
IO.print("main 3") // expect: main 3
+2 -2
View File
@@ -1,10 +1,10 @@
var fiber = new Fiber {
IO.print("fiber")
var result = Fiber.yield
var result = Fiber.yield()
IO.print(result)
}
fiber.call // expect: fiber
fiber.call() // expect: fiber
IO.print("main") // expect: main
fiber.run("run") // expect: run
+4 -4
View File
@@ -1,9 +1,9 @@
var a = new Fiber {
Fiber.yield // expect runtime error: No fiber to yield to.
Fiber.yield() // expect runtime error: No fiber to yield to.
}
// Run a chain of fibers. Since none of them are called, they all get discarded
// and there is no remaining caller.
var b = new Fiber { a.run }
var c = new Fiber { b.run }
c.run
var b = new Fiber { a.run() }
var c = new Fiber { b.run() }
c.run()
+3 -3
View File
@@ -6,9 +6,9 @@ var fiber = new Fiber {
IO.print("fiber 3")
}
var result = fiber.call // expect: fiber 1
var result = fiber.call() // expect: fiber 1
IO.print(result) // expect: yield 1
result = fiber.call // expect: fiber 2
result = fiber.call() // expect: fiber 2
IO.print(result) // expect: yield 2
result = fiber.call // expect: fiber 3
result = fiber.call() // expect: fiber 3
IO.print(result) // expect: null
@@ -4,6 +4,6 @@ var a = new Fiber {
// Run a chain of fibers. Since none of them are called, they all get discarded
// and there is no remaining caller.
var b = new Fiber { a.run }
var c = new Fiber { b.run }
c.run
var b = new Fiber { a.run() }
var c = new Fiber { b.run() }
c.run()
+3 -3
View File
@@ -11,6 +11,6 @@ class Foo {
}
var foo = new Foo
IO.print(foo.closeOverGet.call) // expect: Foo field
foo.closeOverSet.call
IO.print(foo.closeOverGet.call) // expect: new value
IO.print(foo.closeOverGet.call()) // expect: Foo field
foo.closeOverSet.call()
IO.print(foo.closeOverGet.call()) // expect: new value
+1 -1
View File
@@ -4,7 +4,7 @@ for (i in [1, 2, 3]) {
list.add(new Fn { IO.print(i) })
}
for (f in list) f.call
for (f in list) f.call()
// expect: 1
// expect: 2
// expect: 3
+1 -1
View File
@@ -5,7 +5,7 @@ for (i in [1, 2, 3]) {
list.add(new Fn { IO.print(j) })
}
for (f in list) f.call
for (f in list) f.call()
// expect: 2
// expect: 3
// expect: 4
+1 -1
View File
@@ -3,7 +3,7 @@ var f = new Fn {
return [1, 2, 3]
}
for (i in f.call) IO.print(i)
for (i in f.call()) IO.print(i)
// expect: evaluate sequence
// expect: 1
// expect: 2
+2 -2
View File
@@ -4,6 +4,6 @@ var f = new Fn {
}
}
var g = f.call
g.call
var g = f.call()
g.call()
// expect: 1
+1 -1
View File
@@ -4,5 +4,5 @@ var f = new Fn {
}
}
IO.print(f.call)
IO.print(f.call())
// expect: 1
+1 -1
View File
@@ -1,2 +1,2 @@
var f = new Fn {}
IO.print(f.call) // expect: null
IO.print(f.call()) // expect: null
+1 -1
View File
@@ -1,4 +1,4 @@
var f = new Fn {
// Hi.
}
IO.print(f.call) // expect: null
IO.print(f.call()) // expect: null
@@ -1,5 +1,5 @@
new Fn { IO.print("ok") // expect error
}.call // expect error
}.call() // expect error
// The second error is cascaded here. If it starts failing, just remove that
// expectation.
+1
View File
@@ -0,0 +1 @@
new Fn {|| null } // expect error
+1 -1
View File
@@ -1,5 +1,5 @@
var f0 = new Fn { 0 }
IO.print(f0.call) // expect: 0
IO.print(f0.call()) // expect: 0
var f1 = new Fn {|a| a }
IO.print(f1.call(1)) // expect: 1
+4 -4
View File
@@ -1,16 +1,16 @@
// Single expression body.
new Fn { IO.print("ok") }.call // expect: ok
new Fn { IO.print("ok") }.call() // expect: ok
// Curly body.
new Fn {
IO.print("ok") // expect: ok
}.call
}.call()
// Multiple statements.
new Fn {
IO.print("1") // expect: 1
IO.print("2") // expect: 2
}.call
}.call()
// Extra newlines.
new Fn {
@@ -22,4 +22,4 @@ new Fn {
IO.print("2") // expect: 2
}.call
}.call()
@@ -26,11 +26,11 @@ class Bar is Foo {
}
var bar = new Bar
IO.print(bar.closeOverFooGet.call.call) // expect: Foo field
IO.print(bar.closeOverBarGet.call.call) // expect: Bar field
bar.closeOverFooSet.call.call
IO.print(bar.closeOverFooGet.call.call) // expect: new foo value
IO.print(bar.closeOverBarGet.call.call) // expect: Bar field
bar.closeOverBarSet.call.call
IO.print(bar.closeOverFooGet.call.call) // expect: new foo value
IO.print(bar.closeOverBarGet.call.call) // expect: new bar value
IO.print(bar.closeOverFooGet.call().call()) // expect: Foo field
IO.print(bar.closeOverBarGet.call().call()) // expect: Bar field
bar.closeOverFooSet.call().call()
IO.print(bar.closeOverFooGet.call().call()) // expect: new foo value
IO.print(bar.closeOverBarGet.call().call()) // expect: Bar field
bar.closeOverBarSet.call().call()
IO.print(bar.closeOverFooGet.call().call()) // expect: new foo value
IO.print(bar.closeOverBarGet.call().call()) // expect: new bar value
+1 -1
View File
@@ -1009,5 +1009,5 @@ new Fn {
IO.print(9) // expect: 9
IO.print(10) // expect: 10
// 1000
}.call
}.call()
+1 -1
View File
@@ -65537,4 +65537,4 @@ var f = new Fn {
IO.print(65536)
}
f.call // expect: 65536
f.call() // expect: 65536
+2 -2
View File
@@ -1,7 +1,7 @@
var a = [1, 2, 3]
a.clear
a.clear()
IO.print(a) // expect: []
IO.print(a.count) // expect: 0
// Returns null.
IO.print([1, 2].clear) // expect: null
IO.print([1, 2].clear()) // expect: null
+2 -2
View File
@@ -1,7 +1,7 @@
var a = {1: 1, 2: 2, 3: 3}
a.clear
a.clear()
IO.print(a) // expect: {}
IO.print(a.count) // expect: 0
// Returns null.
IO.print({1: 2}.clear) // expect: null
IO.print({1: 2}.clear()) // expect: null
+4 -2
View File
@@ -1,5 +1,6 @@
class Foo {
method { 0 }
method { "getter" }
method() { "no args" }
method(a) { a }
method(a, b) { a + b }
method(a, b, c) { a + b + c }
@@ -19,7 +20,8 @@ class Foo {
}
var foo = new Foo
IO.print(foo.method) // expect: 0
IO.print(foo.method) // expect: getter
IO.print(foo.method()) // expect: no args
IO.print(foo.method(1)) // expect: 1
IO.print(foo.method(1, 2)) // expect: 3
IO.print(foo.method(1, 2, 3)) // expect: 6
+3
View File
@@ -0,0 +1,3 @@
var list = [1, 2]
list[] // expect error
"don't actually want error here, but cascades from above" // expect error
@@ -0,0 +1,3 @@
class Foo {
[] { "empty" } // expect error
}
+1 -1
View File
@@ -14,5 +14,5 @@ IO.print(Nonlocal) // expect: method
new Fn {
Nonlocal = "fn"
}.call
}.call()
IO.print(Nonlocal) // expect: fn
+1 -1
View File
@@ -2,4 +2,4 @@ var Global = "global"
new Fn {
IO.print(Global) // expect: global
}.call
}.call()
@@ -4,4 +4,4 @@ var f = new Fn {
var Global = "global"
f.call // expect: global
f.call() // expect: global
+1 -1
View File
@@ -1,3 +1,3 @@
IO.print(new Fn {
if (false) "no" else return "ok"
}.call) // expect: ok
}.call()) // expect: ok
+1 -1
View File
@@ -1,3 +1,3 @@
IO.print(new Fn {
if (true) return "ok"
}.call) // expect: ok
}.call()) // expect: ok
+1 -1
View File
@@ -1,3 +1,3 @@
IO.print(new Fn {
while (true) return "ok"
}.call) // expect: ok
}.call()) // expect: ok
+1 -1
View File
@@ -3,4 +3,4 @@ var f = new Fn {
IO.print("bad")
}
IO.print(f.call) // expect: ok
IO.print(f.call()) // expect: ok
+1 -1
View File
@@ -3,4 +3,4 @@ var f = new Fn {
IO.print("bad")
}
IO.print(f.call) // expect: null
IO.print(f.call()) // expect: null
+3 -3
View File
@@ -11,6 +11,6 @@ class Foo {
}
Foo.initialize
IO.print(Foo.closeOverGet.call) // expect: Foo field
Foo.closeOverSet.call
IO.print(Foo.closeOverGet.call) // expect: new value
IO.print(Foo.closeOverGet.call()) // expect: Foo field
Foo.closeOverSet.call()
IO.print(Foo.closeOverGet.call()) // expect: new value
+1 -1
View File
@@ -8,4 +8,4 @@ class Derived is Base {
}
var closure = (new Derived).getClosure
IO.print(closure.call) // expect: Base
IO.print(closure.call()) // expect: Base
+1 -1
View File
@@ -4,4 +4,4 @@ class Foo {
}
var closure = (new Foo).getClosure
IO.print(closure.call) // expect: Foo
IO.print(closure.call()) // expect: Foo
+1 -1
View File
@@ -13,7 +13,7 @@ class Outer {
}
(new Inner).method
}.call
}.call()
}
toString { "Outer" }
+1 -1
View File
@@ -4,4 +4,4 @@ class Foo {
}
var closure = (new Foo).getClosure
IO.print(closure.call.call.call) // expect: Foo
IO.print(closure.call().call().call()) // expect: Foo
+1 -1
View File
@@ -1,3 +1,3 @@
new Fn {
IO.print(notDefined) // expect error
}.call
}.call()
+1 -1
View File
@@ -7,7 +7,7 @@ while (i < 4) {
i = i + 1
}
for (f in list) f.call
for (f in list) f.call()
// expect: 2
// expect: 3
// expect: 4
+2 -2
View File
@@ -5,6 +5,6 @@ var f = new Fn {
}
}
var g = f.call
g.call
var g = f.call()
g.call()
// expect: i
+1 -1
View File
@@ -5,5 +5,5 @@ var f = new Fn {
}
}
IO.print(f.call)
IO.print(f.call())
// expect: i