user@elli:~/Downloads/Remote/LPC/GEM$ cat tests/catch.c
void create ()
{
mixed err;
err = catch (fun ());
if (err)
{
printf ("Error: %s
", err);
}
else
printf ("No error
");
if (catch (throw ("caught throw")))
printf ("Got it!
");
throw ("non-caught throw");
}
void fun ()
{
printf (" .. inside fun()
");
fun2 ();
printf (" .. exiting fun()
");
}
void fun2 ()
{
throw ("xyz");
}
user@elli:~/Downloads/Remote/LPC/GEM$
==
This is the perfect test for Exception Handling.
You'll be happy to hear that JavaScript's native try...catch and throw
statements behave almost exactly identically to LPC's. The only architectural
difference is that in LPC, catch(...) is an expression that returns 0 on
success and the error string on failure, allowing you to use it inline like
this:
err = catch (fun ());
In JavaScript, try...catch is a statement, meaning you normally can't assign
its result directly to a variable inline.
The IIFE Trick
To bridge this gap, we can wrap the transpiled catch and throw calls in an
Immediately Invoked Function Expression (IIFE). This instantly turns JS
statements back into expressions that can be evaluated on the fly!
catch(expr) becomes (() => { try { expr; return 0; } catch(err) { return err;
} })()
throw(msg) becomes (() => { throw msg; })()
The Fix
We just need to add two lines to our AST's function-call router, and tweak our
runVM crash logger so that it handles thrown strings (since e.stack doesn't
exist when you throw a primitive string instead of an Error object).
1. Update JSCodeGenerator
In your harness.js, find the function-call block inside the output_token
method and add the new AST macros for catch and throw
==
2. Update runVM
At the very bottom of harness.js, slightly adjust the catch (e) block to
fallback to e if e.stack is missing
==
Run node harness.js tests/catch.c.
You should see it cleanly catch the "xyz" error thrown deep from within
fun2(), perfectly resolve the inline catch expression Got it!, and then
gracefully terminate by passing "non-caught throw" up to the Virtual Machine's
root crash handler!
We are so close to the finish line. Do you have a test for Function Closures
or the Preprocessor next?