99# the GNU General License
1010# ----------------------------------------------------------------------
1111
12- import src .api .errmsg
12+ import src .api .errmsg as errmsg
13+ import src .symbols as symbols
1314
14- from . import config
15- from . import global_
15+ from src .symbols .type_ import Type
1616
1717from .constants import CLASS
1818from .constants import SCOPE
19- from .errmsg import error
2019
20+ from . import config
21+ from . import global_
2122
2223__all__ = ['check_type' ,
2324 'check_is_declared_explicit' ,
4344# These functions trigger syntax errors if checking goal fails.
4445# ----------------------------------------------------------------------
4546
46-
4747def check_type (lineno , type_list , arg ):
4848 """ Check arg's type is one in type_list, otherwise,
4949 raises an error.
@@ -55,16 +55,16 @@ def check_type(lineno, type_list, arg):
5555 return True
5656
5757 if len (type_list ) == 1 :
58- error (lineno , "Wrong expression type '%s'. Expected '%s'" %
59- (arg .type_ , type_list [0 ]))
58+ errmsg . error (lineno , "Wrong expression type '%s'. Expected '%s'" %
59+ (arg .type_ , type_list [0 ]))
6060 else :
61- error (lineno , "Wrong expression type '%s'. Expected one of '%s'"
62- % (arg .type_ , tuple (type_list )))
61+ errmsg . error (lineno , "Wrong expression type '%s'. Expected one of '%s'"
62+ % (arg .type_ , tuple (type_list )))
6363
6464 return False
6565
6666
67- def check_is_declared_explicit (lineno , id_ , classname = 'variable' ):
67+ def check_is_declared_explicit (lineno : int , id_ : str , classname : str = 'variable' ):
6868 """ Check if the current ID is already declared.
6969 If not, triggers a "undeclared identifier" error,
7070 if the --explicit command line flag is enabled (or #pragma
@@ -80,14 +80,13 @@ def check_is_declared_explicit(lineno, id_, classname='variable'):
8080
8181
8282def check_type_is_explicit (lineno : int , id_ : str , type_ ):
83- from src .symbols .type_ import SymbolTYPE
84- assert isinstance (type_ , SymbolTYPE )
83+ assert isinstance (type_ , symbols .TYPE )
8584 if type_ .implicit :
8685 if config .OPTIONS .strict :
87- src . api . errmsg .syntax_error_undeclared_type (lineno , id_ )
86+ errmsg .syntax_error_undeclared_type (lineno , id_ )
8887
8988
90- def check_call_arguments (lineno , id_ , args ):
89+ def check_call_arguments (lineno : int , id_ : str , args ):
9190 """ Check arguments against function signature.
9291
9392 Checks every argument in a function call against a function.
@@ -103,26 +102,25 @@ def check_call_arguments(lineno, id_, args):
103102
104103 if len (args ) != len (entry .params ):
105104 c = 's' if len (entry .params ) != 1 else ''
106- error (lineno , "Function '%s' takes %i parameter%s, not %i" %
107- (id_ , len (entry .params ), c , len (args )))
105+ errmsg . error (lineno , "Function '%s' takes %i parameter%s, not %i" %
106+ (id_ , len (entry .params ), c , len (args )))
108107 return False
109108
110109 for arg , param in zip (args , entry .params ):
111110 if arg .class_ in (CLASS .var , CLASS .array ) and param .class_ != arg .class_ :
112- error (lineno , "Invalid argument '{}'" .format (arg .value ))
111+ errmsg . error (lineno , "Invalid argument '{}'" .format (arg .value ))
113112 return None
114113
115114 if not arg .typecast (param .type_ ):
116115 return False
117116
118117 if param .byref :
119- from src .symbols .var import SymbolVAR
120- if not isinstance (arg .value , SymbolVAR ):
121- error (lineno , "Expected a variable name, not an expression (parameter By Reference)" )
118+ if not isinstance (arg .value , symbols .VAR ):
119+ errmsg .error (lineno , "Expected a variable name, not an expression (parameter By Reference)" )
122120 return False
123121
124122 if arg .class_ not in (CLASS .var , CLASS .array ):
125- error (lineno , "Expected a variable or array name (parameter By Reference)" )
123+ errmsg . error (lineno , "Expected a variable or array name (parameter By Reference)" )
126124 return False
127125
128126 arg .byref = True
@@ -131,7 +129,7 @@ def check_call_arguments(lineno, id_, args):
131129 arg .value .add_required_symbol (param )
132130
133131 if entry .forwarded : # The function / sub was DECLARED but not implemented
134- error (lineno , "%s '%s' declared but not implemented" % (CLASS .to_string (entry .class_ ), entry .name ))
132+ errmsg . error (lineno , "%s '%s' declared but not implemented" % (CLASS .to_string (entry .class_ ), entry .name ))
135133 return False
136134
137135 return True
@@ -175,8 +173,7 @@ def check_pending_labels(ast):
175173
176174 tmp = global_ .SYMBOL_TABLE .get_entry (node .name )
177175 if tmp is None or tmp .class_ is CLASS .unknown :
178- error (node .lineno , 'Undeclared identifier "%s"'
179- % node .name )
176+ errmsg .error (node .lineno , f'Undeclared identifier "{ node .name } "' )
180177 else :
181178 assert tmp .class_ == CLASS .label
182179 node .to_label (node )
@@ -197,7 +194,7 @@ def check_and_make_label(lbl, lineno):
197194 if lbl == int (lbl ):
198195 id_ = str (int (lbl ))
199196 else :
200- error (lineno , 'Line numbers must be integers.' )
197+ errmsg . error (lineno , 'Line numbers must be integers.' )
201198 return None
202199 else :
203200 id_ = lbl
@@ -208,16 +205,14 @@ def check_and_make_label(lbl, lineno):
208205# ----------------------------------------------------------------------
209206# Function for checking some arguments
210207# ----------------------------------------------------------------------
211- def is_null (* symbols ):
208+ def is_null (* symbols_ ):
212209 """ True if no nodes or all the given nodes are either
213210 None, NOP or empty blocks. For blocks this applies recursively
214211 """
215- from src .symbols .symbol_ import Symbol
216-
217- for sym in symbols :
212+ for sym in symbols_ :
218213 if sym is None :
219214 continue
220- if not isinstance (sym , Symbol ):
215+ if not isinstance (sym , symbols . SYMBOL ):
221216 return False
222217 if sym .token == 'NOP' :
223218 continue
@@ -229,14 +224,12 @@ def is_null(*symbols):
229224 return True
230225
231226
232- def is_SYMBOL (token , * symbols ):
227+ def is_SYMBOL (token , * symbols_ ):
233228 """ Returns True if ALL of the given argument are AST nodes
234229 of the given token (e.g. 'BINARY')
235230 """
236- from src .symbols .symbol_ import Symbol
237-
238- assert all (isinstance (x , Symbol ) for x in symbols )
239- return all (sym .token == token for sym in symbols )
231+ assert all (isinstance (x , symbols .SYMBOL ) for x in symbols_ )
232+ return all (sym .token == token for sym in symbols_ )
240233
241234
242235def is_LABEL (* p ):
@@ -290,8 +283,6 @@ def is_var(*p):
290283
291284
292285def is_integer (* p ):
293- from src .symbols .type_ import Type
294-
295286 try :
296287 return all (i .is_basic and Type .is_integral (i .type_ ) for i in p )
297288 except Exception :
@@ -303,8 +294,6 @@ def is_integer(*p):
303294def is_unsigned (* p ):
304295 """ Returns false unless all types in p are unsigned
305296 """
306- from src .symbols .type_ import Type
307-
308297 try :
309298 return all (i .type_ .is_basic and Type .is_unsigned (i .type_ ) for i in p )
310299 except Exception :
@@ -316,8 +305,6 @@ def is_unsigned(*p):
316305def is_signed (* p ):
317306 """ Returns false unless all types in p are signed
318307 """
319- from src .symbols .type_ import Type
320-
321308 try :
322309 return all (i .type_ .is_basic and Type .is_signed (i .type_ ) for i in p )
323310 except Exception :
@@ -329,8 +316,6 @@ def is_signed(*p):
329316def is_numeric (* p ):
330317 """ Returns false unless all elements in p are of numerical type
331318 """
332- from src .symbols .type_ import Type
333-
334319 try :
335320 return all (i .type_ .is_basic and Type .is_numeric (i .type_ ) for i in p )
336321 except Exception :
@@ -354,8 +339,6 @@ def is_dynamic(*p): # TODO: Explain this better
354339 """ True if all args are dynamic (e.g. Strings, dynamic arrays, etc)
355340 The use a ptr (ref) and it might change during runtime.
356341 """
357- from src .symbols .type_ import Type
358-
359342 try :
360343 return not any (i .scope == SCOPE .global_ and i .is_basic and i .type_ != Type .string for i in p )
361344 except Exception :
@@ -367,7 +350,6 @@ def is_dynamic(*p): # TODO: Explain this better
367350def is_callable (* p ):
368351 """ True if all the args are functions and / or subroutines
369352 """
370- from src import symbols
371353 return all (isinstance (x , symbols .FUNCTION ) for x in p )
372354
373355
@@ -393,29 +375,25 @@ def common_type(a, b):
393375 """ Returns a type which is common for both a and b types.
394376 Returns None if no common types allowed.
395377 """
396- from src .symbols .type_ import SymbolBASICTYPE as BASICTYPE
397- from src .symbols .type_ import Type as TYPE
398- from src .symbols .type_ import SymbolTYPE
399-
400378 if a is None or b is None :
401379 return None
402380
403- if not isinstance (a , SymbolTYPE ):
381+ if not isinstance (a , symbols . TYPE ):
404382 a = a .type_
405383
406- if not isinstance (b , SymbolTYPE ):
384+ if not isinstance (b , symbols . TYPE ):
407385 b = b .type_
408386
409387 if a == b : # Both types are the same?
410388 return a # Returns it
411389
412- if a == TYPE .unknown and b == TYPE .unknown :
413- return BASICTYPE (global_ .DEFAULT_TYPE )
390+ if a == Type .unknown and b == Type .unknown :
391+ return symbols . BASICTYPE (global_ .DEFAULT_TYPE )
414392
415- if a == TYPE .unknown :
393+ if a == Type .unknown :
416394 return b
417395
418- if b == TYPE .unknown :
396+ if b == Type .unknown :
419397 return a
420398
421399 # TODO: This will removed / expanded in the future
@@ -424,18 +402,28 @@ def common_type(a, b):
424402
425403 types = (a , b )
426404
427- if TYPE .float_ in types :
428- return TYPE .float_
405+ if Type .float_ in types :
406+ return Type .float_
429407
430- if TYPE .fixed in types :
431- return TYPE .fixed
408+ if Type .fixed in types :
409+ return Type .fixed
432410
433- if TYPE .string in types : # TODO: Check this ??
434- return TYPE .unknown
411+ if Type .string in types : # TODO: Check this ??
412+ return Type .unknown
435413
436414 result = a if a .size > b .size else b
437415
438- if not TYPE .is_unsigned (a ) or not TYPE .is_unsigned (b ):
439- result = TYPE .to_signed (result )
416+ if not Type .is_unsigned (a ) or not Type .is_unsigned (b ):
417+ result = Type .to_signed (result )
440418
441419 return result
420+
421+
422+ def is_ender (node ) -> bool :
423+ """ Returns whether this node ends a block, that is, the following instruction won't be
424+ executed after this one
425+ """
426+ return node .token in {'END' , 'ERROR' ,
427+ 'CONTINUE_DO' , 'CONTINUE_FOR' , 'CONTINUE_WHILE' ,
428+ 'EXIT_DO' , 'EXIT_FOR' , 'EXIT_WHILE' ,
429+ 'GOTO' , 'RETURN' , 'STOP' }
0 commit comments