From f5339993ceb063da48873578f66fd394c1bcfc0b Mon Sep 17 00:00:00 2001 From: Alexander Klingenbeck Date: Thu, 3 Dec 2020 17:21:37 +0100 Subject: [PATCH] Add support for Fiber.try(_) (#835) * Add support for Fiber.try(_) * Add documentation for Fiber.try(_) * Add another test for Fiber.try(_) --- doc/site/modules/core/fiber.markdown | 18 ++++++++++++++++++ src/vm/wren_core.c | 10 ++++++++++ test/core/fiber/try_value.wren | 12 ++++++++++++ test/core/fiber/try_value_yield.wren | 16 ++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 test/core/fiber/try_value.wren create mode 100644 test/core/fiber/try_value_yield.wren diff --git a/doc/site/modules/core/fiber.markdown b/doc/site/modules/core/fiber.markdown index f869abbb..904c9a6b 100644 --- a/doc/site/modules/core/fiber.markdown +++ b/doc/site/modules/core/fiber.markdown @@ -174,6 +174,24 @@ System.print("Caught error: " + error) If the called fiber raises an error, it can no longer be used. +### **try**(value) +Tries to run the fiber. If a runtime error occurs +in the called fiber, the error is captured and is returned as a string. +If the fiber is being +started for the first time, and its function takes a parameter, `value` is +passed to it. + +
+var fiber = Fiber.new {|value|
+  value.badMethod
+}
+
+var error = fiber.try("just a string")
+System.print("Caught error: " + error)
+
+ +If the called fiber raises an error, it can no longer be used. + ### **transfer**() **TODO** diff --git a/src/vm/wren_core.c b/src/vm/wren_core.c index 0aaf8c29..033351fa 100644 --- a/src/vm/wren_core.c +++ b/src/vm/wren_core.c @@ -191,6 +191,15 @@ DEF_PRIMITIVE(fiber_try) return false; } +DEF_PRIMITIVE(fiber_try1) +{ + runFiber(vm, AS_FIBER(args[0]), args, true, true, "try"); + + // If we're switching to a valid fiber to try, remember that we're trying it. + if (!wrenHasError(vm->fiber)) vm->fiber->state = FIBER_TRY; + return false; +} + DEF_PRIMITIVE(fiber_yield) { ObjFiber* current = vm->fiber; @@ -1235,6 +1244,7 @@ void wrenInitializeCore(WrenVM* vm) PRIMITIVE(vm->fiberClass, "transfer(_)", fiber_transfer1); PRIMITIVE(vm->fiberClass, "transferError(_)", fiber_transferError); PRIMITIVE(vm->fiberClass, "try()", fiber_try); + PRIMITIVE(vm->fiberClass, "try(_)", fiber_try1); vm->fnClass = AS_CLASS(wrenFindVariable(vm, coreModule, "Fn")); PRIMITIVE(vm->fnClass->obj.classObj, "new(_)", fn_new); diff --git a/test/core/fiber/try_value.wren b/test/core/fiber/try_value.wren new file mode 100644 index 00000000..9416fece --- /dev/null +++ b/test/core/fiber/try_value.wren @@ -0,0 +1,12 @@ +var fiber = Fiber.new {|v| + System.print("before") + System.print(v) + true.unknownMethod + System.print("after") +} + +System.print(fiber.try("value")) +// expect: before +// expect: value +// expect: Bool does not implement 'unknownMethod'. +System.print("after try") // expect: after try diff --git a/test/core/fiber/try_value_yield.wren b/test/core/fiber/try_value_yield.wren new file mode 100644 index 00000000..4a44d05c --- /dev/null +++ b/test/core/fiber/try_value_yield.wren @@ -0,0 +1,16 @@ +var fiber = Fiber.new {|v| + System.print("before") + System.print(v) + v = Fiber.yield() + System.print(v) + true.unknownMethod + System.print("after") +} + +fiber.try("value1") +// expect: before +// expect: value1 +System.print(fiber.try("value2")) +// expect: value2 +// expect: Bool does not implement 'unknownMethod'. +System.print("after try") // expect: after try