0
# AST Transformation
1
2
Powerful transformation system for adapting Fortran AST to be suitable for Python wrapping, including type conversions, intent handling, code restructuring, and optimization for f2py compatibility.
3
4
## Capabilities
5
6
### Main Transformation Functions
7
8
High-level transformation functions that orchestrate the complete AST modification process.
9
10
```python { .api }
11
def transform_to_generic_wrapper(tree, types, callbacks, constructors, destructors,
12
sizeof_fortran_t, string_lengths, init_lines,
13
abort_func, argument_name_map, move_methods,
14
shorten_routine_names, modules_for_type,
15
default_to_inout, comp_tuple_dtype):
16
"""Transform AST for generic wrapper generation."""
17
18
def transform_to_f90_wrapper(tree, types, callbacks, constructors, destructors,
19
sizeof_fortran_t, string_lengths, init_lines,
20
abort_func, argument_name_map, move_methods,
21
shorten_routine_names, modules_for_type,
22
default_to_inout, comp_tuple_dtype):
23
"""Transform AST for Fortran 90 wrapper generation."""
24
25
def transform_to_py_wrapper(tree, types):
26
"""Transform AST for Python wrapper generation."""
27
```
28
29
### Transformer Classes
30
31
Specialized transformer classes that perform specific AST modifications.
32
33
#### Access and Symbol Management
34
35
```python { .api }
36
class AccessUpdater(FortranTransformer):
37
"""Update access control attributes (public/private)."""
38
39
class PrivateSymbolsRemover(FortranTransformer):
40
"""Remove private symbols that should not be wrapped."""
41
42
class UnwrappablesRemover(FortranTransformer):
43
"""Remove constructs that cannot be wrapped by f2py."""
44
```
45
46
#### Type and Array Handling
47
48
```python { .api }
49
class StringLengthConverter(FortranVisitor):
50
"""Convert Fortran string length specifications."""
51
52
class ArrayDimensionConverter(FortranVisitor):
53
"""Convert array dimension specifications for Python compatibility."""
54
55
class NormaliseTypes(FortranVisitor):
56
"""Normalize Fortran type names and kind specifications."""
57
```
58
59
#### Procedure Transformation
60
61
```python { .api }
62
class MethodFinder(FortranTransformer):
63
"""Identify and mark methods for object-oriented wrapping."""
64
65
class ConstructorExcessToClassMethod(FortranTransformer):
66
"""Convert excess constructor arguments to class methods."""
67
68
class FunctionToSubroutineConverter(FortranTransformer):
69
"""Convert functions to subroutines for easier wrapping."""
70
71
class IntentOutToReturnValues(FortranTransformer):
72
"""Convert intent(out) arguments to return values."""
73
```
74
75
#### Python Compatibility
76
77
```python { .api }
78
class RenameReservedWords(FortranVisitor):
79
"""Rename Fortran identifiers that conflict with Python keywords."""
80
81
class RenameArgumentsPython(FortranVisitor):
82
"""Rename arguments to follow Python naming conventions."""
83
84
class RenameInterfacesPython(FortranVisitor):
85
"""Rename interfaces for Python compatibility."""
86
87
class ReorderOptionalArgumentsPython(FortranVisitor):
88
"""Reorder optional arguments to match Python conventions."""
89
```
90
91
#### Interface and Binding Resolution
92
93
```python { .api }
94
class SetInterfaceProcedureCallNames(FortranVisitor):
95
"""Set procedure call names for interface resolution."""
96
97
class ResolveInterfacePrototypes(FortranTransformer):
98
"""Resolve procedure prototypes within interfaces."""
99
100
class ResolveBindingPrototypes(FortranTransformer):
101
"""Resolve type-bound procedure prototypes."""
102
103
class BindConstructorInterfaces(FortranTransformer):
104
"""Bind constructor procedures to interfaces."""
105
```
106
107
#### Filtering and Selection
108
109
```python { .api }
110
class OnlyAndSkip(FortranTransformer):
111
"""Apply only/skip filters to select items for wrapping."""
112
```
113
114
### Utility Transformation Functions
115
116
#### Symbol and Access Management
117
118
```python { .api }
119
def remove_private_symbols(node, force_public=None):
120
"""Remove private symbols from AST nodes."""
121
122
def fix_subroutine_uses_clauses(tree, types):
123
"""Fix USE clauses in subroutine definitions."""
124
125
def fix_element_uses_clauses(tree, types):
126
"""Fix USE clauses for derived type elements."""
127
```
128
129
#### Argument and Intent Handling
130
131
```python { .api }
132
def set_intent(attributes, intent):
133
"""Set intent specification for procedure arguments."""
134
135
def convert_derived_type_arguments(tree, init_lines, sizeof_fortran_t):
136
"""Convert derived type arguments to opaque handles."""
137
138
def convert_array_intent_out_to_intent_inout(tree):
139
"""Convert array intent(out) to intent(inout) for safety."""
140
```
141
142
#### Interface and Type Management
143
144
```python { .api }
145
def collapse_single_interfaces(tree):
146
"""Collapse interfaces containing only one procedure."""
147
148
def add_missing_constructors(tree):
149
"""Add missing constructor routines for derived types."""
150
151
def add_missing_destructors(tree):
152
"""Add missing destructor routines for derived types."""
153
154
def create_super_types(tree, types):
155
"""Create super-type hierarchies for complex types."""
156
```
157
158
#### Dependency Analysis
159
160
```python { .api }
161
def find_referenced_modules(mods, tree):
162
"""Find all modules referenced by the tree."""
163
164
def find_referenced_types(mods, tree):
165
"""Find all types referenced by the tree."""
166
```
167
168
#### Type and Array Processing
169
170
```python { .api }
171
def append_type_dimension(tree, types):
172
"""Add dimension information to type definitions."""
173
174
def fix_subroutine_type_arrays(tree, types):
175
"""Fix array handling in subroutine signatures."""
176
177
def extract_dimensions_parameters(d, tree):
178
"""Extract dimension parameters from array specifications."""
179
```
180
181
#### Name Management
182
183
```python { .api }
184
def shorten_long_name(name):
185
"""Shorten excessively long routine and type names."""
186
```
187
188
## Usage Examples
189
190
### Basic Transformation
191
192
```python
193
from f90wrap.transform import transform_to_f90_wrapper
194
195
# Basic transformation for F90 wrapper
196
tree = parse_source_files(['source.f90'])
197
types = find_types(tree)
198
transform_to_f90_wrapper(tree, types, [], [], [],
199
sizeof_fortran_t, {}, [],
200
'f90wrap_abort', {}, False,
201
False, {}, False, False)
202
```
203
204
### Custom Transformation Pipeline
205
206
```python
207
from f90wrap.transform import (PrivateSymbolsRemover, RenameReservedWords,
208
IntentOutToReturnValues)
209
210
# Apply specific transformers
211
private_remover = PrivateSymbolsRemover()
212
private_remover.visit(tree)
213
214
rename_transformer = RenameReservedWords()
215
rename_transformer.visit(tree)
216
217
intent_transformer = IntentOutToReturnValues()
218
intent_transformer.visit(tree)
219
```
220
221
### Type and Constructor Management
222
223
```python
224
from f90wrap.transform import (add_missing_constructors, add_missing_destructors,
225
create_super_types)
226
227
# Add missing constructors and destructors
228
add_missing_constructors(tree)
229
add_missing_destructors(tree)
230
231
# Create type hierarchies
232
types = find_types(tree)
233
create_super_types(tree, types)
234
```
235
236
### Argument and Interface Processing
237
238
```python
239
from f90wrap.transform import (convert_array_intent_out_to_intent_inout,
240
collapse_single_interfaces,
241
ReorderOptionalArgumentsPython)
242
243
# Convert array intents for safety
244
convert_array_intent_out_to_intent_inout(tree)
245
246
# Simplify interfaces
247
collapse_single_interfaces(tree)
248
249
# Reorder arguments for Python
250
reorder_transformer = ReorderOptionalArgumentsPython()
251
reorder_transformer.visit(tree)
252
```
253
254
## Transformation Pipeline
255
256
The typical transformation pipeline follows these stages:
257
258
1. **Cleanup Stage**: Remove private symbols, unwrappable constructs
259
2. **Type Processing**: Normalize types, handle derived type arguments
260
3. **Procedure Processing**: Convert functions to subroutines, handle intents
261
4. **Python Compatibility**: Rename reserved words, reorder arguments
262
5. **Interface Resolution**: Resolve prototypes, bind constructors
263
6. **Optimization**: Collapse interfaces, shorten names
264
7. **Validation**: Ensure consistency and completeness
265
266
## Transformation Options
267
268
### Constructor and Destructor Handling
269
270
- **Automatic Detection**: Find type-bound procedures that act as constructors/destructors
271
- **Manual Specification**: Explicitly specify constructor/destructor routines
272
- **Missing Addition**: Automatically add missing constructors/destructors
273
274
### Intent Handling
275
276
- **Safety Conversion**: Convert intent(out) arrays to intent(inout)
277
- **Default Intent**: Set default intent for arguments without explicit intent
278
- **Return Value Conversion**: Convert intent(out) scalars to return values
279
280
### Name Management
281
282
- **Reserved Word Avoidance**: Rename identifiers that conflict with Python keywords
283
- **Convention Adaptation**: Adapt naming to Python conventions
284
- **Length Management**: Shorten excessively long names for compatibility
285
286
### Type System Adaptations
287
288
- **Kind Normalization**: Normalize Fortran kind specifications
289
- **String Length Handling**: Process string length parameters
290
- **Array Dimension Processing**: Handle complex array dimension specifications
291
292
## Error Handling
293
294
The transformation system provides comprehensive error detection:
295
296
- **Circular Dependencies**: Detect and report circular module dependencies
297
- **Missing Types**: Identify references to undefined types
298
- **Invalid Constructs**: Flag constructs that cannot be wrapped
299
- **Consistency Checks**: Verify AST consistency after transformations