jscl
jscl copied to clipboard
Catching unbound-variable in JSCL
I want to load a code dynamically from remote server via websocket. The idea is to catch unbound-variable and undefined-function conditions and ask remote server for missing variables and functions code.
In SBCL I can use the following code to catch the exception:
(handler-bind
((unbound-variable
(lambda (c)
(print c)
(eval `(defvar ,(cell-error-name c) "XXXX"))
(continue c))))
(print "AAA")
(print x11xxaaa)
(print "BBB"))
The result is:
"AAA"
#<UNBOUND-VARIABLE X11XXAAA {100335EA13}>
"XXXX"
"BBB"
But in JSCL this code not working:
"AAA"
ERROR: Variable X11XXAAA is unbound.
I'm tried to use just error
instead of unbound-variable
(this also works in SBCL):
(handler-bind
((error
(lambda (c)
(print c)
(eval `(defvar ,(cell-error-name c) "XXXX"))
(continue c))))
(print "AAA")
(print x11xxaa)
(print "BBB"))
but got:
"AAA"
#<structure !condition>
ERROR: Function 'CELL-ERROR-NAME' undefined
Is there a way to catch undefined-variable
in JSCL, define a new var and continue execution?
Interesting use case!
Unfortunately, as of now, the error for unbound variables is a generic error:
https://github.com/jscl-project/jscl/blob/master/src/prelude.js#L331-L338
actually, most errors signaled by the implementation are those generic unstructured errors, as the condition system is implemented at the library level.
It does not seem that hard to change though. In case somebody wants to tackle this, what can be done is to define a temporary function in prelude.js
. The compiler would generate code to call it when a symbol is unbound. It can be a very simple function initially (for bootstrapping), and then it can be redefined by
https://github.com/jscl-project/jscl/blob/master/src/conditions.lisp
A similar trick is already done with eval_in_lisp
in prelude.js.
I looked at the condition.lisp
and did not see any code for restarts. There is no way to continue execution after an error?
They are restartable. But only if they are trigger with signal
from conditions.lisp
.
The way this works is in %handler-bind
. By default a handler can just return to continue, or do a non-local exit to abort. restart-case
can be implemented on top of this. But it is not there yet, unfortunately.
restart
is possible and needs to be implemented.
But not right away.
Not all Common Lisp
design concepts fall on JS