The funcoverride option allows defining multiple functions with the same name, each overriding the former. That's for compatibility with Firestorm, whose optimizer does that.
While on it, fix a bug where defining a function whose name matches a library function was not reporting an error, and rename self.functions to self.funclibrary for clarity. It also brings consistency with other parts of the code and with the code documentation.
Adds a new tree node type, SUBIDX, which hopefully should never appear in actual output. If it does, it's prefixed with the string (MISSING TYPE) as a cue to the programmer.
There was a time where I decided that the tree would be stored inside the symbol table, as values for the global symbols. I changed my mind later and separated them, but that comment remained.
First, a string does not have its own context, it's a regular expression, therefore if there isn't a matching closing quote until EOF, it's not an unterminated string. It plainly *isn't* a string.
Second, the string lexer searches for either the regexp '[^"\\]' (any character except a double quote or a backslash) or the regexp '\\.', that is, a backslash followed by an "any character" meta. But the "any character" meta does NOT match a newline. The consequence is that a '\' followed by a newline cancels the matching, and the whole thing is not considered a string.
Isolated double quotes are then plain ignored as many other characters.
An example illustrating both cases:
```
default
{
state_entry()
{
string msg = "Hello, Avatar!";
llOwnerSay"(msg); // the opening quote will be ignored
// the following backslash at EOL cancels the previous double quote: \
llOwnerSay(llGetKey(")); // Unterminated string; unmatched so ignored.
}
}
```
The output module adds parentheses where necessary, depending on the evaluation order in the tree. Or that's the idea. Prone to bugs, let's see how it bodes.
- Fix a bunch of bugs found during the debut of the LSL calculator.
- Add infrastructure for functions to be able to produce a result or not depending on arguments. Fixes the llBase64ToInteger/llXorBase64/llXorBase64StringsCorrect cases where they are not deterministic, and allows for the addition of some extra functions whose value can be determined in some cases (e.g. llDetectedType(-1) is always 0). Added several such functions in a new module.
- Add the constant folding option to the help and the default options.
As an additional bonus, the condition folding function is now the one that converts a condition to -1, relieving that burden from the rest of the code and simplifying tests.
Add corresponding tests too. Simplify the identifier renaming coverage test. Also remove extra newlines from library reading code.
We've had to give up on the 'else if' loop-instead-of-recurse optimization, to properly propagate the LastWasReturn flag.
There's also a new hidden option, shrinknames, which automatically enables duplabels due to its nature. The idea is that once general renaming is implemented, in order for label names to not cause collision trouble, they are renamed out of the way with unique names.
Not entirely sure this is really necessary.
When disabled, it now disallows duplicate labels. The plan is that when enabled, it will auto-rename labels so that there are no repetitions within a function.
Add coverage tests too, and also a coverage test that was missed after the latest changes.