I went on to take that code and get it mechanically wired up in a way that split it into a “console kernel” which would make deliberate transitions to calling the usermode “skin” code–and hence be able to gracefully recover from errors, vs. infinite loop or crash out. For example:
>> system/console/print-prompt: does [write-stdout "--ok-->> "] == make action! [ [...]] --ok-->> system/console/print-prompt: does [write-stdddout "--oops!--> "] ** UNSAFE ERROR ENCOUNTERED IN CONSOLE SKIN ** Script Error: write-stdddout has no value ** Where: print-prompt console ** Near: [write-stdddout ~~ "--oops!--> "] ** Line: 1 ** REVERTING TO DEFAULT SKIN >>
(Note: the current error is a bit more verbose than that because it’s trying to be informative for debugging of console internals, but I’ll cut it down.)
Despite running with a lot of userspace code, the console is designed so it can be phased in such a way that when you do things like a debug trace (also written in usermode) you won’t wind up tracing through the console as well. (Unless you want to–but most people wouldn’t, they want to trace their own code.) Because of how it’s done, you also don’t see a ton of implementation stacks for the console in your backtrace…the console exits its “usermode kernel” portion long enough to run skin or user requests through the libRebol API with no kernel on the stack, and then re-enters the kernel after it’s done.
Laying the groundwork for doing this correctly is intended to make it possible to let the console be hookable for all kinds of tasks, whether that’s debugging and needing to show you stack levels and bind stack frames…or anything else! That includes a tutorial console, that checks what you typed and the result you got to see if you should go to the next step!
And now… the web REPL uses it too!
In quite a nifty achievement for the console, it is now live in the web demo!
For the moment, that means you can even use the conventional multi-line-by-hitting-enter mode, instead of Shift-Enter. Really it should kick you over into the web’s multiline editor ability…but that should be easier to do as an aspect of the console extension, it’s all usermode code!
Here’s a little counting console:
>> count: 0 == 0 >> system/console/print-prompt: does [ [\ count: count + 1 [\ write-stdout unspaced [count ">> "] [\ ] == make action! [ [...]] 1>> print "A counting prompt!" A counting prompt! 2>>
You can imagine being able to flip your console mode around to all kinds of things… changing the bindings, being dialected. (The debugger will have a frame it is “focused” on and show you the focus, but then use that frame for binding of expressions–for instance.) Timing prompts could show you how long each command took, or just hook each command prompt to make the timing so you could ask for it retroactively if you ever cared…
It doesn’t have cancellation yet (and if it did, it probably would want to be Escape vs. Ctrl-C). Such things are actually rather complex to do–but of course, solving it is planned for and in the works.
This is really neat to see, hopefully people want to pitch in and make this better. This isn’t C code, so no excuses!