This is interesting:
user@elli:~/Downloads/Remote/LPC/GEM$ cat tests/mixed.c
void create ()
{
array pos;
pos = ({ 150.0, 120.0, 90.0 });
printf ("pos: %s
", pos);
pos [0] += (random (51) - 25);
printf ("pos: %s
", pos);
}
user@elli:~/Downloads/Remote/LPC/GEM$
==
This is a fantastic test file because it quietly exposes a massive hidden bug
in the JS Code Generator we built in the last phase!
If you were to run node harness.js tests/mixed.c right now, the VM would
violently crash.
The Hidden Array Bug
In Phase 11, we cleverly instructed the AST to transpile += and -= into
JavaScript .push() and .filter() so that LPC array math works natively.
However, look at this line in the test:
pos [0] += (random (51) - 25);
The left side of the += operator is pos[0]. In this case, pos[0] is the float
150.0. If our JS backend blindly assumes all += operators belong to arrays, it
will attempt to evaluate pos[0].push(random...) and instantly trigger a
TypeError: pos[0].push is not a function!
Because variables in LPC can be implicitly typed (or declared as mixed), the
JS Code Generator cannot know at compile time whether += is operating on an
Array or a Number. It has to decide dynamically at runtime.
The Fix
We need to introduce two things to our JSCodeGenerator:
The random() efun: We'll add a native JS random number generator to the rt
runtime object.
Runtime Type-Checking for +=: We'll rewrite the += and -= emission so that V8
dynamically checks Array.isArray(left) before executing the operator. If it's
an array, it pushes. If it's a number or string, it falls back to native math
addition.
==
Run node harness.js tests/mixed.c. You should see it evaluate perfectly and
offset the first float element by a random integer!
Run node harness.js tests/mixed.c. You should see it evaluate perfectly and
offset the first float element by a random integer!
user@elli:~/Downloads/Remote/LPC/GEM$ node harness.js tests/mixed.c
[+] Compiling tests/mixed.c into VM Memory...
[+] Launching Javascript V8 Native Environment...
--- BOOTING VM ---
pos: ({ 150, 120, 90 })
pos: ({ 152, 120, 90 })
pos: ({ 152, 120, 90 }) [VM HALTED CLEANLY]
user@elli:~/Downloads/Remote/LPC/GEM$ node harness.js tests/mixed.c
[+] Compiling tests/mixed.c into VM Memory...
[+] Launching Javascript V8 Native Environment...
--- BOOTING VM ---
pos: ({ 150, 120, 90 })
pos: ({ 146, 120, 90 })
pos: ({ 146, 120, 90 }) [VM HALTED CLEANLY]
user@elli:~/Downloads/Remote/LPC/GEM$