2015-03-05 15:18:41 -07:00
|
|
|
#!/usr/bin/env python2
|
|
|
|
|
|
|
|
# (C) Copyright 2015 Sei Lisa. All rights reserved.
|
|
|
|
#
|
|
|
|
# This file is part of LSL PyOptimizer.
|
|
|
|
#
|
|
|
|
# LSL PyOptimizer is free software: you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License as
|
|
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
|
|
# License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# LSL PyOptimizer is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with LSL PyOptimizer. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
# This is the main executable program that imports the libraries.
|
2014-07-25 17:43:44 -07:00
|
|
|
|
|
|
|
from lslopt.lslparse import parser,EParse
|
|
|
|
from lslopt.lsloutput import outscript
|
2014-07-26 12:29:35 -07:00
|
|
|
from lslopt.lsloptimizer import optimizer
|
2014-07-25 17:43:44 -07:00
|
|
|
import sys
|
2015-03-06 12:29:54 -07:00
|
|
|
import os
|
|
|
|
import lslopt.lslcommon
|
2014-07-25 17:43:44 -07:00
|
|
|
|
|
|
|
def main():
|
2014-07-27 17:13:08 -07:00
|
|
|
if len(sys.argv) < 2:
|
2015-03-05 12:45:38 -07:00
|
|
|
sys.stderr.write(
|
|
|
|
r'''LSL optimizer v0.1
|
2015-03-05 15:18:41 -07:00
|
|
|
|
|
|
|
(C) Copyright 2015 Sei Lisa. All rights reserved.
|
|
|
|
|
|
|
|
This program comes with ABSOLUTELY NO WARRANTY.
|
|
|
|
This is free software, and you are welcome to redistribute it
|
|
|
|
under certain conditions; see the file COPYING for details.
|
|
|
|
This program is licensed under the GNU General Public License
|
|
|
|
version 3.
|
2014-07-27 17:13:08 -07:00
|
|
|
|
2014-07-28 09:19:50 -07:00
|
|
|
Usage: %s [-O [+|-]option[,[+|-]option[,...]]] filename
|
2014-07-28 08:28:12 -07:00
|
|
|
|
2014-07-28 09:19:50 -07:00
|
|
|
That's an upper case o, not the number zero.
|
2014-07-28 08:28:12 -07:00
|
|
|
If filename is a dash (-) then standard input is used.
|
2014-07-27 17:13:08 -07:00
|
|
|
|
2014-07-31 15:33:20 -07:00
|
|
|
Options (+ means active by default, - means inactive by default):
|
2015-03-04 17:37:32 -07:00
|
|
|
|
|
|
|
Syntax extensions options:
|
|
|
|
|
2014-07-30 17:02:53 -07:00
|
|
|
extendedglobalexpr + Enables arbitrary expressions in globals (as opposed to
|
2014-07-27 17:13:08 -07:00
|
|
|
dull simple expressions allowed by regular LSL). Needs
|
|
|
|
the optimizer to run for the result to be compilable.
|
2015-03-05 18:56:58 -07:00
|
|
|
breakcont - Allow break/continue statements for loops. Note that
|
|
|
|
when active, 'break' and 'continue' become reserved
|
|
|
|
words, but when inactive they can be used as variables.
|
2014-07-30 17:02:53 -07:00
|
|
|
extendedtypecast + Allows extended typecast syntax e.g. (string)(integer)a
|
2014-07-27 17:13:08 -07:00
|
|
|
is valid with this option.
|
2014-07-30 17:02:53 -07:00
|
|
|
extendedassignment + Enables &=, |=, ^=, <<=, >>= assignment operators.
|
|
|
|
allowkeyconcat + Allow string + key and key + string (both return string)
|
|
|
|
allowmultistrings + Allow C-like string juxtaposition, e.g. "ab" "cd" means
|
2014-07-27 17:13:08 -07:00
|
|
|
"abcd", no concatenation involved. Very useful when used
|
2015-02-28 12:01:51 -07:00
|
|
|
with a preprocessor. Similar to addstrings, but this one
|
|
|
|
is not an optimization, it introduces new syntax.
|
2015-03-05 18:56:58 -07:00
|
|
|
duplabels - Normally, a duplicate label within a function is allowed
|
|
|
|
by the syntax by using {} blocks; however, the server
|
|
|
|
will just refuse to save the script (under Mono) or do
|
|
|
|
something completely unexpected (under LSO: all jumps
|
|
|
|
will go to the last label with that name). This flag
|
|
|
|
works around that limitation by replacing the names of
|
|
|
|
the labels in the output with unique ones.
|
|
|
|
|
2015-03-07 14:55:25 -07:00
|
|
|
Deprecated / compatibility syntax extensions options:
|
2015-03-05 18:56:58 -07:00
|
|
|
|
2015-03-04 17:37:32 -07:00
|
|
|
lazylists - Support syntax like mylist[index] = 5; rather than using
|
|
|
|
llListReplaceList. Only assignment supported. The list
|
|
|
|
is extended when the argument is greater than the list
|
|
|
|
length, by inserting integer zeros. This is implemented
|
|
|
|
for compatibility with Firestorm, but its use is not
|
|
|
|
recommended, as it adds a new function, wasting memory
|
|
|
|
against the very spirit of this program.
|
2015-03-05 12:45:38 -07:00
|
|
|
enableswitch - Support C-like switch() syntax, with some limitations.
|
2015-03-04 17:37:32 -07:00
|
|
|
Like lazylists, it's implemented for compatibility with
|
|
|
|
Firestorm, but not recommended. Note that the operand to
|
|
|
|
switch() may be evaluated more than once.
|
|
|
|
|
|
|
|
Optimization options
|
|
|
|
|
|
|
|
optimize + Runs the optimizer.
|
|
|
|
optsigns + Optimize signs in float and integer constants.
|
|
|
|
optfloats + Optimize floats that represent an integral value.
|
|
|
|
constfold + Fold constant expressions to their values, and simplify
|
2015-03-05 12:45:38 -07:00
|
|
|
some expressions and statements.
|
2015-03-04 17:37:32 -07:00
|
|
|
dcr + Dead code removal. This option removes several instances
|
|
|
|
of code that will never execute, and performs other
|
|
|
|
optimizations like removal of unused variables,
|
|
|
|
functions or expressions.
|
2014-07-31 20:07:50 -07:00
|
|
|
shrinknames - Reduces script memory by shrinking identifiers. In the
|
|
|
|
process, it turns the script into unreadable gibberish,
|
|
|
|
hard to debug, but this gets big savings for complex
|
|
|
|
scripts.
|
2015-03-04 17:37:32 -07:00
|
|
|
addstrings - Concatenate strings together when possible. Note that
|
|
|
|
such an optimization can be counter-productive in some
|
2015-03-05 12:45:38 -07:00
|
|
|
cases, that's why it's disabled by default. For example:
|
2015-03-04 17:37:32 -07:00
|
|
|
string a="a"+"longstring"; string b="b"+"longstring";
|
|
|
|
would keep a single copy of "longstring", while if the
|
|
|
|
strings are added, both "alongstring" and "blongstring"
|
|
|
|
take memory.
|
|
|
|
|
|
|
|
Miscellaneous options
|
|
|
|
|
|
|
|
foldtabs - Tabs can't be copy-pasted, so expressions that produce
|
2015-03-05 12:45:38 -07:00
|
|
|
tabs, e.g. llUnescapeURL("%%09"), aren't optimized by
|
2015-03-04 17:37:32 -07:00
|
|
|
default. This option overrides that check, enabling
|
2015-03-05 12:45:38 -07:00
|
|
|
expansion of functions that produce strings with tabs.
|
|
|
|
The resulting source isn't guaranteed to be
|
|
|
|
copy-paste-able to the viewer.
|
2015-03-04 17:37:32 -07:00
|
|
|
skippreproc + Skip preprocessor directives in the source as if they
|
|
|
|
were comments. Not useful unless the script is itself
|
|
|
|
the output of a preprocessor like cpp, which inserts
|
|
|
|
directives like: # 123 "filename".
|
2015-03-05 18:56:58 -07:00
|
|
|
explicitcast - Add explicit casts where they are implicit. This option
|
|
|
|
is useless with 'optimize' and 'optsigns', and is of
|
|
|
|
basically no use in general, other than to see where
|
|
|
|
automatic casts happen.
|
2014-07-27 17:13:08 -07:00
|
|
|
''' % sys.argv[0])
|
|
|
|
return 1
|
|
|
|
|
2014-07-28 09:19:50 -07:00
|
|
|
options = set(('extendedglobalexpr','extendedtypecast','extendedassignment',
|
2014-07-30 16:37:18 -07:00
|
|
|
'allowkeyconcat','allowmultistrings','skippreproc','optimize',
|
2015-03-04 17:37:32 -07:00
|
|
|
'optsigns','optfloats','constfold','dcr'
|
2014-07-28 09:19:50 -07:00
|
|
|
))
|
|
|
|
|
2015-03-06 12:29:54 -07:00
|
|
|
# If it's good to append the basename to it, it's good to append the
|
|
|
|
# auxiliary files' names to it.
|
|
|
|
lslopt.lslcommon.DataPath = __file__[:-len(os.path.basename(__file__))]
|
|
|
|
|
2014-07-28 08:28:12 -07:00
|
|
|
if sys.argv[1] == '-O':
|
2014-07-27 17:13:08 -07:00
|
|
|
if len(sys.argv) < 4:
|
|
|
|
sys.stderr.write('Command line: Not enough parameters\n')
|
2014-07-25 17:43:44 -07:00
|
|
|
return 1
|
2014-07-28 09:19:50 -07:00
|
|
|
optchanges = sys.argv[2].split(',')
|
|
|
|
for chg in optchanges:
|
2014-07-29 19:54:16 -07:00
|
|
|
if chg[0:1] not in ('+', '-'):
|
2014-07-28 09:19:50 -07:00
|
|
|
chg = '+' + chg
|
|
|
|
if chg[0] == '-':
|
|
|
|
options.discard(chg[1:])
|
|
|
|
else:
|
|
|
|
options.add(chg[1:])
|
2014-07-27 17:13:08 -07:00
|
|
|
fname = sys.argv[3]
|
|
|
|
else:
|
|
|
|
fname = sys.argv[1]
|
|
|
|
|
|
|
|
p = parser()
|
|
|
|
try:
|
2014-07-28 08:28:12 -07:00
|
|
|
if fname == '-':
|
|
|
|
script = sys.stdin.read()
|
2014-07-29 19:54:16 -07:00
|
|
|
ts = p.parse(script, options)
|
2014-07-28 08:28:12 -07:00
|
|
|
else:
|
2014-07-29 19:54:16 -07:00
|
|
|
ts = p.parsefile(fname, options)
|
2014-07-27 17:13:08 -07:00
|
|
|
except EParse as e:
|
|
|
|
print e.message
|
|
|
|
return 1
|
|
|
|
del p
|
|
|
|
|
|
|
|
opt = optimizer()
|
2014-07-29 19:54:16 -07:00
|
|
|
ts = opt.optimize(ts, options)
|
2014-07-27 17:13:08 -07:00
|
|
|
del opt
|
|
|
|
|
|
|
|
outs = outscript()
|
2014-07-29 19:54:16 -07:00
|
|
|
script = outs.output(ts, options)
|
2014-07-27 17:13:08 -07:00
|
|
|
del outs
|
2014-07-29 19:54:16 -07:00
|
|
|
del ts
|
2014-07-27 17:13:08 -07:00
|
|
|
sys.stdout.write(script)
|
|
|
|
return 0
|
2014-07-25 17:43:44 -07:00
|
|
|
|
2014-07-27 14:31:48 -07:00
|
|
|
ret = main()
|
|
|
|
if ret:
|
|
|
|
sys.exit(ret)
|