- Move TODO of <0 to !=-1 to boolean, as it's counter-productive otherwise.
- All a!=b except list!=list are equivalent to !(a==b).
- Change a>b to b<a to simplify cases to analize.
- Proper fall-through in some spots, or return in some others where it didn't apply.
- Simplify handling of a<-2147483648 as a&0, falling through, instead of coping with it ourselves.
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.
This allows better side-effect analysis, because 'return' is not side-effect free unless it's the last statement. But that's better handled in the dead code removal module, as the comment specifies.
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.
}
}
```