Commit graph

73 commits

Author SHA1 Message Date
Sei Lisa
f243f3a3c1 New copyright year 2019-01-01 22:54:34 +01:00
Sei Lisa
3542824d51 Add spaces after commas in vector/rotation constructors 2018-12-27 23:35:23 +01:00
Sei Lisa
fa547cd9e8 Add blank lines to make the output somewhat prettier
Add blank lines between functions, between functions and states, between variables and functions or states, between states, and between events.

Or more concisely: add blank lines between events and between all elements at the global level except between variables (that actually describes the algorithm).

Some test cases expected no newlines; fix them.
2018-12-23 18:12:10 +01:00
Sei Lisa
075d3aba0c Change the AST node type from dict to object
That was long overdue. Obviously, this is a large commit.

The new nr (node record) class has built-in dump capabilities, rather than using print_node().

SEF always exists now, and is a boolean, rather than using the existence of SEF as the flag. This was changed for sanity. However, other flags like 'X' are still possibly absent, and in some cases the absence itself has meaning (in the case of 'X', its absence means that the node has not yet been analyzed).

Similarly, an event is distinguished from a UDF by checking for the existence of the 'scope' attribute. This trick works because events are not in the symbol table therefore they have no scope. But this should probably be changed in future to something more rational and faster.

A few minor bugfixes were applied while going through the code.

- Some tabs used as Unicode were written as byte strings. Add the u'\t' prefix.
- After simplifying a%1 -> a&0, fold again the node and return. It's not clear why it didn't return, and whether it depended on subsequent passes (e.g. after DCR) for possibly optimizing out the result. Now we're sure.
- A few places lacked a SEF declaration.
- Formatting changes to split lines that spilled the margin.
- Some comment changes.
- Expanded lazy_list_set definition while adapting it to object format. The plan was to re-compress it after done, but decided to leave it in expanded form.
- Added a few TODOs & FIXMEs, resisting the temptation to fix them in the same commit:
  - TODO: ~-~-~-expr  ->  expr + -3.
  - FIXME: Now that we have CompareTrees, we can easily check if expr + -expr cancels out and remove a TODO. Low-hanging fruit.
  - TODO: Check what we can do when comparing non-SEF and non-CONST values in '>' (current code relies on converting '>' to '<' for applying more optimizations, but that may miss some opportunities).
  - FIXME: Could remove one comparison in nt == '&&' or nt == '||'. Low-hanging fruit.
2018-04-01 02:14:00 +02:00
Sei Lisa
d0d6d6744b Bump copyright year
The help text in main.py was still at 2015. Oops.
2018-03-23 16:36:45 +01:00
Sei Lisa
aad4cf3bee Fix the fix for the bug introduced in 097c054
Our previous fix was incomplete, because it failed to detect the last IF in a chain of ELSE IFs. For example:

if (a == 2) llDie(); else if (a) llDie(); else if (a == 3) llDie();

That would be transformed by the IF swapper into:

if (a ^ 2)
    if (a)
        llDie();
    else if (a == 3)
        llDie();
else
    llDie();

Note that the last 'else' would bind to the last 'if', not to the first one. So the condition is actually like this:

child[1] of an 'if' statement needs to be guarded in {} if the 'else' may belong to the wrong 'if'.

It will belong to the wrong 'if' if child[1] is a (possibly empty) chain of 'if {whatever} else ...', followed by an 'if' without 'else', that is:

   if (cond) stmt;

(which was what our previous check did), but also e.g.:

   if (cond) stmt; else if (cond) stmt; else if (cond) stmt;

which we neglected to consider in our previous fix.
2017-12-14 21:32:00 +01:00
Sei Lisa
e42479756b Fix bug with nested if's; fix missing EXPR wrap.
097c054 introduced a bug that we hadn't caught until now.

In some occasions, it could swap nested conditions in such a way that the 'else' of the outer statement was made to belong to the inner one, like this:

    if (a)
        if (b)
            stuff;
    else
        stuff;

That is of course parsed with the 'else' belonging to if(b).

Fix implemented at output time, by detecting 'if(a) stmt; else y;' with stmt being an 'if' without 'else', and wrapping the stmt in {} like this: 'if(a){if(b) x;} else y;'. This has some similarity with parenthesis addition.

But the fix has the corner case that, since {} hides visibility of labels, when the inner 'if' has a label as direct child, it can't be swapped lest the label becomes out of scope. So these cases are detected and skipped in the constant folding module.

In the case of 'if(cond);', we transform it to 'cond;', but we forgot to wrap the cond in an EXPR node as required. Fixed too.
2017-11-13 04:04:13 +01:00
Sei Lisa
b80b157489 Add a space between a minus sign and a negative constant.
When a constant was negative internally, it was output with the sign included. The code was not prepared to handle this, and could therefore cause double minus signs. For example, -2147483648 was output as --2147483648, and -4294967296 was output as --1.

Fixed by adding a space for floats, and by translating the number to the range 2147483648..4294967295 for integers (hex would have worked just as well).
2017-10-27 21:02:00 +02:00
Sei Lisa
3f6f8ed8ad Internal code reorganization.
- Separate library loading code into a new module. parser.__init__() no longer loads the library; it accepts (but does not depend on) a library as a parameter.
- Add an optional library argument to parse(). It's no longer mandatory to create a new parser for switching to a different builtins or seftable file.
- Move warning() and types from lslparse to lslcommon.
- Add .copy() to uses of base_keywords, to not rely on it being a frozen set.
- Adjust the test suite.
2017-10-20 18:19:48 +02:00
Sei Lisa
a5ec12c9e9 Change (float)"NaN" to (-1e40*0) in output.
Solves both an inconsistency and the need to create a string.
2017-10-14 13:05:14 +02:00
Sei Lisa
906e76ea47 Format LIST nodes; don't add indent to CONST list in calc mode
LIST nodes will be pretty-printed with newlines between elements if they have 5 elements or more.

List constants won't be indented when in calc mode.
2017-08-25 20:35:24 +02:00
Sei Lisa
a2e793df02 Parentheses around chained assignments are not necessary.
We follow the precedence and associativity rules, though.
2017-08-17 00:40:03 +02:00
Sei Lisa
fe574bb462 Bump copyright year.
'bout time.
2017-08-09 19:45:46 +02:00
Sei Lisa
250090f418 Downgrade a FIXME item to TODO. 2017-01-28 05:04:26 +01:00
Sei Lisa
c08d1edb5d Fix nested lists disabling list mode.
Lists can't contain lists at runtime, but they can at parse time, so the optimizer must behave properly when handling nested lists. And it didn't, because it neglected to preserve the previous state of self.listmode. So we fix that.
2017-01-13 00:36:09 +01:00
Sei Lisa
983808f022 Remove dot from floats when there are no decimals and there's an exponent. 2017-01-12 17:41:34 +01:00
Sei Lisa
2cf5ede817 Fix optimization of -0.0.
It was optimized to ((float)0) because integers are cheaper. But that loses the sign, so that needed to be fixed.
2017-01-12 15:36:08 +01:00
Sei Lisa
a961fee1c3 Minor formatting fix for calculator.
Don't output a newline before a list constant if in calculator mode. While we're there, make a comparison more compact.
2017-01-12 01:57:40 +01:00
Sei Lisa
991e811f2d Fix Python gotcha with module globals, and missing 'cond' in lslextrafuncs.
The previous commit didn't work as expected. "from module import var" freezes the value at load time; changing it later has no effect. A reference to the module needs to be used.

Fix that and the similar problem with LSO. Also revert some "from lslcommon import *" introduced earlier.

That also revealed another bug about missing 'cond' in the import list of lslextrafuncs. This should fix all functions that return values on null key input.
2016-12-21 00:22:49 +01:00
Sei Lisa
7c2c09188d Change how LSLCalc is handled.
Instead of using an option in the command line, use a global in lslcommon, settable by the main program (only the main LSLCalc program, which differs from LSL-PyOptimizer's main, changes it).
2016-12-20 21:25:33 +01:00
Sei Lisa
39261cbfc8 Make Unicode some strings that should be, and improve error reporting in builtins.txt
Also work towards the convention that strings that represent text (possibly translatable) are in double quotes, not single.
2016-12-20 20:13:53 +01:00
Sei Lisa
9879d5f68b Follow-up to 2f4f403 (lslcalc support) 2016-12-15 03:38:51 +01:00
Sei Lisa
7fa691ead7 Activate 'optimize' option by default in lsloutput.
Failure to do so caused a regression test to fail. Harmless, because that option is overriden by main, but fixed.

Bug was introduced in commit 397dc89, with the requirement that the 'optimize' option be active for output optimizations to be applied, by forgetting to update the function header to add that default option.
2016-12-15 03:00:22 +01:00
Sei Lisa
397dc896fb Fix --optimizer-options=-optimize still applying some optimizations.
This option normally takes effect through the base class in lsloptimize.py, which doesn't call the optimization techniques if deactivated. However, lsloutput.py is not called by it, and it applied some optimizations on its own.

Fixed on the reading of the optimization options, by filtering them by whether the optimize option is active.
2016-11-29 23:03:14 +01:00
Sei Lisa
da7b98b4ba Comment fix. 2016-11-15 01:25:35 +01:00
Sei Lisa
79dff25769 Update copyright years of some files; add legalese to seftable.txt 2016-06-27 20:06:41 +02:00
Sei Lisa
f32489a5a8 Distinguish indeterminates and improve infinities in output.
'(float)"-nan"' doesn't return Indet in LSL:
  llOwnerSay(llList2CSV([(float)"-nan"])); // outputs "nan", not "-nan"
Therefore, for the output to yield the correct result we have to use a different strategy to generate an indeterminate. We choose '(1e40*0)' which is shorter than the rest.

Also, we don't output infinites as '(float)"[-]inf"' but alwas as '1e40' or '(float)-1e40' (or just '-1e40' if we're in globals).
2016-05-26 20:00:11 +02:00
Sei Lisa
b7e6e6f7b1 Fix bug with tab handling.
Commit 5804a9a introduced a bug where having the foldtabs option disabled (normal) prevented optimizations of functions. Fix it for good (hopefully). While on it, rename the nofoldtabs option to warntabs, making it default, and use it to disable a warning when there are tabs in a string.
2016-05-07 03:18:50 +02:00
Sei Lisa
c555a01a48 It's possible to enter Infinity as a float constant, so do that rather than the (float)"inf" kludge. It remains for NaN though. 2016-01-06 01:21:04 +01:00
Sei Lisa
025f0f8440 str() doesn't return a fully-expanded float. repr() does. 2015-12-09 03:37:01 +01:00
Sei Lisa
2044f888d4 Fix bug where (typecast)[single_expr] was output as (typecast)(list)single_expr, producing a syntax error in the output for lack of extra parentheses. 2015-09-09 04:14:55 +02:00
Sei Lisa
4cc268b574 Fix parenthesizing of expressions having ~ or ! 2015-06-17 18:30:32 +02:00
Sei Lisa
aaa8d3b7f4 Fix crash when a global was optimized out and another global depended on it. 2015-06-14 03:36:54 +02:00
Sei Lisa
17bf0b7a1e Fix recently introduced bug: function renaming failed. 2015-04-17 03:37:24 +02:00
Sei Lisa
01d8bba3f4 Don't always output a space after the unary minus, only when necessary. 2015-03-28 23:35:08 +01:00
Sei Lisa
f6b472133a Optimize [elem] -> (list)elem on output. Saves us headaches. 2015-03-13 22:42:00 +01:00
Sei Lisa
890e960b57 Implement Lazy List reading. Update docs according to last changes (in FS too).
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.
2015-03-13 06:38:35 +01:00
Sei Lisa
c68a1f4ad6 Add copyright notices to all files, to prepare the program for release. 2015-03-05 23:18:41 +01:00
Sei Lisa
b73805e0ce Add "lazy lists" assignment support (mylist[index] = value).
Add support for LAMBDA (empty) tree nodes while on it, that allow us to define private stuff at the top without caring about Loc.
2015-03-03 17:59:51 +01:00
Sei Lisa
0ca5a8f5b0 Fix typo that made function calls be wrapped in parentheses on output.
No biggie, but what's right is right.
2015-02-28 20:37:59 +01:00
Sei Lisa
1dea1bd12c Make parentheses no longer explicit in the AST (Beta).
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.
2015-02-28 00:43:26 +01:00
Sei Lisa
9cf18ade60 Improve output of floats by minimizing them further. 2014-08-09 23:20:40 +02:00
Sei Lisa
5773449edb Convert warnings to add the WARNING: title in the function. 2014-08-05 15:55:49 +02:00
Sei Lisa
58e22f77ce Prepare for the incoming Dead Code Removal module. 2014-08-05 15:47:14 +02:00
Sei Lisa
17e94a0d0f Add FoldCond as a stub. Change cond constant to -1. Add support for EXPR.
(EXPR as a statement, not as a general 'expression')
2014-08-03 20:06:50 +02:00
Sei Lisa
6a9278cd28 Typo 2014-08-01 05:33:34 +02:00
Sei Lisa
6c248c46e3 Implement the shrinknames option.
Fixes some bugs with the treatment of the shrink attribute, some others with the output of renamed stuff.
2014-08-01 05:07:50 +02:00
Sei Lisa
847d7b1e20 Oops, forgot these in the editor without saving.
They belong to the output module general preparation for renaming.
2014-08-01 02:02:24 +02:00
Sei Lisa
d65f0f1f75 Fully implement duplabels, and prepare output for general renaming.
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.
2014-08-01 01:41:21 +02:00
Sei Lisa
be9145e3c3 Fix bug in float shrinking code. 2014-07-31 18:47:40 +02:00