@@ -1064,8 +1064,8 @@ def __init__(
1064
1064
raise TypeError ('Only a Interface instance is allowed.' )
1065
1065
1066
1066
NoneType = type (None )
1067
- if not isinstance (init_func , ( NoneType , FunctionDef )):
1068
- raise TypeError ( 'init_func must be a FunctionDef' )
1067
+ assert ( pyccel_stage == 'syntactic' and isinstance (init_func , CodeBlock )) or \
1068
+ isinstance ( init_func , ( NoneType , FunctionDef ) )
1069
1069
1070
1070
if not isinstance (free_func , (NoneType , FunctionDef )):
1071
1071
raise TypeError ('free_func must be a FunctionDef' )
@@ -1092,21 +1092,22 @@ def __init__(
1092
1092
self ._classes = classes
1093
1093
self ._imports = imports
1094
1094
1095
- self ._internal_dictionary = {v .name :v for v in variables }
1096
- self ._internal_dictionary .update ({f .name :f for f in funcs })
1097
- self ._internal_dictionary .update ({i .name :i for i in interfaces })
1098
- self ._internal_dictionary .update ({c .name :c for c in classes })
1099
- import_mods = {i .source : [t .object for t in i .target if isinstance (t .object , Module )] for i in imports }
1100
- self ._internal_dictionary .update ({v :t [0 ] for v ,t in import_mods .items () if t })
1101
-
1102
- if init_func :
1103
- init_if = init_func .body .body [0 ]
1104
- # The init function should always contain an If block unless it is part of a wrapper
1105
- if isinstance (init_if , If ):
1106
- init_cond = init_if .blocks [0 ].condition
1107
- init_var = init_cond .args [0 ]
1108
- self ._variables .append (init_var )
1109
- self ._variable_inits .append (LiteralFalse ())
1095
+ if pyccel_stage != "syntactic" :
1096
+ self ._internal_dictionary = {v .name :v for v in variables }
1097
+ self ._internal_dictionary .update ({f .name :f for f in funcs })
1098
+ self ._internal_dictionary .update ({i .name :i for i in interfaces })
1099
+ self ._internal_dictionary .update ({c .name :c for c in classes })
1100
+ import_mods = {i .source : [t .object for t in i .target if isinstance (t .object , Module )] for i in imports }
1101
+ self ._internal_dictionary .update ({v :t [0 ] for v ,t in import_mods .items () if t })
1102
+
1103
+ if init_func :
1104
+ init_if = init_func .body .body [0 ]
1105
+ # The init function should always contain an If block unless it is part of a wrapper
1106
+ if isinstance (init_if , If ):
1107
+ init_cond = init_if .blocks [0 ].condition
1108
+ init_var = init_cond .args [0 ]
1109
+ self ._variables .append (init_var )
1110
+ self ._variable_inits .append (LiteralFalse ())
1110
1111
1111
1112
super ().__init__ (scope )
1112
1113
@@ -1278,20 +1279,29 @@ def module(self):
1278
1279
return self ._module
1279
1280
1280
1281
class Program (ScopedAstNode ):
1282
+ """
1283
+ Represents a Program in the code.
1281
1284
1282
- """Represents a Program in the code. A block consists of the following inputs
1285
+ A class representing a program in the code. A program is a set of statements
1286
+ that are executed when the module is run directly. In Python these statements
1287
+ are located in an `if __name__ == '__main__':` block.
1283
1288
1284
1289
Parameters
1285
1290
----------
1286
- variables: list
1287
- list of the variables that appear in the block .
1291
+ name : str
1292
+ The name used to identify the program (this is used for printing in Fortran) .
1288
1293
1289
- body: list
1290
- a list of statements
1294
+ variables : Iterable[Variable]
1295
+ An iterable object containing the variables that appear in the program.
1296
+
1297
+ body : CodeBlock
1298
+ An CodeBlock containing the statements in the body of the program.
1291
1299
1292
- imports: list, tuple
1293
- list of needed imports
1300
+ imports : Iterable[Import]
1301
+ An iterable object containing the imports used by the program.
1294
1302
1303
+ scope : Scope
1304
+ The scope of the program.
1295
1305
"""
1296
1306
__slots__ = ('_name' , '_variables' , '_body' , '_imports' )
1297
1307
_attribute_nodes = ('_variables' , '_body' , '_imports' )
@@ -1315,18 +1325,16 @@ def __init__(
1315
1325
if not isinstance (i , Variable ):
1316
1326
raise TypeError ('Only a Variable instance is allowed.' )
1317
1327
1318
- if not iterable (body ):
1319
- raise TypeError ('body must be an iterable' )
1320
- body = CodeBlock (body )
1328
+ assert isinstance (body , CodeBlock )
1321
1329
1322
1330
if not iterable (imports ):
1323
1331
raise TypeError ('imports must be an iterable' )
1324
1332
1325
- imports = set ( imports ) # for unicity
1326
- imports = tuple (imports )
1333
+ imports = { i : None for i in imports } # for unicity and ordering
1334
+ imports = tuple (imports . keys () )
1327
1335
1328
1336
self ._name = name
1329
- self ._variables = variables
1337
+ self ._variables = tuple ( variables )
1330
1338
self ._body = body
1331
1339
self ._imports = imports
1332
1340
super ().__init__ (scope )
@@ -4455,24 +4463,6 @@ def args_var(self):
4455
4463
4456
4464
# ...
4457
4465
4458
- class InProgram (TypedAstNode ):
4459
- """
4460
- Class representing the 'in program' test.
4461
-
4462
- Class representing the test indicating whether the code should
4463
- only be executed when the file is executed as a program. In
4464
- other words, a class representing the boolean:
4465
- `__name__ == '__main__'`
4466
- """
4467
- _rank = 0
4468
- _shape = None
4469
- _order = None
4470
- _class_type = PythonNativeBool ()
4471
- _attribute_nodes = ()
4472
- __slots__ = ()
4473
-
4474
- # ...
4475
-
4476
4466
class Decorator (PyccelAstNode ):
4477
4467
""" Class representing a function decorator.
4478
4468
For now this is just designed to handle the pyccel decorators
0 commit comments