Пример #1
0
def add_missing_destructors(tree):
    for node in ft.walk(tree):
        if not isinstance(node, ft.Type):
            continue
        for child in ft.iter_child_nodes(node):
            if isinstance(child, ft.Procedure):
                if 'destructor' in child.attributes:
                    logging.info('found destructor %s' % child.name)
                    break
        else:

            logging.info('adding missing destructor for %s' % node.name)
            new_node = ft.Subroutine(
                '%s_finalise' % node.name,
                node.filename,
                ['Automatically generated destructor for %s' % node.name],
                node.lineno, [
                    ft.Argument(name='this',
                                filename=node.filename,
                                doc=['Object to be destructed'],
                                lineno=node.lineno,
                                attributes=['intent(inout)'],
                                type='type(%s)' % node.name)
                ],
                node.uses, ['destructor', 'skip_call'],
                mod_name=node.mod_name,
                type_name=node.name)
            new_node.method_name = '__del__'
            node.procedures.append(new_node)
    return tree
Пример #2
0
    def write_constructor(self, node):
        handle_arg = ft.Argument(name='handle',
                              filename=node.filename,
                              doc=['Opaque reference to existing derived type instance'],
                              lineno=node.lineno,
                              attributes=['intent(in)', 'optional'],
                              type='integer')
        handle_arg.py_name = 'handle'

        # special case for constructors: return value is 'self' argument,
        # plus we add an extra optional argument
        args = node.ret_val + node.arguments + [handle_arg]

        dct = dict(func_name=node.name,
                   prefix=self.prefix,
                   mod_name=self.f90_mod_name,
                   py_arg_names=', '.join(['%s%s' % (arg.py_name,
                                                     'optional' in arg.attributes and '=None' or '')
                                                     for arg in args ]),
                   f90_arg_names=', '.join(['%s=%s' % (arg.name, arg.py_value) for arg in node.arguments]))

        self.write("def __init__(%(py_arg_names)s):" % dct)
        self.indent()
        self.write(format_doc_string(node))
        self.write('f90wrap.runtime.FortranDerivedType.__init__(self)')
        self.write('self._handle = %(mod_name)s.%(prefix)s%(func_name)s(%(f90_arg_names)s)' % dct)
        self.dedent()
        self.write()
Пример #3
0
    def visit_Procedure(self, node):

        n_dummy = 0
        for arg in node.arguments:
            dims = [
                attr for attr in arg.attributes if attr.startswith('dimension')
            ]
            if dims == []:
                continue
            if len(dims) != 1:
                raise ValueError(
                    'more than one dimension attribute found for arg %s' %
                    arg.name)

            ds = ArrayDimensionConverter.split_dimensions(dims[0])

            new_dummy_args = []
            new_ds = []
            for i, d in enumerate(ds):
                if ArrayDimensionConverter.valid_dim_re.match(d):
                    if d.startswith('len'):
                        arg.f2py_line = ('!f2py %s %s, dimension(%s) :: %s' % \
                                         (arg.type,
                                           ','.join([attr for attr in arg.attributes if not attr.startswith('dimension')]),
                                           d.replace('len', 'slen'), arg.name))
                    new_ds.append(d)
                    continue
                dummy_arg = ft.Argument(name='n%d' % n_dummy,
                                        type='integer',
                                        attributes=['intent(hide)'])

                if 'intent(out)' not in arg.attributes:
                    dummy_arg.f2py_line = (
                        '!f2py intent(hide), depend(%s) :: %s = shape(%s,%d)' %
                        (arg.name, dummy_arg.name, arg.name, i))
                new_dummy_args.append(dummy_arg)
                new_ds.append(dummy_arg.name)
                n_dummy += 1

            if new_dummy_args != []:
                logging.debug('adding dummy arguments %r to %s' %
                              (new_dummy_args, node.name))
                arg.attributes = ([
                    attr for attr in arg.attributes
                    if not attr.startswith('dimension')
                ] + ['dimension(%s)' % ','.join(new_ds)])
                node.arguments.extend(new_dummy_args)