It's great to see you again! Sometimes I've wondered about the status of Semi-Arc. Looks like you've been working on a number of other Lisp implementations in the meantime! Pretty exciting. Thanks for sharing this update with us.
As someone who ported Rainbow line by line to JavaScript, I have to say, the size of the codebase can be quite daunting. A smaller implementation sounds a lot easier to work on.
case ContOp.ApplyFun: // exp2 is a function.
[exp, env] = applyFunction(exp2, args, k, env);
if (exp instanceof Promise)
exp = await exp;
break;
This means the web page is still interactive during the evaluation effectively.
Here is an example: https://nukata.github.io/little-scheme-in-typescript/example.
Click the "Load" button twice and you will see two "yin-yang puzzle" threads run on the page.
Click the "Stop at Writing" button twice to stop them.