Reuse state names for function parameters; restart UsedNames.

Gives us a few more opportunities for catching single-letter identifiers.

UsedNames was not restarted. It's unlikely that this had any detrimental effect on optimization, and it was certainly safe to not restart it. But it looks more correct like this.
This commit is contained in:
Sei Lisa 2017-10-28 22:30:16 +02:00
parent 70f39d7f5e
commit f2a6243695

View file

@ -30,10 +30,10 @@ class renamer(object):
CharSet1 = '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' CharSet1 = '_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
CharSet2 = '0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' CharSet2 = '0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
# TODO: Derive these from builtins.txt somehow. # TODO: Derive these from builtins.txt somehow.
Kws = (frozenset({'do', 'if', 'PI', Kws = frozenset({'do', 'if', 'PI',
'for', 'key', 'EOF', 'for', 'key', 'EOF',
'jump', 'else', 'list', 'TRUE', 'LOOP', 'case' 'jump', 'else', 'list', 'TRUE', 'LOOP', 'case'
})) })
def GetNextShortest(self): def GetNextShortest(self):
"""Generate the next shortest possible identifier""" """Generate the next shortest possible identifier"""
while True: while True:
@ -89,8 +89,11 @@ class renamer(object):
assert False, 'Invalid kind at this scope: ' \ assert False, 'Invalid kind at this scope: ' \
+ kind # pragma: no cover + kind # pragma: no cover
# We make three passes, one for states, then functions, then globals, # We make four passes, one for states, then functions, then globals,
# in that order. # then parameter names and locals, in that order.
# State names are usable as short identifiers for parameters.
stateNames = []
for name in states: for name in states:
# States have top priority. Here's why. An internal event function # States have top priority. Here's why. An internal event function
@ -111,6 +114,7 @@ class renamer(object):
entry = globaldefs[name] entry = globaldefs[name]
if name != 'default': if name != 'default':
name = entry['NewName'] = self.GetNextShortest() name = entry['NewName'] = self.GetNextShortest()
stateNames.append(name)
# Find also the event names it uses, to add them for reuse. # Find also the event names it uses, to add them for reuse.
for node in self.tree[entry['Loc']]['ch']: for node in self.tree[entry['Loc']]['ch']:
assert node['nt'] == 'FNDEF' assert node['nt'] == 'FNDEF'
@ -159,6 +163,10 @@ class renamer(object):
restart = self.WordFirstChar restart = self.WordFirstChar
restartReusable = ReusableNames restartReusable = ReusableNames
ReusableNames = restartReusable.copy() ReusableNames = restartReusable.copy()
restartState = stateNames;
stateNames = restartState[:]
restartUsed = self.UsedNames;
self.UsedNames = restartUsed.copy()
for table in self.symtab: for table in self.symtab:
if First: if First:
First = False First = False
@ -178,10 +186,16 @@ class renamer(object):
InParams = True InParams = True
self.WordFirstChar = restart self.WordFirstChar = restart
ReusableNames = restartReusable.copy() ReusableNames = restartReusable.copy()
stateNames = restartState[:]
self.UsedNames = restartUsed.copy()
# Same procedure as for global vars # Same procedure as for global vars
if ReusableNames: if ReusableNames:
short = ReusableNames.pop() short = ReusableNames.pop()
self.UsedNames.add(short) self.UsedNames.add(short)
elif stateNames:
short = stateNames.pop()
# No need to add it to UsedNames because
# GetNextShortest will always start past it anyway.
else: else:
short = self.GetNextShortest() short = self.GetNextShortest()
table[name]['NewName'] = short table[name]['NewName'] = short