This is a beautiful, classic compiler sanity check. It targets Operator
Precedence.
Because our AST's resolve_precedences method explicitly assigns multiplication
(*) a priority of 6 and addition (+) a priority of 5, the AST will
automatically pluck b * c into a sub-node before evaluating the a + ...
branch.
If you run node harness.js tests/int.c right now, your current engine will
actually execute it perfectly out of the box and print X: 7, because
JavaScript handles basic arithmetic precedence exactly like C!
However, stepping into strict int testing exposes the fundamental difference
between C and JavaScript that we now need to tame: JavaScript does not have
integers, only floats.
The Integer Trap in JS
If your test file instead contained:
int a = 5;
int b = 2;
int x = a / b;
printf("X: %d
", x);
Your C-based gd engine would evaluate x as 2.
Node.js will evaluate x as 2.5.
To strictly enforce LPC's type system in a dynamic JS environment, we need to
do two things:
1. Update the Runtime Printf (The quick fix):
Currently, our rt.printf regex catches %d but just returns the raw JS value.
We should enforce integer casting at the display level. Inside your
JSCodeGenerator.generateRuntime(), we can update the printf switch:
let res = fmt.replace(/%([sdcf])/g, (match, type) => {
let val = args[i++];
if (type === 'c') return String.fromCharCode(val);
if (type === 'f') return Number(val).toFixed(6);
if (type === 'd') return Math.trunc(Number(val)); // Force LPC
integer truncation!
if (type === 's') { val = String(formatValue(val)); let nullIdx =
val.indexOf(String.fromCharCode(0)); return nullIdx !== -1 ? val.substring(0,
nullIdx) : val; }
return val;
});
2. Update the AST Operator Resolver (The deep fix):
To ensure mathematical operations actually behave like C, we can instruct the
JSCodeGenerator to check the resolved_type of the tokens. If the AST detects
division (/) occurring between two int types, we can wrap the generated JS
expression in Math.trunc(...) to mimic C-style integer truncation during the
actual assignment, rather than just during formatting.
Go ahead and run node harness.js tests/int.c to verify the baseline works. Do
you want to augment the test file with division (/) so we can build out the
AST's strict integer-casting rules?