Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def generic_visit(self, node):
print(' ' * self.depth + str(node))
self.depth += 1
FortranVisitor.generic_visit(self, node)
self.depth -= 1
new_attribs = []
for attrib in node.attributes:
if attrib.startswith('dimension('):
new_attribs.append(attrib.replace(old_name, new_name))
else:
new_attribs.append(attrib)
node.attributes = new_attribs
return self.generic_visit(node)
visit_Procedure = visit_Argument
visit_Element = visit_Argument
visit_Module = visit_Argument
visit_Type = visit_Argument
class RenameArgumentsPython(ft.FortranVisitor):
def __init__(self, types):
self.types = types
def visit_Procedure(self, node):
if hasattr(node, 'method_name'):
if 'constructor' in node.attributes:
node.ret_val[0].py_name = 'self'
elif len(node.arguments) >= 1 and node.arguments[0].type in self.types:
node.arguments[0].py_name = 'self'
elif hasattr(node, 'attributes') and 'callback' in node.attributes:
self.visit_Argument(node)
return self.generic_visit(node)
def visit_Argument(self, node):
if not hasattr(node, 'py_name'):
node.py_name = node.name
continue
elif not isinstance(value, Fortran):
new_values.extend(value)
continue
new_values.append(value)
old_value[:] = new_values
elif isinstance(old_value, Fortran):
new_node = self.visit(old_value)
if new_node is None:
delattr(node, field)
else:
setattr(node, field, new_node)
return node
class FortranTreeDumper(FortranVisitor):
"""
Subclass of `FortranVisitor` which prints a textual representation
of the Fortran parse tree.
"""
def __init__(self):
self.depth = 0
def generic_visit(self, node):
print(' ' * self.depth + str(node))
self.depth += 1
FortranVisitor.generic_visit(self, node)
self.depth -= 1
def dump(node):
"""Print contents of Fortran parse tree starting at `node`."""
FortranTreeDumper().visit(node)
class NormaliseTypes(ft.FortranVisitor):
"""
Convert all type names to standard form and resolve kind names
"""
def __init__(self, kind_map):
self.kind_map = kind_map
def visit_Declaration(self, node):
node.type = ft.normalise_type(node.type, self.kind_map)
return self.generic_visit(node)
visit_Argument = visit_Declaration
class SetInterfaceProcedureCallNames(ft.FortranVisitor):
"""
Set call names of procedures within overloaded interfaces to the name of the interface
"""
def visit_Interface(self, node):
for proc in node.procedures:
logging.info('setting call_name of %s to %s' % (proc.name, node.name))
proc.call_name = node.name
return node
def transform_to_generic_wrapper(tree, types, callbacks, constructors,
destructors, short_names, init_lines,
only_subs, only_mods, argument_name_map,
move_methods, shorten_routine_names,
modules_for_type, remove_optional_arguments):
ns = names[:n]
del names[:n]
b = copy.copy(a)
b.name = ', '.join(ns)
alist.append(b)
rev_dict[k] = (alist, min([x[1] for x in rev_dict[k]]))
# Sort by original appearance order of first name
keys = rev_dict.keys()
keys.sort(key=lambda x: rev_dict[x][1])
return keys, rev_dict, func_args
class LatexGenerator(ft.FortranVisitor, LatexOutput):
def __init__(self, stream, fn='', short_doc=False):
ft.FortranVisitor.__init__(self)
LatexOutput.__init__(self)
self.stream = stream
self.depth = 0
self.compact = False
self.is_ret_val = False
self.short_doc = short_doc
def visit_Program(self, node):
if node.doc:
if node.doc[0].strip() == 'OMIT':
return
# Try to get length of string arguments
if not string_length == '*' and not all([x in '0123456789' for x in string_length]):
string_length = self.string_lengths.get(string_length, self.default_string_length)
# Default string length for intent(out) strings
if string_length == '*' and 'intent(out)' in node.attributes:
string_length = self.default_string_length
except ValueError:
string_length = 1
node.type = 'character*(%s)' % str(string_length)
class ArrayDimensionConverter(ft.FortranVisitor):
"""
Transform unspecified dimensions into additional dummy arguments
e.g. the following code
subroutine foo(a)
integer a(:)
end subroutine foo
becomes:
subroutine foo(a, n0)
integer a(n0)
integer n0
!f2py intent(hide), depend(a) :: n0 = shape(a,0)
end subroutine foo
node.method_name = node.name
if node.name == 'assignment(=)':
node.method_name = 'assignment'
elif node.name == 'operator(+)':
node.method_name = '__add__'
elif node.name == 'operator(-)':
node.method_name = '__sub__'
elif node.name == 'operator(*)':
node.method_name = '__mul__'
elif node.method_name == 'operator(/)':
node.method_name = '__div__'
elif '(' in node.name:
raise RuntimeError("unsupported operator overload '%s'" % node.name)
return node
class ReorderOptionalArgumentsPython(ft.FortranVisitor):
"""
Move optional arguments after non-optional arguments:
in Fortran they can come in any order, but in Python
optional arguments must come at the end of argument list.
"""
def visit_Procedure(self, node):
non_optional = [arg for arg in node.arguments if 'optional' not in arg.attributes]
optional = [arg for arg in node.arguments if 'optional' in arg.attributes]
node.arguments = non_optional + optional
return node
class OnlyAndSkip(ft.FortranTransformer):
"""
This class does the job of removing nodes from the tree
node.doc,
node.lineno,
arguments,
node.uses,
node.attributes,
ret_val,
ret_val_doc,
mod_name=node.mod_name,
type_name=node.type_name)
new_node.orig_node = node
if hasattr(node, 'method_name'):
new_node.method_name = node.method_name
return new_node
class RenameReservedWords(ft.FortranVisitor):
def __init__(self, types, name_map=None):
self.types = types
self.name_map = {}
if name_map is not None:
self.name_map.update(name_map)
# rename Python keywords by appending an underscore
import keyword
self.name_map.update(dict((key, key + '_') for key in keyword.kwlist))
# apply same renaming as f2py
import numpy.f2py.crackfortran
self.name_map.update(numpy.f2py.crackfortran.badnames)
# avoid clashes with C intrinsic functions
self.name_map['inverse'] = 'inverse_'