From 0ffe823c18d2fadd0e12879ed860eb357ac4033c Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Sun, 6 Jan 2019 01:33:49 +0100 Subject: [PATCH] Move symbol existence check and creation to newId ENameAlreadyExists has also been expanded to accept an inliner object, even though it's not used yet. Plans are the same as in EParse. --- lslopt/lslinliner.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/lslopt/lslinliner.py b/lslopt/lslinliner.py index cf3980d..482756f 100644 --- a/lslopt/lslinliner.py +++ b/lslopt/lslinliner.py @@ -26,7 +26,9 @@ SINGLE_OPT_EXPR_CHILD_NODES = frozenset({'DECL', 'EXPR', 'RETURN', # TODO: We can do a bit better with evaluation order. -class ENameAlreadyExists(Exception): pass +class ENameAlreadyExists(Exception): + def __init__(self, obj, text): + super(ENameAlreadyExists, self).__init__(text) class EExpansionLoop(Exception): def __init__(self): @@ -34,10 +36,17 @@ class EExpansionLoop(Exception): u" inline functions") class inliner(object): - def newId(self, namespace): - """Create a new identifier based on a namespace""" + def newId(self, namespace, scope, symdata): + """Create a new identifier based on a namespace.""" self.symCtr[namespace] = self.symCtr.get(namespace, 0) + 1 - return '___%s__%05d' % (namespace, self.symCtr[namespace]) + name = '___%s__%05d' % (namespace, self.symCtr[namespace]) + if name in self.symtab[scope]: + kinds = {'l':u"Label", 'f':u"Function", 'v':u"Variable", + 's':u"State"} + raise ENameAlreadyExists(self, u"%s already exists: %s" + % (kinds[symdata['Kind']], name.decode('utf8'))) + self.symtab[scope][name] = symdata + return name def newSymtab(self): self.symtab.append({}) @@ -114,12 +123,9 @@ class inliner(object): copy = node.copy() oldscope = node.scope oldname = node.name - copy.name = self.newId('lbl') + copy.name = self.newId('lbl', scope, {'Type':'l', 'Scope':scope, + 'ref':0}) copy.scope = scope - if copy.name in self.symtab[scope]: - raise ENameAlreadyExists( - u"Label already exists: %s" % copy.name.decode('utf8')) - self.symtab[scope][copy.name] = {'Type':'l','Scope':scope,'ref':0} self.symtab[oldscope][oldname]['NewSymbolName'] = copy.name self.symtab[oldscope][oldname]['NewSymbolScope'] = scope return copy @@ -170,13 +176,8 @@ class inliner(object): retvar = None if rettype is not None: # Returns a value. Create a local variable at the starting level. - retvar = self.newId('ret') - if retvar in self.symtab[scope]: - raise ENameAlreadyExists(u"Symbol %s already exists" - % retvar.decode('utf8')) - # Add the symbol to the symbol table - self.symtab[scope][retvar] = {'Kind':'v', 'Scope':scope, - 'Type':rettype} + retvar = self.newId('ret', scope, {'Kind':'v', 'Scope':scope, + 'Type':rettype}) # Add the declaration to the list of statements fns.append(nr(nt='DECL', t=rettype, name=retvar, scope=scope)) @@ -206,9 +207,9 @@ class inliner(object): self.retvar = retvar self.retscope = scope self.retlscope = scope - retlabel = self.newId('rtl') + retlabel = self.newId('rtl', scope, {'Type':'l', 'Scope':scope, + 'ref':0}) self.retlabel = retlabel - self.symtab[scope][retlabel] = {'Type':'l', 'Scope':scope, 'ref':0} # Get a copy of the function blk = [self.GetFuncCopy(self.tree[fnsym['Loc']])]