Allow passing a value when first starting a fiber.

If the function the fiber is created from takes a parameter, the value
passed to the first call() or transfer() gets bound to that parameter.

Also, this now correctly handles fibers with functions that take
parameters. It used to leave the stack in a busted state. Now, it's a
runtime error to create a fiber with a function that takes any more
than one parameter.
This commit is contained in:
Bob Nystrom
2017-10-19 20:45:13 -07:00
parent e043a95e4e
commit 1661f5368f
12 changed files with 182 additions and 86 deletions

View File

@ -3,5 +3,5 @@ var fiber = Fiber.new {
}
System.print("before") // expect: before
fiber.call() // expect: fiber
fiber.call() // expect: fiber
System.print("after") // expect: after

View File

@ -0,0 +1,7 @@
var fiber = Fiber.new {|value|
System.print(value)
}
System.print("before") // expect: before
fiber.call() // expect: null
System.print("after") // expect: after

View File

@ -2,8 +2,6 @@ var fiber = Fiber.new {
System.print("fiber")
}
// The first value passed to the fiber is ignored, since there's no yield call
// to return it.
System.print("before") // expect: before
fiber.call("ignored") // expect: fiber
System.print("after") // expect: after
System.print("before") // expect: before
fiber.call("value") // expect: fiber
System.print("after") // expect: after

View File

@ -0,0 +1,7 @@
var fiber = Fiber.new {|value|
System.print(value)
}
System.print("before") // expect: before
fiber.call("value") // expect: value
System.print("after") // expect: after

View File

@ -0,0 +1 @@
var fiber = Fiber.new {|a, b| null } // expect runtime error: Function cannot take more than one parameter.

View File

@ -0,0 +1,24 @@
var a = Fiber.new {|param|
System.print("a %(param)")
}
var b = Fiber.new {|param|
System.print("b before %(param)")
a.transfer()
System.print("b after")
}
var c = Fiber.new {|param|
System.print("c before %(param)")
b.transfer()
System.print("c after")
}
System.print("start") // expect: start
c.transfer()
// expect: c before null
// expect: b before null
// expect: a null
// Nothing else gets run since the interpreter stops after a completes.

View File

@ -0,0 +1,24 @@
var a = Fiber.new {|param|
System.print("a %(param)")
}
var b = Fiber.new {|param|
System.print("b before %(param)")
a.transfer("from b")
System.print("b after")
}
var c = Fiber.new {|param|
System.print("c before %(param)")
b.transfer("from c")
System.print("c after")
}
System.print("start") // expect: start
c.transfer("from main")
// expect: c before from main
// expect: b before from c
// expect: a from b
// Nothing else gets run since the interpreter stops after a completes.

View File

@ -7,8 +7,8 @@ var fiber = Fiber.new {
}
System.print(fiber.call()) // expect: fiber 1
// expect: yield 1
// expect: yield 1
System.print(fiber.call()) // expect: fiber 2
// expect: yield 2
// expect: yield 2
System.print(fiber.call()) // expect: fiber 3
// expect: null
// expect: null