@@ -91,6 +91,7 @@ def __init__(self, mangle='', parent_mangle=''):
9191 self .caseins = OrderedDict ()
9292 self .parent_mangle = parent_mangle
9393 self .mangle = mangle
94+ self .ownwer : Symbol = None # Function, Sub, etc. owning this scope
9495
9596 def __getitem__ (self , key ):
9697 return self .symbols .get (key , self .caseins .get (key .lower (), None ))
@@ -110,7 +111,6 @@ def __delitem__(self, key):
110111 del self .caseins [key .lower ()]
111112
112113 def values (self , filter_by_opt = True ):
113- # Return the values ordered
114114 if filter_by_opt and OPTIONS .optimization .value > 1 :
115115 return [y for x , y in self .symbols .items () if y .accessed ]
116116 return [y for x , y in self .symbols .items ()]
@@ -137,7 +137,7 @@ def __init__(self):
137137 self .basic_types [type_ ] = self .declare_type (symbols .BASICTYPE (type_ ))
138138
139139 @property
140- def current_scope (self ):
140+ def current_scope (self ) -> int :
141141 return len (self .table ) - 1
142142
143143 @property
@@ -291,37 +291,25 @@ def enter_scope(self, funcname):
291291 global_ .META_LOOPS .append (global_ .LOOPS ) # saves current LOOPS state
292292 global_ .LOOPS = [] # new LOOPS state
293293
294- def leave_scope ( self ):
295- """ Ends a function body and pops current scope out of the symbol table.
296- """
297- def entry_size (entry ):
294+ @ staticmethod
295+ def compute_offsets ( scope : Scope ) -> int :
296+
297+ def entry_size (var_entry ):
298298 """ For local variables and params, returns the real variable or
299299 local array size in bytes
300300 """
301- if entry .scope == SCOPE .global_ or \
302- entry .is_aliased : # aliases or global variables = 0
301+ if var_entry .scope == SCOPE .global_ or var_entry .is_aliased : # aliases or global variables = 0
303302 return 0
304303
305- if entry .class_ != CLASS .array :
306- return entry .size
307-
308- return entry .memsize
304+ if var_entry .class_ != CLASS .array :
305+ return var_entry .size
309306
310- for v in self .table [self .current_scope ].values (filter_by_opt = False ):
311- if not v .accessed :
312- if v .scope == SCOPE .parameter :
313- kind = 'Parameter'
314- v .accessed = True # HINT: Parameters must always be present even if not used!
315- if not v .byref : # HINT: byref is always marked as used: it can be used to return a value
316- warning_not_used (v .lineno , v .name , kind = kind )
307+ return var_entry .memsize
317308
318- entries = sorted (self . table [ self . current_scope ] .values (filter_by_opt = True ), key = entry_size )
309+ entries = sorted (scope .values (filter_by_opt = True ), key = entry_size )
319310 offset = 0
320311
321312 for entry in entries : # Symbols of the current level
322- if entry .class_ is CLASS .unknown :
323- self .move_to_global_scope (entry .name )
324-
325313 if entry .class_ in (CLASS .function , CLASS .label , CLASS .type_ ):
326314 continue
327315
@@ -340,6 +328,24 @@ def entry_size(entry):
340328 entry .offset = entry_size (entry ) + offset
341329 offset = entry .offset
342330
331+ return offset
332+
333+ def leave_scope (self ):
334+ """ Ends a function body and pops current scope out of the symbol table.
335+ """
336+ for v in self .table [self .current_scope ].values (filter_by_opt = False ):
337+ if not v .accessed :
338+ if v .scope == SCOPE .parameter :
339+ kind = 'Parameter'
340+ v .accessed = True # HINT: Parameters must always be present even if not used!
341+ if not v .byref : # HINT: byref is always marked as used: it can be used to return a value
342+ warning_not_used (v .lineno , v .name , kind = kind )
343+
344+ for entry in self .table [self .current_scope ].values (filter_by_opt = True ): # Symbols of the current level
345+ if entry .class_ is CLASS .unknown :
346+ self .move_to_global_scope (entry .name )
347+
348+ offset = self .compute_offsets (self .table [self .current_scope ])
343349 self .mangle = self [self .current_scope ].parent_mangle
344350 self .table .pop ()
345351 global_ .LOOPS = global_ .META_LOOPS .pop ()
0 commit comments