Add scope field to {} nodes

Since we need to add variables, we need to know which scope to add them to. Add this information to the {} node, which is what creates a new scope.

An alternative would be to scan for any variable or label declaration within the braces and use that or create a new one if none, which is more expensive and may waste symbol tables.
This commit is contained in:
Sei Lisa 2018-12-26 19:47:22 +01:00
parent 3542824d51
commit 76f483fc11
3 changed files with 32 additions and 14 deletions

View file

@ -199,7 +199,9 @@ class foldconst(object):
if (node.nt == 'FNCALL' and 'Loc' in self.symtab[0][node.name] if (node.nt == 'FNCALL' and 'Loc' in self.symtab[0][node.name]
and self.FnSEF(node) and self.FnSEF(node)
): ):
parent[index] = nr(nt='{}', t=None, ch=[ scope = len(self.symtab)
self.symtab.append({})
parent[index] = nr(nt='{}', t=None, scope=scope, ch=[
nr(nt='EXPR', t=x.t, ch=[x]) for x in node.ch]) nr(nt='EXPR', t=x.t, ch=[x]) for x in node.ch])
self.FoldTree(parent, index) self.FoldTree(parent, index)
return return
@ -1662,9 +1664,11 @@ class foldconst(object):
self.FoldTree(child, idx) self.FoldTree(child, idx)
if not child: if not child:
# All events removed - add a dummy timer() # All events removed - add a dummy timer()
scope = len(self.symtab)
self.symtab.append({})
child.append(nr(nt='FNDEF', t=None, name='timer', child.append(nr(nt='FNDEF', t=None, name='timer',
pscope=0, ptypes=[], pnames=[], pscope=scope, ptypes=[], pnames=[],
ch=[nr(nt='{}', t=None, ch=[])] ch=[nr(nt='{}', t=None, scope=scope, ch=[])]
)) ))
return return
@ -1867,7 +1871,10 @@ class foldconst(object):
# We're in the case where there are expressions. If any # We're in the case where there are expressions. If any
# remain, they are not SEF (or they would have been # remain, they are not SEF (or they would have been
# removed earlier) so don't mark this node as SEF. # removed earlier) so don't mark this node as SEF.
parent[index] = nr(nt='{}', t=None, ch=exprlist) scope = len(self.symtab)
self.symtab.append({})
parent[index] = nr(nt='{}', t=None, scope=scope,
ch=exprlist)
else: else:
parent[index] = nr(nt=';', t=None, SEF=True) parent[index] = nr(nt=';', t=None, SEF=True)
return return

View file

@ -124,7 +124,9 @@ class lastpass(object):
# function (must be the result of optimization). # function (must be the result of optimization).
# Insert dummy IF(1){...} statement covering the whole function # Insert dummy IF(1){...} statement covering the whole function
# (if it returs a value, insert a return statement too). # (if it returs a value, insert a return statement too).
child[0] = nr(nt='{}', t=None, ch=[ scope = len(self.symtab)
self.symtab.append({})
child[0] = nr(nt='{}', t=None, scope=scope, ch=[
nr(nt='IF', t=None, ch=[ nr(nt='IF', t=None, ch=[
nr(nt='CONST', t='integer', value=1, SEF=True), nr(nt='CONST', t='integer', value=1, SEF=True),
child[0] child[0]

View file

@ -994,6 +994,8 @@ class parser(object):
if 'lazy_list_set' not in self.symtab[0]: if 'lazy_list_set' not in self.symtab[0]:
self.PushScope() self.PushScope()
paramscope = self.scopeindex paramscope = self.scopeindex
self.PushScope()
blockscope = self.scopeindex
params = (['list', 'integer', 'list'], params = (['list', 'integer', 'list'],
['L', 'i', 'v']) ['L', 'i', 'v'])
self.AddSymbol('f', 0, 'lazy_list_set', Loc=self.usedspots, self.AddSymbol('f', 0, 'lazy_list_set', Loc=self.usedspots,
@ -1025,6 +1027,7 @@ list lazy_list_set(list L, integer i, list v)
nr(nt='{}' nr(nt='{}'
, t=None , t=None
, LIR=True , LIR=True
, scope=blockscope
, ch=[ , ch=[
nr(nt='WHILE' nr(nt='WHILE'
, t=None , t=None
@ -1118,7 +1121,7 @@ list lazy_list_set(list L, integer i, list v)
] ]
) )
self.usedspots += 1 self.usedspots += 1
#self.PopScope() # no locals self.PopScope()
self.PopScope() self.PopScope()
if expr.t is None: if expr.t is None:
@ -1873,8 +1876,9 @@ list lazy_list_set(list L, integer i, list v)
last = self.breakstack.pop() last = self.breakstack.pop()
if last[2]: if last[2]:
ret = nr(nt='{}', t=None, ch=[ret, nr(nt='@', t=None, assert last[1] is not None
name=last[0], scope=last[1])]) ret = nr(nt='{}', t=None, scope=last[1], ch=[ret,
nr(nt='@', t=None, name=last[0], scope=last[1])])
self.AddSymbol('l', last[1], last[0], ref=last[2]) self.AddSymbol('l', last[1], last[0], ref=last[2])
self.PopScope() self.PopScope()
return ret return ret
@ -1917,8 +1921,9 @@ list lazy_list_set(list L, integer i, list v)
last = self.breakstack.pop() last = self.breakstack.pop()
if last[2]: if last[2]:
ret = nr(nt='{}', t=None, ch=[ret, nr(nt='@', t=None, assert last[1] is not None
name=last[0], scope=last[1])]) ret = nr(nt='{}', t=None, scope=last[1], ch=[ret,
nr(nt='@', t=None, name=last[0], scope=last[1])])
self.AddSymbol('l', last[1], last[0], ref=last[2]) self.AddSymbol('l', last[1], last[0], ref=last[2])
self.PopScope() self.PopScope()
return ret return ret
@ -1968,8 +1973,9 @@ list lazy_list_set(list L, integer i, list v)
last = self.breakstack.pop() last = self.breakstack.pop()
if last[2]: if last[2]:
ret = nr(nt='{}', t=None, ch=[ret, nr(nt='@', t=None, assert last[1] is not None
name=last[0], scope=last[1])]) ret = nr(nt='{}', t=None, scope=last[1], ch=[ret,
nr(nt='@', t=None, name=last[0], scope=last[1])])
self.AddSymbol('l', last[1], last[0], ref=last[2]) self.AddSymbol('l', last[1], last[0], ref=last[2])
self.PopScope() self.PopScope()
return ret return ret
@ -2080,7 +2086,7 @@ list lazy_list_set(list L, integer i, list v)
if last[2]: if last[2]:
blk.append(nr(nt='@', name=brk, scope=blkscope)) blk.append(nr(nt='@', name=brk, scope=blkscope))
self.AddSymbol('l', blkscope, brk, ref=last[2]) self.AddSymbol('l', blkscope, brk, ref=last[2])
return nr(nt='{}', t=None, ch=prelude + blk) return nr(nt='{}', t=None, scope=blkscope, ch=prelude + blk)
if tok0 == 'CASE': if tok0 == 'CASE':
if not InsideSwitch: if not InsideSwitch:
@ -2225,12 +2231,13 @@ list lazy_list_set(list L, integer i, list v)
LastIsReturn = getattr(stmt, 'LIR', False) LastIsReturn = getattr(stmt, 'LIR', False)
body.append(stmt) body.append(stmt)
scope_braces = self.scopeindex
self.PopScope() self.PopScope()
self.expect('}') self.expect('}')
self.NextToken() self.NextToken()
node = nr(nt='{}', t=None, ch=body) node = nr(nt='{}', t=None, scope=scope_braces, ch=body)
if LastIsReturn: if LastIsReturn:
node.LIR = True node.LIR = True
return node return node
@ -2784,6 +2791,8 @@ list lazy_list_set(list L, integer i, list v)
# Stack to track the labels for break targets, their scope table index, # Stack to track the labels for break targets, their scope table index,
# and whether they are used. # and whether they are used.
# Elements are sublist with 0 = destination label name, 1 = scope for
# that label, and 2 = reference count of the label.
self.breakstack = [] self.breakstack = []
# Stack to track the labels for continue targets, their scope index, # Stack to track the labels for continue targets, their scope index,
# and whether they are used. # and whether they are used.