Also simplify and fix the matching expression for #line (gcc inserts numeric flags at the end).
It still has many problems. It's O(n^2). It's calculated at every EParse, and EParse can be triggered and ignored while scanning vectors or globals. UniConvScript doesn't read #line at all, thus failing to report a meaningful input line. But at least it's a start.
ReportError() needed to account for terminal encodings that don't support the characters being printed. It was also reporting an inaccurate column number and its corresponding marker position, because the count was in bytes, not in characters, so that has been fixed.
Now EParse.__init__() calls a new function GetErrLineCol() that calculates the line and column corresponding to an error position.
The algorithm for finding the start of the line has also been changed in both ReportError() and EParse.__init__(); as a result, function fieldpos() has been removed.
The exception's lno and cno fields have been changed to be 1-based, rather than 0-based.
Thanks to @Jomik for the report. Fixes#5.
lslcleanup: Variables renamed, order changed, comments added.
Other changes: remove semicolon at end of sentence, use self.Cast instead of creating a CAST node on the fly.
That's exactly what 'cond' is for. Things like a loop with a constant zero vector condition should be recognized.
It was correct before just by chance, because FoldCond currently transforms a constant node into an integer node, but let's not rely on that.
When the index is good, on non-touch functions:
- llDetectedTouchFace returns -1.
- llDetectedTouchST and llDetectedTouchUV return TOUCH_INVALID_TEXCOORD.
We were returning 0 and ZERO_VECTOR respectively.
No other functional changes. This required quite some reorganization affecting many files. As a side effect, PythonType2LSL and LSLType2Python aren't duplicate anymore.
- Resolve for lists that aren't constants, but that are SEF, and reference a constant element, e.g. llList2String([llGetKey(), 5], 1) -> 5.
- Make it work with invalid conversions, if they are SEF.
- Simplify invalid conversions when the list argument is a llGetObjectDetails call and SEF.
- Simplify llList2String(llGetObjectDetails(id, [single_element]), 0) (or -1) to (string)llGetObjectDetails...; same with llList2Key and llList2Integer, converting it to (integer)((string)llGetObjectDetails...).
- Add TODO item to do it similarly for llGet[Link]PrimitiveParams.
Adds auxiliary functions to return a node or constant from a list in any of its forms, its length, and a constant for a node or constant.
Adds some utility members for LSL<->Python type conversion (one of them duplicated from lslparse.py).
Needs maintenance of the types returned by llGetObjectDetails.
if(list!=[]) is always better than if(list), which compiles to if(!(list==[])).
if(float) can't be optimized, but it is equivalent to if(float!=0.0) which can. Same for vector, rotation.
It was failing with a && b && c where a, b, c were known to be bools. It managed to simplify them to a & b & -c but that's not optimal.
Now it recurses on some operators that may return bool when used with bool operands: &, |, ^, * (in the case of &, it's bool if either operand is; for the rest, it's bool if both are). As a result, the above now simplifies to a & b & c, which is optimal.
Adds a new EParseInvalidBrkContArg exception. Previously it raised EParseInvalidBreak or EParseInvalidCont, whose text was misleading for this type of error.
We were letting Python typecast, and that causes the wrong result on Windows. Return the correct result explicitly when "nan" is found in the string.
Also, small reformatting of an else if -> elif.