Closed jason-c-daniels closed 7 years ago
This is the intended behaviour, for simplicity's sake (one of the project's goal is that of minimalism and simplicity) I'm not keen for any additional complexity to be added to the function.
If you want to exit immediately out of aria and back to the caller you can use the error()
function to raise an error, the value of which will be propagated up the stack -- any value type can be used as an error, allowing you to choose something easily-identifiable for this purpose. The error value can then be handled using the ar_try()
macro in C. If you use pcall
anywhere in the code it will also have to propagate this value in its error handler.
Additionally you can overwrite aria's exit
function to inherit whatever behaviour you want -- for example, calling a clean-up callback then calling C's exit
.
Perhaps I'm not following you all that well. I just tried using (error "bleh")
in the standalone/interactive app provided with aria.c
. It didn't exit the main loop.
So let me rephrase this, what I'm looking for is a way for the aria subsystem to terminate operation and to provide some result code...etc. to the host application, even from within an infinite loop in the script. The host app may or may not continue running after the aria subsystem terminates.
Without changing aria, is this currently possible? (i.e. is there something I can type, apart from (exit)
in the interactive mode, which will cause it to terminate?)
(let (exit-val (cons))
(= exit2 (fn (val)
(setcar exit-val t)
(setcdr exit-val val)
(error exit-val)))
(while (is nil (car exit-val))
(pcall
(fn () (print (eval (parse (readline)) global)))
(fn (err tr)
(if (is nil (is err exit-val)) (do
(print \"error:" err)
(print "traceback:")
(while tr
(print (string " [" (dbgloc (car tr)) "] "
(substr (string (car tr)) 0 50)))
(= tr (cdr tr))))))))
(print "exiting..." (cdr exit-val)))
Here's an example of what I meant -- calling (exit2 [val])
sets the pair exit-val
's car to t
and sets its cdr to val
(which you can use for whatever purpose you want). It then raises an error which causes the program to jump to the error handler, which, seeing the exit-val
was raised, doesn't print the error/traceback. while
then exits its loop because exit-val
's car is no-longer nil
.
I gotcha now. The check has to be built into each loop scripted in aria. Therefore, not a true infinite loop that's being interrupted. BUT, this should be an acceptable workaround.
The check has to be built into each loop scripted in aria
exit-val
only has to be propagated in every error handler -- in this case the error handler exists in that loop and sets its outer loop to exit, so the loop can continue to handle regular errors as it normally would. For example, typing:
(while 1 (print "hello") (exit2 "xyz"))
Would exit as expected
Problem: Calling
(exit)
in the aria code kills the host application. This happens because(exit)
calls the c-languageexit
function.Proposed Solution
int in_shutdown
flag andint exit_code
member toar_State
will allow the hosting application to examine the result. (For more complex results consider usingar_Value*
for the result code instead.)