2222
2323
2424__all__ = [
25- ' check_type' ,
26- ' check_is_declared_explicit' ,
27- ' check_and_make_label' ,
28- ' check_type_is_explicit' ,
29- ' check_call_arguments' ,
30- ' check_pending_calls' ,
31- ' check_pending_labels' ,
32- ' is_number' ,
33- ' is_const' ,
34- ' is_static' ,
35- ' is_string' ,
36- ' is_numeric' ,
37- ' is_dynamic' ,
38- ' is_null' ,
39- ' is_unsigned' ,
40- ' common_type'
25+ " check_type" ,
26+ " check_is_declared_explicit" ,
27+ " check_and_make_label" ,
28+ " check_type_is_explicit" ,
29+ " check_call_arguments" ,
30+ " check_pending_calls" ,
31+ " check_pending_labels" ,
32+ " is_number" ,
33+ " is_const" ,
34+ " is_static" ,
35+ " is_string" ,
36+ " is_numeric" ,
37+ " is_dynamic" ,
38+ " is_null" ,
39+ " is_unsigned" ,
40+ " common_type" ,
4141]
4242
4343
4646# These functions trigger syntax errors if checking goal fails.
4747# ----------------------------------------------------------------------
4848
49+
4950def check_type (lineno , type_list , arg ):
50- """ Check arg's type is one in type_list, otherwise,
51+ """Check arg's type is one in type_list, otherwise,
5152 raises an error.
5253 """
5354 if not isinstance (type_list , list ):
@@ -57,17 +58,15 @@ def check_type(lineno, type_list, arg):
5758 return True
5859
5960 if len (type_list ) == 1 :
60- errmsg .error (lineno , "Wrong expression type '%s'. Expected '%s'" %
61- (arg .type_ , type_list [0 ]))
61+ errmsg .error (lineno , "Wrong expression type '%s'. Expected '%s'" % (arg .type_ , type_list [0 ]))
6262 else :
63- errmsg .error (lineno , "Wrong expression type '%s'. Expected one of '%s'"
64- % (arg .type_ , tuple (type_list )))
63+ errmsg .error (lineno , "Wrong expression type '%s'. Expected one of '%s'" % (arg .type_ , tuple (type_list )))
6564
6665 return False
6766
6867
69- def check_is_declared_explicit (lineno : int , id_ : str , classname : str = ' variable' ) -> bool :
70- """ Check if the current ID is already declared.
68+ def check_is_declared_explicit (lineno : int , id_ : str , classname : str = " variable" ) -> bool :
69+ """Check if the current ID is already declared.
7170 If not, triggers a "undeclared identifier" error,
7271 if the --explicit command line flag is enabled (or #pragma
7372 option strict is in use).
@@ -100,12 +99,12 @@ def check_type_is_explicit(lineno: int, id_: str, type_):
10099
101100
102101def check_call_arguments (lineno : int , id_ : str , args ):
103- """ Check arguments against function signature.
102+ """Check arguments against function signature.
104103
105- Checks every argument in a function call against a function.
106- Returns True on success.
104+ Checks every argument in a function call against a function.
105+ Returns True on success.
107106 """
108- if not global_ .SYMBOL_TABLE .check_is_declared (id_ , lineno , ' function' ):
107+ if not global_ .SYMBOL_TABLE .check_is_declared (id_ , lineno , " function" ):
109108 return False
110109
111110 if not check_is_callable (lineno , id_ ):
@@ -114,9 +113,10 @@ def check_call_arguments(lineno: int, id_: str, args):
114113 entry = global_ .SYMBOL_TABLE .get_entry (id_ )
115114
116115 if len (args ) != len (entry .params ):
117- c = 's' if len (entry .params ) != 1 else ''
118- errmsg .error (lineno , f"Function '{ id_ } ' takes { len (entry .params )} parameter{ c } , not { len (args )} " ,
119- fname = entry .filename )
116+ c = "s" if len (entry .params ) != 1 else ""
117+ errmsg .error (
118+ lineno , f"Function '{ id_ } ' takes { len (entry .params )} parameter{ c } , not { len (args )} " , fname = entry .filename
119+ )
120120 return False
121121
122122 for arg , param in zip (args , entry .params ):
@@ -129,8 +129,9 @@ def check_call_arguments(lineno: int, id_: str, args):
129129
130130 if param .byref :
131131 if not isinstance (arg .value , symbols .VAR ):
132- errmsg .error (lineno , "Expected a variable name, not an expression (parameter By Reference)" ,
133- fname = arg .filename )
132+ errmsg .error (
133+ lineno , "Expected a variable name, not an expression (parameter By Reference)" , fname = arg .filename
134+ )
134135 return False
135136
136137 if arg .class_ not in (CLASS .var , CLASS .array ):
@@ -143,15 +144,18 @@ def check_call_arguments(lineno: int, id_: str, args):
143144 arg .value .add_required_symbol (param )
144145
145146 if entry .forwarded : # The function / sub was DECLARED but not implemented
146- errmsg .error (lineno , "%s '%s' declared but not implemented" % (CLASS .to_string (entry .class_ ), entry .name ),
147- fname = entry .filename )
147+ errmsg .error (
148+ lineno ,
149+ "%s '%s' declared but not implemented" % (CLASS .to_string (entry .class_ ), entry .name ),
150+ fname = entry .filename ,
151+ )
148152 return False
149153
150154 return True
151155
152156
153157def check_pending_calls ():
154- """ Calls the above function for each pending call of the current scope
158+ """Calls the above function for each pending call of the current scope
155159 level
156160 """
157161 result = True
@@ -164,7 +168,7 @@ def check_pending_calls():
164168
165169
166170def check_pending_labels (ast ):
167- """ Iteratively traverses the node looking for ID with no class set,
171+ """Iteratively traverses the node looking for ID with no class set,
168172 marks them as labels, and check they've been declared.
169173
170174 This way we avoid stack overflow for high line-numbered listings.
@@ -183,7 +187,7 @@ def check_pending_labels(ast):
183187 for x in node .children :
184188 pending .append (x )
185189
186- if node .token != ' VAR' or (node .token == ' VAR' and node .class_ is not CLASS .unknown ):
190+ if node .token != " VAR" or (node .token == " VAR" and node .class_ is not CLASS .unknown ):
187191 continue
188192
189193 tmp = global_ .SYMBOL_TABLE .get_entry (node .name )
@@ -199,7 +203,7 @@ def check_pending_labels(ast):
199203
200204
201205def check_and_make_label (lbl : Union [str , int , float ], lineno ):
202- """ Checks if the given label (or line number) is valid and, if so,
206+ """Checks if the given label (or line number) is valid and, if so,
203207 returns a label object.
204208 :param lbl: Line number of label (string)
205209 :param lineno: Line number in the basic source code for error reporting
@@ -209,7 +213,7 @@ def check_and_make_label(lbl: Union[str, int, float], lineno):
209213 if lbl == int (lbl ):
210214 id_ = str (int (lbl ))
211215 else :
212- errmsg .error (lineno , ' Line numbers must be integers.' )
216+ errmsg .error (lineno , " Line numbers must be integers." )
213217 return None
214218 else :
215219 id_ = lbl
@@ -221,17 +225,17 @@ def check_and_make_label(lbl: Union[str, int, float], lineno):
221225# Function for checking some arguments
222226# ----------------------------------------------------------------------
223227def is_null (* symbols_ ):
224- """ True if no nodes or all the given nodes are either
228+ """True if no nodes or all the given nodes are either
225229 None, NOP or empty blocks. For blocks this applies recursively
226230 """
227231 for sym in symbols_ :
228232 if sym is None :
229233 continue
230234 if not isinstance (sym , symbols .SYMBOL ):
231235 return False
232- if sym .token == ' NOP' :
236+ if sym .token == " NOP" :
233237 continue
234- if sym .token == ' BLOCK' :
238+ if sym .token == " BLOCK" :
235239 if not is_null (* sym .children ):
236240 return False
237241 continue
@@ -240,61 +244,57 @@ def is_null(*symbols_):
240244
241245
242246def is_SYMBOL (token , * symbols_ ):
243- """ Returns True if ALL of the given argument are AST nodes
247+ """Returns True if ALL of the given argument are AST nodes
244248 of the given token (e.g. 'BINARY')
245249 """
246250 assert all (isinstance (x , symbols .SYMBOL ) for x in symbols_ )
247251 return all (sym .token == token for sym in symbols_ )
248252
249253
250254def is_LABEL (* p ):
251- return is_SYMBOL (' LABEL' , * p )
255+ return is_SYMBOL (" LABEL" , * p )
252256
253257
254258def is_string (* p ):
255- return is_SYMBOL (' STRING' , * p )
259+ return is_SYMBOL (" STRING" , * p )
256260
257261
258262def is_const (* p ):
259- """ A constant in the program, like CONST a = 5
260- """
261- return is_SYMBOL ('VAR' , * p ) and all (x .class_ == CLASS .const for x in p )
263+ """A constant in the program, like CONST a = 5"""
264+ return is_SYMBOL ("VAR" , * p ) and all (x .class_ == CLASS .const for x in p )
262265
263266
264267def is_CONST (* p ):
265- """ Not to be confused with the above.
268+ """Not to be confused with the above.
266269 Check it's a CONSTant expression
267270 """
268- return is_SYMBOL (' CONST' , * p )
271+ return is_SYMBOL (" CONST" , * p )
269272
270273
271274def is_static (* p ):
272- """ A static value (does not change at runtime)
275+ """A static value (does not change at runtime)
273276 which is known at compile time
274277 """
275- return all (is_CONST (x ) or
276- is_number (x ) or
277- is_const (x )
278- for x in p )
278+ return all (is_CONST (x ) or is_number (x ) or is_const (x ) for x in p )
279279
280280
281281def is_number (* p ):
282- """ Returns True if ALL of the arguments are AST nodes
282+ """Returns True if ALL of the arguments are AST nodes
283283 containing NUMBER or numeric CONSTANTS
284284 """
285285 try :
286- return all (i .token == ' NUMBER' or (i .token == 'ID' and i .class_ == CLASS .const ) for i in p )
286+ return all (i .token == " NUMBER" or (i .token == "ID" and i .class_ == CLASS .const ) for i in p )
287287 except Exception :
288288 pass
289289
290290 return False
291291
292292
293293def is_var (* p ):
294- """ Returns True if ALL of the arguments are AST nodes
294+ """Returns True if ALL of the arguments are AST nodes
295295 containing ID
296296 """
297- return is_SYMBOL (' VAR' , * p )
297+ return is_SYMBOL (" VAR" , * p )
298298
299299
300300def is_integer (* p ):
@@ -307,8 +307,7 @@ def is_integer(*p):
307307
308308
309309def is_unsigned (* p ):
310- """ Returns false unless all types in p are unsigned
311- """
310+ """Returns false unless all types in p are unsigned"""
312311 try :
313312 return all (i .type_ .is_basic and Type .is_unsigned (i .type_ ) for i in p )
314313 except Exception :
@@ -318,8 +317,7 @@ def is_unsigned(*p):
318317
319318
320319def is_signed (* p ):
321- """ Returns false unless all types in p are signed
322- """
320+ """Returns false unless all types in p are signed"""
323321 try :
324322 return all (i .type_ .is_basic and Type .is_signed (i .type_ ) for i in p )
325323 except Exception :
@@ -329,8 +327,7 @@ def is_signed(*p):
329327
330328
331329def is_numeric (* p ):
332- """ Returns false unless all elements in p are of numerical type
333- """
330+ """Returns false unless all elements in p are of numerical type"""
334331 try :
335332 return all (i .type_ .is_basic and Type .is_numeric (i .type_ ) for i in p )
336333 except Exception :
@@ -340,8 +337,7 @@ def is_numeric(*p):
340337
341338
342339def is_type (type_ , * p ):
343- """ True if all args have the same type
344- """
340+ """True if all args have the same type"""
345341 try :
346342 return all (i .type_ == type_ for i in p )
347343 except Exception :
@@ -351,7 +347,7 @@ def is_type(type_, *p):
351347
352348
353349def is_dynamic (* p ): # TODO: Explain this better
354- """ True if all args are dynamic (e.g. Strings, dynamic arrays, etc)
350+ """True if all args are dynamic (e.g. Strings, dynamic arrays, etc)
355351 The use a ptr (ref) and it might change during runtime.
356352 """
357353 try :
@@ -363,13 +359,12 @@ def is_dynamic(*p): # TODO: Explain this better
363359
364360
365361def is_callable (* p ):
366- """ True if all the args are functions and / or subroutines
367- """
362+ """True if all the args are functions and / or subroutines"""
368363 return all (isinstance (x , symbols .FUNCTION ) for x in p )
369364
370365
371366def is_block_accessed (block ):
372- """ Returns True if a block is "accessed". A block of code is accessed if
367+ """Returns True if a block is "accessed". A block of code is accessed if
373368 it has a LABEL and it is used in a GOTO, GO SUB or @address access
374369 :param block: A block of code (AST node)
375370 :return: True / False depending if it has labels accessed or not
@@ -381,13 +376,12 @@ def is_block_accessed(block):
381376
382377
383378def is_temporary_value (node ) -> bool :
384- """ Returns if the AST node value is a variable or a temporary copy in the heap.
385- """
386- return node .token not in ('PARAMDECL' , 'STRING' , 'VAR' ) and node .t [0 ] not in ('_' , '#' )
379+ """Returns if the AST node value is a variable or a temporary copy in the heap."""
380+ return node .token not in ("PARAMDECL" , "STRING" , "VAR" ) and node .t [0 ] not in ("_" , "#" )
387381
388382
389383def common_type (a , b ):
390- """ Returns a type which is common for both a and b types.
384+ """Returns a type which is common for both a and b types.
391385 Returns None if no common types allowed.
392386 """
393387 if a is None or b is None :
@@ -435,17 +429,26 @@ def common_type(a, b):
435429
436430
437431def is_ender (node ) -> bool :
438- """ Returns whether this node ends a block, that is, the following instruction won't be
432+ """Returns whether this node ends a block, that is, the following instruction won't be
439433 executed after this one
440434 """
441- return node .token in {'END' , 'ERROR' ,
442- 'CONTINUE_DO' , 'CONTINUE_FOR' , 'CONTINUE_WHILE' ,
443- 'EXIT_DO' , 'EXIT_FOR' , 'EXIT_WHILE' ,
444- 'GOTO' , 'RETURN' , 'STOP' }
435+ return node .token in {
436+ "END" ,
437+ "ERROR" ,
438+ "CONTINUE_DO" ,
439+ "CONTINUE_FOR" ,
440+ "CONTINUE_WHILE" ,
441+ "EXIT_DO" ,
442+ "EXIT_FOR" ,
443+ "EXIT_WHILE" ,
444+ "GOTO" ,
445+ "RETURN" ,
446+ "STOP" ,
447+ }
445448
446449
447450def check_class (node , class_ : CLASS , lineno : int ) -> bool :
448- """ Returns whether the given node has CLASS.unknown or the given class_.
451+ """Returns whether the given node has CLASS.unknown or the given class_.
449452 It False, it will emit a syntax error
450453 """
451454 if node .class_ == CLASS .unknown or node .class_ == class_ :
0 commit comments