mirror of
https://github.com/Sei-Lisa/LSL-PyOptimizer
synced 2025-07-01 15:48:21 +00:00
Change skippreproc -> processpre, add #pragma option processing.
Usage: Options are case insensitive.
This commit is contained in:
parent
a13b1cb77e
commit
0c3ad9b938
3 changed files with 89 additions and 16 deletions
|
@ -312,6 +312,70 @@ class parser(object):
|
|||
if self.pos >= self.length:
|
||||
raise EInternal() # force GetToken to return EOF
|
||||
|
||||
def SetOpt(self, option, value):
|
||||
# See parse() for meaning of options.
|
||||
if option == 'extendedglobalexpr':
|
||||
self.extendedglobalexpr = value
|
||||
|
||||
if option == 'extendedtypecast':
|
||||
self.extendedtypecast = value
|
||||
|
||||
if option == 'extendedassignment':
|
||||
self.extendedassignment = value
|
||||
|
||||
if option == 'explicitcast':
|
||||
self.explicitcast = value
|
||||
|
||||
if option == 'allowkeyconcat':
|
||||
self.allowkeyconcat = value
|
||||
|
||||
if option == 'allowmultistrings':
|
||||
self.allowmultistrings = value
|
||||
|
||||
if option == 'processpre':
|
||||
self.processpre = value
|
||||
|
||||
# TODO: Allow pure C-style string escapes. This is low-priority.
|
||||
#if option == 'allowcescapes':
|
||||
# self.allowcescapes = value
|
||||
|
||||
# Enable switch statements.
|
||||
if option == 'enableswitch':
|
||||
if not self.enableswitch and value:
|
||||
self.keywords |= self.switch_keywords
|
||||
elif self.enableswitch and not value:
|
||||
self.keywords = self.base_keywords
|
||||
if self.breakcont:
|
||||
self.keywords |= self.brkcont_keywords
|
||||
|
||||
self.enableswitch = value
|
||||
|
||||
# Enable break/continue
|
||||
if option == 'breakcont':
|
||||
if not self.breakcont and value:
|
||||
self.keywords |= self.brkcont_keywords
|
||||
elif self.breakcont and not value:
|
||||
self.keywords = self.base_keywords
|
||||
if self.enableswitch:
|
||||
self.keywords |= self.switch_keywords
|
||||
|
||||
self.breakcont = value
|
||||
|
||||
if option == 'errmissingdefault':
|
||||
self.errmissingdefault = value
|
||||
|
||||
if option == 'lazylists':
|
||||
self.lazylists = value
|
||||
|
||||
if option == 'duplabels':
|
||||
self.duplabels = value
|
||||
|
||||
if option == 'shrinknames':
|
||||
self.shrinknames = value
|
||||
|
||||
if option == 'funcoverride':
|
||||
self.funcoverride = value
|
||||
|
||||
def ProcessDirective(self, directive):
|
||||
"""Process a given preprocessor directive during parsing."""
|
||||
|
||||
|
@ -327,7 +391,7 @@ class parser(object):
|
|||
r'^#\s*(?:'
|
||||
r'(?:[Ll][Ii][Nn][Ee]\s+)?(\d+)(?:\s+("(?:[^"\\]|\\.)*"))?'
|
||||
r'|'
|
||||
r'([A-Za-z0-9_]+)\s+(.+?)'
|
||||
r'([A-Za-z0-9_]+)\s+([A-Za-z0-9_]+)\s+([-+,A-Za-z0-9_]+)'
|
||||
r')\s*$'
|
||||
)
|
||||
match = self.parse_directive_re.search(directive)
|
||||
|
@ -351,9 +415,16 @@ class parser(object):
|
|||
del linenum
|
||||
else:
|
||||
assert match.group(3) is not None
|
||||
if match.group(3).lower() == 'pragma':
|
||||
# TODO: process #pragma
|
||||
warning('pragma not implemented')
|
||||
if match.group(3).lower() == 'pragma' and match.group(4) == 'OPT':
|
||||
opts = match.group(5).lower().split(',')
|
||||
for opt in opts:
|
||||
if opt != '':
|
||||
if opt[0] == '-':
|
||||
self.SetOpt(opt[1:], False)
|
||||
elif opt[0] == '+':
|
||||
self.SetOpt(opt[1:], True)
|
||||
else:
|
||||
self.SetOpt(opt, True)
|
||||
|
||||
def GetToken(self):
|
||||
"""Lexer"""
|
||||
|
@ -366,8 +437,8 @@ class parser(object):
|
|||
c = self.script[self.pos]
|
||||
self.pos += 1
|
||||
|
||||
# Process comments
|
||||
if self.skippreproc and self.linestart and c == '#':
|
||||
# Process preprocessor directives
|
||||
if self.processpre and self.linestart and c == '#':
|
||||
# Preprocessor directive.
|
||||
# Most are not supposed to reach us but some do:
|
||||
# - gcpp generates lines in the output like:
|
||||
|
@ -392,6 +463,7 @@ class parser(object):
|
|||
self.ceof()
|
||||
continue
|
||||
|
||||
# Process comments
|
||||
if c == '/':
|
||||
if self.script[self.pos:self.pos+1] == '/':
|
||||
self.pos += 1
|
||||
|
@ -2398,8 +2470,8 @@ list lazy_list_set(list L, integer i, list v)
|
|||
# Allow C style string composition of strings: "blah" "blah" = "blahblah"
|
||||
self.allowmultistrings = 'allowmultistrings' in options
|
||||
|
||||
# Skip preprocessor directives (specifically #line).
|
||||
self.skippreproc = 'skippreproc' in options
|
||||
# Process preprocessor directives (especially #pragma and #line).
|
||||
self.processpre = 'processpre' in options
|
||||
|
||||
# TODO: Allow pure C-style string escapes. This is low-priority.
|
||||
#self.allowcescapes = 'allowcescapes' in options
|
||||
|
|
15
main.py
15
main.py
|
@ -196,8 +196,8 @@ Preprocessor modes:
|
|||
pertinent to it. Implies --precmd=cpp
|
||||
none No preprocessing (default)
|
||||
|
||||
Normally, running the preprocessor needs -O skippreproc to make the output
|
||||
readable by the optimizer.
|
||||
Normally, running the preprocessor needs the option 'processpre' active, to
|
||||
make the output readable by the optimizer. This option is active by default.
|
||||
|
||||
'''.format(progname=sys.argv[0], version=VERSION))
|
||||
return
|
||||
|
@ -284,10 +284,11 @@ Optimizer options (+ means active by default, - means inactive by default):
|
|||
warntabs + Suppress warning when a function can't be optimized
|
||||
because it generates a string or list with a tab, or
|
||||
when a string contains a tab.
|
||||
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 GNU cpp, which inserts
|
||||
directives like: # 123 "filename".
|
||||
processpre + Process some preprocessor directives in the source. This
|
||||
enables usage of #pragma/#line preprocessor directives,
|
||||
and is probably necessary if the script is itself the
|
||||
output of a preprocessor. Note that this option does not
|
||||
make the optimizer process macros.
|
||||
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
|
||||
|
@ -304,7 +305,7 @@ def main():
|
|||
|
||||
# Default options
|
||||
options = set(('extendedglobalexpr','extendedtypecast','extendedassignment',
|
||||
'allowkeyconcat','allowmultistrings','skippreproc','warntabs','optimize',
|
||||
'allowkeyconcat','allowmultistrings','processpre','warntabs','optimize',
|
||||
'optsigns','optfloats','constfold','dcr','errmissingdefault',
|
||||
))
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ class Test02_Parser(UnitTestCase):
|
|||
}}''',
|
||||
['explicitcast','extendedtypecast','extendedassignment',
|
||||
'extendedglobalexpr', 'allowmultistrings', 'allowkeyconcat',
|
||||
'skippreproc', 'duplabels']
|
||||
'processpre', 'duplabels']
|
||||
))
|
||||
print self.parser.scopeindex
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue