Skip to content

Commit ad98d1a

Browse files
committed
feat: add 'recover' and 'retval' builtin functions
1 parent cfcda42 commit ad98d1a

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

argon/vm/mod/builtins.cpp

+56
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,60 @@ ARGON_FUNCTION(builtins_require, require,
292292
return (ArObject *) result;
293293
}
294294

295+
ARGON_FUNCTION(builtins_recover, recover,
296+
"Recover from a panic and retrieve the panic value.\n"
297+
"\n"
298+
"This function must be called inside a defer block. It stops the panic\n"
299+
"propagation and returns the panic value (usually an error object).\n"
300+
"\n"
301+
"If there is no active panic, recover() returns nil.\n"
302+
"\n"
303+
"Usage:\n"
304+
" Inside a defer block, call recover() to handle panics:\n"
305+
" - If a panic occurred, recover() returns the panic value and stops the panic.\n"
306+
" - If no panic occurred, recover() returns nil.\n"
307+
"\n"
308+
"- Returns: The panic value if a panic is active, otherwise nil.\n",
309+
nullptr, false, false) {
310+
auto *err = argon::vm::GetLastError();
311+
if (err != nullptr)
312+
return err;
313+
314+
return ARGON_NIL_VALUE;
315+
}
316+
317+
ARGON_FUNCTION(builtins_retval, retval,
318+
"Get or set the return value of the function that invoked the current defer block.\n"
319+
"\n"
320+
"This function can only be called inside a defer block. It affects the return value\n"
321+
"of the function that is executing the defer, not the defer function itself.\n"
322+
"\n"
323+
"If called without arguments, returns the current return value of the calling function.\n"
324+
"If called with an argument, sets the return value of the calling function to that argument.\n"
325+
"\n"
326+
"- Parameter value: Optional. The new return value to set for the calling function.\n"
327+
"- Returns: The current return value of the calling function.\n",
328+
nullptr, true, false) {
329+
auto *fiber = argon::vm::GetFiber();
330+
auto *frame = fiber->frame;
331+
332+
if (!VariadicCheckPositional((const char *) ARGON_RAW_STRING(((Function *) _func)->name), argc, 0, 1))
333+
return nullptr;
334+
335+
auto *back = frame->back;
336+
if (back == nullptr)
337+
return ARGON_NIL_VALUE;
338+
339+
if (argc == 0)
340+
return NilOrValue(back->return_value);
341+
342+
auto *old = NilOrValue(back->return_value);
343+
344+
back->return_value = IncRef(args[0]);
345+
346+
return old;
347+
}
348+
295349
ARGON_FUNCTION(builtins_show, show,
296350
"Returns a list of names in the local scope or the attributes of the instance.\n"
297351
"\n"
@@ -433,7 +487,9 @@ const ModuleEntry builtins_entries[] = {
433487
MODULE_EXPORT_FUNCTION(builtins_iscallable),
434488
MODULE_EXPORT_FUNCTION(builtins_implements),
435489
MODULE_EXPORT_FUNCTION(builtins_len),
490+
MODULE_EXPORT_FUNCTION(builtins_recover),
436491
MODULE_EXPORT_FUNCTION(builtins_require),
492+
MODULE_EXPORT_FUNCTION(builtins_retval),
437493
//MODULE_EXPORT_FUNCTION(builtins_repr),
438494
MODULE_EXPORT_FUNCTION(builtins_show),
439495
//MODULE_EXPORT_FUNCTION(builtins_str),

0 commit comments

Comments
 (0)