2121from api .errors import InvalidOperatorError
2222from api .errors import InvalidBuiltinFunctionError
2323from api .errors import InternalError
24+ from zxbpp import zxbpp
2425
2526from . import backend
2627from .backend .__float import _float
3637 'FunctionTranslator' ]
3738
3839JumpTable = namedtuple ('JumpTable' , ('label' , 'addresses' ))
40+ LabelledData = namedtuple ('LabelledData' , ('label' , 'data' ))
3941
4042
4143class Translator (TranslatorVisitor ):
@@ -1092,6 +1094,17 @@ def visit_ARRAYDECL(self, node):
10921094 if self .O_LEVEL > 1 :
10931095 return
10941096
1097+ bound_ptrs = [] # Bound tables pointers (empty if not used)
1098+ lbound_label = entry .mangled + '.__LBOUND__'
1099+ ubound_label = entry .mangled + '.__UBOUND__'
1100+
1101+ if entry .lbound_used or entry .ubound_used :
1102+ bound_ptrs = ['0' , '0' ] # NULL by default
1103+ if entry .lbound_used :
1104+ bound_ptrs [0 ] = lbound_label
1105+ if entry .ubound_used :
1106+ bound_ptrs [1 ] = ubound_label
1107+
10951108 data_label = entry .data_label
10961109 idx_table_label = backend .tmp_label ()
10971110 l = ['%04X' % (len (node .bounds ) - 1 )] # Number of dimensions - 1
@@ -1118,21 +1131,23 @@ def visit_ARRAYDECL(self, node):
11181131
11191132 if entry .addr :
11201133 self .ic_varx (entry .data_ptr_label , gl .PTR_TYPE , [self .traverse_const (entry .addr )])
1134+ if bound_ptrs :
1135+ self .ic_data (gl .PTR_TYPE , bound_ptrs )
11211136 else :
11221137 self .ic_varx (entry .data_ptr_label , gl .PTR_TYPE , [data_label ])
1138+ if bound_ptrs :
1139+ self .ic_data (gl .PTR_TYPE , bound_ptrs )
11231140 self .ic_vard (data_label , arr_data )
11241141
11251142 self .ic_vard (idx_table_label , l )
11261143
11271144 if entry .lbound_used :
1128- l = ['%04X' % len (node .bounds )] + \
1129- ['%04X' % bound .lower for bound in node .bounds ]
1130- self .ic_vard ('__LBOUND__.' + entry .mangled , l )
1145+ l = ['%04X' % bound .lower for bound in node .bounds ]
1146+ self .ic_vard (lbound_label , l )
11311147
11321148 if entry .ubound_used :
1133- l = ['%04X' % len (node .bounds )] + \
1134- ['%04X' % bound .upper for bound in node .bounds ]
1135- self .ic_vard ('__UBOUND__.' + entry .mangled , l )
1149+ l = ['%04X' % bound .upper for bound in node .bounds ]
1150+ self .ic_vard (ubound_label , l )
11361151
11371152
11381153class UnaryOpTranslator (TranslatorVisitor ):
@@ -1284,19 +1299,33 @@ def visit_SQR(self, node):
12841299 # endregion
12851300
12861301 def visit_LBOUND (self , node ):
1287- entry = node .operands [0 ]
1288- self .ic_param (gl .BOUND_TYPE , '#__LBOUND__.' + entry .mangled )
12891302 yield node .operands [1 ]
1290- self .ic_fparam (gl .BOUND_TYPE , optemps .new_t ())
1291- self .ic_call ('__BOUND' , self .TYPE (gl .BOUND_TYPE ).size )
1303+ self .ic_param (gl .BOUND_TYPE , node .operands [1 ].t )
1304+ entry = node .operands [0 ]
1305+ if entry .scope == SCOPE .global_ :
1306+ self .ic_fparam (gl .PTR_TYPE , '#{}' .format (entry .mangled ))
1307+ elif entry .scope == SCOPE .parameter :
1308+ self .ic_fparam (entry .t , entry .offset )
1309+ elif entry .scope == SCOPE .local :
1310+ self .ic_paddr (- entry .offset , entry .t )
1311+ t1 = optemps .new_t ()
1312+ self .ic_fparam (gl .PTR_TYPE , t1 )
1313+ self .ic_call ('__LBOUND' , self .TYPE (gl .BOUND_TYPE ).size )
12921314 backend .REQUIRES .add ('bound.asm' )
12931315
12941316 def visit_UBOUND (self , node ):
1295- entry = node .operands [0 ]
1296- self .ic_param (gl .BOUND_TYPE , '#__UBOUND__.' + entry .mangled )
12971317 yield node .operands [1 ]
1298- self .ic_fparam (gl .BOUND_TYPE , optemps .new_t ())
1299- self .ic_call ('__BOUND' , self .TYPE (gl .BOUND_TYPE ).size )
1318+ self .ic_param (gl .BOUND_TYPE , node .operands [1 ].t )
1319+ entry = node .operands [0 ]
1320+ if entry .scope == SCOPE .global_ :
1321+ self .ic_fparam (gl .PTR_TYPE , '#{}' .format (entry .mangled ))
1322+ elif entry .scope == SCOPE .parameter :
1323+ self .ic_fparam (entry .t , entry .offset )
1324+ elif entry .scope == SCOPE .local :
1325+ self .ic_paddr (- entry .offset , entry .t )
1326+ t1 = optemps .new_t ()
1327+ self .ic_fparam (gl .PTR_TYPE , t1 )
1328+ self .ic_call ('__UBOUND' , self .TYPE (gl .BOUND_TYPE ).size )
13001329 backend .REQUIRES .add ('bound.asm' )
13011330
13021331 def visit_USR_STR (self , node ):
@@ -1341,6 +1370,8 @@ def start(self):
13411370 self .visit (f )
13421371
13431372 def visit_FUNCTION (self , node ):
1373+ bound_tables = []
1374+
13441375 self .ic_label (node .mangled )
13451376 if node .convention == CONVENTION .fastcall :
13461377 self .ic_enter ('__fastcall__' )
@@ -1355,6 +1386,28 @@ def visit_FUNCTION(self, node):
13551386 # return
13561387
13571388 if local_var .class_ == CLASS .array and local_var .scope == SCOPE .local :
1389+ bound_ptrs = [] # Bound tables pointers (empty if not used)
1390+ lbound_label = local_var .mangled + '.__LBOUND__'
1391+ ubound_label = local_var .mangled + '.__UBOUND__'
1392+
1393+ if local_var .lbound_used or local_var .ubound_used :
1394+ bound_ptrs = ['0' , '0' ] # NULL by default
1395+ if local_var .lbound_used :
1396+ bound_ptrs [0 ] = lbound_label
1397+ if local_var .ubound_used :
1398+ bound_ptrs [1 ] = ubound_label
1399+
1400+ if bound_ptrs :
1401+ zxbpp .ID_TABLE .define ('__ZXB_USE_LOCAL_ARRAY_WITH_BOUNDS__' , lineno = 0 )
1402+
1403+ if local_var .lbound_used :
1404+ l = ['%04X' % bound .lower for bound in local_var .bounds ]
1405+ bound_tables .append (LabelledData (lbound_label , l ))
1406+
1407+ if local_var .ubound_used :
1408+ l = ['%04X' % bound .upper for bound in local_var .bounds ]
1409+ bound_tables .append (LabelledData (ubound_label , l ))
1410+
13581411 l = [len (local_var .bounds ) - 1 ] + [x .count for x in local_var .bounds [1 :]] # TODO Check this
13591412 q = []
13601413 for x in l :
@@ -1365,7 +1418,7 @@ def visit_FUNCTION(self, node):
13651418 r = []
13661419 if local_var .default_value is not None :
13671420 r .extend (self .array_default_value (local_var .type_ , local_var .default_value ))
1368- self .ic_larrd (local_var .offset , q , local_var .size , r ) # Initializes array bounds
1421+ self .ic_larrd (local_var .offset , q , local_var .size , r , bound_ptrs ) # Initializes array bounds
13691422 elif local_var .class_ == CLASS .const :
13701423 continue
13711424 else : # Local vars always defaults to 0, so if 0 we do nothing
@@ -1428,6 +1481,9 @@ def visit_FUNCTION(self, node):
14281481 else :
14291482 self .ic_leave (node .params .size )
14301483
1484+ for bound_table in bound_tables :
1485+ self .ic_vard (bound_table .label , bound_table .data )
1486+
14311487 def visit_FUNCDECL (self , node ):
14321488 """ Nested scope functions
14331489 """
0 commit comments