11#!/usr/bin/env python
22# -*- coding: utf-8 -*-
33
4- import functools
54from collections import OrderedDict
65from collections import namedtuple
76
@@ -281,15 +280,18 @@ def traverse_const(node):
281280 syntax_error_cant_convert_to_type (node .lineno , str (node .operand ), node .type_ )
282281 return
283282
284- if node .token in ('VAR' , 'VARARRAY' , 'LABEL' , 'FUNCTION' ):
283+ if node .token == 'VARARRAY' :
284+ return node .data_label
285+
286+ if node .token in ('VAR' , 'LABEL' , 'FUNCTION' ):
285287 # TODO: Check what happens with local vars and params
286288 return node .t
287289
288290 if node .token == 'CONST' :
289291 return Translator .traverse_const (node .expr )
290292
291293 if node .token == 'ARRAYACCESS' :
292- return '({} + {})' .format (node .entry .mangled , node .offset )
294+ return '({} + {})' .format (node .entry .data_label , node .offset )
293295
294296 raise InvalidCONSTexpr (node )
295297
@@ -404,7 +406,7 @@ def visit_CONST(self, node):
404406 yield node .t
405407
406408 def visit_VARARRAY (self , node ):
407- self . visit_VAR ( node )
409+ pass
408410
409411 def visit_PARAMDECL (self , node ):
410412 assert node .scope == SCOPE .parameter
@@ -516,36 +518,40 @@ def visit_ARRAYLOAD(self, node):
516518 else :
517519 offset = node .offset
518520 if scope == SCOPE .global_ :
519- self .emit ('load' + self .TSUFFIX (node .type_ ), node .entry .t , '%s + %i' % (node .entry .mangled , offset ))
521+ self .emit ('load' + self .TSUFFIX (node .type_ ), node .entry .t , '%s + %i' % (node .entry .t , offset ))
520522 elif scope == SCOPE .parameter :
521523 self .emit ('pload' + self .TSUFFIX (node .type_ ), node .t , node .entry .offset - offset )
522524 elif scope == SCOPE .local :
523- self .emit ('pload' + self .TSUFFIX (node .type_ ), node .t , - (node .entry .offset - offset ))
525+ t1 = optemps .new_t ()
526+ t2 = optemps .new_t ()
527+ t3 = optemps .new_t ()
528+ self .emit ('pload' + self .TSUFFIX (gl .PTR_TYPE ), t1 ,
529+ - (node .entry .offset - self .TYPE (gl .PTR_TYPE ).size ))
530+ self .emit ('add' + self .TSUFFIX (gl .PTR_TYPE ), t2 , t1 , node .offset )
531+ self .emit ('load' + self .TSUFFIX (node .type_ ), t3 , '*$%s' % t2 )
524532
525533 def visit_ARRAYCOPY (self , node ):
526534 tr = node .children [0 ]
527535 scope = tr .scope
528- offset = self .TYPE (gl .SIZE_TYPE ).size + self .TYPE (gl .BOUND_TYPE ).size * len (tr .bounds )
529536 if scope == SCOPE .global_ :
530- t1 = "#%s + %i " % ( tr .mangled , offset )
537+ t1 = "#%s" % tr .data_label
531538 elif scope == SCOPE .parameter :
532- self . emit ( 'paddr' , '%i' % ( tr . offset - offset ), tr . t )
533- t1 = tr .t
539+ t1 = optemps . new_t ( )
540+ self . emit ( 'pload%s' % self . TSUFFIX ( gl . PTR_TYPE ), t1 , '%i' % ( tr .offset - self . TYPE ( gl . PTR_TYPE ). size ))
534541 elif scope == SCOPE .local :
535- self . emit ( 'paddr' , '%i' % - ( tr . offset - offset ), tr . t )
536- t1 = tr .t
542+ t1 = optemps . new_t ( )
543+ self . emit ( 'pload%s' % self . TSUFFIX ( gl . PTR_TYPE ), t1 , '%i' % - ( tr .offset - self . TYPE ( gl . PTR_TYPE ). size ))
537544
538545 tr = node .children [1 ]
539546 scope = tr .scope
540- offset = self .TYPE (gl .SIZE_TYPE ).size + self .TYPE (gl .BOUND_TYPE ).size * len (tr .bounds )
541547 if scope == SCOPE .global_ :
542- t2 = "#%s + %i " % ( tr .mangled , offset )
548+ t2 = "#%s" % tr .data_label
543549 elif scope == SCOPE .parameter :
544- self . emit ( 'paddr' , '%i' % ( tr . offset - offset ), tr . t )
545- t2 = tr .t
550+ t2 = optemps . new_t ( )
551+ self . emit ( 'pload%s' % self . TSUFFIX ( gl . PTR_TYPE ), t2 , '%i' % ( tr .offset - self . TYPE ( gl . PTR_TYPE ). size ))
546552 elif scope == SCOPE .local :
547- self . emit ( 'paddr' , '%i' % - ( tr . offset - offset ), tr . t )
548- t2 = tr .t
553+ t2 = optemps . new_t ( )
554+ self . emit ( 'pload%s' % self . TSUFFIX ( gl . PTR_TYPE ), t2 , '%i' % - ( tr .offset - self . TYPE ( gl . PTR_TYPE ). size ))
549555
550556 t = optemps .new_t ()
551557 if tr .type_ != Type .string :
@@ -575,7 +581,7 @@ def visit_LETARRAY(self, node):
575581 elif scope == SCOPE .local :
576582 self .emit ('pastore' + suf , - arr .entry .offset , node .children [1 ].t )
577583 else :
578- name = arr .entry .mangled
584+ name = arr .entry .data_label
579585 if scope == SCOPE .global_ :
580586 self .emit ('store' + suf , '%s + %i' % (name , arr .offset ), node .children [1 ].t )
581587 elif scope == SCOPE .parameter :
@@ -1352,28 +1358,44 @@ def visit_VARDECL(self, node):
13521358
13531359 def visit_ARRAYDECL (self , node ):
13541360 entry = node .entry
1361+ assert entry .default_value is None or entry .addr is None , "Cannot use address and default_value at once"
1362+
13551363 if not entry .accessed :
13561364 api .errmsg .warning_not_used (entry .lineno , entry .name )
13571365 if self .O_LEVEL > 1 :
13581366 return
13591367
1368+ data_label = entry .data_label
1369+ idx_table_label = backend .tmp_label ()
13601370 l = ['%04X' % (len (node .bounds ) - 1 )] # Number of dimensions - 1
13611371
13621372 for bound in node .bounds [1 :]:
13631373 l .append ('%04X' % (bound .upper - bound .lower + 1 ))
13641374
13651375 l .append ('%02X' % node .type_ .size )
1376+ arr_data = []
13661377
1367- if entry .default_value is not None :
1368- l . extend ( Translator . array_default_value ( node . type_ , entry .default_value ) )
1378+ if entry .addr :
1379+ self . emit ( 'deflabel' , data_label , "%s" % entry .addr )
13691380 else :
1370- l .extend (['00' ] * node .size )
1381+ if entry .default_value is not None :
1382+ arr_data = Translator .array_default_value (node .type_ , entry .default_value )
1383+ else :
1384+ arr_data = ['00' ] * node .size
13711385
13721386 for alias in entry .aliased_by :
13731387 offset = 1 + 2 * entry .count + alias .offset # TODO: Generalize for multi-arch
13741388 self .emit ('deflabel' , alias .mangled , '%s + %i' % (entry .mangled , offset ))
13751389
1376- self .emit ('vard' , node .mangled , l )
1390+ self .emit ('varx' , node .mangled , self .TSUFFIX (gl .PTR_TYPE ), [idx_table_label ])
1391+
1392+ if entry .addr :
1393+ self .emit ('varx' , entry .data_ptr_label , self .TSUFFIX (gl .PTR_TYPE ), [self .traverse_const (entry .addr )])
1394+ else :
1395+ self .emit ('varx' , entry .data_ptr_label , self .TSUFFIX (gl .PTR_TYPE ), [data_label ])
1396+ self .emit ('vard' , data_label , arr_data )
1397+
1398+ self .emit ('vard' , idx_table_label , l )
13771399
13781400 if entry .lbound_used :
13791401 l = ['%04X' % len (node .bounds )] + \
@@ -1597,17 +1619,18 @@ def visit_FUNCTION(self, node):
15971619 # if self.O_LEVEL > 1:
15981620 # return
15991621
1600- if local_var .class_ == CLASS .array :
1622+ if local_var .class_ == CLASS .array and local_var . scope != SCOPE . global_ :
16011623 l = [len (local_var .bounds ) - 1 ] + [x .count for x in local_var .bounds [1 :]] # TODO Check this
16021624 q = []
16031625 for x in l :
16041626 q .append ('%02X' % (x & 0xFF ))
16051627 q .append ('%02X' % (x >> 8 ))
16061628
16071629 q .append ('%02X' % local_var .type_ .size )
1630+ r = []
16081631 if local_var .default_value is not None :
1609- q .extend (self .array_default_value (local_var .type_ , local_var .default_value ))
1610- self .emit ('lvard ' , local_var .offset , q ) # Initializes array bounds
1632+ r .extend (self .array_default_value (local_var .type_ , local_var .default_value ))
1633+ self .emit ('larrd ' , local_var .offset , q , local_var . size , r ) # Initializes array bounds
16111634 elif local_var .class_ == CLASS .const :
16121635 continue
16131636 else : # Local vars always defaults to 0, so if 0 we do nothing
@@ -1628,8 +1651,8 @@ def visit_FUNCTION(self, node):
16281651 # Now free any local string from memory.
16291652 preserve_hl = False
16301653 for local_var in node .local_symbol_table .values ():
1654+ scope = local_var .scope
16311655 if local_var .type_ == self .TYPE (TYPE .string ): # Only if it's string we free it
1632- scope = local_var .scope
16331656 if local_var .class_ != CLASS .array : # Ok just free it
16341657 if scope == SCOPE .local or (scope == SCOPE .parameter and not local_var .byref ):
16351658 if not preserve_hl :
@@ -1648,13 +1671,35 @@ def visit_FUNCTION(self, node):
16481671 preserve_hl = True
16491672 self .emit ('exchg' )
16501673
1651- offset = - local_var .offset if scope == SCOPE .local else local_var .offset
1652- elems = functools .reduce (lambda x , y : x * y , [x .count for x in local_var .bounds ])
1653- self .emit ('param' + self .TSUFFIX (gl .BOUND_TYPE ), elems )
1654- self .emit ('paddr' , offset , local_var .t )
1655- self .emit ('fparamu16' , local_var .t )
1656- self .emit ('call' , '__ARRAY_FREE' , 0 )
1657- self .REQUIRES .add ('arrayfree.asm' )
1674+ self .emit ('param' + self .TSUFFIX (gl .BOUND_TYPE ), local_var .count )
1675+ t2 = optemps .new_t ()
1676+ if scope == SCOPE .parameter :
1677+ self .emit ('pload%s' % self .TSUFFIX (gl .PTR_TYPE ), t2 ,
1678+ '%i' % (local_var .offset - self .TYPE (gl .PTR_TYPE ).size ))
1679+ elif scope == SCOPE .local :
1680+ self .emit ('pload%s' % self .TSUFFIX (gl .PTR_TYPE ), t2 ,
1681+ '%i' % - (local_var .offset - self .TYPE (gl .PTR_TYPE ).size ))
1682+ self .emit ('fparam' + self .TSUFFIX (gl .PTR_TYPE ), t2 )
1683+ self .emit ('call' , '__ARRAYSTR_FREE_MEM' , 0 ) # frees all the strings and the array itself
1684+ self .REQUIRES .add ('arraystrfree.asm' )
1685+
1686+ if local_var .class_ == CLASS .array and local_var .type_ != self .TYPE (TYPE .string ) and \
1687+ (scope == SCOPE .local or (scope == SCOPE .parameter and not local_var .byref )):
1688+ if not preserve_hl :
1689+ preserve_hl = True
1690+ self .emit ('exchg' )
1691+
1692+ t2 = optemps .new_t ()
1693+ if scope == SCOPE .parameter :
1694+ self .emit ('pload%s' % self .TSUFFIX (gl .PTR_TYPE ), t2 , '%i'
1695+ % (local_var .offset - self .TYPE (gl .PTR_TYPE ).size ))
1696+ elif scope == SCOPE .local :
1697+ self .emit ('pload%s' % self .TSUFFIX (gl .PTR_TYPE ), t2 , '%i'
1698+ % - (local_var .offset - self .TYPE (gl .PTR_TYPE ).size ))
1699+
1700+ self .emit ('fparam' + self .TSUFFIX (gl .PTR_TYPE ), t2 )
1701+ self .emit ('call' , '__MEM_FREE' , 0 )
1702+ self .REQUIRES .add ('free.asm' )
16581703
16591704 if preserve_hl :
16601705 self .emit ('exchg' )
0 commit comments