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.
This commit is contained in:
Sei Lisa 2019-01-06 01:33:49 +01:00
parent 41515f338a
commit 0ffe823c18

View file

@ -26,7 +26,9 @@ SINGLE_OPT_EXPR_CHILD_NODES = frozenset({'DECL', 'EXPR', 'RETURN',
# TODO: We can do a bit better with evaluation order. # 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): class EExpansionLoop(Exception):
def __init__(self): def __init__(self):
@ -34,10 +36,17 @@ class EExpansionLoop(Exception):
u" inline functions") u" inline functions")
class inliner(object): class inliner(object):
def newId(self, namespace): def newId(self, namespace, scope, symdata):
"""Create a new identifier based on a namespace""" """Create a new identifier based on a namespace."""
self.symCtr[namespace] = self.symCtr.get(namespace, 0) + 1 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): def newSymtab(self):
self.symtab.append({}) self.symtab.append({})
@ -114,12 +123,9 @@ class inliner(object):
copy = node.copy() copy = node.copy()
oldscope = node.scope oldscope = node.scope
oldname = node.name oldname = node.name
copy.name = self.newId('lbl') copy.name = self.newId('lbl', scope, {'Type':'l', 'Scope':scope,
'ref':0})
copy.scope = scope 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]['NewSymbolName'] = copy.name
self.symtab[oldscope][oldname]['NewSymbolScope'] = scope self.symtab[oldscope][oldname]['NewSymbolScope'] = scope
return copy return copy
@ -170,13 +176,8 @@ class inliner(object):
retvar = None retvar = None
if rettype is not None: if rettype is not None:
# Returns a value. Create a local variable at the starting level. # Returns a value. Create a local variable at the starting level.
retvar = self.newId('ret') retvar = self.newId('ret', scope, {'Kind':'v', 'Scope':scope,
if retvar in self.symtab[scope]: 'Type':rettype})
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}
# Add the declaration to the list of statements # Add the declaration to the list of statements
fns.append(nr(nt='DECL', t=rettype, name=retvar, scope=scope)) fns.append(nr(nt='DECL', t=rettype, name=retvar, scope=scope))
@ -206,9 +207,9 @@ class inliner(object):
self.retvar = retvar self.retvar = retvar
self.retscope = scope self.retscope = scope
self.retlscope = scope self.retlscope = scope
retlabel = self.newId('rtl') retlabel = self.newId('rtl', scope, {'Type':'l', 'Scope':scope,
'ref':0})
self.retlabel = retlabel self.retlabel = retlabel
self.symtab[scope][retlabel] = {'Type':'l', 'Scope':scope, 'ref':0}
# Get a copy of the function # Get a copy of the function
blk = [self.GetFuncCopy(self.tree[fnsym['Loc']])] blk = [self.GetFuncCopy(self.tree[fnsym['Loc']])]