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.
The reusable names table was being emptied as identifiers were used. This was sub-optimal for function parameters, because new identifiers would need to be created when exhausted.
Reset the reusable names list to a saved copy every time a new parameter list is started, in a similar fashion to what we did with the sequentially generated identifiers.
Commit 13f3c95 was clearly a step in the right direction. We had a test case that mistakenly relied on the broken behaviour that that commit fixed, for the constant values to remain in the output. That is clearly wrong, so we fix the test case to not rely on that.
Rather than using tuples for set belonging, use a frozen set. That eliminates the need to separate them by lengths.
Also, 'Pop' is not a reserved word. It's perfectly valid as a possible substitution identifier, so allow it. If used, it will go to the used words anyway and thus will be skipped by the sequential name generator.
The former ones don't match LSL's behaviour, in particular llRotBetween(<1,0,0>,<-1,0,0>) should return <0,0,1,0> but it didn't. Fix by using an algorithm that is closer to the one used by the sim.
We had too much precision. In LSL, llRound(0.49999997) gives 1, not 0, because the loss of precision after adding 0.5 to that makes the result 1. Fixed by converting to F32 prior to flooring.
LL's algorithm for llEuler2Rot involves calculating a rotation matrix from the Eulers, then transforming the rotation matrix to quaternion. This generates sign discrepancies with our direct quaternion calculation algorithm.
Fixed by making only the necessary calculations to find the correct sign. Unfortunately, they are still heavy (notably, six more trig functions).
Mainly, the input quaternion wasn't being normalized prior to using it for calculations, and that broke compatibility. But even then, sometimes the arc sine of a value greater than 1 could be calculated, so we clamp it.
For all zeros input, the result was <1,0,0,0> but we were producing <0,0,0,.5> because the first branch was taken. Fixed.
We forgot to take the square root when calculating the magnitude of the quaternion while normalizing. Fixed.
Use qnz instead of special casing.
LSL behaves as if it was ZERO_ROTATION instead, so we fix it by creating a function that returns ZERO_ROTATION when given <0,0,0,0>. Use it for llRot2{Fwd,Left,Up} as well.
llAbs(-2147483648) raises this:
System.OverflowException: Value is too small.
at System.Math.Abs (Int32 value) [0x00000] in <filename unknown>:0
at LindenLab.SecondLife.Library.llAbs (Int32 i) [0x00000] in <filename unknown>:0
So it's actually not computable. In LSO it returns -2147483648, though.
llGetSubString and llList2List could produce output longer than the input for some params. Fix that, and join the functions into one unique function for uniformity. Also, get rid of the special case of empty elements, because it can be treated properly by the general case, and it's not so common as to merit special attention.
When the input was of the form e.g. "%4%40", the second "%" was erroneously starting another quoted character. LSL doesn't behave that way: parsing resumes without starting another quoted character. Disturbingly, the expected result in the corresponding test was wrong. Fixed both the test case and the code to match actual LSL behaviour.
llBase64ToString hid another surprise: characters in range from U+0000 to U+001F are substituted by "?" except for tabs (\x09), form feeds (\x0A), shift ins (\x0F) and unit separators (\x1F), which were kept verbatim. So, mimic this behaviour.
There was a duplicate(ish) test, which tested float("nan") instead of NaN or Indet. On Windows it was not duplicate, because under Windows, float("nan") produces Indet, which was not tested. Change it to Indet so we know what we're testing.
When a function was successfully applied, the resulting constant node was not marked as side effect-free. This could potentially lead to poor optimization.
Testing shows that AGENT_LIST_xxx values are not used as a bitfield, but as an enum. There are only three possible valid values. Check only those three.