One reason is to make sense of how to run it: to determine what instructions to emit. This is the kind of analysis where you want to propagate constants (even if they're not flagged as compile-time), to drop dead code (if it can be can determined that it doesn't need to be executed), and so on. For this analysis, even if && evaluation isn't short-circuit, one can replace false && A with just false as long as you know A doesn't have side-effects, and at the very least one can replace:
if (CallA() && false)
{
CallB();
}
With just: CallA();
The other reason to analyze your source code is to provide some level of static information to the user, such as detecting in advance situations that don't make sense. If there is never a situation where the expression `okeoefkepofke[3.141592]` is acceptable, then it's usually a good idea to report it as such even if the expression is 100% dead code as far as execution goes. I would even go one step further and say that static analysis should also register that expression as a (read-only) use of the variable `okeoefkepofke` for purposes of "find all references" or "rename symbol" tools. if (false && okeoefkepofke[3.141592])
Why can't you check that using a float as an array index is a syntax error, no matter if it's going to be evaluated or not?Are multi-pass compilers not a thing any more?
TIL.
I just checked and it doesn't do that, so if it's just doing enough for syntax highlighting, yeah, a custom parser is probably the best way to go about that. Thanks.
a) a compiler that can recover from errors and continue to parse the rest of a file, to produce an AST of all the parts that make sense but error nodes for the bits that don't.
b) a compiler that can optionally not run some passes (like typechecking) so that an editor/treesitter can get an understanding of the structure of the code, but an actual compile will do more. (Actually, this should already happen, so language servers don't do optimisation or IL/bytecode/asm generation passes.)
Checking isn't evaluation. Short-circuiting and by a constant false doesn't mean we skip checks on the right hand side. The right hand side is dead code. We check dead code.
E.g.
if (false) { x = undefined_var; }
should diagnose the undefined_var before throwing away the dead code.(If such a diagnostic exists and would be applied to
if (global_var) { x = undefined_var; }
) "This is perfectly legitimate behaviour... BUT it would mean this would pass semantic checking as well: [...] So now we got this big piece of code that is wrong."
I don't follow. Wrong in what sense? Per the post it would compile and run just fine. If I comment out code so it's never run, it could be whatever I want. Maybe I write pseudocode and gradually uncomment it and turn it into C++ with CodeLLama. Why is Mr. Lernö butting in and telling me how to write code?I've gone back to C99. Sure, arrays aren't bounds checked, but I can write C so much faster than Zig that it doesn't matter.