44# See the file CONTRIBUTORS.md for copyright details.
55# See https://www.gnu.org/licenses/agpl-3.0.html for details.
66# --------------------------------------------------------------------
7+ from typing import Any
78
89from src .api import config , errmsg , global_
910from src .api .constants import CLASS , SCOPE
@@ -82,13 +83,13 @@ def check_is_callable(lineno: int, id_: str) -> bool:
8283
8384
8485def check_type_is_explicit (lineno : int , id_ : str , type_ ):
85- assert isinstance (type_ , symbols .TYPE )
86+ assert isinstance (type_ , symbols .TYPEREF )
8687 if type_ .implicit :
8788 if config .OPTIONS .strict :
8889 errmsg .syntax_error_undeclared_type (lineno , id_ )
8990
9091
91- def check_call_arguments (lineno : int , id_ : str , args , filename : str ):
92+ def check_call_arguments (lineno : int , id_ : str , args : symbols . ARGLIST , filename : str ) -> bool :
9293 """Check arguments against function signature.
9394
9495 Checks every argument in a function call against a function.
@@ -128,8 +129,10 @@ def check_call_arguments(lineno: int, id_: str, args, filename: str):
128129 for param in entry .ref .params :
129130 if param .name in named_args :
130131 continue
132+
131133 if param .default_value is None :
132134 break
135+
133136 arg = symbols .ARGUMENT (param .default_value , lineno = lineno , byref = False , name = param .name )
134137 symbols .ARGLIST .make_node (args , arg )
135138 named_args [arg .name ] = arg
@@ -151,7 +154,7 @@ def check_call_arguments(lineno: int, id_: str, args, filename: str):
151154
152155 if arg .class_ in (CLASS .var , CLASS .array ) and param .class_ != arg .class_ :
153156 errmsg .error (lineno , f"Invalid argument '{ arg .value } '" , fname = arg .filename )
154- return None
157+ return False
155158
156159 if not arg .typecast (param .type_ ):
157160 return False
@@ -252,57 +255,62 @@ def check_and_make_label(lbl: str | int | float, lineno):
252255# ----------------------------------------------------------------------
253256# Function for checking some arguments
254257# ----------------------------------------------------------------------
255- def is_null (* symbols_ ) :
258+ def is_null (* symbols_ : Any ) -> bool :
256259 """True if no nodes or all the given nodes are either
257260 None, NOP or empty blocks. For blocks this applies recursively
258261 """
259262 for sym in symbols_ :
260263 if sym is None :
261264 continue
265+
262266 if not isinstance (sym , symbols .SYMBOL ):
263267 return False
268+
264269 if sym .token == "NOP" :
265270 continue
271+
266272 if sym .token == "BLOCK" :
267273 if not is_null (* sym .children ):
268274 return False
269275 continue
276+
270277 return False
278+
271279 return True
272280
273281
274- def is_SYMBOL (token : str , * symbols_ : symbols .SYMBOL ):
282+ def is_SYMBOL (token : str , * symbols_ : symbols .SYMBOL ) -> bool :
275283 """Returns True if ALL the given argument are AST nodes
276284 of the given token (e.g. 'BINARY')
277285 """
278286 assert all (isinstance (x , symbols .SYMBOL ) for x in symbols_ )
279287 return all (sym .token == token for sym in symbols_ )
280288
281289
282- def is_LABEL (* p ) :
290+ def is_LABEL (* p : symbols . SYMBOL ) -> bool :
283291 return is_SYMBOL ("LABEL" , * p )
284292
285293
286- def is_string (* p ) :
294+ def is_string (* p : symbols . SYMBOL ) -> bool :
287295 """Returns True if ALL the arguments are AST nodes
288296 containing STRING or string CONSTANTS
289297 """
290298 return all (is_SYMBOL ("STRING" , x ) or is_const (x ) and is_type (Type .string , x ) for x in p )
291299
292300
293- def is_const (* p ) :
301+ def is_const (* p : symbols . SYMBOL ) -> bool :
294302 """A constant in the program, like CONST a = 5"""
295303 return is_SYMBOL ("CONST" , * p )
296304
297305
298- def is_CONST (* p ) :
306+ def is_CONST (* p : symbols . SYMBOL ) -> bool :
299307 """Not to be confused with the above.
300308 Check it's a CONSTant EXPRession
301309 """
302310 return is_SYMBOL ("CONSTEXPR" , * p )
303311
304312
305- def is_static (* p ) :
313+ def is_static (* p : symbols . SYMBOL ) -> bool :
306314 """A static value (does not change at runtime)
307315 which is known at compile time
308316 """
@@ -313,7 +321,12 @@ def is_number(*p):
313321 """Returns True if ALL the arguments are AST nodes
314322 containing NUMBER or numeric CONSTANTS
315323 """
316- return all (isinstance (i , Symbol ) and i .token in ("NUMBER" , "CONST" ) and Type .is_numeric (i .type_ ) for i in p )
324+ return all (
325+ isinstance (i , Symbol )
326+ and i .token in ("NUMBER" , "CONST" )
327+ and Type .is_numeric (i .type_ .type_ if isinstance (i .type_ , symbols .TYPEREF ) else i .type_ )
328+ for i in p
329+ )
317330
318331
319332def is_static_str (* p ):
@@ -330,8 +343,8 @@ def is_var(*p):
330343def is_unsigned (* p ):
331344 """Returns false unless all types in p are unsigned"""
332345 try :
333- return all (i .type_ .is_basic and Type .is_unsigned (i .type_ ) for i in p )
334- except Exception :
346+ return all (i .type_ .final . is_basic and Type .is_unsigned (i .type_ . final ) for i in p )
347+ except ( Exception ,) :
335348 pass
336349
337350 return False
@@ -341,7 +354,7 @@ def is_signed(*p):
341354 """Returns false unless all types in p are signed"""
342355 try :
343356 return all (i .type_ .is_basic and Type .is_signed (i .type_ ) for i in p )
344- except Exception :
357+ except ( Exception ,) :
345358 pass
346359
347360 return False
@@ -350,8 +363,8 @@ def is_signed(*p):
350363def is_numeric (* p ):
351364 """Returns false unless all elements in p are of numerical type"""
352365 try :
353- return all (i .type_ .is_basic and Type .is_numeric (i .type_ ) for i in p )
354- except Exception :
366+ return all (i .type_ .final . is_basic and Type .is_numeric (i .type_ . final ) for i in p )
367+ except ( Exception ,) :
355368 pass
356369
357370 return False
@@ -361,7 +374,7 @@ def is_type(type_, *p):
361374 """True if all args have the same type"""
362375 try :
363376 return all (i .type_ == type_ for i in p )
364- except Exception :
377+ except ( Exception ,) :
365378 pass
366379
367380 return False
@@ -373,7 +386,7 @@ def is_dynamic(*p): # TODO: Explain this better
373386 """
374387 try :
375388 return not any (i .scope == SCOPE .global_ and i .is_basic and i .type_ != Type .string for i in p )
376- except Exception :
389+ except ( Exception ,) :
377390 pass
378391
379392 return False
@@ -384,11 +397,22 @@ def is_callable(*p):
384397 return all (x .token == "FUNCTION" for x in p )
385398
386399
387- def is_block_accessed (block ):
388- """Returns True if a block is "accessed". A block of code is accessed if
389- it has a LABEL and it is used in a GOTO, GO SUB or @address access
390- :param block: A block of code (AST node)
391- :return: True / False depending if it has labels accessed or not
400+ def is_block_accessed (block : Symbol ):
401+ """
402+ Checks if a code block or any of its nested children has been accessed.
403+
404+ This function evaluates whether a specific block has been accessed. If the
405+ block is not directly accessed, it recursively checks its child blocks.
406+
407+ Args:
408+ block: The code block to be evaluated. The block is assumed to have
409+ attributes `accessed` (a boolean indicating if the block has
410+ been accessed) and `children` (an iterable of nested child
411+ blocks).
412+
413+ Returns:
414+ bool: True if the block or at least one of its nested child blocks has
415+ been accessed; False otherwise.
392416 """
393417 if is_LABEL (block ) and block .accessed :
394418 return True
@@ -401,17 +425,17 @@ def is_temporary_value(node) -> bool:
401425 return node .token not in ("STRING" , "VAR" ) and node .t [0 ] not in ("_" , "#" )
402426
403427
404- def common_type (a : symbols .TYPE | Type | None , b : symbols .TYPE | Type | None ) -> symbols .TYPE | Type | None :
428+ def common_type (a : symbols .TYPING , b : symbols .TYPING ) -> symbols .TYPE | None :
405429 """Returns a type which is common for both a and b types.
406430 Returns None if no common types allowed.
407431 """
408- if a is None or b is None :
409- return None
432+ assert isinstance ( a , symbols . TYPING )
433+ assert isinstance ( b , symbols . TYPING )
410434
411- if not isinstance (a , symbols .TYPE ):
435+ if isinstance (a , symbols .TYPEREF ):
412436 a = a .type_
413437
414- if not isinstance (b , symbols .TYPE ):
438+ if isinstance (b , symbols .TYPEREF ):
415439 b = b .type_
416440
417441 if a == b : # Both types are the same?
@@ -449,7 +473,7 @@ def common_type(a: symbols.TYPE | Type | None, b: symbols.TYPE | Type | None) ->
449473 return result
450474
451475
452- def is_ender (node ) -> bool :
476+ def is_ender (node : symbols . SYMBOL ) -> bool :
453477 """Returns whether this node ends a block, that is, the following instruction won't be
454478 executed after this one
455479 """
@@ -468,7 +492,7 @@ def is_ender(node) -> bool:
468492 }
469493
470494
471- def check_class (node , class_ : CLASS , lineno : int ) -> bool :
495+ def check_class (node : symbols . ID , class_ : CLASS , lineno : int ) -> bool :
472496 """Returns whether the given node has CLASS.unknown or the given class_.
473497 It False, it will emit a syntax error
474498 """
0 commit comments