diff options
author | Robert Kern <robert.kern@gmail.com> | 2008-07-03 19:57:24 +0000 |
---|---|---|
committer | Robert Kern <robert.kern@gmail.com> | 2008-07-03 19:57:24 +0000 |
commit | 484c100392601f4942ceecbedf32e6df0201d473 (patch) | |
tree | 5e5a58b30a39bd1b5481333ae4a4b9c34e466841 /numpy/f2py/lib | |
parent | 0c817a5d51c2c16db9df5c015ff846002d991d74 (diff) | |
download | numpy-484c100392601f4942ceecbedf32e6df0201d473.tar.gz |
Removing G3 f2py code. Development has moved to https://launchpad.net/f2py/
Diffstat (limited to 'numpy/f2py/lib')
40 files changed, 0 insertions, 21649 deletions
diff --git a/numpy/f2py/lib/__init__.py b/numpy/f2py/lib/__init__.py deleted file mode 100644 index 90a4a5367..000000000 --- a/numpy/f2py/lib/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -F2PY G3 --- The third generation of Fortran to Python Interface Generator. - -Use api module for importing public symbols. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" -__test__ = False diff --git a/numpy/f2py/lib/api.py b/numpy/f2py/lib/api.py deleted file mode 100644 index 0d21da28c..000000000 --- a/numpy/f2py/lib/api.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Public API for F2PY G3. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -from main import main diff --git a/numpy/f2py/lib/doc.txt b/numpy/f2py/lib/doc.txt deleted file mode 100644 index 79ccb0768..000000000 --- a/numpy/f2py/lib/doc.txt +++ /dev/null @@ -1,239 +0,0 @@ -.. -*- rest -*- - -======================= -G3 F2PY library package -======================= - -:Author: - Pearu Peterson <pearu.peterson@gmail.com> -:Created: July 2007 - -.. contents:: Table of Contents - -Overview -======== - -The G3 F2PY library package contains tools to parse Fortran codes and -construct Python C/API extension modules for wrapping Fortran -programs. These tools are also suitable for implementing Fortran -program translators or wrappers to any other programming language. In -fact, wrapping Fortran programs to Python would be just one example of -using these tools. - -Wrapping Fortran with Python - UI -================================= - -There are two user interfaces to wrap Fortran programs with Python: - - - the command line program `f2py` that scans Fortran files - given as command line arguments and builds extension modules - that can be used to call Fortran programs from Python. - The `f2py` program has four different ways of building - extension modules as specified with the following command - line flags: - - - `--g3-numpy` --- create extension modules with NumPy array - support using the new tools from `the 3rd generation of F2PY`__. - This is a work-in-progress feature. - - - `--2d-numpy` --- create extension modules with NumPy array - support using `the stable version of F2PY`__. This is default. - - - `--2d-numeric` --- create extension modules with Numeric - array support using the old version of f2py2e. The f2py2e - package must be downloaded and installed separately from - the `f2py2e homepage`__. - - - `--2d-numarray` --- create extension modules with Numarray - array support using the old version of f2py2e. - - Example:: - - $ cat hello.f90 - subroutine hello - print*, "Hello!" - end subroutine hello - $ f2py --g3-numpy -m foo -c hello.f90 --fcompiler=gnu95 - $ python - >>> import foo - >>> foo.hello() - Hello! - >>> - - See the output of `f2py` for more information. - -__ http://projects.scipy.org/scipy/numpy/wiki/G3F2PY/ -__ http://www.scipy.org/F2py/ -__ http://cens.ioc.ee/projects/f2py2e/ - - - the function `compile()` that scans its string input containing - Fortran code and returns a list of imported extension modules - that can be used to call Fortran programs from Python. - - Example:: - - $ python - >>> from numpy.f2py.lib.api import compile - >>> code = 'subroutine hello\n print*, "Hello!"\nend' - >>> print code - subroutine hello - print*, "Hello!" - end - >>> foo, = compile(code, extra_args = ['--fcompiler=gnu95']) - >>> foo.hello() - Hello! - >>> - -Wrapping Fortran with Python - how it works? -============================================ - -The two users interfaces discussed above are implemented by functions -`main(sys_argv=None)` and `compile(source, jobname='untitled', -extra_args=[], source_ext=None, modulenames=None)` in file -`numpy/f2py/lib/main.py`. Both these functions call -`build_extension(sys_argv, sources_only=False)` function that reads -`sys_argv` list for files and options, constructs wrapper functions, -creates a `numpy.distutils` style `setup.py` file, and finally runs -it. - -`build_extension` options -------------------------- - -The following options are defined that can be used as command line -arguments to `f2py` or in `extra_args` list argument of the `compiler` -function: - - - `-m [<name>]` --- specify the name of a wrapper extension - module. Default is `untitled` or `unspecified` (if `<name>` part - is not specified). - - - `--target-dir=<path>` --- specify the directory path where - extension modules are saved. Default is the current working - directory. - - - `--build-dir=<path>` --- specify the directory path where - temporary files are created during the build process. Default is - `_g2f2py` or temporary directory (when `<path>` part is not - specified)). - - - `-I<path>` --- specifies include directory path that is used for - finding Fortran 90 modules and when compiling sources. - - - `-D<name>[=<value>]`, `-U<name>` --- defines or undefines CPP - macro used in compiling sources. See below for F2PY specific - macros. - - - `-L<path>` --- specifies library directory path that is used in - linking extension modules. - - - `-l<name>` --- specifies library that is used in linking extension - modules. - - - `<filename>.(o|a|so|dll|dylib|sl)` --- specifies extra object - files used in linking extension modules. - - - `<filename>`.pyf --- specifies signature file used for scanning - Fortran program signatures. - - - `<filename>.(f|f90|F90|F)` --- specifies Fortran source files used - for scanning Fortran program signatures (in case no signature - files are specified). These sources will be compiled and linked - with extension modules. - - - `<filename>.(c|cpp|C|CPP|c++)` --- specifies C/C++ source files - that will be compiled and linked with extension modules. Note that - if no signature file is specified then also C/C++ files are - scanned for Fortran program signatures. The Fortran program - signatures are assumed to be inside the C comment `/* f2py ... */` - block. - - - `--fcompiler=<compiler name>` --- specifies Fortran compiler to be - used in compiling/linking the sources. See also `--help-fcompiler` - option. - - - `--help-fcompiler` --- list Fortran compilers that are found in - the system, that are available or unavailable for the current - system. Then return without processing any other options. - - - `--compiler=<compiler name>` --- specifies C/C++ compiler to be - used in compiling/linking the sources. See also `--help-compiler` - option. - - - `--help-compiler` --- list C/C++ compilers that are available - for the current system. Then return without processing any other - options. - -Additional `f2py` command line options --------------------------------------- - -Command line tool `f2py` uses the following additional command line -options: - - - `-c` --- specifies that F2PY should build extension - modules. Without this option F2PY just scans source files for - signatures and constructs extension module sources --- useful when - one needs to build extension modules manually (in Makefile, for - instance). See also `-h` option below. - - - `-h <filename>` --- specifies the signature file name - where the results of scanning sources will be saved. With this - option F2PY just scans the sources but does not construct extension - modules sources --- useful when one needs to edit the signatures - of Fortran programs. If `<filename>` is `stdout` or `stderr` is - specified then the scanned signatures will be dumped to `stdout` - or `stderr` streams, respectively. - - - `--help-link [<resouce name> ]...` --- list system resources as - defined in `numpy/distutils/system_info.py` and return. - - - `--parse` --- specifies that F2PY should just parce the - source files and dump the results to `stdout` stream. - Useful for debugging F2PY parser. - - -F2PY specific CPP macros ------------------------- - -F2PY may use the following CPP macros: - - - `-DF2PY_DEBUG_PYOBJ_TOFROM` --- show debug messages from - `pyobj_(to|from)_<ctype>` functions. - - - `-DPREPEND_FORTRAN`, `-DNO_APPEND_FORTRAN`, `-DUPPERCASE_FORTRAN`, - `-DUNDERSCORE_G77` --- specify how Fortran compiler mangles Fortran - symbol names that need to be accessed from C extension modules. - Usually one never needs to specify these macros as supported - Fortran compilers should always mangle the names to be lower-cased - and with exactly one underscore after the name. - -Options for `compile` ---------------------- - -The `compile` function has the following options: - - - `source` --- a string containing Fortran code. To specify the - Fortran format of the `source` use the following header lines - in the `source` string: - - - `C -*- f77 -*-` --- the string contains Fortran 77 code - - `! -*- f90 -*-` --- the string contains Fortran 90 code in - free format. - - `! -*- fix -*-` --- the string contains Fortran 90 code in - fixed format. - - `! -*- pyf -*-` --- the string contains Fortran signatures. - - - `jobname='untitled'` --- a string specifing the name of an - extension module - - - `extra_args=[]` --- a list of `build_extension(..)` arguments, - see above. - - - `source_ext=None` --- a string specifying the extension (`.f` or - `.f90`) of the file where `source` will be saved for further - processing. Default extension will be determined from the `source` - string. - - - `modulenames=None` --- a list of module names that the build - process should create. `compile` function will try to import - these modules and return the corresponding module objects - as a list. diff --git a/numpy/f2py/lib/extgen/__init__.py b/numpy/f2py/lib/extgen/__init__.py deleted file mode 100644 index 58c965745..000000000 --- a/numpy/f2py/lib/extgen/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Python Extensions Generator -""" - -__all__ = ['Component'] - -from base import Component - -for _m in ['utils', 'c_support', 'py_support', 'setup_py']: - exec 'from %s import *' % (_m) - exec 'import %s as _m' % (_m) - __all__.extend(_m.__all__) - -#from pyc_function import PyCFunction -#from pyc_argument import PyCArgument -#from c_code import CCode - -#import c_type -#from c_type import * -#__all__ += c_type.__all__ -#import c_struct -#from c_struct import * -#__all__ += c_struct.__all__# - -#import predefined_components -#import converters -#c_type.register() diff --git a/numpy/f2py/lib/extgen/base.py b/numpy/f2py/lib/extgen/base.py deleted file mode 100644 index d6f1ee7fd..000000000 --- a/numpy/f2py/lib/extgen/base.py +++ /dev/null @@ -1,543 +0,0 @@ -""" -ExtGen --- Python Extension module Generator. - -Defines Component and Container classes. -""" - -import os -import re -import sys -import time - -class ComponentMetaClass(type): - - classnamespace = {} - - def __new__(mcls, *args, **kws): - cls = type.__new__(mcls, *args, **kws) - n = cls.__name__ - c = ComponentMetaClass.classnamespace.get(n) - if c is None: - ComponentMetaClass.classnamespace[n] = cls - else: - if not c.__module__=='__main__': - sys.stderr.write('ComponentMetaClass: returning %s as %s\n'\ - % (cls, c)) - ComponentMetaClass.classnamespace[n] = c - cls = c - return cls - - def __getattr__(cls, name): - try: return ComponentMetaClass.classnamespace[name] - except KeyError: pass - raise AttributeError("'%s' object has no attribute '%s'"% - (cls.__name__, name)) - -class Component(object): - - __metaclass__ = ComponentMetaClass - - container_options = dict() - component_container_map = dict() - default_container_label = None - default_component_class_name = 'Code' - template = '' - - def __new__(cls, *args, **kws): - obj = object.__new__(cls) - obj._provides = kws.get('provides', None) - obj.parent = None - obj.containers = {} # holds containers for named string lists - obj._components = [] # holds pairs (<Component subclass instance>, <container name or None>) - obj._generate_components = {} # temporary copy of components used for finalize and generate methods. - obj = obj.initialize(*args, **kws) # initialize from constructor arguments - return obj - - def components(self): - if Component._running_generate: - try: - return self._generate_components[Component._running_generate_id] - except KeyError: - pass - while self._generate_components: # clean up old cache - self._generate_components.popitem() - self._generate_components[Component._running_generate_id] = l = list(self._components) - return l - return self._components - components = property(components) - - def initialize(self, *components, **options): - """ - Set additional attributes, add components to instance, etc. - """ - # self.myattr = .. - # map(self.add, components) - return self - - def finalize(self): - """ - Set components after all components are added. - """ - return - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(c) for (c,l) in self.components])) - - def provides(self): - """ - Return a code idiom name that the current class defines. - - Used in avoiding redefinitions of functions and variables. - """ - if self._provides is None: - return '%s_%s' % (self.__class__.__name__, id(self)) - return self._provides - provides = property(provides) - - def warning(message): - #raise RuntimeError('extgen:' + message) - print >> sys.stderr, 'extgen:',message - warning = staticmethod(warning) - - def info(message): - print >> sys.stderr, message - info = staticmethod(info) - - def __getattr__(self, attr): - if attr.startswith('container_'): # convenience feature - return self.get_container(attr[10:]) - if attr.startswith('component_'): # convenience feature - return self.get_component(attr[10:]) - raise AttributeError('%s instance has no attribute %r' % (self.__class__.__name__, attr)) - - def __add__(self, other): # convenience method - self.add(other) - return self - __iadd__ = __add__ - - def _get_class_names(cls): - if not issubclass(cls, Component): - return [cls] - r = [cls] - for b in cls.__bases__: - r += Component._get_class_names(b) - return r - _get_class_names = staticmethod(_get_class_names) - - def add(self, component, container_label=None): - """ - Append component and its target container label to components list. - """ - if isinstance(component, tuple) and len(component)==2 and isinstance(component[0], Component): - assert container_label is None, `container_label` - component, container_label = component - if not isinstance(component, Component) and self.default_component_class_name!=component.__class__.__name__: - clsname = self.default_component_class_name - if clsname is not None: - component = getattr(Component, clsname)(component) - else: - raise ValueError('%s.add requires Component instance but got %r' \ - % (self.__class__.__name__, component.__class__.__name__)) - if container_label is None: - container_label = self.default_container_label - for n in self._get_class_names(component.__class__): - try: - container_label = self.component_container_map[n.__name__] - break - except KeyError: - pass - if container_label is None: - container_label = component.__class__.__name__ - self.components.append((component, container_label)) - component.update_parent(self) - return - - def update_parent(self, parent): - pass - - def get_path(self, *paths): - if not hasattr(self, 'path'): - if paths: - return os.path.join(*paths) - return '' - if not self.parent: - return os.path.join(*((self.path,) + paths)) - return os.path.join(*((self.parent.get_path(), self.path)+paths)) - - def get_component(self, cls): - if isinstance(cls, str): - cls = getattr(Component, cls) - if isinstance(self, cls): - return self - if self.parent: - return self.parent.get_component(cls) - self.warning('could not find %r parent component %s, returning self'\ - % (self.__class__.__name__, cls.__name__)) - return self - - _running_generate = False - _running_generate_id = 0 - _generate_dry_run = True - - def generate(self, dry_run=True): - old_dry_run = Component._generate_dry_run - Component._generate_dry_run = dry_run - Component._running_generate_id += 1 - Component._running_generate = True - self._finalize() - result = self._generate() - Component._running_generate = False - Component._generate_dry_run = old_dry_run - return result - - def _finalize(self): - # recursively finalize all components. - for component, container_key in self.components: - old_parent = component.parent - component.parent = self - component._finalize() - component.parent = old_parent - self.finalize() - - def _generate(self): - """ - Generate code idioms (saved in containers) and - return evaluated template strings. - """ - #self.finalize() - - # clean up containers - self.containers = {} - for n in dir(self): - if n.startswith('container_') and isinstance(getattr(self, n), Container): - delattr(self, n) - - # create containers - for k,kwargs in self.container_options.items(): - self.containers[k] = Container(**kwargs) - - # initialize code idioms - self.init_containers() - - # generate component code idioms - for component, container_key in self.components: - if not isinstance(component, Component): - result = str(component) - if container_key == '<IGNORE>': - pass - elif container_key is not None: - self.get_container(container_key).add(result) - else: - self.warning('%s: no container label specified for component %r'\ - % (self.__class__.__name__,component)) - continue - old_parent = component.parent - component.parent = self - result = component._generate() - if container_key == '<IGNORE>': - pass - elif container_key is not None: - if isinstance(container_key, tuple): - assert len(result)==len(container_key),`len(result),container_key` - results = result - keys = container_key - else: - assert isinstance(result, str) and isinstance(container_key, str), `result, container_key` - results = result, - keys = container_key, - for r,k in zip(results, keys): - container = component.get_container(k) - container.add(r, component.provides) - else: - - self.warning('%s: no container label specified for component providing %r'\ - % (self.__class__.__name__,component.provides)) - component.parent = old_parent - - # update code idioms - self.update_containers() - - # fill templates with code idioms - templates = self.get_templates() - if isinstance(templates, str): - result = self.evaluate(templates) - else: - assert isinstance(templates, (tuple, list)),`type(templates)` - result = tuple(map(self.evaluate, templates)) - return result - - def init_containers(self): - """ - Update containers before processing components. - """ - # container = self.get_container(<key>) - # container.add(<string>, label=None) - return - - def update_containers(self): - """ - Update containers after processing components. - """ - # container = self.get_container(<key>) - # container.add(<string>, label=None) - return - - def get_container(self, name): - """ Return named container. - - Rules for returning containers: - (1) return local container if exists - (2) return parent container if exists - (3) create local container and return it with warning - """ - # local container - try: - return self.containers[name] - except KeyError: - pass - - # parent container - parent = self.parent - while parent is not None: - try: - return parent.containers[name] - except KeyError: - parent = parent.parent - continue - - # create local container - self.warning('Created container for %r with name %r, define it in'\ - ' parent .container_options mapping to get rid of this warning' \ - % (self.__class__.__name__, name)) - c = self.containers[name] = Container() - return c - - def get_templates(self): - """ - Return instance templates. - """ - return self.template - - def evaluate(self, template, **attrs): - """ - Evaluate template using instance attributes and code - idioms from containers. - """ - d = self.containers.copy() - for n in dir(self): - if n in ['show', 'build'] or n.startswith('_'): - continue - v = getattr(self, n) - if isinstance(v, str): - d[n] = v - d.update(attrs) - for label, container in self.containers.items(): - if not container.use_indent: - continue - replace_list = set(re.findall(r'[ ]*%\('+label+r'\)s', template)) - for s in replace_list: - old_indent = container.indent_offset - container.indent_offset = old_indent + len(s) - len(s.lstrip()) - i = template.index(s) - template = template[:i] + str(container) + template[i+len(s):] - container.indent_offset = old_indent - try: - template = template % d - except KeyError, msg: - raise KeyError('%s.container_options needs %s item' % (self.__class__.__name__, msg)) - return re.sub(r'.*[<]KILLLINE[>].*(\n|$)','', template) - - - _registered_components_map = {} - - def register(*components): - """ - Register components so that component classes can use - predefined components via `.get(<provides>)` method. - """ - d = Component._registered_components_map - for component in components: - provides = component.provides - if provides in d: - Component.warning('component that provides %r is already registered, ignoring.' % (provides)) - else: - d[provides] = component - return - register = staticmethod(register) - - def get(provides): - """ - Return predefined component with given provides property.. - """ - try: - return Component._registered_components_map[provides] - except KeyError: - pass - raise KeyError('no registered component provides %r' % (provides)) - get = staticmethod(get) - - def numpy_version(self): - import numpy - return numpy.__version__ - numpy_version = property(numpy_version) - -class Container(object): - """ - Container of a list of named strings. - - >>> c = Container(separator=', ', prefix='"', suffix='"') - >>> c.add('hey',1) - >>> c.add('hoo',2) - >>> print c - "hey, hoo" - >>> c.add('hey',1) - >>> c.add('hey2',1) - Traceback (most recent call last): - ... - ValueError: Container item 1 exists with different value - - >>> c2 = Container() - >>> c2.add('bar') - >>> c += c2 - >>> print c - "hey, hoo, bar" - - """ - __metaclass__ = ComponentMetaClass - - def __init__(self, - separator='\n', prefix='', suffix='', - skip_prefix_when_empty=False, - skip_suffix_when_empty=False, - default = '', reverse=False, - user_defined_str = None, - use_indent = False, - indent_offset = 0, - use_firstline_indent = False, # implies use_indent - replace_map = {}, - ignore_empty_content = False, - skip_prefix_suffix_when_single = False - ): - self.list = [] - self.label_map = {} - - self.separator = separator - self.prefix = prefix - self.suffix = suffix - self.skip_prefix = skip_prefix_when_empty - self.skip_suffix = skip_suffix_when_empty - self.default = default - self.reverse = reverse - self.user_str = user_defined_str - self.use_indent = use_indent or use_firstline_indent - self.indent_offset = indent_offset - self.use_firstline_indent = use_firstline_indent - self.replace_map = replace_map - self.ignore_empty_content = ignore_empty_content - self.skip_prefix_suffix_when_single = skip_prefix_suffix_when_single - - def __nonzero__(self): - return bool(self.list) - - def has(self, label): - return label in self.label_map - - def get(self, label): - return self.list[self.label_map[label]] - - def __add__(self, other): - if isinstance(other, Container): - lst = [(i,l) for (l,i) in other.label_map.items()] - lst.sort() - for i,l in lst: - self.add(other.list[i], l) - else: - self.add(other) - return self - __iadd__ = __add__ - - def add(self, content, label=None): - """ Add content to container using label. - If label is None, an unique label will be generated using time.time(). - """ - if content is None: - return - if content=='' and self.ignore_empty_content: - return - assert isinstance(content, str),`type(content)` - if label is None: - label = time.time() - if self.has(label): - d = self.get(label) - if d!=content: - raise ValueError("Container item %r exists with different value" % (label)) - return - for old, new in self.replace_map.items(): - content = content.replace(old, new) - self.list.append(content) - self.label_map[label] = len(self.list)-1 - return - - def __str__(self): - if self.user_str is not None: - return self.user_str(self) - if self.list: - l = self.list - if self.reverse: - l = l[:] - l.reverse() - if self.use_firstline_indent: - new_l = [] - for l1 in l: - lines = l1.split('\\n') - i = len(lines[0]) - len(lines[0].lstrip()) - indent = i * ' ' - new_l.append(lines[0]) - new_l.extend([indent + l2 for l2 in lines[1:]]) - l = new_l - r = self.separator.join(l) - if not (len(self.list)==1 and self.skip_prefix_suffix_when_single): - r = self.prefix + r - r = r + self.suffix - else: - r = self.default - if not self.skip_prefix: - r = self.prefix + r - if not self.skip_suffix: - r = r + self.suffix - if r and self.use_indent: - lines = r.splitlines(True) - indent = self.indent_offset * ' ' - r = ''.join([indent + line for line in lines]) - return r - - def copy(self, mapping=None, **extra_options): - options = dict(separator=self.separator, prefix=self.prefix, suffix=self.suffix, - skip_prefix_when_empty=self.skip_prefix, - skip_suffix_when_empty=self.skip_suffix, - default = self.default, reverse=self.reverse, - user_defined_str = self.user_str, - use_indent = self.use_indent, - indent_offset = self.indent_offset, - use_firstline_indent = self.use_firstline_indent, - replace_map = self.replace_map, - ignore_empty_content = self.ignore_empty_content, - skip_prefix_suffix_when_single = self.skip_prefix_suffix_when_single - ) - options.update(extra_options) - cpy = Container(**options) - if mapping is None: - cpy += self - else: - lst = [(i,l) for (l,i) in self.label_map.items()] - lst.sort() - for i,l in lst: - cpy.add(mapping(other.list[i]), l) - return cpy - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/numpy/f2py/lib/extgen/c_support.py b/numpy/f2py/lib/extgen/c_support.py deleted file mode 100644 index 95ef1ac55..000000000 --- a/numpy/f2py/lib/extgen/c_support.py +++ /dev/null @@ -1,293 +0,0 @@ - -__all__ = ['CLine', 'Keyword', 'CTypeSpec', 'CDeclarator', 'CDeclaration', - 'CArgument', 'CCode', 'CFunction', 'CSource', 'CHeader', 'CStdHeader'] - -from base import Component -from utils import Line, Code, FileSource - -class CLine(Line): - pass - -class Keyword(CLine): - pass - -class CInitExpr(CLine): - pass - -class CTypeSpec(CLine): - - """ - >>> i = CTypeSpec('int') - >>> print i.generate() - int - >>> print i.as_ptr().generate() - int* - """ - def as_ptr(self): return self.__class__(self.generate()+'*') - - -class CDeclarator(Component): - - """ - - >>> CDeclarator('name').generate() - 'name' - >>> CDeclarator('name','0').generate() - 'name = 0' - """ - container_options = dict( - Initializer = dict(default='',prefix=' = ', skip_prefix_when_empty=True, - ignore_empty_content = True - ), - ScalarInitializer = dict(default='',prefix=' = ', skip_prefix_when_empty=True, - ignore_empty_content = True - ), - SequenceInitializer = dict(default='',prefix=' = {\n', skip_prefix_when_empty=True, - suffix='}', skip_suffix_when_empty=True, - ignore_empty_content = True, - separator = ',\n', use_indent=True, - ), - StringInitializer = dict(default='',prefix=' = "', skip_prefix_when_empty=True, - suffix='"', skip_suffix_when_empty=True, - ignore_empty_content = True, - separator='\\n"\n"', replace_map = {'\n':'\\n'}, - use_firstline_indent = True, - ), - ) - - default_component_class_name = 'CInitExpr' - - component_container_map = dict( - CInitExpr = 'Initializer' - ) - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name]+[c for (c,l) in self.components]))) - - def initialize(self, name, *initvalues, **options): - self.name = name - self.is_string = options.get('is_string', None) - if self.is_string: - assert not options.get('is_scalar', None) - self.is_scalar = False - else: - if name.endswith(']'): - self.is_scalar = False - else: - self.is_scalar = options.get('is_scalar', True) - - map(self.add, initvalues) - return self - - def update_containers(self): - if self.is_scalar: - self.container_ScalarInitializer += self.container_Initializer - self.template = '%(name)s%(ScalarInitializer)s' - elif self.is_string: - self.container_StringInitializer += self.container_Initializer - self.template = '%(name)s%(StringInitializer)s' - elif len(self.containers)>1 or not self.is_scalar: - self.container_SequenceInitializer += self.container_Initializer - self.template = '%(name)s%(SequenceInitializer)s' - else: - self.container_ScalarInitializer += self.container_Initializer - self.template = '%(name)s%(ScalarInitializer)s' - -class CDeclaration(Component): - - """ - >>> d = CDeclaration('int', 'a') - >>> print d.generate() - int a - >>> d += 'b' - >>> print d.generate() - int a, b - >>> d += CDeclarator('c',1) - >>> print d.generate() - int a, b, c = 1 - """ - - template = '%(CTypeSpec)s %(CDeclarator)s' - - container_options = dict( - CTypeSpec = dict(default='int', separator=' '), - CDeclarator = dict(default='<KILLLINE>', separator=', '), - ) - - component_container_map = dict( - CTypeSpec = 'CTypeSpec', - CDeclarator = 'CDeclarator', - ) - - default_component_class_name = 'CDeclarator' - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[c for (c,l) in self.components]))) - - def initialize(self, ctype, *declarators, **options): - ctype = CTypeSpec(ctype) - self.ctype = ctype - self.add(ctype) - map(self.add, declarators) - return self - -class CArgument(CDeclaration): - - def initialize(self, name, ctype, **options): - return CDeclaration.initialize(self, ctype, name, **options) - - -class CCode(Code): - parent_container_options = dict(default='<KILLLINE>', use_indent=True, ignore_empty_content=True) - -class CFunction(Component): - - """ - >>> f = CFunction('foo') - >>> print f.generate() - int - foo(void) { - } - >>> f += Keyword('static') - >>> f += CArgument('a', 'int') - >>> f += 'a = 2;' - >>> print f.generate() - static - int - foo(int a) { - a = 2; - } - >>> f += CArgument('b', 'float') - >>> f += CDeclaration('float', 'c') - >>> f += CDeclaration('float', CDeclarator('d','3.0')) - >>> print f.generate() - static - int - foo(int a, float b) { - float c; - float d = 3.0; - a = 2; - } - """ - - template = '''\ -%(CSpecifier)s -%(CTypeSpec)s -%(name)s(%(CArgument)s) { - %(CDeclaration)s - %(CBody)s -}''' - - container_options = dict( - CArgument = dict(separator=', ', default='void'), - CDeclaration = dict(default='<KILLLINE>', use_indent=True, ignore_empty_content=True, - separator = ';\n', suffix=';', skip_suffix_when_empty=True), - CBody = dict(default='<KILLLINE>', use_indent=True, ignore_empty_content=True), - CTypeSpec = dict(default='int', separator = ' ', ignore_empty_content=True), - CSpecifier = dict(default='<KILLLINE>', separator = ' ', ignore_empty_content = True) - ) - - component_container_map = dict( - CArgument = 'CArgument', - CDeclaration = 'CDeclaration', - CCode = 'CBody', - CTypeSpec = 'CTypeSpec', - Keyword = 'CSpecifier', - ) - - default_component_class_name = 'CCode' - - def initialize(self, name, rctype='int', *components, **options): - self.name = name - rctype = CTypeSpec(rctype) - self.rctype = rctype - self.add(rctype) - map(self.add, components) - if options: self.warning('%s unused options: %s\n' % (self.__class__.__name__, options)) - return self - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name, self.rctype]+[c for (c,l) in self.components]))) - -class CHeader(CLine): - - """ - >>> h = CHeader('noddy.h') - >>> print h.generate() - #include "noddy.h" - - """ - template = '#include "%(line)s"' - -class CStdHeader(CHeader): - template = '#include <%(line)s>' - -class CSource(FileSource): - - """ - >>> s = CSource('foo.c') - >>> print s.generate() #doctest: +ELLIPSIS - /* -*- c -*- */ - /* This file 'foo.c' is generated using ExtGen tool - from NumPy version ... - ExtGen is developed by Pearu Peterson <pearu.peterson@gmail.com>. - For more information see http://www.scipy.org/ExtGen/ . - */ - #ifdef __cplusplus - extern "C" { - #endif - #ifdef __cplusplus - } - #endif - <BLANKLINE> - """ - - container_options = dict( - CHeader = dict(default='<KILLLINE>', prefix='\n/* CHeader */\n', skip_prefix_when_empty=True), - CTypeDef = dict(default='<KILLLINE>', prefix='\n/* CTypeDef */\n', skip_prefix_when_empty=True), - CProto = dict(default='<KILLLINE>', prefix='\n/* CProto */\n', skip_prefix_when_empty=True), - CDefinition = dict(default='<KILLLINE>', prefix='\n/* CDefinition */\n', skip_prefix_when_empty=True), - CDeclaration = dict(default='<KILLLINE>', separator=';\n', suffix=';', - prefix='\n/* CDeclaration */\n', skip_prefix_when_empty=True), - CMainProgram = dict(default='<KILLLINE>', prefix='\n/* CMainProgram */\n', skip_prefix_when_empty=True), - ) - - template_c_header = '''\ -/* -*- c -*- */ -/* This file %(path)r is generated using ExtGen tool - from NumPy version %(numpy_version)s. - ExtGen is developed by Pearu Peterson <pearu.peterson@gmail.com>. - For more information see http://www.scipy.org/ExtGen/ . -*/''' - - - template = template_c_header + ''' -#ifdef __cplusplus -extern \"C\" { -#endif -%(CHeader)s -%(CTypeDef)s -%(CProto)s -%(CDefinition)s -%(CDeclaration)s -%(CMainProgram)s -#ifdef __cplusplus -} -#endif -''' - - component_container_map = dict( - CHeader = 'CHeader', - CFunction = 'CDefinition', - CDeclaration = 'CDeclaration', - ) - - - - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/numpy/f2py/lib/extgen/doc.txt b/numpy/f2py/lib/extgen/doc.txt deleted file mode 100644 index c86af8d96..000000000 --- a/numpy/f2py/lib/extgen/doc.txt +++ /dev/null @@ -1,449 +0,0 @@ -.. -*- rest -*- - -============================================ -ExtGen --- Python extension module generator -============================================ - -:Author: - Pearu Peterson <pearu.peterson@gmail.com> -:Created: August 2007 - -.. contents:: Table of Contents - -Introduction -============ - -ExtGen is a pure Python package that provides a high-level -tool for constructing and building Python extension modules. -Even an inexperienced user with no background on writing extension -modules can build extension modules on fly when using ExtGen tool! - -Hello example follows - - >>> from numpy.f2py.lib.extgen import * - >>> m = PyCModule('foo') # define extension module component - >>> f = PyCFunction('hello') # define function component - >>> f += 'printf("Hello!\\n");' # put a C statement into function body - >>> m += f # add function to module - >>> print m.generate() # shows a string containing C source to extension module - # useful for debugging - >>> foo = m.build() # compile, build, and return extension module object - >>> foo.hello() # call function - Hello! - - -Users reference manual -====================== - -Writing a python extension module requires a knowledge of Pyhton C/API -details and may take lots of effort to get your first extension module -compile and working, even for a simple problem. See the `Simple Example`__ -in Python reference manual. ExtGen provides a high level tool for -constructing extension modules by automatically taking care of the -Pyhton C/API details while providing full control how an extension -module is created. - -__ http://docs.python.org/ext/ - -Getting started ---------------- - -Creating the `Simple Example`__ with the help of ExtGen tool is really simple - - >>> system = PyCFunction('system', - PyCArgument('command', 'c_const_char_ptr'), - PyCReturn('sts','c_int')) - >>> system += 'sts = system(command);' - >>> module = PyCModule('spam', system) - >>> spam = module.build() - >>> spam.system('pwd') - /home/pearu/svn/numpy/numpy/f2py/lib - 0 - -__ http://docs.python.org/ext/ - -ExtGen generated modules have automatically generated documentation -strings that accept also user input - - >>> a = PyCArgument('command', 'c_const_char_ptr', - input_description='a shell command string') - >>> r = PyCReturn('sts', 'c_int', - output_description='status value returned by shell command') - >>> system = PyCFunction('system', title='Execute a shell command.') - >>> system += a # add argument component to function - >>> system += r # add return value component to function - >>> system += 'sts = system(command);' # add C code to functon body - >>> module = PyCModule('spam', system) # create module instance with function component - >>> spam = module.build() - >>> print spam.__doc__ - This module 'spam' is generated with ExtGen from NumPy version 1.0.4.dev3744. - :Functions: - system(command) -> sts - >>> print spam.system.__doc__ - system(command) -> sts - Execute a shell command. - :Parameters: - command : a to C const char ptr convertable object - a shell command string - :Returns: - sts : a to C int convertable object - status value returned by shell command - >>> - -To see the source code that ExtGen generates, use `.generate()` method for any component instance - - >>> print system.generate() - static - char pyc_function_system_doc[] = - " system(command) -> sts" - "\n\nExecute a shell command." - "\n\n:Parameters:\n" - " command : a to C const char ptr convertable object\n" - " a shell command string" - "\n\n:Returns:\n" - " sts : a to C int convertable object\n" - " status value returned by shell command" - ; - static - PyObject* - pyc_function_system(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) { - PyObject * volatile pyc_buildvalue = NULL; - volatile int capi_success = 1; - const char * command = NULL; - int sts = 0; - static char *capi_kwlist[] = {"command", NULL}; - if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"z", - capi_kwlist, &command)) { - sts = system(command); - capi_success = !PyErr_Occurred(); - if (capi_success) { - pyc_buildvalue = Py_BuildValue("i", sts); - } - } - return pyc_buildvalue; - } - >>> print module.generate() # prints full extension module source - ... - -Components ----------- - -All components are subclassed of `Component` base class that provides -the following methods: - -- `.generate(self)` --- return a generated component string -- `.add(self, component, container_label=None)` --- add subcomponent - to component instance. The `container_label` argument can be used to tell - `ExtGen` where this component should be used, see `Developers reference - manual` for more details, otherwise `EgtGen` figures that out by - looking at subcomponent class properties. -- `.__add__(self, other)`, `.__iadd__(self, other)` --- shortcuts - for `self.add(other)` call. - -ExtGen provides the following Python C/API related components: - -- `SetupPy(<build directory>, *components)` --- generates a `setup.py` file - that is used to build extension modules to the given build directory. - It provides the following methods: - - - `.execute(self, *args)` --- runs `python setup.py` command with given - arguments. - - One can add `PyCModule` and `PySource` components to `SetupPy`. - -- `PyCModule(<modulename>, *components, title=..., description=...)` --- - represents python extension module source. It provides the following - methods: - - - `.build(self, build_dir=None, clean_at_exit=None)` --- compilers, - builds, and returns extension module object. - - One can add `PyCFunction` components to `PyCModule`. - -- `PyCFunction(<funcname>, *components, title=..., description=...)` --- - represents python extension module function source. - - One can add `PyCArgument`, `PyCReturn`, `CCode` components to `PyCfunction`. - String components are converted `CCode` components by default. - -- `PyCArgument(<argname>, ctype=<expected C type>, **components, - input_intent='required', input_title=..., input_description=..., - output_intent='hide', output_title=..., output_description=..., - title=..., description=..., - depends=<list of argument dependencies>)` --- represents argument - to python extension module function. - - `ctype` is `PyCTypeSpec` component instance or string. In the latter case - it is converted to `PyCTypeSpec` component. - -- `PyCReturn(<retname>, ctype=<expected C type>, **components)` --- - same as `PyCArgument` but with `input_intent='hide'` and `output_intent='return'` - options set. - -- `PyCTypeSpec(<typeobj>)` --- represents variable type in a - python extension module. Over 70 types are supported: - - >>> typenames = PyCTypeSpec.typeinfo_map.keys() - >>> typenames.sort() - >>> print ', '.join(typenames) - buffer, c_Py_UNICODE, c_Py_complex, c_Py_ssize_t, c_char, c_char1, - c_const_char_ptr, c_double, c_float, c_int, c_long, c_long_long, - c_short, c_unsigned_char, c_unsigned_int, c_unsigned_long, - c_unsigned_long_long, c_unsigned_short, cell, cobject, complex, dict, - file, float, frozenset, function, generator, instance, int, iter, - list, long, method, module, numeric_array, numpy_complex128, - numpy_complex160, numpy_complex192, numpy_complex256, numpy_complex32, - numpy_complex64, numpy_descr, numpy_float128, numpy_float16, - numpy_float32, numpy_float64, numpy_float80, numpy_float96, - numpy_int128, numpy_int16, numpy_int32, numpy_int64, numpy_int8, - numpy_iter, numpy_multiiter, numpy_ndarray, numpy_ufunc, - numpy_uint128, numpy_uint16, numpy_uint32, numpy_uint64, numpy_uint8, - object, property, set, slice, str, tuple, type, unicode - - `typeobj` can be python type instance (e.g. `int`) or one of the string values - from the list of typenames above. - -- `PySource(<filename>, *components)` --- represents pure python module file. - - One can add `Code` components to `PySource`. - -ExtGen provides the following C related components: - -- `CSource` --- represents C file. Derived from `FileSource`. - - One can add `CCode` components to `CSource`. - String input is converted to `CCode` component. - -- `CHeader(<header filename>)`, `CStdHeader(<std header filename>)`. Derived from `Line`. - -- `CCode(*components)` --- represents any C code block. Derived from `Code`. - -- `CFunction(<funcname>, rctype=CTypeSpec('int'), *components)` --- represents - a C function. - - One can add `CArgument`, `CDeclaration`, `CCode` components to `CFunction`. - -- `CDeclaration(<ctype>, *declarators)` --- represenets `<ctype> <declarators list>` - code idiom. `<ctype>` is `CTypeSpec` instance. - - One can add `CDeclarator` components to `CDeclaration`. - -- `CArgument(<argument name>, <ctype>)` --- C function argument. Derived from `CDeclaration`. - -- `CTypeSpec(<typename>)` --- C type specifier. Derived from `Line`. - -- `CDeclarator(<name>, *initvalues, is_string=..., is_scalar=...)` --- represents - `<name> [= <initialzer>]` code idiom. - - String input is converted to `CInitExpr` component. - -ExtGen provides the following general purpose components: - -- `Word(<word>)` - - Nothing can be added to `Word`. - -- `Line(*strings)` - - One can add `Line` component to `Line`. - String input is converted to `Line` component. - -- `Code(*lines)` - - One can add `Line` and `Code` components to `Code`. - String input is converted to `Line` component. - -- `FileSource(<filename>, *components)`. - - One can add `Line` and `Code` components to `FileSource`. - String input is converted to `Code` component. - -Developers reference manual -=========================== - -To extend ExtGen, one needs to understand the infrastructure of -generating extension modules. - -There are two important concepts in ExtGen model: components and -containers. Components (ref. class `Component`) define code blocks or -code idioms used in building up a code sources. Containers (ref. class -`Container`) are named string lists that are joined together with -specified rules resulting actual code sources. ExtGen uses two steps -for constructing code sources: - -- creating code components and adding them together to a parent - component. For example, the `PyCModule` instance in the - hello example becomes a parent component to a `PyCFunction` instance - after executing `m += f`. - -- generating code source by calling `.generate()` method of the - parent component. - -One can iterate the above process as one wishes. - -The method `PyCModule.build()` is defined for convenience. -It compiles the generated sources, builds an extension module, -imports the resulting module to Python, and returns the module object. - -All component classes must be derived from the base class `Component` -defined in `extgen/base.py` file. `Component` class defines the -following methods and attributes: - -- `.initialize(self, *args, **kws)` is used to initialize the attributes - and subcomponents of the `Component` instance. Derived classes - usually redefine it to define the signature of the component - constructor. - -- `.add(self, component, container_label=None)` is used to add - subcomponents to the `Component`. Derived classes can affect - the behavior of the `.add()` method by redefining the following - class attributes: - - - `.default_component_class_name` is used when the `component` - argument is not a `Component` instance. - - - `.default_container_label` is used when component - `container_label` is undefined. - - - `.component_containe_map` is used to find `container_label` - corresponding to `component` argument class. - -- `.update_parent(self, parent)` is called after `parent.add(self,..)`. - -- `.finalize(self)` is called after finishing adding new components - and before `.generate()` method call. - -- `.generate(self)` returns a source code string. It recursively - processes all subcomponents, creates code containers, and - evaluates code templates. - -- `.provides(self)` property method returns an unique string - labeling the current component. The label is used to name - the result of `.generate()` method when storing it to a container. - The result is saved to container only if container does not - contain the given provides label. With this feature one avoids - redefining the same functions, variables, types etc that are needed - by different components. - -- `.init_containers(self)` is called before processing subcomponents. - Derived classes may redefine it. - -- `.update_containers(self)` is called after processing subcomponents. - Derived classes usually define it to fill up any containers. - -- `.get_templates(self)` is used by `.generate()` method to evaluate - the templates and return results. By default, `.get_templates()` - returns `.template` attribute. Derived classes may redefine it - to return a tuple of templates, then also `.generate()` will - return a tuple of source code strings. - -- `.get_container(self, name)` or `.container_<name>` can be used - to retrive a container with a given name. If the current component - does not have requested container then the method tries to find - the container from parent classes. If it still does not find it, - then a new container with the given name will be created for - the current component. One should acctually avoid the last - solution and always define the containers in `.container_options` - class attribute. This attribute is a mapping between container - names and keyword options to the `Container` constructor. - See `Container` options below for more detail. - -- `.evaluate(self, template)` will evaluate `template` using - the attributes (with string values) and the code from containers. - -- `.info(message)`, `.warning(message)` are utility methods and - will write messages to `sys.stderr`. - -- `.register(*components)` will register predefined components - that can be retrived via `.get(provides)` method. - -Deriving a new `Component` class involves the following -tasks: - -- A component class must have a base class `Component`. - -- A component class may redefine `.initialize()`, - `.init_containers()`, `.add()`, `update_parent()`, - `.update_containers()`, `.get_templates()` - methods, `.provides()` property method and `.container_options`, - `.component_container_map`, `.default_container_label`, - `.default_component_class_name`, `.template` attributes. - -- In `.initialize()` method one can process constructor options, - set new attributes and add predefined components. It must - return a `Component` instance. - -- In `.init_containers()` and `.update_containers()` methods - one may retrive containers from parents via `.get_container(<name>)` - method or `.container_<name>` attribute and fill them using - `.add()` method of the container. - -- The attribute `.template` is a string containing formatting mapping keys - that correspond to containers names or instance attribute names. - -- The attribute `.container_options` is a mapping of container - names and keyword argument dictionaries used as options - to a `Container` constructor. - -- The attribute `.component_container_map` is a mapping between - subcomponent class names and the names of containers that should - be used to save the code generation results. - -- All classes derived from `Component` are available as - `Component.<subclass name>`. - -See `extgen/*.py` files for more examples how to redefine `Component` -class methods and attributes. - - -Using `Container` class ------------------------ - -`Container` class has the following optional arguments: - - - `separator='\n'` - - `prefix=''` - - `suffix=''` - - `skip_prefix_when_empty=False` - - `skip_suffix_when_empty=False` - - `default=''` - - `reverse=False` - - `use_indent=False` - - `use_firstline_indent=False` - - `indent_offset=0` - - `user_defined_str=None` - - `replace_map={}` - - `ignore_empty_content=False` - - `skip_prefix_suffix_when_single=False` - -that are used to enhance the behaviour of `Container.__str__()` -method. By default, `Container.__str__()` returns -`prefix+separator.join(<Container instance>.list)+suffix`. - -One can add items to `Container` instance using `.add(<string>, -label=None)` method. The items are saved in `.list` and `.label_map` -attributes. - -`Container` instances can be combined using `+` operator and -copied with `.copy()` method. The `.copy()` method has the -same arguments as `Container` constructor and can be used -to change certain container properties. - -The `label` argument should contain an unique value that represents -the content of `<string>`. If `label` is `None` then `label = -time.time()` will be set. - -If one tries to add items with the same label to the container then -the equality of the corresponding string values will be checked. If -they are not equal then `ValueError` is raised, otherwise adding an -item is ignored. - -If `reverse` is `True` then the `.list` is reversed before joining -its items. If `use_indent` is `True` then each item in `.list` will -be prefixed with `indent_offset` spaces. If `use_firstline_indent` is -`True` then additional indention of the number of starting spaces -in `.line[0]` is used. The `replace_map` is used to apply -`.replace(key, value)` method to the result of `__str__()`. -Full control over the `__str__()` method is obtained via -defining `user_defined_str` that should be a callable object taking -list as input and return a string. diff --git a/numpy/f2py/lib/extgen/py_support.py b/numpy/f2py/lib/extgen/py_support.py deleted file mode 100644 index 9f0057133..000000000 --- a/numpy/f2py/lib/extgen/py_support.py +++ /dev/null @@ -1,1104 +0,0 @@ - -__all__ = ['PySource', 'PyCFunction', 'PyCModule', 'PyCTypeSpec', 'PyCArgument', 'PyCReturn'] - -import os -import sys -from base import Component -from utils import * -from c_support import * - -class PySource(FileSource): - - template_py_header = '''\ -#!/usr/bin/env python -# This file %(path)r is generated using ExtGen tool -# from NumPy version %(numpy_version)s. -# ExtGen is developed by Pearu Peterson <pearu.peterson@gmail.com>. -# For more information see http://www.scipy.org/ExtGen/ .''' - - container_options = dict( - Content = dict(default='', - prefix = template_py_header + '\n', - suffix = '\n', - use_indent=True) - ) - - pass - -class PyCModule(CSource): - - """ - >>> m = PyCModule('PyCModule_test', title='This is first line.\\nSecond line.', description='This is a module.\\nYes, it is.') - >>> mod = m.build() - >>> print mod.__doc__ #doctest: +ELLIPSIS - This module 'PyCModule_test' is generated with ExtGen from NumPy version ... - <BLANKLINE> - This is first line. - Second line. - <BLANKLINE> - This is a module. - Yes, it is. - """ - - template = CSource.template_c_header + ''' -#ifdef __cplusplus -extern \"C\" { -#endif -#include "Python.h" -%(CHeader)s -%(CTypeDef)s -%(CProto)s -%(CDefinition)s -%(CAPIDefinition)s -%(CDeclaration)s -%(PyCModuleCDeclaration)s -%(CMainProgram)s -#ifdef __cplusplus -} -#endif -''' - - container_options = CSource.container_options.copy() - container_options.update(CAPIDefinition=container_options['CDefinition'], - PyCModuleCDeclaration=dict(default='<KILLLINE>', - ignore_empty_content=True), - ) - - component_container_map = dict( - PyCModuleInitFunction = 'CMainProgram', - PyCModuleCDeclaration = 'PyCModuleCDeclaration', - PyCFunction = 'CAPIDefinition', - ) - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - - self = CSource.initialize(self, '%smodule.c' % (pyname), **options) - self.need_numpy_support = False - - self.cdecl = PyCModuleCDeclaration(pyname) - self += self.cdecl - - self.main = PyCModuleInitFunction(pyname) - self += self.main - map(self.add, components) - return self - - def update_parent(self, parent): - if isinstance(parent, Component.SetupPy): - self.update_SetupPy(parent) - - def update_SetupPy(self, parent): - parent.setup_py += self.evaluate(' config.add_extension(%(pyname)r, sources = ["%(extmodulesrc)s"])', - extmodulesrc = self.path) - parent.init_py += 'import %s' % (self.pyname) - - def finalize(self): - if self.need_numpy_support: - self.add(CCode(''' -#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API -#include "numpy/arrayobject.h" -#include "numpy/arrayscalars.h" -'''), 'CHeader') - self.main.add(CCode(''' -import_array(); -if (PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "failed to load NumPy array module."); - goto capi_error; -} -'''),'CBody') - CSource.finalize(self) - - def build(self, build_dir=None, clean_at_exit=None): - """ build(build_dir=None, clean_at_exit=None) - - A convenience function to build, import, an return - an extension module object. - """ - if build_dir is None: - import tempfile - import time - packagename = 'extgen_' + str(hex(int(time.time()*10000000)))[2:] - build_dir = os.path.join(tempfile.gettempdir(), packagename) - clean_at_exit = True - - setup = Component.SetupPy(build_dir) - setup += self - s,o = setup.execute('build_ext','--inplace') - if s: - self.info('return status=%s' % (s)) - self.info(o) - raise RuntimeError('failed to build extension module %r,'\ - ' the build is located in %r directory'\ - % (self.pyname, build_dir)) - - if clean_at_exit: - import atexit - import shutil - atexit.register(lambda d=build_dir: shutil.rmtree(d)) - self.info('directory %r will be removed at exit from python.' % (build_dir)) - - sys.path.insert(0, os.path.dirname(build_dir)) - packagename = os.path.basename(build_dir) - try: - p = __import__(packagename) - m = getattr(p, self.pyname) - except: - del sys.path[0] - raise - else: - del sys.path[0] - return m - -class PyCModuleCDeclaration(Component): - - template = '''\ -static PyObject* extgen_module; -static -PyMethodDef extgen_module_methods[] = { - %(PyMethodDef)s - {NULL,NULL,0,NULL} -}; -static -char extgen_module_doc[] = -"This module %(pyname)r is generated with ExtGen from NumPy version %(numpy_version)s." -%(Title)s -%(Description)s -%(FunctionSignature)s -;''' - container_options = dict( - PyMethodDef = dict(suffix=',', skip_suffix_when_empty=True,separator=',\n', - default='<KILLLINE>', use_indent=True, ignore_empty_content=True), - FunctionSignature = dict(prefix='"\\n\\n:Functions:\\n"\n" ', skip_prefix_when_empty=True, use_indent=True, - ignore_empty_content=True, default='<KILLLINE>', - separator = '"\n" ', suffix='"', skip_suffix_when_empty=True, - ), - Title = dict(default='<KILLLINE>',prefix='"\\n\\n',suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - Description = dict(default='<KILLLINE>',prefix='"\\n\\n"\n"', - suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - ) - - default_component_class_name = 'Line' - - def initialize(self, pyname): - self.pyname = pyname - return self - - def update_parent(self, parent): - if isinstance(parent, PyCModule): - self.update_PyCModule(parent) - - def update_PyCModule(self, parent): - if parent.title: - self.add(parent.title, 'Title') - if parent.description: - self.add(parent.description, 'Description') - - -class PyCModuleInitFunction(CFunction): - - """ - >>> f = PyCModuleInitFunction('test_PyCModuleInitFunction') - >>> print f.generate() - PyMODINIT_FUNC - inittest_PyCModuleInitFunction(void) { - PyObject* extgen_module_dict = NULL; - PyObject* extgen_str_obj = NULL; - extgen_module = Py_InitModule(\"test_PyCModuleInitFunction\", extgen_module_methods); - if ((extgen_module_dict = PyModule_GetDict(extgen_module))==NULL) goto capi_error; - if ((extgen_str_obj = PyString_FromString(extgen_module_doc))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, \"__doc__\", extgen_str_obj); - Py_DECREF(extgen_str_obj); - if ((extgen_str_obj = PyString_FromString(\"restructuredtext\"))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, \"__docformat__\", extgen_str_obj); - Py_DECREF(extgen_str_obj); - return; - capi_error: - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, \"failed to initialize 'test_PyCModuleInitFunction' module.\"); - } - return; - } - """ - - template = '''\ -%(CSpecifier)s -%(CTypeSpec)s -%(name)s(void) { - PyObject* extgen_module_dict = NULL; - PyObject* extgen_str_obj = NULL; - %(CDeclaration)s - extgen_module = Py_InitModule("%(pyname)s", extgen_module_methods); - if ((extgen_module_dict = PyModule_GetDict(extgen_module))==NULL) goto capi_error; - if ((extgen_str_obj = PyString_FromString(extgen_module_doc))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, "__doc__", extgen_str_obj); - Py_DECREF(extgen_str_obj); - if ((extgen_str_obj = PyString_FromString("restructuredtext"))==NULL) goto capi_error; - PyDict_SetItemString(extgen_module_dict, "__docformat__", extgen_str_obj); - Py_DECREF(extgen_str_obj); - %(CBody)s - return; -capi_error: - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "failed to initialize %(pyname)r module."); - } - return; -}''' - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - self = CFunction.initialize(self, 'init'+pyname, 'PyMODINIT_FUNC', *components, **options) - return self - -#helper classes for PyCFunction -class KWListBase(Word): parent_container_options = dict(separator=', ', suffix=', ', skip_suffix_when_empty=True) -class ReqKWList(KWListBase): pass -class OptKWList(KWListBase): pass -class ExtKWList(KWListBase): pass -class ArgBase(Word): parent_container_options = dict(separator=', ') -class ReqArg(ArgBase): pass -class OptArg(ArgBase): pass -class ExtArg(ArgBase): pass -class RetArg(ArgBase): - parent_container_options = dict(separator=', ', prefix='(', suffix=')', default = 'None', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - skip_prefix_suffix_when_single=True) -class OptExtArg(ArgBase): - parent_container_options = dict(separator=', ', prefix=' [, ', skip_prefix_when_empty=True, - suffix=']', skip_suffix_when_empty=True) -class ArgDocBase(Word): - parent_container_options = dict(default='<KILLLINE>', prefix='"\\n\\nArguments:\\n"\n" ', - separator='\\n"\n" ', suffix='"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}) -class ReqArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Parameters:\\n"\n" ') -class OptArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Optional parameters:\\n"\n" ') -class ExtArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Extra parameters:\\n"\n" ') -class RetArgDoc(ArgDocBase): - parent_container_options = ArgDocBase.parent_container_options.copy() - parent_container_options.update(prefix='"\\n\\n:Returns:\\n"\n" ', - default='"\\n\\n:Returns:\\n None"') -class ArgFmtBase(Word): parent_container_options = dict(separator='') -class ReqArgFmt(ArgFmtBase): pass -class OptArgFmt(ArgFmtBase): pass -class ExtArgFmt(ArgFmtBase): pass -class RetArgFmt(ArgFmtBase): pass -class OptExtArgFmt(ArgFmtBase): - parent_container_options = dict(separator='', prefix='|', skip_prefix_when_empty=True) -class ArgObjBase(Word): parent_container_options = dict(separator=', ', prefix=', ', skip_prefix_when_empty=True) -class ReqArgObj(ArgObjBase): pass -class OptArgObj(ArgObjBase): pass -class ExtArgObj(ArgObjBase): pass -class RetArgObj(ArgObjBase): pass - -class FunctionSignature(Component): - template = '%(name)s(%(ReqArg)s%(OptExtArg)s) -> %(RetArg)s' - parent_container_options = dict() - container_options = dict( - ReqArg = ReqArg.parent_container_options, - OptArg = OptArg.parent_container_options, - ExtArg = ExtArg.parent_container_options, - RetArg = RetArg.parent_container_options, - OptExtArg = OptExtArg.parent_container_options, - ) - def initialize(self, name, *components, **options): - self.name = name - map(self.add, components) - return self - def update_containers(self): - self.container_OptExtArg += self.container_OptArg + self.container_ExtArg - -class PyCFunction(CFunction): - - """ - >>> from __init__ import * - >>> f = PyCFunction('foo') - >>> print f.generate() - static - char pyc_function_foo_doc[] = - \" foo() -> None\" - \"\\n\\n:Returns:\\n None\" - ; - static - PyObject* - pyc_function_foo(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) { - PyObject * volatile pyc_buildvalue = NULL; - volatile int capi_success = 1; - static char *capi_kwlist[] = {NULL}; - if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"", - capi_kwlist)) { - capi_success = !PyErr_Occurred(); - if (capi_success) { - pyc_buildvalue = Py_BuildValue(""); - } - } - return pyc_buildvalue; - } - >>> f = PyCFunction('foo', title=' Function title.\\nSecond line.', description=' This is a function.\\n2nd line.') - >>> e = PyCModule('PyCFunction_test', f) - >>> mod = e.build() - >>> print mod.foo.__doc__ - foo() -> None - <BLANKLINE> - Function title. - Second line. - <BLANKLINE> - This is a function. - 2nd line. - <BLANKLINE> - :Returns: - None - """ - - template = '''\ -static -char %(name)s_doc[] = -" %(FunctionSignature)s" -%(Title)s -%(Description)s -%(ReqArgDoc)s -%(RetArgDoc)s -%(OptArgDoc)s -%(ExtArgDoc)s -; -static -PyObject* -%(name)s(PyObject *pyc_self, PyObject *pyc_args, PyObject *pyc_keywds) { - PyObject * volatile pyc_buildvalue = NULL; - volatile int capi_success = 1; - %(CDeclaration)s - static char *capi_kwlist[] = {%(ReqKWList)s%(OptKWList)s%(ExtKWList)sNULL}; - if (PyArg_ParseTupleAndKeywords(pyc_args, pyc_keywds,"%(ReqArgFmt)s%(OptExtArgFmt)s", - capi_kwlist%(ReqArgObj)s%(OptArgObj)s%(ExtArgObj)s)) { - %(FromPyObj)s - %(CBody)s - capi_success = !PyErr_Occurred(); - if (capi_success) { - %(PyObjFrom)s - pyc_buildvalue = Py_BuildValue("%(RetArgFmt)s"%(RetArgObj)s); - %(CleanPyObjFrom)s - } - %(CleanCBody)s - %(CleanFromPyObj)s - } - return pyc_buildvalue; -}''' - - container_options = CFunction.container_options.copy() - - container_options.update(\ - - TMP = dict(), - - ReqArg = ReqArg.parent_container_options, - OptArg = OptArg.parent_container_options, - ExtArg = ExtArg.parent_container_options, - RetArg = RetArg.parent_container_options, - - FunctionSignature = FunctionSignature.parent_container_options, - - OptExtArg = OptExtArg.parent_container_options, - - Title = dict(default='<KILLLINE>',prefix='"\\n\\n',suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - Description = dict(default='<KILLLINE>',prefix='"\\n\\n"\n"', - suffix='"',separator='\\n"\n"', - skip_prefix_when_empty=True, skip_suffix_when_empty=True, - use_firstline_indent=True, replace_map={'\n':'\\n'}), - - ReqArgDoc = ReqArgDoc.parent_container_options, - OptArgDoc = OptArgDoc.parent_container_options, - ExtArgDoc = ExtArgDoc.parent_container_options, - RetArgDoc = RetArgDoc.parent_container_options, - - ReqKWList = ReqKWList.parent_container_options, - OptKWList = OptKWList.parent_container_options, - ExtKWList = ExtKWList.parent_container_options, - - ReqArgFmt = ReqArgFmt.parent_container_options, - OptArgFmt = OptArgFmt.parent_container_options, - ExtArgFmt = ExtArgFmt.parent_container_options, - OptExtArgFmt = OptExtArgFmt.ExtArgFmt.parent_container_options, - RetArgFmt = ExtArgFmt.parent_container_options, - - ReqArgObj = ReqArgObj.parent_container_options, - OptArgObj = OptArgObj.parent_container_options, - ExtArgObj = ExtArgObj.parent_container_options, - RetArgObj = RetArgObj.parent_container_options, - - FromPyObj = CCode.parent_container_options, - PyObjFrom = CCode.parent_container_options, - - CleanPyObjFrom = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - CleanCBody = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - CleanFromPyObj = dict(default='<KILLLINE>', reverse=True, use_indent=True, ignore_empty_content=True), - - ) - - default_component_class_name = 'CCode' - - component_container_map = CFunction.component_container_map.copy() - component_container_map.update( - PyCArgument = 'TMP', - CCode = 'CBody', - ) - - def initialize(self, pyname, *components, **options): - self.pyname = pyname - self.title = options.pop('title', None) - self.description = options.pop('description', None) - self = CFunction.initialize(self, 'pyc_function_'+pyname, 'PyObject*', **options) - self.signature = FunctionSignature(pyname) - self += self.signature - if self.title: - self.add(self.title, 'Title') - if self.description: - self.add(self.description, 'Description') - map(self.add, components) - return self - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.pyname]+[c for (c,l) in self.components]))) - - def update_parent(self, parent): - if isinstance(parent, PyCModule): - self.update_PyCModule(parent) - - def update_PyCModule(self, parent): - t = ' {"%(pyname)s", (PyCFunction)%(name)s, METH_VARARGS | METH_KEYWORDS, %(name)s_doc}' - parent.cdecl.add(self.evaluate(t),'PyMethodDef') - parent.cdecl.add(self.signature,'FunctionSignature') - - def update_containers(self): - self.container_OptExtArg += self.container_OptArg + self.container_ExtArg - self.container_OptExtArgFmt += self.container_OptArgFmt + self.container_ExtArgFmt - - # resolve dependencies - sorted_arguments = [] - sorted_names = [] - comp_map = {} - dep_map = {} - for (c,l) in self.components: - if not isinstance(c, Component.PyCArgument): - continue - d = [n for n in c.depends if n not in sorted_names] - if not d: - sorted_arguments.append((c,l)) - sorted_names.append(c.name) - else: - comp_map[c.name] = (c,l) - dep_map[c.name] = d - - while dep_map: - dep_map_copy = dep_map.copy() - for name, deps in dep_map.items(): - d = [n for n in deps if n in dep_map] - if not d: - sorted_arguments.append(comp_map[name]) - del dep_map[name] - else: - dep_map[name] = d - if dep_map_copy==dep_map: - self.warnign('%s: detected cyclic dependencies in %r, incorrect behavior is expected.\n'\ - % (self.provides, dep_map)) - sorted_arguments += dep_map.values() - break - - for c, l in sorted_arguments: - old_parent = c.parent - c.parent = self - c.ctype.set_converters(c) - c.parent = old_parent - - -class PyCArgument(Component): - - """ - >>> from __init__ import * - >>> a = PyCArgument('a') - >>> print a - PyCArgument('a', PyCTypeSpec('object')) - >>> print a.generate() - a - >>> f = PyCFunction('foo') - >>> f += a - >>> f += PyCArgument('b') - >>> m = PyCModule('PyCArgument_test') - >>> m += f - >>> #print m.generate() - >>> mod = m.build() - >>> print mod.__doc__ #doctest: +ELLIPSIS - This module 'PyCArgument_test' is generated with ExtGen from NumPy version ... - <BLANKLINE> - :Functions: - foo(a, b) -> None - - """ - - container_options = dict( - TMP = dict() - ) - - component_container_map = dict( - PyCTypeSpec = 'TMP' - ) - - template = '%(name)s' - - def initialize(self, name, ctype = object, *components, **options): - self.input_intent = options.pop('input_intent','required') # 'optional', 'extra', 'hide' - self.output_intent = options.pop('output_intent','hide') # 'return' - self.input_title = options.pop('input_title', None) - self.output_title = options.pop('output_title', None) - self.input_description = options.pop('input_description', None) - self.output_description = options.pop('output_description', None) - self.depends = options.pop('depends', []) - title = options.pop('title', None) - description = options.pop('description', None) - if title is not None: - if self.input_intent!='hide': - if self.input_title is None: - self.input_title = title - elif self.output_intent!='hide': - if self.output_title is None: - self.output_title = title - if description is not None: - if self.input_intent!='hide': - if self.input_description is None: - self.input_description = description - elif self.output_intent!='hide': - if self.output_description is None: - self.output_description = description - if options: self.warning('%s unused options: %s\n' % (self.__class__.__name__, options)) - - self.name = name - self.ctype = ctype = PyCTypeSpec(ctype) - self += ctype - - self.cvar = name - self.pycvar = None - self.retpycvar = None - - retfmt = ctype.get_pyret_fmt(self) - if isinstance(ctype, PyCTypeSpec): - if retfmt and retfmt in 'SON': - if self.output_intent == 'return': - if self.input_intent=='hide': - self.retpycvar = name - else: - self.pycvar = name - self.retpycvar = name + '_return' - elif self.input_intent!='hide': - self.pycvar = name - else: - self.pycvar = name - self.retpycvar = name - else: - self.pycvar = name + '_pyc' - self.retpycvar = name + '_pyc_r' - - ctype.set_titles(self) - - map(self.add, components) - return self - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.name]+[c for (c,l) in self.components]))) - - def update_parent(self, parent): - if isinstance(parent, PyCFunction): - self.update_PyCFunction(parent) - - def update_PyCFunction(self, parent): - ctype = self.ctype - - input_doc_title = '%s : %s' % (self.name, self.input_title) - output_doc_title = '%s : %s' % (self.name, self.output_title) - if self.input_description is not None: - input_doc_descr = ' %s' % (self.input_description) - else: - input_doc_descr = None - if self.output_description is not None: - output_doc_descr = ' %s' % (self.output_description) - else: - output_doc_descr = None - - # add components to parent: - parent += ctype.get_decl(self, parent) - if self.input_intent=='required': - parent += ReqArg(self.name) - parent.signature += ReqArg(self.name) - parent += ReqKWList('"' + self.name + '"') - parent += ReqArgFmt(ctype.get_pyarg_fmt(self)) - parent += ReqArgObj(ctype.get_pyarg_obj(self)) - parent += ReqArgDoc(input_doc_title) - parent += ReqArgDoc(input_doc_descr) - elif self.input_intent=='optional': - parent += OptArg(self.name) - parent.signature += OptArg(self.name) - parent += OptKWList('"' + self.name + '"') - parent += OptArgFmt(ctype.get_pyarg_fmt(self)) - parent += OptArgObj(ctype.get_pyarg_obj(self)) - parent += OptArgDoc(input_doc_title) - parent += OptArgDoc(input_doc_descr) - elif self.input_intent=='extra': - parent += ExtArg(self.name) - parent.signature += ExtArg(self.name) - parent += ExtKWList('"' + self.name + '"') - parent += ExtArgFmt(ctype.get_pyarg_fmt(self)) - parent += ExtArgObj(ctype.get_pyarg_obj(self)) - parent += ExtArgDoc(input_doc_title) - parent += ExtArgDoc(input_doc_descr) - elif self.input_intent=='hide': - pass - else: - raise NotImplementedError('input_intent=%r' % (self.input_intent)) - - if self.output_intent=='return': - parent += RetArg(self.name) - parent.signature += RetArg(self.name) - parent += RetArgFmt(ctype.get_pyret_fmt(self)) - parent += RetArgObj(ctype.get_pyret_obj(self)) - parent += RetArgDoc(output_doc_title) - parent += RetArgDoc(output_doc_descr) - elif self.output_intent=='hide': - pass - else: - raise NotImplementedError('output_intent=%r' % (self.output_intent)) - -class PyCReturn(PyCArgument): - - def initialize(self, name, ctype = object, *components, **options): - return PyCArgument(name, ctype, input_intent='hide', output_intent='return', *components, **options) - -class PyCTypeSpec(CTypeSpec): - - """ - >>> s = PyCTypeSpec(object) - >>> print s - PyCTypeSpec('object') - >>> print s.generate() - PyObject* - - >>> from __init__ import * - >>> m = PyCModule('test_PyCTypeSpec') - >>> f = PyCFunction('func') - >>> f += PyCArgument('i', int, output_intent='return') - >>> f += PyCArgument('l', long, output_intent='return') - >>> f += PyCArgument('f', float, output_intent='return') - >>> f += PyCArgument('c', complex, output_intent='return') - >>> f += PyCArgument('s', str, output_intent='return') - >>> f += PyCArgument('u', unicode, output_intent='return') - >>> f += PyCArgument('t', tuple, output_intent='return') - >>> f += PyCArgument('lst', list, output_intent='return') - >>> f += PyCArgument('d', dict, output_intent='return') - >>> f += PyCArgument('set', set, output_intent='return') - >>> f += PyCArgument('o1', object, output_intent='return') - >>> f += PyCArgument('o2', object, output_intent='return') - >>> m += f - >>> b = m.build() #doctest: +ELLIPSIS - >>> b.func(23, 23l, 1.2, 1+2j, 'hello', u'hei', (2,'a'), [-2], {3:4}, set([1,2]), 2, '15') - (23, 23L, 1.2, (1+2j), 'hello', u'hei', (2, 'a'), [-2], {3: 4}, set([1, 2]), 2, '15') - >>> print b.func.__doc__ - func(i, l, f, c, s, u, t, lst, d, set, o1, o2) -> (i, l, f, c, s, u, t, lst, d, set, o1, o2) - <BLANKLINE> - :Parameters: - i : a python int object - l : a python long object - f : a python float object - c : a python complex object - s : a python str object - u : a python unicode object - t : a python tuple object - lst : a python list object - d : a python dict object - set : a python set object - o1 : a python object - o2 : a python object - <BLANKLINE> - :Returns: - i : a python int object - l : a python long object - f : a python float object - c : a python complex object - s : a python str object - u : a python unicode object - t : a python tuple object - lst : a python list object - d : a python dict object - set : a python set object - o1 : a python object - o2 : a python object - - >>> m = PyCModule('test_PyCTypeSpec_c') - >>> f = PyCFunction('func_c_int') - >>> f += PyCArgument('i1', 'c_char', output_intent='return') - >>> f += PyCArgument('i2', 'c_short', output_intent='return') - >>> f += PyCArgument('i3', 'c_int', output_intent='return') - >>> f += PyCArgument('i4', 'c_long', output_intent='return') - >>> f += PyCArgument('i5', 'c_long_long', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_unsigned_int') - >>> f += PyCArgument('i1', 'c_unsigned_char', output_intent='return') - >>> f += PyCArgument('i2', 'c_unsigned_short', output_intent='return') - >>> f += PyCArgument('i3', 'c_unsigned_int', output_intent='return') - >>> f += PyCArgument('i4', 'c_unsigned_long', output_intent='return') - >>> f += PyCArgument('i5', 'c_unsigned_long_long', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_float') - >>> f += PyCArgument('f1', 'c_float', output_intent='return') - >>> f += PyCArgument('f2', 'c_double', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_complex') - >>> f += PyCArgument('c1', 'c_Py_complex', output_intent='return') - >>> m += f - >>> f = PyCFunction('func_c_string') - >>> f += PyCArgument('s1', 'c_const_char_ptr', output_intent='return') - >>> f += PyCArgument('s2', 'c_const_char_ptr', output_intent='return') - >>> f += PyCArgument('s3', 'c_Py_UNICODE', output_intent='return') - >>> f += PyCArgument('s4', 'c_char1', output_intent='return') - >>> m += f - >>> b = m.build() - >>> b.func_c_int(2,3,4,5,6) - (2, 3, 4, 5, 6L) - >>> b.func_c_unsigned_int(-1,-1,-1,-1,-1) - (255, 65535, 4294967295, 18446744073709551615L, 18446744073709551615L) - >>> b.func_c_float(1.2,1.2) - (1.2000000476837158, 1.2) - >>> b.func_c_complex(1+2j) - (1+2j) - >>> b.func_c_string('hei', None, u'tere', 'b') - ('hei', None, u'tere', 'b') - - >>> import numpy - >>> m = PyCModule('test_PyCTypeSpec_numpy') - >>> f = PyCFunction('func_int') - >>> f += PyCArgument('i1', numpy.int8, output_intent='return') - >>> f += PyCArgument('i2', numpy.int16, output_intent='return') - >>> f += PyCArgument('i3', numpy.int32, output_intent='return') - >>> f += PyCArgument('i4', numpy.int64, output_intent='return') - >>> m += f - >>> f = PyCFunction('func_uint') - >>> f += PyCArgument('i1', numpy.uint8, output_intent='return') - >>> f += PyCArgument('i2', numpy.uint16, output_intent='return') - >>> f += PyCArgument('i3', numpy.uint32, output_intent='return') - >>> f += PyCArgument('i4', numpy.uint64, output_intent='return') - >>> m += f - >>> f = PyCFunction('func_float') - >>> f += PyCArgument('f1', numpy.float32, output_intent='return') - >>> f += PyCArgument('f2', numpy.float64, output_intent='return') - >>> f += PyCArgument('f3', numpy.float128, output_intent='return') - >>> m += f - >>> f = PyCFunction('func_complex') - >>> f += PyCArgument('c1', numpy.complex64, output_intent='return') - >>> f += PyCArgument('c2', numpy.complex128, output_intent='return') - >>> f += PyCArgument('c3', numpy.complex256, output_intent='return') - >>> m += f - >>> f = PyCFunction('func_array') - >>> f += PyCArgument('a1', numpy.ndarray, output_intent='return') - >>> m += f - >>> b = m.build() - >>> b.func_int(numpy.int8(-2), numpy.int16(-3), numpy.int32(-4), numpy.int64(-5)) - (-2, -3, -4, -5) - >>> b.func_uint(numpy.uint8(-1), numpy.uint16(-1), numpy.uint32(-1), numpy.uint64(-1)) - (255, 65535, 4294967295, 18446744073709551615) - >>> b.func_float(numpy.float32(1.2),numpy.float64(1.2),numpy.float128(1.2)) - (1.20000004768, 1.2, 1.19999999999999995559) - >>> b.func_complex(numpy.complex64(1+2j),numpy.complex128(1+2j),numpy.complex256(1+2j)) - ((1+2j), (1+2j), (1.0+2.0j)) - >>> b.func_array(numpy.array([1,2])) - array([1, 2]) - >>> b.func_array(numpy.array(2)) - array(2) - >>> b.func_array(2) - Traceback (most recent call last): - ... - TypeError: argument 1 must be numpy.ndarray, not int - >>> b.func_array(numpy.int8(2)) - Traceback (most recent call last): - ... - TypeError: argument 1 must be numpy.ndarray, not numpy.int8 - """ - - typeinfo_map = dict( - int = ('PyInt_Type', 'PyIntObject*', 'O!', 'N', 'NULL'), - long = ('PyLong_Type', 'PyLongObject*', 'O!', 'N', 'NULL'), - float = ('PyFloat_Type', 'PyFloatObject*', 'O!', 'N', 'NULL'), - complex = ('PyComplex_Type', 'PyComplexObject*', 'O!', 'N', 'NULL'), - str = ('PyString_Type', 'PyStringObject*', 'S', 'N', 'NULL'), - unicode = ('PyUnicode_Type', 'PyUnicodeObject*', 'U', 'N', 'NULL'), - buffer = ('PyBuffer_Type', 'PyBufferObject*', 'O!', 'N', 'NULL'), - tuple = ('PyTuple_Type', 'PyTupleObject*', 'O!', 'N', 'NULL'), - list = ('PyList_Type', 'PyListObject*', 'O!', 'N', 'NULL'), - dict = ('PyDict_Type', 'PyDictObject*', 'O!', 'N', 'NULL'), - file = ('PyFile_Type', 'PyFileObject*', 'O!', 'N', 'NULL'), - instance = ('PyInstance_Type', 'PyObject*', 'O!', 'N', 'NULL'), - function = ('PyFunction_Type', 'PyFunctionObject*', 'O!', 'N', 'NULL'), - method = ('PyMethod_Type', 'PyObject*', 'O!', 'N', 'NULL'), - module = ('PyModule_Type', 'PyObject*', 'O!', 'N', 'NULL'), - iter = ('PySeqIter_Type', 'PyObject*', 'O!', 'N', 'NULL'), - property = ('PyProperty_Type', 'PyObject*', 'O!', 'N', 'NULL'), - slice = ('PySlice_Type', 'PyObject*', 'O!', 'N', 'NULL'), - cell = ('PyCell_Type', 'PyCellObject*', 'O!', 'N', 'NULL'), - generator = ('PyGen_Type', 'PyGenObject*', 'O!', 'N', 'NULL'), - set = ('PySet_Type', 'PySetObject*', 'O!', 'N', 'NULL'), - frozenset = ('PyFrozenSet_Type', 'PySetObject*', 'O!', 'N', 'NULL'), - cobject = (None, 'PyCObject*', 'O', 'N', 'NULL'), - type = ('PyType_Type', 'PyTypeObject*', 'O!', 'N', 'NULL'), - object = (None, 'PyObject*', 'O', 'N', 'NULL'), - numpy_ndarray = ('PyArray_Type', 'PyArrayObject*', 'O!', 'N', 'NULL'), - numpy_descr = ('PyArrayDescr_Type','PyArray_Descr', 'O!', 'N', 'NULL'), - numpy_ufunc = ('PyUFunc_Type', 'PyUFuncObject*', 'O!', 'N', 'NULL'), - numpy_iter = ('PyArrayIter_Type', 'PyArrayIterObject*', 'O!', 'N', 'NULL'), - numpy_multiiter = ('PyArrayMultiIter_Type', 'PyArrayMultiIterObject*', 'O!', 'N', 'NULL'), - numpy_int8 = ('PyInt8ArrType_Type', 'PyInt8ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int16 = ('PyInt16ArrType_Type', 'PyInt16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int32 = ('PyInt32ArrType_Type', 'PyInt32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int64 = ('PyInt64ArrType_Type', 'PyInt64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_int128 = ('PyInt128ArrType_Type', 'PyInt128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint8 = ('PyUInt8ArrType_Type', 'PyUInt8ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint16 = ('PyUInt16ArrType_Type', 'PyUInt16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint32 = ('PyUInt32ArrType_Type', 'PyUInt32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint64 = ('PyUInt64ArrType_Type', 'PyUInt64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_uint128 = ('PyUInt128ArrType_Type', 'PyUInt128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float16 = ('PyFloat16ArrType_Type', 'PyFloat16ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float32 = ('PyFloat32ArrType_Type', 'PyFloat32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float64 = ('PyFloat64ArrType_Type', 'PyFloat64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float80 = ('PyFloat80ArrType_Type', 'PyFloat80ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float96 = ('PyFloat96ArrType_Type', 'PyFloat96ScalarObject*', 'O!', 'N', 'NULL'), - numpy_float128 = ('PyFloat128ArrType_Type', 'PyFloat128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex32 = ('PyComplex32ArrType_Type', 'PyComplex32ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex64 = ('PyComplex64ArrType_Type', 'PyComplex64ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex128 = ('PyComplex128ArrType_Type', 'PyComplex128ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex160 = ('PyComplex160ArrType_Type', 'PyComplex160ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex192 = ('PyComplex192ArrType_Type', 'PyComplex192ScalarObject*', 'O!', 'N', 'NULL'), - numpy_complex256 = ('PyComplex256ArrType_Type', 'PyComplex256ScalarObject*', 'O!', 'N', 'NULL'), - numeric_array = ('PyArray_Type', 'PyArrayObject*', 'O!', 'N', 'NULL'), - c_char = (None, 'char', 'b', 'b', '0'), - c_unsigned_char = (None, 'unsigned char', 'B', 'B', '0'), - c_short = (None, 'short int', 'h', 'h', '0'), - c_unsigned_short = (None, 'unsigned short int', 'H', 'H', '0'), - c_int = (None,'int', 'i', 'i', '0'), - c_unsigned_int = (None,'unsigned int', 'I', 'I', '0'), - c_long = (None,'long', 'l', 'l', '0'), - c_unsigned_long = (None,'unsigned long', 'k', 'k', '0'), - c_long_long = (None,'PY_LONG_LONG', 'L', 'L', '0'), - c_unsigned_long_long = (None,'unsigned PY_LONG_LONG', 'K', 'K', '0'), - c_Py_ssize_t = (None,'Py_ssize_t', 'n', 'n', '0'), - c_char1 = (None,'char', 'c', 'c', '"\\0"'), - c_float = (None,'float', 'f', 'f', '0.0'), - c_double = (None,'double', 'd', 'd', '0.0'), - c_Py_complex = (None,'Py_complex', 'D', 'D', '{0.0, 0.0}'), - c_const_char_ptr = (None,'const char *', 'z', 'z', 'NULL'), - c_Py_UNICODE = (None,'Py_UNICODE*','u','u', 'NULL'), - ) - - def initialize(self, typeobj): - if isinstance(typeobj, self.__class__): - return typeobj - - m = self.typeinfo_map - - key = None - if isinstance(typeobj, type): - if typeobj.__module__=='__builtin__': - key = typeobj.__name__ - if key=='array': - key = 'numeric_array' - elif typeobj.__module__=='numpy': - key = 'numpy_' + typeobj.__name__ - elif isinstance(typeobj, str): - key = typeobj - if key.startswith('numpy_'): - k = key[6:] - named_scalars = ['byte','short','int','long','longlong', - 'ubyte','ushort','uint','ulong','ulonglong', - 'intp','uintp', - 'float_','double', - 'longfloat','longdouble', - 'complex_', - ] - if k in named_scalars: - import numpy - key = 'numpy_' + getattr(numpy, k).__name__ - - try: item = m[key] - except KeyError: - raise NotImplementedError('%s: need %s support' % (self.__class__.__name__, typeobj)) - - self.typeobj_name = key - self.ctypeobj = item[0] - self.line = item[1] - self.arg_fmt = item[2] - self.ret_fmt = item[3] - self.cinit_value = item[4] - - self.need_numpy_support = False - if key.startswith('numpy_'): - self.need_numpy_support = True - #self.add(Component.get('arrayobject.h'), 'CHeader') - #self.add(Component.get('import_array'), 'ModuleInit') - if key.startswith('numeric_'): - raise NotImplementedError(self.__class__.__name__ + ': Numeric support') - - return self - - def finalize(self): - if self.need_numpy_support: - self.component_PyCModule.need_numpy_support = True - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join([repr(self.typeobj_name)]+[repr(c) for (c,l) in self.components])) - - def get_pyarg_fmt(self, arg): - if arg.input_intent=='hide': return None - return self.arg_fmt - - def get_pyarg_obj(self, arg): - if arg.input_intent=='hide': return None - if self.arg_fmt=='O!': - return '&%s, &%s' % (self.ctypeobj, arg.pycvar) - return '&' + arg.pycvar - - def get_pyret_fmt(self, arg): - if arg.output_intent=='hide': return None - return self.ret_fmt - - def get_pyret_obj(self, arg): - if arg.output_intent=='return': - if self.get_pyret_fmt(arg)=='D': - return '&' + arg.retpycvar - return arg.retpycvar - return - - def get_init_value(self, arg): - return self.cinit_value - - def set_titles(self, arg): - if self.typeobj_name == 'object': - tn = 'a python ' + self.typeobj_name - else: - if self.typeobj_name.startswith('numpy_'): - tn = 'a numpy.' + self.typeobj_name[6:] + ' object' - elif self.typeobj_name.startswith('c_'): - n = self.typeobj_name[2:] - if not n.startswith('Py_'): - n = ' '.join(n.split('_')) - tn = 'a to C ' + n + ' convertable object' - else: - tn = 'a python ' + self.typeobj_name + ' object' - if arg.input_intent!='hide': - r = '' - if arg.input_title: r = ', ' + arg.input_title - arg.input_title = tn + r - if arg.output_intent!='hide': - r = '' - if arg.output_title: r = ', ' + arg.output_title - arg.output_title = tn + r - - def get_decl(self, arg, func): - init_value = self.get_init_value(arg) - if init_value: - init = ' = %s' % (init_value) - else: - init = '' - if arg.pycvar and arg.pycvar==arg.retpycvar: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - else: - if self.get_pyret_obj(arg) is None: - if self.get_pyret_obj(arg) is not None: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - elif self.get_pyarg_obj(arg) is not None: - func += CDeclaration(self, '%s%s' % (arg.pycvar, init)) - func += CDeclaration(self,'%s%s' % (arg.retpycvar, init)) - else: - func += CDeclaration(self, '%s%s' % (arg.retpycvar, init)) - return - - def set_converters(self, arg): - """ - Notes for user: - if arg is intent(optional, in, out) and not specified - as function argument then function may created but - it must then have *new reference* (ie use Py_INCREF - unless it is a new reference already). - """ - # this method is called from PyCFunction.update_containers(), - # note that self.parent is None put arg.parent is PyCFunction - # instance. - eval_a = arg.evaluate - FromPyObj = arg.container_FromPyObj - PyObjFrom = arg.container_PyObjFrom - - argfmt = self.get_pyarg_fmt(arg) - retfmt = self.get_pyret_fmt(arg) - if arg.output_intent=='return': - if arg.input_intent in ['optional', 'extra']: - if retfmt in 'SON': - FromPyObj += eval_a('''\ -if (!(%(pycvar)s==NULL)) { - /* make %(pycvar)r a new reference */ - %(retpycvar)s = %(pycvar)s; - Py_INCREF((PyObject*)%(retpycvar)s); -} -''') - PyObjFrom += eval_a('''\ -if (%(retpycvar)s==NULL) { - /* %(pycvar)r was not specified */ - if (%(pycvar)s==NULL) { - %(retpycvar)s = Py_None; - Py_INCREF((PyObject*)%(retpycvar)s); - } else { - %(retpycvar)s = %(pycvar)s; - /* %(pycvar)r must be a new reference or expect a core dump. */ - } -} elif (!(%(retpycvar)s == %(pycvar)s)) { - /* a new %(retpycvar)r was created, undoing %(pycvar)s new reference */ - Py_DECREF((PyObject*)%(pycvar)s); -} -''') - elif arg.input_intent=='hide': - if retfmt in 'SON': - PyObjFrom += eval_a('''\ -if (%(retpycvar)s==NULL) { - %(retpycvar)s = Py_None; - Py_INCREF((PyObject*)%(retpycvar)s); -} /* else %(retpycvar)r must be a new reference or expect a core dump. */ -''') - elif arg.input_intent=='required': - if retfmt in 'SON': - FromPyObj += eval_a('''\ -/* make %(pycvar)r a new reference */ -%(retpycvar)s = %(pycvar)s; -Py_INCREF((PyObject*)%(retpycvar)s); -''') - PyObjFrom += eval_a('''\ -if (!(%(retpycvar)s==%(pycvar)s)) { - /* a new %(retpycvar)r was created, undoing %(pycvar)r new reference */ - /* %(retpycvar)r must be a new reference or expect a core dump. */ - Py_DECREF((PyObject*)%(pycvar)s); -} -''') - - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/numpy/f2py/lib/extgen/setup_py.py b/numpy/f2py/lib/extgen/setup_py.py deleted file mode 100644 index da1d84943..000000000 --- a/numpy/f2py/lib/extgen/setup_py.py +++ /dev/null @@ -1,124 +0,0 @@ - -__all__ = ['SetupPy'] - -import os -import sys -from numpy.distutils.exec_command import exec_command -from base import Component -from utils import FileSource - -def write_files(container): - s = ['creating files and directories:'] - for filename, i in container.label_map.items(): - content = container.list[i] - d,f = os.path.split(filename) - if d and not os.path.isdir(d): - s.append(' %s/' % (d)) - if not Component._generate_dry_run: - os.makedirs(d) - s.append(' %s' % (filename)) - if not Component._generate_dry_run: - overwrite = True - if os.path.isfile(filename): - overwrite = False - f = file(filename, 'r') - i = 0 - for line in f: - if 'is generated using ExtGen tool' in line: - overwrite = True - break - i += 1 - if i>5: break - if not overwrite: - s[-1] += ' - unknown file exists, skipping' - else: - s[-1] += ' - extgen generated file exists, overwriting' - if overwrite: - f = file(filename,'w') - f.write(content) - f.close() - return '\n'.join(s) - - -class SetupPy(Component): - - """ - >>> from __init__ import * - >>> s = SetupPy('SetupPy_doctest') - >>> s += PyCModule('foo') - >>> s,o = s.execute('build_ext', '--inplace') - >>> assert s==0,`s` - >>> import SetupPy_doctest as mypackage - >>> print mypackage.foo.__doc__ #doctest: +ELLIPSIS - This module 'foo' is generated with ExtGen from NumPy version... - - """ - template_setup_py_start = '''\ -def configuration(parent_package='', top_path = ''): - from numpy.distutils.misc_util import Configuration - config = Configuration('',parent_package,top_path)''' - template_setup_py_end = '''\ - return config -if __name__ == "__main__": - from numpy.distutils.core import setup - setup(configuration=configuration) -''' - template = '%(SourceWriter)s' - - container_options = dict( - SourceWriter = dict(user_defined_str = write_files), - TMP = dict() - ) - - component_container_map = dict( - FileSource = 'SourceWriter', - ExtensionModule = 'TMP', - ) - - def initialize(self, build_dir, *components, **options): - self.name = self.path = build_dir - if not self.path: - self.setup_py = setup_py = Component.PySource('extgen_setup.py') - self.init_py = init_py = Component.PySource('extgen__init__.py') - else: - self.setup_py = setup_py = Component.PySource('setup.py') - self.init_py = init_py = Component.PySource('__init__.py') - - setup_py += self.template_setup_py_start - - self += init_py - self += setup_py - - map(self.add, components) - - return self - - def finalize(self): - self.setup_py += self.template_setup_py_end - - def execute(self, *args): - """ - Run generated setup.py file with given arguments. - """ - if not args: - raise ValueError('need setup.py arguments') - self.info(self.generate(dry_run=False)) - cmd = [sys.executable,'setup.py'] + list(args) - self.info('entering %r directory' % (self.path)) - self.info('executing command %r' % (' '.join(cmd))) - try: - r = exec_command(cmd, execute_in=self.path, use_tee=False) - except: - self.info('leaving %r directory' % (self.path)) - raise - else: - self.info('leaving %r directory' % (self.path)) - return r - - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/numpy/f2py/lib/extgen/utils.py b/numpy/f2py/lib/extgen/utils.py deleted file mode 100644 index aa156469f..000000000 --- a/numpy/f2py/lib/extgen/utils.py +++ /dev/null @@ -1,126 +0,0 @@ - -__all__ = ['Word', 'Line', 'Code', 'FileSource'] - -from base import Component - -class Word(Component): - template = '%(word)s' - - def initialize(self, word): - if not word: return None - self.word = word - return self - - def add(self, component, container_label=None): - raise ValueError('%s does not take components' % (self.__class__.__name__)) - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.word]+[c for (c,l) in self.components]))) - - -class Line(Component): - - """ - >>> l = Line('hey') - >>> l += ' you ' - >>> l += 2 - >>> print l - Line('hey you 2') - >>> print l.generate() - hey you 2 - >>> l += l - >>> print l.generate() - hey you 2hey you 2 - """ - - template = '%(line)s' - - def initialize(self, *strings): - self.line = '' - map(self.add, strings) - return self - - def add(self, component, container_label=None): - if isinstance(component, Line): - self.line += component.line - elif isinstance(component, str): - self.line += component - elif component is None: - pass - else: - self.line += str(component) - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.line]+[c for (c,l) in self.components]))) - - -class Code(Component): - - """ - >>> c = Code('start') - >>> c += 2 - >>> c += 'end' - >>> c - Code(Line('start'), Line('2'), Line('end')) - >>> print c.generate() - start - 2 - end - """ - - template = '%(Line)s' - - container_options = dict( - Line = dict(default = '<KILLLINE>', ignore_empty_content=True) - ) - component_container_map = dict( - Line = 'Line' - ) - default_component_class_name = 'Line' - - def initialize(self, *lines): - map(self.add, lines) - return self - - def add(self, component, label=None): - if isinstance(component, Code): - assert label is None,`label` - self.components += component.components - else: - Component.add(self, component, label) - - -class FileSource(Component): - - container_options = dict( - Content = dict(default='<KILLLINE>') - ) - - template = '%(Content)s' - - default_component_class_name = 'Code' - - component_container_map = dict( - Line = 'Content', - Code = 'Content', - ) - - def initialize(self, path, *components, **options): - self.path = path - map(self.add, components) - self._provides = options.pop('provides', path) - if options: self.warning('%s unused options: %s\n' % (self.__class__.__name__, options)) - return self - - def finalize(self): - self._provides = self.get_path() or self._provides - - def __repr__(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,[self.path]+[c for (c,l) in self.components]))) - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() diff --git a/numpy/f2py/lib/main.py b/numpy/f2py/lib/main.py deleted file mode 100644 index de34895e5..000000000 --- a/numpy/f2py/lib/main.py +++ /dev/null @@ -1,534 +0,0 @@ -""" -Tools for building F2PY generated extension modules. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import re -import sys -import tempfile - -try: - from numpy import __version__ as numpy_version -except ImportError: - numpy_version = 'N/A' - -__all__ = ['main', 'compile'] - -__usage__ = """ -F2PY G3 --- The third generation of Fortran to Python Interface Generator -========================================================================= - -Description ------------ - -f2py program generates a Python C/API file (<modulename>module.c) that -contains wrappers for given Fortran functions and data so that they -can be accessed from Python. With the -c option the corresponding -extension modules are built. - -Options -------- - - --g3-numpy Use numpy.f2py.lib tool, the 3rd generation of F2PY, - with NumPy support. - --2d-numpy Use numpy.f2py tool with NumPy support. [DEFAULT] - --2d-numeric Use f2py2e tool with Numeric support. - --2d-numarray Use f2py2e tool with Numarray support. - - -m <modulename> Name of the module; f2py generates a Python/C API - file <modulename>module.c or extension module <modulename>. - For wrapping Fortran 90 modules, f2py will use Fortran - module names. - --parse Parse Fortran files and print result to stdout. - - -Options effective only with -h ------------------------------- - - -h <filename> Write signatures of the fortran routines to file <filename> - and exit. You can then edit <filename> and use it instead - of <fortran files> for generating extension module source. - If <filename> is stdout or stderr then the signatures are - printed to the corresponding stream. - - --overwrite-signature Overwrite existing signature file. - -Options effective only with -c ------------------------------- - - -c Compile fortran sources and build extension module. - - --build-dir <dirname> All f2py generated files are created in <dirname>. - Default is tempfile.mktemp() and it will be removed after - f2py stops unless <dirname> is specified via --build-dir - option. - -numpy.distutils options effective only with -c ----------------------------------------------- - - --fcompiler=<name> Specify Fortran compiler type by vendor - - - -Extra options effective only with -c ------------------------------------- - - -L/path/to/lib/ -l<libname> - -D<name[=define]> -U<name> - -I/path/to/include/ - <filename>.o <filename>.(so|dynlib|dll) <filename>.a - - Using the following macros may be required with non-gcc Fortran - compilers: - -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN - -DUNDERSCORE_G77 - - -DF2PY_DEBUG_PYOBJ_TOFROM --- pyobj_(to|from)_<ctype> functions will - print debugging messages to stderr. - -""" - -import re -import shutil -import parser.api -from parser.api import parse, PythonModule, EndStatement, Module, Subroutine, Function,\ - get_reader - -def get_values(sys_argv, prefix='', suffix='', strip_prefix=False, strip_suffix=False): - """ - Return a list of values with pattern - <prefix><value><suffix>. - The corresponding items will be removed from sys_argv. - """ - match = re.compile(prefix + r'.*' + suffix + '\Z').match - ret = [item for item in sys_argv if match(item)] - [sys_argv.remove(item) for item in ret] - if strip_prefix and prefix: - i = len(prefix) - ret = [item[i:] for item in ret] - if strip_suffix and suffix: - i = len(suffix) - ret = [item[:-i] for item in ret] - return ret - -def get_option(sys_argv, option, default_return = None): - """ - Return True if sys_argv has <option>. - If <option> is not in sys_argv, return default_return. - <option> (when present) will be removed from sys_argv. - """ - try: - i = sys_argv.index(option) - except ValueError: - return default_return - del sys_argv[i] - return True - -def get_option_value(sys_argv, option, default_value = None, default_return = None): - """ - Return <value> from - sys_argv = [...,<option>,<value>,...] - list. - If <option> is the last element, return default_value. - If <option> is not in sys_argv, return default_return. - Both <option> and <value> (when present) will be removed from sys_argv. - """ - try: - i = sys_argv.index(option) - except ValueError: - return default_return - if len(sys_argv)-1==i: - del sys_argv[i] - return default_value - value = sys_argv[i+1] - del sys_argv[i+1] - del sys_argv[i] - return value - -def get_signature_output(sys_argv): - return get_option_value(sys_argv,'-h','stdout') - - -def parse_files(sys_argv): - flag = 'file' - file_names = [] - only_names = [] - skip_names = [] - options = [] - for word in sys_argv: - if word=='': pass - elif word=='only:': flag = 'only' - elif word=='skip:': flag = 'skip' - elif word==':': flag = 'file' - elif word.startswith('--'): options.append(word) - else: - {'file': file_names,'only': only_names, 'skip': skip_names}[flag].append(word) - - if options: - sys.stderr.write('Unused options: %s\n' % (', '.join(options))) - for filename in file_names: - if not os.path.isfile(filename): - sys.stderr.write('No or not a file %r. Skipping.\n' % (filename)) - continue - sys.stderr.write('Parsing %r..\n' % (filename)) - reader = parser.api.get_reader(filename) - print parser.api.Fortran2003.Program(reader) - return - -def dump_signature(sys_argv): - """ Read Fortran files and dump the signatures to file or stdout. - XXX: Not well tested. - """ - signature_output = get_signature_output(sys_argv) - - # initialize output stream - if signature_output in ['stdout','stderr']: - output_stream = getattr(sys, signature_output) - modulename = get_option_value(sys_argv,'-m','untitled','unknown') - else: - name,ext = os.path.splitext(signature_output) - if ext != '.pyf': - signature_output += '.pyf' - if os.path.isfile(signature_output): - overwrite = get_option(sys_argv, '--overwrite-signature', False) - if not overwrite: - print >> sys.stderr, 'Signature file %r exists. '\ - 'Use --overwrite-signature to overwrite.' % (signature_output) - sys.exit() - modulename = get_option_value(sys_argv,'-m',os.path.basename(name), - os.path.basename(name)) - output_stream = open(signature_output,'w') - - flag = 'file' - file_names = [] - only_names = [] - skip_names = [] - options = [] - for word in sys_argv: - if word=='': pass - elif word=='only:': flag = 'only' - elif word=='skip:': flag = 'skip' - elif word==':': flag = 'file' - elif word.startswith('--'): options.append(word) - else: - {'file': file_names,'only': only_names, - 'skip': skip_names}[flag].append(word) - - if options: - sys.stderr.write('Unused options: %s\n' % (', '.join(options))) - - output_stream.write('''! -*- f90 -*- -! Note: the context of this file is case sensitive. -''') - output_stream.write('PYTHON MODULE %s\n' % (modulename)) - output_stream.write(' INTERFACE\n\n') - for filename in file_names: - if not os.path.isfile(filename): - sys.stderr.write('No or not a file %r. Skipping.\n' % (filename)) - continue - sys.stderr.write('Parsing %r..\n' % (filename)) - block = parse(filename) - if block is None: - sys.exit(1) - output_stream.write('! File: %s, source mode = %r\n' % (filename, block.reader.mode)) - if block.content and isinstance(block.content[0],PythonModule): - for subblock in block.content[0].content[0].content: - if isinstance(subblock, EndStatement): - break - output_stream.write(subblock.topyf(' ')+'\n') - else: - output_stream.write(block.topyf(' ')+'\n') - output_stream.write(' END INTERFACE\n') - output_stream.write('END PYTHON MODULE %s\n' % (modulename)) - - if signature_output not in ['stdout','stderr']: - output_stream.close() - return - -def construct_extension_sources(modulename, parse_files, include_dirs, build_dir): - """ - Construct wrapper sources. - """ - from py_wrap import PythonWrapperModule - - f90_modules = [] - external_subprograms = [] - for filename in parse_files: - if not os.path.isfile(filename): - sys.stderr.write('No or not a file %r. Skipping.\n' % (filename)) - continue - sys.stderr.write('Parsing %r..\n' % (filename)) - for block in parse(filename, include_dirs=include_dirs).content: - if isinstance(block, Module): - f90_modules.append(block) - elif isinstance(block, (Subroutine, Function)): - external_subprograms.append(block) - else: - sys.stderr.write("Unhandled structure: %r\n" % (block.__class__)) - - module_infos = [] - - for block in f90_modules: - wrapper = PythonWrapperModule(block.name) - wrapper.add(block) - c_code = wrapper.c_code() - f_code = '! -*- f90 -*-\n' + wrapper.fortran_code() - c_fn = os.path.join(build_dir,'%smodule.c' % (block.name)) - f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py.f90' % (block.name)) - f = open(c_fn,'w') - f.write(c_code) - f.close() - f = open(f_fn,'w') - f.write(f_code) - f.close() - #f_lib = '%s_f_wrappers_f2py' % (block.name) - module_info = {'name':block.name, 'c_sources':[c_fn], - 'f_sources':[f_fn], 'language':'f90'} - module_infos.append(module_info) - - if external_subprograms: - wrapper = PythonWrapperModule(modulename) - for block in external_subprograms: - wrapper.add(block) - c_code = wrapper.c_code() - f_code = wrapper.fortran_code() - c_fn = os.path.join(build_dir,'%smodule.c' % (modulename)) - ext = '.f' - language = 'f77' - if wrapper.isf90: - f_code = '! -*- f90 -*-\n' + f_code - ext = '.f90' - language = 'f90' - f_fn = os.path.join(build_dir,'%s_f_wrappers_f2py%s' % (modulename, ext)) - f = open(c_fn,'w') - f.write(c_code) - f.close() - f = open(f_fn,'w') - f.write(f_code) - f.close() - module_info = {'name':modulename, 'c_sources':[c_fn], - 'f_sources':[f_fn], 'language':language} - module_infos.append(module_info) - - return module_infos - -def build_extension(sys_argv, sources_only = False): - """ - Build wrappers to Fortran 90 modules and external subprograms. - """ - modulename = get_option_value(sys_argv,'-m','untitled','unspecified') - - if sources_only: - build_dir = get_option_value(sys_argv,'--build-dir','.','') - else: - build_dir = get_option_value(sys_argv,'--build-dir','.',None) - if build_dir is None: - build_dir = tempfile.mktemp() - clean_build_dir = True - else: - clean_build_dir = False - if build_dir and not os.path.exists(build_dir): os.makedirs(build_dir) - - include_dirs = get_values(sys_argv,'-I',strip_prefix=True) - library_dirs = get_values(sys_argv,'-L',strip_prefix=True) - libraries = get_values(sys_argv,'-l',strip_prefix=True) - _define_macros = get_values(sys_argv,'-D',strip_prefix=True) - undef_macros = get_values(sys_argv,'-U',strip_prefix=True) - extra_objects = get_values(sys_argv,'','[.](o|a|so|dll|dylib|sl)') - - define_macros = [] - for item in _define_macros: - name_value = item.split('=',1) - if len(name_value)==1: - name_value.append(None) - if len(name_value)==2: - define_macros.append(tuple(name_value)) - else: - print 'Invalid use of -D:',name_value - - pyf_files = get_values(sys_argv,'','[.]pyf') - fortran_files = get_values(sys_argv,'','[.](f|f90|F90|F)') - c_files = get_values(sys_argv,'','[.](c|cpp|C|CPP|c[+][+])') - - fc_flags = get_values(sys_argv,'--fcompiler=') - - options = get_values(sys_argv,'-') - if options: - sys.stderr.write('Unused options: %s\n' % (', '.join(options))) - - if pyf_files: - parse_files = pyf_files - else: - parse_files = fortran_files + c_files - - module_infos = construct_extension_sources(modulename, parse_files, include_dirs, build_dir) - - if sources_only: - return - - def configuration(parent_package='', top_path=None or ''): - from numpy.distutils.misc_util import Configuration - config = Configuration('',parent_package,top_path) - flibname = modulename + '_fortran_f2py' - if fortran_files: - config.add_library(flibname, - sources = fortran_files) - libraries.insert(0,flibname) - - for module_info in module_infos: - name = module_info['name'] - c_sources = module_info['c_sources'] - f_sources = module_info['f_sources'] - language = module_info['language'] - if f_sources: - f_lib = '%s_f_wrappers_f2py' % (name) - config.add_library(f_lib, sources = f_sources) - libs = [f_lib] + libraries - else: - libs = libraries - config.add_extension(name, - sources=c_sources + c_files, - libraries = libs, - define_macros = define_macros, - undef_macros = undef_macros, - include_dirs = include_dirs, - extra_objects = extra_objects, - language = language, - ) - return config - - old_sys_argv = sys.argv[:] - build_dir_ext_temp = os.path.join(build_dir,'ext_temp') - build_dir_clib_temp = os.path.join(build_dir,'clib_temp') - build_dir_clib_clib = os.path.join(build_dir,'clib_clib') - new_sys_argv = [sys.argv[0]] + ['build_ext', - '--build-temp',build_dir_ext_temp, - '--build-lib',build_dir, - 'build_clib', - '--build-temp',build_dir_clib_temp, - '--build-clib',build_dir_clib_clib, - ] - temp_dirs = [build_dir_ext_temp, build_dir_clib_temp, build_dir_clib_clib] - - if fc_flags: - new_sys_argv += ['config_fc'] + fc_flags - sys.argv[:] = new_sys_argv - - sys.stderr.write('setup arguments: %r\n' % (' '.join(sys.argv))) - - from numpy.distutils.core import setup - setup(configuration=configuration) - - sys.argv[:] = old_sys_argv - - if 1 or clean_build_dir: - for d in temp_dirs: - if os.path.exists(d): - sys.stderr.write('Removing build directory %s\n'%(d)) - shutil.rmtree(d) - return - -def main(sys_argv = None): - """ Main function of f2py script. - """ - if sys_argv is None: - sys_argv = sys.argv[1:] - if '--help-link' in sys_argv: - sys_argv.remove('--help-link') - from numpy.distutils.system_info import show_all - show_all() - return - if '-c' in sys_argv: - sys_argv.remove('-c') - build_extension(sys_argv) - return - if '--parse' in sys_argv: - sys_argv.remove('--parse') - parse_files(sys_argv) - return - if '-h' in sys_argv: - dump_signature(sys_argv) - return - if not sys_argv or '--help' in sys_argv: - print >> sys.stdout, __usage__ - - build_extension(sys_argv, sources_only = True) - return - -def compile(source, - jobname = 'untitled', - extra_args = [], - source_ext = None, - modulenames = None - ): - """ - Build extension module from processing source with f2py. - - jobname - the name of compile job. For non-module source - this will be also the name of extension module. - modulenames - the list of extension module names that - the given compilation job should create. - extra_args - a list of extra arguments for numpy style - setup.py command line. - source_ext - extension of the Fortran source file: .f90 or .f - - Extension modules are saved to current working directory. - Returns a list of module objects according to modulenames - input. - """ - from nary import encode - tempdir = tempfile.gettempdir() - s = 'f2pyjob_%s_%s' % (jobname, encode(source)) - tmpdir = os.path.join(tempdir, s) - if source_ext is None: - reader = get_reader(source) - source_ext = {'free90':'.f90','fix90':'.f90','fix77':'.f','pyf':'.pyf'}[reader.mode] - - if modulenames is None: - modulenames = jobname, - if os.path.isdir(tmpdir): - sys.path.insert(0, tmpdir) - try: - modules = [] - for modulename in modulenames: - exec('import %s as m' % (modulename)) - modules.append(m) - sys.path.pop(0) - return modules - except ImportError: - pass - sys.path.pop(0) - else: - os.mkdir(tmpdir) - - fname = os.path.join(tmpdir,'%s_src%s' % (jobname, source_ext)) - - f = open(fname,'w') - f.write(source) - f.close() - - sys_argv = [] - sys_argv.extend(['--build-dir',tmpdir]) - #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM']) - sys_argv.extend(['-m',jobname, fname]) - - build_extension(sys_argv + extra_args) - - sys.path.insert(0, tmpdir) - modules = [] - for modulename in modulenames: - exec('import %s as m' % (modulename)) - modules.append(m) - sys.path.pop(0) - return modules - -#EOF diff --git a/numpy/f2py/lib/nary.py b/numpy/f2py/lib/nary.py deleted file mode 100644 index 948672b8c..000000000 --- a/numpy/f2py/lib/nary.py +++ /dev/null @@ -1,32 +0,0 @@ -""" -nary - convert integer to a number with an arbitrary base. -""" - -__all__ = ['nary'] - -_alphabet='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' -def _getalpha(r): - if r>=len(_alphabet): - return '_'+nary(r-len(_alphabet),len(_alphabet)) - return _alphabet[r] - -def nary(number, base=64): - """ - Return string representation of a number with a given base. - """ - if isinstance(number, str): - number = eval(number) - n = number - s = '' - while n: - n1 = n // base - r = n - n1*base - n = n1 - s = _getalpha(r) + s - return s - -def encode(string): - import md5 - return nary('0x'+md5.new(string).hexdigest()) - -#print nary(12345124254252525522512324,64) diff --git a/numpy/f2py/lib/parser/Fortran2003.py b/numpy/f2py/lib/parser/Fortran2003.py deleted file mode 100644 index 8242ab0a0..000000000 --- a/numpy/f2py/lib/parser/Fortran2003.py +++ /dev/null @@ -1,5890 +0,0 @@ -#!/usr/bin/env python -""" -Fortran 2003 Syntax Rules. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import re -from splitline import string_replace_map -import pattern_tools as pattern -from readfortran import FortranReaderBase - -############################################################################### -############################## BASE CLASSES ################################### -############################################################################### - -class NoMatchError(Exception): - pass - -class ParseError(Exception): - pass - -class Base(object): - """ Base class for Fortran 2003 syntax rules. - - All Base classes have the following attributes: - .string - original argument to construct a class instance, it's type - is either str or FortranReaderBase. - .item - Line instance (holds label) or None. - """ - subclasses = {} - - def __new__(cls, string, parent_cls = None): - """ - """ - if parent_cls is None: - parent_cls = [cls] - elif cls not in parent_cls: - parent_cls.append(cls) - #print '__new__:',cls.__name__,`string` - match = cls.__dict__.get('match', None) - if isinstance(string, FortranReaderBase) and not issubclass(cls, BlockBase) \ - and match is not None: - reader = string - item = reader.get_item() - if item is None: return - try: - obj = cls(item.line, parent_cls = parent_cls) - except NoMatchError: - obj = None - if obj is None: - reader.put_item(item) - return - obj.item = item - return obj - errmsg = '%s: %r' % (cls.__name__, string) - if match is not None: - try: - result = cls.match(string) - except NoMatchError, msg: - if str(msg)==errmsg: # avoid recursion 1. - raise - result = None - else: - result = None - - #print '__new__:result:',cls.__name__,`string,result` - if isinstance(result, tuple): - obj = object.__new__(cls) - obj.string = string - obj.item = None - if hasattr(cls, 'init'): obj.init(*result) - return obj - elif isinstance(result, Base): - return result - elif result is None: - for subcls in Base.subclasses.get(cls.__name__,[]): - if subcls in parent_cls: # avoid recursion 2. - continue - #print '%s:%s: %r' % (cls.__name__,subcls.__name__,string) - try: - obj = subcls(string, parent_cls = parent_cls) - except NoMatchError, msg: - obj = None - if obj is not None: - return obj - else: - raise AssertionError,`result` - raise NoMatchError,errmsg - -## def restore_reader(self): -## self._item.reader.put_item(self._item) -## return - - def init(self, *items): - self.items = items - return - def torepr(self): - return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,self.items))) - def compare(self, other): - return cmp(self.items,other.items) - - def __str__(self): return self.tostr() - - def __repr__(self): return self.torepr() - - def __cmp__(self, other): - if self is other: return 0 - if not isinstance(other, self.__class__): return cmp(self.__class__, other.__class__) - return self.compare(other) - - def tofortran(self, tab='', isfix=None): - return tab + str(self) - - -class BlockBase(Base): - """ - <block-base> = [ <startcls> ] - [ <subcls> ]... - ... - [ <subcls> ]... - [ <endcls> ] - """ - def match(startcls, subclasses, endcls, reader): - assert isinstance(reader,FortranReaderBase),`reader` - content = [] - if startcls is not None: - try: - obj = startcls(reader) - except NoMatchError: - obj = None - if obj is None: return - content.append(obj) - if endcls is not None: - classes = subclasses + [endcls] - else: - classes = subclasses[:] - i = 0 - while 1: - cls = classes[i] - try: - obj = cls(reader) - except NoMatchError: - obj = None - if obj is None: - j = i - for cls in classes[i+1:]: - j += 1 - try: - obj = cls(reader) - except NoMatchError: - obj = None - if obj is not None: - break - if obj is not None: - i = j - if obj is not None: - content.append(obj) - if endcls is not None and isinstance(obj, endcls): break - continue - if endcls is not None: - item = reader.get_item() - if item is not None: - reader.error('failed to parse with %s, skipping.' % ('|'.join([c.__name__ for c in classes[i:]])), item) - continue - if hasattr(content[0],'name'): - reader.error('unexpected eof file while looking line for <%s> of %s.'\ - % (classes[-1].__name__.lower().replace('_','-'), content[0].name)) - else: - reader.error('unexpected eof file while looking line for <%s>.'\ - % (classes[-1].__name__.lower().replace('_','-'))) - break - if not content: return - if startcls is not None and endcls is not None: - # check names of start and end statements: - start_stmt = content[0] - end_stmt = content[-1] - if isinstance(end_stmt, endcls) and hasattr(end_stmt, 'get_name') and hasattr(start_stmt, 'get_name'): - if end_stmt.get_name() is not None: - if start_stmt.get_name() != end_stmt.get_name(): - end_stmt._item.reader.error('expected <%s-name> is %s but got %s. Ignoring.'\ - % (end_stmt.get_type().lower(), start_stmt.get_name(), end_stmt.get_name())) - else: - end_stmt.set_name(start_stmt.get_name()) - return content, - match = staticmethod(match) - - def init(self, content): - self.content = content - return - def compare(self, other): - return cmp(self.content,other.content) - - def tostr(self): - return self.tofortran() - def torepr(self): - return '%s(%s)' % (self.__class__.__name__,', '.join(map(repr, self.content))) - - def tofortran(self, tab='', isfix=None): - l = [] - start = self.content[0] - end = self.content[-1] - extra_tab = '' - if isinstance(end, EndStmtBase): - extra_tab = ' ' - l.append(start.tofortran(tab=tab,isfix=isfix)) - for item in self.content[1:-1]: - l.append(item.tofortran(tab=tab+extra_tab,isfix=isfix)) - if len(self.content)>1: - l.append(end.tofortran(tab=tab,isfix=isfix)) - return '\n'.join(l) - -## def restore_reader(self): -## content = self.content[:] -## content.reverse() -## for obj in content: -## obj.restore_reader() -## return - -class SequenceBase(Base): - """ - <sequence-base> = <obj>, <obj> [ , <obj> ]... - """ - def match(separator, subcls, string): - line, repmap = string_replace_map(string) - if isinstance(separator, str): - splitted = line.split(separator) - else: - splitted = separator[1].split(line) - separator = separator[0] - if len(splitted)<=1: return - lst = [] - for p in splitted: - lst.append(subcls(repmap(p.strip()))) - return separator, tuple(lst) - match = staticmethod(match) - def init(self, separator, items): - self.separator = separator - self.items = items - return - def tostr(self): - s = self.separator - if s==',': s = s + ' ' - elif s==' ': pass - else: s = ' ' + s + ' ' - return s.join(map(str, self.items)) - def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.separator, self.items) - def compare(self, other): - return cmp((self.separator,self.items),(other.separator,self.items)) - -class UnaryOpBase(Base): - """ - <unary-op-base> = <unary-op> <rhs> - """ - def tostr(self): - return '%s %s' % tuple(self.items) - def match(op_pattern, rhs_cls, string): - m = op_pattern.match(string) - if not m: return - #if not m: return rhs_cls(string) - rhs = string[m.end():].lstrip() - if not rhs: return - op = string[:m.end()].rstrip().upper() - return op, rhs_cls(rhs) - match = staticmethod(match) - - -class BinaryOpBase(Base): - """ - <binary-op-base> = <lhs> <op> <rhs> - <op> is searched from right by default. - """ - def match(lhs_cls, op_pattern, rhs_cls, string, right=True): - line, repmap = string_replace_map(string) - if isinstance(op_pattern, str): - if right: - t = line.rsplit(op_pattern,1) - else: - t = line.split(op_pattern,1) - if len(t)!=2: return - lhs, rhs = t[0].rstrip(), t[1].lstrip() - op = op_pattern - else: - if right: - t = op_pattern.rsplit(line) - else: - t = op_pattern.lsplit(line) - if t is None or len(t)!=3: return - lhs, op, rhs = t - lhs = lhs.rstrip() - rhs = rhs.lstrip() - op = op.upper() - if not lhs: return - if not rhs: return - lhs_obj = lhs_cls(repmap(lhs)) - rhs_obj = rhs_cls(repmap(rhs)) - return lhs_obj, op, rhs_obj - match = staticmethod(match) - def tostr(self): - return '%s %s %s' % tuple(self.items) - -class SeparatorBase(Base): - """ - <separator-base> = [ <lhs> ] : [ <rhs> ] - """ - def match(lhs_cls, rhs_cls, string, require_lhs=False, require_rhs=False): - line, repmap = string_replace_map(string) - if ':' not in line: return - lhs,rhs = line.split(':',1) - lhs = lhs.rstrip() - rhs = rhs.lstrip() - lhs_obj, rhs_obj = None, None - if lhs: - if lhs_cls is None: return - lhs_obj = lhs_cls(repmap(lhs)) - elif require_lhs: - return - if rhs: - if rhs_cls is None: return - rhs_obj = rhs_cls(repmap(rhs)) - elif require_rhs: - return - return lhs_obj, rhs_obj - match = staticmethod(match) - def tostr(self): - s = '' - if self.items[0] is not None: - s += '%s :' % (self.items[0]) - else: - s += ':' - if self.items[1] is not None: - s += ' %s' % (self.items[1]) - return s - -class KeywordValueBase(Base): - """ - <keyword-value-base> = [ <lhs> = ] <rhs> - """ - def match(lhs_cls, rhs_cls, string, require_lhs = True, upper_lhs = False): - if require_lhs and '=' not in string: return - if isinstance(lhs_cls, (list, tuple)): - for s in lhs_cls: - try: - obj = KeywordValueBase.match(s, rhs_cls, string, require_lhs=require_lhs, upper_lhs=upper_lhs) - except NoMatchError: - obj = None - if obj is not None: return obj - return obj - lhs,rhs = string.split('=',1) - lhs = lhs.rstrip() - rhs = rhs.lstrip() - if not rhs: return - if not lhs: - if require_lhs: return - return None, rhs_cls(rhs) - if isinstance(lhs_cls, str): - if upper_lhs: - lhs = lhs.upper() - if lhs_cls!=lhs: return - return lhs, rhs_cls(rhs) - return lhs_cls(lhs),rhs_cls(rhs) - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return str(self.items[1]) - return '%s = %s' % tuple(self.items) - -class BracketBase(Base): - """ - <bracket-base> = <left-bracket-base> <something> <right-bracket> - """ - def match(brackets, cls, string, require_cls=True): - i = len(brackets)/2 - left = brackets[:i] - right = brackets[-i:] - if string.startswith(left) and string.endswith(right): - line = string[i:-i].strip() - if not line: - if require_cls: - return - return left,None,right - return left,cls(line),right - return - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: - return '%s%s' % (self.items[0], self.items[2]) - return '%s%s%s' % tuple(self.items) - -class NumberBase(Base): - """ - <number-base> = <number> [ _ <kind-param> ] - """ - def match(number_pattern, string): - m = number_pattern.match(string) - if m is None: return - return m.group('value').upper(),m.group('kind_param') - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return str(self.items[0]) - return '%s_%s' % tuple(self.items) - def compare(self, other): - return cmp(self.items[0], other.items[0]) - -class CallBase(Base): - """ - <call-base> = <lhs> ( [ <rhs> ] ) - """ - def match(lhs_cls, rhs_cls, string, upper_lhs = False, require_rhs=False): - if not string.endswith(')'): return - line, repmap = string_replace_map(string) - i = line.find('(') - if i==-1: return - lhs = line[:i].rstrip() - if not lhs: return - rhs = line[i+1:-1].strip() - lhs = repmap(lhs) - if upper_lhs: - lhs = lhs.upper() - rhs = repmap(rhs) - if isinstance(lhs_cls, str): - if lhs_cls!=lhs: return - else: - lhs = lhs_cls(lhs) - if rhs: - if isinstance(rhs_cls, str): - if rhs_cls!=rhs: return - else: - rhs = rhs_cls(rhs) - return lhs, rhs - elif require_rhs: - return - return lhs, None - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return '%s()' % (self.items[0]) - return '%s(%s)' % (self.items[0], self.items[1]) - -class CALLBase(CallBase): - """ - <CALL-base> = <LHS> ( [ <rhs> ] ) - """ - def match(lhs_cls, rhs_cls, string, require_rhs = False): - return CallBase.match(lhs_cls, rhs_cls, string, upper_lhs=True, require_rhs = require_rhs) - match = staticmethod(match) - -class StringBase(Base): - """ - <string-base> = <xyz> - """ - def match(pattern, string): - if isinstance(pattern, (list,tuple)): - for p in pattern: - obj = StringBase.match(p, string) - if obj is not None: return obj - return - if isinstance(pattern, str): - if len(pattern)==len(string) and pattern==string: return string, - return - if pattern.match(string): return string, - return - match = staticmethod(match) - def init(self, string): - self.string = string - return - def tostr(self): return str(self.string) - def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.string) - def compare(self, other): - return cmp(self.string,other.string) - -class STRINGBase(StringBase): - """ - <STRING-base> = <XYZ> - """ - match = staticmethod(StringBase.match) - def match(pattern, string): - if isinstance(pattern, (list,tuple)): - for p in pattern: - obj = STRINGBase.match(p, string) - if obj is not None: return obj - return - STRING = string.upper() - if isinstance(pattern, str): - if len(pattern)==len(string) and pattern==STRING: return STRING, - return - if pattern.match(STRING): return STRING, - return - match = staticmethod(match) - -class StmtBase(Base): - """ - [ <label> ] <stmt> - """ - def tofortran(self, tab='', isfix=None): - label = None - if self.item is not None: label = self.item.label - if isfix: - colon = '' - c = ' ' - else: - colon = ':' - c = '' - if label: - t = c + label + colon - if isfix: - while len(t)<6: t += ' ' - else: - tab = tab[len(t):] or ' ' - else: - t = '' - return t + tab + str(self) - -class EndStmtBase(StmtBase): - """ - <end-stmt-base> = END [ <stmt> [ <stmt-name>] ] - """ - def match(stmt_type, stmt_name, string, require_stmt_type=False): - start = string[:3].upper() - if start != 'END': return - line = string[3:].lstrip() - start = line[:len(stmt_type)].upper() - if start: - if start.replace(' ','') != stmt_type.replace(' ',''): return - line = line[len(stmt_type):].lstrip() - else: - if require_stmt_type: return - line = '' - if line: - if stmt_name is None: return - return stmt_type, stmt_name(line) - return stmt_type, None - match = staticmethod(match) - def init(self, stmt_type, stmt_name): - self.items = [stmt_type, stmt_name] - self.type, self.name = stmt_type, stmt_name - return - def get_name(self): return self.items[1] - def get_type(self): return self.items[0] - def set_name(self, name): - self.items[1] = name - def tostr(self): - if self.items[1] is not None: - return 'END %s %s' % tuple(self.items) - return 'END %s' % (self.items[0]) - def torepr(self): - return '%s(%r, %r)' % (self.__class__.__name__, self.type, self.name) - -def isalnum(c): return c.isalnum() or c=='_' - -class WORDClsBase(Base): - """ - <WORD-cls> = <WORD> [ [ :: ] <cls> ] - """ - def match(pattern, cls, string, check_colons=False, require_cls=False): - if isinstance(pattern, (tuple,list)): - for p in pattern: - try: - obj = WORDClsBase.match(p, cls, string, check_colons=check_colons, require_cls=require_cls) - except NoMatchError: - obj = None - if obj is not None: return obj - return - if isinstance(pattern, str): - if string[:len(pattern)].upper()!=pattern: return - line = string[len(pattern):] - if not line: return pattern, None - if isalnum(line[0]): return - line = line.lstrip() - if check_colons and line.startswith('::'): - line = line[2:].lstrip() - if not line: - if require_cls: return - return pattern, None - if cls is None: return - return pattern, cls(line) - m = pattern.match(string) - if m is None: return - line = string[len(m.group()):] - if pattern.value is not None: - pattern_value = pattern.value - else: - pattern_value = m.group().upper() - if not line: return pattern_value, None - if isalnum(line[0]): return - line = line.lstrip() - if check_colons and line.startswith('::'): - line = line[2:].lstrip() - if not line: - if require_cls: return - return pattern_value, None - if cls is None: return - return pattern_value, cls(line) - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return str(self.items[0]) - s = str(self.items[1]) - if s and s[0] in '(*': - return '%s%s' % (self.items[0], s) - return '%s %s' % (self.items[0], s) - def tostr_a(self): # colons version of tostr - if self.items[1] is None: return str(self.items[0]) - return '%s :: %s' % (self.items[0], self.items[1]) - -############################################################################### -############################### SECTION 1 #################################### -############################################################################### - -#R101: <xyz-list> = <xyz> [ , <xyz> ]... -#R102: <xyz-name> = <name> -#R103: <scalar-xyz> = <xyz> - -############################################################################### -############################### SECTION 2 #################################### -############################################################################### - -class Program(BlockBase): # R201 - """ - <program> = <program-unit> - [ <program-unit> ] ... - """ - subclass_names = [] - use_names = ['Program_Unit'] - def match(reader): - return BlockBase.match(Program_Unit, [Program_Unit], None, reader) - match = staticmethod(match) - -class Program_Unit(Base): # R202 - """ - <program-unit> = <main-program> - | <external-subprogram> - | <module> - | <block-data> - """ - subclass_names = ['Main_Program', 'External_Subprogram', 'Module', 'Block_Data'] - -class External_Subprogram(Base): # R203 - """ - <external-subprogram> = <function-subprogram> - | <subroutine-subprogram> - """ - subclass_names = ['Function_Subprogram', 'Subroutine_Subprogram'] - - -class Specification_Part(BlockBase): # R204 - """ - <specification-part> = [ <use-stmt> ]... - [ <import-stmt> ]... - [ <implicit-part> ] - [ <declaration-construct> ]... - """ - subclass_names = [] - use_names = ['Use_Stmt', 'Import_Stmt', 'Implicit_Part', 'Declaration_Construct'] - def match(reader): - return BlockBase.match(None, [Use_Stmt, Import_Stmt, Implicit_Part, Declaration_Construct], None, reader) - match = staticmethod(match) - -class Implicit_Part(Base): # R205 - """ - <implicit-part> = [ <implicit-part-stmt> ]... - <implicit-stmt> - """ - subclass_names = [] - use_names = ['Implicit_Part_Stmt', 'Implicit_Stmt'] - -class Implicit_Part_Stmt(Base): # R206 - """ - <implicit-part-stmt> = <implicit-stmt> - | <parameter-stmt> - | <format-stmt> - | <entry-stmt> - """ - subclass_names = ['Implicit_Stmt', 'Parameter_Stmt', 'Format_Stmt', 'Entry_Stmt'] - -class Declaration_Construct(Base): # R207 - """ - <declaration-construct> = <derived-type-def> - | <entry-stmt> - | <enum-def> - | <format-stmt> - | <interface-block> - | <parameter-stmt> - | <procedure-declaration-stmt> - | <specification-stmt> - | <type-declaration-stmt> - | <stmt-function-stmt> - """ - subclass_names = ['Derived_Type_Def', 'Entry_Stmt', 'Enum_Def', 'Format_Stmt', - 'Interface_Block', 'Parameter_Stmt', 'Procedure_Declaration_Stmt', - 'Specification_Stmt', 'Type_Declaration_Stmt', 'Stmt_Function_Stmt'] - -class Execution_Part(BlockBase): # R208 - """ - <execution-part> = <executable-construct> - | [ <execution-part-construct> ]... - - <execution-part> shall not contain <end-function-stmt>, <end-program-stmt>, <end-subroutine-stmt> - """ - subclass_names = [] - use_names = ['Executable_Construct_C201', 'Execution_Part_Construct_C201'] - def match(string): return BlockBase.match(Executable_Construct_C201, [Execution_Part_Construct_C201], None, string) - match = staticmethod(match) - -class Execution_Part_Construct(Base): # R209 - """ - <execution-part-construct> = <executable-construct> - | <format-stmt> - | <entry-stmt> - | <data-stmt> - """ - subclass_names = ['Executable_Construct', 'Format_Stmt', 'Entry_Stmt', 'Data_Stmt'] - -class Execution_Part_Construct_C201(Base): - subclass_names = ['Executable_Construct_C201', 'Format_Stmt', 'Entry_Stmt', 'Data_Stmt'] - -class Internal_Subprogram_Part(Base): # R210 - """ - <internal-subprogram-part> = <contains-stmt> - <internal-subprogram> - [ <internal-subprogram> ]... - """ - subclass_names = [] - use_names = ['Contains_Stmt', 'Internal_Subprogram'] - -class Internal_Subprogram(Base): # R211 - """ - <internal-subprogram> = <function-subprogram> - | <subroutine-subprogram> - """ - subclass_names = ['Function_Subprogram', 'Subroutine_Subprogram'] - -class Specification_Stmt(Base):# R212 - """ - <specification-stmt> = <access-stmt> - | <allocatable-stmt> - | <asynchronous-stmt> - | <bind-stmt> - | <common-stmt> - | <data-stmt> - | <dimension-stmt> - | <equivalence-stmt> - | <external-stmt> - | <intent-stmt> - | <intrinsic-stmt> - | <namelist-stmt> - | <optional-stmt> - | <pointer-stmt> - | <protected-stmt> - | <save-stmt> - | <target-stmt> - | <volatile-stmt> - | <value-stmt> - """ - subclass_names = ['Access_Stmt', 'Allocatable_Stmt', 'Asynchronous_Stmt','Bind_Stmt', - 'Common_Stmt', 'Data_Stmt', 'Dimension_Stmt', 'Equivalence_Stmt', - 'External_Stmt', 'Intent_Stmt', 'Intrinsic_Stmt', 'Namelist_Stmt', - 'Optional_Stmt','Pointer_Stmt','Protected_Stmt','Save_Stmt', - 'Target_Stmt','Volatile_Stmt', 'Value_Stmt'] - -class Executable_Construct(Base):# R213 - """ - <executable-construct> = <action-stmt> - | <associate-stmt> - | <case-construct> - | <do-construct> - | <forall-construct> - | <if-construct> - | <select-type-construct> - | <where-construct> - """ - subclass_names = ['Action_Stmt', 'Associate_Stmt', 'Case_Construct', 'Do_Construct', - 'Forall_Construct', 'If_Construct', 'Select_Type_Construct', 'Where_Construct'] - -class Executable_Construct_C201(Base): - subclass_names = Executable_Construct.subclass_names[:] - subclass_names[subclass_names.index('Action_Stmt')] = 'Action_Stmt_C201' - - -class Action_Stmt(Base):# R214 - """ - <action-stmt> = <allocate-stmt> - | <assignment-stmt> - | <backspace-stmt> - | <call-stmt> - | <close-stmt> - | <continue-stmt> - | <cycle-stmt> - | <deallocate-stmt> - | <endfile-stmt> - | <end-function-stmt> - | <end-program-stmt> - | <end-subroutine-stmt> - | <exit-stmt> - | <flush-stmt> - | <forall-stmt> - | <goto-stmt> - | <if-stmt> - | <inquire-stmt> - | <nullify-stmt> - | <open-stmt> - | <pointer-assignment-stmt> - | <print-stmt> - | <read-stmt> - | <return-stmt> - | <rewind-stmt> - | <stop-stmt> - | <wait-stmt> - | <where-stmt> - | <write-stmt> - | <arithmetic-if-stmt> - | <computed-goto-stmt> - """ - subclass_names = ['Allocate_Stmt', 'Assignment_Stmt', 'Backspace_Stmt', 'Call_Stmt', - 'Close_Stmt', 'Continue_Stmt', 'Cycle_Stmt', 'Deallocate_Stmt', - 'Endfile_Stmt', 'End_Function_Stmt', 'End_Subroutine_Stmt', 'Exit_Stmt', - 'Flush_Stmt', 'Forall_Stmt', 'Goto_Stmt', 'If_Stmt', 'Inquire_Stmt', - 'Nullify_Stmt', 'Open_Stmt', 'Pointer_Assignment_Stmt', 'Print_Stmt', - 'Read_Stmt', 'Return_Stmt', 'Rewind_Stmt', 'Stop_Stmt', 'Wait_Stmt', - 'Where_Stmt', 'Write_Stmt', 'Arithmetic_If_Stmt', 'Computed_Goto_Stmt'] - -class Action_Stmt_C201(Base): - """ - <action-stmt-c201> = <action-stmt> - C201 is applied. - """ - subclass_names = Action_Stmt.subclass_names[:] - subclass_names.remove('End_Function_Stmt') - subclass_names.remove('End_Subroutine_Stmt') - #subclass_names.remove('End_Program_Stmt') - -class Action_Stmt_C802(Base): - """ - <action-stmt-c802> = <action-stmt> - C802 is applied. - """ - subclass_names = Action_Stmt.subclass_names[:] - subclass_names.remove('End_Function_Stmt') - subclass_names.remove('End_Subroutine_Stmt') - subclass_names.remove('If_Stmt') - -class Action_Stmt_C824(Base): - """ - <action-stmt-c824> = <action-stmt> - C824 is applied. - """ - subclass_names = Action_Stmt.subclass_names[:] - subclass_names.remove('End_Function_Stmt') - subclass_names.remove('End_Subroutine_Stmt') - subclass_names.remove('Continue_Stmt') - subclass_names.remove('Goto_Stmt') - subclass_names.remove('Return_Stmt') - subclass_names.remove('Stop_Stmt') - subclass_names.remove('Exit_Stmt') - subclass_names.remove('Cycle_Stmt') - subclass_names.remove('Arithmetic_If_Stmt') - -class Keyword(Base): # R215 - """ - <keyword> = <name> - """ - subclass_names = ['Name'] - -############################################################################### -############################### SECTION 3 #################################### -############################################################################### - -#R301: <character> = <alphanumeric-character> | <special-character> -#R302: <alphanumeric-character> = <letter> | <digit> | <underscore> -#R303: <underscore> = _ - -class Name(StringBase): # R304 - """ - <name> = <letter> [ <alphanumeric_character> ]... - """ - subclass_names = [] - def match(string): return StringBase.match(pattern.abs_name, string) - match = staticmethod(match) - -class Constant(Base): # R305 - """ - <constant> = <literal-constant> - | <named-constant> - """ - subclass_names = ['Literal_Constant','Named_Constant'] - -class Literal_Constant(Base): # R306 - """ - <literal-constant> = <int-literal-constant> - | <real-literal-constant> - | <complex-literal-constant> - | <logical-literal-constant> - | <char-literal-constant> - | <boz-literal-constant> - """ - subclass_names = ['Int_Literal_Constant', 'Real_Literal_Constant','Complex_Literal_Constant', - 'Logical_Literal_Constant','Char_Literal_Constant','Boz_Literal_Constant'] - -class Named_Constant(Base): # R307 - """ - <named-constant> = <name> - """ - subclass_names = ['Name'] - -class Int_Constant(Base): # R308 - """ - <int-constant> = <constant> - """ - subclass_names = ['Constant'] - -class Char_Constant(Base): # R309 - """ - <char-constant> = <constant> - """ - subclass_names = ['Constant'] - -#R310: <intrinsic-operator> = <power-op> | <mult-op> | <add-op> | <concat-op> | <rel-op> | <not-op> | <and-op> | <or-op> | <equiv-op> -#R311: <defined-operator> = <defined-unary-op> | <defined-binary-op> | <extended-intrinsic-op> -#R312: <extended-intrinsic-op> = <intrinsic-op> - -class Label(StringBase): # R313 - """ - <label> = <digit> [ <digit> [ <digit> [ <digit> [ <digit> ] ] ] ] - """ - subclass_names = [] - def match(string): return StringBase.match(pattern.abs_label, string) - match = staticmethod(match) - -############################################################################### -############################### SECTION 4 #################################### -############################################################################### - -class Type_Spec(Base): # R401 - """ - <type-spec> = <intrinsic-type-spec> - | <derived-type-spec> - """ - subclass_names = ['Intrinsic_Type_Spec', 'Derived_Type_Spec'] - -class Type_Param_Value(StringBase): # R402 - """ - <type-param-value> = <scalar-int-expr> - | * - | : - """ - subclass_names = ['Scalar_Int_Expr'] - use_names = [] - def match(string): return StringBase.match(['*',':'], string) - match = staticmethod(match) - -class Intrinsic_Type_Spec(WORDClsBase): # R403 - """ - <intrinsic-type-spec> = INTEGER [ <kind-selector> ] - | REAL [ <kind-selector> ] - | DOUBLE COMPLEX - | COMPLEX [ <kind-selector> ] - | CHARACTER [ <char-selector> ] - | LOGICAL [ <kind-selector> ] - Extensions: - | DOUBLE PRECISION - | BYTE - """ - subclass_names = [] - use_names = ['Kind_Selector','Char_Selector'] - - def match(string): - for w,cls in [('INTEGER',Kind_Selector), - ('REAL',Kind_Selector), - ('COMPLEX',Kind_Selector), - ('LOGICAL',Kind_Selector), - ('CHARACTER',Char_Selector), - (pattern.abs_double_complex_name, None), - (pattern.abs_double_precision_name, None), - ('BYTE', None), - ]: - try: - obj = WORDClsBase.match(w,cls,string) - except NoMatchError: - obj = None - if obj is not None: return obj - return - match = staticmethod(match) - - -class Kind_Selector(Base): # R404 - """ - <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> ) - Extensions: - | * <char-length> - """ - subclass_names = [] - use_names = ['Char_Length','Scalar_Int_Initialization_Expr'] - - def match(string): - if string[0]+string[-1] != '()': - if not string.startswith('*'): return - return '*',Char_Length(string[1:].lstrip()) - line = string[1:-1].strip() - if line[:4].upper()=='KIND': - line = line[4:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - return '(',Scalar_Int_Initialization_Expr(line),')' - match = staticmethod(match) - def tostr(self): - if len(self.items)==2: return '%s%s' % tuple(self.items) - return '%sKIND = %s%s' % tuple(self.items) - -class Signed_Int_Literal_Constant(NumberBase): # R405 - """ - <signed-int-literal-constant> = [ <sign> ] <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] # never used because sign is included in pattern - def match(string): - return NumberBase.match(pattern.abs_signed_int_literal_constant_named, string) - match = staticmethod(match) - -class Int_Literal_Constant(NumberBase): # R406 - """ - <int-literal-constant> = <digit-string> [ _ <kind-param> ] - """ - subclass_names = [] - def match(string): - return NumberBase.match(pattern.abs_int_literal_constant_named, string) - match = staticmethod(match) - -#R407: <kind-param> = <digit-string> | <scalar-int-constant-name> -#R408: <signed-digit-string> = [ <sign> ] <digit-string> -#R409: <digit-string> = <digit> [ <digit> ]... -#R410: <sign> = + | - - -class Boz_Literal_Constant(Base): # R411 - """ - <boz-literal-constant> = <binary-constant> - | <octal-constant> - | <hex-constant> - """ - subclass_names = ['Binary_Constant','Octal_Constant','Hex_Constant'] - -class Binary_Constant(STRINGBase): # R412 - """ - <binary-constant> = B ' <digit> [ <digit> ]... ' - | B \" <digit> [ <digit> ]... \" - """ - subclass_names = [] - def match(string): return STRINGBase.match(pattern.abs_binary_constant, string) - match = staticmethod(match) - -class Octal_Constant(STRINGBase): # R413 - """ - <octal-constant> = O ' <digit> [ <digit> ]... ' - | O \" <digit> [ <digit> ]... \" - """ - subclass_names = [] - def match(string): return STRINGBase.match(pattern.abs_octal_constant, string) - match = staticmethod(match) - -class Hex_Constant(STRINGBase): # R414 - """ - <hex-constant> = Z ' <digit> [ <digit> ]... ' - | Z \" <digit> [ <digit> ]... \" - """ - subclass_names = [] - def match(string): return STRINGBase.match(pattern.abs_hex_constant, string) - match = staticmethod(match) - -#R415: <hex-digit> = <digit> | A | B | C | D | E | F - -class Signed_Real_Literal_Constant(NumberBase): # R416 - """ - <signed-real-literal-constant> = [ <sign> ] <real-literal-constant> - """ - subclass_names = ['Real_Literal_Constant'] # never used - def match(string): - return NumberBase.match(pattern.abs_signed_real_literal_constant_named, string) - match = staticmethod(match) - -class Real_Literal_Constant(NumberBase): # R417 - """ - """ - subclass_names = [] - def match(string): - return NumberBase.match(pattern.abs_real_literal_constant_named, string) - match = staticmethod(match) - -#R418: <significand> = <digit-string> . [ <digit-string> ] | . <digit-string> -#R419: <exponent-letter> = E | D -#R420: <exponent> = <signed-digit-string> - -class Complex_Literal_Constant(Base): # R421 - """ - <complex-literal-constant> = ( <real-part>, <imag-part> ) - """ - subclass_names = [] - use_names = ['Real_Part','Imag_Part'] - def match(string): - if not string or string[0]+string[-1]!='()': return - if not pattern.abs_complex_literal_constant.match(string): - return - r,i = string[1:-1].split(',') - return Real_Part(r.strip()), Imag_Part(i.strip()) - match = staticmethod(match) - def tostr(self): return '(%s, %s)' % tuple(self.items) - -class Real_Part(Base): # R422 - """ - <real-part> = <signed-int-literal-constant> - | <signed-real-literal-constant> - | <named-constant> - """ - subclass_names = ['Signed_Int_Literal_Constant','Signed_Real_Literal_Constant','Named_Constant'] - -class Imag_Part(Base): # R423 - """ - <imag-part> = <real-part> - """ - subclass_names = ['Signed_Int_Literal_Constant','Signed_Real_Literal_Constant','Named_Constant'] - -class Char_Selector(Base): # R424 - """ - <char-selector> = <length-selector> - | ( LEN = <type-param-value> , KIND = <scalar-int-initialization-expr> ) - | ( <type-param-value> , [ KIND = ] <scalar-int-initialization-expr> ) - | ( KIND = <scalar-int-initialization-expr> [ , LEN = <type-param-value> ] ) - """ - subclass_names = ['Length_Selector'] - use_names = ['Type_Param_Value','Scalar_Int_Initialization_Expr'] - def match(string): - if string[0]+string[-1] != '()': return - line, repmap = string_replace_map(string[1:-1].strip()) - if line[:3].upper()=='LEN': - line = line[3:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - i = line.find(',') - if i==-1: return - v = line[:i].rstrip() - line = line[i+1:].lstrip() - if line[:4].upper()!='KIND': return - line = line[4:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - v = repmap(v) - line = repmap(line) - return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) - elif line[:4].upper()=='KIND': - line = line[4:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - i = line.find(',') - if i==-1: return None,Scalar_Int_Initialization_Expr(line) - v = line[i+1:].lstrip() - line = line[:i].rstrip() - if v[:3].upper()!='LEN': return - v = v[3:].lstrip() - if not v.startswith('='): return - v = v[1:].lstrip() - return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) - else: - i = line.find(',') - if i==-1: return - v = line[:i].rstrip() - line = line[i+1:].lstrip() - if line[:4].upper()=='KIND': - line = line[4:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - return Type_Param_Value(v), Scalar_Int_Initialization_Expr(line) - return - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: - return '(KIND = %s)' % (self.items[1]) - return '(LEN = %s, KIND = %s)' % (self.items[0],self.items[1]) - -class Length_Selector(Base): # R425 - """ - <length -selector> = ( [ LEN = ] <type-param-value> ) - | * <char-length> [ , ] - """ - subclass_names = [] - use_names = ['Type_Param_Value','Char_Length'] - def match(string): - if string[0]+string[-1] == '()': - line = string[1:-1].strip() - if line[:3].upper()=='LEN': - line = line[3:].lstrip() - if not line.startswith('='): return - line = line[1:].lstrip() - return '(',Type_Param_Value(line),')' - if not string.startswith('*'): return - line = string[1:].lstrip() - if string[-1]==',': line = line[:-1].rstrip() - return '*',Char_Length(line) - match = staticmethod(match) - def tostr(self): - if len(self.items)==2: return '%s%s' % tuple(self.items) - return '%sLEN = %s%s' % tuple(self.items) - -class Char_Length(BracketBase): # R426 - """ - <char-length> = ( <type-param-value> ) - | <scalar-int-literal-constant> - """ - subclass_names = ['Scalar_Int_Literal_Constant'] - use_names = ['Type_Param_Value'] - def match(string): return BracketBase.match('()',Type_Param_Value, string) - match = staticmethod(match) - -class Char_Literal_Constant(Base): # R427 - """ - <char-literal-constant> = [ <kind-param> _ ] ' <rep-char> ' - | [ <kind-param> _ ] \" <rep-char> \" - """ - subclass_names = [] - rep = pattern.char_literal_constant - def match(string): - if string[-1] not in '"\'': return - if string[-1]=='"': - abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named2 - else: - abs_a_n_char_literal_constant_named = pattern.abs_a_n_char_literal_constant_named1 - line, repmap = string_replace_map(string) - m = abs_a_n_char_literal_constant_named.match(line) - if not m: return - kind_param = m.group('kind_param') - line = m.group('value') - line = repmap(line) - return line, kind_param - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return str(self.items[0]) - return '%s_%s' % (self.items[1], self.items[0]) - -class Logical_Literal_Constant(NumberBase): # R428 - """ - <logical-literal-constant> = .TRUE. [ _ <kind-param> ] - | .FALSE. [ _ <kind-param> ] - """ - subclass_names = [] - def match(string): - return NumberBase.match(pattern.abs_logical_literal_constant_named, string) - match = staticmethod(match) - -class Derived_Type_Def(Base): # R429 - """ - <derived-type-def> = <derived-type-stmt> - [ <type-param-def-stmt> ]... - [ <private-or-sequence> ]... - [ <component-part> ] - [ <type-bound-procedure-part> ] - <end-type-stmt> - """ - subclass_names = [] - use_names = ['Derived_Type_Stmt', 'Type_Param_Def_Stmt', 'Private_Or_Sequence', - 'Component_Part', 'Type_Bound_Procedure_Part', 'End_Type_Stmt'] - -class Derived_Type_Stmt(StmtBase): # R430 - """ - <derived-type-stmt> = TYPE [ [ , <type-attr-spec-list> ] :: ] <type-name> [ ( <type-param-name-list> ) ] - """ - subclass_names = [] - use_names = ['Type_Attr_Spec_List', 'Type_Name', 'Type_Param_Name_List'] - def match(string): - if string[:4].upper()!='TYPE': return - line = string[4:].lstrip() - i = line.find('::') - attr_specs = None - if i!=-1: - if line.startswith(','): - l = line[1:i].strip() - if not l: return - attr_specs = Type_Attr_Spec_List(l) - line = line[i+2:].lstrip() - m = pattern.name.match(line) - if m is None: return - name = Type_Name(m.group()) - line = line[m.end():].lstrip() - if not line: return attr_specs, name, None - if line[0]+line[-1]!='()': return - return attr_specs, name, Type_Param_Name_List(line[1:-1].strip()) - match = staticmethod(match) - def tostr(self): - s = 'TYPE' - if self.items[0] is not None: - s += ', %s :: %s' % (self.items[0], self.items[1]) - else: - s += ' :: %s' % (self.items[1]) - if self.items[2] is not None: - s += '(%s)' % (self.items[2]) - return s - -class Type_Name(Name): # C424 - """ - <type-name> = <name> - <type-name> shall not be DOUBLEPRECISION or the name of intrinsic type - """ - subclass_names = [] - use_names = [] - def match(string): - if pattern.abs_intrinsic_type_name.match(string): return - return Name.match(string) - match = staticmethod(match) - -class Type_EXTENDS_Parent_Type_Name(CALLBase): - """ - <..> = EXTENDS ( <parent-type-name> ) - """ - subclass_names = [] - use_names = ['Parent_Type_Name'] - def match(string): return CALLBase.match('EXTENDS', Parent_Type_Name, string) - match = staticmethod(match) - -class Type_Attr_Spec(STRINGBase): # R431 - """ - <type-attr-spec> = <access-spec> - | EXTENDS ( <parent-type-name> ) - | ABSTRACT - | BIND (C) - """ - subclass_names = ['Access_Spec', 'Type_EXTENDS_Parent_Type_Name', 'Language_Binding_Spec'] - def match(string): return STRINGBase.match('ABSTRACT', string) - match = staticmethod(match) - -class Private_Or_Sequence(Base): # R432 - """ - <private-or-sequence> = <private-components-stmt> - | <sequence-stmt> - """ - subclass_names = ['Private_Components_Stmt', 'Sequence_Stmt'] - -class End_Type_Stmt(EndStmtBase): # R433 - """ - <end-type-stmt> = END TYPE [ <type-name> ] - """ - subclass_names = [] - use_names = ['Type_Name'] - def match(string): return EndStmtBase.match('TYPE',Type_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Sequence_Stmt(STRINGBase): # R434 - """ - <sequence-stmt> = SEQUENCE - """ - subclass_names = [] - def match(string): return STRINGBase.match('SEQUENCE', string) - match = staticmethod(match) - -class Type_Param_Def_Stmt(StmtBase): # R435 - """ - <type-param-def-stmt> = INTEGER [ <kind-selector> ] , <type-param-attr-spec> :: <type-param-decl-list> - """ - subclass_names = [] - use_names = ['Kind_Selector', 'Type_Param_Attr_Spec', 'Type_Param_Decl_List'] - def match(string): - if string[:7].upper()!='INTEGER': return - line, repmap = string_replace_map(string[7:].lstrip()) - if not line: return - i = line.find(',') - if i==-1: return - kind_selector = repmap(line[:i].rstrip()) or None - line = repmap(line[i+1:].lstrip()) - i = line.find('::') - if i==-1: return - l1 = line[:i].rstrip() - l2 = line[i+2:].lstrip() - if not l1 or not l2: return - if kind_selector: kind_selector = Kind_Selector(kind_selector) - return kind_selector, Type_Param_Attr_Spec(l1), Type_Param_Decl_List(l2) - match = staticmethod(match) - def tostr(self): - s = 'INTEGER' - if self.items[0] is not None: - s += '%s, %s :: %s' % tuple(self.items) - else: - s += ', %s :: %s' % tuple(self.items[1:]) - return s - -class Type_Param_Decl(BinaryOpBase): # R436 - """ - <type-param-decl> = <type-param-name> [ = <scalar-int-initialization-expr> ] - """ - subclass_names = ['Type_Param_Name'] - use_names = ['Scalar_Int_Initialization_Expr'] - def match(string): - if '=' not in string: return - lhs,rhs = string.split('=',1) - lhs = lhs.rstrip() - rhs = rhs.lstrip() - if not lhs or not rhs: return - return Type_Param_Name(lhs),'=',Scalar_Int_Initialization_Expr(rhs) - match = staticmethod(match) - -class Type_Param_Attr_Spec(STRINGBase): # R437 - """ - <type-param-attr-spec> = KIND - | LEN - """ - subclass_names = [] - def match(string): return STRINGBase.match(['KIND', 'LEN'], string) - match = staticmethod(match) - - -class Component_Part(BlockBase): # R438 - """ - <component-part> = [ <component-def-stmt> ]... - """ - subclass_names = [] - use_names = ['Component_Def_Stmt'] - def match(reader): - content = [] - while 1: - try: - obj = Component_Def_Stmt(reader) - except NoMatchError: - obj = None - if obj is None: - break - content.append(obj) - if content: - return content, - return - match = staticmethod(match) - - def tofortran(self, tab='', isfix=None): - l = [] - for item in self.content: - l.append(item.tofortran(tab=tab,isfix=isfix)) - return '\n'.join(l) - -class Component_Def_Stmt(Base): # R439 - """ - <component-def-stmt> = <data-component-def-stmt> - | <proc-component-def-stmt> - """ - subclass_names = ['Data_Component_Def_Stmt', 'Proc_Component_Def_Stmt'] - -class Data_Component_Def_Stmt(StmtBase): # R440 - """ - <data-component-def-stmt> = <declaration-type-spec> [ [ , <component-attr-spec-list> ] :: ] <component-decl-list> - """ - subclass_names = [] - use_names = ['Declaration_Type_Spec', 'Component_Attr_Spec_List', 'Component_Decl_List'] - -class Dimension_Component_Attr_Spec(CALLBase): - """ - <dimension-component-attr-spec> = DIMENSION ( <component-array-spec> ) - """ - subclass_names = [] - use_names = ['Component_Array_Spec'] - def match(string): return CALLBase.match('DIMENSION', Component_Array_Spec, string) - match = staticmethod(match) - -class Component_Attr_Spec(STRINGBase): # R441 - """ - <component-attr-spec> = POINTER - | DIMENSION ( <component-array-spec> ) - | ALLOCATABLE - | <access-spec> - """ - subclass_names = ['Access_Spec', 'Dimension_Component_Attr_Spec'] - use_names = [] - def match(string): return STRINGBase.match(['POINTER', 'ALLOCATABLE'], string) - match = staticmethod(match) - -class Component_Decl(Base): # R442 - """ - <component-decl> = <component-name> [ ( <component-array-spec> ) ] [ * <char-length> ] [ <component-initialization> ] - """ - subclass_names = [] - use_names = ['Component_Name', 'Component_Array_Spec', 'Char_Length', 'Component_Initialization'] - def match(string): - m = pattern.name.match(string) - if m is None: return - name = Component_Name(m.group()) - newline = string[m.end():].lstrip() - if not newline: return name, None, None, None - array_spec = None - char_length = None - init = None - if newline.startswith('('): - line, repmap = string_replace_map(newline) - i = line.find(')') - if i==-1: return - array_spec = Component_Array_Spec(repmap(line[1:i].strip())) - newline = repmap(line[i+1:].lstrip()) - if newline.startswith('*'): - line, repmap = string_replace_map(newline) - i = line.find('=') - if i!=-1: - char_length = repmap(line[1:i].strip()) - newline = repmap(newline[i:].lstrip()) - else: - char_length = repmap(newline[1:].strip()) - newline = '' - char_length = Char_Length(char_length) - if newline.startswith('='): - init = Component_Initialization(newline) - else: - assert newline=='',`newline` - return name, array_spec, char_length, init - match = staticmethod(match) - def tostr(self): - s = str(self.items[0]) - if self.items[1] is not None: - s += '(' + str(self.items[1]) + ')' - if self.items[2] is not None: - s += '*' + str(self.items[2]) - if self.items[3] is not None: - s += ' ' + str(self.items[3]) - return s - -class Component_Array_Spec(Base): # R443 - """ - <component-array-spec> = <explicit-shape-spec-list> - | <deferred-shape-spec-list> - """ - subclass_names = ['Explicit_Shape_Spec_List', 'Deferred_Shape_Spec_List'] - -class Component_Initialization(Base): # R444 - """ - <component-initialization> = = <initialization-expr> - | => <null-init> - """ - subclass_names = [] - use_names = ['Initialization_Expr', 'Null_Init'] - def match(string): - if string.startswith('=>'): - return '=>', Null_Init(string[2:].lstrip()) - if string.startswith('='): - return '=', Initialization_Expr(string[2:].lstrip()) - return - match = staticmethod(match) - def tostr(self): return '%s %s' % tuple(self.items) - - -class Proc_Component_Def_Stmt(StmtBase): # R445 - """ - <proc-component-def-stmt> = PROCEDURE ( [ <proc-interface> ] ) , <proc-component-attr-spec-list> :: <proc-decl-list> - """ - subclass_names = [] - use_names = ['Proc_Interface', 'Proc_Component_Attr_Spec_List', 'Proc_Decl_List'] - -class Proc_Component_PASS_Arg_Name(CALLBase): - """ - <proc-component-PASS-arg-name> = PASS ( <arg-name> ) - """ - subclass_names = [] - use_names = ['Arg_Name'] - def match(string): return CALLBase.match('PASS', Arg_Name, string) - match = staticmethod(match) - -class Proc_Component_Attr_Spec(STRINGBase): # R446 - """ - <proc-component-attr-spec> = POINTER - | PASS [ ( <arg-name> ) ] - | NOPASS - | <access-spec> - """ - subclass_names = ['Access_Spec', 'Proc_Component_PASS_Arg_Name'] - def match(string): return STRINGBase.match(['POINTER','PASS','NOPASS'], string) - match = staticmethod(match) - -class Private_Components_Stmt(StmtBase): # R447 - """ - <private-components-stmt> = PRIVATE - """ - subclass_names = [] - def match(string): return StringBase.match('PRIVATE', string) - match = staticmethod(match) - -class Type_Bound_Procedure_Part(Base): # R448 - """ - <type-bound-procedure-part> = <contains-stmt> - [ <binding-private-stmt> ] - <proc-binding-stmt> - [ <proc-binding-stmt> ]... - """ - subclass_names = [] - use_names = ['Contains_Stmt', 'Binding_Private_Stmt', 'Proc_Binding_Stmt'] - -class Binding_Private_Stmt(StmtBase, STRINGBase): # R449 - """ - <binding-private-stmt> = PRIVATE - """ - subclass_names = [] - def match(string): return StringBase.match('PRIVATE', string) - match = staticmethod(match) - -class Proc_Binding_Stmt(Base): # R450 - """ - <proc-binding-stmt> = <specific-binding> - | <generic-binding> - | <final-binding> - """ - subclass_names = ['Specific_Binding', 'Generic_Binding', 'Final_Binding'] - -class Specific_Binding(StmtBase): # R451 - """ - <specific-binding> = PROCEDURE [ ( <interface-name> ) ] [ [ , <binding-attr-list> ] :: ] <binding-name> [ => <procedure-name> ] - """ - subclass_names = [] - use_names = ['Interface_Name', 'Binding_Attr_List', 'Binding_Name', 'Procedure_Name'] - -class Generic_Binding(StmtBase): # R452 - """ - <generic-binding> = GENERIC [ , <access-spec> ] :: <generic-spec> => <binding-name-list> - """ - subclass_names = [] - use_names = ['Access_Spec', 'Generic_Spec', 'Binding_Name_List'] - -class Binding_PASS_Arg_Name(CALLBase): - """ - <binding-PASS-arg-name> = PASS ( <arg-name> ) - """ - subclass_names = [] - use_names = ['Arg_Name'] - def match(string): return CALLBase.match('PASS', Arg_Name, string) - match = staticmethod(match) - -class Binding_Attr(STRINGBase): # R453 - """ - <binding-attr> = PASS [ ( <arg-name> ) ] - | NOPASS - | NON_OVERRIDABLE - | <access-spec> - """ - subclass_names = ['Access_Spec', 'Binding_PASS_Arg_Name'] - def match(string): return STRINGBase.match(['PASS', 'NOPASS', 'NON_OVERRIDABLE'], string) - match = staticmethod(match) - -class Final_Binding(StmtBase, WORDClsBase): # R454 - """ - <final-binding> = FINAL [ :: ] <final-subroutine-name-list> - """ - subclass_names = [] - use_names = ['Final_Subroutine_Name_List'] - def match(string): return WORDClsBase.match('FINAL',Final_Subroutine_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Derived_Type_Spec(CallBase): # R455 - """ - <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ] - """ - subclass_names = ['Type_Name'] - use_names = ['Type_Param_Spec_List'] - def match(string): return CallBase.match(Type_Name, Type_Param_Spec_List, string) - match = staticmethod(match) - -class Type_Param_Spec(KeywordValueBase): # R456 - """ - <type-param-spec> = [ <keyword> = ] <type-param-value> - """ - subclass_names = ['Type_Param_Value'] - use_names = ['Keyword'] - def match(string): return KeywordValueBase.match(Keyword, Type_Param_Value, string) - match = staticmethod(match) - -class Structure_Constructor_2(KeywordValueBase): # R457.b - """ - <structure-constructor-2> = [ <keyword> = ] <component-data-source> - """ - subclass_names = ['Component_Data_Source'] - use_names = ['Keyword'] - def match(string): return KeywordValueBase.match(Keyword, Component_Data_Source, string) - match = staticmethod(match) - -class Structure_Constructor(CallBase): # R457 - """ - <structure-constructor> = <derived-type-spec> ( [ <component-spec-list> ] ) - | <structure-constructor-2> - """ - subclass_names = ['Structure_Constructor_2'] - use_names = ['Derived_Type_Spec', 'Component_Spec_List'] - def match(string): return CallBase.match(Derived_Type_Spec, Component_Spec_List, string) - match = staticmethod(match) - -class Component_Spec(KeywordValueBase): # R458 - """ - <component-spec> = [ <keyword> = ] <component-data-source> - """ - subclass_names = ['Component_Data_Source'] - use_names = ['Keyword'] - def match(string): return KeywordValueBase.match(Keyword, Component_Data_Source, string) - match = staticmethod(match) - -class Component_Data_Source(Base): # R459 - """ - <component-data-source> = <expr> - | <data-target> - | <proc-target> - """ - subclass_names = ['Proc_Target', 'Data_Target', 'Expr'] - -class Enum_Def(Base): # R460 - """ - <enum-def> = <enum-def-stmt> - <enumerator-def-stmt> - [ <enumerator-def-stmt> ]... - <end-enum-stmt> - """ - subclass_names = [] - use_names = ['Enum_Def_Stmt', 'Enumerator_Def_Stmt', 'End_Enum_Stmt'] - -class Enum_Def_Stmt(STRINGBase): # R461 - """ - <enum-def-stmt> = ENUM, BIND(C) - """ - subclass_names = [] - def match(string): - if string[:4].upper()!='ENUM': return - line = string[4:].lstrip() - if not line.startswith(','): return - line = line[1:].lstrip() - if line[:4].upper()!='BIND': return - line = line[4:].lstrip() - if not line or line[0]+line[-1]!='()': return - line = line[1:-1].strip() - if line!='C' or line!='c': return - return 'ENUM, BIND(C)', - match = staticmethod(match) - -class Enumerator_Def_Stmt(StmtBase, WORDClsBase): # R462 - """ - <enumerator-def-stmt> = ENUMERATOR [ :: ] <enumerator-list> - """ - subclass_names = [] - use_names = ['Enumerator_List'] - def match(string): return WORDClsBase.match('ENUMERATOR',Enumerator_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Enumerator(BinaryOpBase): # R463 - """ - <enumerator> = <named-constant> [ = <scalar-int-initialization-expr> ] - """ - subclass_names = ['Named_Constant'] - use_names = ['Scalar_Int_Initialization_Expr'] - def match(string): - if '=' not in string: return - lhs,rhs = string.split('=',1) - return Named_Constant(lhs.rstrip()),'=',Scalar_Int_Initialization_Expr(rhs.lstrip()) - match = staticmethod(match) - -class End_Enum_Stmt(EndStmtBase): # R464 - """ - <end-enum-stmt> = END ENUM - """ - subclass_names = [] - def match(string): return EndStmtBase.match('ENUM',None, string, requite_stmt_type=True) - match = staticmethod(match) - -class Array_Constructor(BracketBase): # R465 - """ - <array-constructor> = (/ <ac-spec> /) - | <left-square-bracket> <ac-spec> <right-square-bracket> - - """ - subclass_names = [] - use_names = ['Ac_Spec'] - def match(string): - try: - obj = BracketBase.match('(//)', Ac_Spec, string) - except NoMatchError: - obj = None - if obj is None: - obj = BracketBase.match('[]', Ac_Spec, string) - return obj - match = staticmethod(match) - -class Ac_Spec(Base): # R466 - """ - <ac-spec> = <type-spec> :: - | [ <type-spec> :: ] <ac-value-list> - """ - subclass_names = ['Ac_Value_List'] - use_names = ['Type_Spec'] - def match(string): - if string.endswith('::'): - return Type_Spec(string[:-2].rstrip()),None - line, repmap = string_replace_map(string) - i = line.find('::') - if i==-1: return - ts = line[:i].rstrip() - line = line[i+2:].lstrip() - ts = repmap(ts) - line = repmap(line) - return Type_Spec(ts),Ac_Value_List(line) - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: - return str(self.items[1]) - if self.items[1] is None: - return str(self.items[0]) + ' ::' - return '%s :: %s' % self.items - -# R467: <left-square-bracket> = [ -# R468: <right-square-bracket> = ] - -class Ac_Value(Base): # R469 - """ - <ac-value> = <expr> - | <ac-implied-do> - """ - subclass_names = ['Ac_Implied_Do','Expr'] - -class Ac_Implied_Do(Base): # R470 - """ - <ac-implied-do> = ( <ac-value-list> , <ac-implied-do-control> ) - """ - subclass_names = [] - use_names = ['Ac_Value_List','Ac_Implied_Do_Control'] - def match(string): - if string[0]+string[-1] != '()': return - line, repmap = string_replace_map(string[1:-1].strip()) - i = line.rfind('=') - if i==-1: return - j = line[:i].rfind(',') - assert j!=-1 - s1 = repmap(line[:j].rstrip()) - s2 = repmap(line[j+1:].lstrip()) - return Ac_Value_List(s1),Ac_Implied_Do_Control(s2) - match = staticmethod(match) - def tostr(self): return '(%s, %s)' % tuple(self.items) - -class Ac_Implied_Do_Control(Base): # R471 - """ - <ac-implied-do-control> = <ac-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] - """ - subclass_names = [] - use_names = ['Ac_Do_Variable','Scalar_Int_Expr'] - def match(string): - i = string.find('=') - if i==-1: return - s1 = string[:i].rstrip() - line, repmap = string_replace_map(string[i+1:].lstrip()) - t = line.split(',') - if not (2<=len(t)<=3): return - t = [Scalar_Int_Expr(s.strip()) for s in t] - return Ac_Do_Variable(s1), t - match = staticmethod(match) - def tostr(self): return '%s = %s' % (self.items[0], ', '.join(map(str,self.items[1]))) - -class Ac_Do_Variable(Base): # R472 - """ - <ac-do-variable> = <scalar-int-variable> - <ac-do-variable> shall be a named variable - """ - subclass_names = ['Scalar_Int_Variable'] - -############################################################################### -############################### SECTION 5 #################################### -############################################################################### - -class Type_Declaration_Stmt(Base): # R501 - """ - <type-declaration-stmt> = <declaration-type-spec> [ [ , <attr-spec> ]... :: ] <entity-decl-list> - """ - subclass_names = [] - use_names = ['Declaration_Type_Spec', 'Attr_Spec_List', 'Entity_Decl_List'] - - def match(string): - line, repmap = string_replace_map(string) - i = line.find('::') - if i!=-1: - j = line[:i].find(',') - if j!=-1: - i = j - else: - if line[:6].upper()=='DOUBLE': - m = re.search(r'\s[a-z_]',line[6:].lstrip(),re.I) - if m is None: return - i = m.start() + len(line)-len(line[6:].lstrip()) - else: - m = re.search(r'\s[a-z_]',line,re.I) - if m is None: return - i = m.start() - type_spec = Declaration_Type_Spec(repmap(line[:i].rstrip())) - if type_spec is None: return - line = line[i:].lstrip() - if line.startswith(','): - i = line.find('::') - if i==-1: return - attr_specs = Attr_Spec_List(repmap(line[1:i].strip())) - if attr_specs is None: return - line = line[i:] - else: - attr_specs = None - if line.startswith('::'): - line = line[2:].lstrip() - entity_decls = Entity_Decl_List(repmap(line)) - if entity_decls is None: return - return type_spec, attr_specs, entity_decls - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: - return '%s :: %s' % (self.items[0], self.items[2]) - else: - return '%s, %s :: %s' % self.items - -class Declaration_Type_Spec(Base): # R502 - """ - <declaration-type-spec> = <intrinsic-type-spec> - | TYPE ( <derived-type-spec> ) - | CLASS ( <derived-type-spec> ) - | CLASS ( * ) - """ - subclass_names = ['Intrinsic_Type_Spec'] - use_names = ['Derived_Type_Spec'] - - def match(string): - if string[-1] != ')': return - start = string[:4].upper() - if start == 'TYPE': - line = string[4:].lstrip() - if not line.startswith('('): return - return 'TYPE',Derived_Type_Spec(line[1:-1].strip()) - start = string[:5].upper() - if start == 'CLASS': - line = string[5:].lstrip() - if not line.startswith('('): return - line = line[1:-1].strip() - if line=='*': return 'CLASS','*' - return 'CLASS', Derived_Type_Spec(line) - return - match = staticmethod(match) - def tostr(self): return '%s(%s)' % self.items - -class Dimension_Attr_Spec(CALLBase): # R503.d - """ - <dimension-attr-spec> = DIMENSION ( <array-spec> ) - """ - subclass_names = [] - use_names = ['Array_Spec'] - def match(string): return CALLBase.match('DIMENSION', Array_Spec, string) - match = staticmethod(match) - -class Intent_Attr_Spec(CALLBase): # R503.f - """ - <intent-attr-spec> = INTENT ( <intent-spec> ) - """ - subclass_names = [] - use_names = ['Intent_Spec'] - def match(string): return CALLBase.match('INTENT', Intent_Spec, string) - match = staticmethod(match) - -class Attr_Spec(STRINGBase): # R503 - """ - <attr-spec> = <access-spec> - | ALLOCATABLE - | ASYNCHRONOUS - | DIMENSION ( <array-spec> ) - | EXTERNAL - | INTENT ( <intent-spec> ) - | INTRINSIC - | <language-binding-spec> - | OPTIONAL - | PARAMETER - | POINTER - | PROTECTED - | SAVE - | TARGET - | VALUE - | VOLATILE - """ - subclass_names = ['Access_Spec', 'Language_Binding_Spec', - 'Dimension_Attr_Spec', 'Intent_Attr_Spec'] - use_names = [] - def match(string): return STRINGBase.match(pattern.abs_attr_spec, string) - match = staticmethod(match) - -class Entity_Decl(Base): # R504 - """ - <entity-decl> = <object-name> [ ( <array-spec> ) ] [ * <char-length> ] [ <initialization> ] - | <function-name> [ * <char-length> ] - """ - subclass_names = [] - use_names = ['Object_Name', 'Array_Spec', 'Char_Length', 'Initialization', 'Function_Name'] - def match(string): - m = pattern.name.match(string) - if m is None: return - name = Name(m.group()) - newline = string[m.end():].lstrip() - if not newline: return name, None, None, None - array_spec = None - char_length = None - init = None - if newline.startswith('('): - line, repmap = string_replace_map(newline) - i = line.find(')') - if i==-1: return - array_spec = Array_Spec(repmap(line[1:i].strip())) - newline = repmap(line[i+1:].lstrip()) - if newline.startswith('*'): - line, repmap = string_replace_map(newline) - i = line.find('=') - if i!=-1: - char_length = repmap(line[1:i].strip()) - newline = repmap(newline[i:].lstrip()) - else: - char_length = repmap(newline[1:].strip()) - newline = '' - char_length = Char_Length(char_length) - if newline.startswith('='): - init = Initialization(newline) - else: - assert newline=='',`newline` - return name, array_spec, char_length, init - match = staticmethod(match) - def tostr(self): - s = str(self.items[0]) - if self.items[1] is not None: - s += '(' + str(self.items[1]) + ')' - if self.items[2] is not None: - s += '*' + str(self.items[2]) - if self.items[3] is not None: - s += ' ' + str(self.items[3]) - return s - -class Object_Name(Base): # R505 - """ - <object-name> = <name> - """ - subclass_names = ['Name'] - -class Initialization(Base): # R506 - """ - <initialization> = = <initialization-expr> - | => <null-init> - """ - subclass_names = [] - use_names = ['Initialization_Expr', 'Null_Init'] - def match(string): - if string.startswith('=>'): - return '=>', Null_Init(string[2:].lstrip()) - if string.startswith('='): - return '=', Initialization_Expr(string[2:].lstrip()) - return - match = staticmethod(match) - def tostr(self): return '%s %s' % self.items - -class Null_Init(STRINGBase): # R507 - """ - <null-init> = <function-reference> - - <function-reference> shall be a reference to the NULL intrinsic function with no arguments. - """ - subclass_names = ['Function_Reference'] - def match(string): return STRINGBase.match('NULL', string) - match = staticmethod(match) - -class Access_Spec(STRINGBase): # R508 - """ - <access-spec> = PUBLIC - | PRIVATE - """ - subclass_names = [] - def match(string): return STRINGBase.match(['PUBLIC','PRIVATE'], string) - match = staticmethod(match) - -class Language_Binding_Spec(Base): # R509 - """ - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr> ] ) - """ - subclass_names = [] - use_names = ['Scalar_Char_Initialization_Expr'] - def match(string): - start = string[:4].upper() - if start != 'BIND': return - line = string[4:].lstrip() - if not line or line[0]+line[-1]!='()': return - line = line[1:-1].strip() - if not line: return - start = line[0].upper() - if start!='C': return - line = line[1:].lstrip() - if not line: return None, - if not line.startswith(','): return - line = line[1:].lstrip() - start = line[:4].upper() - if start!='NAME': return - line=line[4:].lstrip() - if not line.startswith('='): return - return Scalar_Char_Initialization_Expr(line[1:].lstrip()), - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return 'BIND(C)' - return 'BIND(C, NAME = %s)' % (self.items[0]) - -class Array_Spec(Base): # R510 - """ - <array-spec> = <explicit-shape-spec-list> - | <assumed-shape-spec-list> - | <deferred-shape-spec-list> - | <assumed-size-spec> - """ - subclass_names = ['Assumed_Size_Spec', 'Explicit_Shape_Spec_List', 'Assumed_Shape_Spec_List', - 'Deferred_Shape_Spec_List'] - -class Explicit_Shape_Spec(SeparatorBase): # R511 - """ - <explicit-shape-spec> = [ <lower-bound> : ] <upper-bound> - """ - subclass_names = [] - use_names = ['Lower_Bound', 'Upper_Bound'] - def match(string): - line, repmap = string_replace_map(string) - if ':' not in line: - return None, Upper_Bound(string) - lower,upper = line.split(':',1) - lower = lower.rstrip() - upper = upper.lstrip() - if not upper: return - if not lower: return - return Lower_Bound(repmap(lower)), Upper_Bound(repmap(upper)) - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return str(self.items[1]) - return SeparatorBase.tostr(self) - -class Lower_Bound(Base): # R512 - """ - <lower-bound> = <specification-expr> - """ - subclass_names = ['Specification_Expr'] - -class Upper_Bound(Base): # R513 - """ - <upper-bound> = <specification-expr> - """ - subclass_names = ['Specification_Expr'] - -class Assumed_Shape_Spec(SeparatorBase): # R514 - """ - <assumed-shape-spec> = [ <lower-bound> ] : - """ - subclass_names = [] - use_names = ['Lower_Bound'] - def match(string): return SeparatorBase.match(Lower_Bound, None, string) - match = staticmethod(match) - -class Deferred_Shape_Spec(SeparatorBase): # R515 - """ - <deferred_shape_spec> = : - """ - subclass_names = [] - def match(string): - if string==':': return None,None - return - match = staticmethod(match) - -class Assumed_Size_Spec(Base): # R516 - """ - <assumed-size-spec> = [ <explicit-shape-spec-list> , ] [ <lower-bound> : ] * - """ - subclass_names = [] - use_names = ['Explicit_Shape_Spec_List', 'Lower_Bound'] - def match(string): - if not string.endswith('*'): return - line = string[:-1].rstrip() - if not line: return None,None - if line.endswith(':'): - line, repmap = string_replace_map(line[:-1].rstrip()) - i = line.rfind(',') - if i==-1: - return None, Lower_Bound(repmap(line)) - return Explicit_Shape_Spec_List(repmap(line[:i].rstrip())), Lower_Bound(repmap(line[i+1:].lstrip())) - if not line.endswith(','): return - line = line[:-1].rstrip() - return Explicit_Shape_Spec_List(line), None - match = staticmethod(match) - def tostr(self): - s = '' - if self.items[0] is not None: - s += str(self.items[0]) + ', ' - if self.items[1] is not None: - s += str(self.items[1]) + ' : ' - s += '*' - return s - -class Intent_Spec(STRINGBase): # R517 - """ - <intent-spec> = IN - | OUT - | INOUT - """ - subclass_names = [] - def match(string): return STRINGBase.match(pattern.abs_intent_spec, string) - match = staticmethod(match) - -class Access_Stmt(StmtBase, WORDClsBase): # R518 - """ - <access-stmt> = <access-spec> [ [ :: ] <access-id-list> ] - """ - subclass_names = [] - use_names = ['Access_Spec', 'Access_Id_List'] - def match(string): return WORDClsBase.match(['PUBLIC', 'PRIVATE'],Access_Id_List,string,check_colons=True, require_cls=False) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Access_Id(Base): # R519 - """ - <access-id> = <use-name> - | <generic-spec> - """ - subclass_names = ['Use_Name', 'Generic_Spec'] - -class Object_Name_Deferred_Shape_Spec_List_Item(CallBase): - """ - <..> = <object-name> [ ( <deferred-shape-spec-list> ) ] - """ - subclass_names = ['Object_Name'] - use_names = ['Deferred_Shape_Spec_List'] - def match(string): return CallBase.match(Object_Name, Deferred_Shape_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -class Allocatable_Stmt(StmtBase, WORDClsBase): # R520 - """ - <allocateble-stmt> = ALLOCATABLE [ :: ] <object-name> [ ( <deferred-shape-spec-list> ) ] [ , <object-name> [ ( <deferred-shape-spec-list> ) ] ]... - """ - subclass_names = [] - use_names = ['Object_Name_Deferred_Shape_Spec_List_Item_List'] - def match(string): - return WORDClsBase.match('ALLOCATABLE', Object_Name_Deferred_Shape_Spec_List_Item_List, string, - check_colons=True, require_cls=True) - match = staticmethod(match) - -class Asynchronous_Stmt(StmtBase, WORDClsBase): # R521 - """ - <asynchronous-stmt> = ASYNCHRONOUS [ :: ] <object-name-list> - """ - subclass_names = [] - use_names = ['Object_Name_List'] - def match(string): return WORDClsBase.match('ASYNCHRONOUS',Object_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - - -class Bind_Stmt(StmtBase): # R522 - """ - <bind-stmt> = <language-binding-spec> [ :: ] <bind-entity-list> - """ - subclass_names = [] - use_names = ['Language_Binding_Spec', 'Bind_Entity_List'] - def match(string): - i = string.find('::') - if i==-1: - i = string.find(')') - if i==-1: return - lhs. rhs = string[:i], string[i+1:] - else: - lhs, rhs = string.split('::',1) - lhs = lhs.rstrip() - rhs = rhs.lstrip() - if not lhs or not rhs: return - return Language_Binding_Spec(lhs), Bind_Entity_List(rhs) - match = staticmethod(match) - def tostr(self): - return '%s :: %s' % self.items - - -class Bind_Entity(BracketBase): # R523 - """ - <bind-entity> = <entity-name> - | / <common-block-name> / - """ - subclass_names = ['Entity_Name'] - use_names = ['Common_Block_Name'] - def match(string): return BracketBase.match('//',Common_Block_Name, string) - match = staticmethod(match) - -class Data_Stmt(StmtBase): # R524 - """ - <data-stmt> = DATA <data-stmt-set> [ [ , ] <data-stmt-set> ]... - """ - subclass_names = [] - use_names = ['Data_Stmt_Set'] - -class Data_Stmt_Set(Base): # R525 - """ - <data-stmt-set> = <data-stmt-object-list> / <data-stmt-value-list> / - """ - subclass_names = [] - use_names = ['Data_Stmt_Object_List', 'Data_Stmt_Value_List'] - -class Data_Stmt_Object(Base): # R526 - """ - <data-stmt-object> = <variable> - | <data-implied-do> - """ - subclass_names = ['Variable', 'Data_Implied_Do'] - -class Data_Implied_Do(Base): # R527 - """ - <data-implied-do> = ( <data-i-do-object-list> , <data-i-do-variable> = <scalar-int-expr > , <scalar-int-expr> [ , <scalar-int-expr> ] ) - """ - subclass_names = [] - use_names = ['Data_I_Do_Object_List', 'Data_I_Do_Variable', 'Scalar_Int_Expr'] - -class Data_I_Do_Object(Base): # R528 - """ - <data-i-do-object> = <array-element> - | <scalar-structure-component> - | <data-implied-do> - """ - subclass_names = ['Array_Element', 'Scalar_Structure_Component', 'Data_Implied_Do'] - -class Data_I_Do_Variable(Base): # R529 - """ - <data-i-do-variable> = <scalar-int-variable> - """ - subclass_names = ['Scalar_Int_Variable'] - -class Data_Stmt_Value(Base): # R530 - """ - <data-stmt-value> = [ <data-stmt-repeat> * ] <data-stmt-constant> - """ - subclass_names = ['Data_Stmt_Constant'] - use_names = ['Data_Stmt_Repeat'] - def match(string): - line, repmap = string_replace_map(string) - s = line.split('*') - if len(s)!=2: return - lhs = repmap(s[0].rstrip()) - rhs = repmap(s[1].lstrip()) - if not lhs or not rhs: return - return Data_Stmt_Repeat(lhs), Data_Stmt_Constant(rhs) - match = staticmethod(match) - def tostr(self): - return '%s * %s' % self.items - -class Data_Stmt_Repeat(Base): # R531 - """ - <data-stmt-repeat> = <scalar-int-constant> - | <scalar-int-constant-subobject> - """ - subclass_names = ['Scalar_Int_Constant', 'Scalar_Int_Constant_Subobject'] - -class Data_Stmt_Constant(Base): # R532 - """ - <data-stmt-constant> = <scalar-constant> - | <scalar-constant-subobject> - | <signed-int-literal-constant> - | <signed-real-literal-constant> - | <null-init> - | <structure-constructor> - """ - subclass_names = ['Scalar_Constant', 'Scalar_Constant_Subobject', - 'Signed_Int_Literal_Constant', 'Signed_Real_Literal_Constant', - 'Null_Init', 'Structure_Constructor'] - -class Int_Constant_Subobject(Base): # R533 - """ - <int-constant-subobject> = <constant-subobject> - """ - subclass_names = ['Constant_Subobject'] - -class Constant_Subobject(Base): # R534 - """ - <constant-subobject> = <designator> - """ - subclass_names = ['Designator'] - -class Dimension_Stmt(StmtBase): # R535 - """ - <dimension-stmt> = DIMENSION [ :: ] <array-name> ( <array-spec> ) [ , <array-name> ( <array-spec> ) ]... - """ - subclass_names = [] - use_names = ['Array_Name', 'Array_Spec'] - def match(string): - if string[:9].upper()!='DIMENSION': return - line, repmap = string_replace_map(string[9:].lstrip()) - if line.startswith('::'): line = line[2:].lstrip() - decls = [] - for s in line.split(','): - s = s.strip() - if not s.endswith(')'): return - i = s.find('(') - if i==-1: return - decls.append((Array_Name(repmap(s[:i].rstrip())), Array_Spec(repmap(s[i+1:-1].strip())))) - if not decls: return - return decls, - match = staticmethod(match) - def tostr(self): - return 'DIMENSION :: ' + ', '.join(['%s(%s)' % ns for ns in self.items[0]]) - -class Intent_Stmt(StmtBase): # R536 - """ - <intent-stmt> = INTENT ( <intent-spec> ) [ :: ] <dummy-arg-name-list> - """ - subclass_names = [] - use_names = ['Intent_Spec', 'Dummy_Arg_Name_List'] - def match(string): - if string[:6].upper()!='INTENT': return - line = string[6:].lstrip() - if not line or not line.startswith('('): return - i = line.rfind(')') - if i==-1: return - spec = line[1:i].strip() - if not spec: return - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - if not line: return - return Intent_Spec(spec), Dummy_Arg_Name_List(line) - match = staticmethod(match) - def tostr(self): - return 'INTENT(%s) :: %s' % self.items - -class Optional_Stmt(StmtBase, WORDClsBase): # R537 - """ - <optional-stmt> = OPTIONAL [ :: ] <dummy-arg-name-list> - """ - subclass_names = [] - use_names = ['Dummy_Arg_Name_List'] - def match(string): return WORDClsBase.match('OPTIONAL',Dummy_Arg_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Parameter_Stmt(StmtBase, CALLBase): # R538 - """ - <parameter-stmt> = PARAMETER ( <named-constant-def-list> ) - """ - subclass_names = [] - use_names = ['Named_Constant_Def_List'] - def match(string): return CALLBase.match('PARAMETER', Named_Constant_Def_List, string, require_rhs=True) - match = staticmethod(match) - -class Named_Constant_Def(KeywordValueBase): # R539 - """ - <named-constant-def> = <named-constant> = <initialization-expr> - """ - subclass_names = [] - use_names = ['Named_Constant', 'Initialization_Expr'] - def match(string): return KeywordValueBase.match(Named_Constant, Initialization_Expr, string) - match = staticmethod(match) - -class Pointer_Stmt(StmtBase, WORDClsBase): # R540 - """ - <pointer-stmt> = POINTER [ :: ] <pointer-decl-list> - """ - subclass_names = [] - use_names = ['Pointer_Decl_List'] - def match(string): return WORDClsBase.match('POINTER',Pointer_Decl_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Pointer_Decl(CallBase): # R541 - """ - <pointer-decl> = <object-name> [ ( <deferred-shape-spec-list> ) ] - | <proc-entity-name> - """ - subclass_names = ['Proc_Entity_Name', 'Object_Name'] - use_names = ['Deferred_Shape_Spec_List'] - def match(string): return CallBase.match(Object_Name, Deferred_Shape_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -class Protected_Stmt(StmtBase, WORDClsBase): # R542 - """ - <protected-stmt> = PROTECTED [ :: ] <entity-name-list> - """ - subclass_names = [] - use_names = ['Entity_Name_List'] - def match(string): return WORDClsBase.match('PROTECTED',Entity_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Save_Stmt(StmtBase, WORDClsBase): # R543 - """ - <save-stmt> = SAVE [ [ :: ] <saved-entity-list> ] - """ - subclass_names = [] - use_names = ['Saved_Entity_List'] - def match(string): return WORDClsBase.match('SAVE',Saved_Entity_List,string,check_colons=True, require_cls=False) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Saved_Entity(BracketBase): # R544 - """ - <saved-entity> = <object-name> - | <proc-pointer-name> - | / <common-block-name> / - """ - subclass_names = ['Object_Name', 'Proc_Pointer_Name'] - use_names = ['Common_Block_Name'] - def match(string): return BracketBase.match('//',CommonBlockName, string) - match = staticmethod(match) - -class Proc_Pointer_Name(Base): # R545 - """ - <proc-pointer-name> = <name> - """ - subclass_names = ['Name'] - -class Target_Stmt(StmtBase): # R546 - """ - <target-stmt> = TARGET [ :: ] <object-name> [ ( <array-spec> ) ] [ , <object-name> [ ( <array-spec> ) ] ]... - """ - subclass_names = [] - use_names = ['Object_Name', 'Array_Spec'] - -class Value_Stmt(StmtBase, WORDClsBase): # R547 - """ - <value-stmt> = VALUE [ :: ] <dummy-arg-name-list> - """ - subclass_names = [] - use_names = ['Dummy_Arg_Name_List'] - def match(string): return WORDClsBase.match('VALUE',Dummy_Arg_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Volatile_Stmt(StmtBase, WORDClsBase): # R548 - """ - <volatile-stmt> = VOLATILE [ :: ] <object-name-list> - """ - subclass_names = [] - use_names = ['Object_Name_List'] - def match(string): return WORDClsBase.match('VOLATILE',Object_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Implicit_Stmt(StmtBase, WORDClsBase): # R549 - """ - <implicit-stmt> = IMPLICIT <implicit-spec-list> - | IMPLICIT NONE - """ - subclass_names = [] - use_names = ['Implicit_Spec_List'] - def match(string): - for w,cls in [(pattern.abs_implicit_none, None), - ('IMPLICIT', Implicit_Spec_List)]: - try: - obj = WORDClsBase.match(w, cls, string) - except NoMatchError: - obj = None - if obj is not None: return obj - return - match = staticmethod(match) - -class Implicit_Spec(CallBase): # R550 - """ - <implicit-spec> = <declaration-type-spec> ( <letter-spec-list> ) - """ - subclass_names = [] - use_names = ['Declaration_Type_Spec', 'Letter_Spec_List'] - def match(string): - if not string.endswith(')'): return - i = string.rfind('(') - if i==-1: return - s1 = string[:i].rstrip() - s2 = string[i+1:-1].strip() - if not s1 or not s2: return - return Declaration_Type_Spec(s1), Letter_Spec_List(s2) - match = staticmethod(match) - -class Letter_Spec(Base): # R551 - """ - <letter-spec> = <letter> [ - <letter> ] - """ - subclass_names = [] - def match(string): - if len(string)==1: - lhs = string.upper() - if 'A'<=lhs<='Z': return lhs, None - return - if '-' not in string: return - lhs,rhs = string.split('-',1) - lhs = lhs.strip().upper() - rhs = rhs.strip().upper() - if not len(lhs)==len(rhs)==1: return - if not ('A'<=lhs<=rhs<='Z'): return - return lhs,rhs - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return str(self.items[0]) - return '%s - %s' % tuple(self.items) - -class Namelist_Stmt(StmtBase): # R552 - """ - <namelist-stmt> = NAMELIST / <namelist-group-name> / <namelist-group-object-list> [ [ , ] / <namelist-group-name> / <namelist-group-object-list> ] - """ - subclass_names = [] - use_names = ['Namelist_Group_Name', 'Namelist_Group_Object_List'] - -class Namelist_Group_Object(Base): # R553 - """ - <namelist-group-object> = <variable-name> - """ - subclass_names = ['Variable_Name'] - -class Equivalence_Stmt(StmtBase, WORDClsBase): # R554 - """ - <equivalence-stmt> = EQUIVALENCE <equivalence-set-list> - """ - subclass_names = [] - use_names = ['Equivalence_Set_List'] - def match(string): return WORDClsBase.match('EQUIVALENCE', Equivalence_Set_List, string) - match = staticmethod(match) - -class Equivalence_Set(Base): # R555 - """ - <equivalence-set> = ( <equivalence-object> , <equivalence-object-list> ) - """ - subclass_names = [] - use_names = ['Equivalence_Object', 'Equivalence_Object_List'] - def match(string): - if not string or string[0]+string[-1]!='()': return - line = string[1:-1].strip() - if not line: return - l = Equivalence_Object_List(line) - obj = l.items[0] - l.items = l.items[1:] - if not l.items: return - return obj, l - match = staticmethod(match) - def tostr(self): return '(%s, %s)' % tuple(self.items) - -class Equivalence_Object(Base): # R556 - """ - <equivalence-object> = <variable-name> - | <array-element> - | <substring> - """ - subclass_names = ['Variable_Name', 'Array_Element', 'Substring'] - -class Common_Stmt(StmtBase): # R557 - """ - <common-stmt> = COMMON [ / [ <common-block-name> ] / ] <common-block-object-list> [ [ , ] / [ <common-block-name> ] / <common-block-object-list> ]... - """ - subclass_names = [] - use_names = ['Common_Block_Name', 'Common_Block_Object_List'] - def match(string): - if string[:6].upper()!='COMMON': return - line = string[6:] - if not line or 'A'<=line[0].upper()<='Z' or line[0]=='_': return - line, repmap = string_replace_map(line.lstrip()) - items = [] - if line.startswith('/'): - i = line.find('/',1) - if i==-1: return - name = line[1:i].strip() or None - if name is not None: name = Common_Block_Name(name) - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - lst = Common_Block_Object_List(repmap(line)) - line = '' - else: - l = line[:i].rstrip() - if l.endswith(','): l = l[:-1].rstrip() - if not l: return - lst = Common_Block_Object_List(repmap(l)) - line = line[i:].lstrip() - else: - name = None - i = line.find('/') - if i==-1: - lst = Common_Block_Object_List(repmap(line)) - line = '' - else: - l = line[:i].rstrip() - if l.endswith(','): l = l[:-1].rstrip() - if not l: return - lst = Common_Block_Object_List(repmap(l)) - line = line[i:].lstrip() - items.append((name, lst)) - while line: - if line.startswith(','): line = line[1:].lstrip() - if not line.startswith('/'): return - i = line.find('/',1) - name = line[1:i].strip() or None - if name is not None: name = Common_Block_Name(name) - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - lst = Common_Block_Object_List(repmap(line)) - line = '' - else: - l = line[:i].rstrip() - if l.endswith(','): l = l[:-1].rstrip() - if not l: return - lst = Common_Block_Object_List(repmap(l)) - line = line[i:].lstrip() - items.append((name, lst)) - return items, - match = staticmethod(match) - def tostr(self): - s = 'COMMON' - for (name, lst) in self.items[0]: - if name is not None: - s += ' /%s/ %s' % (name, lst) - else: - s += ' // %s' % (lst) - return s - -class Common_Block_Object(CallBase): # R558 - """ - <common-block-object> = <variable-name> [ ( <explicit-shape-spec-list> ) ] - | <proc-pointer-name> - """ - subclass_names = ['Proc_Pointer_Name','Variable_Name'] - use_names = ['Variable_Name', 'Explicit_Shape_Spec_List'] - def match(string): return CallBase.match(Variable_Name, Explicit_Shape_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -############################################################################### -############################### SECTION 6 #################################### -############################################################################### - -class Variable(Base): # R601 - """ - <variable> = <designator> - """ - subclass_names = ['Designator'] - -class Variable_Name(Base): # R602 - """ - <variable-name> = <name> - """ - subclass_names = ['Name'] - -class Designator(Base): # R603 - """ - <designator> = <object-name> - | <array-element> - | <array-section> - | <structure-component> - | <substring> - <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ] - <structure-component> = <data-ref> - """ - subclass_names = ['Object_Name','Array_Section','Array_Element','Structure_Component', - 'Substring' - ] - -class Logical_Variable(Base): # R604 - """ - <logical-variable> = <variable> - """ - subclass_names = ['Variable'] - -class Default_Logical_Variable(Base): # R605 - """ - <default-logical-variable> = <variable> - """ - subclass_names = ['Variable'] - -class Char_Variable(Base): # R606 - """ - <char-variable> = <variable> - """ - subclass_names = ['Variable'] - -class Default_Char_Variable(Base): # R607 - """ - <default-char-variable> = <variable> - """ - subclass_names = ['Variable'] - - -class Int_Variable(Base): # R608 - """ - <int-variable> = <variable> - """ - subclass_names = ['Variable'] - - -class Substring(CallBase): # R609 - """ - <substring> = <parent-string> ( <substring-range> ) - """ - subclass_names = [] - use_names = ['Parent_String','Substring_Range'] - def match(string): return CallBase.match(Parent_String, Substring_Range, string, require_rhs=True) - match = staticmethod(match) - -class Parent_String(Base): # R610 - """ - <parent-string> = <scalar-variable-name> - | <array-element> - | <scalar-structure-component> - | <scalar-constant> - """ - subclass_names = ['Scalar_Variable_Name', 'Array_Element', 'Scalar_Structure_Component', 'Scalar_Constant'] - -class Substring_Range(SeparatorBase): # R611 - """ - <substring-range> = [ <scalar-int-expr> ] : [ <scalar-int-expr> ] - """ - subclass_names = [] - use_names = ['Scalar_Int_Expr'] - def match(string): - return SeparatorBase.match(Scalar_Int_Expr, Scalar_Int_Expr, string) - match = staticmethod(match) - -class Data_Ref(SequenceBase): # R612 - """ - <data-ref> = <part-ref> [ % <part-ref> ]... - """ - subclass_names = ['Part_Ref'] - use_names = [] - def match(string): return SequenceBase.match(r'%', Part_Ref, string) - match = staticmethod(match) - -class Part_Ref(CallBase): # R613 - """ - <part-ref> = <part-name> [ ( <section-subscript-list> ) ] - """ - subclass_names = ['Part_Name'] - use_names = ['Section_Subscript_List'] - def match(string): - return CallBase.match(Part_Name, Section_Subscript_List, string, require_rhs=True) - match = staticmethod(match) - -class Structure_Component(Base): # R614 - """ - <structure-component> = <data-ref> - """ - subclass_names = ['Data_Ref'] - -class Type_Param_Inquiry(BinaryOpBase): # R615 - """ - <type-param-inquiry> = <designator> % <type-param-name> - """ - subclass_names = [] - use_names = ['Designator','Type_Param_Name'] - def match(string): - return BinaryOpBase.match(\ - Designator, pattern.percent_op.named(), Type_Param_Name, string) - match = staticmethod(match) - -class Array_Element(Base): # R616 - """ - <array-element> = <data-ref> - """ - subclass_names = ['Data_Ref'] - -class Array_Section(CallBase): # R617 - """ - <array-section> = <data-ref> [ ( <substring-range> ) ] - """ - subclass_names = ['Data_Ref'] - use_names = ['Substring_Range'] - def match(string): return CallBase.match(Data_Ref, Substring_Range, string, require_rhs=True) - match = staticmethod(match) - -class Subscript(Base): # R618 - """ - <subscript> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Section_Subscript(Base): # R619 - """ - <section-subscript> = <subscript> - | <subscript-triplet> - | <vector-subscript> - """ - subclass_names = ['Subscript_Triplet', 'Vector_Subscript', 'Subscript'] - -class Subscript_Triplet(Base): # R620 - """ - <subscript-triplet> = [ <subscript> ] : [ <subscript> ] [ : <stride> ] - """ - subclass_names = [] - use_names = ['Subscript','Stride'] - def match(string): - line, repmap = string_replace_map(string) - t = line.split(':') - if len(t)<=1 or len(t)>3: return - lhs_obj,rhs_obj, stride_obj = None, None, None - if len(t)==2: - lhs,rhs = t[0].rstrip(),t[1].lstrip() - else: - lhs,rhs,stride = t[0].rstrip(),t[1].strip(),t[2].lstrip() - if stride: - stride_obj = Stride(repmap(stride)) - if lhs: - lhs_obj = Subscript(repmap(lhs)) - if rhs: - rhs_obj = Subscript(repmap(rhs)) - return lhs_obj, rhs_obj, stride_obj - match = staticmethod(match) - def tostr(self): - s = '' - if self.items[0] is not None: - s += str(self.items[0]) + ' :' - else: - s += ':' - if self.items[1] is not None: - s += ' ' + str(self.items[1]) - if self.items[2] is not None: - s += ' : ' + str(self.items[2]) - return s - -class Stride(Base): # R621 - """ - <stride> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Vector_Subscript(Base): # R622 - """ - <vector-subscript> = <int-expr> - """ - subclass_names = ['Int_Expr'] - -class Allocate_Stmt(StmtBase): # R623 - """ - <allocate-stmt> = ALLOCATE ( [ <type-spec> :: ] <allocation-list> [ , <alloc-opt-list> ] ) - """ - subclass_names = [] - use_names = ['Type_Spec', 'Allocation_List', 'Alloc_Opt_List'] - -class Alloc_Opt(KeywordValueBase):# R624 - """ - <alloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - | SOURCE = <source-expr> - """ - subclass_names = [] - use_names = ['Stat_Variable', 'Errmsg_Variable', 'Source_Expr'] - def match(string): - for (k,v) in [('STAT', Stat_Variable), - ('ERRMSG', Errmsg_Variable), - ('SOURCE', Source_Expr) - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return - match = staticmethod(match) - - -class Stat_Variable(Base):# R625 - """ - <stat-variable> = <scalar-int-variable> - """ - subclass_names = ['Scalar_Int_Variable'] - -class Errmsg_Variable(Base):# R626 - """ - <errmsg-variable> = <scalar-default-char-variable> - """ - subclass_names = ['Scalar_Default_Char_Variable'] - -class Source_Expr(Base):# R627 - """ - <source-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Allocation(CallBase):# R628 - """ - <allocation> = <allocate-object> [ ( <allocate-shape-spec-list> ) ] - | <variable-name> - """ - subclass_names = ['Variable_Name', 'Allocate_Object'] - use_names = ['Allocate_Shape_Spec_List'] - def match(string): - return CallBase.match(Allocate_Object, Allocate_Shape_Spec_List, string, require_rhs = True) - match = staticmethod(match) - -class Allocate_Object(Base): # R629 - """ - <allocate-object> = <variable-name> - | <structure-component> - """ - subclass_names = ['Variable_Name', 'Structure_Component'] - -class Allocate_Shape_Spec(SeparatorBase): # R630 - """ - <allocate-shape-spec> = [ <lower-bound-expr> : ] <upper-bound-expr> - """ - subclass_names = [] - use_names = ['Lower_Bound_Expr', 'Upper_Bound_Expr'] - def match(string): - line, repmap = string_replace_map(string) - if ':' not in line: return None, Upper_Bound_Expr(string) - lower,upper = line.split(':',1) - lower = lower.rstrip() - upper = upper.lstrip() - if not upper: return - if not lower: return - return Lower_Bound_Expr(repmap(lower)), Upper_Bound_Expr(repmap(upper)) - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return str(self.items[1]) - return SeparatorBase.tostr(self) - - -class Lower_Bound_Expr(Base): # R631 - """ - <lower-bound-expr> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Upper_Bound_Expr(Base): # R632 - """ - <upper-bound-expr> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Nullify_Stmt(StmtBase, CALLBase): # R633 - """ - <nullify-stmt> = NULLIFY ( <pointer-object-list> ) - """ - subclass_names = [] - use_names = ['Pointer_Object_List'] - def match(string): return CALLBase.match('NULLIFY', Pointer_Object_List, string, require_rhs=True) - match = staticmethod(match) - -class Pointer_Object(Base): # R634 - """ - <pointer-object> = <variable-name> - | <structure-component> - | <proc-pointer-name> - """ - subclass_names = ['Variable_Name', 'Structure_Component', 'Proc_Pointer_Name'] - -class Deallocate_Stmt(StmtBase): # R635 - """ - <deallocate-stmt> = DEALLOCATE ( <allocate-object-list> [ , <dealloc-opt-list> ] ) - """ - subclass_names = [] - use_names = ['Allocate_Object_List', 'Dealloc_Opt_List'] - -class Dealloc_Opt(KeywordValueBase): # R636 - """ - <dealloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - """ - subclass_names = [] - use_names = ['Stat_Variable', 'Errmsg_Variable'] - def match(string): - for (k,v) in [('STAT', Stat_Variable), - ('ERRMSG', Errmsg_Variable), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return - match = staticmethod(match) - -class Scalar_Char_Initialization_Expr(Base): - subclass_names = ['Char_Initialization_Expr'] - -############################################################################### -############################### SECTION 7 #################################### -############################################################################### - -class Primary(Base): # R701 - """ - <primary> = <constant> - | <designator> - | <array-constructor> - | <structure-constructor> - | <function-reference> - | <type-param-inquiry> - | <type-param-name> - | ( <expr> ) - """ - subclass_names = ['Constant', 'Parenthesis', 'Designator','Array_Constructor', - 'Structure_Constructor', - 'Function_Reference', 'Type_Param_Inquiry', 'Type_Param_Name', - ] - -class Parenthesis(BracketBase): # R701.h - """ - <parenthesis> = ( <expr> ) - """ - subclass_names = [] - use_names = ['Expr'] - def match(string): return BracketBase.match('()', Expr, string) - match = staticmethod(match) - -class Level_1_Expr(UnaryOpBase): # R702 - """ - <level-1-expr> = [ <defined-unary-op> ] <primary> - <defined-unary-op> = . <letter> [ <letter> ]... . - """ - subclass_names = ['Primary'] - use_names = [] - def match(string): - if pattern.non_defined_binary_op.match(string): - raise NoMatchError,'%s: %r' % (Level_1_Expr.__name__, string) - return UnaryOpBase.match(\ - pattern.defined_unary_op.named(),Primary,string) - match = staticmethod(match) - -class Defined_Unary_Op(STRINGBase): # R703 - """ - <defined-unary-op> = . <letter> [ <letter> ]... . - """ - subclass_names = ['Defined_Op'] - - -class Defined_Op(STRINGBase): # R703, 723 - """ - <defined-op> = . <letter> [ <letter> ]... . - """ - subclass_names = [] - def match(string): - if pattern.non_defined_binary_op.match(string): - raise NoMatchError,'%s: %r' % (Defined_Unary_Op.__name__, string) - return STRINGBase.match(pattern.abs_defined_op, string) - match = staticmethod(match) - -class Mult_Operand(BinaryOpBase): # R704 - """ - <mult-operand> = <level-1-expr> [ <power-op> <mult-operand> ] - <power-op> = ** - """ - subclass_names = ['Level_1_Expr'] - use_names = ['Mult_Operand'] - def match(string): - return BinaryOpBase.match(\ - Level_1_Expr,pattern.power_op.named(),Mult_Operand,string,right=False) - match = staticmethod(match) - -class Add_Operand(BinaryOpBase): # R705 - """ - <add-operand> = [ <add-operand> <mult-op> ] <mult-operand> - <mult-op> = * - | / - """ - subclass_names = ['Mult_Operand'] - use_names = ['Add_Operand','Mult_Operand'] - def match(string): - return BinaryOpBase.match(Add_Operand,pattern.mult_op.named(),Mult_Operand,string) - match = staticmethod(match) - -class Level_2_Expr(BinaryOpBase): # R706 - """ - <level-2-expr> = [ [ <level-2-expr> ] <add-op> ] <add-operand> - <level-2-expr> = [ <level-2-expr> <add-op> ] <add-operand> - | <level-2-unary-expr> - <add-op> = + - | - - """ - subclass_names = ['Level_2_Unary_Expr'] - use_names = ['Level_2_Expr'] - def match(string): - return BinaryOpBase.match(\ - Level_2_Expr,pattern.add_op.named(),Add_Operand,string) - match = staticmethod(match) - -class Level_2_Unary_Expr(UnaryOpBase): # R706.c - """ - <level-2-unary-expr> = [ <add-op> ] <add-operand> - """ - subclass_names = ['Add_Operand'] - use_names = [] - def match(string): return UnaryOpBase.match(pattern.add_op.named(),Add_Operand,string) - match = staticmethod(match) - -#R707: <power-op> = ** -#R708: <mult-op> = * | / -#R709: <add-op> = + | - - -class Level_3_Expr(BinaryOpBase): # R710 - """ - <level-3-expr> = [ <level-3-expr> <concat-op> ] <level-2-expr> - <concat-op> = // - """ - subclass_names = ['Level_2_Expr'] - use_names =['Level_3_Expr'] - def match(string): - return BinaryOpBase.match(\ - Level_3_Expr,pattern.concat_op.named(),Level_2_Expr,string) - match = staticmethod(match) - -#R711: <concat-op> = // - -class Level_4_Expr(BinaryOpBase): # R712 - """ - <level-4-expr> = [ <level-3-expr> <rel-op> ] <level-3-expr> - <rel-op> = .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | == | /= | < | <= | > | >= - """ - subclass_names = ['Level_3_Expr'] - use_names = [] - def match(string): - return BinaryOpBase.match(\ - Level_3_Expr,pattern.rel_op.named(),Level_3_Expr,string) - match = staticmethod(match) - -#R713: <rel-op> = .EQ. | .NE. | .LT. | .LE. | .GT. | .GE. | == | /= | < | <= | > | >= - -class And_Operand(UnaryOpBase): # R714 - """ - <and-operand> = [ <not-op> ] <level-4-expr> - <not-op> = .NOT. - """ - subclass_names = ['Level_4_Expr'] - use_names = [] - def match(string): - return UnaryOpBase.match(\ - pattern.not_op.named(),Level_4_Expr,string) - match = staticmethod(match) - -class Or_Operand(BinaryOpBase): # R715 - """ - <or-operand> = [ <or-operand> <and-op> ] <and-operand> - <and-op> = .AND. - """ - subclass_names = ['And_Operand'] - use_names = ['Or_Operand','And_Operand'] - def match(string): - return BinaryOpBase.match(\ - Or_Operand,pattern.and_op.named(),And_Operand,string) - match = staticmethod(match) - -class Equiv_Operand(BinaryOpBase): # R716 - """ - <equiv-operand> = [ <equiv-operand> <or-op> ] <or-operand> - <or-op> = .OR. - """ - subclass_names = ['Or_Operand'] - use_names = ['Equiv_Operand'] - def match(string): - return BinaryOpBase.match(\ - Equiv_Operand,pattern.or_op.named(),Or_Operand,string) - match = staticmethod(match) - - -class Level_5_Expr(BinaryOpBase): # R717 - """ - <level-5-expr> = [ <level-5-expr> <equiv-op> ] <equiv-operand> - <equiv-op> = .EQV. - | .NEQV. - """ - subclass_names = ['Equiv_Operand'] - use_names = ['Level_5_Expr'] - def match(string): - return BinaryOpBase.match(\ - Level_5_Expr,pattern.equiv_op.named(),Equiv_Operand,string) - match = staticmethod(match) - -#R718: <not-op> = .NOT. -#R719: <and-op> = .AND. -#R720: <or-op> = .OR. -#R721: <equiv-op> = .EQV. | .NEQV. - -class Expr(BinaryOpBase): # R722 - """ - <expr> = [ <expr> <defined-binary-op> ] <level-5-expr> - <defined-binary-op> = . <letter> [ <letter> ]... . - TODO: defined_binary_op must not be intrinsic_binary_op!! - """ - subclass_names = ['Level_5_Expr'] - use_names = ['Expr'] - def match(string): - return BinaryOpBase.match(Expr, pattern.defined_binary_op.named(), Level_5_Expr, - string) - match = staticmethod(match) - -class Defined_Unary_Op(STRINGBase): # R723 - """ - <defined-unary-op> = . <letter> [ <letter> ]... . - """ - subclass_names = ['Defined_Op'] - -class Logical_Expr(Base): # R724 - """ - <logical-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Char_Expr(Base): # R725 - """ - <char-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Default_Char_Expr(Base): # R726 - """ - <default-char-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Int_Expr(Base): # R727 - """ - <int-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Numeric_Expr(Base): # R728 - """ - <numeric-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Specification_Expr(Base): # R729 - """ - <specification-expr> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Initialization_Expr(Base): # R730 - """ - <initialization-expr> = <expr> - """ - subclass_names = ['Expr'] - -class Char_Initialization_Expr(Base): # R731 - """ - <char-initialization-expr> = <char-expr> - """ - subclass_names = ['Char_Expr'] - -class Int_Initialization_Expr(Base): # R732 - """ - <int-initialization-expr> = <int-expr> - """ - subclass_names = ['Int_Expr'] - -class Logical_Initialization_Expr(Base): # R733 - """ - <logical-initialization-expr> = <logical-expr> - """ - subclass_names = ['Logical_Expr'] - -class Assignment_Stmt(StmtBase, BinaryOpBase): # R734 - """ - <assignment-stmt> = <variable> = <expr> - """ - subclass_names = [] - use_names = ['Variable', 'Expr'] - def match(string): - return BinaryOpBase.match(Variable, '=', Expr, string, right=False) - match = staticmethod(match) - -class Pointer_Assignment_Stmt(StmtBase): # R735 - """ - <pointer-assignment-stmt> = <data-pointer-object> [ ( <bounds-spec-list> ) ] => <data-target> - | <data-pointer-object> ( <bounds-remapping-list> ) => <data-target> - | <proc-pointer-object> => <proc-target> - """ - subclass_names = [] - use_names = ['Data_Pointer_Object', 'Bounds_Spec_List', 'Data_Target', 'Bounds_Remapping_List', - 'Proc_Pointer_Object', 'Proc_Target'] - -class Data_Pointer_Object(BinaryOpBase): # R736 - """ - <data-pointer-object> = <variable-name> - | <variable> % <data-pointer-component-name> - """ - subclass_names = ['Variable_Name'] - use_names = ['Variable', 'Data_Pointer_Component_Name'] - def match(string): - return BinaryOpBase.match(Variable, r'%', Data_Pointer_Component_Name, string) - match = staticmethod(match) - -class Bounds_Spec(SeparatorBase): # R737 - """ - <bounds-spec> = <lower-bound-expr> : - """ - subclass_names = [] - use_names = ['Lower_Bound_Expr'] - def match(string): return SeparatorBase.match(Lower_Bound_Expr, None, string, require_lhs=True) - match = staticmethod(match) - -class Bounds_Remapping(SeparatorBase): # R738 - """ - <bounds-remapping> = <lower-bound-expr> : <upper-bound-expr> - """ - subclass_names = [] - use_classes = ['Lower_Bound_Expr', 'Upper_Bound_Expr'] - def match(string): return SeparatorBase.match(Lower_Bound_Expr, Upper_Bound_Expr, string, require_lhs=True, require_rhs=True) - match = staticmethod(match) - -class Data_Target(Base): # R739 - """ - <data-target> = <variable> - | <expr> - """ - subclass_names = ['Variable','Expr'] - -class Proc_Pointer_Object(Base): # R740 - """ - <proc-pointer-object> = <proc-pointer-name> - | <proc-component-ref> - """ - subclass_names = ['Proc_Pointer_Name', 'Proc_Component_Ref'] - -class Proc_Component_Ref(BinaryOpBase): # R741 - """ - <proc-component-ref> = <variable> % <procedure-component-name> - """ - subclass_names = [] - use_names = ['Variable','Procedure_Component_Name'] - def match(string): - return BinaryOpBase.match(Variable, r'%', Procedure_Component_Name, string) - match = staticmethod(match) - -class Proc_Target(Base): # R742 - """ - <proc-target> = <expr> - | <procedure-name> - | <proc-component-ref> - """ - subclass_names = ['Proc_Component_Ref', 'Procedure_Name', 'Expr'] - - -class Where_Stmt(StmtBase): # R743 - """ - <where-stmt> = WHERE ( <mask-expr> ) <where-assignment-stmt> - """ - subclass_names = [] - use_names = ['Mask_Expr', 'Where_Assignment_Stmt'] - def match(string): - if string[:5].upper()!='WHERE': return - line, repmap = string_replace_map(string[5:].lstrip()) - if not line.startswith('('): return - i = line.find(')') - if i==-1: return - stmt = repmap(line[i+1:].lstrip()) - if not stmt: return - expr = repmap(line[1:i].strip()) - if not expr: return - return Mask_Expr(expr), Where_Assignment_Stmt(stmt) - match = staticmethod(match) - def tostr(self): return 'WHERE (%s) %s' % tuple(self.items) - - -class Where_Construct(Base): # R744 - """ - <where-construct> = <where-construct-stmt> - [ <where-body-construct> ]... - [ <masked-elsewhere-stmt> - [ <where-body-construct> ]... - ]... - [ <elsewhere-stmt> - [ <where-body-construct> ]... ] - <end-where-stmt> - """ - subclass_names = [] - use_names = ['Where_Construct_Stmt', 'Where_Body_Construct', - 'Elsewhere_Stmt', 'End_Where_Stmt' - ] - -class Where_Construct_Stmt(StmtBase): # R745 - """ - <where-construct-stmt> = [ <where-construct-name> : ] WHERE ( <mask-expr> ) - """ - subclass_names = [] - use_names = ['Where_Construct_Name', 'Mask_Expr'] - - def match(string): - if string[:5].upper()!='WHERE': return - line = string[5:].lstrip() - if not line: return - if line[0]+line[-1] != '()': return - line = line[1:-1].strip() - if not line: return - return Mask_Expr(line), - match = staticmethod(match) - def tostr(self): return 'WHERE (%s)' % tuple(self.items) - -class Where_Body_Construct(Base): # R746 - """ - <where-body-construct> = <where-assignment-stmt> - | <where-stmt> - | <where-construct> - """ - subclass_names = ['Where_Assignment_Stmt', 'Where_Stmt', 'Where_Construct'] - -class Where_Assignment_Stmt(Base): # R747 - """ - <where-assignment-stmt> = <assignment-stmt> - """ - subclass_names = ['Assignment_Stmt'] - -class Mask_Expr(Base): # R748 - """ - <mask-expr> = <logical-expr> - """ - subclass_names = ['Logical_Expr'] - -class Masked_Elsewhere_Stmt(StmtBase): # R749 - """ - <masked-elsewhere-stmt> = ELSEWHERE ( <mask-expr> ) [ <where-construct-name> ] - """ - subclass_names = [] - use_names = ['Mask_Expr', 'Where_Construct_Name'] - def match(string): - if string[:9].upper()!='ELSEWHERE': return - line = string[9:].lstrip() - if not line.startswith('('): return - i = line.rfind(')') - if i==-1: return - expr = line[1:i].strip() - if not expr: return - line = line[i+1:].rstrip() - if line: - return Mask_Expr(expr), Where_Construct_Name(line) - return Mask_Expr(expr), None - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return 'ELSEWHERE(%s)' % (self.items[0]) - return 'ELSEWHERE(%s) %s' % self.items - -class Elsewhere_Stmt(StmtBase, WORDClsBase): # R750 - """ - <elsewhere-stmt> = ELSEWHERE [ <where-construct-name> ] - """ - subclass_names = [] - use_names = ['Where_Construct_Name'] - def match(string): return WORDClsBase.match('ELSEWHERE', Where_Construct_Name, string) - match = staticmethod(match) - -class End_Where_Stmt(EndStmtBase): # R751 - """ - <end-where-stmt> = END WHERE [ <where-construct-name> ] - """ - subclass_names = [] - use_names = ['Where_Construct_Name'] - def match(string): return EndStmtBase.match('WHERE',Where_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - - -class Forall_Construct(Base): # R752 - """ - <forall-construct> = <forall-construct-stmt> - [ <forall-body-construct> ]... - <end-forall-stmt> - """ - subclass_names = [] - use_names = ['Forall_Construct_Stmt', 'Forall_Body_Construct', 'End_Forall_Stmt'] - -class Forall_Construct_Stmt(StmtBase, WORDClsBase): # R753 - """ - <forall-construct-stmt> = [ <forall-construct-name> : ] FORALL <forall-header> - """ - subclass_names = [] - use_names = ['Forall_Construct_Name', 'Forall_Header'] - def match(string): return WORDClsBase.match('FORALL', Forall_Header, string, require_cls = True) - match = staticmethod(match) - -class Forall_Header(Base): # R754 - """ - <forall-header> = ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) - """ - subclass_names = [] - use_names = ['Forall_Triplet_Spec_List', 'Scalar_Mask_Expr'] - -class Forall_Triplet_Spec(Base): # R755 - """ - <forall-triplet-spec> = <index-name> = <subscript> : <subscript> [ : <stride> ] - """ - subclass_names = [] - use_names = ['Index_Name', 'Subscript', 'Stride'] - -class Forall_Body_Construct(Base): # R756 - """ - <forall-body-construct> = <forall-assignment-stmt> - | <where-stmt> - | <where-construct> - | <forall-construct> - | <forall-stmt> - """ - subclass_names = ['Forall_Assignment_Stmt', 'Where_Stmt', 'Where_Construct', - 'Forall_Construct', 'Forall_Stmt'] - -class Forall_Assignment_Stmt(Base): # R757 - """ - <forall-assignment-stmt> = <assignment-stmt> - | <pointer-assignment-stmt> - """ - subclass_names = ['Assignment_Stmt', 'Pointer_Assignment_Stmt'] - -class End_Forall_Stmt(EndStmtBase): # R758 - """ - <end-forall-stmt> = END FORALL [ <forall-construct-name> ] - """ - subclass_names = [] - use_names = ['Forall_Construct_Name'] - def match(string): return EndStmtBase.match('FORALL',Forall_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Forall_Stmt(StmtBase): # R759 - """ - <forall-stmt> = FORALL <forall-header> <forall-assignment-stmt> - """ - subclass_names = [] - use_names = ['Forall_Header', 'Forall_Assignment_Stmt'] - def match(string): - if string[:6].upper()!='FORALL': return - line, repmap = string_replace_map(string[6:].lstrip()) - if not line.startswith(')'): return - i = line.find(')') - if i==-1: return - header = repmap(line[1:i].strip()) - if not header: return - line = repmap(line[i+1:].lstrip()) - if not line: return - return Forall_Header(header), Forall_Assignment_Stmt(line) - match = staticmethod(match) - def tostr(self): return 'FORALL %s %s' % self.items - -############################################################################### -############################### SECTION 8 #################################### -############################################################################### - -class Block(BlockBase): # R801 - """ - block = [ <execution-part-construct> ]... - """ - subclass_names = [] - use_names = ['Execution_Part_Construct'] - def match(string): return BlockBase.match(None, [Execution_Part_Construct], None, string) - match = staticmethod(match) - -class If_Construct(BlockBase): # R802 - """ - <if-construct> = <if-then-stmt> - <block> - [ <else-if-stmt> - <block> - ]... - [ <else-stmt> - <block> - ] - <end-if-stmt> - """ - subclass_names = [] - use_names = ['If_Then_Stmt', 'Block', 'Else_If_Stmt', 'Else_Stmt', 'End_If_Stmt'] - - def match(reader): - content = [] - try: - obj = If_Then_Stmt(reader) - except NoMatchError: - obj = None - if obj is None: return - content.append(obj) - obj = Block(reader) - if obj is None: return # todo: restore reader - content.append(obj) - while 1: - try: - obj = Else_If_Stmt(reader) - except NoMatchError: - obj = None - if obj is not None: - content.append(obj) - obj = Block(reader) - if obj is None: return # todo: restore reader - content.append(obj) - continue - try: - obj = Else_Stmt(reader) - except NoMatchError: - obj = None - if obj is not None: - content.append(obj) - obj = Block(reader) - if obj is None: return # todo: restore reader - content.append(obj) - break - try: - obj = End_If_Stmt(reader) - except NoMatchError: - obj = None - if obj is None: return # todo: restore reader - content.append(obj) - return content, - match = staticmethod(match) - - def tofortran(self, tab='', isfix=None): - l = [] - start = self.content[0] - end = self.content[-1] - l.append(start.tofortran(tab=tab,isfix=isfix)) - for item in self.content[1:-1]: - if isinstance(item, (Else_If_Stmt, Else_Stmt)): - l.append(item.tofortran(tab=tab,isfix=isfix)) - else: - l.append(item.tofortran(tab=tab+' ',isfix=isfix)) - l.append(end.tofortran(tab=tab,isfix=isfix)) - return '\n'.join(l) - - -class If_Then_Stmt(StmtBase): # R803 - """ - <if-then-stmt> = [ <if-construct-name> : ] IF ( <scalar-logical-expr> ) THEN - """ - subclass_names = [] - use_names = ['If_Construct_Name', 'Scalar_Logical_Expr'] - def match(string): - if string[:2].upper()!='IF': return - if string[-4:].upper()!='THEN': return - line = string[2:-4].strip() - if not line: return - if line[0]+line[-1]!='()': return - return Scalar_Logical_Expr(line[1:-1].strip()), - match = staticmethod(match) - def tostr(self): return 'IF (%s) THEN' % self.items - -class Else_If_Stmt(StmtBase): # R804 - """ - <else-if-stmt> = ELSE IF ( <scalar-logical-expr> ) THEN [ <if-construct-name> ] - """ - subclass_names = [] - use_names = ['Scalar_Logical_Expr', 'If_Construct_Name'] - - def match(string): - if string[:4].upper()!='ELSE': return - line = string[4:].lstrip() - if line[:2].upper()!='IF': return - line = line[2:].lstrip() - if not line.startswith('('): return - i = line.rfind(')') - if i==-1: return - expr = line[1:i].strip() - line = line[i+1:].lstrip() - if line[:4].upper()!='THEN': return - line = line[4:].lstrip() - if line: return Scalar_Logical_Expr(expr), If_Construct_Name(line) - return Scalar_Logical_Expr(expr), None - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: - return 'ELSE IF (%s) THEN' % (self.items[0]) - return 'ELSE IF (%s) THEN %s' % self.items - -class Else_Stmt(StmtBase): # R805 - """ - <else-stmt> = ELSE [ <if-construct-name> ] - """ - subclass_names = [] - use_names = ['If_Construct_Name'] - def match(string): - if string[:4].upper()!='ELSE': return - line = string[4:].lstrip() - if line: return If_Construct_Name(line), - return None, - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: - return 'ELSE' - return 'ELSE %s' % self.items - -class End_If_Stmt(EndStmtBase): # R806 - """ - <end-if-stmt> = END IF [ <if-construct-name> ] - """ - subclass_names = [] - use_names = ['If_Construct_Name'] - def match(string): return EndStmtBase.match('IF',If_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class If_Stmt(StmtBase): # R807 - """ - <if-stmt> = IF ( <scalar-logical-expr> ) <action-stmt> - """ - subclass_names = [] - use_names = ['Scalar_Logical_Expr', 'Action_Stmt_C802'] - def match(string): - if string[:2].upper() != 'IF': return - line, repmap = string_replace_map(string) - line = line[2:].lstrip() - if not line.startswith('('): return - i = line.find(')') - if i==-1: return - expr = repmap(line[1:i].strip()) - stmt = repmap(line[i+1:].lstrip()) - return Scalar_Logical_Expr(expr), Action_Stmt_C802(stmt) - match = staticmethod(match) - def tostr(self): return 'IF (%s) %s' % self.items - -class Case_Construct(Base): # R808 - """ - <case-construct> = <select-case-stmt> - [ <case-stmt> - <block> - ].. - <end-select-stmt> - """ - subclass_names = [] - use_names = ['Select_Case_Stmt', 'Case_Stmt', 'End_Select_Stmt'] - -class Select_Case_Stmt(StmtBase, CALLBase): # R809 - """ - <select-case-stmt> = [ <case-construct-name> : ] SELECT CASE ( <case-expr> ) - """ - subclass_names = [] - use_names = ['Case_Construct_Name', 'Case_Expr'] - def match(string): return CALLBase.match(pattter.abs_select_case, Case_Expr, string) - match = staticmethod(match) - -class Case_Stmt(StmtBase): # R810 - """ - <case-stmt> = CASE <case-selector> [ <case-construct-name> ] - """ - subclass_names = [] - use_names = ['Case_Selector', 'Case_Construct_Name'] - -class End_Select_Stmt(EndStmtBase): # R811 - """ - <end-select-stmt> = END SELECT [ <case-construct-name> ] - """ - subclass_names = [] - use_names = ['Case_Construct_Name'] - def match(string): return EndStmtBase.match('SELECT',Case_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Case_Expr(Base): # R812 - """ - <case-expr> = <scalar-int-expr> - | <scalar-char-expr> - | <scalar-logical-expr> - """ - subclass_names = [] - subclass_names = ['Scalar_Int_Expr', 'Scalar_Char_Expr', 'Scalar_Logical_Expr'] - -class Case_Selector(Base): # R813 - """ - <case-selector> = ( <case-value-range-list> ) - | DEFAULT - """ - subclass_names = [] - use_names = ['Case_Value_Range_List'] - -class Case_Value_Range(SeparatorBase): # R814 - """ - <case-value-range> = <case-value> - | <case-value> : - | : <case-value> - | <case-value> : <case-value> - """ - subclass_names = ['Case_Value'] - def match(string): return SeparatorBase.match(Case_Value, Case_Value, string) - match = staticmethod(match) - -class Case_Value(Base): # R815 - """ - <case-value> = <scalar-int-initialization-expr> - | <scalar-char-initialization-expr> - | <scalar-logical-initialization-expr> - """ - subclass_names = ['Scalar_Int_Initialization_Expr', 'Scalar_Char_Initialization_Expr', 'Scalar_Logical_Initialization_Expr'] - - -class Associate_Construct(Base): # R816 - """ - <associate-construct> = <associate-stmt> - <block> - <end-associate-stmt> - """ - subclass_names = [] - use_names = ['Associate_Stmt', 'Block', 'End_Associate_Stmt'] - -class Associate_Stmt(StmtBase, CALLBase): # R817 - """ - <associate-stmt> = [ <associate-construct-name> : ] ASSOCIATE ( <association-list> ) - """ - subclass_names = [] - use_names = ['Associate_Construct_Name', 'Association_List'] - def match(string): return CALLBase.match('ASSOCIATE', Association_List, string) - match = staticmethod(match) - -class Association(BinaryOpBase): # R818 - """ - <association> = <associate-name> => <selector> - """ - subclass_names = [] - use_names = ['Associate_Name', 'Selector'] - def match(string): return BinaryOpBase.match(Assiciate_Name, '=>', Selector, string) - match = staticmethod(match) - -class Selector(Base): # R819 - """ - <selector> = <expr> - | <variable> - """ - subclass_names = ['Expr', 'Variable'] - -class End_Associate_Stmt(EndStmtBase): # R820 - """ - <end-associate-stmt> = END ASSOCIATE [ <associate-construct-name> ] - """ - subclass_names = [] - use_names = ['Associate_Construct_Name'] - def match(string): return EndStmtBase.match('ASSOCIATE',Associate_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Select_Type_Construct(Base): # R821 - """ - <select-type-construct> = <select-type-stmt> - [ <type-guard-stmt> - <block> - ]... - <end-select-type-stmt> - """ - subclass_names = [] - use_names = ['Select_Type_Stmt', 'Type_Guard_Stmt', 'Block', 'End_Select_Type_Stmt'] - -class Select_Type_Stmt(StmtBase): # R822 - """ - <select-type-stmt> = [ <select-construct-name> : ] SELECT TYPE ( [ <associate-name> => ] <selector> ) - """ - subclass_names = [] - use_names = ['Select_Construct_Name', 'Associate_Name', 'Selector'] - -class Type_Guard_Stmt(StmtBase): # R823 - """ - <type-guard-stmt> = TYPE IS ( <type-spec> ) [ <select-construct-name> ] - | CLASS IS ( <type-spec> ) [ <select-construct-name> ] - | CLASS DEFAULT [ <select-construct-name> ] - """ - subclass_names = [] - use_names = ['Type_Spec', 'Select_Construct_Name'] - def match(string): - if string[:4].upper()=='TYPE': - line = string[4:].lstrip() - if not line[:2].upper()=='IS': return - line = line[2:].lstrip() - kind = 'TYPE IS' - elif string[:5].upper()=='CLASS': - line = string[5:].lstrip() - if line[:2].upper()=='IS': - line = line[2:].lstrip() - kind = 'CLASS IS' - elif line[:7].upper()=='DEFAULT': - line = line[7:].lstrip() - if line: - if isalnum(line[0]): return - return 'CLASS DEFAULT', None, Select_Construct_Name(line) - return 'CLASS DEFAULT', None, None - else: - return - else: - return - if not line.startswith('('): return - i = line.rfind(')') - if i==-1: return - l = line[1:i].strip() - if not l: return - line = line[i+1:].lstrip() - if line: - return kind, Type_Spec(l), Select_Construct_Name(line) - return kind, Type_Spec(l), None - match = staticmethod(match) - def tostr(self): - s = str(self.items[0]) - if self.items[1] is not None: - s += ' (%s)' % (self.items[0]) - if self.items[2] is not None: - s += ' %s' % (self.items[2]) - return s - -class End_Select_Type_Stmt(EndStmtBase): # R824 - """ - <end-select-type-stmt> = END SELECT [ <select-construct-name> ] - """ - subclass_names = [] - use_names = ['Select_Construct_Name'] - def match(string): return EndStmtBase.match('SELECT',Select_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Do_Construct(Base): # R825 - """ - <do-construct> = <block-do-construct> - | <nonblock-do-construct> - """ - subclass_names = ['Block_Do_Construct', 'Nonblock_Do_Construct'] - -class Block_Do_Construct(BlockBase): # R826 - """ - <block-do-construct> = <do-stmt> - <do-block> - <end-do> - """ - subclass_names = [] - use_names = ['Do_Stmt', 'Do_Block', 'End_Do'] - def match(reader): - assert isinstance(reader,FortranReaderBase),`reader` - content = [] - try: - obj = Do_Stmt(reader) - except NoMatchError: - obj = None - if obj is None: return - content.append(obj) - if isinstance(obj, Label_Do_Stmt): - label = str(obj.dolabel) - while 1: - try: - obj = Execution_Part_Construct(reader) - except NoMatchError: - obj = None - if obj is None: break - content.append(obj) - if isinstance(obj, Continue_Stmt) and obj.item.label==label: - return content, - return - raise RuntimeError,'Expected continue stmt with specified label' - else: - obj = End_Do(reader) - content.append(obj) - raise NotImplementedError - return content, - match = staticmethod(match) - - def tofortran(self, tab='', isfix=None): - if not isinstance(self.content[0], Label_Do_Stmt): - return BlockBase.tofortran(tab, isfix) - l = [] - start = self.content[0] - end = self.content[-1] - extra_tab = ' ' - l.append(start.tofortran(tab=tab,isfix=isfix)) - for item in self.content[1:-1]: - l.append(item.tofortran(tab=tab+extra_tab,isfix=isfix)) - if len(self.content)>1: - l.append(end.tofortran(tab=tab,isfix=isfix)) - return '\n'.join(l) - -class Do_Stmt(Base): # R827 - """ - <do-stmt> = <label-do-stmt> - | <nonlabel-do-stmt> - """ - subclass_names = ['Label_Do_Stmt', 'Nonlabel_Do_Stmt'] - -class Label_Do_Stmt(StmtBase): # R828 - """ - <label-do-stmt> = [ <do-construct-name> : ] DO <label> [ <loop-control> ] - """ - subclass_names = [] - use_names = ['Do_Construct_Name', 'Label', 'Loop_Control'] - def match(string): - if string[:2].upper()!='DO': return - line = string[2:].lstrip() - m = pattern.label.match(line) - if m is None: return - label = m.group() - line = line[m.end():].lstrip() - if line: return Label(label), Loop_Control(line) - return Label(label), None - match = staticmethod(match) - def tostr(self): - if self.itens[1] is None: return 'DO %s' % (self.items[0]) - return 'DO %s %s' % self.items - -class Nonlabel_Do_Stmt(StmtBase, WORDClsBase): # R829 - """ - <nonlabel-do-stmt> = [ <do-construct-name> : ] DO [ <loop-control> ] - """ - subclass_names = [] - use_names = ['Do_Construct_Name', 'Loop_Control'] - def match(string): return WORDClsBase.match('DO', Loop_Control, string) - match = staticmethod(match) - -class Loop_Control(Base): # R830 - """ - <loop-control> = [ , ] <do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] - | [ , ] WHILE ( <scalar-logical-expr> ) - """ - subclass_names = [] - use_names = ['Do_Variable', 'Scalar_Int_Expr', 'Scalar_Logical_Expr'] - def match(string): - if string.startswith(','): - line, repmap = string_replace_map(string[1:].lstrip()) - else: - line, repmap = string_replace_map(string) - if line[:5].upper()=='WHILE' and line[5:].lstrip().startswith('('): - l = line[5:].lstrip() - i = l.find(')') - if i!=-1 and i==len(l)-1: - return Scalar_Logical_Expr(repmap(l[1:i].strip())), - if line.count('=')!=1: return - var,rhs = line.split('=') - rhs = [s.strip() for s in rhs.lstrip().split(',')] - if not 2<=len(rhs)<=3: return - return Variable(repmap(var.rstrip())),map(Scalar_Int_Expr, map(repmap,rhs)) - match = staticmethod(match) - def tostr(self): - if len(self.items)==1: return ', WHILE (%s)' % (self.items[0]) - return ', %s = %s' % (self.items[0], ', '.join(map(str,self.items[1]))) - -class Do_Variable(Base): # R831 - """ - <do-variable> = <scalar-int-variable> - """ - subclass_names = ['Scalar_Int_Variable'] - -class Do_Block(Base): # R832 - """ - <do-block> = <block> - """ - subclass_names = ['Block'] - -class End_Do(Base): # R833 - """ - <end-do> = <end-do-stmt> - | <continue-stmt> - """ - subclass_names = ['End_Do_Stmt', 'Continue_Stmt'] - -class End_Do_Stmt(EndStmtBase): # R834 - """ - <end-do-stmt> = END DO [ <do-construct-name> ] - """ - subclass_names = [] - use_names = ['Do_Construct_Name'] - def match(string): return EndStmtBase.match('DO',Do_Construct_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Nonblock_Do_Construct(Base): # R835 - """ - <nonblock-do-stmt> = <action-term-do-construct> - | <outer-shared-do-construct> - """ - subclass_names = ['Action_Term_Do_Construct', 'Outer_Shared_Do_Construct'] - -class Action_Term_Do_Construct(BlockBase): # R836 - """ - <action-term-do-construct> = <label-do-stmt> - <do-body> - <do-term-action-stmt> - """ - subclass_names = [] - use_names = ['Label_Do_Stmt', 'Do_Body', 'Do_Term_Action_Stmt'] - def match(reader): - content = [] - for cls in [Label_Do_Stmt, Do_Body, Do_Term_Action_Stmt]: - obj = cls(reader) - if obj is None: # todo: restore reader - return - content.append(obj) - return content, - match = staticmethod(match) - -class Do_Body(BlockBase): # R837 - """ - <do-body> = [ <execution-part-construct> ]... - """ - subclass_names = [] - use_names = ['Execution_Part_Construct'] - def match(string): return BlockBase.match(None, [Execution_Part_Construct], None, string) - match = staticmethod(match) - -class Do_Term_Action_Stmt(StmtBase): # R838 - """ - <do-term-action-stmt> = <action-stmt> - C824: <do-term-action-stmt> shall not be <continue-stmt>, <goto-stmt>, <return-stmt>, <stop-stmt>, - <exit-stmt>, <cycle-stmt>, <end-function-stmt>, <end-subroutine-stmt>, - <end-program-stmt>, <arithmetic-if-stmt> - """ - subclass_names = ['Action_Stmt_C824'] - -class Outer_Shared_Do_Construct(BlockBase): # R839 - """ - <outer-shared-do-construct> = <label-do-stmt> - <do-body> - <shared-term-do-construct> - """ - subclass_names = [] - use_names = ['Label_Do_Stmt', 'Do_Body', 'Shared_Term_Do_Construct'] - def match(reader): - content = [] - for cls in [Label_Do_Stmt, Do_Body, Shared_Term_Do_Construct]: - obj = cls(reader) - if obj is None: # todo: restore reader - return - content.append(obj) - return content, - match = staticmethod(match) - -class Shared_Term_Do_Construct(Base): # R840 - """ - <shared-term-do-construct> = <outer-shared-do-construct> - | <inner-shared-do-construct> - """ - subclass_names = ['Outer_Shared_Do_Construct', 'Inner_Shared_Do_Construct'] - -class Inner_Shared_Do_Construct(BlockBase): # R841 - """ - <inner-shared-do-construct> = <label-do-stmt> - <do-body> - <do-term-shared-stmt> - """ - subclass_names = [] - use_names = ['Label_Do_Stmt', 'Do_Body', 'Do_Term_Shared_Stmt'] - - def match(reader): - content = [] - for cls in [Label_Do_Stmt, Do_Body, Do_Term_Shared_Stmt]: - obj = cls(reader) - if obj is None: # todo: restore reader - return - content.append(obj) - return content, - match = staticmethod(match) - -class Do_Term_Shared_Stmt(StmtBase): # R842 - """ - <do-term-shared-stmt> = <action-stmt> - C826: see C824 above. - """ - subclass_names = ['Action_Stmt'] - -class Cycle_Stmt(StmtBase, WORDClsBase): # R843 - """ - <cycle-stmt> = CYCLE [ <do-construct-name> ] - """ - subclass_names = [] - use_names = ['Do_Construct_Name'] - def match(string): return WORDClsBase.match('CYCLE', Do_Construct_Name, string) - match = staticmethod(match) - -class Exit_Stmt(StmtBase, WORDClsBase): # R844 - """ - <exit-stmt> = EXIT [ <do-construct-name> ] - """ - subclass_names = [] - use_names = ['Do_Construct_Name'] - def match(string): return WORDClsBase.match('EXIT', Do_Construct_Name, string) - match = staticmethod(match) - -class Goto_Stmt(StmtBase): # R845 - """ - <goto-stmt> = GO TO <label> - """ - subclass_names = [] - use_names = ['Label'] - def match(string): - if string[:2].upper() != 'GO': return - line = string[2:].lstrip() - if line[:2].upper() != 'TO': return - return Label(line[2:].lstrip()), - match = staticmethod(match) - def tostr(self): return 'GO TO %s' % (self.items[0]) - -class Computed_Goto_Stmt(StmtBase): # R846 - """ - <computed-goto-stmt> = GO TO ( <label-list> ) [ , ] <scalar-int-expr> - """ - subclass_names = [] - use_names = ['Label_List', 'Scalar_Int_Expr'] - def match(string): - if string[:2].upper()!='GO': return - line = string[2:].lstrip() - if line[:2].upper()!='TO': return - line = line[2:].lstrip() - if not line.startswith('('): return - i = line.find(')') - if i==-1: return - lst = line[1:i].strip() - if not lst: return - line = line[i+1:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - if not line: return - return Label_List(lst), Scalar_Int_Expr(line) - match = staticmethod(match) - def tostr(self): return 'GO TO (%s), %s' % self.items - -class Arithmetic_If_Stmt(StmtBase): # R847 - """ - <arithmetic-if-stmt> = IF ( <scalar-numeric-expr> ) <label> , <label> , <label> - """ - subclass_names = [] - use_names = ['Scalar_Numeric_Expr', 'Label'] - def match(string): - if string[:2].upper() != 'IF': return - line = string[2:].lstrip() - if not line.startswith('('): return - i = line.rfind(')') - if i==-1: return - labels = line[i+1:].lstrip().split(',') - if len(labels) != 3: return - labels = [Label(l.strip()) for l in labels] - return (Scalar_Numeric_Expr(line[1:i].strip()),) + tuple(labels) - match = staticmethod(match) - def tostr(self): return 'IF (%s) %s, %s, %s' % self.items - -class Continue_Stmt(StmtBase, STRINGBase): # R848 - """ - <continue-stmt> = CONTINUE - """ - subclass_names = [] - def match(string): return STRINGBase.match('CONTINUE', string) - match = staticmethod(match) - - -class Stop_Stmt(StmtBase, WORDClsBase): # R849 - """ - <stop-stmt> = STOP [ <stop-code> ] - """ - subclass_names = [] - use_names = ['Stop_Code'] - def match(string): return WORDClsBase.match('STOP', Stop_Code, string) - match = staticmethod(match) - -class Stop_Code(StringBase): # R850 - """ - <stop-code> = <scalar-char-constant> - | <digit> [ <digit> [ <digit> [ <digit> [ <digit> ] ] ] ] - """ - subclass_names = ['Scalar_Char_Constant'] - def match(string): return StringBase.match(pattern.abs_label, string) - match = staticmethod(match) - - -############################################################################### -############################### SECTION 9 #################################### -############################################################################### - -class Io_Unit(StringBase): # R901 - """ - <io-unit> = <file-unit-number> - | * - | <internal-file-variable> - """ - subclass_names = ['File_Unit_Number', 'Internal_File_Variable'] - def match(string): return StringBase.match('*', string) - match = staticmethod(match) - -class File_Unit_Number(Base): # R902 - """ - <file-unit-number> = <scalar-int-expr> - """ - subclass_names = ['Scalar_Int_Expr'] - -class Internal_File_Variable(Base): # R903 - """ - <internal-file-variable> = <char-variable> - C901: <char-variable> shall not be an array section with a vector subscript. - """ - subclass_names = ['Char_Variable'] - -class Open_Stmt(StmtBase, CALLBase): # R904 - """ - <open-stmt> = OPEN ( <connect-spec-list> ) - """ - subclass_names = [] - use_names = ['Connect_Spec_List'] - def match(string): CALLBase.match('OPEN', Connect_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -class Connect_Spec(KeywordValueBase): # R905 - """ - <connect-spec> = [ UNIT = ] <file-unit-number> - | ACCESS = <scalar-default-char-expr> - | ACTION = <scalar-default-char-expr> - | ASYNCHRONOUS = <scalar-default-char-expr> - | BLANK = <scalar-default-char-expr> - | DECIMAL = <scalar-default-char-expr> - | DELIM = <scalar-default-char-expr> - | ENCODING = <scalar-default-char-expr> - | ERR = <label> - | FILE = <file-name-expr> - | FORM = <scalar-default-char-expr> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | PAD = <scalar-default-char-expr> - | POSITION = <scalar-default-char-expr> - | RECL = <scalar-int-expr> - | ROUND = <scalar-default-char-expr> - | SIGN = <scalar-default-char-expr> - | STATUS = <scalar-default-char-expr> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label', 'File_Name_Expr', 'Iomsg_Variable', - 'Scalar_Int_Expr', 'Scalar_Int_Variable'] - def match(string): - for (k,v) in [\ - (['ACCESS','ACTION','ASYNCHRONOUS','BLANK','DECIMAL','DELIM','ENCODING', - 'FORM','PAD','POSITION','ROUND','SIGN','STATUS'], Scalar_Default_Char_Expr), - ('ERR', Label), - ('FILE',File_Name_Expr), - ('IOSTAT', Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('RECL', Scalar_Int_Expr), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number - match = staticmethod(match) - - -class File_Name_Expr(Base): # R906 - """ - <file-name-expr> = <scalar-default-char-expr> - """ - subclass_names = ['Scalar_Default_Char_Expr'] - -class Iomsg_Variable(Base): # R907 - """ - <iomsg-variable> = <scalar-default-char-variable> - """ - subclass_names = ['Scalar_Default_Char_Variable'] - -class Close_Stmt(StmtBase, CALLBase): # R908 - """ - <close-stmt> = CLOSE ( <close-spec-list> ) - """ - subclass_names = [] - use_names = ['Close_Spec_List'] - def match(string): CALLBase.match('CLOSE', Close_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -class Close_Spec(KeywordValueBase): # R909 - """ - <close-spec> = [ UNIT = ] <file-unit-number> - | IOSTAT = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | ERR = <label> - | STATUS = <scalar-default-char-expr> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label', 'Iomsg_Variable', - 'Scalar_Int_Variable'] - def match(string): - for (k,v) in [\ - ('ERR', Label), - ('IOSTAT', Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('STATUS', Scalar_Default_Char_Expr), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number(string) - match = staticmethod(match) - -class Read_Stmt(StmtBase): # R910 - """ - <read-stmt> = READ ( <io-control-spec-list> ) [ <input-item-list> ] - | READ <format> [ , <input-item-list> ] - """ - subclass_names = [] - use_names = ['Io_Control_Spec_List', 'Input_Item_List', 'Format'] - -class Write_Stmt(StmtBase): # R911 - """ - <write-stmt> = WRITE ( <io-control-spec-list> ) [ <output-item-list> ] - """ - subclass_names = [] - use_names = ['Io_Control_Spec_List', 'Output_Item_List'] - def match(string): - if string[:5].upper()!='WRITE': return - line = string[5:].lstrip() - if not line.startswith('('): return - line, repmap = string_replace_map(line) - i = line.find(')') - if i==-1: return - l = line[1:i].strip() - if not l: return - l = repmap(l) - if i==len(line)-1: - return Io_Control_Spec_List(l),None - return Io_Control_Spec_List(l), Output_Item_List(repmap(line[i+1:].lstrip())) - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return 'WRITE(%s)' % (self.items[0]) - return 'WRITE(%s) %s' % tuple(self.items) - -class Print_Stmt(StmtBase): # R912 - """ - <print-stmt> = PRINT <format> [ , <output-item-list> ] - """ - subclass_names = [] - use_names = ['Format', 'Output_Item_List'] - def match(string): - if string[:5].upper()!='PRINT': return - line = string[5:] - if not line: return - c = line[0].upper() - if 'A'<=c<='Z' or c=='_' or '0'<=c<='9': return - line, repmap = string_replace_map(line.lstrip()) - i = line.find(',') - if i==-1: return Format(repmap(line)), None - l = repmap(line[i+1:].lstrip()) - if not l: return - return Format(repmap(line[:i].rstrip())), Output_Item_List(l) - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return 'PRINT %s' % (self.items[0]) - return 'PRINT %s, %s' % tuple(self.items) - -class Io_Control_Spec_List(SequenceBase): # R913-list - """ - <io-control-spec-list> is a list taking into account C910, C917, C918 - """ - subclass_names = [] - use_names = ['Io_Control_Spec'] - def match(string): - line, repmap = string_replace_map(string) - splitted = line.split(',') - if not splitted: return - lst = [] - for i in range(len(splitted)): - p = splitted[i].strip() - if i==0: - if '=' not in p: p = 'UNIT=%s' % (repmap(p)) - else: p = repmap(p) - elif i==1: - if '=' not in p: - p = repmap(p) - try: - f = Format(p) - # todo: make sure that f is char-expr, if not, raise NoMatchError - p = 'FMT=%s' % (Format(p)) - except NoMatchError: - p = 'NML=%s' % (Namelist_Group_Name(p)) - else: - p = repmap(p) - else: - p = repmap(p) - lst.append(Io_Control_Spec(p)) - return ',', tuple(lst) - match = staticmethod(match) - -class Io_Control_Spec(KeywordValueBase): # R913 - """ - <io-control-spec> = [ UNIT = ] <io-unit> - | [ FMT = ] <format> - | [ NML = ] <namelist-group-name> - | ADVANCE = <scalar-default-char-expr> - | ASYNCHRONOUS = <scalar-char-initialization-expr> - | BLANK = <scalar-default-char-expr> - | DECIMAL = <scalar-default-char-expr> - | DELIM = <scalar-default-char-expr> - | END = <label> - | EOR = <label> - | ERR = <label> - | ID = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | PAD = <scalar-default-char-expr> - | POS = <scalar-int-expr> - | REC = <scalar-int-expr> - | ROUND = <scalar-default-char-expr> - | SIGN = <scalar-default-char-expr> - | SIZE = <scalar-int-variable> - """ - subclass_names = [] - use_names = ['Io_Unit', 'Format', 'Namelist_Group_Name', 'Scalar_Default_Char_Expr', - 'Scalar_Char_Initialization_Expr', 'Label', 'Scalar_Int_Variable', - 'Iomsg_Variable', 'Scalar_Int_Expr'] - def match(string): - for (k,v) in [\ - (['ADVANCE', 'BLANK', 'DECIMAL', 'DELIM', 'PAD', 'ROUND', 'SIGN'], Scalar_Default_Char_Expr), - ('ASYNCHRONOUS', Scalar_Char_Initialization_Expr), - (['END','EOR','ERR'], Label), - (['ID','IOSTAT','SIZE'], Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - (['POS', 'REC'], Scalar_Int_Expr), - ('UNIT', Io_Unit), - ('FMT', Format), - ('NML', Namelist_Group_Name) - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return - match = staticmethod(match) - -class Format(StringBase): # R914 - """ - <format> = <default-char-expr> - | <label> - | * - """ - subclass_names = ['Label', 'Default_Char_Expr'] - def match(string): return StringBase.match('*', string) - match = staticmethod(match) - -class Input_Item(Base): # R915 - """ - <input-item> = <variable> - | <io-implied-do> - """ - subclass_names = ['Variable', 'Io_Implied_Do'] - -class Output_Item(Base): # R916 - """ - <output-item> = <expr> - | <io-implied-do> - """ - subclass_names = ['Expr', 'Io_Implied_Do'] - -class Io_Implied_Do(Base): # R917 - """ - <io-implied-do> = ( <io-implied-do-object-list> , <io-implied-do-control> ) - """ - subclass_names = [] - use_names = ['Io_Implied_Do_Object_List', 'Io_Implied_Do_Control'] - -class Io_Implied_Do_Object(Base): # R918 - """ - <io-implied-do-object> = <input-item> - | <output-item> - """ - subclass_names = ['Input_Item', 'Output_Item'] - -class Io_Implied_Do_Control(Base): # R919 - """ - <io-implied-do-control> = <do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] - """ - subclass_names = [] - use_names = ['Do_Variable', 'Scalar_Int_Expr'] - -class Dtv_Type_Spec(CALLBase): # R920 - """ - <dtv-type-spec> = TYPE ( <derived-type-spec> ) - | CLASS ( <derived-type-spec> ) - """ - subclass_names = [] - use_names = ['Derived_Type_Spec'] - def match(string): CALLStmt.match(['TYPE', 'CLASS'], Derived_Type_Spec, string, require_rhs=True) - match = staticmethod(match) - -class Wait_Stmt(StmtBase, CALLBase): # R921 - """ - <wait-stmt> = WAIT ( <wait-spec-list> ) - """ - subclass_names = [] - use_names = ['Wait_Spec_List'] - def match(string): return CALLBase.match('WAIT', Wait_Spec_List, string, require_rhs=True) - match = staticmethod(match) - -class Wait_Spec(KeywordValueBase): # R922 - """ - <wait-spec> = [ UNIT = ] <file-unit-number> - | END = <label> - | EOR = <label> - | ERR = <label> - | ID = <scalar-int-expr> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Label', 'Scalar_Int_Expr', 'Iomsg_Variable', 'Scalar_Int_Variable'] - def match(string): - for (k,v) in [\ - (['END','EOR','ERR'], Label), - ('IOSTAT', Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('ID', Scalar_Int_Expr), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number(string) - - match = staticmethod(match) - -class Backspace_Stmt(StmtBase): # R923 - """ - <backspace-stmt> = BACKSPACE <file-unit-number> - | BACKSPACE ( <position-spec-list> ) - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Position_Spec_List'] - -class Endfile_Stmt(StmtBase): # R924 - """ - <endfile-stmt> = ENDFILE <file-unit-number> - | ENDFILE ( <position-spec-list> ) - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Position_Spec_List'] - -class Rewind_Stmt(StmtBase): # R925 - """ - <rewind-stmt> = REWIND <file-unit-number> - | REWIND ( <position-spec-list> ) - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Position_Spec_List'] - -class Position_Spec(KeywordValueBase): # R926 - """ - <position-spec> = [ UNIT = ] <file-unit-number> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | ERR = <label> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Iomsg_Variable', 'Scalar_Int_Variable', 'Label'] - def match(string): - for (k,v) in [\ - ('ERR', Label), - ('IOSTAT', Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number(string) - match = staticmethod(match) - - -class Flush_Stmt(StmtBase): # R927 - """ - <flush-stmt> = FLUSH <file-unit-number> - | FLUSH ( <position-spec-list> ) - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Position_Spec_List'] - -class Flush_Spec(KeywordValueBase): # R928 - """ - <flush-spec> = [ UNIT = ] <file-unit-number> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | ERR = <label> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'Iomsg_Variable', 'Scalar_Int_Variable', 'Label'] - def match(string): - for (k,v) in [\ - ('ERR', Label), - ('IOSTAT', Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number(string) - match = staticmethod(match) - -class Inquire_Stmt(StmtBase): # R929 - """ - <inquire-stmt> = INQUIRE ( <inquire-spec-list> ) - | INQUIRE ( IOLENGTH = <scalar-int-variable> ) <output-item-list> - """ - subclass_names = [] - use_names = ['Inquire_Spec_List', 'Scalar_Int_Variable', 'Output_Item_List'] - -class Inquire_Spec(KeywordValueBase): # R930 - """ - <inquire-spec> = [ UNIT = ] <file-unit-number> - | FILE = <file-name-expr> - | ACCESS = <scalar-default-char-variable> - | ACTION = <scalar-default-char-variable> - | ASYNCHRONOUS = <scalar-default-char-variable> - | BLANK = <scalar-default-char-variable> - | DECIMAL = <scalar-default-char-variable> - | DELIM = <scalar-default-char-variable> - | DIRECT = <scalar-default-char-variable> - | ENCODING = <scalar-default-char-variable> - | ERR = <label> - | EXIST = <scalar-default-logical-variable> - | FORM = <scalar-default-char-variable> - | FORMATTED = <scalar-default-char-variable> - | ID = <scalar-int-expr> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | NAME = <scalar-default-char-variable> - | NAMED = <scalar-default-logical-variable> - | NEXTREC = <scalar-int-variable> - | NUMBER = <scalar-int-variable> - | OPENED = <scalar-default-logical-variable> - | PAD = <scalar-default-char-variable> - | PENDING = <scalar-default-logical-variable> - | POS = <scalar-int-variable> - | POSITION = <scalar-default-char-variable> - | READ = <scalar-default-char-variable> - | READWRITE = <scalar-default-char-variable> - | RECL = <scalar-int-variable> - | ROUND = <scalar-default-char-variable> - | SEQUENTIAL = <scalar-default-char-variable> - | SIGN = <scalar-default-char-variable> - | SIZE = <scalar-int-variable> - | STREAM = <scalar-default-char-variable> - | UNFORMATTED = <scalar-default-char-variable> - | WRITE = <scalar-default-char-variable> - """ - subclass_names = [] - use_names = ['File_Unit_Number', 'File_Name_Expr', 'Scalar_Default_Char_Variable', - 'Scalar_Default_Logical_Variable', 'Scalar_Int_Variable', 'Scalar_Int_Expr', - 'Label', 'Iomsg_Variable'] - def match(string): - for (k,v) in [\ - (['ACCESS','ACTION','ASYNCHRONOUS', 'BLANK', 'DECIMAL', 'DELIM', - 'DIRECT','ENCODING','FORM','NAME','PAD', 'POSITION','READ','READWRITE', - 'ROUND', 'SEQUENTIAL', 'SIGN','STREAM','UNFORMATTED','WRITE'], - Scalar_Default_Char_Variable), - ('ERR', Label), - (['EXIST','NAMED','PENDING'], Scalar_Default_Logical_Variable), - ('ID', Scalar_Int_Expr), - (['IOSTAT','NEXTREC','NUMBER','POS','RECL','SIZE'], Scalar_Int_Variable), - ('IOMSG', Iomsg_Variable), - ('FILE', File_Name_Expr), - ('UNIT', File_Unit_Number), - ]: - try: - obj = KeywordValueBase.match(k, v, string, upper_lhs = True) - except NoMatchError: - obj = None - if obj is not None: return obj - return 'UNIT', File_Unit_Number(string) - return - match = staticmethod(match) - -############################################################################### -############################### SECTION 10 #################################### -############################################################################### - -class Format_Stmt(StmtBase, WORDClsBase): # R1001 - """ - <format-stmt> = FORMAT <format-specification> - """ - subclass_names = [] - use_names = ['Format_Specification'] - def match(string): WORDClsBase.match('FORMAT', Format_Specification, string, require_cls=True) - match = staticmethod(match) - -class Format_Specification(BracketBase): # R1002 - """ - <format-specification> = ( [ <format-item-list> ] ) - """ - subclass_names = [] - use_names = ['Format_Item_List'] - def match(string): return BracketBase.match('()', Format_Item_List, string, require_cls=False) - match = staticmethod(match) - -class Format_Item(Base): # R1003 - """ - <format-item> = [ <r> ] <data-edit-desc> - | <control-edit-desc> - | <char-string-edit-desc> - | [ <r> ] ( <format-item-list> ) - """ - subclass_names = ['Control_Edit_Desc', 'Char_String_Edit_Desc'] - use_names = ['R', 'Format_Item_List'] - -class R(Base): # R1004 - """ - <r> = <int-literal-constant> - <r> shall be positive and without kind parameter specified. - """ - subclass_names = ['Int_Literal_Constant'] - -class Data_Edit_Desc(Base): # R1005 - """ - <data-edit-desc> = I <w> [ . <m> ] - | B <w> [ . <m> ] - | O <w> [ . <m> ] - | Z <w> [ . <m> ] - | F <w> . <d> - | E <w> . <d> [ E <e> ] - | EN <w> . <d> [ E <e> ] - | ES <w> . <d> [ E <e>] - | G <w> . <d> [ E <e> ] - | L <w> - | A [ <w> ] - | D <w> . <d> - | DT [ <char-literal-constant> ] [ ( <v-list> ) ] - """ - subclass_names = [] - use_names = ['W', 'M', 'D', 'E', 'Char_Literal_Constant', 'V_List'] - def match(string): - c = string[0].upper() - if c in ['I','B','O','Z','D']: - line = string[1:].lstrip() - if '.' in line: - i1,i2 = line.split('.',1) - i1 = i1.rstrip() - i2 = i2.lstrip() - return c, W(i1), M(i2), None - return c,W(line), None, None - if c in ['E','G']: - line = string[1:].lstrip() - if line.count('.')==1: - i1,i2 = line.split('.',1) - i1 = i1.rstrip() - i2 = i2.lstrip() - return c, W(i1), D(i2), None - elif line.count('.')==2: - i1,i2,i3 = line.split('.',2) - i1 = i1.rstrip() - i2 = i2.lstrip() - i3 = i3.lstrip() - return c, W(i1), D(i2), E(i3) - else: - return - if c=='L': - line = string[1:].lstrip() - if not line: return - return c, W(line), None, None - if c=='A': - line = string[1:].lstrip() - if not line: - return c, None, None, None - return c, W(line), None, None - c = string[:2].upper() - if len(c)!=2: return - if c in ['EN','ES']: - line = string[2:].lstrip() - if line.count('.')==1: - i1,i2 = line.split('.',1) - i1 = i1.rstrip() - i2 = i2.lstrip() - return c, W(i1), D(i2), None - elif line.count('.')==2: - i1,i2,i3 = line.split('.',2) - i1 = i1.rstrip() - i2 = i2.lstrip() - i3 = i3.lstrip() - return c, W(i1), D(i2), E(i3) - else: - return - if c=='DT': - line = string[2:].lstrip() - if not line: - return c, None, None, None - lst = None - if line.endswith(')'): - i = line.rfind('(') - if i==-1: return - l = line[i+1:-1].strip() - if not l: return - lst = V_List(l) - line = line[:i].rstrip() - if not line: - return c, None, lst, None - return c, Char_Literal_Constant(line), lst, None - return - match = staticmethod(match) - def tostr(self): - c = selt.items[0] - if c in ['I', 'B', 'O', 'Z', 'F', 'D', 'A', 'L']: - if self.items[2] is None: - return '%s%s' % (c, self.items[1]) - return '%s%s.%s' % (c, self.items[1], self.items[2]) - if c in ['E', 'EN', 'ES', 'G']: - if self.items[3] is None: - return '%s%s.%s' % (c, self.items[1], self.items[2]) - return '%s%s.%sE%s' % (c, self.items[1], self.items[2], self.items[3]) - if c=='DT': - if self.items[1] is None: - if self.items[2] is None: - return c - else: - return '%s(%s)' % (c, self.items[2]) - else: - if self.items[2] is None: - return '%s%s' % (c, self.items[1]) - else: - return '%s%s(%s)' % (c, self.items[1], self.items[2]) - raise NotImpletenetedError,`c` - -class W(Base): # R1006 - """ - <w> = <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] - -class M(Base): # R1007 - """ - <m> = <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] - -class D(Base): # R1008 - """ - <d> = <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] - -class E(Base): # R1009 - """ - <e> = <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] - -class V(Base): # R1010 - """ - <v> = <signed-int-literal-constant> - """ - subclass_names = ['Signed_Int_Literal_Constant'] - -class Control_Edit_Desc(Base): # R1011 - """ - <control-edit-desc> = <position-edit-desc> - | [ <r> ] / - | : - | <sign-edit-desc> - | <k> P - | <blank-interp-edit-desc> - | <round-edit-desc> - | <decimal-edit-desc> - """ - subclass_names = ['Position_Edit_Desc', 'Sign_Edit_Desc', 'Blank_Interp_Edit_Desc', 'Round_Edit_Desc', - 'Decimal_Edit_Desc'] - use_names = ['R', 'K'] - -class K(Base): # R1012 - """ - <k> = <signed-int-literal-constant> - """ - subclass_names = ['Signed_Int_Literal_Constant'] - -class Position_Edit_Desc(Base): # R1013 - """ - <position-edit-desc> = T <n> - | TL <n> - | TR <n> - | <n> X - """ - subclass_names = [] - use_names = ['N'] - -class N(Base): # R1014 - """ - <n> = <int-literal-constant> - """ - subclass_names = ['Int_Literal_Constant'] - -class Sign_Edit_Desc(STRINGBase): # R1015 - """ - <sign-edit-desc> = SS - | SP - | S - """ - subclass_names = [] - def match(string): return STRINGBase.match(['SS','SP','S'], string) - match = staticmethod(match) - -class Blank_Interp_Edit_Desc(STRINGBase): # R1016 - """ - <blank-interp-edit-desc> = BN - | BZ - """ - subclass_names = [] - def match(string): return STRINGBase.match(['BN','BZ',], string) - match = staticmethod(match) - -class Round_Edit_Desc(STRINGBase): # R1017 - """ - <round-edit-desc> = RU - | RD - | RZ - | RN - | RC - | RP - """ - subclass_names = [] - def match(string): return STRINGBase.match(['RU','RD','RZ','RN','RC','RP'], string) - match = staticmethod(match) - -class Decimal_Edit_Desc(STRINGBase): # R1018 - """ - <decimal-edit-desc> = DC - | DP - """ - subclass_names = [] - def match(string): return STRINGBase.match(['DC','DP'], string) - match = staticmethod(match) - -class Char_String_Edit_Desc(Base): # R1019 - """ - <char-string-edit-desc> = <char-literal-constant> - """ - subclass_names = ['Char_Literal_Constant'] - -############################################################################### -############################### SECTION 11 #################################### -############################################################################### - -class Main_Program(Base): # R1101 - """ - <main-program> = [ <program-stmt> ] - [ <specification-part> ] - [ <execution-part> ] - [ <internal-subprogram-part> ] - <end-program-stmt> - """ - subclass_names = [] - use_names = ['Program_Stmt', 'Specification_Part', 'Execution_Part', 'Internal_Subprogram_Part', - 'End_Program_Stmt'] - -class Program_Stmt(StmtBase, WORDClsBase): # R1102 - """ - <program-stmt> = PROGRAM <program-name> - """ - subclass_names = [] - use_names = ['Program_Name'] - def match(string): return WORDClsBase.match('PROGRAM',Program_Name, string, require_cls = True) - match = staticmethod(match) - -class End_Program_Stmt(EndStmtBase): # R1103 - """ - <end-program-stmt> = END [ PROGRAM [ <program-name> ] ] - """ - subclass_names = [] - use_names = ['Program_Name'] - def match(string): return EndStmtBase.match('PROGRAM',Program_Name, string) - match = staticmethod(match) - -class Module(Base): # R1104 - """ - <module> = <module-stmt> - [ <specification-part> ] - [ <module-subprogram-part> ] - <end-module-stmt> - """ - subclass_names = [] - use_names = ['Module_Stmt', 'Specification_Part', 'Module_Subprogram_Part', 'End_Module_Stmt'] - -class Module_Stmt(StmtBase, WORDClsBase): # R1105 - """ - <module-stmt> = MODULE <module-name> - """ - subclass_names = [] - use_names = ['Module_Name'] - def match(string): return WORDClsBase.match('MODULE',Module_Name, string, require_cls = True) - match = staticmethod(match) - -class End_Module_Stmt(EndStmtBase): # R1106 - """ - <end-module-stmt> = END [ MODULE [ <module-name> ] ] - """ - subclass_names = [] - use_names = ['Module_Name'] - def match(string): return EndStmtBase.match('MODULE',Module_Name, string, require_stmt_type=True) - match = staticmethod(match) - -class Module_Subprogram_Part(Base): # R1107 - """ - <module-subprogram-part> = <contains-stmt> - <module-subprogram> - [ <module-subprogram> ]... - """ - subclass_names = [] - use_names = ['Contains_Stmt', 'Module_Subprogram'] - -class Module_Subprogram(Base): # R1108 - """ - <module-subprogram> = <function-subprogram> - | <subroutine-subprogram> - """ - subclass_names = ['Function_Subprogram', 'Subroutine_Subprogram'] - -class Use_Stmt(StmtBase): # R1109 - """ - <use-stmt> = USE [ [ , <module-nature> ] :: ] <module-name> [ , <rename-list> ] - | USE [ [ , <module-nature> ] :: ] <module-name> , ONLY: [ <only-list> ] - """ - subclass_names = [] - use_names = ['Module_Nature', 'Module_Name', 'Rename_List', 'Only_List'] - - def match(string): - if string[:3].upper() != 'USE': return - line = string[3:] - if not line: return - if isalnum(line[0]): return - line = line.lstrip() - i = line.find('::') - nature = None - if i!=-1: - if line.startswith(','): - l = line[1:i].strip() - if not l: return - nature = Module_Nature(l) - line = line[i+2:].lstrip() - if not line: return - i = line.find(',') - if i==-1: return nature, Module_Name(line), '', None - name = line[:i].rstrip() - if not name: return - name = Module_Name(name) - line = line[i+1:].lstrip() - if not line: return - if line[:5].upper()=='ONLY:': - line = line[5:].lstrip() - if not line: - return nature, name, ', ONLY:', None - return nature, name, ', ONLY:', Only_List(line) - return nature, name, ',', Rename_List(line) - match = staticmethod(match) - def tostr(self): - s = 'USE' - if self.items[0] is not None: - s += ', %s' % (self.items[0]) - s += ' :: %s%s' % (self.items[1], self.items[2]) - if self.items[3] is not None: - s += ' %s' % (self.items[3]) - return s - -class Module_Nature(STRINGBase): # R1110 - """ - <module-nature> = INTRINSIC - | NON_INTRINSIC - """ - subclass_names = [] - def match(string): return STRINGBase.match(['INTRINSIC','NON_INTRINSIC'], string) - match = staticmethod(match) - -class Rename(Base): # R1111 - """ - <rename> = <local-name> => <use-name> - | OPERATOR(<local-defined-operator>) => OPERATOR(<use-defined-operator>) - """ - subclass_names = [] - use_names = ['Local_Name', 'Use_Name', 'Local_Defined_Operator', 'Use_Defined_Operator'] - def match(string): - s = string.split('=>', 1) - if len(s) != 2: return - lhs, rhs = s[0].rstrip(), s[1].lstrip() - if not lhs or not rhs: return - if lhs[:8].upper()=='OPERATOR' and rhs[:8].upper()=='OPERATOR': - l = lhs[8:].lstrip() - r = rhs[8:].lstrip() - if l and r and l[0]+l[-1]=='()': - if r[0]+r[-1] != '()': return - l = l[1:-1].strip() - r = r[1:-1].strip() - if not l or not r: return - return 'OPERATOR', Local_Defined_Operator(l), Use_Defined_Operator(r) - return None, Local_Name(lhs), Use_Name(rhs) - match = staticmethod(match) - def tostr(self): - if not self.items[0]: - return '%s => %s' % self.items[1:] - return '%s(%s) => %s(%s)' % (self.items[0], self.items[1],self.items[0], self.items[2]) - -class Only(Base): # R1112 - """ - <only> = <generic-spec> - | <only-use-name> - | <rename> - """ - subclass_names = ['Generic_Spec', 'Only_Use_Name', 'Rename'] - -class Only_Use_Name(Base): # R1113 - """ - <only-use-name> = <name> - """ - subclass_names = ['Name'] - -class Local_Defined_Operator(Base): # R1114 - """ - <local-defined-operator> = <defined-unary-op> - | <defined-binary-op> - """ - subclass_names = ['Defined_Unary_Op', 'Defined_Binary_Op'] - -class Use_Defined_Operator(Base): # R1115 - """ - <use-defined-operator> = <defined-unary-op> - | <defined-binary-op> - """ - subclass_names = ['Defined_Unary_Op', 'Defined_Binary_Op'] - -class Block_Data(Base): # R1116 - """ - <block-data> = <block-data-stmt> - [ <specification-part> ] - <end-block-data-stmt> - """ - subclass_names = [] - use_names = ['Block_Data_Stmt', 'Specification_Part', 'End_Block_Data_Stmt'] - -class Block_Data_Stmt(StmtBase): # R1117 - """ - <block-data-stmt> = BLOCK DATA [ <block-data-name> ] - """ - subclass_names = [] - use_names = ['Block_Data_Name'] - def match(string): - if string[:5].upper()!='BLOCK': return - line = string[5:].lstrip() - if line[:4].upper()!='DATA': return - line = line[4:].lstrip() - if not line: return None, - return Block_Data_Name(line), - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return 'BLOCK DATA' - return 'BLOCK DATA %s' % self.items - -class End_Block_Data_Stmt(EndStmtBase): # R1118 - """ - <end-block-data-stmt> = END [ BLOCK DATA [ <block-data-name> ] ] - """ - subclass_names = [] - use_names = ['Block_Data_Name'] - def match(string): return EndStmtBase.match('BLOCK DATA',Block_Data_Name, string) - match = staticmethod(match) - -############################################################################### -############################### SECTION 12 #################################### -############################################################################### - - -class Interface_Block(Base): # R1201 - """ - <interface-block> = <interface-stmt> - [ <interface-specification> ]... - <end-interface-stmt> - """ - subclass_names = [] - use_names = ['Interface_Stmt', 'Interface_Specification', 'End_Interface_Stmt'] - -class Interface_Specification(Base): # R1202 - """ - <interface-specification> = <interface-body> - | <procedure-stmt> - """ - subclass_names = ['Interface_Body', 'Procedure_Stmt'] - -class Interface_Stmt(StmtBase): # R1203 - """ - <interface-stmt> = INTERFACE [ <generic-spec> ] - | ABSTRACT INTERFACE - """ - subclass_names = [] - use_names = ['Generic_Spec'] - -class End_Interface_Stmt(EndStmtBase): # R1204 - """ - <end-interface-stmt> = END INTERFACE [ <generic-spec> ] - """ - subclass_names = [] - use_names = ['Generic_Spec'] - def match(string): return EndStmtBase.match('INTERFACE',Generic_Spec, string, require_stmt_type=True) - match = staticmethod(match) - -class Interface_Body(Base): # R1205 - """ - <interface-body> = <function-stmt> - [ <specification-part> ] - <end-function-stmt> - | <subroutine-stmt> - [ <specification-part> ] - <end-subroutine-stmt> - """ - subclass_names = [] - use_names = ['Function_Stmt', 'Specification_Part', 'Subroutine_Stmt', 'End_Function_Stmt', 'End_Subroutine_Stmt'] - -class Procedure_Stmt(StmtBase): # R1206 - """ - <procedure-stmt> = [ MODULE ] PROCEDURE <procedure-name-list> - """ - subclass_names = [] - use_names = ['Procedure_Name_List'] - -class Generic_Spec(Base): # R1207 - """ - <generic-spec> = <generic-name> - | OPERATOR ( <defined-operator> ) - | ASSIGNMENT ( = ) - | <dtio-generic-spec> - """ - subclass_names = ['Generic_Name', 'Dtio_Generic_Spec'] - use_names = ['Defined_Operator'] - -class Dtio_Generic_Spec(Base): # R1208 - """ - <dtio-generic-spec> = READ ( FORMATTED ) - | READ ( UNFORMATTED ) - | WRITE ( FORMATTED ) - | WRITE ( UNFORMATTED ) - """ - subclass_names = [] - -class Import_Stmt(StmtBase, WORDClsBase): # R1209 - """ - <import-stmt> = IMPORT [ :: ] <import-name-list> - """ - subclass_names = [] - use_names = ['Import_Name_List'] - def match(string): return WORDClsBase.match('IMPORT',Import_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class External_Stmt(StmtBase, WORDClsBase): # R1210 - """ - <external-stmt> = EXTERNAL [ :: ] <external-name-list> - """ - subclass_names = [] - use_names = ['External_Name_List'] - def match(string): return WORDClsBase.match('EXTERNAL',External_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Procedure_Declaration_Stmt(StmtBase): # R1211 - """ - <procedure-declaration-stmt> = PROCEDURE ( [ <proc-interface> ] ) [ [ , <proc-attr-spec> ]... :: ] <proc-decl-list> - """ - subclass_names = [] - use_names = ['Proc_Interface', 'Proc_Attr_Spec', 'Proc_Decl_List'] - -class Proc_Interface(Base): # R1212 - """ - <proc-interface> = <interface-name> - | <declaration-type-spec> - """ - subclass_names = ['Interface_Name', 'Declaration_Type_Spec'] - -class Proc_Attr_Spec(Base): # R1213 - """ - <proc-attr-spec> = <access-spec> - | <proc-language-binding-spec> - | INTENT ( <intent-spec> ) - | OPTIONAL - | SAVE - """ - subclass_names = ['Access_Spec', 'Proc_Language_Binding_Spec'] - use_names = ['Intent_Spec'] - -class Proc_Decl(BinaryOpBase): # R1214 - """ - <proc-decl> = <procedure-entity-name> [ => <null-init> ] - """ - subclass_names = ['Procedure_Entity_Name'] - use_names = ['Null_Init'] - def match(string): return BinaryOpBase.match(Procedure_Entity_Name,'=>', Null_Init, string) - match = staticmethod(match) - -class Interface_Name(Base): # R1215 - """ - <interface-name> = <name> - """ - subclass_names = ['Name'] - -class Intrinsic_Stmt(StmtBase, WORDClsBase): # R1216 - """ - <intrinsic-stmt> = INTRINSIC [ :: ] <intrinsic-procedure-name-list> - """ - subclass_names = [] - use_names = ['Intrinsic_Procedure_Name_List'] - def match(string): return WORDClsBase.match('INTRINSIC',Intrinsic_Procedure_Name_List,string,check_colons=True, require_cls=True) - match = staticmethod(match) - tostr = WORDClsBase.tostr_a - -class Function_Reference(CallBase): # R1217 - """ - <function-reference> = <procedure-designator> ( [ <actual-arg-spec-list> ] ) - """ - subclass_names = [] - use_names = ['Procedure_Designator','Actual_Arg_Spec_List'] - def match(string): - return CallBase.match(Procedure_Designator, Actual_Arg_Spec_List, string) - match = staticmethod(match) - -class Call_Stmt(StmtBase): # R1218 - """ - <call-stmt> = CALL <procedure-designator> [ ( [ <actual-arg-spec-list> ] ) ] - """ - subclass_names = [] - use_names = ['Procedure_Designator', 'Actual_Arg_Spec_List'] - def match(string): - if string[:4].upper()!='CALL': return - line, repmap = string_replace_map(string[4:].lstrip()) - if line.endswith(')'): - i = line.rfind('(') - if i==-1: return - args = repmap(line[i+1:-1].strip()) - if args: - return Procedure_Designator(repmap(line[:i].rstrip())),Actual_Arg_Spec_List(args) - return Procedure_Designator(repmap(line[:i].rstrip())),None - return Procedure_Designator(string[4:].lstrip()),None - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: return 'CALL %s' % (self.items[0]) - return 'CALL %s(%s)' % self.items - -class Procedure_Designator(BinaryOpBase): # R1219 - """ - <procedure-designator> = <procedure-name> - | <proc-component-ref> - | <data-ref> % <binding-name> - """ - subclass_names = ['Procedure_Name','Proc_Component_Ref'] - use_names = ['Data_Ref','Binding_Name'] - def match(string): - return BinaryOpBase.match(\ - Data_Ref, pattern.percent_op.named(), Binding_Name, string) - match = staticmethod(match) - -class Actual_Arg_Spec(KeywordValueBase): # R1220 - """ - <actual-arg-spec> = [ <keyword> = ] <actual-arg> - """ - subclass_names = ['Actual_Arg'] - use_names = ['Keyword'] - def match(string): return KeywordValueBase.match(Keyword, Actual_Arg, string) - match = staticmethod(match) - -class Actual_Arg(Base): # R1221 - """ - <actual-arg> = <expr> - | <variable> - | <procedure-name> - | <proc-component-ref> - | <alt-return-spec> - """ - subclass_names = ['Procedure_Name','Proc_Component_Ref','Alt_Return_Spec', 'Variable', 'Expr'] - -class Alt_Return_Spec(Base): # R1222 - """ - <alt-return-spec> = * <label> - """ - subclass_names = [] - use_names = ['Label'] - def match(string): - if not string.startswith('*'): return - line = string[1:].lstrip() - if not line: return - return Label(line), - match = staticmethod(match) - def tostr(self): return '*%s' % (self.items[0]) - -class Function_Subprogram(BlockBase): # R1223 - """ - <function-subprogram> = <function-stmt> - [ <specification-part> ] - [ <execution-part> ] - [ <internal-subprogram-part> ] - <end-function-stmt> - """ - subclass_names = [] - use_names = ['Function_Stmt', 'Specification_Part', 'Execution_Part', - 'Internal_Subprogram_Part', 'End_Function_Stmt'] - def match(reader): - return BlockBase.match(Function_Stmt, [Specification_Part, Execution_Part, Internal_Subprogram_Part], End_Function_Stmt, reader) - match = staticmethod(match) - -class Function_Stmt(StmtBase): # R1224 - """ - <function-stmt> = [ <prefix> ] FUNCTION <function-name> ( [ <dummy-arg-name-list> ] ) [ <suffix> ] - """ - subclass_names = [] - use_names = ['Prefix','Function_Name','Dummy_Arg_Name_List', 'Suffix'] - -class Proc_Language_Binding_Spec(Base): #1225 - """ - <proc-language-binding-spec> = <language-binding-spec> - """ - subclass_names = ['Language_Binding_Spec'] - -class Dummy_Arg_Name(Base): # R1226 - """ - <dummy-arg-name> = <name> - """ - subclass_names = ['Name'] - -class Prefix(SequenceBase): # R1227 - """ - <prefix> = <prefix-spec> [ <prefix-spec> ].. - """ - subclass_names = ['Prefix_Spec'] - _separator = (' ',re.compile(r'\s+(?=[a-z_])',re.I)) - def match(string): return SequenceBase.match(Prefix._separator, Prefix_Spec, string) - match = staticmethod(match) - -class Prefix_Spec(STRINGBase): # R1228 - """ - <prefix-spec> = <declaration-type-spec> - | RECURSIVE - | PURE - | ELEMENTAL - """ - subclass_names = ['Declaration_Type_Spec'] - def match(string): - return STRINGBase.match(['RECURSIVE', 'PURE', 'ELEMENTAL'], string) - match = staticmethod(match) - -class Suffix(Base): # R1229 - """ - <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] - | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] - """ - subclass_names = ['Proc_Language_Binding_Spec'] - use_names = ['Result_Name'] - - def match(string): - if string[:6].upper()=='RESULT': - line = string[6:].lstrip() - if not line.startswith('('): return - i = line.find(')') - if i==-1: return - name = line[1:i].strip() - if not name: return - line = line[i+1:].lstrip() - if line: return Result_Name(name), Proc_Language_Binding_Spec(line) - return Result_Name(name), None - if not string.endswith(')'): return - i = string.rfind('(') - if i==-1: return - name = string[i+1:-1].strip() - if not name: return - line = string[:i].rstrip() - if line[-6:].upper()!='RESULT': return - line = line[:-6].rstrip() - if not line: return - return Result_Name(name), Proc_Language_Binding_Spec(line) - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: - return 'RESULT(%s)' % (self.items[0]) - return 'RESULT(%s) %s' % self.items - -class End_Function_Stmt(EndStmtBase): # R1230 - """ - <end-function-stmt> = END [ FUNCTION [ <function-name> ] ] - """ - subclass_names = [] - use_names = ['Function_Name'] - def match(string): return EndStmtBase.match('FUNCTION',Function_Name, string) - match = staticmethod(match) - -class Subroutine_Subprogram(BlockBase): # R1231 - """ - <subroutine-subprogram> = <subroutine-stmt> - [ <specification-part> ] - [ <execution-part> ] - [ <internal-subprogram-part> ] - <end-subroutine-stmt> - """ - subclass_names = [] - use_names = ['Subroutine_Stmt', 'Specification_Part', 'Execution_Part', - 'Internal_Subprogram_Part', 'End_Subroutine_Stmt'] - def match(reader): - return BlockBase.match(Subroutine_Stmt, [Specification_Part, Execution_Part, Internal_Subprogram_Part], End_Subroutine_Stmt, reader) - match = staticmethod(match) - -class Subroutine_Stmt(StmtBase): # R1232 - """ - <subroutine-stmt> = [ <prefix> ] SUBROUTINE <subroutine-name> [ ( [ <dummy-arg-list> ] ) [ <proc-language-binding-spec> ] ] - """ - subclass_names = [] - use_names = ['Prefix', 'Subroutine_Name', 'Dummy_Arg_List', 'Proc_Language_Binding_Spec'] - def match(string): - line, repmap = string_replace_map(string) - m = pattern.subroutine.search(line) - if m is None: return - prefix = line[:m.start()].rstrip() or None - if prefix is not None: - prefix = Prefix(repmap(prefix)) - line = line[m.end():].lstrip() - m = pattern.name.match(line) - if m is None: return - name = Subroutine_Name(m.group()) - line = line[m.end():].lstrip() - dummy_args = None - if line.startswith('('): - i = line.find(')') - if i==-1: return - dummy_args = line[1:i].strip() or None - if dummy_args is not None: - dummy_args = Dummy_Arg_List(repmap(dummy_args)) - line = line[i+1:].lstrip() - binding_spec = None - if line: - binding_spec = Proc_Language_Binding_Spec(repmap(line)) - return prefix, name, dummy_args, binding_spec - match = staticmethod(match) - def get_name(self): return self.items[1] - def tostr(self): - if self.items[0] is not None: - s = '%s SUBROUTINE %s' % (self.items[0], self.items[1]) - else: - s = 'SUBROUTINE %s' % (self.items[1]) - if self.items[2] is not None: - s += '(%s)' % (self.items[2]) - if self.items[3] is not None: - s += ' %s' % (self.items[3]) - return s - -class Dummy_Arg(StringBase): # R1233 - """ - <dummy-arg> = <dummy-arg-name> - | * - """ - subclass_names = ['Dummy_Arg_Name'] - def match(string): return StringBase.match('*', string) - match = staticmethod(match) - -class End_Subroutine_Stmt(EndStmtBase): # R1234 - """ - <end-subroutine-stmt> = END [ SUBROUTINE [ <subroutine-name> ] ] - """ - subclass_names = [] - use_names = ['Subroutine_Name'] - def match(string): return EndStmtBase.match('SUBROUTINE', Subroutine_Name, string) - match = staticmethod(match) - -class Entry_Stmt(StmtBase): # R1235 - """ - <entry-stmt> = ENTRY <entry-name> [ ( [ <dummy-arg-list> ] ) [ <suffix> ] ] - """ - subclass_names = [] - use_names = ['Entry_Name', 'Dummy_Arg_List', 'Suffix'] - -class Return_Stmt(StmtBase): # R1236 - """ - <return-stmt> = RETURN [ <scalar-int-expr> ] - """ - subclass_names = [] - use_names = ['Scalar_Int_Expr'] - def match(string): - start = string[:6].upper() - if start!='RETURN': return - if len(string)==6: return None, - return Scalar_Int_Expr(string[6:].lstrip()), - match = staticmethod(match) - def tostr(self): - if self.items[0] is None: return 'RETURN' - return 'RETURN %s' % self.items - -class Contains_Stmt(StmtBase, STRINGBase): # R1237 - """ - <contains-stmt> = CONTAINS - """ - subclass_names = [] - def match(string): return STRINGBase.match('CONTAINS',string) - match = staticmethod(match) - -class Stmt_Function_Stmt(StmtBase): # R1238 - """ - <stmt-function-stmt> = <function-name> ( [ <dummy-arg-name-list> ] ) = Scalar_Expr - """ - subclass_names = [] - use_names = ['Function_Name', 'Dummy_Arg_Name_List', 'Scalar_Expr'] - - def match(string): - i = string.find('=') - if i==-1: return - expr = string[i+1:].lstrip() - if not expr: return - line = string[:i].rstrip() - if not line or not line.endswith(')'): return - i = line.find('(') - if i==-1: return - name = line[:i].rstrip() - if not name: return - args = line[i+1:-1].strip() - if args: - return Function_Name(name), Dummy_Arg_Name_List(args), Scalar_Expr(expr) - return Function_Name(name), None, Scalar_Expr(expr) - match = staticmethod(match) - def tostr(self): - if self.items[1] is None: - return '%s () = %s' % (self.items[0], self.items[2]) - return '%s (%s) = %s' % self.items - -############################################################################### -################ GENERATE Scalar_, _List, _Name CLASSES ####################### -############################################################################### - -ClassType = type(Base) -_names = dir() -for clsname in _names: - cls = eval(clsname) - if not (isinstance(cls, ClassType) and issubclass(cls, Base) and not cls.__name__.endswith('Base')): continue - names = getattr(cls, 'subclass_names', []) + getattr(cls, 'use_names', []) - for n in names: - if n in _names: continue - if n.endswith('_List'): - _names.append(n) - n = n[:-5] - #print 'Generating %s_List' % (n) - exec '''\ -class %s_List(SequenceBase): - subclass_names = [\'%s\'] - use_names = [] - def match(string): return SequenceBase.match(r\',\', %s, string) - match = staticmethod(match) -''' % (n, n, n) - elif n.endswith('_Name'): - _names.append(n) - n = n[:-5] - #print 'Generating %s_Name' % (n) - exec '''\ -class %s_Name(Base): - subclass_names = [\'Name\'] -''' % (n) - elif n.startswith('Scalar_'): - _names.append(n) - n = n[7:] - #print 'Generating Scalar_%s' % (n) - exec '''\ -class Scalar_%s(Base): - subclass_names = [\'%s\'] -''' % (n,n) - - -Base_classes = {} -for clsname in dir(): - cls = eval(clsname) - if isinstance(cls, ClassType) and issubclass(cls, Base) and not cls.__name__.endswith('Base'): - Base_classes[cls.__name__] = cls - - -############################################################################### -##################### OPTIMIZE subclass_names tree ############################ -############################################################################### - -if 1: # Optimize subclass tree: - - def _rpl_list(clsname): - if clsname not in Base_classes: - #print 'Not implemented:',clsname - return [] # remove this code when all classes are implemented - cls = Base_classes[clsname] - if 'match' in cls.__dict__: - return [clsname] - l = [] - for n in getattr(cls,'subclass_names',[]): - l1 = _rpl_list(n) - for n1 in l1: - if n1 not in l: - l.append(n1) - return l - - for cls in Base_classes.values(): - if not hasattr(cls, 'subclass_names'): continue - opt_subclass_names = [] - for n in cls.subclass_names: - for n1 in _rpl_list(n): - if n1 not in opt_subclass_names: opt_subclass_names.append(n1) - if not opt_subclass_names==cls.subclass_names: - #print cls.__name__,':',', '.join(cls.subclass_names),'->',', '.join(opt_subclass_names) - cls.subclass_names[:] = opt_subclass_names - #else: - # print cls.__name__,':',opt_subclass_names - - -# Initialize Base.subclasses dictionary: -for clsname, cls in Base_classes.items(): - subclass_names = getattr(cls, 'subclass_names', None) - if subclass_names is None: - print '%s class is missing subclass_names list' % (clsname) - continue - try: - l = Base.subclasses[clsname] - except KeyError: - Base.subclasses[clsname] = l = [] - for n in subclass_names: - if n in Base_classes: - l.append(Base_classes[n]) - else: - print '%s not implemented needed by %s' % (n,clsname) - -if False: - for cls in Base_classes.values(): - subclasses = Base.subclasses.get(cls.__name__,[]) - subclasses_names = [c.__name__ for c in subclasses] - subclass_names = getattr(cls,'subclass_names', []) - use_names = getattr(cls,'use_names',[]) - for n in subclasses_names: - break - if n not in subclass_names: - print '%s needs to be added to %s subclasses_name list' % (n,cls.__name__) - for n in subclass_names: - break - if n not in subclasses_names: - print '%s needs to be added to %s subclass_name list' % (n,cls.__name__) - for n in use_names + subclass_names: - if n not in Base_classes: - print '%s not defined used by %s' % (n, cls.__name__) - - -#EOF diff --git a/numpy/f2py/lib/parser/__init__.py b/numpy/f2py/lib/parser/__init__.py deleted file mode 100644 index 9d707c01f..000000000 --- a/numpy/f2py/lib/parser/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -Tools for parsing Fortran 60/77/90/2003 codes into Statement tree. - -Use api module for importing public symbols. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" diff --git a/numpy/f2py/lib/parser/api.py b/numpy/f2py/lib/parser/api.py deleted file mode 100644 index 476c142e5..000000000 --- a/numpy/f2py/lib/parser/api.py +++ /dev/null @@ -1,73 +0,0 @@ -""" -Public API for Fortran parser. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import Fortran2003 -# import all Statement classes: -from base_classes import EndStatement -from block_statements import * - -# CHAR_BIT is used to convert object bit sizes to byte sizes -from utils import CHAR_BIT - -def get_reader(input, isfree=None, isstrict=None, include_dirs = None): - import os - import re - from readfortran import FortranFileReader, FortranStringReader - from parsefortran import FortranParser - if os.path.isfile(input): - name,ext = os.path.splitext(input) - if ext.lower() in ['.c']: - # get signatures from C file comments starting with `/*f2py` and ending with `*/`. - # TODO: improve parser to take line number offset making line numbers in - # parser messages correct. - f2py_c_comments = re.compile('/[*]\s*f2py\s.*[*]/',re.I | re.M) - f = open(filename,'r') - c_input = '' - for s1 in f2py_c_comments.findall(f.read()): - c_input += s1[2:-2].lstrip()[4:] + '\n' - f.close() - if isfree is None: isfree = True - if isstrict is None: isstrict = True - return parse(c_input, isfree, isstrict, include_dirs) - reader = FortranFileReader(input, - include_dirs = include_dirs) - if isfree is None: isfree = reader.isfree - if isstrict is None: isstrict = reader.isstrict - reader.set_mode(isfree, isstrict) - elif isinstance(input, str): - if isfree is None: isfree = True - if isstrict is None: isstrict = False - reader = FortranStringReader(input, - isfree, isstrict, - include_dirs = include_dirs) - else: - raise TypeError,'Expected string or filename input but got %s' % (type(input)) - return reader - -def parse(input, isfree=None, isstrict=None, include_dirs = None): - """ Parse input and return Statement tree. - - input --- string or filename. - isfree, isstrict --- specify input Fortran format. - Defaults are True, False, respectively, or - determined from input. - include_dirs --- list of include directories. - Default contains current working directory - and the directory of file name. - """ - from parsefortran import FortranParser - reader = get_reader(input, isfree, isstrict, include_dirs) - parser = FortranParser(reader) - parser.parse() - parser.analyze() - return parser.block diff --git a/numpy/f2py/lib/parser/base_classes.py b/numpy/f2py/lib/parser/base_classes.py deleted file mode 100644 index 68ea9c24a..000000000 --- a/numpy/f2py/lib/parser/base_classes.py +++ /dev/null @@ -1,819 +0,0 @@ -""" ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['Statement','BeginStatement','EndStatement', 'Variable', - 'AttributeHolder','ProgramBlock'] - -import re -import sys -import copy -from readfortran import Line -from numpy.distutils.misc_util import yellow_text, red_text -from utils import split_comma, specs_split_comma, is_int_literal_constant - -class AttributeHolder: - # copied from symbolic.base module - """ - Defines a object with predefined attributes. Only those attributes - are allowed that are specified as keyword arguments of a constructor. - When an argument is callable then the corresponding attribute will - be read-only and set by the value the callable object returns. - """ - def __init__(self, **kws): - self._attributes = {} - self._readonly = [] - for k,v in kws.items(): - self._attributes[k] = v - if callable(v): - self._readonly.append(k) - return - - def __getattr__(self, name): - if name not in self._attributes: - raise AttributeError,'%s instance has no attribute %r, '\ - 'expected attributes: %s' \ - % (self.__class__.__name__,name, - ','.join(self._attributes.keys())) - value = self._attributes[name] - if callable(value): - value = value() - self._attributes[name] = value - return value - - def __setattr__(self, name, value): - if name in ['_attributes','_readonly']: - self.__dict__[name] = value - return - if name in self._readonly: - raise AttributeError,'%s instance attribute %r is readonly' \ - % (self.__class__.__name__, name) - if name not in self._attributes: - raise AttributeError,'%s instance has no attribute %r, '\ - 'expected attributes: %s' \ - % (self.__class__.__name__,name,','.join(self._attributes.keys())) - self._attributes[name] = value - - def isempty(self): - for k in self._attributes.keys(): - v = getattr(self,k) - if v: return False - return True - - def __repr__(self): return self.torepr() - - def torepr(self, depth=-1, tab = ''): - if depth==0: return tab + self.__class__.__name__ - l = [self.__class__.__name__+':'] - ttab = tab + ' ' - for k in self._attributes.keys(): - v = getattr(self,k) - if v: - if isinstance(v,list): - l.append(ttab + '%s=<%s-list>' % (k,len(v))) - elif isinstance(v,dict): - l.append(ttab + '%s=<dict with keys %s>' % (k,v.keys())) - else: - l.append(ttab + '%s=<%s>' % (k,type(v))) - return '\n'.join(l) - - def todict(self): - d = {} - for k in self._attributes.keys(): - v = getattr(self, k) - d[k] = v - return d - -def get_base_classes(cls): - bases = () - for c in cls.__bases__: - bases += get_base_classes(c) - return bases + cls.__bases__ + (cls,) - -class Variable: - """ - Variable instance has attributes: - name - typedecl - dimension - attributes - intent - parent - Statement instances defining the variable - """ - def __init__(self, parent, name): - self.parent = parent - self.parents = [parent] - self.name = name - self.typedecl = None - self.dimension = None - self.bounds = None - self.length = None - self.attributes = [] - self.intent = None - self.bind = [] - self.check = [] - self.init = None - - # after calling analyze the following additional attributes are set: - # .is_array: - # rank - # shape - return - - def __repr__(self): - l = [] - for a in ['name','typedecl','dimension','bounds','length','attributes','intent','bind','check','init']: - v = getattr(self,a) - if v: - l.append('%s=%r' % (a,v)) - return 'Variable: ' + ', '.join(l) - - def get_bit_size(self): - typesize = self.typedecl.get_bit_size() - if self.is_pointer(): - # The size of pointer descriptor is compiler version dependent. Read: - # http://www.nersc.gov/vendor_docs/intel/f_ug1/pgwarray.htm - # https://www.cca-forum.org/pipermail/cca-fortran/2003-February/000123.html - # https://www.cca-forum.org/pipermail/cca-fortran/2003-February/000122.html - # On sgi descriptor size may be 128+ bits! - if self.is_array(): - wordsize = 4 # XXX: on a 64-bit system it is 8. - rank = len(self.bounds or self.dimension) - return 6 * wordsize + 12 * rank - return typesize - if self.is_array(): - size = reduce(lambda x,y:x*y,self.bounds or self.dimension,1) - if self.length: - size *= self.length - return size * typesize - if self.length: - return self.length * typesize - return typesize - - def get_typedecl(self): - if self.typedecl is None: - self.set_type(self.parent.get_type(self.name)) - return self.typedecl - - def add_parent(self, parent): - if id(parent) not in map(id, self.parents): - self.parents.append(parent) - self.parent = parent - return - - def set_type(self, typedecl): - if self.typedecl is not None: - if not self.typedecl==typedecl: - self.parent.warning(\ - 'variable %r already has type %s,'\ - ' resetting to %s' \ - % (self.name, self.typedecl.tostr(),typedecl.tostr())) - assert typedecl is not None - self.typedecl = typedecl - return - - def set_init(self, expr): - if self.init is not None: - if not self.init==expr: - self.parent.warning(\ - 'variable %r already has initialization %r, '\ - ' resetting to %r' % (self.name, self.expr, expr)) - self.init = expr - return - - def set_dimension(self, dims): - if self.dimension is not None: - if not self.dimension==dims: - self.parent.warning(\ - 'variable %r already has dimension %r, '\ - ' resetting to %r' % (self.name, self.dimension, dims)) - self.dimension = dims - return - - def set_bounds(self, bounds): - if self.bounds is not None: - if not self.bounds==bounds: - self.parent.warning(\ - 'variable %r already has bounds %r, '\ - ' resetting to %r' % (self.name, self.bounds, bounds)) - self.bounds = bounds - return - - def set_length(self, length): - if self.length is not None: - if not self.length==length: - self.parent.warning(\ - 'variable %r already has length %r, '\ - ' resetting to %r' % (self.name, self.length, length)) - self.length = length - return - - known_intent_specs = ['IN','OUT','INOUT','CACHE','HIDE', 'COPY', - 'OVERWRITE', 'CALLBACK', 'AUX', 'C', 'INPLACE', - 'OUT='] - - def set_intent(self, intent): - if self.intent is None: - self.intent = [] - for i in intent: - if i not in self.intent: - if i not in self.known_intent_specs: - self.parent.warning('unknown intent-spec %r for %r'\ - % (i, self.name)) - self.intent.append(i) - return - - known_attributes = ['PUBLIC', 'PRIVATE', 'ALLOCATABLE', 'ASYNCHRONOUS', - 'EXTERNAL', 'INTRINSIC', 'OPTIONAL', 'PARAMETER', - 'POINTER', 'PROTECTED', 'SAVE', 'TARGET', 'VALUE', - 'VOLATILE', 'REQUIRED'] - - def is_intent_in(self): - if not self.intent: return True - if 'HIDE' in self.intent: return False - if 'INPLACE' in self.intent: return False - if 'IN' in self.intent: return True - if 'OUT' in self.intent: return False - if 'INOUT' in self.intent: return False - if 'OUTIN' in self.intent: return False - return True - - def is_intent_inout(self): - if not self.intent: return False - if 'INOUT' in self.intent: - if 'IN' in self.intent or 'HIDE' in self.intent or 'INPLACE' in self.intent: - self.warning('INOUT ignored in INPUT(%s)' % (', '.join(self.intent))) - return False - return True - return False - - def is_intent_hide(self): - if not self.intent: return False - if 'HIDE' in self.intent: return True - if 'OUT' in self.intent: - return 'IN' not in self.intent and 'INPLACE' not in self.intent and 'INOUT' not in self.intent - return False - - def is_intent_inplace(self): return self.intent and 'INPLACE' in self.intent - def is_intent_out(self): return self.intent and 'OUT' in self.intent - def is_intent_c(self): return self.intent and 'C' in self.intent - def is_intent_cache(self): return self.intent and 'CACHE' in self.intent - def is_intent_copy(self): return self.intent and 'COPY' in self.intent - def is_intent_overwrite(self): return self.intent and 'OVERWRITE' in self.intent - def is_intent_callback(self): return self.intent and 'CALLBACK' in self.intent - def is_intent_aux(self): return self.intent and 'AUX' in self.intent - - def is_private(self): - if 'PUBLIC' in self.attributes: return False - if 'PRIVATE' in self.attributes: return True - parent_attrs = self.parent.parent.a.attributes - if 'PUBLIC' in parent_attrs: return False - if 'PRIVATE' in parent_attrs: return True - return - def is_public(self): return not self.is_private() - - def is_allocatable(self): return 'ALLOCATABLE' in self.attributes - def is_external(self): return 'EXTERNAL' in self.attributes - def is_intrinsic(self): return 'INTRINSIC' in self.attributes - def is_parameter(self): return 'PARAMETER' in self.attributes - def is_optional(self): return 'OPTIONAL' in self.attributes and 'REQUIRED' not in self.attributes and not self.is_intent_hide() - def is_required(self): return self.is_optional() and not self.is_intent_hide() - def is_pointer(self): return 'POINTER' in self.attributes - - def is_array(self): return not not (self.bounds or self.dimension) - def is_scalar(self): return not self.is_array() - - def update(self, *attrs): - attributes = self.attributes - if len(attrs)==1 and isinstance(attrs[0],(tuple,list)): - attrs = attrs[0] - for attr in attrs: - lattr = attr.lower() - uattr = attr.upper() - if lattr.startswith('dimension'): - assert self.dimension is None, `self.dimension,attr` - l = attr[9:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.set_dimension(split_comma(l[1:-1].strip(), self.parent.item)) - continue - if lattr.startswith('intent'): - l = attr[6:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.set_intent(specs_split_comma(l[1:-1].strip(), - self.parent.item, upper=True)) - continue - if lattr.startswith('bind'): - l = attr[4:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.bind = specs_split_comma(l[1:-1].strip(), self.parent.item, - upper = True) - continue - if lattr.startswith('check'): - l = attr[5:].lstrip() - assert l[0]+l[-1]=='()',`l` - self.check.extend(split_comma(l[1:-1].strip()), self.parent.item) - continue - if uattr not in attributes: - if uattr not in self.known_attributes: - self.parent.warning('unknown attribute %r' % (attr)) - attributes.append(uattr) - return - - def __str__(self): - s = '' - typedecl = self.get_typedecl() - if typedecl is not None: - s += typedecl.tostr() + ' ' - a = self.attributes[:] - if self.dimension is not None: - a.append('DIMENSION(%s)' % (', '.join(self.dimension))) - if self.intent is not None: - a.append('INTENT(%s)' % (', '.join(self.intent))) - if self.bind: - a.append('BIND(%s)' % (', '.join(self.bind))) - if self.check: - a.append('CHECK(%s)' % (', '.join(self.check))) - if a: - s += ', ' + ', '.join(a) + ' :: ' - s += self.name - if self.bounds: - s += '(%s)' % (', '.join([':'.join(spec) for spec in self.bounds])) - if self.length: - if is_int_literal_constant(self.length): - s += '*%s' % (self.length) - else: - s += '*(%s)' % (self.length) - if self.init: - s += ' = ' + self.init - return s - - def get_array_spec(self): - assert self.is_array(),'array_spec is available only for arrays' - if self.bounds: - if self.dimension: - self.parent.warning('both bounds=%r and dimension=%r are defined, ignoring dimension.' % (self.bounds, self.dimension)) - array_spec = self.bounds - else: - array_spec = self.dimension - return array_spec - - def is_deferred_shape_array(self): - if not self.is_array(): return False - return self.is_allocatable() or self.is_pointer() - - def is_assumed_size_array(self): - if not self.is_array(): return False - return self.get_array_spec()[-1][-1]=='*' - - def is_assumed_shape_array(self): - if not self.is_array(): return False - if self.is_deferred_shape_array(): return False - for spec in self.get_array_spec(): - if not spec[-1]: return True - return False - - def is_explicit_shape_array(self): - if not self.is_array(): return False - if self.is_deferred_shape_array(): return False - for spec in self.get_array_spec(): - if not spec[-1] or spec[-1] == '*': return False - return True - - def is_allocatable_array(self): - return self.is_array() and self.is_allocatable() - - def is_array_pointer(self): - return self.is_array() and self.is_pointer() - - def analyze(self): - typedecl = self.get_typedecl() - if self.is_array(): - array_spec = self.get_array_spec() - self.rank = len(array_spec) - if self.is_deferred_shape_array(): # a(:,:) - pass - elif self.is_explicit_shape_array(): - shape = [] - for spec in array_spec: - if len(spec)==1: - shape.append(spec[0]) - else: - shape.append(spec[1]-spec[0]) - self.shape = shape - return - -class ProgramBlock: - pass - -class Statement: - """ - Statement instance has attributes: - parent - Parent BeginStatement or FortranParser instance - item - Line instance containing the statement line - isvalid - boolean, when False, the Statement instance will be ignored - """ - modes = ['free90','fix90','fix77','pyf'] - _repr_attr_names = [] - - def __init__(self, parent, item): - self.parent = parent - if item is not None: - self.reader = item.reader - else: - self.reader = parent.reader - self.top = getattr(parent,'top',None) # the top of statement tree - self.item = item - - if isinstance(parent, ProgramBlock): - self.programblock = parent - elif isinstance(self, ProgramBlock): - self.programblock = self - elif hasattr(parent,'programblock'): - self.programblock = parent.programblock - else: - #self.warning('%s.programblock attribute not set.' % (self.__class__.__name__)) - pass - - # when a statement instance is constructed by error, set isvalid to False - self.isvalid = True - # when a statement should be ignored, set ignore to True - self.ignore = False - - # attribute a will hold analyze information. - a_dict = {} - for cls in get_base_classes(self.__class__): - if hasattr(cls,'a'): - a_dict.update(copy.deepcopy(cls.a.todict())) - self.a = AttributeHolder(**a_dict) - if hasattr(self.__class__,'a'): - assert self.a is not self.__class__.a - - self.process_item() - - return - - def __repr__(self): - return self.torepr() - - def torepr(self, depth=-1,incrtab=''): - tab = incrtab + self.get_indent_tab() - clsname = self.__class__.__name__ - l = [tab + yellow_text(clsname)] - if depth==0: - return '\n'.join(l) - ttab = tab + ' ' - for n in self._repr_attr_names: - attr = getattr(self, n, None) - if not attr: continue - if hasattr(attr, 'torepr'): - r = attr.torepr(depth-1,incrtab) - else: - r = repr(attr) - l.append(ttab + '%s=%s' % (n, r)) - if self.item is not None: l.append(ttab + 'item=%r' % (self.item)) - if not self.isvalid: l.append(ttab + 'isvalid=%r' % (self.isvalid)) - if self.ignore: l.append(ttab + 'ignore=%r' % (self.ignore)) - if not self.a.isempty(): - l.append(ttab + 'a=' + self.a.torepr(depth-1,incrtab+' ').lstrip()) - return '\n'.join(l) - - def get_indent_tab(self,colon=None,deindent=False,isfix=None): - if isfix is None: isfix = self.reader.isfix - if isfix: - tab = ' '*6 - else: - tab = '' - p = self.parent - while isinstance(p, Statement): - tab += ' ' - p = p.parent - if deindent: - tab = tab[:-2] - if self.item is None: - return tab - s = self.item.label - if colon is None: - if isfix: - colon = '' - else: - colon = ':' - if s: - c = '' - if isfix: - c = ' ' - tab = tab[len(c+s)+len(colon):] - if not tab: tab = ' ' - tab = c + s + colon + tab - return tab - - def __str__(self): - return self.tofortran() - - def asfix(self): - lines = [] - for line in self.tofortran(isfix=True).split('\n'): - if len(line)>72 and line[0]==' ': - lines.append(line[:72]+'&\n &') - line = line[72:] - while len(line)>66: - lines.append(line[:66]+'&\n &') - line = line[66:] - lines.append(line+'\n') - else: lines.append(line+'\n') - return ''.join(lines).replace('\n &\n','\n') - - def format_message(self, kind, message): - if self.item is not None: - message = self.reader.format_message(kind, message, - self.item.span[0], self.item.span[1]) - else: - return message - return message - - def show_message(self, message, stream=sys.stderr): - print >> stream, message - stream.flush() - return - - def error(self, message): - message = self.format_message('ERROR', red_text(message)) - self.show_message(message) - return - - def warning(self, message): - message = self.format_message('WARNING', yellow_text(message)) - self.show_message(message) - return - - def info(self, message): - message = self.format_message('INFO', message) - self.show_message(message) - return - - def analyze(self): - self.warning('nothing analyzed') - return - - def get_variable(self, name): - """ Return Variable instance of variable name. - """ - mth = getattr(self,'get_variable_by_name', self.parent.get_variable) - return mth(name) - - def get_type(self, name): - """ Return type declaration using implicit rules - for name. - """ - mth = getattr(self,'get_type_by_name', self.parent.get_type) - return mth(name) - - def get_type_decl(self, kind): - mth = getattr(self,'get_type_decl_by_kind', self.parent.get_type_decl) - return mth(kind) - - def get_provides(self): - """ Returns dictonary containing statements that block provides or None when N/A. - """ - return - -class BeginStatement(Statement): - """ <blocktype> <name> - - BeginStatement instances have additional attributes: - name - blocktype - - Block instance has attributes: - content - list of Line or Statement instances - name - name of the block, unnamed blocks are named - with the line label - parent - Block or FortranParser instance - item - Line instance containing the block start statement - get_item, put_item - methods to retrive/submit Line instances - from/to Fortran reader. - isvalid - boolean, when False, the Block instance will be ignored. - - stmt_cls, end_stmt_cls - - """ - _repr_attr_names = ['blocktype','name'] + Statement._repr_attr_names - def __init__(self, parent, item=None): - - self.content = [] - self.get_item = parent.get_item # get line function - self.put_item = parent.put_item # put line function - if not hasattr(self, 'blocktype'): - self.blocktype = self.__class__.__name__.lower() - if not hasattr(self, 'name'): - # process_item may change this - self.name = '__'+self.blocktype.upper()+'__' - Statement.__init__(self, parent, item) - return - - def tostr(self): - return self.blocktype.upper() + ' '+ self.name - - def tofortran(self, isfix=None): - l=[self.get_indent_tab(colon=':', isfix=isfix) + self.tostr()] - for c in self.content: - l.append(c.tofortran(isfix=isfix)) - return '\n'.join(l) - - def torepr(self, depth=-1, incrtab=''): - tab = incrtab + self.get_indent_tab() - ttab = tab + ' ' - l=[Statement.torepr(self, depth=depth,incrtab=incrtab)] - if depth==0 or not self.content: - return '\n'.join(l) - l.append(ttab+'content:') - for c in self.content: - if isinstance(c,EndStatement): - l.append(c.torepr(depth-1,incrtab)) - else: - l.append(c.torepr(depth-1,incrtab + ' ')) - return '\n'.join(l) - - def process_item(self): - """ Process the line - """ - item = self.item - if item is None: return - self.fill() - return - - def fill(self, end_flag = False): - """ - Fills blocks content until the end of block statement. - """ - - mode = self.reader.mode - classes = self.get_classes() - self.classes = [cls for cls in classes if mode in cls.modes] - self.pyf_classes = [cls for cls in classes if 'pyf' in cls.modes] - - item = self.get_item() - while item is not None: - if isinstance(item, Line): - if self.process_subitem(item): - end_flag = True - break - item = self.get_item() - - if not end_flag: - self.warning('failed to find the end of block') - return - - def process_subitem(self, item): - """ - Check is item is blocks start statement, if it is, read the block. - - Return True to stop adding items to given block. - """ - line = item.get_line() - - # First check for the end of block - cls = self.end_stmt_cls - if cls.match(line): - stmt = cls(self, item) - if stmt.isvalid: - self.content.append(stmt) - return True - - if item.is_f2py_directive: - classes = self.pyf_classes - else: - classes = self.classes - - # Look for statement match - for cls in classes: - if cls.match(line): - stmt = cls(self, item) - if stmt.isvalid: - if not stmt.ignore: - self.content.append(stmt) - return False - # item may be cloned that changes the items line: - line = item.get_line() - - # Check if f77 code contains inline comments or other f90 - # constructs that got undetected by get_source_info. - if item.reader.isfix77: - i = line.find('!') - if i != -1: - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block'\ - ' maybe due to inline comment.'\ - ' Trying to remove the comment.'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - # .. but at the expense of loosing the comment. - self.show_message(message) - newitem = item.copy(line[:i].rstrip()) - return self.process_subitem(newitem) - - # try fix90 statement classes - f77_classes = self.classes - classes = [] - for cls in self.get_classes(): - if 'fix90' in cls.modes and cls not in f77_classes: - classes.append(cls) - if classes: - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block'\ - ' maybe due to strict f77 mode.'\ - ' Trying f90 fix mode patterns..'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - self.show_message(message) - - item.reader.set_mode(False, False) - self.classes = classes - - r = BeginStatement.process_subitem(self, item) - if r is None: - # restore f77 fix mode - self.classes = f77_classes - item.reader.set_mode(False, True) - else: - message = item.reader.format_message(\ - 'INFORMATION', - 'The f90 fix mode resolved the parse pattern issue.'\ - ' Setting reader to f90 fix mode.', - item.span[0], item.span[1]) - self.show_message(message) - # set f90 fix mode - self.classes = f77_classes + classes - self.reader.set_mode(False, False) - return r - - self.handle_unknown_item(item) - return - - def handle_unknown_item(self, item): - message = item.reader.format_message(\ - 'WARNING', - 'no parse pattern found for "%s" in %r block.'\ - % (item.get_line(),self.__class__.__name__), - item.span[0], item.span[1]) - self.show_message(message) - self.content.append(item) - #sys.exit() - return - - def analyze(self): - for stmt in self.content: - stmt.analyze() - return - -class EndStatement(Statement): - """ - END [<blocktype> [<name>]] - - EndStatement instances have additional attributes: - name - blocktype - """ - _repr_attr_names = ['blocktype','name'] + Statement._repr_attr_names - - def __init__(self, parent, item): - if not hasattr(self, 'blocktype'): - self.blocktype = self.__class__.__name__.lower()[3:] - Statement.__init__(self, parent, item) - - def process_item(self): - item = self.item - line = item.get_line().replace(' ','')[3:] - blocktype = self.blocktype - if line.lower().startswith(blocktype): - line = line[len(blocktype):].strip() - else: - if line: - # not the end of expected block - line = '' - self.isvalid = False - if line: - if not line==self.parent.name: - self.warning(\ - 'expected the end of %r block but got the end of %r, skipping.'\ - % (self.parent.name, line)) - self.isvalid = False - self.name = self.parent.name - - def analyze(self): - return - - def get_indent_tab(self,colon=None,deindent=False,isfix=None): - return Statement.get_indent_tab(self, colon=colon, deindent=True,isfix=isfix) - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'END %s %s'\ - % (self.blocktype.upper(),self.name or '') diff --git a/numpy/f2py/lib/parser/block_statements.py b/numpy/f2py/lib/parser/block_statements.py deleted file mode 100644 index 734ce2bb4..000000000 --- a/numpy/f2py/lib/parser/block_statements.py +++ /dev/null @@ -1,1229 +0,0 @@ -""" -Fortran block statements. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['BeginSource','Module','PythonModule','Program','BlockData','Interface', - 'Subroutine','Function','Select','WhereConstruct','ForallConstruct', - 'IfThen','If','Do','Associate','TypeDecl','Enum', - 'EndSource','EndModule','EndPythonModule','EndProgram','EndBlockData','EndInterface', - 'EndSubroutine','EndFunction','EndSelect','EndWhere','EndForall', - 'EndIfThen','EndDo','EndAssociate','EndType','EndEnum', - ] - -import re -import sys - -from base_classes import BeginStatement, EndStatement, Statement,\ - AttributeHolder, ProgramBlock, Variable -from readfortran import Line -from utils import filter_stmts, parse_bind, parse_result, AnalyzeError, is_name - -class HasImplicitStmt: - - a = AttributeHolder(implicit_rules = {}) - - def get_type_by_name(self, name): - implicit_rules = self.a.implicit_rules - if implicit_rules is None: - raise AnalyzeError,'Implicit rules mapping is null while getting %r type' % (name) - l = name[0].lower() - if l in implicit_rules: - return implicit_rules[l] - # default rules: - if l in 'ijklmn': - l = 'default_integer' - else: - l = 'default_real' - t = implicit_rules.get(l, None) - if t is None: - if l[8:]=='real': - implicit_rules[l] = t = Real(self, self.item.copy('real')) - else: - implicit_rules[l] = t = Integer(self, self.item.copy('integer')) - return t - - def topyf(self, tab=' '): - implicit_rules = self.a.implicit_rules - if implicit_rules is None: - return tab + 'IMPLICIT NONE\n' - items = {} - for c,t in implicit_rules.items(): - if c.startswith('default'): - continue - st = t.tostr() - if st in items: - items[st].append(c) - else: - items[st] = [c] - if not items: - return tab + '! default IMPLICIT rules apply\n' - s = 'IMPLICIT' - ls = [] - for st,l in items.items(): - l.sort() - ls.append(st + ' (%s)' % (', '.join(l))) - s += ' ' + ', '.join(ls) - return tab + s + '\n' - -class HasUseStmt: - - a = AttributeHolder(use = {}, - use_provides = {}) - - def get_entity(self, name): - for modname, modblock in self.top.a.module.items(): - for stmt in modblock.content: - if getattr(stmt,'name','') == name: - return stmt - return - - def topyf(self, tab=' '): - sys.stderr.write('HasUseStmt.topyf not implemented\n') - return '' - -class AccessSpecs: - - a = AttributeHolder(private_id_list = [], public_id_list = []) - - def topyf(self, tab=' '): - private_list = self.a.private_id_list - public_list = self.a.public_id_list - l = [] - if '' in private_list: l.append(tab + 'PRIVATE\n') - if '' in public_list: l.append(tab + 'PUBLIC\n') - for a in private_list: - if not a: continue - l.append(tab + 'PRIVATE :: %s\n' % (a)) - for a in public_list: - if not a: continue - l.append(tab + 'PUBLIC :: %s\n' % (a)) - return ''.join(l) - -class HasVariables: - - a = AttributeHolder(variables = {}, - variable_names = [] # defines the order of declarations - ) - - def get_variable_by_name(self, name): - variables = self.a.variables - if name in variables: - var = variables[name] - else: - var = variables[name] = Variable(self, name) - self.a.variable_names.append(name) - return var - - def topyf(self,tab='', only_variables = None): - s = '' - if only_variables is None: - only_variables = self.a.variables.keys() - for name in only_variables: - var = self.a.variables[name] - s += tab + str(var) + '\n' - return s - -class HasTypeDecls: - - a = AttributeHolder(type_decls = {}) - - def topyf(self, tab=''): - s = '' - for name, stmt in self.a.type_decls.items(): - s += stmt.topyf(tab=' '+tab) - return s - - def get_type_decl_by_kind(self, kind): - type_decls = self.a.type_decls - type_decl = type_decls.get(kind, None) - if type_decl is None: - return self.get_entity(kind) - return type_decl - -class HasAttributes: - - known_attributes = [] - a = AttributeHolder(attributes = []) - - def topyf(self, tab=''): - s = '' - for attr in self.a.attributes: - s += tab + attr + '\n' - return s - - def update_attributes(self,*attrs): - attributes = self.a.attributes - known_attributes = self.known_attributes - if len(attrs)==1 and isinstance(attrs[0],(tuple,list)): - attrs = attrs[0] - for attr in attrs: - uattr = attr.upper() - if uattr not in attributes: - if isinstance(known_attributes,(list, tuple)): - if uattr not in known_attributes: - self.warning('unknown attribute %r' % (attr)) - elif not known_attributes(uattr): - self.warning('unknown attribute %r' % (attr)) - attributes.append(uattr) - return - -class HasModuleProcedures: - - a = AttributeHolder(module_procedures = []) - -# File block - -class EndSource(EndStatement): - """ - Dummy End statement for BeginSource. - """ - match = staticmethod(lambda s: False) - -class BeginSource(BeginStatement): - """ - Fortran source content. - """ - match = staticmethod(lambda s: True) - end_stmt_cls = EndSource - a = AttributeHolder(module = {}, - external_subprogram = {}, - blockdata = {}, - ) - - def tostr(self): - return '!' + self.blocktype.upper() + ' '+ self.name - - def process_item(self): - self.name = self.reader.name - self.top = self - self.fill(end_flag = True) - return - - def analyze(self): - for stmt in self.content: - if isinstance(stmt, Module): - stmt.analyze() - self.a.module[stmt.name] = stmt - elif isinstance(stmt, SubProgramStatement): - stmt.analyze() - self.a.external_subprogram[stmt.name] = stmt - elif isinstance(stmt, BlockData): - stmt.analyze() - self.a.blockdata[stmt.name] = stmt - else: - stmt.analyze() - return - - def get_classes(self): - if self.reader.ispyf: - return [PythonModule] + program_unit - return program_unit - - def process_subitem(self, item): - # MAIN block does not define start/end line conditions, - # so it should never end until all lines are read. - # However, sometimes F77 programs lack the PROGRAM statement, - # and here we fix that: - if self.reader.isfix77: - line = item.get_line() - if line=='end': - message = item.reader.format_message(\ - 'WARNING', - 'assuming the end of undefined PROGRAM statement', - item.span[0],item.span[1]) - print >> sys.stderr, message - p = Program(self) - p.content.extend(self.content) - p.content.append(EndProgram(p,item)) - self.content[:] = [p] - return - return BeginStatement.process_subitem(self, item) - - def topyf(self, tab=''): # XXXX - s = '' - for name, stmt in self.a.module.items(): - s += stmt.topyf(tab=tab) - for name, stmt in self.a.external_subprogram.items(): - s += stmt.topyf(tab=tab) - for name, stmt in self.a.blockdata.items(): - s += stmt.topyf(tab=tab) - return s -# Module - -class EndModule(EndStatement): - match = re.compile(r'end(\s*module\s*\w*|)\Z', re.I).match - -class Module(BeginStatement, HasAttributes, - HasImplicitStmt, HasUseStmt, HasVariables, - HasTypeDecls, AccessSpecs): - """ - MODULE <name> - .. - END [MODULE [name]] - """ - match = re.compile(r'module\s*\w+\Z', re.I).match - end_stmt_cls = EndModule - - a = AttributeHolder(module_subprogram = {}, - module_provides = {}, # all symbols that are public and so - # can be imported via USE statement - # by other blocks - module_interface = {} - ) - - known_attributes = ['PUBLIC', 'PRIVATE'] - - def get_classes(self): - return access_spec + specification_part + module_subprogram_part - - def process_item(self): - name = self.item.get_line().replace(' ','')[len(self.blocktype):].strip() - self.name = name - return BeginStatement.process_item(self) - - def get_provides(self): - return self.a.module_provides - - def get_interface(self): - return self.a.module_interface - - def analyze(self): - content = self.content[:] - - while content: - stmt = content.pop(0) - if isinstance(stmt, Contains): - for stmt in filter_stmts(content, SubProgramStatement): - stmt.analyze() - self.a.module_subprogram[stmt.name] = stmt - stmt = content.pop(0) - assert isinstance(stmt, EndModule),`stmt` - continue - stmt.analyze() - - if content: - self.show_message('Not analyzed content: %s' % content) - - #module_provides = self.a.module_provides - #for name, var in self.a.variables.items(): - # if var.is_public(): - # if name in module_provides: - # self.warning('module data object name conflict with %s, overriding.' % (name)) - # module_provides[name] = var - - return - - def topyf(self, tab=''): - s = tab + 'MODULE '+self.name + '\n' - s += HasImplicitStmt.topyf(self, tab=tab+' ') - s += AccessSpecs.topyf(self, tab=tab+' ') - s += HasAttributes.topyf(self, tab=tab+' ') - s += HasTypeDecls.topyf(self, tab=tab+' ') - s += HasVariables.topyf(self, tab=tab+' ') - for name, stmt in self.a.module_interface.items(): - s += stmt.topyf(tab=tab+' ') - s += tab + ' CONTAINS\n' - for name, stmt in self.a.module_subprogram.items(): - s += stmt.topyf(tab=tab+' ') - s += tab + 'END MODULE ' + self.name + '\n' - return s - -# Python Module - -class EndPythonModule(EndStatement): - match = re.compile(r'end(\s*python\s*module\s*\w*|)\Z', re.I).match - -class PythonModule(BeginStatement, HasImplicitStmt, HasUseStmt): - """ - PYTHON MODULE <name> - .. - END [PYTHON MODULE [name]] - """ - modes = ['pyf'] - match = re.compile(r'python\s*module\s*\w+\Z', re.I).match - end_stmt_cls = EndPythonModule - - def get_classes(self): - return [Interface, Function, Subroutine, Module] - - def process_item(self): - self.name = self.item.get_line().replace(' ','')\ - [len(self.blocktype):].strip() - return BeginStatement.process_item(self) - -# Program - -class EndProgram(EndStatement): - """ - END [PROGRAM [name]] - """ - match = re.compile(r'end(\s*program\s*\w*|)\Z', re.I).match - -class Program(BeginStatement, ProgramBlock, - #HasAttributes, # XXX: why Program needs .attributes? - HasImplicitStmt, HasUseStmt, AccessSpecs): - """ PROGRAM [name] - """ - match = re.compile(r'program\s*\w*\Z', re.I).match - end_stmt_cls = EndProgram - - def get_classes(self): - return specification_part + execution_part + internal_subprogram_part - - def process_item(self): - if self.item is not None: - name = self.item.get_line().replace(' ','')\ - [len(self.blocktype):].strip() - if name: - self.name = name - return BeginStatement.process_item(self) - -# BlockData - -class EndBlockData(EndStatement): - """ - END [ BLOCK DATA [ <block-data-name> ] ] - """ - match = re.compile(r'end(\s*block\s*data\s*\w*|)\Z', re.I).match - blocktype = 'blockdata' - -class BlockData(BeginStatement, HasImplicitStmt, HasUseStmt, - HasVariables, AccessSpecs): - """ - BLOCK DATA [ <block-data-name> ] - """ - end_stmt_cls = EndBlockData - match = re.compile(r'block\s*data\s*\w*\Z', re.I).match - - def process_item(self): - self.name = self.item.get_line()[5:].lstrip()[4:].lstrip() - return BeginStatement.process_item(self) - - def get_classes(self): - return specification_part - -# Interface - -class EndInterface(EndStatement): - match = re.compile(r'end\s*interface\s*\w*\Z', re.I).match - blocktype = 'interface' - -class Interface(BeginStatement, HasAttributes, HasImplicitStmt, HasUseStmt, - HasModuleProcedures, AccessSpecs - ): - """ - INTERFACE [<generic-spec>] | ABSTRACT INTERFACE - END INTERFACE [<generic-spec>] - - <generic-spec> = <generic-name> - | OPERATOR ( <defined-operator> ) - | ASSIGNMENT ( = ) - | <dtio-generic-spec> - <dtio-generic-spec> = READ ( FORMATTED ) - | READ ( UNFORMATTED ) - | WRITE ( FORMATTED ) - | WRITE ( UNFORMATTED ) - - """ - modes = ['free90', 'fix90', 'pyf'] - match = re.compile(r'(interface\s*(\w+\s*\(.*\)|\w*)|abstract\s*interface)\Z',re.I).match - end_stmt_cls = EndInterface - blocktype = 'interface' - - a = AttributeHolder(interface_provides = {}) - - def get_classes(self): - l = intrinsic_type_spec + interface_specification - if self.reader.mode=='pyf': - return [Subroutine, Function] + l - return l - - def process_item(self): - line = self.item.get_line() - self.isabstract = line.startswith('abstract') - if self.isabstract: - self.generic_spec = '' - else: - self.generic_spec = line[len(self.blocktype):].strip() - self.name = self.generic_spec # XXX - return BeginStatement.process_item(self) - - def tostr(self): - if self.isabstract: - return 'ABSTRACT INTERFACE' - return 'INTERFACE '+ str(self.generic_spec) - - #def get_provides(self): - # return self.a.interface_provides - - def analyze(self): - content = self.content[:] - - while content: - stmt = content.pop(0) - if isinstance(stmt, self.end_stmt_cls): - break - stmt.analyze() - #assert isinstance(stmt, SubProgramStatement),`stmt.__class__.__name__` - if content: - self.show_message('Not analyzed content: %s' % content) - - if self.name in self.parent.a.variables: - var = self.parent.a.variables.pop(self.name) - self.update_attributes(var.attributes) - - parent_interface = self.parent.get_interface() - if self.name in parent_interface: - p = parent_interface[self.name] - last = p.content.pop() - assert isinstance(last,EndInterface),`last.__class__` - p.content += self.content - p.update_attributes(self.a.attributes) - else: - parent_interface[self.name] = self - return - - def topyf(self, tab=''): - s = tab + self.tostr() + '\n' - s += HasImplicitStmt.topyf(self, tab=tab+' ') - s += HasAttributes.topyf(self, tab=tab+' ') - s += HasUseStmt.topyf(self, tab=tab+' ') - s += tab + 'END' + self.tostr() + '\n' - return s - -# Subroutine - -class SubProgramStatement(BeginStatement, ProgramBlock, - HasImplicitStmt, HasAttributes, - HasUseStmt, - HasVariables, HasTypeDecls, AccessSpecs - ): - """ - [ <prefix> ] <FUNCTION|SUBROUTINE> <name> [ ( <args> ) ] [ <suffix> ] - """ - - a = AttributeHolder(internal_subprogram = {}) - - def process_item(self): - clsname = self.__class__.__name__.lower() - item = self.item - line = item.get_line() - m = self.match(line) - i = line.lower().find(clsname) - assert i!=-1,`clsname, line` - self.prefix = line[:i].rstrip() - self.name = line[i:m.end()].lstrip()[len(clsname):].strip() - line = line[m.end():].lstrip() - args = [] - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - line2 = item.apply_map(line[:i+1]) - for a in line2[1:-1].split(','): - a=a.strip() - if not a: continue - args.append(a) - line = line[i+1:].lstrip() - suffix = item.apply_map(line) - self.bind, suffix = parse_bind(suffix, item) - self.result = None - if isinstance(self, Function): - self.result, suffix = parse_result(suffix, item) - if suffix: - assert self.bind is None,`self.bind` - self.bind, suffix = parse_result(suffix, item) - if self.result is None: - self.result = self.name - assert not suffix,`suffix` - self.args = args - self.typedecl = None - return BeginStatement.process_item(self) - - def tostr(self): - clsname = self.__class__.__name__.upper() - s = '' - if self.prefix: - s += self.prefix + ' ' - if self.typedecl is not None: - assert isinstance(self, Function),`self.__class__.__name__` - s += self.typedecl.tostr() + ' ' - s += clsname - suf = '' - if self.result and self.result!=self.name: - suf += ' RESULT ( %s )' % (self.result) - if self.bind: - suf += ' BIND ( %s )' % (', '.join(self.bind)) - return '%s %s(%s)%s' % (s, self.name,', '.join(self.args),suf) - - def get_classes(self): - return f2py_stmt + specification_part + execution_part \ - + internal_subprogram_part - - def analyze(self): - content = self.content[:] - - if self.prefix: - self.update_attributes(prefix.upper().split()) - - variables = self.a.variables - for a in self.args: - assert a not in variables - assert is_name(a) - variables[a] = Variable(self, a) - - if isinstance(self, Function): - var = variables[self.result] = Variable(self, self.result) - if self.typedecl is not None: - var.set_type(self.typedecl) - - while content: - stmt = content.pop(0) - if isinstance(stmt, Contains): - for stmt in filter_stmts(content, SubProgramStatement): - stmt.analyze() - self.a.internal_subprogram[stmt.name] = stmt - stmt = content.pop(0) - assert isinstance(stmt, self.end_stmt_cls),`stmt` - elif isinstance(stmt, self.end_stmt_cls): - continue - else: - stmt.analyze() - - if content: - self.show_message('Not analyzed content: %s' % content) - - #parent_provides = self.parent.get_provides() - #if parent_provides is not None: - # if self.is_public(): - # if self.name in parent_provides: - # self.warning('module subprogram name conflict with %s, overriding.' % (self.name)) - # parent_provides[self.name] = self - - return - - def topyf(self, tab=''): - s = tab + self.__class__.__name__.upper() - s += ' ' + self.name + ' (%s)' % (', '.join(self.args)) - if isinstance(self, Function) and self.result != self.name: - s += ' RESULT (%s)' % (self.result) - s += '\n' - s += HasImplicitStmt.topyf(self, tab=tab+' ') - s += AccessSpecs.topyf(self, tab=tab+' ') - s += HasTypeDecls.topyf(self, tab=tab+' ') - s += HasVariables.topyf(self, tab=tab+' ', only_variables = self.args) - s += tab + 'END ' + self.__class__.__name__.upper() + ' ' + self.name + '\n' - return s - -class EndSubroutine(EndStatement): - """ - END [SUBROUTINE [name]] - """ - match = re.compile(r'end(\s*subroutine\s*\w*|)\Z', re.I).match - - -class Subroutine(SubProgramStatement): - """ - [ <prefix> ] SUBROUTINE <name> [ ( [ <dummy-arg-list> ] ) [ <proc-language-binding-spec> ]] - """ - end_stmt_cls = EndSubroutine - match = re.compile(r'(recursive|pure|elemental|\s)*subroutine\s*\w+', re.I).match - _repr_attr_names = ['prefix','bind','suffix','args'] + Statement._repr_attr_names - -# Function - -class EndFunction(EndStatement): - """ - END [FUNCTION [name]] - """ - match = re.compile(r'end(\s*function\s*\w*|)\Z', re.I).match - -class Function(SubProgramStatement): - """ - [ <prefix> ] FUNCTION <name> ( [<dummy-arg-list>] ) [<suffix>] - <prefix> = <prefix-spec> [ <prefix-spec> ]... - <prefix-spec> = <declaration-type-spec> - | RECURSIVE | PURE | ELEMENTAL - <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] - | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] - """ - end_stmt_cls = EndFunction - match = re.compile(r'(recursive|pure|elemental|\s)*function\s*\w+', re.I).match - _repr_attr_names = ['prefix','bind','suffix','args','typedecl'] + Statement._repr_attr_names - - def subroutine_wrapper_code(self): - name = 'f2pywrap_' + self.name - args = ['f2pyvalue_'+self.result] + self.args - var = self.a.variables[self.result] - typedecl = var.get_typedecl().astypedecl() - lines = [] - tab = ' '*6 - lines.append('%sSUBROUTINE %s(%s)' % (tab, name, ', '.join(args))) - if isinstance(self.parent,Module): - lines.append('%s USE %s' % (tab, self.parent.name)) - else: - if isinstance(typedecl, TypeStmt): - type_decl = typedecl.get_type_decl(typedecl.name) - if type_decl.parent is self: - for line in str(type_decl).split('\n'): - lines.append('%s %s' % (tab, line.lstrip())) - lines.append('%s EXTERNAL %s' % (tab, self.name)) - lines.append('%s %s %s' % (tab, str(typedecl).lstrip(), self.name)) - lines.append('%s %s %s' % (tab, str(typedecl).lstrip(), args[0])) - lines.append('!f2py intent(out) %s' % (args[0])) - for a in self.args: - v = self.a.variables[a] - lines.append('%s %s' % (tab, str(v).lstrip())) - lines.append('%s %s = %s(%s)' % (tab, args[0], self.name, ', '.join(self.args))) - #lines.append('%s print*,"%s=",%s' % (tab, args[0], args[0])) # debug line - lines.append('%sEND SUBROUTINE %s' % (tab, name)) - return '\n'.join(lines) - - def subroutine_wrapper(self): - code = self.subroutine_wrapper_code() - from api import parse - block = parse(code) # XXX: set include_dirs - while len(block.content)==1: - block = block.content[0] - return block - -# Handle subprogram prefixes - -class SubprogramPrefix(Statement): - """ - <prefix> <declaration-type-spec> <function|subroutine> ... - """ - match = re.compile(r'(pure|elemental|recursive|\s)+\b',re.I).match - def process_item(self): - line = self.item.get_line() - m = self.match(line) - prefix = line[:m.end()].rstrip() - rest = self.item.get_line()[m.end():].lstrip() - if rest: - self.parent.put_item(self.item.copy(prefix)) - self.item.clone(rest) - self.isvalid = False - return - if self.parent.__class__ not in [Function, Subroutine]: - self.isvalid = False - return - prefix = prefix + ' ' + self.parent.prefix - self.parent.prefix = prefix.strip() - self.ignore = True - return - -# SelectCase - -class EndSelect(EndStatement): - match = re.compile(r'end\s*select\s*\w*\Z', re.I).match - blocktype = 'select' - -class Select(BeginStatement): - """ - [ <case-construct-name> : ] SELECT CASE ( <case-expr> ) - - """ - match = re.compile(r'select\s*case\s*\(.*\)\Z',re.I).match - end_stmt_cls = EndSelect - name = '' - def tostr(self): - return 'SELECT CASE ( %s )' % (self.expr) - def process_item(self): - self.expr = self.item.get_line()[6:].lstrip()[4:].lstrip()[1:-1].strip() - self.name = self.item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Case] + execution_part_construct - -# Where - -class EndWhere(EndStatement): - """ - END WHERE [ <where-construct-name> ] - """ - match = re.compile(r'end\s*\where\s*\w*\Z',re.I).match - - -class Where(BeginStatement): - """ - [ <where-construct-name> : ] WHERE ( <mask-expr> ) - <mask-expr> = <logical-expr> - """ - match = re.compile(r'where\s*\([^)]*\)\Z',re.I).match - end_stmt_cls = EndWhere - name = '' - def tostr(self): - return 'WHERE ( %s )' % (self.expr) - def process_item(self): - self.expr = self.item.get_line()[5:].lstrip()[1:-1].strip() - self.name = self.item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Assignment, WhereStmt, - WhereConstruct, ElseWhere - ] - -WhereConstruct = Where - -# Forall - -class EndForall(EndStatement): - """ - END FORALL [ <forall-construct-name> ] - """ - match = re.compile(r'end\s*forall\s*\w*\Z',re.I).match - -class Forall(BeginStatement): - """ - [ <forall-construct-name> : ] FORALL <forall-header> - [ <forall-body-construct> ]... - <forall-body-construct> = <forall-assignment-stmt> - | <where-stmt> - | <where-construct> - | <forall-construct> - | <forall-stmt> - <forall-header> = ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) - <forall-triplet-spec> = <index-name> = <subscript> : <subscript> [ : <stride> ] - <subscript|stride> = <scalar-int-expr> - <forall-assignment-stmt> = <assignment-stmt> | <pointer-assignment-stmt> - """ - end_stmt_cls = EndForall - match = re.compile(r'forarr\s*\(.*\)\Z',re.I).match - name = '' - def process_item(self): - self.specs = self.item.get_line()[6:].lstrip()[1:-1].strip() - return BeginStatement.process_item(self) - def tostr(self): - return 'FORALL (%s)' % (self.specs) - def get_classes(self): - return [GeneralAssignment, WhereStmt, WhereConstruct, - ForallConstruct, ForallStmt] - -ForallConstruct = Forall - -# IfThen - -class EndIfThen(EndStatement): - """ - END IF [ <if-construct-name> ] - """ - match = re.compile(r'end\s*if\s*\w*\Z', re.I).match - blocktype = 'if' - -class IfThen(BeginStatement): - """ - [<if-construct-name> :] IF ( <scalar-logical-expr> ) THEN - - IfThen instance has the following attributes: - expr - """ - - match = re.compile(r'if\s*\(.*\)\s*then\Z',re.I).match - end_stmt_cls = EndIfThen - name = '' - - def tostr(self): - return 'IF (%s) THEN' % (self.expr) - - def process_item(self): - item = self.item - line = item.get_line()[2:-4].strip() - assert line[0]=='(' and line[-1]==')',`line` - self.expr = line[1:-1].strip() - self.name = item.label - return BeginStatement.process_item(self) - - def get_classes(self): - return [Else, ElseIf] + execution_part_construct - -class If(BeginStatement): - """ - IF ( <scalar-logical-expr> ) action-stmt - """ - - match = re.compile(r'if\s*\(',re.I).match - - def process_item(self): - item = self.item - mode = self.reader.mode - classes = self.get_classes() - classes = [cls for cls in classes if mode in cls.modes] - - line = item.get_line()[2:].lstrip() - i = line.find(')') - expr = line[1:i].strip() - line = line[i+1:].strip() - if line.lower()=='then': - self.isvalid = False - return - self.expr = item.apply_map(expr) - - if not line: - newitem = self.get_item() - else: - newitem = item.copy(line) - newline = newitem.get_line() - for cls in classes: - if cls.match(newline): - stmt = cls(self, newitem) - if stmt.isvalid: - self.content.append(stmt) - return - if not line: - self.put_item(newitem) - self.isvalid = False - return - - def tostr(self): - assert len(self.content)==1,`self.content` - return 'IF (%s) %s' % (self.expr, str(self.content[0]).lstrip()) - - def tofortran(self,isfix=None): - return self.get_indent_tab(colon=':',isfix=isfix) + self.tostr() - - def get_classes(self): - return action_stmt - -# Do - -class EndDo(EndStatement): - """ - END DO [ <do-construct-name> ] - """ - match = re.compile(r'end\s*do\s*\w*\Z', re.I).match - blocktype = 'do' - -class Do(BeginStatement): - """ - [ <do-construct-name> : ] DO label [loopcontrol] - [ <do-construct-name> : ] DO [loopcontrol] - - """ - - match = re.compile(r'do\b\s*\d*',re.I).match - item_re = re.compile(r'do\b\s*(?P<label>\d*)\s*,?\s*(?P<loopcontrol>.*)\Z',re.I).match - end_stmt_cls = EndDo - name = '' - - def tostr(self): - return 'DO %s %s' % (self.endlabel, self.loopcontrol) - - def process_item(self): - item = self.item - line = item.get_line() - m = self.item_re(line) - self.endlabel = m.group('label').strip() - self.name = item.label - self.loopcontrol = m.group('loopcontrol').strip() - return BeginStatement.process_item(self) - - def process_subitem(self, item): - r = False - if self.endlabel: - label = item.label - if label == self.endlabel: - r = True - if isinstance(self.parent, Do) and label==self.parent.endlabel: - # the same item label may be used for different block ends - self.put_item(item) - return BeginStatement.process_subitem(self, item) or r - - def get_classes(self): - return execution_part_construct - -# Associate - -class EndAssociate(EndStatement): - """ - END ASSOCIATE [ <associate-construct-name> ] - """ - match = re.compile(r'end\s*associate\s*\w*\Z',re.I).match - -class Associate(BeginStatement): - """ - [ <associate-construct-name> : ] ASSOCIATE ( <association-list> ) - <block> - - <association> = <associate-name> => <selector> - <selector> = <expr> | <variable> - """ - match = re.compile(r'associate\s*\(.*\)\Z',re.I).match - end_stmt_cls = EndAssociate - - def process_item(self): - line = self.item.get_line()[9:].lstrip() - self.associations = line[1:-1].strip() - return BeginStatement.process_item(self) - def tostr(self): - return 'ASSOCIATE (%s)' % (self.associations) - def get_classes(self): - return execution_part_construct - -# Type - -class EndType(EndStatement): - """ - END TYPE [<type-name>] - """ - match = re.compile(r'end\s*type\s*\w*\Z', re.I).match - blocktype = 'type' - -class Type(BeginStatement, HasVariables, HasAttributes, AccessSpecs): - """ - TYPE [ [ , <type-attr-spec-list>] :: ] <type-name> [ ( <type-param-name-list> ) ] - <type-attr-spec> = <access-spec> | EXTENDS ( <parent-type-name> ) - | ABSTRACT | BIND(C) - """ - match = re.compile(r'type\b\s*').match - end_stmt_cls = EndType - - a = AttributeHolder(extends = None, - parameters = {}, - component_names = [], # specifies component order for sequence types - components = {} - ) - known_attributes = re.compile(r'\A(PUBLIC|PRIVATE|SEQUENCE|ABSTRACT|BIND\s*\(.*\))\Z',re.I).match - - def process_item(self): - line = self.item.get_line()[4:].lstrip() - if line.startswith('('): - self.isvalid = False - return - specs = [] - i = line.find('::') - if i!=-1: - for s in line[:i].split(','): - s = s.strip() - if s: specs.append(s) - line = line[i+2:].lstrip() - self.specs = specs - i = line.find('(') - if i!=-1: - self.name = line[:i].rstrip() - assert line[-1]==')',`line` - self.params = split_comma(line[i+1:-1].lstrip()) - else: - self.name = line - self.params = [] - if not is_name(self.name): - self.isvalid = False - return - return BeginStatement.process_item(self) - - def tostr(self): - s = 'TYPE' - if self.specs: - s += ', '.join(['']+self.specs) + ' ::' - s += ' ' + self.name - if self.params: - s += ' ('+', '.join(self.params)+')' - return s - - def get_classes(self): - return [Integer] + private_or_sequence + component_part +\ - type_bound_procedure_part - - def analyze(self): - BeginStatement.analyze(self) - for spec in self.specs: - i = spec.find('(') - if i!=-1: - assert spec.endswith(')'),`spec` - s = spec[:i].rstrip().upper() - n = spec[i+1:-1].strip() - if s=='EXTENDS': - self.a.extends = n - continue - elif s=='BIND': - args,rest = parse_bind(spec) - assert not rest,`rest` - spec = 'BIND(%s)' % (', '.join(args)) - else: - spec = '%s(%s)' % (s,n) - else: - spec = spec.upper() - self.update_attributes(spec) - - component_names = self.a.component_names - content = self.content[:] - while content: - stmt = content.pop(0) - if isinstance(stmt, self.end_stmt_cls): - break - stmt.analyze() - - if content: - self.show_message('Not analyzed content: %s' % content) - - parameters = self.a.parameters - components = self.a.components - component_names = self.a.component_names - for name in self.a.variable_names: - var = self.a.variables[name] - if name in self.params: - parameters[name] = var - else: - component_names.append(name) - components[name] = var - - self.parent.a.type_decls[self.name] = self - - #parent_provides = self.parent.get_provides() - #if parent_provides is not None: - # if self.is_public(): - # if self.name in parent_provides: - # self.warning('type declaration name conflict with %s, overriding.' % (self.name)) - # parent_provides[self.name] = self - - return - - def topyf(self, tab=''): - s = tab + 'TYPE' - if self.a.extends is not None: - s += ', EXTENDS(%s) ::' % (self.a.extends) - s += ' ' + self.name - if self.a.parameters: - s += ' (%s)' % (', '.join(self.a.parameters)) - s += '\n' - s += AccessSpecs.topyf(self, tab=tab+' ') - s += HasAttributes.topyf(self, tab=tab+' ') - s += HasVariables.topyf(self, tab=tab+' ') - s += tab + 'END TYPE ' + self.name + '\n' - return s - - # Wrapper methods: - - def get_bit_size(self, _cache={}): - try: - return _cache[id(self)] - except KeyError: - s = 0 - for name,var in self.a.components.items(): - s += var.get_bit_size() - _cache[id(self)] = s - return s - -TypeDecl = Type - -# Enum - -class EndEnum(EndStatement): - """ - END ENUM - """ - match = re.compile(r'end\s*enum\Z',re.I).match - blocktype = 'enum' - -class Enum(BeginStatement): - """ - ENUM , BIND(C) - <enumerator-def-stmt> - [ <enumerator-def-stmt> ]... - """ - blocktype = 'enum' - end_stmt_cls = EndEnum - match = re.compile(r'enum\s*,\s*bind\s*\(\s*c\s*\)\Z',re.I).match - def process_item(self): - return BeginStatement.process_item(self) - def get_classes(self): - return [Enumerator] - -################################################### - -import statements -import typedecl_statements -__all__.extend(statements.__all__) -__all__.extend(typedecl_statements.__all__) - -from statements import * -from typedecl_statements import * - -f2py_stmt = [Threadsafe, FortranName, Depend, Check, CallStatement, - CallProtoArgument] - -access_spec = [Public, Private] - -interface_specification = [Function, Subroutine, - ModuleProcedure - ] - -module_subprogram_part = [ Contains, Function, Subroutine ] - -specification_stmt = access_spec + [ Allocatable, Asynchronous, Bind, - Common, Data, Dimension, Equivalence, External, Intent, Intrinsic, - Namelist, Optional, Pointer, Protected, Save, Target, Volatile, - Value ] - -intrinsic_type_spec = [ SubprogramPrefix, Integer , Real, - DoublePrecision, Complex, DoubleComplex, Character, Logical, Byte - ] - -derived_type_spec = [ ] -type_spec = intrinsic_type_spec + derived_type_spec -declaration_type_spec = intrinsic_type_spec + [ TypeStmt, Class ] - -type_declaration_stmt = declaration_type_spec - -private_or_sequence = [ Private, Sequence ] - -component_part = declaration_type_spec + [ ModuleProcedure ] - -proc_binding_stmt = [SpecificBinding, GenericBinding, FinalBinding] - -type_bound_procedure_part = [Contains, Private] + proc_binding_stmt - -#R214 -action_stmt = [ Allocate, GeneralAssignment, Assign, Backspace, Call, Close, - Continue, Cycle, Deallocate, Endfile, Exit, Flush, ForallStmt, - Goto, If, Inquire, Nullify, Open, Print, Read, Return, Rewind, - Stop, Wait, WhereStmt, Write, ArithmeticIf, ComputedGoto, - AssignedGoto, Pause ] -# GeneralAssignment = Assignment + PointerAssignment -# EndFunction, EndProgram, EndSubroutine - part of the corresponding blocks - -executable_construct = [ Associate, Do, ForallConstruct, IfThen, - Select, WhereConstruct ] + action_stmt -#Case, see Select - -execution_part_construct = executable_construct + [ Format, Entry, - Data ] - -execution_part = execution_part_construct[:] - -#C201, R208 -for cls in [EndFunction, EndProgram, EndSubroutine]: - try: execution_part.remove(cls) - except ValueError: pass - -internal_subprogram = [Function, Subroutine] - -internal_subprogram_part = [ Contains, ] + internal_subprogram - -declaration_construct = [ TypeDecl, Entry, Enum, Format, Interface, - Parameter, ModuleProcedure, ] + specification_stmt + \ - type_declaration_stmt -# stmt-function-stmt - -implicit_part = [ Implicit, Parameter, Format, Entry ] - -specification_part = [ Use, Import ] + implicit_part + \ - declaration_construct - - -external_subprogram = [Function, Subroutine] - -main_program = [Program] + specification_part + execution_part + \ - internal_subprogram_part - -program_unit = main_program + external_subprogram + [Module, - BlockData ] diff --git a/numpy/f2py/lib/parser/doc.txt b/numpy/f2py/lib/parser/doc.txt deleted file mode 100644 index b27178cd1..000000000 --- a/numpy/f2py/lib/parser/doc.txt +++ /dev/null @@ -1,395 +0,0 @@ -.. -*- rest -*- - -====================== -Fortran parser package -====================== - -:Author: - Pearu Peterson <pearu.peterson@gmail.com> -:Created: September 2006 - - -.. contents:: Table of Contents - -Overview -======== - -The Fortran parser package is a Python implementation -of Fortran 66/77/90/95/2003 language parser. The code -is under NumPy SVN tree: `numpy/f2py/lib/parser/`__. -The Fortran language syntax rules are defined in `Fortran2003.py`__, -the rules are taken from the following ISO/IEC 1539 working draft: -http://j3-fortran.org/doc/2003_Committee_Draft/04-007.pdf. - -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/ -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/Fortran2003.py - -Fortran parser package structure -================================ - -`numpy.f2py.lib.parser` package contains the following files: - -api.py - public API for Fortran parser --------------------------------------- - -`This file`__ exposes `Statement` subclasses, `CHAR_BIT` constant, and a function `parse`. - -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/api.py - -Function `parse(<input>, ..)` parses, analyzes and returns a `Statement` -tree of Fortran input. For example, - -:: - - >>> from api import parse - >>> code = """ - ... c comment - ... subroutine foo(a) - ... integer a - ... print*,"a=",a - ... end - ... """ - >>> tree = parse(code,isfree=False) - >>> print tree - !BEGINSOURCE <cStringIO.StringI object at 0xb75ac410> mode=fix90 - SUBROUTINE foo(a) - INTEGER a - PRINT *, "a=", a - END SUBROUTINE foo - >>> - >>> tree - BeginSource - blocktype='beginsource' - name='<cStringIO.StringI object at 0xb75ac410> mode=fix90' - a=AttributeHolder: - external_subprogram=<dict with keys ['foo']> - content: - Subroutine - args=['a'] - item=Line('subroutine foo(a)',(3, 3),'') - a=AttributeHolder: - variables=<dict with keys ['a']> - content: - Integer - selector=('', '') - entity_decls=['a'] - item=Line('integer a',(4, 4),'') - Print - item=Line('print*,"a=",a',(5, 5),'') - EndSubroutine - blocktype='subroutine' - name='foo' - item=Line('end',(6, 6),'') - -readfortran.py --------------- - -`This file`__ contains tools for reading Fortran codes from file and string objects. - -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/readfortran.py - -To read Fortran code from a file, use `FortranFileReader` class. -`FortranFileReader` class is iterator over Fortran code lines -and is derived from `FortranReaderBase` class. -It automatically handles the line continuations and comments, as -well as it detects if Fortran file is in the free or fixed format. - -For example, - -:: - - >>> from readfortran import * - >>> import os - >>> reader = FortranFileReader(os.path.expanduser('~/src/blas/daxpy.f')) - >>> reader.next() - Line('subroutine daxpy(n,da,dx,incx,dy,incy)',(1, 1),'') - >>> reader.next() - Comment('c constant times a vector plus a vector.\nc uses unrolled loops for increments equal to one.\nc jack dongarra, linpack, 3/11/78.\nc modified 12/3/93, array(1) declarations changed to array(*)',(3, 6)) - >>> reader.next() - Line('double precision dx(*),dy(*),da',(8, 8),'') - >>> reader.next() - Line('integer i,incx,incy,ix,iy,m,mp1,n',(9, 9),'') - -Note that `FortranReaderBase.next()` method may return `Line`, `SyntaxErrorLine`, `Comment`, `MultiLine`, -`SyntaxErrorMultiLine` instances. - -`Line` instance has the following attributes: - - * `.line` - contains Fortran code line - * `.span` - a 2-tuple containing the span of line numbers containing - Fortran code in the original Fortran file - * `.label` - the label of Fortran code line - * `.reader` - the `FortranReaderBase` class instance - * `.strline` - if it is not `None` then it contains Fortran code line with parenthesis - content and string literal constants saved in the `.strlinemap` dictionary. - * `.is_f2py_directive` - `True` if line starts with the f2py directive comment. - -and the following methods: - - * `.get_line()` - returns `.strline` (also evalutes it if None). Also - handles Hollerith contstants in the fixed F77 mode. - * `.isempty()` - returns `True` if Fortran line contains no code. - * `.copy(line=None, apply_map=False)` - returns a `Line` instance - with given `.span`, `.label`, `.reader` information but the line content - replaced with `line` (when not `None`) and applying `.strlinemap` - mapping (when `apply_map` is `True`). - * `.apply_map(line)` - apply `.strlinemap` mapping to line content. - * `.has_map()` - returns `True` if `.strlinemap` mapping exists. - -For example, - -:: - - >>> item = reader.next() - >>> item - Line('if(n.le.0)return',(11, 11),'') - >>> item.line - 'if(n.le.0)return' - >>> item.strline - 'if(F2PY_EXPR_TUPLE_4)return' - >>> item.strlinemap - {'F2PY_EXPR_TUPLE_4': 'n.le.0'} - >>> item.label - '' - >>> item.span - (11, 11) - >>> item.get_line() - 'if(F2PY_EXPR_TUPLE_4)return' - >>> item.copy('if(F2PY_EXPR_TUPLE_4)pause',True) - Line('if(n.le.0)pause',(11, 11),'') - -`Comment` instance has the following attributes: - - * `.comment` - a comment string - * `.span` - a 2-tuple containing the span of line numbers containing - Fortran comment in the original Fortran file - * `.reader` - the `FortranReaderBase` class instance - -and `.isempty()` method. - -`MultiLine` class represents multiline syntax in the .pyf files:: - - <prefix>'''<lines>'''<suffix> - -`MultiLine` instance has the following attributes: - - * `.prefix` - the content of `<prefix>` - * `.block` - a list of lines - * `.suffix` - the content of `<suffix>` - * `.span` - a 2-tuple containing the span of line numbers containing - multiline syntax in the original Fortran file - * `.reader` - the `FortranReaderBase` class instance - -and `.isempty()` method. - -`SyntaxErrorLine` and `SyntaxErrorMultiLine` are like `Line` and `MultiLine` -classes, respectively, with a functionality of issuing an error -message to `sys.stdout` when constructing an instance of the corresponding -class. - -To read a Fortran code from a string, use `FortranStringReader` class:: - - reader = FortranStringReader(<string>, <isfree>, <isstrict>) - -where the second and third arguments are used to specify the format -of the given `<string>` content. When `<isfree>` and `<isstrict>` are both -`True`, the content of a .pyf file is assumed. For example, - -:: - - >>> code = """ - ... c comment - ... subroutine foo(a) - ... print*, "a=",a - ... end - ... """ - >>> reader = FortranStringReader(code, False, True) - >>> reader.next() - Comment('c comment',(2, 2)) - >>> reader.next() - Line('subroutine foo(a)',(3, 3),'') - >>> reader.next() - Line('print*, "a=",a',(4, 4),'') - >>> reader.next() - Line('end',(5, 5),'') - -`FortranReaderBase` has the following attributes: - - * `.source` - a file-like object with `.next()` method to retrive - a source code line - * `.source_lines` - a list of read source lines - * `.reader` - a `FortranReaderBase` instance for reading files - from INCLUDE statements. - * `.include_dirs` - a list of directories where INCLUDE files - are searched. Default is `['.']`. - -and the following methods: - - * `.set_mode(isfree, isstrict)` - set Fortran code format information - * `.close_source()` - called when `.next()` raises `StopIteration` exception. - -parsefortran.py ---------------- - -`This file`__ contains code for parsing Fortran code from `FortranReaderBase` iterator. - -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/parsefortran.py - -`FortranParser` class holds the parser information while -iterating over items returned by `FortranReaderBase` iterator. -The parsing information, collected when calling `.parse()` method, -is saved in `.block` attribute as an instance -of `BeginSource` class defined in `block_statements.py` file. - -For example, - -:: - - >>> reader = FortranStringReader(code, False, True) - >>> parser = FortranParser(reader) - >>> parser.parse() - >>> print parser.block - !BEGINSOURCE <cStringIO.StringI object at 0xb751d500> mode=fix77 - SUBROUTINE foo(a) - PRINT *, "a=", a - END SUBROUTINE foo - -Files `block_statements.py`__, `base_classes.py`__, `typedecl_statements.py`__, `statements.py`__ -------------------------------------------------------------------------------------------------- - -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/block_statements.py -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/base_classes.py -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/typedecl_statements.py -__ http://projects.scipy.org/scipy/numpy/browser/trunk/numpy/f2py/lib/parser/statements.py - -The model for representing Fortran code statements consists of a tree of `Statement` -classes defined in `base_classes.py`. There are two types of statements: one-line -statements and block statements. Block statements consists of start and end -statements, and content statements in between that can be of both types again. - -`Statement` instance has the following attributes: - - * `.parent` - it is either parent block-type statement or `FortranParser` instance. - * `.item` - a `Line` instance containing Fortran statement line information, see above. - * `.isvalid` - when `False` then processing this `Statement` instance will be skipped, - for example, when the content of `.item` does not match with - the `Statement` class. - * `.ignore` - when `True` then the `Statement` instance will be ignored. - * `.modes` - a list of Fortran format modes where the `Statement` instance is valid. - -and the following methods: - - * `.info(message)`, `.warning(message)`, `.error(message)` - to spit out messages to - `sys.stderr` stream. - * `.get_variable(name)` - get `Variable` instance by name that is defined in - current namespace. If name is not defined, then the corresponding - `Variable` instance is created. - * `.analyze()` - calculate various information about the `Statement`, this information - is saved in `.a` attribute that is `AttributeHolder` instance. - -All statement classes are derived from the `Statement` class. Block statements are -derived from the `BeginStatement` class and is assumed to end with an `EndStatement` -instance in `.content` attribute list. `BeginStatement` and `EndStatement` instances -have the following attributes: - - * `.name` - name of the block, blocks without names use line label - as the name. - * `.blocktype` - type of the block (derived from class name) - * `.content` - a list of `Statement` (or `Line`) instances. - -and the following methods: - - * `.__str__()` - returns string representation of Fortran code. - -A number of statements may declare a variable that is used in other -statement expressions. Variables are represented via `Variable` class -and its instances have the following attributes: - - * `.name` - name of the variable - * `.typedecl` - type declaration - * `.dimension` - list of dimensions - * `.bounds` - list of bounds - * `.length` - length specs - * `.attributes` - list of attributes - * `.bind` - list of bind information - * `.intent` - list of intent information - * `.check` - list of check expressions - * `.init` - initial value of the variable - * `.parent` - statement instance declaring the variable - * `.parents` - list of statements that specify variable information - -and the following methods: - - * `.is_private()` - * `.is_public()` - * `.is_allocatable()` - * `.is_external()` - * `.is_intrinsic()` - * `.is_parameter()` - * `.is_optional()` - * `.is_required()` - -The following type declaration statements are defined in `typedecl_statements.py`: - - `Integer`, `Real`, `DoublePrecision`, `Complex`, `DoubleComplex`, `Logical`, - `Character`, `Byte`, `Type`, `Class` - -and they have the following attributes: - - * `.selector` - contains lenght and kind specs - * `.entity_decls`, `.attrspec` - -and methods: - - * `.tostr()` - return string representation of Fortran type declaration - * `.astypedecl()` - pure type declaration instance, it has no `.entity_decls` - and `.attrspec`. - * `.analyze()` - processes `.entity_decls` and `.attrspec` attributes and adds - `Variable` instance to `.parent.a.variables` dictionary. - -The following block statements are defined in `block_statements.py`: - - `BeginSource`, `Module`, `PythonModule`, `Program`, `BlockData`, `Interface`, - `Subroutine`, `Function`, `Select`, `Where`, `Forall`, `IfThen`, `If`, `Do`, - `Associate`, `TypeDecl (Type)`, `Enum` - -Block statement classes may have different properties which are declared via -deriving them from the following classes: - - `HasImplicitStmt`, `HasUseStmt`, `HasVariables`, `HasTypeDecls`, - `HasAttributes`, `HasModuleProcedures`, `ProgramBlock` - -In summary, the `.a` attribute may hold different information sets as follows: - - * `BeginSource` - `.module`, `.external_subprogram`, `.blockdata` - * `Module` - `.attributes`, `.implicit_rules`, `.use`, `.use_provides`, `.variables`, - `.type_decls`, `.module_subprogram`, `.module_data` - * `PythonModule` - `.implicit_rules`, `.use`, `.use_provides` - * `Program` - `.attributes`, `.implicit_rules`, `.use`, `.use_provides` - * `BlockData` - `.implicit_rules`, `.use`, `.use_provides`, `.variables` - * `Interface` - `.implicit_rules`, `.use`, `.use_provides`, `.module_procedures` - * `Function`, `Subroutine` - `.implicit_rules`, `.attributes`, `.use`, `.use_statements`, - `.variables`, `.type_decls`, `.internal_subprogram` - * `TypeDecl` - `.variables`, `.attributes` - -Block statements have the following methods: - - * `.get_classes()` - returns a list of `Statement` classes that are valid - as a content of given block statement. - -The following one line statements are defined: - - `Implicit`, `TypeDeclarationStatement` derivatives (see above), - `Assignment`, `PointerAssignment`, `Assign`, `Call`, `Goto`, `ComputedGoto`, - `AssignedGoto`, `Continue`, `Return`, `Stop`, `Print`, `Read`, `Write`, `Flush`, - `Wait`, `Contains`, `Allocate`, `Deallocate`, `ModuleProcedure`, `Access`, - `Public`, `Private`, `Close`, `Cycle`, `Backspace`, `Endfile`, `Reeinf`, `Open`, - `Format`, `Save`, `Data`, `Nullify`, `Use`, `Exit`, `Parameter`, `Equivalence`, - `Dimension`, `Target`, `Pointer`, `Protected`, `Volatile`, `Value`, - `ArithmeticIf`, `Intrinsic`, `Inquire`, `Sequence`, `External`, `Namelist`, - `Common`, `Optional`, `Intent`, `Entry`, `Import`, `Forall`, - `SpecificBinding`, `GenericBinding`, `FinalBinding`, `Allocatable`, - `Asynchronous`, `Bind`, `Else`, `ElseIf`, `Case`, `Where`, `ElseWhere`, - `Enumerator`, `FortranName`, `Threadsafe`, `Depend`, `Check`, - `CallStatement`, `CallProtoArgument`, `Pause` - diff --git a/numpy/f2py/lib/parser/parsefortran.py b/numpy/f2py/lib/parser/parsefortran.py deleted file mode 100644 index 2dacd9e9f..000000000 --- a/numpy/f2py/lib/parser/parsefortran.py +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env python -""" -Defines FortranParser. - -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 -""" - -__all__ = ['FortranParser'] - -import re -import sys -import traceback -from numpy.distutils.misc_util import yellow_text, red_text - -from readfortran import FortranFileReader, FortranStringReader -from block_statements import BeginSource -from utils import AnalyzeError - -class FortranParser: - - cache = {} - - def __init__(self, reader): - """ - Parser of FortranReader structure. - Use .parse() method for parsing, parsing result is saved in .block attribute. - """ - self.reader = reader - if reader.id in self.cache: - parser = self.cache[reader.id] - self.block = parser.block - self.is_analyzed = parser.is_analyzed - self.block.show_message('using cached %s' % (reader.id)) - else: - self.cache[reader.id] = self - self.block = None - self.is_analyzed = False - return - - def get_item(self): - try: - return self.reader.next(ignore_comments = True) - except StopIteration: - pass - return - - def put_item(self, item): - self.reader.fifo_item.insert(0, item) - return - - def parse(self): - if self.block is not None: - return - try: - block = self.block = BeginSource(self) - except KeyboardInterrupt: - raise - except: - reader = self.reader - while reader is not None: - message = reader.format_message('FATAL ERROR', - 'while processing line', - reader.linecount, reader.linecount) - reader.show_message(message, sys.stderr) - reader = reader.reader - traceback.print_exc(file=sys.stderr) - self.reader.show_message(red_text('STOPPED PARSING'), sys.stderr) - return - return - - def analyze(self): - if self.is_analyzed: - return - if self.block is None: - self.reader.show_message('Nothing to analyze.') - return - - try: - self.block.analyze() - except AnalyzeError: - pass - except Exception, msg: - if str(msg) != '123454321': - traceback.print_exc(file=sys.stderr) - self.reader.show_message(red_text('FATAL ERROR: STOPPED ANALYSING %r CONTENT' % (self.reader.source) ), sys.stderr) - sys.exit(123454321) - return - self.is_analyzed = True - return - -def test_pyf(): - string = """ -python module foo - interface tere - subroutine bar - real r - end subroutine bar - end interface tere -end python module foo -""" - reader = FortranStringReader(string, True, True) - parser = FortranParser(reader) - block = parser.parse() - print block - -def test_free90(): - string = """ -module foo - - subroutine bar - real r - if ( pc_get_lun() .ne. 6) & - write ( pc_get_lun(), '( & - & /, a, /, " p=", i4, " stopping c_flag=", a, & - & /, " print unit=", i8)') & - trim(title), pcpsx_i_pel(), trim(c_flag), pc_get_lun() - if (.true.) then - call smth - end if - aaa : if (.false.) then - else if (a) then aaa - else aaa - end if aaa - hey = 1 - end subroutine bar - abstract interface - - end interface - -end module foo -""" - reader = FortranStringReader(string, True, False) - parser = FortranParser(reader) - block = parser.parse() - print block - -def test_f77(): - string = """\ - program foo - a = 3 - end - subroutine bar - end - pure function foo(a) - end - pure real*4 recursive function bar() - end -""" - reader = FortranStringReader(string, False, True) - parser = FortranParser(reader) - block = parser.parse() - print block - -def simple_main(): - import sys - if not sys.argv[1:]: - return parse_all_f() - for filename in sys.argv[1:]: - reader = FortranFileReader(filename) - print yellow_text('Processing '+filename+' (mode=%r)' % (reader.mode)) - parser = FortranParser(reader) - parser.parse() - parser.analyze() - print parser.block.torepr(4) - #print parser.block - -def profile_main(): - import hotshot, hotshot.stats - prof = hotshot.Profile("_parsefortran.prof") - prof.runcall(simple_main) - prof.close() - stats = hotshot.stats.load("_parsefortran.prof") - stats.strip_dirs() - stats.sort_stats('time', 'calls') - stats.print_stats(30) - -def parse_all_f(): - for filename in open('opt_all_f.txt'): - filename = filename.strip() - reader = FortranFileReader(filename) - print yellow_text('Processing '+filename+' (mode=%r)' % (reader.mode)) - parser = FortranParser(reader) - block = parser.parse() - print block - -if __name__ == "__main__": - #test_f77() - #test_free90() - #test_pyf() - simple_main() - #profile_main() - #parse_all_f() diff --git a/numpy/f2py/lib/parser/pattern_tools.py b/numpy/f2py/lib/parser/pattern_tools.py deleted file mode 100644 index 3c009a6a8..000000000 --- a/numpy/f2py/lib/parser/pattern_tools.py +++ /dev/null @@ -1,401 +0,0 @@ -""" -Tools for constructing patterns. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import re - -class Pattern: - """ - p1 | p2 -> <p1> | <p2> - p1 + p2 -> <p1> <p2> - p1 & p2 -> <p1><p2> - ~p1 -> [ <p1> ] - ~~p1 -> [ <p1> ]... - ~~~p1 -> <p1> [ <p1> ]... - ~~~~p1 -> ~~~p1 - abs(p1) -> whole string match of <p1> - p1.named(name) -> match of <p1> has name - p1.match(string) -> return string match with <p1> - p1.flags(<re.I,..>) - p1.rsplit(..) -> split a string from the rightmost p1 occurrence - p1.lsplit(..) -> split a string from the leftmost p1 occurrence - """ - _special_symbol_map = {'.': '[.]', - '*': '[*]', - '+': '[+]', - '|': '[|]', - '(': r'\(', - ')': r'\)', - '[': r'\[', - ']': r'\]', - '^': '[^]', - '$': '[$]', - '?': '[?]', - '{': '\{', - '}': '\}', - '>': '[>]', - '<': '[<]', - '=': '[=]' - } - - def __init__(self, label, pattern, optional=0, flags=0, value=None): - self.label = label - self.pattern = pattern - self.optional = optional - self._flags = flags - self.value = value - return - - def flags(self, *flags): - f = self._flags - for f1 in flags: - f = f | f1 - return Pattern(self.label, self.pattern, optional=self.optional, flags=f, value=self.value) - - def get_compiled(self): - try: - return self._compiled_pattern - except AttributeError: - self._compiled_pattern = compiled = re.compile(self.pattern, self._flags) - return compiled - - def match(self, string): - return self.get_compiled().match(string) - - def search(self, string): - return self.get_compiled().search(string) - - def rsplit(self, string): - """ - Return (<lhs>, <pattern_match>, <rhs>) where - string = lhs + pattern_match + rhs - and rhs does not contain pattern_match. - If no pattern_match is found in string, return None. - """ - compiled = self.get_compiled() - t = compiled.split(string) - if len(t) < 3: return - if '' in t[1:-1]: return - rhs = t[-1].strip() - pattern_match = t[-2].strip() - assert abs(self).match(pattern_match),`self,string,t,pattern_match` - lhs = (''.join(t[:-2])).strip() - return lhs, pattern_match, rhs - - def lsplit(self, string): - """ - Return (<lhs>, <pattern_match>, <rhs>) where - string = lhs + pattern_match + rhs - and rhs does not contain pattern_match. - If no pattern_match is found in string, return None. - """ - compiled = self.get_compiled() - t = compiled.split(string) # can be optimized - if len(t) < 3: return - lhs = t[0].strip() - pattern_match = t[1].strip() - rhs = (''.join(t[2:])).strip() - assert abs(self).match(pattern_match),`pattern_match` - return lhs, pattern_match, rhs - - def __abs__(self): - return Pattern(self.label, r'\A' + self.pattern+ r'\Z',flags=self._flags, value=self.value) - - def __repr__(self): - return '%s(%r, %r)' % (self.__class__.__name__, self.label, self.pattern) - - def __or__(self, other): - label = '( %s OR %s )' % (self.label, other.label) - if self.pattern==other.pattern: - pattern = self.pattern - flags = self._flags - else: - pattern = '(%s|%s)' % (self.pattern, other.pattern) - flags = self._flags | other._flags - return Pattern(label, pattern, flags=flags) - - def __and__(self, other): - if isinstance(other, Pattern): - label = '%s%s' % (self.label, other.label) - pattern = self.pattern + other.pattern - flags = self._flags | other._flags - else: - assert isinstance(other,str),`other` - label = '%s%s' % (self.label, other) - pattern = self.pattern + other - flags = self._flags - return Pattern(label, pattern, flags=flags) - - def __rand__(self, other): - assert isinstance(other,str),`other` - label = '%s%s' % (other, self.label) - pattern = other + self.pattern - return Pattern(label, pattern, flags=self._flags) - - def __invert__(self): - if self.optional: - if self.optional==1: - return Pattern(self.label + '...', self.pattern[:-1] + '*', optional=2,flags=self._flags) - if self.optional==2: - return Pattern('%s %s' % (self.label[1:-4].strip(), self.label), self.pattern[:-1] + '+', - optional=3, flags=self._flags) - return self - label = '[ %s ]' % (self.label) - pattern = '(%s)?' % (self.pattern) - return Pattern(label, pattern, optional=1, flags=self._flags) - - def __add__(self, other): - if isinstance(other, Pattern): - label = '%s %s' % (self.label, other.label) - pattern = self.pattern + r'\s*' + other.pattern - flags = self._flags | other._flags - else: - assert isinstance(other,str),`other` - label = '%s %s' % (self.label, other) - other = self._special_symbol_map.get(other, other) - pattern = self.pattern + r'\s*' + other - flags = self._flags - return Pattern(label, pattern, flags = flags) - - def __radd__(self, other): - assert isinstance(other,str),`other` - label = '%s %s' % (other, self.label) - other = self._special_symbol_map.get(other, other) - pattern = other + r'\s*' + self.pattern - return Pattern(label, pattern, flags=self._flags) - - def named(self, name = None): - if name is None: - label = self.label - assert label[0]+label[-1]=='<>' and ' ' not in label,`label` - else: - label = '<%s>' % (name) - pattern = '(?P%s%s)' % (label.replace('-','_'), self.pattern) - return Pattern(label, pattern, flags=self._flags, value= self.value) - - def rename(self, label): - if label[0]+label[-1]!='<>': - label = '<%s>' % (label) - return Pattern(label, self.pattern, optional=self.optional, flags=self._flags, value=self.value) - - def __call__(self, string): - m = self.match(string) - if m is None: return - if self.value is not None: return self.value - return m.group() - -# Predefined patterns - -letter = Pattern('<letter>','[A-Z]',flags=re.I) -name = Pattern('<name>', r'[A-Z]\w*',flags=re.I) -digit = Pattern('<digit>',r'\d') -underscore = Pattern('<underscore>', '_') -binary_digit = Pattern('<binary-digit>',r'[01]') -octal_digit = Pattern('<octal-digit>',r'[0-7]') -hex_digit = Pattern('<hex-digit>',r'[\dA-F]',flags=re.I) - -digit_string = Pattern('<digit-string>',r'\d+') -binary_digit_string = Pattern('<binary-digit-string>',r'[01]+') -octal_digit_string = Pattern('<octal-digit-string>',r'[0-7]+') -hex_digit_string = Pattern('<hex-digit-string>',r'[\dA-F]+',flags=re.I) - -sign = Pattern('<sign>',r'[+-]') -exponent_letter = Pattern('<exponent-letter>',r'[ED]',flags=re.I) - -alphanumeric_character = Pattern('<alphanumeric-character>',r'\w') # [A-Z0-9_] -special_character = Pattern('<special-character>',r'[ =+-*/\()[\]{},.:;!"%&~<>?,\'`^|$#@]') -character = alphanumeric_character | special_character - -kind_param = digit_string | name -kind_param_named = kind_param.named('kind-param') -signed_digit_string = ~sign + digit_string -int_literal_constant = digit_string + ~('_' + kind_param) -signed_int_literal_constant = ~sign + int_literal_constant -int_literal_constant_named = digit_string.named('value') + ~ ('_' + kind_param_named) -signed_int_literal_constant_named = (~sign + digit_string).named('value') + ~ ('_' + kind_param_named) - -binary_constant = ('B' + ("'" & binary_digit_string & "'" | '"' & binary_digit_string & '"')).flags(re.I) -octal_constant = ('O' + ("'" & octal_digit_string & "'" | '"' & octal_digit_string & '"')).flags(re.I) -hex_constant = ('Z' + ("'" & hex_digit_string & "'" | '"' & hex_digit_string & '"')).flags(re.I) -boz_literal_constant = binary_constant | octal_constant | hex_constant - -exponent = signed_digit_string -significand = digit_string + '.' + ~digit_string | '.' + digit_string -real_literal_constant = significand + ~(exponent_letter + exponent) + ~ ('_' + kind_param) | \ - digit_string + exponent_letter + exponent + ~ ('_' + kind_param) -real_literal_constant_named = (significand + ~(exponent_letter + exponent) |\ - digit_string + exponent_letter + exponent).named('value') + ~ ('_' + kind_param_named) -signed_real_literal_constant_named = (~sign + (significand + ~(exponent_letter + exponent) |\ - digit_string + exponent_letter + exponent)).named('value') + ~ ('_' + kind_param_named) -signed_real_literal_constant = ~sign + real_literal_constant - -named_constant = name -real_part = signed_int_literal_constant | signed_real_literal_constant | named_constant -imag_part = real_part -complex_literal_constant = '(' + real_part + ',' + imag_part + ')' - -a_n_rep_char = Pattern('<alpha-numeric-rep-char>',r'\w') -rep_char = Pattern('<rep-char>',r'.') -char_literal_constant = ~( kind_param + '_') + ("'" + ~~rep_char + "'" | '"' + ~~rep_char + '"' ) -a_n_char_literal_constant_named1 = ~( kind_param_named + '_') + (~~~("'" + ~~a_n_rep_char + "'" )).named('value') -a_n_char_literal_constant_named2 = ~( kind_param_named + '_') + (~~~('"' + ~~a_n_rep_char + '"' )).named('value') - -logical_literal_constant = ('[.](TRUE|FALSE)[.]' + ~ ('_' + kind_param)).flags(re.I) -logical_literal_constant_named = Pattern('<value>',r'[.](TRUE|FALSE)[.]',flags=re.I).named() + ~ ('_' + kind_param_named) -literal_constant = int_literal_constant | real_literal_constant | complex_literal_constant | logical_literal_constant | char_literal_constant | boz_literal_constant -constant = literal_constant | named_constant -int_constant = int_literal_constant | boz_literal_constant | named_constant -char_constant = char_literal_constant | named_constant - -# assume that replace_string_map is applied: -part_ref = name + ~((r'[(]' + name + r'[)]')) -data_ref = part_ref + ~~~(r'[%]' + part_ref) -primary = constant | name | data_ref | (r'[(]' + name + r'[)]') - -power_op = Pattern('<power-op>',r'(?<![*])[*]{2}(?![*])') -mult_op = Pattern('<mult-op>',r'(?<![*])[*](?![*])|(?<![/])[/](?![/])') -add_op = Pattern('<add-op>',r'[+-]') -concat_op = Pattern('<concat-op>',r'(?<![/])[/]{2}(?![/])') -rel_op = Pattern('<rel-op>','[.]EQ[.]|[.]NE[.]|[.]LT[.]|[.]LE[.]|[.]GT[.]|[.]GE[.]|[=]{2}|/[=]|[<][=]|[<]|[>][=]|[>]',flags=re.I) -not_op = Pattern('<not-op>','[.]NOT[.]',flags=re.I) -and_op = Pattern('<and-op>','[.]AND[.]',flags=re.I) -or_op = Pattern('<or-op>','[.]OR[.]',flags=re.I) -equiv_op = Pattern('<equiv-op>','[.]EQV[.]|[.]NEQV[.]',flags=re.I) -percent_op = Pattern('<percent-op>',r'%',flags=re.I) -intrinsic_operator = power_op | mult_op | add_op | concat_op | rel_op | not_op | and_op | or_op | equiv_op -extended_intrinsic_operator = intrinsic_operator - -defined_unary_op = Pattern('<defined-unary-op>','[.][A-Z]+[.]',flags=re.I) -defined_binary_op = Pattern('<defined-binary-op>','[.][A-Z]+[.]',flags=re.I) -defined_operator = defined_unary_op | defined_binary_op | extended_intrinsic_operator -abs_defined_operator = abs(defined_operator) -defined_op = Pattern('<defined-op>','[.][A-Z]+[.]',flags=re.I) -abs_defined_op = abs(defined_op) - -non_defined_binary_op = intrinsic_operator | logical_literal_constant - -label = Pattern('<label>','\d{1,5}') -abs_label = abs(label) - -keyword = name -keyword_equal = keyword + '=' - - - - -abs_constant = abs(constant) -abs_literal_constant = abs(literal_constant) -abs_int_literal_constant = abs(int_literal_constant) -abs_signed_int_literal_constant = abs(signed_int_literal_constant) -abs_signed_int_literal_constant_named = abs(signed_int_literal_constant_named) -abs_int_literal_constant_named = abs(int_literal_constant_named) -abs_real_literal_constant = abs(real_literal_constant) -abs_signed_real_literal_constant = abs(signed_real_literal_constant) -abs_signed_real_literal_constant_named = abs(signed_real_literal_constant_named) -abs_real_literal_constant_named = abs(real_literal_constant_named) -abs_complex_literal_constant = abs(complex_literal_constant) -abs_logical_literal_constant = abs(logical_literal_constant) -abs_char_literal_constant = abs(char_literal_constant) -abs_boz_literal_constant = abs(boz_literal_constant) -abs_name = abs(name) -abs_a_n_char_literal_constant_named1 = abs(a_n_char_literal_constant_named1) -abs_a_n_char_literal_constant_named2 = abs(a_n_char_literal_constant_named2) -abs_logical_literal_constant_named = abs(logical_literal_constant_named) -abs_binary_constant = abs(binary_constant) -abs_octal_constant = abs(octal_constant) -abs_hex_constant = abs(hex_constant) - -intrinsic_type_name = Pattern('<intrinsic-type-name>',r'(INTEGER|REAL|COMPLEX|LOGICAL|CHARACTER|DOUBLE\s*COMPLEX|DOUBLE\s*PRECISION|BYTE)',flags=re.I) -abs_intrinsic_type_name = abs(intrinsic_type_name) -double_complex_name = Pattern('<double-complex-name>','DOUBLE\s*COMPLEX', flags=re.I, value='DOUBLE COMPLEX') -double_precision_name = Pattern('<double-precision-name>','DOUBLE\s*PRECISION', flags=re.I, value='DOUBLE PRECISION') -abs_double_complex_name = abs(double_complex_name) -abs_double_precision_name = abs(double_precision_name) - -access_spec = Pattern('<access-spec>',r'PUBLIC|PRIVATE',flags=re.I) -abs_access_spec = abs(access_spec) - -implicit_none = Pattern('<implicit-none>',r'IMPLICIT\s*NONE',flags=re.I, value='IMPLICIT NONE') -abs_implicit_none = abs(implicit_none) - -attr_spec = Pattern('<attr-spec>',r'ALLOCATABLE|ASYNCHRONOUS|EXTERNAL|INTENT|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|SAVE|TARGET|VALUE|VOLATILE',flags=re.I) -abs_attr_spec = abs(attr_spec) - -dimension = Pattern('<dimension>',r'DIMENSION', flags=re.I) -abs_dimension = abs(dimension) - -intent = Pattern('<intent>', r'INTENT', flags=re.I) -abs_intent = abs(intent) - -intent_spec = Pattern('<intent-spec>', r'INOUT|IN|OUT', flags=re.I) -abs_intent_spec = abs(intent_spec) - -subroutine = Pattern('<subroutine>', r'SUBROUTINE', flags=re.I) - -select_case = Pattern('<select-case>', r'SELECT\s*CASE', flags=re.I, value='SELECT CASE') -abs_select_case = abs(select_case) - -def _test(): - assert name.match('a1_a') - assert abs(name).match('a1_a') - assert not abs(name).match('a1_a[]') - - m = abs(kind_param) - assert m.match('23') - assert m.match('SHORT') - - m = abs(signed_digit_string) - assert m.match('23') - assert m.match('+ 23') - assert m.match('- 23') - assert m.match('-23') - assert not m.match('+n') - - m = ~sign.named() + digit_string.named('number') - r = m.match('23') - assert r.groupdict()=={'number': '23', 'sign': None} - r = m.match('- 23') - assert r.groupdict()=={'number': '23', 'sign': '-'} - - m = abs(char_literal_constant) - assert m.match('"adadfa"') - assert m.match('"adadfa""adad"') - assert m.match('HEY_"adadfa"') - assert m.match('HEY _ "ad\tadfa"') - assert not m.match('adadfa') - - def assert_equal(result, expect): - try: - assert result==expect - except AssertionError, msg: - raise AssertionError,"Expected %r but got %r: %s" \ - % (expect, result, msg) - - m = mult_op.named() - assert m.rsplit('a * b') - assert_equal(m.lsplit('a * c* b'),('a','*','c* b')) - assert_equal(m.rsplit('a * c* b'),('a * c','*','b')) - assert_equal(m.lsplit('a * b ** c'),('a','*','b ** c')) - assert_equal(m.rsplit('a * b ** c'),('a','*','b ** c')) - assert_equal(m.lsplit('a * b ** c * d'),('a','*','b ** c * d')) - assert_equal(m.rsplit('a * b ** c * d'),('a * b ** c','*','d')) - - m = power_op.named() - assert m.rsplit('a ** b') - assert_equal(m.lsplit('a * b ** c'),('a * b','**','c')) - assert_equal(m.rsplit('a * b ** c'),('a * b','**','c')) - assert_equal(m.lsplit('a ** b ** c'),('a','**','b ** c')) - assert_equal(m.rsplit('a ** b ** c'),('a ** b','**','c')) - print 'ok' - -if __name__ == '__main__': - _test() diff --git a/numpy/f2py/lib/parser/readfortran.py b/numpy/f2py/lib/parser/readfortran.py deleted file mode 100644 index e3acffa36..000000000 --- a/numpy/f2py/lib/parser/readfortran.py +++ /dev/null @@ -1,857 +0,0 @@ -#!/usr/bin/env python -""" -Defines FortranReader classes for reading Fortran codes from -files and strings. FortranReader handles comments and line continuations -of both fix and free format Fortran codes. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['FortranFileReader', - 'FortranStringReader', - 'FortranReaderError', - 'Line', 'SyntaxErrorLine', - 'Comment', - 'MultiLine','SyntaxErrorMultiLine', - ] - -import re -import os -import sys -import tempfile -import traceback -from cStringIO import StringIO -from numpy.distutils.misc_util import yellow_text, red_text, blue_text - -from sourceinfo import get_source_info -from splitline import String, string_replace_map, splitquote - -_spacedigits=' 0123456789' -_cf2py_re = re.compile(r'(?P<indent>\s*)!f2py(?P<rest>.*)',re.I) -_is_fix_cont = lambda line: line and len(line)>5 and line[5]!=' ' and line[:5]==5*' ' -_is_f90_cont = lambda line: line and '&' in line and line.rstrip()[-1]=='&' -_f90label_re = re.compile(r'\s*(?P<label>(\w+\s*:|\d+))\s*(\b|(?=&)|\Z)',re.I) -_is_include_line = re.compile(r'\s*include\s*("[^"]+"|\'[^\']+\')\s*\Z',re.I).match -_is_fix_comment = lambda line: line and line[0] in '*cC!' -_hollerith_start_search = re.compile(r'(?P<pre>\A|,\s*)(?P<num>\d+)h',re.I).search -_is_call_stmt = re.compile(r'call\b', re.I).match - -class FortranReaderError: # TODO: may be derive it from Exception - def __init__(self, message): - self.message = message - print >> sys.stderr,message - sys.stderr.flush() - -class Line: - """ Holds a Fortran source line. - """ - - f2py_strmap_findall = re.compile(r'(_F2PY_STRING_CONSTANT_\d+_|F2PY_EXPR_TUPLE_\d+)').findall - - def __init__(self, line, linenospan, label, reader): - self.line = line.strip() - self.span = linenospan - self.label = label - self.reader = reader - self.strline = None - self.is_f2py_directive = linenospan[0] in reader.f2py_comment_lines - - def has_map(self): - return not not (hasattr(self,'strlinemap') and self.strlinemap) - - def apply_map(self, line): - if not hasattr(self,'strlinemap') or not self.strlinemap: - return line - findall = self.f2py_strmap_findall - str_map = self.strlinemap - keys = findall(line) - for k in keys: - line = line.replace(k, str_map[k]) - return line - - def copy(self, line = None, apply_map = False): - if line is None: - line = self.line - if apply_map: - line = self.apply_map(line) - return Line(line, self.span, self.label, self.reader) - - def clone(self, line): - self.line = self.apply_map(line) - self.strline = None - return - - def __repr__(self): - return self.__class__.__name__+'(%r,%s,%r)' \ - % (self.line, self.span, self.label) - - def isempty(self, ignore_comments=False): - return not (self.line.strip() or self.label) - - def get_line(self): - if self.strline is not None: - return self.strline - line = self.line - if self.reader.isfix77: - # Handle Hollerith constants by replacing them - # with char-literal-constants. - # H constants may appear only in DATA statements and - # in the argument list of CALL statement. - # Holleriht constants were removed from the Fortran 77 standard. - # The following handling is not perfect but works for simple - # usage cases. - # todo: Handle hollerith constants in DATA statement - if _is_call_stmt(line): - l2 = self.line[4:].lstrip() - i = l2.find('(') - if i != -1 and l2[-1]==')': - substrings = ['call '+l2[:i+1]] - start_search = _hollerith_start_search - l2 = l2[i+1:-1].strip() - m = start_search(l2) - while m: - substrings.append(l2[:m.start()]) - substrings.append(m.group('pre')) - num = int(m.group('num')) - substrings.append("'"+l2[m.end():m.end()+num]+"'") - l2 = l2[m.end()+num:] - m = start_search(l2) - substrings.append(l2) - substrings.append(')') - line = ''.join(substrings) - - line, str_map = string_replace_map(line, lower=not self.reader.ispyf) - self.strline = line - self.strlinemap = str_map - return line - -class SyntaxErrorLine(Line, FortranReaderError): - def __init__(self, line, linenospan, label, reader, message): - Line.__init__(self, line, linenospan, label, reader) - FortranReaderError.__init__(self, message) - -class Comment: - """ Holds Fortran comment. - """ - def __init__(self, comment, linenospan, reader): - self.comment = comment - self.span = linenospan - self.reader = reader - def __repr__(self): - return self.__class__.__name__+'(%r,%s)' \ - % (self.comment, self.span) - def isempty(self, ignore_comments=False): - return ignore_comments or len(self.comment)<2 - -class MultiLine: - """ Holds (prefix, line list, suffix) representing multiline - syntax in .pyf files: - prefix+'''+lines+'''+suffix. - """ - def __init__(self, prefix, block, suffix, linenospan, reader): - self.prefix = prefix - self.block = block - self.suffix = suffix - self.span = linenospan - self.reader = reader - def __repr__(self): - return self.__class__.__name__+'(%r,%r,%r,%s)' \ - % (self.prefix,self.block,self.suffix, - self.span) - def isempty(self, ignore_comments=False): - return not (self.prefix or self.block or self.suffix) - -class SyntaxErrorMultiLine(MultiLine, FortranReaderError): - def __init__(self, prefix, block, suffix, linenospan, reader, message): - MultiLine.__init__(self, prefix, block, suffix, linenospan, reader) - FortranReaderError.__init__(self, message) - - -class FortranReaderBase: - - def __init__(self, source, isfree, isstrict): - """ - source - file-like object with .next() method - used to retrive a line. - source may contain - - Fortran 77 code - - fixed format Fortran 90 code - - free format Fortran 90 code - - .pyf signatures - extended free format Fortran 90 syntax - """ - - self.linecount = 0 - self.source = source - self.isclosed = False - - self.filo_line = [] - self.fifo_item = [] - self.source_lines = [] - - self.f2py_comment_lines = [] # line numbers that contain f2py directives - - self.reader = None - self.include_dirs = ['.'] - - self.set_mode(isfree, isstrict) - return - - def set_mode(self, isfree, isstrict): - self.isfree90 = isfree and not isstrict - self.isfix90 = not isfree and not isstrict - self.isfix77 = not isfree and isstrict - self.ispyf = isfree and isstrict - self.isfree = isfree - self.isfix = not isfree - self.isstrict = isstrict - - if self.isfree90: mode = 'free90' - elif self.isfix90: mode = 'fix90' - elif self.isfix77: mode = 'fix77' - else: mode = 'pyf' - self.mode = mode - self.name = '%s mode=%s' % (self.source, mode) - return - - def close_source(self): - # called when self.source.next() raises StopIteration. - pass - - # For handling raw source lines: - - def put_single_line(self, line): - self.filo_line.append(line) - self.linecount -= 1 - return - - def get_single_line(self): - try: - line = self.filo_line.pop() - self.linecount += 1 - return line - except IndexError: - pass - if self.isclosed: - return None - try: - line = self.source.next() - except StopIteration: - self.isclosed = True - self.close_source() - return None - self.linecount += 1 - # expand tabs, replace special symbols, get rid of nl characters - line = line.expandtabs().replace('\xa0',' ').rstrip() - self.source_lines.append(line) - if not line: - return self.get_single_line() - return line - - def get_next_line(self): - line = self.get_single_line() - if line is None: return - self.put_single_line(line) - return line - - # Parser methods: - def get_item(self): - try: - return self.next(ignore_comments = True) - except StopIteration: - pass - return - - def put_item(self, item): - self.fifo_item.insert(0, item) - return - # Iterator methods: - - def __iter__(self): - return self - - def next(self, ignore_comments = False): - - try: - if self.reader is not None: - try: - return self.reader.next() - except StopIteration: - self.reader = None - item = self._next(ignore_comments) - if isinstance(item, Line) and _is_include_line(item.line): - reader = item.reader - filename = item.line.strip()[7:].lstrip()[1:-1] - include_dirs = self.include_dirs[:] - path = filename - for incl_dir in include_dirs: - path = os.path.join(incl_dir, filename) - if os.path.exists(path): - break - if not os.path.isfile(path): - dirs = os.pathsep.join(include_dirs) - message = reader.format_message(\ - 'WARNING', - 'include file %r not found in %r,'\ - ' ignoring.' % (filename, dirs), - item.span[0], item.span[1]) - reader.show_message(message, sys.stdout) - return self.next(ignore_comments = ignore_comments) - message = reader.format_message('INFORMATION', - 'found file %r' % (path), - item.span[0], item.span[1]) - reader.show_message(message, sys.stdout) - self.reader = FortranFileReader(path, include_dirs = include_dirs) - return self.reader.next(ignore_comments = ignore_comments) - return item - except StopIteration: - raise - except: - message = self.format_message('FATAL ERROR', - 'while processing line', - self.linecount, self.linecount) - self.show_message(message, sys.stdout) - traceback.print_exc(file=sys.stdout) - self.show_message(red_text('STOPPED READING'), sys.stdout) - raise StopIteration - - def _next(self, ignore_comments = False): - fifo_item_pop = self.fifo_item.pop - while 1: - try: - item = fifo_item_pop(0) - except IndexError: - item = self.get_source_item() - if item is None: - raise StopIteration - if not item.isempty(ignore_comments): - break - # else ignore empty lines and comments - if not isinstance(item, Comment): - if not self.ispyf and isinstance(item, Line) \ - and not item.is_f2py_directive \ - and ';' in item.get_line(): - # ;-separator not recognized in pyf-mode - items = [] - for line in item.get_line().split(';'): - line = line.strip() - items.append(item.copy(line, apply_map=True)) - items.reverse() - for newitem in items: - self.fifo_item.insert(0, newitem) - return fifo_item_pop(0) - return item - # collect subsequent comments to one comment instance - comments = [] - start = item.span[0] - while isinstance(item, Comment): - comments.append(item.comment) - end = item.span[1] - while 1: - try: - item = fifo_item_pop(0) - except IndexError: - item = self.get_source_item() - if item is None or not item.isempty(ignore_comments): - break - if item is None: - break # hold raising StopIteration for the next call. - if item is not None: - self.fifo_item.insert(0,item) - return self.comment_item('\n'.join(comments), start, end) - - # Interface to returned items: - - def line_item(self, line, startlineno, endlineno, label, errmessage=None): - if errmessage is None: - return Line(line, (startlineno, endlineno), label, self) - return SyntaxErrorLine(line, (startlineno, endlineno), - label, self, errmessage) - - def multiline_item(self, prefix, lines, suffix, - startlineno, endlineno, errmessage=None): - if errmessage is None: - return MultiLine(prefix, lines, suffix, (startlineno, endlineno), self) - return SyntaxErrorMultiLine(prefix, lines, suffix, - (startlineno, endlineno), self, errmessage) - - def comment_item(self, comment, startlineno, endlineno): - return Comment(comment, (startlineno, endlineno), self) - - # For handling messages: - - def show_message(self, message, stream = sys.stdout): - stream.write(message+'\n') - stream.flush() - return - - def format_message(self, kind, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - back_index = {'warning':2,'error':3,'info':0}.get(kind.lower(),3) - r = ['%s while processing %r (mode=%r)..' % (kind, self.id, self.mode)] - for i in range(max(1,startlineno-back_index),startlineno): - r.append('%5d:%s' % (i,self.source_lines[i-1])) - for i in range(startlineno,min(endlineno+back_index,len(self.source_lines))+1): - if i==0 and not self.source_lines: - break - linenostr = '%5d:' % (i) - if i==endlineno: - sourceline = self.source_lines[i-1] - l0 = linenostr+sourceline[:startcolno] - if endcolno==-1: - l1 = sourceline[startcolno:] - l2 = '' - else: - l1 = sourceline[startcolno:endcolno] - l2 = sourceline[endcolno:] - r.append('%s%s%s <== %s' % (l0,yellow_text(l1),l2,red_text(message))) - else: - r.append(linenostr+ self.source_lines[i-1]) - return '\n'.join(r) - - def format_error_message(self, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - return self.format_message('ERROR',message, startlineno, - endlineno, startcolno, endcolno) - - def format_warning_message(self, message, startlineno, endlineno, - startcolno=0, endcolno=-1): - return self.format_message('WARNING',message, startlineno, - endlineno, startcolno, endcolno) - - def error(self, message, item=None): - if item is None: - m = self.format_error_message(message, len(self.source_lines)-2, len(self.source_lines)) - else: - m = self.format_error_message(message, item.span[0], item.span[1]) - self.show_message(m) - return - - def warning(self, message, item=None): - if item is None: - m = self.format_warning_message(message, len(self.source_lines)-2, len(self.source_lines)) - else: - m = self.format_warning_message(message, item.span[0], item.span[1]) - self.show_message(m) - return - - # Auxiliary methods for processing raw source lines: - - def handle_cf2py_start(self, line): - """ - f2py directives can be used only in Fortran codes. - They are ignored when used inside .pyf files. - """ - if not line or self.ispyf: return line - if self.isfix: - if line[0] in '*cC!#': - if line[1:5].lower() == 'f2py': - line = 5*' ' + line[5:] - self.f2py_comment_lines.append(self.linecount) - if self.isfix77: - return line - m = _cf2py_re.match(line) - if m: - newline = m.group('indent')+5*' '+m.group('rest') - self.f2py_comment_lines.append(self.linecount) - assert len(newline)==len(line),`newlinel,line` - return newline - return line - - def handle_inline_comment(self, line, lineno, quotechar=None): - if quotechar is None and '!' not in line and \ - '"' not in line and "'" not in line: - return line, quotechar - i = line.find('!') - put_item = self.fifo_item.append - if quotechar is None and i!=-1: - # first try a quick method - newline = line[:i] - if '"' not in newline and '\'' not in newline: - if self.isfix77 or not line[i:].startswith('!f2py'): - put_item(self.comment_item(line[i:], lineno, lineno)) - return newline, quotechar - # handle cases where comment char may be a part of a character content - #splitter = LineSplitter(line, quotechar) - #items = [item for item in splitter] - #newquotechar = splitter.quotechar - items, newquotechar = splitquote(line, quotechar) - - noncomment_items = [] - noncomment_items_append = noncomment_items.append - n = len(items) - commentline = None - for k in range(n): - item = items[k] - if isinstance(item, String) or '!' not in item: - noncomment_items_append(item) - continue - j = item.find('!') - noncomment_items_append(item[:j]) - items[k] = item[j:] - commentline = ''.join(items[k:]) - break - if commentline is not None: - if commentline.startswith('!f2py'): - # go to next iteration: - newline = ''.join(noncomment_items) + commentline[5:] - self.f2py_comment_lines.append(lineno) - return self.handle_inline_comment(newline, lineno, quotechar) - put_item(self.comment_item(commentline, lineno, lineno)) - return ''.join(noncomment_items), newquotechar - - def handle_multilines(self, line, startlineno, mlstr): - i = line.find(mlstr) - if i != -1: - prefix = line[:i] - # skip fake multiline starts - p,k = prefix,0 - while p.endswith('\\'): - p,k = p[:-1],k+1 - if k % 2: return - if i != -1 and '!' not in prefix: - # Note character constans like 'abc"""123', - # so multiline prefix should better not contain `'' or `"' not `!'. - for quote in '"\'': - if prefix.count(quote) % 2: - message = self.format_warning_message(\ - 'multiline prefix contains odd number of %r characters' \ - % (quote), startlineno, startlineno, - 0, len(prefix)) - self.show_message(message, sys.stderr) - - suffix = None - multilines = [] - line = line[i+3:] - while line is not None: - j = line.find(mlstr) - if j != -1 and '!' not in line[:j]: - multilines.append(line[:j]) - suffix = line[j+3:] - break - multilines.append(line) - line = self.get_single_line() - if line is None: - message = self.format_error_message(\ - 'multiline block never ends', startlineno, - startlineno, i) - return self.multiline_item(\ - prefix,multilines,suffix,\ - startlineno, self.linecount, message) - suffix,qc = self.handle_inline_comment(suffix, self.linecount) - # no line continuation allowed in multiline suffix - if qc is not None: - message = self.format_message(\ - 'ASSERTION FAILURE(pyf)', - 'following character continuation: %r, expected None.' % (qc), - startlineno, self.linecount) - self.show_message(message, sys.stderr) - # XXX: should we do line.replace('\\'+mlstr[0],mlstr[0]) - # for line in multilines? - return self.multiline_item(prefix,multilines,suffix, - startlineno, self.linecount) - - # The main method of interpreting raw source lines within - # the following contexts: f77, fixed f90, free f90, pyf. - - def get_source_item(self): - """ - a source item is .. - - a fortran line - - a list of continued fortran lines - - a multiline - lines inside triple-qoutes, only when in ispyf mode - """ - get_single_line = self.get_single_line - line = get_single_line() - if line is None: return - startlineno = self.linecount - line = self.handle_cf2py_start(line) - is_f2py_directive = startlineno in self.f2py_comment_lines - - label = None - if self.ispyf: - # handle multilines - for mlstr in ['"""',"'''"]: - r = self.handle_multilines(line, startlineno, mlstr) - if r: return r - - if self.isfix: - label = line[:5].strip().lower() - if label.endswith(':'): label = label[:-1].strip() - if not line.strip(): - # empty line - return self.line_item(line[6:],startlineno,self.linecount,label) - if _is_fix_comment(line): - return self.comment_item(line, startlineno, startlineno) - for i in range(5): - if line[i] not in _spacedigits: - message = 'non-space/digit char %r found in column %i'\ - ' of fixed Fortran code' % (line[i],i+1) - if self.isfix90: - message = message + ', switching to free format mode' - message = self.format_warning_message(\ - message,startlineno, self.linecount) - self.show_message(message, sys.stderr) - self.set_mode(True, False) - else: - return self.line_item(line[6:], startlineno, self.linecount, - label, self.format_error_message(\ - message, startlineno, self.linecount)) - - if self.isfix77 and not is_f2py_directive: - lines = [line[6:72]] - while _is_fix_cont(self.get_next_line()): - # handle fix format line continuations for F77 code - line = get_single_line() - lines.append(line[6:72]) - return self.line_item(''.join(lines),startlineno,self.linecount,label) - - handle_inline_comment = self.handle_inline_comment - - if self.isfix90 and not is_f2py_directive: - # handle inline comment - newline,qc = handle_inline_comment(line[6:], startlineno) - lines = [newline] - next_line = self.get_next_line() - while _is_fix_cont(next_line) or _is_fix_comment(next_line): - # handle fix format line continuations for F90 code. - # mixing fix format and f90 line continuations is not allowed - # nor detected, just eject warnings. - line2 = get_single_line() - if _is_fix_comment(line2): - # handle fix format comments inside line continuations - citem = self.comment_item(line2,self.linecount,self.linecount) - self.fifo_item.append(citem) - else: - newline, qc = self.handle_inline_comment(line2[6:], - self.linecount, qc) - lines.append(newline) - next_line = self.get_next_line() - # no character continuation should follows now - if qc is not None: - message = self.format_message(\ - 'ASSERTION FAILURE(fix90)', - 'following character continuation: %r, expected None.'\ - % (qc), startlineno, self.linecount) - self.show_message(message, sys.stderr) - if len(lines)>1: - for i in range(len(lines)): - l = lines[i] - if l.rstrip().endswith('&'): - message = self.format_warning_message(\ - 'f90 line continuation character `&\' detected'\ - ' in fix format code', - startlineno + i, startlineno + i, l.rfind('&')+5) - self.show_message(message, sys.stderr) - return self.line_item(''.join(lines),startlineno, - self.linecount,label) - start_index = 0 - if self.isfix90: - start_index = 6 - - lines = [] - lines_append = lines.append - put_item = self.fifo_item.append - qc = None - while line is not None: - if start_index: # fix format code - line,qc = handle_inline_comment(line[start_index:], - self.linecount,qc) - is_f2py_directive = self.linecount in self.f2py_comment_lines - else: - line_lstrip = line.lstrip() - if lines: - if line_lstrip.startswith('!'): - # check for comment line within line continuation - put_item(self.comment_item(line_lstrip, - self.linecount, self.linecount)) - line = get_single_line() - continue - else: - # first line, check for a f90 label - m = _f90label_re.match(line) - if m: - assert not label,`label,m.group('label')` - label = m.group('label').strip() - if label.endswith(':'): label = label[:-1].strip() - if not self.ispyf: label = label.lower() - line = line[m.end():] - line,qc = handle_inline_comment(line, self.linecount, qc) - is_f2py_directive = self.linecount in self.f2py_comment_lines - - i = line.rfind('&') - if i!=-1: - line_i1_rstrip = line[i+1:].rstrip() - if not lines: - # first line - if i == -1 or line_i1_rstrip: - lines_append(line) - break - lines_append(line[:i]) - line = get_single_line() - continue - if i == -1 or line_i1_rstrip: - # no line continuation follows - i = len(line) - k = -1 - if i != -1: - # handle the beggining of continued line - k = line[:i].find('&') - if k != 1 and line[:k].lstrip(): - k = -1 - lines_append(line[k+1:i]) - if i==len(line): - break - line = get_single_line() - - if qc is not None: - message = self.format_message('ASSERTION FAILURE(free)', - 'following character continuation: %r, expected None.' % (qc), - startlineno, self.linecount) - self.show_message(message, sys.stderr) - return self.line_item(''.join(lines),startlineno,self.linecount,label) - - ## FortranReaderBase - -# Fortran file and string readers: - -class FortranFileReader(FortranReaderBase): - - def __init__(self, filename, - include_dirs = None): - isfree, isstrict = get_source_info(filename) - self.id = filename - self.file = open(filename,'r') - FortranReaderBase.__init__(self, self.file, isfree, isstrict) - if include_dirs is None: - self.include_dirs.insert(0, os.path.dirname(filename)) - else: - self.include_dirs = include_dirs[:] - return - - def close_source(self): - self.file.close() - -class FortranStringReader(FortranReaderBase): - - def __init__(self, string, isfree, isstrict, include_dirs = None): - self.id = 'string-'+str(id(string)) - source = StringIO(string) - FortranReaderBase.__init__(self, source, isfree, isstrict) - if include_dirs is not None: - self.include_dirs = include_dirs[:] - return - -# Testing: - -def test_f77(): - string_f77 = """ -c12346 comment - subroutine foo - call foo - 'bar -a 'g - abc=2 -cf2py call me ! hey - call you ! hi - end - '""" - reader = FortranStringReader(string_f77,False,True) - for item in reader: - print item - - filename = tempfile.mktemp()+'.f' - f = open(filename,'w') - f.write(string_f77) - f.close() - - reader = FortranFileReader(filename) - for item in reader: - print item - -def test_pyf(): - string_pyf = """\ -python module foo - interface - beginml '''1st line - 2nd line - end line'''endml='tere!fake comment'!should be a comment - a = 2 - 'charc\"onstant' ''' single line mline '''a='hi!fake comment'!should be a comment - a=\\\\\\\\\\'''not a multiline''' - !blah='''never ending multiline - b=3! hey, fake line continuation:& - c=4& !line cont - &45 - thisis_label_2 : c = 3 - xxif_isotropic_2 : if ( string_upper_compare ( o%opt_aniso, 'ISOTROPIC' ) ) then - g=3 - endif - end interface - if ( pc_get_lun() .ne. 6) & - - write ( pc_get_lun(), '( & - & /, a, /, " p=", i4, " stopping c_flag=", a, & - & /, " print unit=", i8)') & - trim(title), pcpsx_i_pel(), trim(c_flag), pc_get_lun() -end python module foo -! end of file -""" - reader = FortranStringReader(string_pyf,True, True) - for item in reader: - print item - -def test_fix90(): - string_fix90 = """\ - subroutine foo -cComment - 1234 a = 3 !inline comment - b = 3 -! - !4!line cont. with comment symbol - &5 - a = 3!f2py.14 ! pi! -! KDMO - write (obj%print_lun, *) ' KDMO : ' - write (obj%print_lun, *) ' COORD = ',coord, ' BIN_WID = ', & - obj%bin_wid,' VEL_DMO = ', obj%vel_dmo - end subroutine foo - subroutine - - & foo - end -""" - reader = FortranStringReader(string_fix90,False, False) - for item in reader: - print item - -def simple_main(): - for filename in sys.argv[1:]: - print 'Processing',filename - reader = FortranFileReader(filename) - for item in reader: - print >> sys.stdout, item - sys.stdout.flush() - pass - -def profile_main(): - import hotshot, hotshot.stats - prof = hotshot.Profile("readfortran.prof") - prof.runcall(simple_main) - prof.close() - stats = hotshot.stats.load("readfortran.prof") - stats.strip_dirs() - stats.sort_stats('time', 'calls') - stats.print_stats(30) - -if __name__ == "__main__": - #test_pyf() - #test_fix90() - #profile_main() - simple_main() diff --git a/numpy/f2py/lib/parser/sourceinfo.py b/numpy/f2py/lib/parser/sourceinfo.py deleted file mode 100644 index 7eb980251..000000000 --- a/numpy/f2py/lib/parser/sourceinfo.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Provides get_source_info(<filename>) function to determine the format -(free|fixed|strict|pyf) of a Fortran file. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['get_source_info'] - -import re -import os -import sys - -_has_f_extension = re.compile(r'.*[.](for|ftn|f77|f)\Z',re.I).match -_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-',re.I).search -_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-',re.I).search -_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-',re.I).search -_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]',re.I).match - -def get_source_info(filename): - """ - Determine if fortran file is - - in fix format and contains Fortran 77 code -> return False, True - - in fix format and contains Fortran 90 code -> return False, False - - in free format and contains Fortran 90 code -> return True, False - - in free format and contains signatures (.pyf) -> return True, True - """ - base,ext = os.path.splitext(filename) - if ext=='.pyf': - return True, True - isfree = False - isstrict = False - f = open(filename,'r') - firstline = f.readline() - f.close() - if _has_f_extension(filename) and \ - not (_has_f90_header(firstline) or _has_fix_header(firstline)): - isstrict = True - elif is_free_format(filename) and not _has_fix_header(firstline): - isfree = True - return isfree,isstrict - -def is_free_format(file): - """Check if file is in free format Fortran.""" - # f90 allows both fixed and free format, assuming fixed unless - # signs of free format are detected. - isfree = False - f = open(file,'r') - line = f.readline() - n = 10000 # the number of non-comment lines to scan for hints - if _has_f_header(line): - n = 0 - elif _has_f90_header(line): - n = 0 - isfree = True - contline = False - while n>0 and line: - line = line.rstrip() - if line and line[0]!='!': - n -= 1 - if line[0]!='\t' and _free_f90_start(line[:5]) or line[-1:]=='&': - isfree = True - break - line = f.readline() - f.close() - return isfree - -def simple_main(): - for filename in sys.argv[1:]: - isfree, isstrict = get_source_info(filename) - print '%s: isfree=%s, isstrict=%s' % (filename, isfree, isstrict) - -if __name__ == '__main__': - simple_main() diff --git a/numpy/f2py/lib/parser/splitline.py b/numpy/f2py/lib/parser/splitline.py deleted file mode 100644 index 9d4a40fc5..000000000 --- a/numpy/f2py/lib/parser/splitline.py +++ /dev/null @@ -1,426 +0,0 @@ -#!/usr/bin/env python -""" -Defines LineSplitter and helper functions. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['String','string_replace_map','splitquote','splitparen'] - -import re - -class String(str): pass -class ParenString(str): pass - -def split2(line, lower=False): - """ - Split line into non-string part and into a start of a string part. - Returns 2-tuple. The second item either is empty string or start - of a string part. - """ - return LineSplitter(line,lower=lower).split2() - -_f2py_str_findall = re.compile(r"_F2PY_STRING_CONSTANT_\d+_").findall -_is_name = re.compile(r'\w*\Z',re.I).match -_is_simple_str = re.compile(r'\w*\Z',re.I).match -_f2py_findall = re.compile(r'(_F2PY_STRING_CONSTANT_\d+_|F2PY_EXPR_TUPLE_\d+)').findall - -class string_replace_dict(dict): - """ - Dictionary object that is callable for applying map returned - by string_replace_map() function. - """ - def __call__(self, line): - for k in _f2py_findall(line): - line = line.replace(k, self[k]) - return line - -def string_replace_map(line, lower=False, - _cache={'index':0,'pindex':0}): - """ - 1) Replaces string constants with symbol `'_F2PY_STRING_CONSTANT_<index>_'` - 2) Replaces (expression) with symbol `(F2PY_EXPR_TUPLE_<index>)` - Returns a new line and the replacement map. - """ - items = [] - string_map = string_replace_dict() - rev_string_map = {} - for item in splitquote(line, lower=lower)[0]: - if isinstance(item, String) and not _is_simple_str(item[1:-1]): - key = rev_string_map.get(item) - if key is None: - _cache['index'] += 1 - index = _cache['index'] - key = "_F2PY_STRING_CONSTANT_%s_" % (index) - it = item[1:-1] - string_map[key] = it - rev_string_map[it] = key - items.append(item[0]+key+item[-1]) - else: - items.append(item) - newline = ''.join(items) - items = [] - expr_keys = [] - for item in splitparen(newline): - if isinstance(item, ParenString) and not _is_name(item[1:-1]): - key = rev_string_map.get(item) - if key is None: - _cache['pindex'] += 1 - index = _cache['pindex'] - key = 'F2PY_EXPR_TUPLE_%s' % (index) - it = item[1:-1].strip() - string_map[key] = it - rev_string_map[it] = key - expr_keys.append(key) - items.append(item[0]+key+item[-1]) - else: - items.append(item) - found_keys = set() - for k in expr_keys: - v = string_map[k] - l = _f2py_str_findall(v) - if l: - found_keys = found_keys.union(l) - for k1 in l: - v = v.replace(k1, string_map[k1]) - string_map[k] = v - for k in found_keys: - del string_map[k] - return ''.join(items), string_map - -def splitquote(line, stopchar=None, lower=False, quotechars = '"\''): - """ - Fast LineSplitter - """ - items = [] - i = 0 - while 1: - try: - char = line[i]; i += 1 - except IndexError: - break - l = [] - l_append = l.append - nofslashes = 0 - if stopchar is None: - # search for string start - while 1: - if char in quotechars and not nofslashes % 2: - stopchar = char - i -= 1 - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - if not l: continue - item = ''.join(l) - if lower: item = item.lower() - items.append(item) - continue - if char==stopchar: - # string starts with quotechar - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - if l: - item = String(''.join(l)) - items.append(item) - break - # else continued string - while 1: - if char==stopchar and not nofslashes % 2: - l_append(char) - stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - if l: - item = String(''.join(l)) - items.append(item) - return items, stopchar - -class LineSplitterBase: - - def __iter__(self): - return self - - def next(self): - item = '' - while not item: - item = self.get_item() # get_item raises StopIteration - return item - -class LineSplitter(LineSplitterBase): - """ Splits a line into non strings and strings. E.g. - abc=\"123\" -> ['abc=','\"123\"'] - Handles splitting lines with incomplete string blocks. - """ - def __init__(self, line, - quotechar = None, - lower=False, - ): - self.fifo_line = [c for c in line] - self.fifo_line.reverse() - self.quotechar = quotechar - self.lower = lower - - def split2(self): - """ - Split line until the first start of a string. - """ - try: - item1 = self.get_item() - except StopIteration: - return '','' - i = len(item1) - l = self.fifo_line[:] - l.reverse() - item2 = ''.join(l) - return item1,item2 - - def get_item(self): - fifo_pop = self.fifo_line.pop - try: - char = fifo_pop() - except IndexError: - raise StopIteration - fifo_append = self.fifo_line.append - quotechar = self.quotechar - l = [] - l_append = l.append - - nofslashes = 0 - if quotechar is None: - # search for string start - while 1: - if char in '"\'' and not nofslashes % 2: - self.quotechar = char - fifo_append(char) - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - item = ''.join(l) - if self.lower: item = item.lower() - return item - - if char==quotechar: - # string starts with quotechar - l_append(char) - try: - char = fifo_pop() - except IndexError: - return String(''.join(l)) - # else continued string - while 1: - if char==quotechar and not nofslashes % 2: - l_append(char) - self.quotechar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - return String(''.join(l)) - -def splitparen(line,paren='()'): - """ - Fast LineSplitterParen. - """ - stopchar = None - startchar, endchar = paren[0],paren[1] - - items = [] - i = 0 - while 1: - try: - char = line[i]; i += 1 - except IndexError: - break - nofslashes = 0 - l = [] - l_append = l.append - if stopchar is None: - # search for parenthesis start - while 1: - if char==startchar and not nofslashes % 2: - stopchar = endchar - i -= 1 - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - item = ''.join(l) - else: - nofstarts = 0 - while 1: - if char==stopchar and not nofslashes % 2 and nofstarts==1: - l_append(char) - stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - if char==startchar: - nofstarts += 1 - elif char==endchar: - nofstarts -= 1 - l_append(char) - try: - char = line[i]; i += 1 - except IndexError: - break - item = ParenString(''.join(l)) - items.append(item) - return items - -class LineSplitterParen(LineSplitterBase): - """ Splits a line into strings and strings with parenthesis. E.g. - a(x) = b(c,d) -> ['a','(x)',' = b','(c,d)'] - """ - def __init__(self, line, paren = '()'): - self.fifo_line = [c for c in line] - self.fifo_line.reverse() - self.startchar = paren[0] - self.endchar = paren[1] - self.stopchar = None - - def get_item(self): - fifo_pop = self.fifo_line.pop - try: - char = fifo_pop() - except IndexError: - raise StopIteration - fifo_append = self.fifo_line.append - startchar = self.startchar - endchar = self.endchar - stopchar = self.stopchar - l = [] - l_append = l.append - - nofslashes = 0 - if stopchar is None: - # search for parenthesis start - while 1: - if char==startchar and not nofslashes % 2: - self.stopchar = endchar - fifo_append(char) - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - item = ''.join(l) - return item - - nofstarts = 0 - while 1: - if char==stopchar and not nofslashes % 2 and nofstarts==1: - l_append(char) - self.stopchar = None - break - if char=='\\': - nofslashes += 1 - else: - nofslashes = 0 - if char==startchar: - nofstarts += 1 - elif char==endchar: - nofstarts -= 1 - l_append(char) - try: - char = fifo_pop() - except IndexError: - break - return ParenString(''.join(l)) - -def test(): - splitter = LineSplitter('abc\\\' def"12\\"3""56"dfad\'a d\'') - l = [item for item in splitter] - assert l==['abc\\\' def','"12\\"3"','"56"','dfad','\'a d\''],`l` - assert splitter.quotechar is None - l,stopchar=splitquote('abc\\\' def"12\\"3""56"dfad\'a d\'') - assert l==['abc\\\' def','"12\\"3"','"56"','dfad','\'a d\''],`l` - assert stopchar is None - - splitter = LineSplitter('"abc123&') - l = [item for item in splitter] - assert l==['"abc123&'],`l` - assert splitter.quotechar=='"' - l,stopchar = splitquote('"abc123&') - assert l==['"abc123&'],`l` - assert stopchar=='"' - - splitter = LineSplitter(' &abc"123','"') - l = [item for item in splitter] - assert l==[' &abc"','123'] - assert splitter.quotechar is None - l,stopchar = splitquote(' &abc"123','"') - assert l==[' &abc"','123'] - assert stopchar is None - - l = split2('') - assert l==('',''),`l` - l = split2('12') - assert l==('12',''),`l` - l = split2('1"a"//"b"') - assert l==('1','"a"//"b"'),`l` - l = split2('"ab"') - assert l==('','"ab"'),`l` - - splitter = LineSplitterParen('a(b) = b(x,y(1)) b\((a)\)') - l = [item for item in splitter] - assert l==['a', '(b)', ' = b', '(x,y(1))', ' b\\(', '(a)', '\\)'],`l` - l = splitparen('a(b) = b(x,y(1)) b\((a)\)') - assert l==['a', '(b)', ' = b', '(x,y(1))', ' b\\(', '(a)', '\\)'],`l` - - l = string_replace_map('a()') - print l - print 'ok' - -if __name__ == '__main__': - test() diff --git a/numpy/f2py/lib/parser/statements.py b/numpy/f2py/lib/parser/statements.py deleted file mode 100644 index 119216d4c..000000000 --- a/numpy/f2py/lib/parser/statements.py +++ /dev/null @@ -1,1856 +0,0 @@ -""" -Fortran single line statements. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['GeneralAssignment', - 'Assignment','PointerAssignment','Assign','Call','Goto','ComputedGoto','AssignedGoto', - 'Continue','Return','Stop','Print','Read','Read0','Read1','Write','Flush','Wait', - 'Contains','Allocate','Deallocate','ModuleProcedure','Access','Public','Private', - 'Close','Cycle','Backspace','Endfile','Rewind','Open','Format','Save', - 'Data','Nullify','Use','Exit','Parameter','Equivalence','Dimension','Target', - 'Pointer','Protected','Volatile','Value','ArithmeticIf','Intrinsic', - 'Inquire','Sequence','External','Namelist','Common','Optional','Intent', - 'Entry','Import','ForallStmt','SpecificBinding','GenericBinding', - 'FinalBinding','Allocatable','Asynchronous','Bind','Else','ElseIf', - 'Case','WhereStmt','ElseWhere','Enumerator','FortranName','Threadsafe', - 'Depend','Check','CallStatement','CallProtoArgument','Pause'] - -import re -import sys - -from base_classes import Statement, Variable - -# Auxiliary tools - -from utils import split_comma, specs_split_comma, AnalyzeError, ParseError,\ - get_module_file, parse_bind, parse_result, is_name - -class StatementWithNamelist(Statement): - """ - <statement> [ :: ] <name-list> - """ - def process_item(self): - if self.item.has_map(): - self.isvalid = False - return - if hasattr(self,'stmtname'): - clsname = self.stmtname - else: - clsname = self.__class__.__name__ - line = self.item.get_line()[len(clsname):].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = items = [] - for item in split_comma(line): - if not is_name(item): - self.isvalid = False - return - items.append(item) - return - - def tofortran(self,isfix=None): - if hasattr(self,'stmtname'): - clsname = self.stmtname.upper() - else: - clsname = self.__class__.__name__.upper() - s = ', '.join(self.items) - if s: - s = ' ' + s - return self.get_indent_tab(isfix=isfix) + clsname + s - -# Execution statements - -class GeneralAssignment(Statement): - """ - <variable> = <expr> - <pointer variable> => <expr> - """ - - match = re.compile(r'\w[^=]*\s*=\>?').match - item_re = re.compile(r'(?P<variable>\w[^=]*)\s*(?P<sign>=\>?)\s*(?P<expr>.*)\Z',re.I).match - _repr_attr_names = ['variable','sign','expr'] + Statement._repr_attr_names - - def process_item(self): - m = self.item_re(self.item.get_line()) - if not m: - self.isvalid = False - return - self.sign = sign = m.group('sign') - if isinstance(self, Assignment) and sign != '=': - self.isvalid = False - return - elif isinstance(self, PointerAssignment) and sign != '=>': - self.isvalid = False - return - else: - if sign=='=>': - self.__class__ = PointerAssignment - else: - self.__class__ = Assignment - apply_map = self.item.apply_map - self.variable = apply_map(m.group('variable').replace(' ','')) - self.expr = apply_map(m.group('expr')) - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + '%s %s %s' \ - % (self.variable, self.sign, self.expr) - - def analyze(self): return - -class Assignment(GeneralAssignment): - pass - -class PointerAssignment(GeneralAssignment): - pass - -class Assign(Statement): - """ - ASSIGN <label> TO <int-variable-name> - """ - modes = ['fix77'] - match = re.compile(r'assign\s*\d+\s*to\s*\w+\s*\Z',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.lower().find('to') - assert not self.item.has_map() - self.items = [line[:i].rstrip(),line[i+2:].lstrip()] - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'ASSIGN %s TO %s' \ - % (self.items[0], self.items[1]) - def analyze(self): return - -class Call(Statement): - """Call statement class - CALL <procedure-designator> [ ( [ <actual-arg-spec-list> ] ) ] - - <procedure-designator> = <procedure-name> - | <proc-component-ref> - | <data-ref> % <binding-name> - - <actual-arg-spec> = [ <keyword> = ] <actual-arg> - <actual-arg> = <expr> - | <variable> - | <procedure-name> - | <proc-component-ref> - | <alt-return-spec> - <alt-return-spec> = * <label> - - <proc-component-ref> = <variable> % <procedure-component-name> - - <variable> = <designator> - - Call instance has attributes: - designator - arg_list - """ - match = re.compile(r'call\b', re.I).match - - def process_item(self): - item = self.item - apply_map = item.apply_map - line = item.get_line()[4:].strip() - i = line.find('(') - items = [] - if i==-1: - self.designator = apply_map(line).strip() - else: - j = line.find(')') - if j == -1 or len(line)-1 != j: - self.isvalid = False - return - self.designator = apply_map(line[:i]).strip() - items = split_comma(line[i+1:-1], item) - self.items = items - return - - def tofortran(self, isfix=None): - s = self.get_indent_tab(isfix=isfix) + 'CALL '+str(self.designator) - if self.items: - s += '('+', '.join(map(str,self.items))+ ')' - return s - - def analyze(self): - a = self.programblock.a - variables = a.variables - if hasattr(a, 'external'): - external = a.external - if self.designator in external: - print >> sys.stderr, 'Need to analyze:',self - return - -class Goto(Statement): - """ - GO TO <label> - """ - match = re.compile(r'go\s*to\s*\d+\s*\Z', re.I).match - - def process_item(self): - assert not self.item.has_map() - self.label = self.item.get_line()[2:].lstrip()[2:].lstrip() - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'GO TO %s' % (self.label) - def analyze(self): return - -class ComputedGoto(Statement): - """ - GO TO ( <label-list> ) [ , ] <scalar-int-expr> - """ - match = re.compile(r'go\s*to\s*\(',re.I).match - def process_item(self): - apply_map = self.item.apply_map - line = self.item.get_line()[2:].lstrip()[2:].lstrip() - i = line.index(')') - self.items = split_comma(line[1:i], self.item) - line = line[i+1:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - self.expr = apply_map(line) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'GO TO (%s) %s' \ - % (', '.join(self.items), self.expr) - def analyze(self): return - -class AssignedGoto(Statement): - """ - GO TO <int-variable-name> [ ( <label> [ , <label> ]... ) ] - """ - modes = ['fix77'] - match = re.compile(r'go\s*to\s*\w+\s*\(?',re.I).match - def process_item(self): - line = self.item.get_line()[2:].lstrip()[2:].lstrip() - i = line.find('(') - if i==-1: - self.varname = line - self.items = [] - return - self.varname = line[:i].rstrip() - assert line[-1]==')',`line` - self - self.items = split_comma(line[i+1:-1], self.item) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - if self.items: - return tab + 'GO TO %s (%s)' \ - % (self.varname, ', '.join(self.items)) - return tab + 'GO TO %s' % (self.varname) - def analyze(self): return - -class Continue(Statement): - """ - CONTINUE - """ - match = re.compile(r'continue\Z',re.I).match - - def process_item(self): - self.label = self.item.label - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(deindent=True) + 'CONTINUE' - - def analyze(self): return - -class Return(Statement): - """ - RETURN [ <scalar-int-expr> ] - """ - match = re.compile(r'return\b',re.I).match - - def process_item(self): - self.expr = self.item.apply_map(self.item.get_line()[6:].lstrip()) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - if self.expr: - return tab + 'RETURN %s' % (self.expr) - return tab + 'RETURN' - - def analyze(self): return - -class Stop(Statement): - """ - STOP [ <stop-code> ] - <stop-code> = <scalar-char-constant> | <1-5-digit> - """ - match = re.compile(r'stop\s*(\'\w*\'|"\w*"|\d+|)\Z',re.I).match - - def process_item(self): - self.code = self.item.apply_map(self.item.get_line()[4:].lstrip()) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - if self.code: - return tab + 'STOP %s' % (self.code) - return tab + 'STOP' - - def analyze(self): return - -class Print(Statement): - """ - PRINT <format> [, <output-item-list>] - <format> = <default-char-expr> | <label> | * - - <output-item> = <expr> | <io-implied-do> - <io-implied-do> = ( <io-implied-do-object-list> , <implied-do-control> ) - <io-implied-do-object> = <input-item> | <output-item> - <implied-do-control> = <do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] - <input-item> = <variable> | <io-implied-do> - """ - match = re.compile(r'print\s*(\'\w*\'|\"\w*\"|\d+|[*]|\b\w)', re.I).match - - def process_item(self): - item = self.item - apply_map = item.apply_map - line = item.get_line()[5:].lstrip() - items = split_comma(line, item) - self.format = items[0] - self.items = items[1:] - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'PRINT %s' \ - % (', '.join([self.format]+self.items)) - def analyze(self): return - -class Read(Statement): - """ -Read0: READ ( <io-control-spec-list> ) [ <input-item-list> ] - - <io-control-spec-list> = [ UNIT = ] <io-unit> - | [ FORMAT = ] <format> - | [ NML = ] <namelist-group-name> - | ADVANCE = <scalar-default-char-expr> - ... - -Read1: READ <format> [, <input-item-list>] - <format> == <default-char-expr> | <label> | * - """ - match = re.compile(r'read\b\s*[\w(*\'"]', re.I).match - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - if line.startswith('('): - self.__class__ = Read0 - else: - self.__class__ = Read1 - self.process_item() - return - def analyze(self): return - -class Read0(Read): - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - i = line.find(')') - self.specs = specs_split_comma(line[1:i], item) - self.items = split_comma(line[i+1:], item) - return - - def tofortran(self, isfix=None): - s = self.get_indent_tab(isfix=isfix) + 'READ (%s)' % (', '.join(self.specs)) - if self.items: - return s + ' ' + ', '.join(self.items) - return s - -class Read1(Read): - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip() - items = split_comma(line, item) - self.format = items[0] - self.items = items[1:] - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'READ ' \ - + ', '.join([self.format]+self.items) - -class Write(Statement): - """ - WRITE ( io-control-spec-list ) [<output-item-list>] - """ - match = re.compile(r'write\s*\(', re.I).match - def process_item(self): - item = self.item - line = item.get_line()[5:].lstrip() - i = line.find(')') - assert i != -1, `line` - self.specs = specs_split_comma(line[1:i], item) - self.items = split_comma(line[i+1:], item) - return - - def tofortran(self, isfix=None): - s = self.get_indent_tab(isfix=isfix) + 'WRITE (%s)' % ', '.join(self.specs) - if self.items: - s += ' ' + ', '.join(self.items) - return s - def analyze(self): return - - -class Flush(Statement): - """ - FLUSH <file-unit-number> - FLUSH ( <flush-spec-list> ) - <flush-spec> = [ UNIT = ] <file-unit-number> - | IOSTAT = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | ERR = <label> - """ - match = re.compile(r'flush\b',re.I).match - - def process_item(self): - line = self.item.get_line()[5:].lstrip() - if not line: - self.isvalid = False - return - if line.startswith('('): - assert line[-1] == ')', `line` - self.specs = specs_split_comma(line[1:-1],self.item) - else: - self.specs = specs_split_comma(line,self.item) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - return tab + 'FLUSH (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Wait(Statement): - """ - WAIT ( <wait-spec-list> ) - <wait-spec> = [ UNIT = ] <file-unit-number> - | END = <label> - | EOR = <label> - | ERR = <label> - | ID = <scalar-int-expr> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - - """ - match = re.compile(r'wait\s*\(.*\)\Z',re.I).match - def process_item(self): - self.specs = specs_split_comma(\ - self.item.get_line()[4:].lstrip()[1:-1], self.item) - return - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - return tab + 'WAIT (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Contains(Statement): - """ - CONTAINS - """ - match = re.compile(r'contains\Z',re.I).match - def process_item(self): return - def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) + 'CONTAINS' - -class Allocate(Statement): - """ - ALLOCATE ( [ <type-spec> :: ] <allocation-list> [ , <alloc-opt-list> ] ) - <alloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - | SOURCE = <source-expr> - <allocation> = <allocate-object> [ ( <allocate-shape-spec-list> ) ] - """ - match = re.compile(r'allocate\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[8:].lstrip()[1:-1].strip() - item2 = self.item.copy(line, True) - line2 = item2.get_line() - i = line2.find('::') - if i != -1: - spec = item2.apply_map(line2[:i].rstrip()) - from block_statements import type_spec - stmt = None - for cls in type_spec: - if cls.match(spec): - stmt = cls(self, item2.copy(spec)) - if stmt.isvalid: - break - if stmt is not None and stmt.isvalid: - spec = stmt - else: - self.warning('TODO: unparsed type-spec' + `spec`) - line2 = line2[i+2:].lstrip() - else: - spec = None - self.spec = spec - self.items = specs_split_comma(line2, item2) - return - - def tofortran(self, isfix=None): - t = '' - if self.spec: - t = self.spec.tostr() + ' :: ' - return self.get_indent_tab(isfix=isfix) \ - + 'ALLOCATE (%s%s)' % (t,', '.join(self.items)) - def analyze(self): return - -class Deallocate(Statement): - """ - DEALLOCATE ( <allocate-object-list> [ , <dealloc-opt-list> ] ) - <allocate-object> = <variable-name> - | <structure-component> - <structure-component> = <data-ref> - <dealloc-opt> = STAT = <stat-variable> - | ERRMSG = <errmsg-variable> - """ - match = re.compile(r'deallocate\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[10:].lstrip()[1:-1].strip() - self.items = specs_split_comma(line, self.item) - return - def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) \ - + 'DEALLOCATE (%s)' % (', '.join(self.items)) - def analyze(self): return - -class ModuleProcedure(Statement): - """ - [ MODULE ] PROCEDURE <procedure-name-list> - """ - match = re.compile(r'(module\s*|)procedure\b',re.I).match - def process_item(self): - line = self.item.get_line() - m = self.match(line) - assert m,`line` - items = split_comma(line[m.end():].strip(), self.item) - for n in items: - if not is_name(n): - self.isvalid = False - return - self.items = items - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - return tab + 'MODULE PROCEDURE %s' % (', '.join(self.items)) - - def analyze(self): - module_procedures = self.parent.a.module_procedures - module_procedures.extend(self.items) - # XXX: add names to parent_provides - return - -class Access(Statement): - """ - <access-spec> [ [::] <access-id-list>] - <access-spec> = PUBLIC | PRIVATE - <access-id> = <use-name> | <generic-spec> - """ - match = re.compile(r'(public|private)\b',re.I).match - def process_item(self): - clsname = self.__class__.__name__.lower() - line = self.item.get_line() - if not line.lower().startswith(clsname): - self.isvalid = False - return - line = line[len(clsname):].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - - def tofortran(self, isfix=None): - clsname = self.__class__.__name__.upper() - tab = self.get_indent_tab(isfix=isfix) - if self.items: - return tab + clsname + ' ' + ', '.join(self.items) - return tab + clsname - - def analyze(self): - clsname = self.__class__.__name__ - l = getattr(self.parent.a, clsname.lower() + '_id_list') - if self.items: - for name in self.items: - if name not in l: l.append(name) - else: - if '' not in l: - l.append('') - return - -class Public(Access): - is_public = True -class Private(Access): - is_public = False - -class Close(Statement): - """ - CLOSE ( <close-spec-list> ) - <close-spec> = [ UNIT = ] <file-unit-number> - | IOSTAT = <scalar-int-variable> - | IOMSG = <iomsg-variable> - | ERR = <label> - | STATUS = <scalar-default-char-expr> - """ - match = re.compile(r'close\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip()[1:-1].strip() - self.specs = specs_split_comma(line, self.item) - return - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - return tab + 'CLOSE (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Cycle(Statement): - """ - CYCLE [ <do-construct-name> ] - """ - match = re.compile(r'cycle\b\s*\w*\s*\Z',re.I).match - def process_item(self): - self.name = self.item.get_line()[5:].lstrip() - return - def tofortran(self, isfix=None): - if self.name: - return self.get_indent_tab(isfix=isfix) + 'CYCLE ' + self.name - return self.get_indent_tab(isfix=isfix) + 'CYCLE' - def analyze(self): return - -class FilePositioningStatement(Statement): - """ - REWIND <file-unit-number> - REWIND ( <position-spec-list> ) - <position-spec-list> = [ UNIT = ] <file-unit-number> - | IOMSG = <iomsg-variable> - | IOSTAT = <scalar-int-variable> - | ERR = <label> - The same for BACKSPACE, ENDFILE. - """ - match = re.compile(r'(rewind|backspace|endfile)\b',re.I).match - - def process_item(self): - clsname = self.__class__.__name__.lower() - line = self.item.get_line() - if not line.lower().startswith(clsname): - self.isvalid = False - return - line = line[len(clsname):].lstrip() - if line.startswith('('): - assert line[-1]==')',`line` - spec = line[1:-1].strip() - else: - spec = line - self.specs = specs_split_comma(spec, self.item) - return - - def tofortran(self, isfix=None): - clsname = self.__class__.__name__.upper() - return self.get_indent_tab(isfix=isfix) + clsname + ' (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Backspace(FilePositioningStatement): pass - -class Endfile(FilePositioningStatement): pass - -class Rewind(FilePositioningStatement): pass - -class Open(Statement): - """ - OPEN ( <connect-spec-list> ) - <connect-spec> = [ UNIT = ] <file-unit-number> - | ACCESS = <scalar-default-char-expr> - | .. - """ - match = re.compile(r'open\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[4:].lstrip()[1:-1].strip() - self.specs = specs_split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'OPEN (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Format(Statement): - """ - FORMAT <format-specification> - <format-specification> = ( [ <format-item-list> ] ) - <format-item> = [ <r> ] <data-edit-descr> - | <control-edit-descr> - | <char-string-edit-descr> - | [ <r> ] ( <format-item-list> ) - <data-edit-descr> = I <w> [ . <m> ] - | B <w> [ . <m> ] - ... - <r|w|m|d|e> = <int-literal-constant> - <v> = <signed-int-literal-constant> - <control-edit-descr> = <position-edit-descr> - | [ <r> ] / - | : - ... - <position-edit-descr> = T <n> - | TL <n> - ... - <sign-edit-descr> = SS | SP | S - ... - - """ - match = re.compile(r'format\s*\(.*\)\Z', re.I).match - def process_item(self): - item = self.item - if not item.label: - # R1001: - self.warning('R1001: FORMAT statement must be labeled but got %r.' \ - % (item.label)) - line = item.get_line()[6:].lstrip() - assert line[0]+line[-1]=='()',`line` - self.specs = split_comma(line[1:-1], item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'FORMAT (%s)' % (', '.join(self.specs)) - def analyze(self): return - -class Save(Statement): - """ - SAVE [ [ :: ] <saved-entity-list> ] - <saved-entity> = <object-name> - | <proc-pointer-name> - | / <common-block-name> / - <proc-pointer-name> = <name> - <object-name> = <name> - """ - match = re.compile(r'save\b',re.I).match - def process_item(self): - assert not self.item.has_map() - line = self.item.get_line()[4:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - items = [] - for s in line.split(','): - s = s.strip() - if not s: continue - if s.startswith('/'): - assert s.endswith('/'),`s` - n = s[1:-1].strip() - assert is_name(n),`n` - items.append('/%s/' % (n)) - elif is_name(s): - items.append(s) - else: - self.isvalid = False - return - self.items = items - return - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - if not self.items: - return tab + 'SAVE' - return tab + 'SAVE %s' % (', '.join(self.items)) - def analyze(self): return - -class Data(Statement): - """ - DATA <data-stmt-set> [ [ , ] <data-stmt-set> ]... - <data-stmt-set> = <data-stmt-object-list> / <data-stmt-value-list> / - <data-stmt-object> = <variable> | <data-implied-do> - <data-implied-do> = ( <data-i-do-object-list> , <data-i-do-variable> = <scalar-int-expr> , <scalar-int-expr> [ , <scalar-int-expr> ] ) - <data-i-do-object> = <array-element> | <scalar-structure-component> | <data-implied-do> - <data-i-do-variable> = <scalar-int-variable> - <variable> = <designator> - <designator> = <object-name> - | <array-element> - | <array-section> - | <structure-component> - | <substring> - <array-element> = <data-ref> - <array-section> = <data-ref> [ ( <substring-range> ) ] - - """ - match = re.compile(r'data\b',re.I).match - - def process_item(self): - line = self.item.get_line()[4:].lstrip() - stmts = [] - self.isvalid = False - while line: - i = line.find('/') - if i==-1: return - j = line.find('/',i+1) - if j==-1: return - l1, l2 = line[:i].rstrip(),line[i+1:j].strip() - l1 = split_comma(l1, self.item) - l2 = split_comma(l2, self.item) - stmts.append((l1,l2)) - line = line[j+1:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - self.stmts = stmts - self.isvalid = True - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - l = [] - for o,v in self.stmts: - l.append('%s / %s /' %(', '.join(o),', '.join(v))) - return tab + 'DATA ' + ' '.join(l) - def analyze(self): return - -class Nullify(Statement): - """ - NULLIFY ( <pointer-object-list> ) - <pointer-object> = <variable-name> - """ - match = re.compile(r'nullify\s*\(.*\)\Z',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip()[1:-1].strip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'NULLIFY (%s)' % (', '.join(self.items)) - def analyze(self): return - -class Use(Statement): - """ - USE [ [ , <module-nature> ] :: ] <module-name> [ , <rename-list> ] - USE [ [ , <module-nature> ] :: ] <module-name> , ONLY : [ <only-list> ] - <module-nature> = INTRINSIC | NON_INTRINSIC - <rename> = <local-name> => <use-name> - | OPERATOR ( <local-defined-operator> ) => OPERATOR ( <use-defined-operator> ) - <only> = <generic-spec> | <only-use-name> | <rename> - <only-use-name> = <use-name> - """ - match = re.compile(r'use\b',re.I).match - def process_item(self): - line = self.item.get_line()[3:].lstrip() - nature = '' - if line.startswith(','): - i = line.find('::') - nature = line[1:i].strip().upper() - line = line[i+2:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - if nature and not is_name(nature): - self.isvalid = False - return - self.nature = nature - i = line.find(',') - self.isonly = False - if i==-1: - self.name = line - self.items = [] - else: - self.name = line[:i].rstrip() - line = line[i+1:].lstrip() - if line.lower().startswith('only') and line[4:].lstrip().startswith(':'): - self.isonly = True - line = line[4:].lstrip()[1:].lstrip() - self.items = split_comma(line, self.item) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = 'USE' - if self.nature: - s += ' ' + self.nature + ' ::' - s += ' ' + self.name - if self.isonly: - s += ', ONLY:' - elif self.items: - s += ',' - if self.items: - s += ' ' + ', '.join(self.items) - return tab + s - - def analyze(self): - use = self.parent.a.use - if self.name in use: - return - - modules = self.top.a.module - if self.name not in modules: - fn = None - for d in self.reader.include_dirs: - fn = get_module_file(self.name, d) - if fn is not None: - break - if fn is not None: - from readfortran import FortranFileReader - from parsefortran import FortranParser - self.info('looking module information from %r' % (fn)) - reader = FortranFileReader(fn) - parser = FortranParser(reader) - parser.parse() - parser.block.a.module.update(modules) - parser.analyze() - modules.update(parser.block.a.module) - - if self.name not in modules: - self.warning('no information about the module %r in use statement' % (self.name)) - return - - module = modules[self.name] - use_provides = self.parent.a.use_provides - print use - - return - -class Exit(Statement): - """ - EXIT [ <do-construct-name> ] - """ - match = re.compile(r'exit\b\s*\w*\s*\Z',re.I).match - def process_item(self): - self.name = self.item.get_line()[4:].lstrip() - return - def tofortran(self, isfix=None): - if self.name: - return self.get_indent_tab(isfix=isfix) + 'EXIT ' + self.name - return self.get_indent_tab(isfix=isfix) + 'EXIT' - def analyze(self): return - -class Parameter(Statement): - """ - PARAMETER ( <named-constant-def-list> ) - <named-constant-def> = <named-constant> = <initialization-expr> - """ - match = re.compile(r'parameter\s*\(.*\)\Z', re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip()[1:-1].strip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'PARAMETER (%s)' % (', '.join(self.items)) - def analyze(self): - for item in self.items: - i = item.find('=') - assert i!=-1,`item` - name = item[:i].rstrip() - value = item[i+1:].lstrip() - var = self.get_variable(name) - var.update('parameter') - var.set_init(value) - return - -class Equivalence(Statement): - """ - EQUIVALENCE <equivalence-set-list> - <equivalence-set> = ( <equivalence-object> , <equivalence-object-list> ) - <equivalence-object> = <variable-name> | <array-element> | <substring> - """ - match = re.compile(r'equivalence\s*\(.*\)\Z', re.I).match - def process_item(self): - items = [] - for s in self.item.get_line()[11:].lstrip().split(','): - s = s.strip() - assert s[0]+s[-1]=='()',`s,self.item.get_line()` - s = ', '.join(split_comma(s[1:-1], self.item)) - items.append('('+s+')') - self.items = items - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'EQUIVALENCE %s' % (', '.join(self.items)) - def analyze(self): return - -class Dimension(Statement): - """ - DIMENSION [ :: ] <array-name> ( <array-spec> ) [ , <array-name> ( <array-spec> ) ]... - - """ - match = re.compile(r'dimension\b', re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'DIMENSION %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - assert i!=-1 and line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - return - -class Target(Statement): - """ - TARGET [ :: ] <object-name> ( <array-spec> ) [ , <object-name> ( <array-spec> ) ]... - - """ - match = re.compile(r'target\b', re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'TARGET %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - assert i!=-1 and line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - var.update('target') - return - - -class Pointer(Statement): - """ - POINTER [ :: ] <pointer-decl-list> - <pointer-decl> = <object-name> [ ( <deferred-shape-spec-list> ) ] - | <proc-entity-name> - - """ - match = re.compile(r'pointer\b',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'POINTER %s' % (', '.join(self.items)) - def analyze(self): - for line in self.items: - i = line.find('(') - if i==-1: - name = line - array_spec = None - else: - assert line.endswith(')'),`line` - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1].strip(), self.item) - var = self.get_variable(name) - var.set_bounds(array_spec) - var.update('pointer') - return - -class Protected(StatementWithNamelist): - """ - PROTECTED [ :: ] <entity-name-list> - """ - match = re.compile(r'protected\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('protected') - return - -class Volatile(StatementWithNamelist): - """ - VOLATILE [ :: ] <object-name-list> - """ - match = re.compile(r'volatile\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('volatile') - return - -class Value(StatementWithNamelist): - """ - VALUE [ :: ] <dummy-arg-name-list> - """ - match = re.compile(r'value\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('value') - return - -class ArithmeticIf(Statement): - """ - IF ( <scalar-numeric-expr> ) <label> , <label> , <label> - """ - match = re.compile(r'if\s*\(.*\)\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\Z', re.I).match - def process_item(self): - line = self.item.get_line()[2:].lstrip() - line,l2,l3 = line.rsplit(',',2) - i = line.rindex(')') - l1 = line[i+1:] - self.expr = self.item.apply_map(line[1:i]).strip() - self.labels = [l1.strip(),l2.strip(),l3.strip()] - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'IF (%s) %s' \ - % (self.expr,', '.join(self.labels)) - def analyze(self): return - -class Intrinsic(StatementWithNamelist): - """ - INTRINSIC [ :: ] <intrinsic-procedure-name-list> - """ - match = re.compile(r'intrinsic\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('intrinsic') - return - -class Inquire(Statement): - """ - INQUIRE ( <inquire-spec-list> ) - INQUIRE ( IOLENGTH = <scalar-int-variable> ) <output-item-list> - - <inquire-spec> = [ UNIT = ] <file-unit-number> - | FILE = <file-name-expr> - ... - <output-item> = <expr> - | <io-implied-do> - """ - match = re.compile(r'inquire\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - i = line.index(')') - self.specs = specs_split_comma(line[1:i].strip(), self.item) - self.items = split_comma(line[i+1:].lstrip(), self.item) - return - def tofortran(self, isfix=None): - if self.items: - return self.get_indent_tab(isfix=isfix) + 'INQUIRE (%s) %s' \ - % (', '.join(self.specs), ', '.join(self.items)) - return self.get_indent_tab(isfix=isfix) + 'INQUIRE (%s)' \ - % (', '.join(self.specs)) - def analyze(self): return - -class Sequence(Statement): - """ - SEQUENCE - """ - match = re.compile(r'sequence\Z',re.I).match - def process_item(self): - return - def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) + 'SEQUENCE' - def analyze(self): - self.parent.update_attributes('SEQUENCE') - return - -class External(StatementWithNamelist): - """ - EXTERNAL [ :: ] <external-name-list> - """ - match = re.compile(r'external\b', re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('external') - return - - -class Namelist(Statement): - """ - NAMELIST / <namelist-group-name> / <namelist-group-object-list> [ [ , ] / <namelist-group-name> / <namelist-group-object-list> ]... - <namelist-group-object> = <variable-name> - """ - match = re.compile(r'namelist\b',re.I).match - def process_item(self): - line = self.item.get_line()[8:].lstrip() - items = [] - while line: - assert line.startswith('/'),`line` - i = line.find('/',1) - assert i!=-1,`line` - name = line[:i+1] - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - items.append((name,line)) - line = '' - continue - s = line[:i].rstrip() - if s.endswith(','): - s = s[:-1].rstrip() - items.append((name,s)) - line = line[i+1:].lstrip() - self.items = items - return - - def tofortran(self, isfix=None): - l = [] - for name,s in self.items: - l.append('%s %s' % (name,s)) - tab = self.get_indent_tab(isfix=isfix) - return tab + 'NAMELIST ' + ', '.join(l) - -class Common(Statement): - """ - COMMON [ / [ <common-block-name> ] / ] <common-block-object-list> \ - [ [ , ] / [ <common-block-name> ] / <common-block-object-list> ]... - <common-block-object> = <variable-name> [ ( <explicit-shape-spec-list> ) ] - | <proc-pointer-name> - """ - match = re.compile(r'common\b',re.I).match - def process_item(self): - item = self.item - line = item.get_line()[6:].lstrip() - items = [] - while line: - if not line.startswith('/'): - name = '' - assert not items,`line` - else: - i = line.find('/',1) - assert i!=-1,`line` - name = line[1:i].strip() - line = line[i+1:].lstrip() - i = line.find('/') - if i==-1: - items.append((name,split_comma(line, item))) - line = '' - continue - s = line[:i].rstrip() - if s.endswith(','): - s = s[:-1].rstrip() - items.append((name,split_comma(s,item))) - line = line[i:].lstrip() - self.items = items - return - def tofortran(self, isfix=None): - l = [] - for name,s in self.items: - s = ', '.join(s) - if name: - l.append('/ %s / %s' % (name,s)) - else: - l.append(s) - tab = self.get_indent_tab(isfix=isfix) - return tab + 'COMMON ' + ' '.join(l) - def analyze(self): - for cname, items in self.items: - for item in items: - i = item.find('(') - if i!=-1: - assert item.endswith(')'),`item` - name = item[:i].rstrip() - shape = split_comma(item[i+1:-1].strip(), self.item) - else: - name = item - shape = None - var = self.get_variable(name) - if shape is not None: - var.set_bounds(shape) - # XXX: add name,var to parent_provides - return - -class Optional(StatementWithNamelist): - """ - OPTIONAL [ :: ] <dummy-arg-name-list> - <dummy-arg-name> = <name> - """ - match = re.compile(r'optional\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('optional') - return - -class Intent(Statement): - """ - INTENT ( <intent-spec> ) [ :: ] <dummy-arg-name-list> - <intent-spec> = IN | OUT | INOUT - - generalization for pyf-files: - INTENT ( <intent-spec-list> ) [ :: ] <dummy-arg-name-list> - <intent-spec> = IN | OUT | INOUT | CACHE | HIDE | OUT = <name> - """ - match = re.compile(r'intent\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.find(')') - self.specs = specs_split_comma(line[1:i], self.item, upper=True) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = [s.strip() for s in line.split(',')] - for n in self.items: - if not is_name(n): - self.isvalid = False - return - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'INTENT (%s) %s' \ - % (', '.join(self.specs), ', '.join(self.items)) - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.set_intent(self.specs) - return - - -class Entry(Statement): - """ - ENTRY <entry-name> [ ( [ <dummy-arg-list> ] ) [ <suffix> ] ] - <suffix> = <proc-language-binding-spec> [ RESULT ( <result-name> ) ] - | RESULT ( <result-name> ) [ <proc-language-binding-spec> ] - <proc-language-binding-spec> = <language-binding-spec> - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr> ] ) - <dummy-arg> = <dummy-arg-name> | * - """ - match = re.compile(r'entry\b', re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - m = re.match(r'\w+', line) - name = line[:m.end()] - line = line[m.end():].lstrip() - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - items = split_comma(line[1:i], self.item) - line = line[i+1:].lstrip() - else: - items = [] - self.bind, line = parse_bind(line, self.item) - self.result, line = parse_result(line, self.item) - if line: - assert self.bind is None,`self.bind` - self.bind, line = parse_bind(line, self.item) - assert not line,`line` - self.name = name - self.items = items - return - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = tab + 'ENTRY '+self.name - if self.items: - s += ' (%s)' % (', '.join(self.items)) - if self.result: - s += ' RESULT (%s)' % (self.result) - if self.bind: - s += ' BIND (%s)' % (', '.join(self.bind)) - return s - -class Import(StatementWithNamelist): - """ - IMPORT [ [ :: ] <import-name-list> ] - """ - match = re.compile(r'import(\b|\Z)',re.I).match - -class Forall(Statement): - """ - FORALL <forall-header> <forall-assignment-stmt> - <forall-header> = ( <forall-triplet-spec-list> [ , <scalar-mask-expr> ] ) - <forall-triplet-spec> = <index-name> = <subscript> : <subscript> [ : <stride> ] - <subscript|stride> = <scalar-int-expr> - <forall-assignment-stmt> = <assignment-stmt> | <pointer-assignment-stmt> - """ - match = re.compile(r'forall\s*\(.*\).*=', re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.index(')') - - line0 = line[1:i] - line = line[i+1:].lstrip() - stmt = GeneralAssignment(self, self.item.copy(line, True)) - if stmt.isvalid: - self.content = [stmt] - else: - self.isvalid = False - return - - specs = [] - mask = '' - for l in split_comma(line0,self.item): - j = l.find('=') - if j==-1: - assert not mask,`mask,l` - mask = l - continue - assert j!=-1,`l` - index = l[:j].rstrip() - it = self.item.copy(l[j+1:].lstrip()) - l = it.get_line() - k = l.split(':') - if len(k)==3: - s1, s2, s3 = map(it.apply_map, - [k[0].strip(),k[1].strip(),k[2].strip()]) - else: - assert len(k)==2,`k` - s1, s2 = map(it.apply_map, - [k[0].strip(),k[1].strip()]) - s3 = '1' - specs.append((index,s1,s2,s3)) - - self.specs = specs - self.mask = mask - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - l = [] - for index,s1,s2,s3 in self.specs: - s = '%s = %s : %s' % (index,s1,s2) - if s3!='1': - s += ' : %s' % (s3) - l.append(s) - s = ', '.join(l) - if self.mask: - s += ', ' + self.mask - return tab + 'FORALL (%s) %s' % \ - (s, str(self.content[0]).lstrip()) - def analyze(self): return - -ForallStmt = Forall - -class SpecificBinding(Statement): - """ - PROCEDURE [ ( <interface-name> ) ] [ [ , <binding-attr-list> ] :: ] <binding-name> [ => <procedure-name> ] - <binding-attr> = PASS [ ( <arg-name> ) ] - | NOPASS - | NON_OVERRIDABLE - | DEFERRED - | <access-spec> - <access-spec> = PUBLIC | PRIVATE - """ - match = re.compile(r'procedure\b',re.I).match - def process_item(self): - line = self.item.get_line()[9:].lstrip() - if line.startswith('('): - i = line.index(')') - name = line[1:i].strip() - line = line[i+1:].lstrip() - else: - name = '' - self.iname = name - if line.startswith(','): - line = line[1:].lstrip() - i = line.find('::') - if i != -1: - attrs = split_comma(line[:i], self.item) - line = line[i+2:].lstrip() - else: - attrs = [] - attrs1 = [] - for attr in attrs: - if is_name(attr): - attr = attr.upper() - else: - i = attr.find('(') - assert i!=-1 and attr.endswith(')'),`attr` - attr = '%s (%s)' % (attr[:i].rstrip().upper(), attr[i+1:-1].strip()) - attrs1.append(attr) - self.attrs = attrs1 - i = line.find('=') - if i==-1: - self.name = line - self.bname = '' - else: - self.name = line[:i].rstrip() - self.bname = line[i+1:].lstrip()[1:].lstrip() - return - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = 'PROCEDURE ' - if self.iname: - s += '(' + self.iname + ') ' - if self.attrs: - s += ', ' + ', '.join(self.attrs) + ' :: ' - if self.bname: - s += '%s => %s' % (self.name, self.bname) - else: - s += self.name - return tab + s - -class GenericBinding(Statement): - """ - GENERIC [ , <access-spec> ] :: <generic-spec> => <binding-name-list> - """ - match = re.compile(r'generic\b.*::.*=\>.*\Z', re.I).match - def process_item(self): - line = self.item.get_line()[7:].lstrip() - if line.startswith(','): - line = line[1:].lstrip() - i = line.index('::') - self.aspec = line[:i].rstrip().upper() - line = line[i+2:].lstrip() - i = line.index('=>') - self.spec = self.item.apply_map(line[:i].rstrip()) - self.items = split_comma(line[i+2:].lstrip()) - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = 'GENERIC' - if self.aspec: - s += ', '+self.aspec - s += ' :: ' + self.spec + ' => ' + ', '.join(self.items) - return tab + s - - -class FinalBinding(StatementWithNamelist): - """ - FINAL [ :: ] <final-subroutine-name-list> - """ - stmtname = 'final' - match = re.compile(r'final\b', re.I).match - -class Allocatable(Statement): - """ - ALLOCATABLE [ :: ] <object-name> [ ( <deferred-shape-spec-list> ) ] [ , <object-name> [ ( <deferred-shape-spec-list> ) ] ]... - """ - match = re.compile(r'allocatable\b',re.I).match - def process_item(self): - line = self.item.get_line()[11:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'ALLOCATABLE ' + ', '.join(self.items) - def analyze(self): - for line in self.items: - i = line.find('(') - if i==-1: - name = line - array_spec = None - else: - assert line.endswith(')') - name = line[:i].rstrip() - array_spec = split_comma(line[i+1:-1], self.item) - var = self.get_variable(name) - var.update('allocatable') - if array_spec is not None: - var.set_bounds(array_spec) - return - -class Asynchronous(StatementWithNamelist): - """ - ASYNCHRONOUS [ :: ] <object-name-list> - """ - match = re.compile(r'asynchronous\b',re.I).match - def analyze(self): - for name in self.items: - var = self.get_variable(name) - var.update('asynchronous') - return - - -class Bind(Statement): - """ - <language-binding-spec> [ :: ] <bind-entity-list> - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr> ] ) - <bind-entity> = <entity-name> | / <common-block-name> / - """ - match = re.compile(r'bind\s*\(.*\)',re.I).match - def process_item(self): - line = self.item.line - self.specs, line = parse_bind(line, self.item) - if line.startswith('::'): - line = line[2:].lstrip() - items = [] - for item in split_comma(line, self.item): - if item.startswith('/'): - assert item.endswith('/'),`item` - item = '/ ' + item[1:-1].strip() + ' /' - items.append(item) - self.items = items - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'BIND (%s) %s' %\ - (', '.join(self.specs), ', '.join(self.items)) - -# IF construct statements - -class Else(Statement): - """ - ELSE [<if-construct-name>] - """ - match = re.compile(r'else\b\s*\w*\s*\Z',re.I).match - - def process_item(self): - item = self.item - self.name = item.get_line()[4:].strip() - parent_name = getattr(self.parent,'name','') - if self.name and self.name!=parent_name: - self.warning('expected if-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def tofortran(self, isfix=None): - if self.name: - return self.get_indent_tab(deindent=True) + 'ELSE ' + self.name - return self.get_indent_tab(deindent=True) + 'ELSE' - - def analyze(self): return - -class ElseIf(Statement): - """ - ELSE IF ( <scalar-logical-expr> ) THEN [ <if-construct-name> ] - """ - match = re.compile(r'else\s*if\s*\(.*\)\s*then\s*\w*\s*\Z',re.I).match - - def process_item(self): - item = self.item - line = item.get_line()[4:].lstrip()[2:].lstrip() - i = line.find(')') - assert line[0]=='(' - self.expr = item.apply_map(line[1:i]) - self.name = line[i+1:].lstrip()[4:].strip() - parent_name = getattr(self.parent,'name','') - if self.name and self.name!=parent_name: - self.warning('expected if-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def tofortran(self, isfix=None): - s = '' - if self.name: - s = ' ' + self.name - return self.get_indent_tab(deindent=True) + 'ELSE IF (%s) THEN%s' \ - % (self.expr, s) - - def analyze(self): return - -# SelectCase construct statements - -class Case(Statement): - """ - CASE <case-selector> [ <case-constract-name> ] - <case-selector> = ( <case-value-range-list> ) | DEFAULT - <case-value-range> = <case-value> - | <case-value> : - | : <case-value> - | <case-value> : <case-value> - <case-value> = <scalar-(int|char|logical)-initialization-expr> - """ - match = re.compile(r'case\b\s*(\(.*\)|DEFAULT)\s*\w*\Z',re.I).match - def process_item(self): - #assert self.parent.__class__.__name__=='Select',`self.parent.__class__` - line = self.item.get_line()[4:].lstrip() - if line.startswith('('): - i = line.find(')') - items = split_comma(line[1:i].strip(), self.item) - line = line[i+1:].lstrip() - else: - assert line.lower().startswith('default'),`line` - items = [] - line = line[7:].lstrip() - for i in range(len(items)): - it = self.item.copy(items[i]) - rl = [] - for r in it.get_line().split(':'): - rl.append(it.apply_map(r.strip())) - items[i] = rl - self.items = items - self.name = line - parent_name = getattr(self.parent, 'name', '') - if self.name and self.name!=parent_name: - self.warning('expected case-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = 'CASE' - if self.items: - l = [] - for item in self.items: - l.append((' : '.join(item)).strip()) - s += ' ( %s )' % (', '.join(l)) - else: - s += ' DEFAULT' - if self.name: - s += ' ' + self.name - return s - def analyze(self): return - -# Where construct statements - -class Where(Statement): - """ - WHERE ( <mask-expr> ) <where-assignment-stmt> - """ - match = re.compile(r'where\s*\(.*\)\s*\w.*\Z',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - i = line.index(')') - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - newitem = self.item.copy(line) - cls = Assignment - if cls.match(line): - stmt = cls(self, newitem) - if stmt.isvalid: - self.content = [stmt] - return - self.isvalid = False - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - return tab + 'WHERE ( %s ) %s' % (self.expr, str(self.content[0]).lstrip()) - def analyze(self): return - -WhereStmt = Where - -class ElseWhere(Statement): - """ - ELSE WHERE ( <mask-expr> ) [ <where-construct-name> ] - ELSE WHERE [ <where-construct-name> ] - """ - match = re.compile(r'else\s*where\b',re.I).match - def process_item(self): - line = self.item.get_line()[4:].lstrip()[5:].lstrip() - self.expr = None - if line.startswith('('): - i = line.index(')') - assert i != -1,`line` - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - self.name = line - parent_name = getattr(self.parent,'name','') - if self.name and not self.name==parent_name: - self.warning('expected where-construct-name %r but got %r, skipping.'\ - % (parent_name, self.name)) - self.isvalid = False - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = 'ELSE WHERE' - if self.expr is not None: - s += ' ( %s )' % (self.expr) - if self.name: - s += ' ' + self.name - return tab + s - def analyze(self): return - -# Enum construct statements - -class Enumerator(Statement): - """ - ENUMERATOR [ :: ] <enumerator-list> - <enumerator> = <named-constant> [ = <scalar-int-initialization-expr> ] - """ - match = re.compile(r'enumerator\b',re.I).match - def process_item(self): - line = self.item.get_line()[10:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line, self.item) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'ENUMERATOR ' + ', '.join(self.items) - -# F2PY specific statements - -class FortranName(Statement): - """ - FORTRANNAME <name> - """ - match = re.compile(r'fortranname\s*\w+\Z',re.I).match - def process_item(self): - self.value = self.item.get_line()[11:].lstrip() - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'FORTRANNAME ' + self.value - -class Threadsafe(Statement): - """ - THREADSAFE - """ - match = re.compile(r'threadsafe\Z',re.I).match - def process_item(self): - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'THREADSAFE' - -class Depend(Statement): - """ - DEPEND ( <name-list> ) [ :: ] <dummy-arg-name-list> - - """ - match = re.compile(r'depend\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[6:].lstrip() - i = line.find(')') - self.depends = split_comma(line[1:i].strip(), self.item) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.items = split_comma(line) - return - - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'DEPEND ( %s ) %s' \ - % (', '.join(self.depends), ', '.join(self.items)) - -class Check(Statement): - """ - CHECK ( <c-int-scalar-expr> ) [ :: ] <name> - - """ - match = re.compile(r'check\s*\(',re.I).match - def process_item(self): - line = self.item.get_line()[5:].lstrip() - i = line.find(')') - assert i!=-1,`line` - self.expr = self.item.apply_map(line[1:i].strip()) - line = line[i+1:].lstrip() - if line.startswith('::'): - line = line[2:].lstrip() - self.value = line - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'CHECK ( %s ) %s' \ - % (self.expr, self.value) - -class CallStatement(Statement): - """ - CALLSTATEMENT <c-expr> - """ - match = re.compile(r'callstatement\b', re.I).match - def process_item(self): - self.expr = self.item.apply_map(self.item.get_line()[13:].lstrip()) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'CALLSTATEMENT ' + self.expr - -class CallProtoArgument(Statement): - """ - CALLPROTOARGUMENT <c-type-spec-list> - """ - match = re.compile(r'callprotoargument\b', re.I).match - def process_item(self): - self.specs = self.item.apply_map(self.item.get_line()[17:].lstrip()) - return - def tofortran(self, isfix=None): - return self.get_indent_tab(isfix=isfix) + 'CALLPROTOARGUMENT ' + self.specs - -# Non-standard statements - -class Pause(Statement): - """ - PAUSE [ <char-literal-constant|int-literal-constant> ] - """ - match = re.compile(r'pause\s*(\d+|\'\w*\'|"\w*"|)\Z', re.I).match - def process_item(self): - self.value = self.item.apply_map(self.item.get_line()[5:].lstrip()) - return - def tofortran(self, isfix=None): - if self.value: - return self.get_indent_tab(isfix=isfix) + 'PAUSE ' + self.value - return self.get_indent_tab(isfix=isfix) + 'PAUSE' - def analyze(self): return diff --git a/numpy/f2py/lib/parser/test_Fortran2003.py b/numpy/f2py/lib/parser/test_Fortran2003.py deleted file mode 100644 index 3bf796b46..000000000 --- a/numpy/f2py/lib/parser/test_Fortran2003.py +++ /dev/null @@ -1,2101 +0,0 @@ -from numpy.testing import * - -from Fortran2003 import * -from api import get_reader - -############################################################################### -############################### SECTION 2 #################################### -############################################################################### - -class TestProgram(TestCase): # R201 - - def test_simple(self): - reader = get_reader('''\ - subroutine foo - end subroutine foo - subroutine bar - end - ''') - cls = Program - a = cls(reader) - assert isinstance(a, cls),`a` - assert_equal(str(a), 'SUBROUTINE foo\nEND SUBROUTINE foo\nSUBROUTINE bar\nEND SUBROUTINE bar') - -class TestSpecificationPart(TestCase): # R204 - - def test_simple(self): - from api import get_reader - reader = get_reader('''\ - integer a''') - cls = Specification_Part - a = cls(reader) - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTEGER :: a') - assert_equal(repr(a), "Specification_Part(Type_Declaration_Stmt(Intrinsic_Type_Spec('INTEGER', None), None, Entity_Decl(Name('a'), None, None, None)))") - -############################################################################### -############################### SECTION 3 #################################### -############################################################################### - -class TestName(TestCase): # R304 - - def test_name(self): - a = Name('a') - assert isinstance(a,Name),`a` - a = Name('a2') - assert isinstance(a,Name),`a` - a = Designator('a') - assert isinstance(a,Name),`a` - a = Constant('a') - assert isinstance(a,Name),`a` - a = Expr('a') - assert isinstance(a,Name),`a` - -############################################################################### -############################### SECTION 4 #################################### -############################################################################### - -class TestTypeParamValue(TestCase): # 402 - - def test_type_param_value(self): - cls = Type_Param_Value - a = cls('*') - assert isinstance(a,cls),`a` - assert_equal(str(a),'*') - assert_equal(repr(a),"Type_Param_Value('*')") - - a = cls(':') - assert isinstance(a,cls),`a` - assert_equal(str(a),':') - - a = cls('1+2') - assert isinstance(a,Level_2_Expr),`a` - assert_equal(str(a),'1 + 2') - -class TestIntrinsicTypeSpec(TestCase): # R403 - - def test_intrinsic_type_spec(self): - cls = Intrinsic_Type_Spec - a = cls('INTEGER') - assert isinstance(a,cls),`a` - assert_equal(str(a),'INTEGER') - assert_equal(repr(a), "Intrinsic_Type_Spec('INTEGER', None)") - - a = cls('Integer*2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'INTEGER*2') - - a = cls('real*2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'REAL*2') - - a = cls('logical*2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'LOGICAL*2') - - a = cls('complex*2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'COMPLEX*2') - - a = cls('character*2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'CHARACTER*2') - - a = cls('double complex') - assert isinstance(a,cls),`a` - assert_equal(str(a),'DOUBLE COMPLEX') - - a = cls('double precision') - assert isinstance(a,cls),`a` - assert_equal(str(a),'DOUBLE PRECISION') - -class TestKindSelector(TestCase): # R404 - - def test_kind_selector(self): - cls = Kind_Selector - a = cls('(1)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(KIND = 1)') - assert_equal(repr(a),"Kind_Selector('(', Int_Literal_Constant('1', None), ')')") - - a = cls('(kind=1+2)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(KIND = 1 + 2)') - - a = cls('* 1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'*1') - -class TestSignedIntLiteralConstant(TestCase): # R405 - - def test_int_literal_constant(self): - cls = Signed_Int_Literal_Constant - a = cls('1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1') - assert_equal(repr(a),"%s('1', None)" % (cls.__name__)) - - a = cls('+ 21_2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+ 21_2') - assert_equal(repr(a),"%s('+ 21', '2')" % (cls.__name__)) - - a = cls('-21_SHORT') - assert isinstance(a,cls),`a` - assert_equal(str(a),'-21_SHORT') - - a = cls('21_short') - assert isinstance(a,cls),`a` - assert_equal(str(a),'21_short') - - a = cls('+1976354279568241_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+1976354279568241_8') - -class TestIntLiteralConstant(TestCase): # R406 - - def test_int_literal_constant(self): - cls = Int_Literal_Constant - a = cls('1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1') - assert_equal(repr(a),"%s('1', None)" % (cls.__name__)) - - a = cls('21_2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'21_2') - assert_equal(repr(a),"%s('21', '2')" % (cls.__name__)) - - a = cls('21_SHORT') - assert isinstance(a,cls),`a` - assert_equal(str(a),'21_SHORT') - - a = cls('21_short') - assert isinstance(a,cls),`a` - assert_equal(str(a),'21_short') - - a = cls('1976354279568241_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1976354279568241_8') - -class TestBinaryConstant(TestCase): # R412 - - def test_boz_literal_constant(self): - cls = Boz_Literal_Constant - bcls = Binary_Constant - a = cls('B"01"') - assert isinstance(a,bcls),`a` - assert_equal(str(a),'B"01"') - assert_equal(repr(a),"%s('B\"01\"')" % (bcls.__name__)) - -class TestOctalConstant(TestCase): # R413 - - def test_boz_literal_constant(self): - cls = Boz_Literal_Constant - ocls = Octal_Constant - a = cls('O"017"') - assert isinstance(a,ocls),`a` - assert_equal(str(a),'O"017"') - assert_equal(repr(a),"%s('O\"017\"')" % (ocls.__name__)) - -class TestHexConstant(TestCase): # R414 - - def test_boz_literal_constant(self): - cls = Boz_Literal_Constant - zcls = Hex_Constant - a = cls('Z"01A"') - assert isinstance(a,zcls),`a` - assert_equal(str(a),'Z"01A"') - assert_equal(repr(a),"%s('Z\"01A\"')" % (zcls.__name__)) - -class TestSignedRealLiteralConstant(TestCase): # R416 - - def test_signed_real_literal_constant(self): - cls = Signed_Real_Literal_Constant - a = cls('12.78') - assert isinstance(a,cls),`a` - assert_equal(str(a),'12.78') - assert_equal(repr(a),"%s('12.78', None)" % (cls.__name__)) - - a = cls('+12.78_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+12.78_8') - assert_equal(repr(a),"%s('+12.78', '8')" % (cls.__name__)) - - a = cls('- 12.') - assert isinstance(a,cls),`a` - assert_equal(str(a),'- 12.') - - a = cls('1.6E3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E3') - - a = cls('+1.6E3_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+1.6E3_8') - - a = cls('1.6D3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6D3') - - a = cls('-1.6E-3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'-1.6E-3') - a = cls('1.6E+3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E+3') - - a = cls('3E4') - assert isinstance(a,cls),`a` - assert_equal(str(a),'3E4') - - a = cls('.123') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.123') - - a = cls('+1.6E-3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+1.6E-3') - - a = cls('10.9E7_QUAD') - assert isinstance(a,cls),`a` - assert_equal(str(a),'10.9E7_QUAD') - - a = cls('-10.9e-17_quad') - assert isinstance(a,cls),`a` - assert_equal(str(a),'-10.9E-17_quad') - -class TestRealLiteralConstant(TestCase): # R417 - - def test_real_literal_constant(self): - cls = Real_Literal_Constant - a = cls('12.78') - assert isinstance(a,cls),`a` - assert_equal(str(a),'12.78') - assert_equal(repr(a),"%s('12.78', None)" % (cls.__name__)) - - a = cls('12.78_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'12.78_8') - assert_equal(repr(a),"%s('12.78', '8')" % (cls.__name__)) - - a = cls('12.') - assert isinstance(a,cls),`a` - assert_equal(str(a),'12.') - - a = cls('1.6E3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E3') - - a = cls('1.6E3_8') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E3_8') - - a = cls('1.6D3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6D3') - - a = cls('1.6E-3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E-3') - a = cls('1.6E+3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E+3') - - a = cls('3E4') - assert isinstance(a,cls),`a` - assert_equal(str(a),'3E4') - - a = cls('.123') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.123') - - a = cls('1.6E-3') - assert isinstance(a,cls),`a` - assert_equal(str(a),'1.6E-3') - - a = cls('10.9E7_QUAD') - assert isinstance(a,cls),`a` - assert_equal(str(a),'10.9E7_QUAD') - - a = cls('10.9e-17_quad') - assert isinstance(a,cls),`a` - assert_equal(str(a),'10.9E-17_quad') - - a = cls('0.0D+0') - assert isinstance(a,cls),`a` - assert_equal(str(a),'0.0D+0') - -class TestCharSelector(TestCase): # R424 - - def test_char_selector(self): - cls = Char_Selector - a = cls('(len=2, kind=8)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(LEN = 2, KIND = 8)') - assert_equal(repr(a),"Char_Selector(Int_Literal_Constant('2', None), Int_Literal_Constant('8', None))") - - - a = cls('(2, kind=8)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(LEN = 2, KIND = 8)') - - a = cls('(2, 8)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(LEN = 2, KIND = 8)') - - a = cls('(kind=8)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(KIND = 8)') - - a = cls('(kind=8,len=2)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(LEN = 2, KIND = 8)') - -class TestComplexLiteralConstant(TestCase): # R421 - - def test_complex_literal_constant(self): - cls = Complex_Literal_Constant - a = cls('(1.0, -1.0)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(1.0, -1.0)') - assert_equal(repr(a),"Complex_Literal_Constant(Signed_Real_Literal_Constant('1.0', None), Signed_Real_Literal_Constant('-1.0', None))") - - a = cls('(3,3.1E6)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(3, 3.1E6)') - - a = cls('(4.0_4, 3.6E7_8)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(4.0_4, 3.6E7_8)') - - a = cls('( 0., PI)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(0., PI)') - - -class TestTypeName(TestCase): # C424 - - def test_simple(self): - cls = Type_Name - a = cls('a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a') - assert_equal(repr(a),"Type_Name('a')") - - self.assertRaises(NoMatchError,cls,'integer') - self.assertRaises(NoMatchError,cls,'doubleprecision') - -class TestLengthSelector(TestCase): # R425 - - def test_length_selector(self): - cls = Length_Selector - a = cls('( len = *)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(LEN = *)') - assert_equal(repr(a),"Length_Selector('(', Type_Param_Value('*'), ')')") - - a = cls('*2,') - assert isinstance(a,cls),`a` - assert_equal(str(a),'*2') - -class TestCharLength(TestCase): # R426 - - def test_char_length(self): - cls = Char_Length - a = cls('(1)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(1)') - assert_equal(repr(a),"Char_Length('(', Int_Literal_Constant('1', None), ')')") - - a = cls('1') - assert isinstance(a,Int_Literal_Constant),`a` - assert_equal(str(a),'1') - - a = cls('(*)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(*)') - - a = cls('(:)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(:)') - -class TestCharLiteralConstant(TestCase): # R427 - - def test_char_literal_constant(self): - cls = Char_Literal_Constant - a = cls('NIH_"DO"') - assert isinstance(a,cls),`a` - assert_equal(str(a),'NIH_"DO"') - assert_equal(repr(a),'Char_Literal_Constant(\'"DO"\', \'NIH\')') - - a = cls("'DO'") - assert isinstance(a,cls),`a` - assert_equal(str(a),"'DO'") - assert_equal(repr(a),'Char_Literal_Constant("\'DO\'", None)') - - a = cls("'DON''T'") - assert isinstance(a,cls),`a` - assert_equal(str(a),"'DON''T'") - - a = cls('"DON\'T"') - assert isinstance(a,cls),`a` - assert_equal(str(a),'"DON\'T"') - - a = cls('""') - assert isinstance(a,cls),`a` - assert_equal(str(a),'""') - - a = cls("''") - assert isinstance(a,cls),`a` - assert_equal(str(a),"''") - - a = cls('"hey ha(ada)\t"') - assert isinstance(a,cls),`a` - assert_equal(str(a),'"hey ha(ada)\t"') - -class TestLogicalLiteralConstant(TestCase): # R428 - - def test_logical_literal_constant(self): - cls = Logical_Literal_Constant - a = cls('.TRUE.') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.TRUE.') - assert_equal(repr(a),"%s('.TRUE.', None)" % (cls.__name__)) - - a = cls('.True.') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.TRUE.') - - a = cls('.FALSE.') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.FALSE.') - - a = cls('.TRUE._HA') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.TRUE._HA') - -class TestDerivedTypeStmt(TestCase): # R430 - - def test_simple(self): - cls = Derived_Type_Stmt - a = cls('type a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'TYPE :: a') - assert_equal(repr(a),"Derived_Type_Stmt(None, Type_Name('a'), None)") - - a = cls('type ::a(b,c)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'TYPE :: a(b, c)') - - a = cls('type, private, abstract::a(b,c)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'TYPE, PRIVATE, ABSTRACT :: a(b, c)') - -class TestTypeName(TestCase): # C423 - - def test_simple(self): - cls = Type_Name - a = cls('a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a') - assert_equal(repr(a),"Type_Name('a')") - -class TestTypeAttrSpec(TestCase): # R431 - - def test_simple(self): - cls = Type_Attr_Spec - a = cls('abstract') - assert isinstance(a, cls),`a` - assert_equal(str(a),'ABSTRACT') - assert_equal(repr(a),"Type_Attr_Spec('ABSTRACT')") - - a = cls('bind (c )') - assert isinstance(a, Language_Binding_Spec),`a` - assert_equal(str(a),'BIND(C)') - - a = cls('extends(a)') - assert isinstance(a, Type_EXTENDS_Parent_Type_Name),`a` - assert_equal(str(a),'EXTENDS(a)') - - a = cls('private') - assert isinstance(a, Access_Spec),`a` - assert_equal(str(a),'PRIVATE') - - -class TestEndTypeStmt(TestCase): # R433 - - def test_simple(self): - cls = End_Type_Stmt - a = cls('end type') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END TYPE') - assert_equal(repr(a),"End_Type_Stmt('TYPE', None)") - - a = cls('end type a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END TYPE a') - -class TestSequenceStmt(TestCase): # R434 - - def test_simple(self): - cls = Sequence_Stmt - a = cls('sequence') - assert isinstance(a, cls),`a` - assert_equal(str(a),'SEQUENCE') - assert_equal(repr(a),"Sequence_Stmt('SEQUENCE')") - -class TestTypeParamDefStmt(TestCase): # R435 - - def test_simple(self): - cls = Type_Param_Def_Stmt - a = cls('integer ,kind :: a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTEGER, KIND :: a') - assert_equal(repr(a),"Type_Param_Def_Stmt(None, Type_Param_Attr_Spec('KIND'), Name('a'))") - - a = cls('integer*2 ,len :: a=3, b=2+c') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTEGER*2, LEN :: a = 3, b = 2 + c') - -class TestTypeParamDecl(TestCase): # R436 - - def test_simple(self): - cls = Type_Param_Decl - a = cls('a=2') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a = 2') - assert_equal(repr(a),"Type_Param_Decl(Name('a'), '=', Int_Literal_Constant('2', None))") - - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - -class TestTypeParamAttrSpec(TestCase): # R437 - - def test_simple(self): - cls = Type_Param_Attr_Spec - a = cls('kind') - assert isinstance(a, cls),`a` - assert_equal(str(a),'KIND') - assert_equal(repr(a),"Type_Param_Attr_Spec('KIND')") - - a = cls('len') - assert isinstance(a, cls),`a` - assert_equal(str(a),'LEN') - -class TestComponentAttrSpec(TestCase): # R441 - - def test_simple(self): - cls = Component_Attr_Spec - a = cls('pointer') - assert isinstance(a, cls),`a` - assert_equal(str(a),'POINTER') - assert_equal(repr(a),"Component_Attr_Spec('POINTER')") - - a = cls('allocatable') - assert isinstance(a, cls),`a` - assert_equal(str(a),'ALLOCATABLE') - - a = cls('dimension(a)') - assert isinstance(a, Dimension_Component_Attr_Spec),`a` - assert_equal(str(a),'DIMENSION(a)') - - a = cls('private') - assert isinstance(a, Access_Spec),`a` - assert_equal(str(a),'PRIVATE') - -class TestComponentDecl(TestCase): # R442 - - def test_simple(self): - cls = Component_Decl - a = cls('a(1)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)') - assert_equal(repr(a),"Component_Decl(Name('a'), Explicit_Shape_Spec(None, Int_Literal_Constant('1', None)), None, None)") - - a = cls('a(1)*(3)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)*(3)') - - a = cls('a(1)*(3) = 2') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)*(3) = 2') - - a = cls('a(1) => NULL') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1) => NULL') - -class TestFinalBinding(TestCase): # R454 - - def test_simple(self): - cls = Final_Binding - a = cls('final a, b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'FINAL :: a, b') - assert_equal(repr(a),"Final_Binding('FINAL', Final_Subroutine_Name_List(',', (Name('a'), Name('b'))))") - - a = cls('final::a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'FINAL :: a') - -class TestDerivedTypeSpec(TestCase): # R455 - - def test_simple(self): - cls = Derived_Type_Spec - a = cls('a(b)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a(b)') - assert_equal(repr(a),"Derived_Type_Spec(Type_Name('a'), Name('b'))") - - a = cls('a(b,c,g=1)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a(b, c, g = 1)') - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - - a = cls('a()') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a()') - -class TestTypeParamSpec(TestCase): # R456 - - def test_type_param_spec(self): - cls = Type_Param_Spec - a = cls('a=1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a = 1') - assert_equal(repr(a),"Type_Param_Spec(Name('a'), Int_Literal_Constant('1', None))") - - a = cls('k=a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a') - - a = cls('k=:') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = :') - -class TestTypeParamSpecList(TestCase): # R456-list - - def test_type_param_spec_list(self): - cls = Type_Param_Spec_List - - a = cls('a,b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a, b') - assert_equal(repr(a),"Type_Param_Spec_List(',', (Name('a'), Name('b')))") - - a = cls('a') - assert isinstance(a,Name),`a` - - a = cls('k=a,c,g=1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a, c, g = 1') - -class TestStructureConstructor2(TestCase): # R457.b - - def test_simple(self): - cls = Structure_Constructor_2 - a = cls('k=a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a') - assert_equal(repr(a),"Structure_Constructor_2(Name('k'), Name('a'))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestStructureConstructor(TestCase): # R457 - - def test_structure_constructor(self): - cls = Structure_Constructor - a = cls('t()') - assert isinstance(a,cls),`a` - assert_equal(str(a),'t()') - assert_equal(repr(a),"Structure_Constructor(Type_Name('t'), None)") - - a = cls('t(s=1, a)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'t(s = 1, a)') - - a = cls('a=k') - assert isinstance(a,Structure_Constructor_2),`a` - assert_equal(str(a),'a = k') - assert_equal(repr(a),"Structure_Constructor_2(Name('a'), Name('k'))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestComponentSpec(TestCase): # R458 - - def test_simple(self): - cls = Component_Spec - a = cls('k=a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a') - assert_equal(repr(a),"Component_Spec(Name('k'), Name('a'))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - - a = cls('a % b') - assert isinstance(a, Proc_Component_Ref),`a` - assert_equal(str(a),'a % b') - - a = cls('s =a % b') - assert isinstance(a, Component_Spec),`a` - assert_equal(str(a),'s = a % b') - -class TestComponentSpecList(TestCase): # R458-list - - def test_simple(self): - cls = Component_Spec_List - a = cls('k=a, b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a, b') - assert_equal(repr(a),"Component_Spec_List(',', (Component_Spec(Name('k'), Name('a')), Name('b')))") - - a = cls('k=a, c') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a, c') - -class TestArrayConstructor(TestCase): # R465 - - def test_simple(self): - cls = Array_Constructor - a = cls('(/a/)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(/a/)') - assert_equal(repr(a),"Array_Constructor('(/', Name('a'), '/)')") - - a = cls('[a]') - assert isinstance(a,cls),`a` - assert_equal(str(a),'[a]') - assert_equal(repr(a),"Array_Constructor('[', Name('a'), ']')") - - a = cls('[integer::a]') - assert isinstance(a,cls),`a` - assert_equal(str(a),'[INTEGER :: a]') - - a = cls('[integer::a,b]') - assert isinstance(a,cls),`a` - assert_equal(str(a),'[INTEGER :: a, b]') - -class TestAcSpec(TestCase): # R466 - - def test_ac_spec(self): - cls = Ac_Spec - a = cls('integer ::') - assert isinstance(a,cls),`a` - assert_equal(str(a),'INTEGER ::') - assert_equal(repr(a),"Ac_Spec(Intrinsic_Type_Spec('INTEGER', None), None)") - - a = cls('integer :: a,b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'INTEGER :: a, b') - - a = cls('a,b') - assert isinstance(a,Ac_Value_List),`a` - assert_equal(str(a),'a, b') - - a = cls('integer :: a, (a, b, n = 1, 5)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'INTEGER :: a, (a, b, n = 1, 5)') - -class TestAcValueList(TestCase): # R469-list - - def test_ac_value_list(self): - cls = Ac_Value_List - a = cls('a, b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a, b') - assert_equal(repr(a),"Ac_Value_List(',', (Name('a'), Name('b')))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestAcImpliedDo(TestCase): # R470 - - def test_ac_implied_do(self): - cls = Ac_Implied_Do - a = cls('( a, b, n = 1, 5 )') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(a, b, n = 1, 5)') - assert_equal(repr(a),"Ac_Implied_Do(Ac_Value_List(',', (Name('a'), Name('b'))), Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('1', None), Int_Literal_Constant('5', None)]))") - -class TestAcImpliedDoControl(TestCase): # R471 - - def test_ac_implied_do_control(self): - cls = Ac_Implied_Do_Control - a = cls('n = 3, 5') - assert isinstance(a,cls),`a` - assert_equal(str(a),'n = 3, 5') - assert_equal(repr(a),"Ac_Implied_Do_Control(Name('n'), [Int_Literal_Constant('3', None), Int_Literal_Constant('5', None)])") - - a = cls('n = 3+1, 5, 1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'n = 3 + 1, 5, 1') - -############################################################################### -############################### SECTION 5 #################################### -############################################################################### - -class TestTypeDeclarationStmt(TestCase): # R501 - - def test_simple(self): - cls = Type_Declaration_Stmt - a = cls('integer a') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'INTEGER :: a') - assert_equal(repr(a), "Type_Declaration_Stmt(Intrinsic_Type_Spec('INTEGER', None), None, Entity_Decl(Name('a'), None, None, None))") - - a = cls('integer ,dimension(2):: a*3') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'INTEGER, DIMENSION(2) :: a*3') - - a = cls('real a') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'REAL :: a') - assert_equal(repr(a), "Type_Declaration_Stmt(Intrinsic_Type_Spec('REAL', None), None, Entity_Decl(Name('a'), None, None, None))") - - a = cls('REAL A( LDA, * ), B( LDB, * )') - assert isinstance(a, cls),`a` - - a = cls('DOUBLE PRECISION ALPHA, BETA') - assert isinstance(a, cls),`a` - -class TestDeclarationTypeSpec(TestCase): # R502 - - def test_simple(self): - cls = Declaration_Type_Spec - a = cls('Integer*2') - assert isinstance(a, Intrinsic_Type_Spec),`a` - assert_equal(str(a), 'INTEGER*2') - - a = cls('type(foo)') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'TYPE(foo)') - assert_equal(repr(a), "Declaration_Type_Spec('TYPE', Type_Name('foo'))") - -class TestAttrSpec(TestCase): # R503 - - def test_simple(self): - cls = Attr_Spec - a = cls('allocatable') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'ALLOCATABLE') - - a = cls('dimension(a)') - assert isinstance(a, Dimension_Attr_Spec),`a` - assert_equal(str(a),'DIMENSION(a)') - -class TestDimensionAttrSpec(TestCase): # R503.d - - def test_simple(self): - cls = Dimension_Attr_Spec - a = cls('dimension(a)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'DIMENSION(a)') - assert_equal(repr(a),"Dimension_Attr_Spec('DIMENSION', Explicit_Shape_Spec(None, Name('a')))") - -class TestIntentAttrSpec(TestCase): # R503.f - - def test_simple(self): - cls = Intent_Attr_Spec - a = cls('intent(in)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTENT(IN)') - assert_equal(repr(a),"Intent_Attr_Spec('INTENT', Intent_Spec('IN'))") - -class TestEntityDecl(TestCase): # 504 - - def test_simple(self): - cls = Entity_Decl - a = cls('a(1)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)') - assert_equal(repr(a),"Entity_Decl(Name('a'), Explicit_Shape_Spec(None, Int_Literal_Constant('1', None)), None, None)") - - a = cls('a(1)*(3)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)*(3)') - - a = cls('a(1)*(3) = 2') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(1)*(3) = 2') - -class TestAccessSpec(TestCase): # R508 - - def test_simple(self): - cls = Access_Spec - a = cls('private') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PRIVATE') - assert_equal(repr(a),"Access_Spec('PRIVATE')") - - a = cls('public') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PUBLIC') - -class TestLanguageBindingSpec(TestCase): # R509 - - def test_simple(self): - cls = Language_Binding_Spec - a = cls('bind(c)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'BIND(C)') - assert_equal(repr(a),'Language_Binding_Spec(None)') - - a = cls('bind(c, name="hey")') - assert isinstance(a, cls),`a` - assert_equal(str(a),'BIND(C, NAME = "hey")') - -class TestExplicitShapeSpec(TestCase): # R511 - - def test_simple(self): - cls = Explicit_Shape_Spec - a = cls('a:b') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a : b') - assert_equal(repr(a),"Explicit_Shape_Spec(Name('a'), Name('b'))") - - a = cls('a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a') - -class TestUpperBound(TestCase): # R513 - - def test_simple(self): - cls = Upper_Bound - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - - self.assertRaises(NoMatchError,cls,'*') - -class TestAssumedShapeSpec(TestCase): # R514 - - def test_simple(self): - cls = Assumed_Shape_Spec - a = cls(':') - assert isinstance(a, cls),`a` - assert_equal(str(a),':') - assert_equal(repr(a),'Assumed_Shape_Spec(None, None)') - - a = cls('a :') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a :') - -class TestDeferredShapeSpec(TestCase): # R515 - - def test_simple(self): - cls = Deferred_Shape_Spec - a = cls(':') - assert isinstance(a, cls),`a` - assert_equal(str(a),':') - assert_equal(repr(a),'Deferred_Shape_Spec(None, None)') - - -class TestAssumedSizeSpec(TestCase): # R516 - - def test_simple(self): - cls = Assumed_Size_Spec - a = cls('*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'*') - assert_equal(repr(a),'Assumed_Size_Spec(None, None)') - - a = cls('1:*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'1 : *') - - a = cls('a,1:*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a, 1 : *') - - a = cls('a:b,1:*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a : b, 1 : *') - -class TestAccessStmt(TestCase): # R518 - - def test_simple(self): - cls = Access_Stmt - a = cls('private') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PRIVATE') - assert_equal(repr(a),"Access_Stmt('PRIVATE', None)") - - a = cls('public a,b') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PUBLIC :: a, b') - - a = cls('public ::a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PUBLIC :: a') - -class TestParameterStmt(TestCase): # R538 - - def test_simple(self): - cls = Parameter_Stmt - a = cls('parameter(a=1)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PARAMETER(a = 1)') - assert_equal(repr(a),"Parameter_Stmt('PARAMETER', Named_Constant_Def(Name('a'), Int_Literal_Constant('1', None)))") - - a = cls('parameter(a=1, b=a+2)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PARAMETER(a = 1, b = a + 2)') - - a = cls('PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PARAMETER(ONE = 1.0D+0, ZERO = 0.0D+0)') - -class TestNamedConstantDef(TestCase): # R539 - - def test_simple(self): - cls = Named_Constant_Def - a = cls('a=1') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a = 1') - assert_equal(repr(a),"Named_Constant_Def(Name('a'), Int_Literal_Constant('1', None))") - -class TestPointerDecl(TestCase): # R541 - - def test_simple(self): - cls = Pointer_Decl - a = cls('a(:)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(:)') - assert_equal(repr(a),"Pointer_Decl(Name('a'), Deferred_Shape_Spec(None, None))") - - a = cls('a(:,:)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(:, :)') - -class TestImplicitStmt(TestCase): # R549 - - def test_simple(self): - cls = Implicit_Stmt - a = cls('implicitnone') - assert isinstance(a, cls),`a` - assert_equal(str(a),'IMPLICIT NONE') - assert_equal(repr(a),"Implicit_Stmt('IMPLICIT NONE', None)") - - a = cls('implicit real(a-d), double precision(r-t,x), type(a) (y-z)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'IMPLICIT REAL(A - D), DOUBLE PRECISION(R - T, X), TYPE(a)(Y - Z)') - -class TestImplicitSpec(TestCase): # R550 - - def test_simple(self): - cls = Implicit_Spec - a = cls('integer (a-z)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTEGER(A - Z)') - assert_equal(repr(a),"Implicit_Spec(Intrinsic_Type_Spec('INTEGER', None), Letter_Spec('A', 'Z'))") - - a = cls('double complex (r,d-g)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'DOUBLE COMPLEX(R, D - G)') - -class TestLetterSpec(TestCase): # R551 - - def test_simple(self): - cls = Letter_Spec - a = cls('a-z') - assert isinstance(a, cls),`a` - assert_equal(str(a),'A - Z') - assert_equal(repr(a),"Letter_Spec('A', 'Z')") - - a = cls('d') - assert isinstance(a, cls),`a` - assert_equal(str(a),'D') - -class TestEquivalenceStmt(TestCase): # R554 - - def test_simple(self): - cls = Equivalence_Stmt - a = cls('equivalence (a, b ,z)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'EQUIVALENCE(a, b, z)') - assert_equal(repr(a),"Equivalence_Stmt('EQUIVALENCE', Equivalence_Set(Name('a'), Equivalence_Object_List(',', (Name('b'), Name('z')))))") - - a = cls('equivalence (a, b ,z),(b,l)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'EQUIVALENCE(a, b, z), (b, l)') - -class TestCommonStmt(TestCase): # R557 - - def test_simple(self): - cls = Common_Stmt - a = cls('common a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'COMMON // a') - assert_equal(repr(a),"Common_Stmt([(None, Name('a'))])") - - a = cls('common // a,b') - assert isinstance(a, cls),`a` - assert_equal(str(a),'COMMON // a, b') - - a = cls('common /name/ a,b') - assert isinstance(a, cls),`a` - assert_equal(str(a),'COMMON /name/ a, b') - - a = cls('common /name/ a,b(4,5) // c, /ljuks/ g(2)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'COMMON /name/ a, b(4, 5) // c /ljuks/ g(2)') - -class TestCommonBlockObject(TestCase): # R558 - - def test_simple(self): - cls = Common_Block_Object - a = cls('a(2)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(2)') - assert_equal(repr(a),"Common_Block_Object(Name('a'), Explicit_Shape_Spec(None, Int_Literal_Constant('2', None)))") - - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - - -############################################################################### -############################### SECTION 6 #################################### -############################################################################### - -class TestSubstring(TestCase): # R609 - - def test_simple(self): - cls = Substring - a = cls('a(:)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(:)') - assert_equal(repr(a),"Substring(Name('a'), Substring_Range(None, None))") - - a = cls('a(1:2)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a(1 : 2)') - assert_equal(repr(a),"Substring(Name('a'), Substring_Range(Int_Literal_Constant('1', None), Int_Literal_Constant('2', None)))") - - -class TestSubstringRange(TestCase): # R611 - - def test_simple(self): - cls = Substring_Range - a = cls(':') - assert isinstance(a, cls),`a` - assert_equal(str(a),':') - assert_equal(repr(a),"Substring_Range(None, None)") - - a = cls('a+1:') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a + 1 :') - - a = cls('a+1: c/foo(g)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a + 1 : c / foo(g)') - - a = cls('a:b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a : b') - assert_equal(repr(a),"Substring_Range(Name('a'), Name('b'))") - - a = cls('a:') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a :') - - a = cls(':b') - assert isinstance(a,cls),`a` - assert_equal(str(a),': b') - - -class TestDataRef(TestCase): # R612 - - def test_data_ref(self): - cls = Data_Ref - a = cls('a%b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a % b') - assert_equal(repr(a),"Data_Ref('%', (Name('a'), Name('b')))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestPartRef(TestCase): # R613 - - def test_part_ref(self): - cls = Part_Ref - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - -class TestTypeParamInquiry(TestCase): # R615 - - def test_simple(self): - cls = Type_Param_Inquiry - a = cls('a % b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a % b') - assert_equal(repr(a),"Type_Param_Inquiry(Name('a'), '%', Name('b'))") - - -class TestArraySection(TestCase): # R617 - - def test_array_section(self): - cls = Array_Section - a = cls('a(:)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a(:)') - assert_equal(repr(a),"Array_Section(Name('a'), Substring_Range(None, None))") - - a = cls('a(2:)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a(2 :)') - - -class TestSectionSubscript(TestCase): # R619 - - def test_simple(self): - cls = Section_Subscript - - a = cls('1:2') - assert isinstance(a, Subscript_Triplet),`a` - assert_equal(str(a),'1 : 2') - - a = cls('zzz') - assert isinstance(a, Name),`a` - assert_equal(str(a),'zzz') - -class TestSectionSubscriptList(TestCase): # R619-list - - def test_simple(self): - cls = Section_Subscript_List - a = cls('a,2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a, 2') - assert_equal(repr(a),"Section_Subscript_List(',', (Name('a'), Int_Literal_Constant('2', None)))") - - a = cls('::1') - assert isinstance(a,Subscript_Triplet),`a` - assert_equal(str(a),': : 1') - - a = cls('::1, 3') - assert isinstance(a,cls),`a` - assert_equal(str(a),': : 1, 3') - -class TestSubscriptTriplet(TestCase): # R620 - - def test_simple(self): - cls = Subscript_Triplet - a = cls('a:b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a : b') - assert_equal(repr(a),"Subscript_Triplet(Name('a'), Name('b'), None)") - - a = cls('a:b:1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a : b : 1') - - a = cls(':') - assert isinstance(a,cls),`a` - assert_equal(str(a),':') - - a = cls('::5') - assert isinstance(a,cls),`a` - assert_equal(str(a),': : 5') - - a = cls(':5') - assert isinstance(a,cls),`a` - assert_equal(str(a),': 5') - - a = cls('a+1 :') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a + 1 :') - -class TestAllocOpt(TestCase): # R624 - - def test_simple(self): - cls = Alloc_Opt - a = cls('stat=a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'STAT = a') - assert_equal(repr(a),"Alloc_Opt('STAT', Name('a'))") - -class TestNullifyStmt(TestCase): # R633 - - def test_simple(self): - cls = Nullify_Stmt - a = cls('nullify (a)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'NULLIFY(a)') - assert_equal(repr(a),"Nullify_Stmt('NULLIFY', Name('a'))") - - a = cls('nullify (a,c)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'NULLIFY(a, c)') - -############################################################################### -############################### SECTION 7 #################################### -############################################################################### - -class TestPrimary(TestCase): # R701 - - def test_simple(self): - cls = Primary - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - - a = cls('(a)') - assert isinstance(a,Parenthesis),`a` - assert_equal(str(a),'(a)') - - a = cls('1') - assert isinstance(a,Int_Literal_Constant),`a` - assert_equal(str(a),'1') - - a = cls('1.') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'1.') - - a = cls('(1, n)') - assert isinstance(a,Complex_Literal_Constant),`a` - assert_equal(str(a),'(1, n)') - - a = cls('.true.') - assert isinstance(a,Logical_Literal_Constant),`a` - assert_equal(str(a),'.TRUE.') - - a = cls('"hey a()c"') - assert isinstance(a,Char_Literal_Constant),`a` - assert_equal(str(a),'"hey a()c"') - - a = cls('b"0101"') - assert isinstance(a,Binary_Constant),`a` - assert_equal(str(a),'B"0101"') - - a = cls('o"0107"') - assert isinstance(a,Octal_Constant),`a` - assert_equal(str(a),'O"0107"') - - a = cls('z"a107"') - assert isinstance(a,Hex_Constant),`a` - assert_equal(str(a),'Z"A107"') - - a = cls('a % b') - assert isinstance(a,Data_Ref),`a` - assert_equal(str(a),'a % b') - - a = cls('a(:)') - assert isinstance(a,Array_Section),`a` - assert_equal(str(a),'a(:)') - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - -class TestParenthesis(TestCase): # R701.h - - def test_simple(self): - cls = Parenthesis - a = cls('(a)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(a)') - assert_equal(repr(a),"Parenthesis('(', Name('a'), ')')") - - a = cls('(a+1)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(a + 1)') - - a = cls('((a))') - assert isinstance(a,cls),`a` - assert_equal(str(a),'((a))') - - a = cls('(a+(a+c))') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(a + (a + c))') - -class TestLevel1Expr(TestCase): # R702 - - def test_simple(self): - cls = Level_1_Expr - a = cls('.hey. a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.HEY. a') - assert_equal(repr(a),"Level_1_Expr('.HEY.', Name('a'))") - - self.assertRaises(NoMatchError,cls,'.not. a') - -class TestMultOperand(TestCase): # R704 - - def test_simple(self): - cls = Mult_Operand - a = cls('a**b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a ** b') - assert_equal(repr(a),"Mult_Operand(Name('a'), '**', Name('b'))") - - a = cls('a**2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a ** 2') - - a = cls('(a+b)**2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'(a + b) ** 2') - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - -class TestAddOperand(TestCase): # R705 - - def test_simple(self): - cls = Add_Operand - a = cls('a*b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a * b') - assert_equal(repr(a),"Add_Operand(Name('a'), '*', Name('b'))") - - a = cls('a/b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a / b') - - a = cls('a**b') - assert isinstance(a,Mult_Operand),`a` - assert_equal(str(a),'a ** b') - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - -class TestLevel2Expr(TestCase): # R706 - - def test_simple(self): - cls = Level_2_Expr - a = cls('a+b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a + b') - assert_equal(repr(a),"Level_2_Expr(Name('a'), '+', Name('b'))") - - a = cls('a-b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a - b') - - a = cls('a+b+c') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a + b + c') - - a = cls('+a') - assert isinstance(a,Level_2_Unary_Expr),`a` - assert_equal(str(a),'+ a') - - a = cls('+1') - assert isinstance(a,Level_2_Unary_Expr),`a` - assert_equal(str(a),'+ 1') - - a = cls('+a+b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+ a + b') - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - - -class TestLevel2UnaryExpr(TestCase): - - def test_simple(self): - cls = Level_2_Unary_Expr - a = cls('+a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+ a') - assert_equal(repr(a),"Level_2_Unary_Expr('+', Name('a'))") - - a = cls('-a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'- a') - - a = cls('+1') - assert isinstance(a,cls),`a` - assert_equal(str(a),'+ 1') - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - - -class TestLevel3Expr(TestCase): # R710 - - def test_simple(self): - cls = Level_3_Expr - a = cls('a//b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a // b') - assert_equal(repr(a),"Level_3_Expr(Name('a'), '//', Name('b'))") - - a = cls('"a"//"b"') - assert isinstance(a,cls),`a` - assert_equal(str(a),'"a" // "b"') - -class TestLevel4Expr(TestCase): # R712 - - def test_simple(self): - cls = Level_4_Expr - a = cls('a.eq.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .EQ. b') - assert_equal(repr(a),"Level_4_Expr(Name('a'), '.EQ.', Name('b'))") - - a = cls('a.ne.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .NE. b') - - a = cls('a.lt.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .LT. b') - - a = cls('a.gt.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .GT. b') - - a = cls('a.ge.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .GE. b') - - a = cls('a==b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a == b') - - a = cls('a/=b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a /= b') - - a = cls('a<b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a < b') - - a = cls('a<=b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a <= b') - - a = cls('a>=b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a >= b') - - a = cls('a>b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a > b') - -class TestAndOperand(TestCase): # R714 - - def test_simple(self): - cls = And_Operand - a = cls('.not.a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'.NOT. a') - assert_equal(repr(a),"And_Operand('.NOT.', Name('a'))") - -class TestOrOperand(TestCase): # R715 - - def test_simple(self): - cls = Or_Operand - a = cls('a.and.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .AND. b') - assert_equal(repr(a),"Or_Operand(Name('a'), '.AND.', Name('b'))") - - -class TestEquivOperand(TestCase): # R716 - - def test_simple(self): - cls = Equiv_Operand - a = cls('a.or.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .OR. b') - assert_equal(repr(a),"Equiv_Operand(Name('a'), '.OR.', Name('b'))") - - -class TestLevel5Expr(TestCase): # R717 - - def test_simple(self): - cls = Level_5_Expr - a = cls('a.eqv.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .EQV. b') - assert_equal(repr(a),"Level_5_Expr(Name('a'), '.EQV.', Name('b'))") - - a = cls('a.neqv.b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .NEQV. b') - - a = cls('a.eq.b') - assert isinstance(a,Level_4_Expr),`a` - assert_equal(str(a),'a .EQ. b') - -class TestExpr(TestCase): # R722 - - def test_simple(self): - cls = Expr - a = cls('a .op. b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a .OP. b') - assert_equal(repr(a),"Expr(Name('a'), '.OP.', Name('b'))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - - a = cls('3.e2') - assert isinstance(a,Real_Literal_Constant),`a` - - a = cls('0.0E-1') - assert isinstance(a,Real_Literal_Constant),`a` - assert_equal(str(a),'0.0E-1') - - self.assertRaises(NoMatchError,Scalar_Int_Expr,'a,b') - -class TestAssignmentStmt(TestCase): # R734 - - def test_simple(self): - cls = Assignment_Stmt - a = cls('a = b') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a = b') - assert_equal(repr(a),"Assignment_Stmt(Name('a'), '=', Name('b'))") - - a = cls('a(3:4) = b+c') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a(3 : 4) = b + c') - - a = cls('a%c = b+c') - assert isinstance(a, cls),`a` - assert_equal(str(a),'a % c = b + c') - -class TestProcComponentRef(TestCase): # R741 - - def test_proc_component_ref(self): - cls = Proc_Component_Ref - a = cls('a % b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a % b') - assert_equal(repr(a),"Proc_Component_Ref(Name('a'), '%', Name('b'))") - -class TestWhereStmt(TestCase): # R743 - - def test_simple(self): - cls = Where_Stmt - a = cls('where (a) c=2') - assert isinstance(a,cls),`a` - assert_equal(str(a),'WHERE (a) c = 2') - assert_equal(repr(a),"Where_Stmt(Name('a'), Assignment_Stmt(Name('c'), '=', Int_Literal_Constant('2', None)))") - -class TestWhereConstructStmt(TestCase): # R745 - - def test_simple(self): - cls = Where_Construct_Stmt - a = cls('where (a)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'WHERE (a)') - assert_equal(repr(a),"Where_Construct_Stmt(Name('a'))") - - -############################################################################### -############################### SECTION 8 #################################### -############################################################################### - -class TestContinueStmt(TestCase): # R848 - - def test_simple(self): - cls = Continue_Stmt - a = cls('continue') - assert isinstance(a, cls),`a` - assert_equal(str(a),'CONTINUE') - assert_equal(repr(a),"Continue_Stmt('CONTINUE')") - -############################################################################### -############################### SECTION 9 #################################### -############################################################################### - -class TestIoUnit(TestCase): # R901 - - def test_simple(self): - cls = Io_Unit - a = cls('*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'*') - - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - -class TestWriteStmt(TestCase): # R911 - - def test_simple(self): - cls = Write_Stmt - a = cls('write (123)"hey"') - assert isinstance(a, cls),`a` - assert_equal(str(a),'WRITE(UNIT = 123) "hey"') - assert_equal(repr(a),'Write_Stmt(Io_Control_Spec_List(\',\', (Io_Control_Spec(\'UNIT\', Int_Literal_Constant(\'123\', None)),)), Char_Literal_Constant(\'"hey"\', None))') - -class TestPrintStmt(TestCase): # R912 - - def test_simple(self): - cls = Print_Stmt - a = cls('print 123') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PRINT 123') - assert_equal(repr(a),"Print_Stmt(Label('123'), None)") - - a = cls('print *,"a=",a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PRINT *, "a=", a') - -class TestIoControlSpec(TestCase): # R913 - - def test_simple(self): - cls = Io_Control_Spec - a = cls('end=123') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END = 123') - assert_equal(repr(a),"Io_Control_Spec('END', Label('123'))") - -class TestIoControlSpecList(TestCase): # R913-list - - def test_simple(self): - cls = Io_Control_Spec_List - a = cls('end=123') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END = 123') - assert_equal(repr(a),"Io_Control_Spec_List(',', (Io_Control_Spec('END', Label('123')),))") - - a = cls('123') - assert isinstance(a, cls),`a` - assert_equal(str(a),'UNIT = 123') - - a = cls('123,*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'UNIT = 123, FMT = *') - - a = cls('123,fmt=a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'UNIT = 123, FMT = a') - - if 0: - # see todo note in Io_Control_Spec_List - a = cls('123,a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'UNIT = 123, NML = a') - -class TestFormat(TestCase): # R914 - - def test_simple(self): - cls = Format - a = cls('*') - assert isinstance(a, cls),`a` - assert_equal(str(a),'*') - assert_equal(repr(a),"Format('*')") - - a = cls('a') - assert isinstance(a, Name),`a` - assert_equal(str(a),'a') - - a = cls('123') - assert isinstance(a, Label),`a` - assert_equal(str(a),'123') - -class TestWaitStmt(TestCase): # R921 - - def test_simple(self): - cls = Wait_Stmt - a = cls('wait (123)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'WAIT(UNIT = 123)') - -class TestWaitSpec(TestCase): # R922 - - def test_simple(self): - cls = Wait_Spec - a = cls('123') - assert isinstance(a, cls),`a` - assert_equal(str(a),'UNIT = 123') - assert_equal(repr(a),"Wait_Spec('UNIT', Int_Literal_Constant('123', None))") - - a = cls('err=1') - assert isinstance(a, cls),`a` - assert_equal(str(a),'ERR = 1') - -############################################################################### -############################### SECTION 10 #################################### -############################################################################### - - -############################################################################### -############################### SECTION 11 #################################### -############################################################################### - -class TestUseStmt(TestCase): # R1109 - - def test_simple(self): - cls = Use_Stmt - a = cls('use a') - assert isinstance(a, cls),`a` - assert_equal(str(a),'USE :: a') - assert_equal(repr(a),"Use_Stmt(None, Name('a'), '', None)") - - a = cls('use :: a, c=>d') - assert isinstance(a, cls),`a` - assert_equal(str(a),'USE :: a, c => d') - - a = cls('use :: a, operator(.hey.)=>operator(.hoo.)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'USE :: a, OPERATOR(.HEY.) => OPERATOR(.HOO.)') - - a = cls('use, intrinsic :: a, operator(.hey.)=>operator(.hoo.), c=>g') - assert isinstance(a, cls),`a` - assert_equal(str(a),'USE, INTRINSIC :: a, OPERATOR(.HEY.) => OPERATOR(.HOO.), c => g') - -class TestModuleNature(TestCase): # R1110 - - def test_simple(self): - cls = Module_Nature - a = cls('intrinsic') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTRINSIC') - assert_equal(repr(a),"Module_Nature('INTRINSIC')") - - a = cls('non_intrinsic') - assert isinstance(a, cls),`a` - assert_equal(str(a),'NON_INTRINSIC') - -############################################################################### -############################### SECTION 12 #################################### -############################################################################### - -class TestFunctionReference(TestCase): # R1217 - - def test_simple(self): - cls = Function_Reference - a = cls('f()') - assert isinstance(a,cls),`a` - assert_equal(str(a),'f()') - assert_equal(repr(a),"Function_Reference(Name('f'), None)") - - a = cls('f(2,k=1,a)') - assert isinstance(a,cls),`a` - assert_equal(str(a),'f(2, k = 1, a)') - - -class TestProcedureDesignator(TestCase): # R1219 - - def test_procedure_designator(self): - cls = Procedure_Designator - a = cls('a%b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a % b') - assert_equal(repr(a),"Procedure_Designator(Name('a'), '%', Name('b'))") - -class TestActualArgSpec(TestCase): # R1220 - - def test_simple(self): - cls = Actual_Arg_Spec - a = cls('k=a') - assert isinstance(a,cls),`a` - assert_equal(str(a),'k = a') - assert_equal(repr(a),"Actual_Arg_Spec(Name('k'), Name('a'))") - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestActualArgSpecList(TestCase): - - def test_simple(self): - cls = Actual_Arg_Spec_List - a = cls('a,b') - assert isinstance(a,cls),`a` - assert_equal(str(a),'a, b') - assert_equal(repr(a),"Actual_Arg_Spec_List(',', (Name('a'), Name('b')))") - - a = cls('a = k') - assert isinstance(a,Actual_Arg_Spec),`a` - assert_equal(str(a),'a = k') - - a = cls('a = k,b') - assert isinstance(a,Actual_Arg_Spec_List),`a` - assert_equal(str(a),'a = k, b') - - a = cls('a') - assert isinstance(a,Name),`a` - assert_equal(str(a),'a') - -class TestAltReturnSpec(TestCase): # R1222 - - def test_alt_return_spec(self): - cls = Alt_Return_Spec - a = cls('* 123') - assert isinstance(a,cls),`a` - assert_equal(str(a),'*123') - assert_equal(repr(a),"Alt_Return_Spec(Label('123'))") - -class TestPrefix(TestCase): # R1227 - - def test_simple(self): - cls = Prefix - a = cls('pure recursive') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PURE RECURSIVE') - assert_equal(repr(a), "Prefix(' ', (Prefix_Spec('PURE'), Prefix_Spec('RECURSIVE')))") - - a = cls('integer * 2 pure') - assert isinstance(a, cls),`a` - assert_equal(str(a),'INTEGER*2 PURE') - -class TestPrefixSpec(TestCase): # R1228 - - def test_simple(self): - cls = Prefix_Spec - a = cls('pure') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PURE') - assert_equal(repr(a),"Prefix_Spec('PURE')") - - a = cls('elemental') - assert isinstance(a, cls),`a` - assert_equal(str(a),'ELEMENTAL') - - a = cls('recursive') - assert isinstance(a, cls),`a` - assert_equal(str(a),'RECURSIVE') - - a = cls('integer * 2') - assert isinstance(a, Intrinsic_Type_Spec),`a` - assert_equal(str(a),'INTEGER*2') - -class TestSubroutineSubprogram(TestCase): # R1231 - - def test_simple(self): - from api import get_reader - reader = get_reader('''\ - subroutine foo - end subroutine foo''') - cls = Subroutine_Subprogram - a = cls(reader) - assert isinstance(a, cls),`a` - assert_equal(str(a),'SUBROUTINE foo\nEND SUBROUTINE foo') - assert_equal(repr(a),"Subroutine_Subprogram(Subroutine_Stmt(None, Name('foo'), None, None), End_Subroutine_Stmt('SUBROUTINE', Name('foo')))") - - reader = get_reader('''\ - subroutine foo - integer a - end subroutine foo''') - cls = Subroutine_Subprogram - a = cls(reader) - assert isinstance(a, cls),`a` - assert_equal(str(a),'SUBROUTINE foo\n INTEGER :: a\nEND SUBROUTINE foo') - -class TestSubroutineStmt(TestCase): # R1232 - - def test_simple(self): - cls = Subroutine_Stmt - a = cls('subroutine foo') - assert isinstance(a, cls),`a` - assert_equal(str(a),'SUBROUTINE foo') - assert_equal(repr(a),"Subroutine_Stmt(None, Name('foo'), None, None)") - - a = cls('pure subroutine foo') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PURE SUBROUTINE foo') - - a = cls('pure subroutine foo(a,b)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'PURE SUBROUTINE foo(a, b)') - - a = cls('subroutine foo() bind(c)') - assert isinstance(a, cls),`a` - assert_equal(str(a),'SUBROUTINE foo BIND(C)') - -class TestEndSubroutineStmt(TestCase): # R1234 - - def test_simple(self): - cls = End_Subroutine_Stmt - a = cls('end subroutine foo') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END SUBROUTINE foo') - assert_equal(repr(a),"End_Subroutine_Stmt('SUBROUTINE', Name('foo'))") - - a = cls('end') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END SUBROUTINE') - - a = cls('endsubroutine') - assert isinstance(a, cls),`a` - assert_equal(str(a),'END SUBROUTINE') - -class TestReturnStmt(TestCase): # R1236 - - def test_simple(self): - cls = Return_Stmt - a = cls('return') - assert isinstance(a, cls),`a` - assert_equal(str(a), 'RETURN') - assert_equal(repr(a), 'Return_Stmt(None)') - -class TestContains(TestCase): # R1237 - - def test_simple(self): - cls = Contains_Stmt - a = cls('Contains') - assert isinstance(a, cls),`a` - assert_equal(str(a),'CONTAINS') - assert_equal(repr(a),"Contains_Stmt('CONTAINS')") - -if False: - nof_needed_tests = 0 - nof_needed_match = 0 - total_needs = 0 - total_classes = 0 - for name in dir(): - obj = eval(name) - if not isinstance(obj, ClassType): continue - if not issubclass(obj, Base): continue - clsname = obj.__name__ - if clsname.endswith('Base'): continue - total_classes += 1 - subclass_names = obj.__dict__.get('subclass_names',None) - use_names = obj.__dict__.get('use_names',None) - if not use_names: continue - match = obj.__dict__.get('match',None) - try: - test_cls = eval('test_%s' % (clsname)) - except NameError: - test_cls = None - total_needs += 1 - if match is None: - if test_cls is None: - #print 'Needs tests:', clsname - print 'Needs match implementation:', clsname - nof_needed_tests += 1 - nof_needed_match += 1 - else: - print 'Needs match implementation:', clsname - nof_needed_match += 1 - else: - if test_cls is None: - #print 'Needs tests:', clsname - nof_needed_tests += 1 - continue - print '-----' - print 'Nof match implementation needs:',nof_needed_match,'out of',total_needs - print 'Nof tests needs:',nof_needed_tests,'out of',total_needs - print 'Total number of classes:',total_classes - print '-----' - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/parser/test_parser.py b/numpy/f2py/lib/parser/test_parser.py deleted file mode 100644 index f242b867f..000000000 --- a/numpy/f2py/lib/parser/test_parser.py +++ /dev/null @@ -1,497 +0,0 @@ -""" -Test parsing single Fortran lines. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -from numpy.testing import * -from block_statements import * -from readfortran import Line, FortranStringReader - - -def parse(cls, line, label='', - isfree=True, isstrict=False): - if label: - line = label + ' : ' + line - reader = FortranStringReader(line, isfree, isstrict) - item = reader.next() - if not cls.match(item.get_line()): - raise ValueError, '%r does not match %s pattern' % (line, cls.__name__) - stmt = cls(item, item) - if stmt.isvalid: - r = str(stmt) - if not isstrict: - r1 = parse(cls, r, isstrict=True) - if r != r1: - raise ValueError, 'Failed to parse %r with %s pattern in pyf mode, got %r' % (r, cls.__name__, r1) - return r - raise ValueError, 'parsing %r with %s pattern failed' % (line, cls.__name__) - -class TestStatements(TestCase): - - def test_assignment(self): - assert_equal(parse(Assignment,'a=b'), 'a = b') - assert_equal(parse(PointerAssignment,'a=>b'), 'a => b') - assert_equal(parse(Assignment,'a (2)=b(n,m)'), 'a(2) = b(n,m)') - assert_equal(parse(Assignment,'a % 2(2,4)=b(a(i))'), 'a%2(2,4) = b(a(i))') - - def test_assign(self): - assert_equal(parse(Assign,'assign 10 to a'),'ASSIGN 10 TO a') - - def test_call(self): - assert_equal(parse(Call,'call a'),'CALL a') - assert_equal(parse(Call,'call a()'),'CALL a') - assert_equal(parse(Call,'call a(1)'),'CALL a(1)') - assert_equal(parse(Call,'call a(1,2)'),'CALL a(1, 2)') - assert_equal(parse(Call,'call a % 2 ( n , a+1 )'),'CALL a % 2(n, a+1)') - - def test_goto(self): - assert_equal(parse(Goto,'go to 19'),'GO TO 19') - assert_equal(parse(Goto,'goto 19'),'GO TO 19') - assert_equal(parse(ComputedGoto,'goto (1, 2 ,3) a+b(2)'), - 'GO TO (1, 2, 3) a+b(2)') - assert_equal(parse(ComputedGoto,'goto (1, 2 ,3) , a+b(2)'), - 'GO TO (1, 2, 3) a+b(2)') - assert_equal(parse(AssignedGoto,'goto a'),'GO TO a') - assert_equal(parse(AssignedGoto,'goto a ( 1 )'),'GO TO a (1)') - assert_equal(parse(AssignedGoto,'goto a ( 1 ,2)'),'GO TO a (1, 2)') - - def test_continue(self): - assert_equal(parse(Continue,'continue'),'CONTINUE') - - def test_return(self): - assert_equal(parse(Return,'return'),'RETURN') - assert_equal(parse(Return,'return a'),'RETURN a') - assert_equal(parse(Return,'return a+1'),'RETURN a+1') - assert_equal(parse(Return,'return a(c, a)'),'RETURN a(c, a)') - - def test_stop(self): - assert_equal(parse(Stop,'stop'),'STOP') - assert_equal(parse(Stop,'stop 1'),'STOP 1') - assert_equal(parse(Stop,'stop "a"'),'STOP "a"') - assert_equal(parse(Stop,'stop "a b"'),'STOP "a b"') - - def test_print(self): - assert_equal(parse(Print, 'print*'),'PRINT *') - assert_equal(parse(Print, 'print "a b( c )"'),'PRINT "a b( c )"') - assert_equal(parse(Print, 'print 12, a'),'PRINT 12, a') - assert_equal(parse(Print, 'print 12, a , b'),'PRINT 12, a, b') - assert_equal(parse(Print, 'print 12, a(c,1) , b'),'PRINT 12, a(c,1), b') - - def test_read(self): - assert_equal(parse(Read, 'read ( 10 )'),'READ (10)') - assert_equal(parse(Read, 'read ( 10 ) a '),'READ (10) a') - assert_equal(parse(Read, 'read ( 10 ) a , b'),'READ (10) a, b') - assert_equal(parse(Read, 'read *'),'READ *') - assert_equal(parse(Read, 'read 12'),'READ 12') - assert_equal(parse(Read, 'read "a b"'),'READ "a b"') - assert_equal(parse(Read, 'read "a b",a'),'READ "a b", a') - assert_equal(parse(Read, 'read * , a'),'READ *, a') - assert_equal(parse(Read, 'read "hey a" , a'),'READ "hey a", a') - assert_equal(parse(Read, 'read * , a , b'),'READ *, a, b') - assert_equal(parse(Read, 'read ( unit =10 )'),'READ (UNIT = 10)') - - def test_write(self): - assert_equal(parse(Write, 'write ( 10 )'),'WRITE (10)') - assert_equal(parse(Write, 'write ( 10 , a )'),'WRITE (10, a)') - assert_equal(parse(Write, 'write ( 10 ) b'),'WRITE (10) b') - assert_equal(parse(Write, 'write ( 10 ) a(1) , b+2'),'WRITE (10) a(1), b+2') - assert_equal(parse(Write, 'write ( unit=10 )'),'WRITE (UNIT = 10)') - - def test_flush(self): - assert_equal(parse(Flush, 'flush 10'),'FLUSH (10)') - assert_equal(parse(Flush, 'flush (10)'),'FLUSH (10)') - assert_equal(parse(Flush, 'flush (UNIT = 10)'),'FLUSH (UNIT = 10)') - assert_equal(parse(Flush, 'flush (10, err= 23)'),'FLUSH (10, ERR = 23)') - - def test_wait(self): - assert_equal(parse(Wait, 'wait(10)'),'WAIT (10)') - assert_equal(parse(Wait, 'wait(10,err=129)'),'WAIT (10, ERR = 129)') - - def test_contains(self): - assert_equal(parse(Contains, 'contains'),'CONTAINS') - - def test_allocate(self): - assert_equal(parse(Allocate, 'allocate (a)'), 'ALLOCATE (a)') - assert_equal(parse(Allocate, \ - 'allocate (a, stat=b)'), 'ALLOCATE (a, STAT = b)') - assert_equal(parse(Allocate, 'allocate (a,b(:1))'), 'ALLOCATE (a, b(:1))') - assert_equal(parse(Allocate, \ - 'allocate (real(8)::a)'), 'ALLOCATE (REAL(KIND=8) :: a)') - def test_deallocate(self): - assert_equal(parse(Deallocate, 'deallocate (a)'), 'DEALLOCATE (a)') - assert_equal(parse(Deallocate, 'deallocate (a, stat=b)'), 'DEALLOCATE (a, STAT = b)') - - def test_moduleprocedure(self): - assert_equal(parse(ModuleProcedure,\ - 'ModuleProcedure a'), 'MODULE PROCEDURE a') - assert_equal(parse(ModuleProcedure,\ - 'module procedure a , b'), 'MODULE PROCEDURE a, b') - - def test_access(self): - assert_equal(parse(Public,'Public'),'PUBLIC') - assert_equal(parse(Public,'public a'),'PUBLIC a') - assert_equal(parse(Public,'public :: a'),'PUBLIC a') - assert_equal(parse(Public,'public a,b,c'),'PUBLIC a, b, c') - assert_equal(parse(Public,'public :: a(:,:)'),'PUBLIC a(:,:)') - assert_equal(parse(Private,'private'),'PRIVATE') - assert_equal(parse(Private,'private :: a'),'PRIVATE a') - - def test_close(self): - assert_equal(parse(Close,'close (12)'),'CLOSE (12)') - assert_equal(parse(Close,'close (12, err=99)'),'CLOSE (12, ERR = 99)') - assert_equal(parse(Close,'close (12, status = a(1,2))'),'CLOSE (12, STATUS = a(1,2))') - - def test_cycle(self): - assert_equal(parse(Cycle,'cycle'),'CYCLE') - assert_equal(parse(Cycle,'cycle ab'),'CYCLE ab') - - def test_rewind(self): - assert_equal(parse(Rewind,'rewind 1'),'REWIND (1)') - assert_equal(parse(Rewind,'rewind (1)'),'REWIND (1)') - assert_equal(parse(Rewind,'rewind (1, err = 123)'),'REWIND (1, ERR = 123)') - - def test_backspace(self): - assert_equal(parse(Backspace,'backspace 1'),'BACKSPACE (1)') - assert_equal(parse(Backspace,'backspace (1)'),'BACKSPACE (1)') - assert_equal(parse(Backspace,'backspace (1, err = 123)'),'BACKSPACE (1, ERR = 123)') - - def test_endfile(self): - assert_equal(parse(Endfile,'endfile 1'),'ENDFILE (1)') - assert_equal(parse(Endfile,'endfile (1)'),'ENDFILE (1)') - assert_equal(parse(Endfile,'endfile (1, err = 123)'),'ENDFILE (1, ERR = 123)') - - def test_open(self): - assert_equal(parse(Open,'open (1)'),'OPEN (1)') - assert_equal(parse(Open,'open (1, err = 123)'),'OPEN (1, ERR = 123)') - - def test_format(self): - assert_equal(parse(Format,'1: format ()'),'1: FORMAT ()') - assert_equal(parse(Format,'199 format (1)'),'199: FORMAT (1)') - assert_equal(parse(Format,'2 format (1 , SS)'),'2: FORMAT (1, ss)') - - def test_save(self): - assert_equal(parse(Save,'save'), 'SAVE') - assert_equal(parse(Save,'save :: a'), 'SAVE a') - assert_equal(parse(Save,'save a,b'), 'SAVE a, b') - - def test_data(self): - assert_equal(parse(Data,'data a /b/'), 'DATA a / b /') - assert_equal(parse(Data,'data a , c /b/'), 'DATA a, c / b /') - assert_equal(parse(Data,'data a /b ,c/'), 'DATA a / b, c /') - assert_equal(parse(Data,'data a /b/ c,e /d/'), 'DATA a / b / c, e / d /') - assert_equal(parse(Data,'data a(1,2) /b/'), 'DATA a(1,2) / b /') - assert_equal(parse(Data,'data a /b, c(1)/'), 'DATA a / b, c(1) /') - - def test_nullify(self): - assert_equal(parse(Nullify,'nullify(a)'),'NULLIFY (a)') - assert_equal(parse(Nullify,'nullify(a ,b)'),'NULLIFY (a, b)') - - def test_use(self): - assert_equal(parse(Use, 'use a'), 'USE a') - assert_equal(parse(Use, 'use :: a'), 'USE a') - assert_equal(parse(Use, 'use, intrinsic:: a'), 'USE INTRINSIC :: a') - assert_equal(parse(Use, 'use :: a ,only: b'), 'USE a, ONLY: b') - assert_equal(parse(Use, 'use :: a , only: b=>c'), 'USE a, ONLY: b=>c') - assert_equal(parse(Use, 'use :: a , b=>c'), 'USE a, b=>c') - assert_equal(parse(Use,\ - 'use :: a , only: operator(+) , b'),\ - 'USE a, ONLY: operator(+), b') - - def test_exit(self): - assert_equal(parse(Exit,'exit'),'EXIT') - assert_equal(parse(Exit,'exit ab'),'EXIT ab') - - def test_parameter(self): - assert_equal(parse(Parameter,'parameter (a = b(1,2))'), - 'PARAMETER (a = b(1,2))') - assert_equal(parse(Parameter,'parameter (a = b(1,2) , b=1)'), - 'PARAMETER (a = b(1,2), b=1)') - - def test_equivalence(self): - assert_equal(parse(Equivalence,'equivalence (a , b)'),'EQUIVALENCE (a, b)') - assert_equal(parse(Equivalence,'equivalence (a , b) , ( c, d(1) , g )'), - 'EQUIVALENCE (a, b), (c, d(1), g)') - - def test_dimension(self): - assert_equal(parse(Dimension,'dimension a(b)'),'DIMENSION a(b)') - assert_equal(parse(Dimension,'dimension::a(b)'),'DIMENSION a(b)') - assert_equal(parse(Dimension,'dimension a(b) , c(d)'),'DIMENSION a(b), c(d)') - assert_equal(parse(Dimension,'dimension a(b,c)'),'DIMENSION a(b,c)') - - def test_target(self): - assert_equal(parse(Target,'target a(b)'),'TARGET a(b)') - assert_equal(parse(Target,'target::a(b)'),'TARGET a(b)') - assert_equal(parse(Target,'target a(b) , c(d)'),'TARGET a(b), c(d)') - assert_equal(parse(Target,'target a(b,c)'),'TARGET a(b,c)') - - def test_pointer(self): - assert_equal(parse(Pointer,'pointer a=b'),'POINTER a=b') - assert_equal(parse(Pointer,'pointer :: a=b'),'POINTER a=b') - assert_equal(parse(Pointer,'pointer a=b, c=d(1,2)'),'POINTER a=b, c=d(1,2)') - - def test_protected(self): - assert_equal(parse(Protected,'protected a'),'PROTECTED a') - assert_equal(parse(Protected,'protected::a'),'PROTECTED a') - assert_equal(parse(Protected,'protected a , b'),'PROTECTED a, b') - - def test_volatile(self): - assert_equal(parse(Volatile,'volatile a'),'VOLATILE a') - assert_equal(parse(Volatile,'volatile::a'),'VOLATILE a') - assert_equal(parse(Volatile,'volatile a , b'),'VOLATILE a, b') - - def test_value(self): - assert_equal(parse(Value,'value a'),'VALUE a') - assert_equal(parse(Value,'value::a'),'VALUE a') - assert_equal(parse(Value,'value a , b'),'VALUE a, b') - - def test_arithmeticif(self): - assert_equal(parse(ArithmeticIf,'if (a) 1,2,3'),'IF (a) 1, 2, 3') - assert_equal(parse(ArithmeticIf,'if (a(1)) 1,2,3'),'IF (a(1)) 1, 2, 3') - assert_equal(parse(ArithmeticIf,'if (a(1,2)) 1,2,3'),'IF (a(1,2)) 1, 2, 3') - - def test_intrinsic(self): - assert_equal(parse(Intrinsic,'intrinsic a'),'INTRINSIC a') - assert_equal(parse(Intrinsic,'intrinsic::a'),'INTRINSIC a') - assert_equal(parse(Intrinsic,'intrinsic a , b'),'INTRINSIC a, b') - - def test_inquire(self): - assert_equal(parse(Inquire, 'inquire (1)'),'INQUIRE (1)') - assert_equal(parse(Inquire, 'inquire (1, err=123)'),'INQUIRE (1, ERR = 123)') - assert_equal(parse(Inquire, 'inquire (iolength=a) b'),'INQUIRE (IOLENGTH = a) b') - assert_equal(parse(Inquire, 'inquire (iolength=a) b ,c(1,2)'), - 'INQUIRE (IOLENGTH = a) b, c(1,2)') - - def test_sequence(self): - assert_equal(parse(Sequence, 'sequence'),'SEQUENCE') - - def test_external(self): - assert_equal(parse(External,'external a'),'EXTERNAL a') - assert_equal(parse(External,'external::a'),'EXTERNAL a') - assert_equal(parse(External,'external a , b'),'EXTERNAL a, b') - - def test_common(self): - assert_equal(parse(Common, 'common a'),'COMMON a') - assert_equal(parse(Common, 'common a , b'),'COMMON a, b') - assert_equal(parse(Common, 'common a , b(1,2)'),'COMMON a, b(1,2)') - assert_equal(parse(Common, 'common // a'),'COMMON a') - assert_equal(parse(Common, 'common / name/ a'),'COMMON / name / a') - assert_equal(parse(Common, 'common / name/ a , c'),'COMMON / name / a, c') - assert_equal(parse(Common, 'common / name/ a /foo/ c(1) ,d'), - 'COMMON / name / a / foo / c(1), d') - assert_equal(parse(Common, 'common / name/ a, /foo/ c(1) ,d'), - 'COMMON / name / a / foo / c(1), d') - - def test_optional(self): - assert_equal(parse(Optional,'optional a'),'OPTIONAL a') - assert_equal(parse(Optional,'optional::a'),'OPTIONAL a') - assert_equal(parse(Optional,'optional a , b'),'OPTIONAL a, b') - - def test_intent(self): - assert_equal(parse(Intent,'intent (in) a'),'INTENT (IN) a') - assert_equal(parse(Intent,'intent(in)::a'),'INTENT (IN) a') - assert_equal(parse(Intent,'intent(in) a , b'),'INTENT (IN) a, b') - assert_equal(parse(Intent,'intent (in, out) a'),'INTENT (IN, OUT) a') - - def test_entry(self): - assert_equal(parse(Entry,'entry a'), 'ENTRY a') - assert_equal(parse(Entry,'entry a()'), 'ENTRY a') - assert_equal(parse(Entry,'entry a(b)'), 'ENTRY a (b)') - assert_equal(parse(Entry,'entry a(b,*)'), 'ENTRY a (b, *)') - assert_equal(parse(Entry,'entry a bind(c , name="a b")'), - 'ENTRY a BIND (C, NAME = "a b")') - assert_equal(parse(Entry,'entry a result (b)'), 'ENTRY a RESULT (b)') - assert_equal(parse(Entry,'entry a bind(d) result (b)'), - 'ENTRY a RESULT (b) BIND (D)') - assert_equal(parse(Entry,'entry a result (b) bind( c )'), - 'ENTRY a RESULT (b) BIND (C)') - assert_equal(parse(Entry,'entry a(b,*) result (g)'), - 'ENTRY a (b, *) RESULT (g)') - - def test_import(self): - assert_equal(parse(Import,'import'),'IMPORT') - assert_equal(parse(Import,'import a'),'IMPORT a') - assert_equal(parse(Import,'import::a'),'IMPORT a') - assert_equal(parse(Import,'import a , b'),'IMPORT a, b') - - def test_forall(self): - assert_equal(parse(ForallStmt,'forall (i = 1:n(k,:) : 2) a(i) = i*i*b(i)'), - 'FORALL (i = 1 : n(k,:) : 2) a(i) = i*i*b(i)') - assert_equal(parse(ForallStmt,'forall (i=1:n,j=2:3) a(i) = b(i,i)'), - 'FORALL (i = 1 : n, j = 2 : 3) a(i) = b(i,i)') - assert_equal(parse(ForallStmt,'forall (i=1:n,j=2:3, 1+a(1,2)) a(i) = b(i,i)'), - 'FORALL (i = 1 : n, j = 2 : 3, 1+a(1,2)) a(i) = b(i,i)') - - def test_specificbinding(self): - assert_equal(parse(SpecificBinding,'procedure a'),'PROCEDURE a') - assert_equal(parse(SpecificBinding,'procedure :: a'),'PROCEDURE a') - assert_equal(parse(SpecificBinding,'procedure , NOPASS :: a'),'PROCEDURE , NOPASS :: a') - assert_equal(parse(SpecificBinding,'procedure , public, pass(x ) :: a'),'PROCEDURE , PUBLIC, PASS (x) :: a') - assert_equal(parse(SpecificBinding,'procedure(n) a'),'PROCEDURE (n) a') - assert_equal(parse(SpecificBinding,'procedure(n),pass :: a'), - 'PROCEDURE (n) , PASS :: a') - assert_equal(parse(SpecificBinding,'procedure(n) :: a'), - 'PROCEDURE (n) a') - assert_equal(parse(SpecificBinding,'procedure a= >b'),'PROCEDURE a => b') - assert_equal(parse(SpecificBinding,'procedure(n),pass :: a =>c'), - 'PROCEDURE (n) , PASS :: a => c') - - def test_genericbinding(self): - assert_equal(parse(GenericBinding,'generic :: a=>b'),'GENERIC :: a => b') - assert_equal(parse(GenericBinding,'generic, public :: a=>b'),'GENERIC, PUBLIC :: a => b') - assert_equal(parse(GenericBinding,'generic, public :: a(1,2)=>b ,c'), - 'GENERIC, PUBLIC :: a(1,2) => b, c') - - def test_finalbinding(self): - assert_equal(parse(FinalBinding,'final a'),'FINAL a') - assert_equal(parse(FinalBinding,'final::a'),'FINAL a') - assert_equal(parse(FinalBinding,'final a , b'),'FINAL a, b') - - def test_allocatable(self): - assert_equal(parse(Allocatable,'allocatable a'),'ALLOCATABLE a') - assert_equal(parse(Allocatable,'allocatable :: a'),'ALLOCATABLE a') - assert_equal(parse(Allocatable,'allocatable a (1,2)'),'ALLOCATABLE a (1,2)') - assert_equal(parse(Allocatable,'allocatable a (1,2) ,b'),'ALLOCATABLE a (1,2), b') - - def test_asynchronous(self): - assert_equal(parse(Asynchronous,'asynchronous a'),'ASYNCHRONOUS a') - assert_equal(parse(Asynchronous,'asynchronous::a'),'ASYNCHRONOUS a') - assert_equal(parse(Asynchronous,'asynchronous a , b'),'ASYNCHRONOUS a, b') - - def test_bind(self): - assert_equal(parse(Bind,'bind(c) a'),'BIND (C) a') - assert_equal(parse(Bind,'bind(c) :: a'),'BIND (C) a') - assert_equal(parse(Bind,'bind(c) a ,b'),'BIND (C) a, b') - assert_equal(parse(Bind,'bind(c) /a/'),'BIND (C) / a /') - assert_equal(parse(Bind,'bind(c) /a/ ,b'),'BIND (C) / a /, b') - assert_equal(parse(Bind,'bind(c,name="hey") a'),'BIND (C, NAME = "hey") a') - - def test_else(self): - assert_equal(parse(Else,'else'),'ELSE') - assert_equal(parse(ElseIf,'else if (a) then'),'ELSE IF (a) THEN') - assert_equal(parse(ElseIf,'else if (a.eq.b(1,2)) then'), - 'ELSE IF (a.eq.b(1,2)) THEN') - - def test_case(self): - assert_equal(parse(Case,'case (1)'),'CASE ( 1 )') - assert_equal(parse(Case,'case (1:)'),'CASE ( 1 : )') - assert_equal(parse(Case,'case (:1)'),'CASE ( : 1 )') - assert_equal(parse(Case,'case (1:2)'),'CASE ( 1 : 2 )') - assert_equal(parse(Case,'case (a(1,2))'),'CASE ( a(1,2) )') - assert_equal(parse(Case,'case ("ab")'),'CASE ( "ab" )') - assert_equal(parse(Case,'case default'),'CASE DEFAULT') - assert_equal(parse(Case,'case (1:2 ,3:4)'),'CASE ( 1 : 2, 3 : 4 )') - assert_equal(parse(Case,'case (a(1,:):)'),'CASE ( a(1,:) : )') - assert_equal(parse(Case,'case default'),'CASE DEFAULT') - - def test_where(self): - assert_equal(parse(WhereStmt,'where (1) a=1'),'WHERE ( 1 ) a = 1') - assert_equal(parse(WhereStmt,'where (a(1,2)) a=1'),'WHERE ( a(1,2) ) a = 1') - - def test_elsewhere(self): - assert_equal(parse(ElseWhere,'else where'),'ELSE WHERE') - assert_equal(parse(ElseWhere,'elsewhere (1)'),'ELSE WHERE ( 1 )') - assert_equal(parse(ElseWhere,'elsewhere(a(1,2))'),'ELSE WHERE ( a(1,2) )') - - def test_enumerator(self): - assert_equal(parse(Enumerator,'enumerator a'), 'ENUMERATOR a') - assert_equal(parse(Enumerator,'enumerator:: a'), 'ENUMERATOR a') - assert_equal(parse(Enumerator,'enumerator a,b'), 'ENUMERATOR a, b') - assert_equal(parse(Enumerator,'enumerator a=1'), 'ENUMERATOR a=1') - assert_equal(parse(Enumerator,'enumerator a=1 , b=c(1,2)'), 'ENUMERATOR a=1, b=c(1,2)') - - def test_fortranname(self): - assert_equal(parse(FortranName,'fortranname a'),'FORTRANNAME a') - - def test_threadsafe(self): - assert_equal(parse(Threadsafe,'threadsafe'),'THREADSAFE') - - def test_depend(self): - assert_equal(parse(Depend,'depend( a) b'), 'DEPEND ( a ) b') - assert_equal(parse(Depend,'depend( a) ::b'), 'DEPEND ( a ) b') - assert_equal(parse(Depend,'depend( a,c) b,e'), 'DEPEND ( a, c ) b, e') - - def test_check(self): - assert_equal(parse(Check,'check(1) a'), 'CHECK ( 1 ) a') - assert_equal(parse(Check,'check(1) :: a'), 'CHECK ( 1 ) a') - assert_equal(parse(Check,'check(b(1,2)) a'), 'CHECK ( b(1,2) ) a') - assert_equal(parse(Check,'check(a>1) :: a'), 'CHECK ( a>1 ) a') - - def test_callstatement(self): - assert_equal(parse(CallStatement,'callstatement (*func)()',isstrict=1), - 'CALLSTATEMENT (*func)()') - assert_equal(parse(CallStatement,'callstatement i=1;(*func)()',isstrict=1), - 'CALLSTATEMENT i=1;(*func)()') - - def test_callprotoargument(self): - assert_equal(parse(CallProtoArgument,'callprotoargument int(*), double'), - 'CALLPROTOARGUMENT int(*), double') - - def test_pause(self): - assert_equal(parse(Pause,'pause'),'PAUSE') - assert_equal(parse(Pause,'pause 1'),'PAUSE 1') - assert_equal(parse(Pause,'pause "hey"'),'PAUSE "hey"') - assert_equal(parse(Pause,'pause "hey pa"'),'PAUSE "hey pa"') - - def test_integer(self): - assert_equal(parse(Integer,'integer'),'INTEGER') - assert_equal(parse(Integer,'integer*4'),'INTEGER*4') - assert_equal(parse(Integer,'integer*4 a'),'INTEGER*4 a') - assert_equal(parse(Integer,'integer*4, a'),'INTEGER*4 a') - assert_equal(parse(Integer,'integer*4 a ,b'),'INTEGER*4 a, b') - assert_equal(parse(Integer,'integer*4 :: a ,b'),'INTEGER*4 a, b') - assert_equal(parse(Integer,'integer*4 a(1,2)'),'INTEGER*4 a(1,2)') - assert_equal(parse(Integer,'integer*4 :: a(1,2),b'),'INTEGER*4 a(1,2), b') - assert_equal(parse(Integer,'integer*4 external :: a'), - 'INTEGER*4, external :: a') - assert_equal(parse(Integer,'integer*4, external :: a'), - 'INTEGER*4, external :: a') - assert_equal(parse(Integer,'integer*4 external , intent(in) :: a'), - 'INTEGER*4, external, intent(in) :: a') - assert_equal(parse(Integer,'integer(kind=4)'),'INTEGER(KIND=4)') - assert_equal(parse(Integer,'integer ( kind = 4)'),'INTEGER(KIND=4)') - assert_equal(parse(Integer,'integer(kind=2+2)'),'INTEGER(KIND=2+2)') - assert_equal(parse(Integer,'integer(kind=f(4,5))'),'INTEGER(KIND=f(4,5))') - - def test_character(self): - assert_equal(parse(Character,'character'),'CHARACTER') - assert_equal(parse(Character,'character*2'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character**'),'CHARACTER(LEN=*)') - assert_equal(parse(Character,'character*(2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =2),'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character*(len =:)'),'CHARACTER(LEN=:)') - assert_equal(parse(Character,'character(len =2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character(2)'),'CHARACTER(LEN=2)') - assert_equal(parse(Character,'character(kind=2)'),'CHARACTER(KIND=2)') - assert_equal(parse(Character,'character(kind=2,len=3)'), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'character(lEN=3,kind=2)'), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'character(len=3,kind=2)', isstrict=True), - 'CHARACTER(LEN=3, KIND=2)') - assert_equal(parse(Character,'chaRACTER(len=3,kind=fA(1,2))', isstrict=True), - 'CHARACTER(LEN=3, KIND=fA(1,2))') - assert_equal(parse(Character,'character(len=3,kind=fA(1,2))'), - 'CHARACTER(LEN=3, KIND=fa(1,2))') - - def test_implicit(self): - assert_equal(parse(Implicit,'implicit none'),'IMPLICIT NONE') - assert_equal(parse(Implicit,'implicit'),'IMPLICIT NONE') - assert_equal(parse(Implicit,'implicit integer (i-m)'), - 'IMPLICIT INTEGER ( i-m )') - assert_equal(parse(Implicit,'implicit integer (i-m,p,q-r)'), - 'IMPLICIT INTEGER ( i-m, p, q-r )') - assert_equal(parse(Implicit,'implicit integer (i-m), real (z)'), - 'IMPLICIT INTEGER ( i-m ), REAL ( z )') - - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/parser/typedecl_statements.py b/numpy/f2py/lib/parser/typedecl_statements.py deleted file mode 100644 index 7414a6d2d..000000000 --- a/numpy/f2py/lib/parser/typedecl_statements.py +++ /dev/null @@ -1,563 +0,0 @@ -""" -Fortran type declaration statements. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['Integer', 'Real', 'DoublePrecision', 'Complex', 'DoubleComplex', - 'Character', 'Logical', 'Byte', 'TypeStmt','Class', - 'intrinsic_type_spec', 'declaration_type_spec', - 'Implicit'] - -import re -import string -from base_classes import Statement, BeginStatement, EndStatement,\ - AttributeHolder, Variable -from utils import split_comma, AnalyzeError, name_re, is_entity_decl, is_name, CHAR_BIT, parse_array_spec - -# Intrinsic type specification statements - -class TypeDeclarationStatement(Statement): - """ - <declaration-type-spec> [ [, <attr-spec>] :: ] <entity-decl-list> - <declaration-type-spec> = <intrinsic-type-spec> - | TYPE ( <derived-type-spec> ) - | CLASS ( <derived-type-spec> ) - | CLASS ( * ) - - <derived-type-spec> = <type-name> [ ( <type-param-spec-list> ) ] - <type-param-spec> = [ <keyword> = ] <type-param-value> - <type-param-value> = <scalar-int-expr> | * | : - - <intrinsic-type-spec> = INTEGER [<kind-selector>] - | REAL [<kind-selector>] - | DOUBLE PRECISION - | COMPLEX [<kind-selector>] - | CHARACTER [<char-selector>] - | LOGICAL [<kind-selector>] - - <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> ) - EXTENSION: - <kind-selector> = ( [ KIND = ] <scalar-int-initialization-expr> ) - | * <length> - - <char-selector> = <length-selector> - | ( LEN = <type-param-value>, KIND = <scalar-int-initialization-expr> ) - | ( <type-param-value>, [ KIND = ] <scalar-int-initialization-expr> ) - | ( KIND = <scalar-int-initialization-expr> [, LEN = <type-param-value>] ) - <length-selector> = ( [ LEN = ] <type-param-value> ) - | * <char-length> [ , ] - <char-length> = ( <type-param-value> ) | <scalar-int-literal-constant> - - <attr-spec> = <access-spec> | ALLOCATABLE | ASYNCHRONOUS - | DIMENSION ( <array-spec> ) | EXTERNAL - | INTENT ( <intent-spec> ) | INTRINSIC - | <language-binding-spec> | OPTIONAL - | PARAMETER | POINTER | PROTECTED | SAVE - | TARGET | VALUE | VOLATILE - <entity-decl> = <object-name> [ ( <array-spec> ) ] [ * <char-length> ] [ <initialization> ] - | <function-name> [ * <char-length> ] - <initialization> = = <initialization-expr> - | => NULL - <access-spec> = PUBLIC | PRIVATE - <language-binding-spec> = BIND ( C [ , NAME = <scalar-char-initialization-expr>] ) - <array-spec> = <explicit-shape-spec-list> - | <assumed-shape-spec-list> - | <deferred-shape-spec-list> - | <assumed-size-spec> - <explicit-shape-spec> = [ <lower-bound> : ] <upper-bound> - <assumed-shape-spec> = [ <lower-bound> ] : - <deferred-shape-spec> = : - <assumed-size-spec> = [ <explicit-shape-spec-list> , ] [ <lower-bound> : ] * - <bound> = <specification-expr> - - <int-literal-constant> = <digit-string> [ _ <kind-param> ] - <digit-string> = <digit> [ <digit> ].. - <kind-param> = <digit-string> | <scalar-int-constant-name> - """ - _repr_attr_names = ['selector','attrspec','entity_decls'] + Statement._repr_attr_names - - def process_item(self): - item = self.item - apply_map = item.apply_map - clsname = self.__class__.__name__.lower() - line = item.get_line() - from block_statements import Function - - if not line.lower().startswith(clsname): - i = 0 - j = 0 - for c in line: - i += 1 - if c==' ': continue - j += 1 - if j==len(clsname): - break - line = line[:i].replace(' ','') + line[i:] - - assert line.lower().startswith(clsname),`line,clsname` - line = line[len(clsname):].lstrip() - - if line.startswith('('): - i = line.find(')') - selector = apply_map(line[:i+1].strip()) - line = line[i+1:].lstrip() - elif line.startswith('*'): - selector = '*' - line = line[1:].lstrip() - if line.startswith('('): - i = line.find(')') - selector += apply_map(line[:i+1].rstrip()) - line = line[i+1:].lstrip() - else: - m = re.match(r'\d+(_\w+|)|[*]',line) - if not m: - self.isvalid = False - return - i = m.end() - selector += line[:i].rstrip() - line = line[i:].lstrip() - else: - selector = '' - - fm = Function.match(line) - if fm: - l2 = line[:fm.end()] - m2 = re.match(r'.*?\b(?P<name>\w+)\Z',l2) - if not m2: - self.isvalid = False - return - fname = m2.group('name') - fitem = item.copy(clsname+selector+' :: '+fname, - apply_map=True) - self.parent.put_item(fitem) - item.clone(line) - self.isvalid = False - return - - if line.startswith(','): - line = line[1:].lstrip() - - self.raw_selector = selector - if isinstance(self, Character): - self.selector = self._parse_char_selector(selector) - else: - self.selector = self._parse_kind_selector(selector) - - i = line.find('::') - if i==-1: - self.attrspec = [] - self.entity_decls = split_comma(line, self.item) - else: - self.attrspec = split_comma(line[:i].rstrip(), self.item) - self.entity_decls = split_comma(line[i+2:].lstrip(), self.item) - for entity in self.entity_decls: - if not is_entity_decl(entity): - self.isvalid = False - return - - if isinstance(self.parent, Function) \ - and self.parent.name in self.entity_decls: - assert self.parent.typedecl is None,`self.parent.typedecl` - self.parent.typedecl = self - self.ignore = True - if isinstance(self, Type): - self.name = self.selector[1].lower() - assert is_name(self.name),`self.name` - else: - self.name = clsname - return - - def _parse_kind_selector(self, selector): - if not selector: - return '','' - length,kind = '','' - if selector.startswith('*'): - length = selector[1:].lstrip() - else: - assert selector[0]+selector[-1]=='()',`selector` - l = selector[1:-1].strip() - if l.lower().startswith('kind'): - l = l[4:].lstrip() - assert l.startswith('='),`l` - kind = l[1:].lstrip() - else: - kind = l - return length,kind - - def _parse_char_selector(self, selector): - if not selector: - return '','' - if selector.startswith('*'): - l = selector[1:].lstrip() - if l.startswith('('): - if l.endswith(','): l = l[:-1].rstrip() - assert l.endswith(')'),`l` - l = l[1:-1].strip() - if l.lower().startswith('len'): - l = l[3:].lstrip()[1:].lstrip() - kind='' - else: - assert selector[0]+selector[-1]=='()',`selector` - l = split_comma(selector[1:-1].strip(), self.item) - if len(l)==1: - l = l[0] - if l.lower().startswith('len'): - l=l[3:].lstrip() - assert l.startswith('='),`l` - l=l[1:].lstrip() - kind = '' - elif l.lower().startswith('kind'): - kind = l[4:].lstrip()[1:].lstrip() - l = '' - else: - kind = '' - else: - assert len(l)==2 - if l[0].lower().startswith('len'): - assert l[1].lower().startswith('kind'),`l` - kind = l[1][4:].lstrip()[1:].lstrip() - l = l[0][3:].lstrip()[1:].lstrip() - elif l[0].lower().startswith('kind'): - assert l[1].lower().startswith('len'),`l` - kind = l[0][4:].lstrip()[1:].lstrip() - l = l[1][3:].lstrip()[1:].lstrip() - else: - if l[1].lower().startswith('kind'): - kind = l[1][4:].lstrip()[1:].lstrip() - l = l[0] - else: - kind = l[1] - l = l[0] - return l,kind - - def tostr(self): - clsname = self.__class__.__name__.upper() - s = '' - length, kind = self.selector - if isinstance(self, Character): - if length and kind: - s += '(LEN=%s, KIND=%s)' % (length,kind) - elif length: - s += '(LEN=%s)' % (length) - elif kind: - s += '(KIND=%s)' % (kind) - else: - if isinstance(self, Type): - s += '(%s)' % (kind) - else: - if length: - s += '*%s' % (length) - if kind: - s += '(KIND=%s)' % (kind) - - return clsname + s - - def tofortran(self,isfix=None): - tab = self.get_indent_tab(isfix=isfix) - s = self.tostr() - if self.attrspec: - s += ', ' + ', '.join(self.attrspec) - if self.entity_decls: - s += ' ::' - if self.entity_decls: - s += ' ' + ', '.join(self.entity_decls) - return tab + s - - def __str__(self): - return self.tofortran() - - def __eq__(self, other): - if self.__class__ is not other.__class__: - return False - return self.selector==other.selector - - def astypedecl(self): - if self.entity_decls or self.attrspec: - return self.__class__(self.parent, self.item.copy(self.tostr())) - return self - - def analyze(self): - if not self.entity_decls: - return - variables = self.parent.a.variables - typedecl = self.astypedecl() - attrspec = self.attrspec[:] - try: - access_spec = [a for a in attrspec if a.lower() in ['private','public']][0] - attrspec.remove(access_spec) - except IndexError: - access_spec = None - for item in self.entity_decls: - name, array_spec, char_length, value = self._parse_entity(item) - var = self.parent.get_variable(name) - var.add_parent(self) - if char_length: - var.set_length(char_length) - else: - var.set_type(typedecl) - var.update(self.attrspec) - if array_spec: - var.set_bounds(array_spec) - if value: - var.set_init(value) - if access_spec is not None: - l = getattr(self.parent.a,access_spec.lower() + '_id_list') - l.append(name) - var.analyze() - return - - def _parse_entity(self, line): - m = name_re(line) - assert m,`line,self.item,self.__class__.__name__` - name = line[:m.end()] - line = line[m.end():].lstrip() - array_spec = None - item = self.item.copy(line) - line = item.get_line() - if line.startswith('('): - i = line.find(')') - assert i!=-1,`line` - array_spec = parse_array_spec(line[1:i].strip(), item) - line = line[i+1:].lstrip() - char_length = None - if line.startswith('*'): - i = line.find('=') - if i==-1: - char_length = item.apply_map(line[1:].lstrip()) - line = '' - else: - char_length = item.apply_map(line[1:i].strip()) - line = line[i:] - value = None - if line.startswith('='): - value = item.apply_map(line[1:].lstrip()) - return name, array_spec, char_length, value - - def get_zero_value(self): - raise NotImplementedError,`self.__class__.__name__` - - def assign_expression(self, name, value): - return '%s = %s' % (name, value) - - def get_kind(self): - return self.selector[1] or self.default_kind - - def get_length(self): - return self.selector[0] or 1 - - def get_byte_size(self): - length, kind = self.selector - if length: return int(length) - if kind: return int(kind) - return self.default_kind - - def get_bit_size(self): - return CHAR_BIT * int(self.get_byte_size()) - - def is_intrinsic(self): return not isinstance(self,(Type,Class)) - def is_derived(self): return isinstance(self,Type) - - def is_numeric(self): return isinstance(self,(Integer,Real, DoublePrecision,Complex,DoubleComplex,Byte)) - def is_nonnumeric(self): return isinstance(self,(Character,Logical)) - - -class Integer(TypeDeclarationStatement): - match = re.compile(r'integer\b',re.I).match - default_kind = 4 - - def get_zero_value(self): - kind = self.get_kind() - if kind==self.default_kind: return '0' - return '0_%s' % (kind) - -class Real(TypeDeclarationStatement): - match = re.compile(r'real\b',re.I).match - default_kind = 4 - - def get_zero_value(self): - kind = self.get_kind() - if kind==self.default_kind: return '0.0' - return '0_%s' % (kind) - -class DoublePrecision(TypeDeclarationStatement): - match = re.compile(r'double\s*precision\b',re.I).match - default_kind = 8 - - def get_byte_size(self): - return self.default_kind - - def get_zero_value(self): - return '0.0D0' - -class Complex(TypeDeclarationStatement): - match = re.compile(r'complex\b',re.I).match - default_kind = 4 - - def get_byte_size(self): - length, kind = self.selector - if length: return int(length) - if kind: return 2*int(kind) - return 2*self.default_kind - - def get_zero_value(self): - kind = self.get_kind() - if kind==self.default_kind: return '(0.0, 0.0)' - return '(0.0_%s, 0.0_%s)' % (kind, kind) - - def get_part_typedecl(self): - bz = self.get_byte_size()/2 - return Real(self.parent, self.item.copy('REAL*%s' % (bz))) - -class DoubleComplex(TypeDeclarationStatement): - # not in standard - match = re.compile(r'double\s*complex\b',re.I).match - default_kind = 8 - - def get_byte_size(self): - return 2*self.default_kind - - def get_zero_value(self): - return '(0.0D0,0.0D0)' - -class Logical(TypeDeclarationStatement): - match = re.compile(r'logical\b',re.I).match - default_kind = 4 - - def get_zero_value(self): - return ".FALSE." - -class Character(TypeDeclarationStatement): - match = re.compile(r'character\b',re.I).match - default_kind = 1 - - def get_bit_size(self): - length = self.get_length() - if length=='*': - return 0 # model for character*(*) - return CHAR_BIT * int(length) * int(self.get_kind()) - - def get_zero_value(self): - return "''" - -class Byte(TypeDeclarationStatement): - # not in standard - match = re.compile(r'byte\b',re.I).match - default_kind = 1 - - def get_zero_value(self): - return '0' - -class Type(TypeDeclarationStatement): - match = re.compile(r'type\s*\(', re.I).match - - def get_zero_value(self): - type_decl = self.get_type_decl(self.name) - component_names = type_decl.a.component_names - components = type_decl.a.components - l = [] - for name in component_names: - var = components[name] - l.append(var.typedecl.get_zero_value()) - return '%s(%s)' % (type_decl.name, ', '.join(l)) - - def get_kind(self): - # See 4.5.2, page 48 - raise NotImplementedError,`self.__class__.__name__` - - def get_bit_size(self): - return self.get_type_decl(self.name).get_bit_size() - -TypeStmt = Type - -class Class(TypeDeclarationStatement): - match = re.compile(r'class\s*\(', re.I).match - -class Implicit(Statement): - """ - IMPLICIT <implicit-spec-list> - IMPLICIT NONE - <implicit-spec> = <declaration-type-spec> ( <letter-spec-list> ) - <letter-spec> = <letter> [ - <letter> ] - """ - match = re.compile(r'implicit\b',re.I).match - - letters = string.lowercase - - def process_item(self): - line = self.item.get_line()[8:].lstrip() - if line.lower()=='none': - self.items = [] - return - items = [] - for item in split_comma(line, self.item): - i = item.find('(') - assert i!=-1 and item.endswith(')'),`item` - specs = [] - for spec in split_comma(item[i+1:-1].strip(), self.item): - if '-' in spec: - s,e = spec.lower().split('-') - s = s.strip() - e = e.strip() - assert s in self.letters and e in self.letters,`s,e` - else: - e = s = spec.lower().strip() - assert s in self.letters,`s,e` - specs.append((s,e)) - tspec = item[:i].rstrip() - stmt = None - for cls in declaration_type_spec: - if cls.match(tspec): - stmt = cls(self, self.item.copy(tspec)) - if stmt.isvalid: - break - assert stmt is not None,`item,line` - items.append((stmt,specs)) - self.items = items - return - - def tofortran(self, isfix=None): - tab = self.get_indent_tab(isfix=isfix) - if not self.items: - return tab + 'IMPLICIT NONE' - l = [] - for stmt,specs in self.items: - l1 = [] - for s,e in specs: - if s==e: - l1.append(s) - else: - l1.append(s + '-' + e) - l.append('%s ( %s )' % (stmt.tostr(), ', '.join(l1))) - return tab + 'IMPLICIT ' + ', '.join(l) - - def analyze(self): - implicit_rules = self.parent.a.implicit_rules - if not self.items: - if implicit_rules: - self.warning('overriding previously set implicit rule mapping'\ - ' %r.' % (implicit_rules)) - self.parent.a.implicit_rules = None - return - if implicit_rules is None: - self.warning('overriding previously set IMPLICIT NONE') - self.parent.a.implicit_rules = implicit_rules = {} - for stmt,specs in self.items: - for s,e in specs: - for l in string.lowercase[string.lowercase.index(s.lower()):\ - string.lowercase.index(e.lower())+1]: - implicit_rules[l] = stmt - return - -intrinsic_type_spec = [ \ - Integer , Real, - DoublePrecision, Complex, DoubleComplex, Character, Logical, Byte - ] -declaration_type_spec = intrinsic_type_spec + [ TypeStmt, Class ] diff --git a/numpy/f2py/lib/parser/utils.py b/numpy/f2py/lib/parser/utils.py deleted file mode 100644 index b27bf670f..000000000 --- a/numpy/f2py/lib/parser/utils.py +++ /dev/null @@ -1,177 +0,0 @@ -""" -Various utility functions. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: May 2006 ------ -""" - -__all__ = ['split_comma', 'specs_split_comma', - 'ParseError','AnalyzeError', - 'get_module_file','parse_bind','parse_result','is_name','parse_array_spec', - 'CHAR_BIT','str2stmt'] - -import re -import os, glob - -class ParseError(Exception): - pass - -class AnalyzeError(Exception): - pass - -is_name = re.compile(r'^[a-z_]\w*$',re.I).match -name_re = re.compile(r'[a-z_]\w*',re.I).match -is_entity_decl = re.compile(r'^[a-z_]\w*',re.I).match -is_int_literal_constant = re.compile(r'^\d+(_\w+|)$').match - -def split_comma(line, item = None, comma=',', keep_empty=False): - items = [] - if item is None: - for s in line.split(comma): - s = s.strip() - if not s and not keep_empty: continue - items.append(s) - return items - newitem = item.copy(line, True) - apply_map = newitem.apply_map - for s in newitem.get_line().split(comma): - s = apply_map(s).strip() - if not s and not keep_empty: continue - items.append(s) - return items - -def parse_array_spec(line, item = None): - items = [] - for spec in split_comma(line, item): - items.append(tuple(split_comma(spec, item, comma=':', keep_empty=True))) - return items - -def specs_split_comma(line, item = None, upper=False): - specs0 = split_comma(line, item) - specs = [] - for spec in specs0: - i = spec.find('=') - if i!=-1: - kw = spec[:i].strip().upper() - v = spec[i+1:].strip() - specs.append('%s = %s' % (kw, v)) - else: - if upper: - spec = spec.upper() - specs.append(spec) - return specs - -def parse_bind(line, item = None): - if not line.lower().startswith('bind'): - return None, line - if item is not None: - newitem = item.copy(line, apply_map=True) - newline = newitem.get_line() - else: - newitem = None - newline = newline[4:].lstrip() - i = newline.find(')') - assert i!=-1,`newline` - args = [] - for a in specs_split_comma(newline[1:i].strip(), newitem, upper=True): - args.append(a) - rest = newline[i+1:].lstrip() - if item is not None: - rest = newitem.apply_map(rest) - return args, rest - -def parse_result(line, item = None): - if not line.lower().startswith('result'): - return None, line - line = line[6:].lstrip() - i = line.find(')') - assert i != -1,`line` - name = line[1:i].strip() - assert is_name(name),`name` - return name, line[i+1:].lstrip() - -def filter_stmts(content, classes): - """ Pop and return classes instances from content. - """ - stmts = [] - indices = [] - for i in range(len(content)): - stmt = content[i] - if isinstance(stmt, classes): - stmts.append(stmt) - indices.append(i) - indices.reverse() - for i in indices: - del content[i] - return stmts - - -def get_module_files(directory, _cache={}): - if directory in _cache: - return _cache[directory] - module_line = re.compile(r'(\A|^)module\s+(?P<name>\w+)\s*(!.*|)$',re.I | re.M) - d = {} - for fn in glob.glob(os.path.join(directory,'*.f90')): - f = open(fn,'r') - for name in module_line.findall(f.read()): - name = name[1] - if name in d: - print d[name],'already defines',name - continue - d[name] = fn - _cache[directory] = d - return d - -def get_module_file(name, directory, _cache={}): - fn = _cache.get(name, None) - if fn is not None: - return fn - if name.endswith('_module'): - f1 = os.path.join(directory,name[:-7]+'.f90') - if os.path.isfile(f1): - _cache[name] = fn - return f1 - pattern = re.compile(r'\s*module\s+(?P<name>[a-z]\w*)', re.I).match - for fn in glob.glob(os.path.join(directory,'*.f90')): - f = open(fn,'r') - for line in f: - m = pattern(line) - if m and m.group('name')==name: - _cache[name] = fn - f.close() - return fn - f.close() - return - -def str2stmt(string, isfree=True, isstrict=False): - """ Convert Fortran code to Statement tree. - """ - from readfortran import Line, FortranStringReader - from parsefortran import FortranParser - reader = FortranStringReader(string, isfree, isstrict) - parser = FortranParser(reader) - parser.parse() - parser.analyze() - block = parser.block - while len(block.content)==1: - block = block.content[0] - return block - -def get_char_bit(): - import numpy - one = numpy.ubyte(1) - two = numpy.ubyte(2) - n = numpy.ubyte(2) - i = 1 - while n>=two: - n <<= one - i += 1 - return i - -CHAR_BIT = get_char_bit() diff --git a/numpy/f2py/lib/py_wrap.py b/numpy/f2py/lib/py_wrap.py deleted file mode 100644 index 47c8437ad..000000000 --- a/numpy/f2py/lib/py_wrap.py +++ /dev/null @@ -1,128 +0,0 @@ -__all__ = ['PythonWrapperModule'] - -import re -import os -import sys - -from parser.api import * -from wrapper_base import * -from py_wrap_type import * -from py_wrap_subprogram import * - -class PythonWrapperModule(WrapperBase): - - main_template = '''\ -#ifdef __cplusplus -extern \"C\" { -#endif -#include "Python.h" - -#define PY_ARRAY_UNIQUE_SYMBOL PyArray_API -#include "numpy/arrayobject.h" -#include "numpy/arrayscalars.h" - -%(header_list)s - -%(typedef_list)s - -%(extern_list)s - -%(c_code_list)s - -%(capi_code_list)s - -%(objdecl_list)s - -static PyObject *f2py_module; - -static PyMethodDef f2py_module_methods[] = { - %(module_method_list)s - {NULL,NULL,0,NULL} -}; - -PyMODINIT_FUNC init%(modulename)s(void) { - f2py_module = Py_InitModule("%(modulename)s", f2py_module_methods); - import_array(); - if (PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "failed to load array module."); - goto capi_err; - } - %(module_init_list)s - return; -capi_err: - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_RuntimeError, "failed to initialize %(modulename)s module."); - } - return; -} -#ifdef __cplusplus -} -#endif -''' - - main_fortran_template = '''\ -%(fortran_code_list)s -''' - - - - def __init__(self, modulename): - WrapperBase.__init__(self) - self.modulename = modulename - self.cname = 'f2py_' + modulename - - self.defined_cpp_code = [] - self.defined_c_code = [] - self.defined_types = [] - self.defined_capi_codes = [] - - - self.header_list = [] - self.typedef_list = [] - self.extern_list = [] - self.objdecl_list = [] - self.c_code_list = [] - self.capi_code_list = [] - - self.module_method_list = [] - self.module_init_list = [] - - self.fortran_code_list = [] - - self.list_names = ['header', 'typedef', 'extern', 'objdecl', - 'c_code','capi_code','module_method','module_init', - 'fortran_code'] - self.isf90 = False - return - - def add(self, block): - if isinstance(block, BeginSource): - for name, moduleblock in block.a.module.items(): - self.add(moduleblock) - #for name, subblock in block.a.external_subprogram.items(): - # self.add(subblock) - elif isinstance(block, Subroutine): - PythonCAPISubProgram(self, block) - elif isinstance(block, Function): - fcode = block.subroutine_wrapper_code() - self.fortran_code_list.append(fcode) - wrapper_block = block.subroutine_wrapper() - PythonCAPISubProgram(self, wrapper_block) - elif isinstance(block, Module): - self.isf90 = True - for name,declblock in block.a.type_decls.items(): - self.add(declblock) - for name,subblock in block.a.module_subprogram.items(): - self.add(subblock) - elif isinstance(block, tuple([TypeDecl]+declaration_type_spec)): - if isinstance(block, (TypeDecl, TypeStmt)): - self.isf90 = True - PythonCAPIType(self, block) - else: - raise NotImplementedError,`block.__class__.__name__` - return - - def c_code(self): - return self.apply_attributes(self.main_template) - def fortran_code(self): - return self.apply_attributes(self.main_fortran_template) diff --git a/numpy/f2py/lib/py_wrap_subprogram.py b/numpy/f2py/lib/py_wrap_subprogram.py deleted file mode 100644 index 8dd0c3efb..000000000 --- a/numpy/f2py/lib/py_wrap_subprogram.py +++ /dev/null @@ -1,210 +0,0 @@ -__all__ = ['PythonCAPISubProgram'] - -import sys - -from parser.api import TypeDecl, TypeStmt, Module -from wrapper_base import * -from py_wrap_type import * - -class PythonCAPISubProgram(WrapperBase): - """ - Fortran subprogram hooks. - """ - - header_template_f77 = '''\ -#define %(name)s_f F_FUNC(%(name)s, %(NAME)s) -''' - extern_template_f77 = '''\ -extern void %(name)s_f(%(ctype_args_f_clist)s); -''' - objdecl_template_doc = '''\ -static char %(cname)s__doc[] = ""; -''' - module_method_template = '''\ -{"%(pyname)s", (PyCFunction)%(cname)s, METH_VARARGS | METH_KEYWORDS, %(cname)s__doc},''' - - capi_code_template = '''\ -static PyObject* %(cname)s(PyObject *capi_self, PyObject *capi_args, PyObject *capi_keywds) { - PyObject * volatile capi_buildvalue = NULL; - volatile int f2py_success = 1; - %(decl_list)s - static char *capi_kwlist[] = {%(kw_clist+optkw_clist+extrakw_clist+["NULL"])s}; - if (PyArg_ParseTupleAndKeywords(capi_args,capi_keywds, - "%(pyarg_format_elist)s", - %(["capi_kwlist"]+pyarg_obj_clist)s)) { - %(frompyobj_list)s - %(call_list)s - f2py_success = !PyErr_Occurred(); - if (f2py_success) { - %(pyobjfrom_list)s - capi_buildvalue = Py_BuildValue("%(return_format_elist)s" - %(return_obj_clist)s); - %(clean_pyobjfrom_list)s - } - %(clean_call_list)s - %(clean_frompyobj_list)s - } - return capi_buildvalue; -} -''' - - header_template_module = ''' -#define %(name)s_f (*%(name)s_func_ptr) -#define %(init_func)s_f F_FUNC(%(init_func)s, %(INIT_FUNC)s) -''' - typedef_template_module = ''' -typedef void (*%(name)s_functype)(%(ctype_args_f_clist)s); -typedef void (*%(init_func)s_c_functype)(%(name)s_functype); -''' - extern_template_module = '''\ -extern void %(init_func)s_f(%(init_func)s_c_functype); -static %(name)s_functype %(name)s_func_ptr; -''' - objdecl_template_module = ''' -''' - fortran_code_template_module = ''' - subroutine %(init_func)s(init_func_c) - use %(mname)s - external init_func_c - call init_func_c(%(name)s) - end -''' - c_code_template_module = ''' -static void %(init_func)s_c(%(name)s_functype func_ptr) { - %(name)s_func_ptr = func_ptr; -} -''' - module_init_template_module = ''' -%(init_func)s_f(%(init_func)s_c); -''' - - def __init__(self, parent, block): - WrapperBase.__init__(self) - self.name = name = pyname = block.name - self.cname = cname = '%s_%s' % (parent.cname,name) - - defined = parent.defined_capi_codes - if cname in defined: - return - defined.append(cname) - - self.info('Generating interface for %s %s: %s' % (parent.modulename, block.__class__.__name__, cname)) - self.parent = parent - - if pyname.startswith('f2pywrap_'): - pyname = pyname[9:] - self.pyname = pyname - - self.header_template = '' - self.extern_template = '' - self.module_init_template = '' - self.typedef_template = '' - self.c_code_template = '' - self.objdecl_template = '' - self.fortran_code_template = '' - - WrapperCPPMacro(parent, 'F_FUNC') - - if isinstance(block.parent, Module): - self.mname = block.parent.name - self.init_func = '%s_init' % (name) - self.typedef_template += self.typedef_template_module - self.header_template += self.header_template_module - self.fortran_code_template += self.fortran_code_template_module - self.module_init_template += self.module_init_template_module - self.objdecl_template += self.objdecl_template_module - self.c_code_template += self.c_code_template_module - self.extern_template += self.extern_template_module - else: - self.extern_template += self.extern_template_f77 - self.header_template += self.header_template_f77 - - self.objdecl_template += self.objdecl_template_doc - - self.decl_list = [] - self.kw_list = [] - self.optkw_list = [] - self.extrakw_list = [] - self.pyarg_format_list = [] - self.pyarg_obj_list = [] - self.frompyobj_list = [] - self.call_list = [] - self.pyobjfrom_list = [] - self.return_format_list = [] - self.return_obj_list = [] - self.buildvalue_list = [] - self.clean_pyobjfrom_list = [] - self.clean_call_list = [] - self.clean_frompyobj_list = [] - - args_f = [] - extra_args_f = [] - ctype_args_f = [] - extra_ctype_args_f = [] - argindex = -1 - for argname in block.args: - argindex += 1 - var = block.a.variables[argname] - typedecl = var.get_typedecl() - PythonCAPIType(parent, typedecl) - ti = PyTypeInterface(typedecl) - if var.is_intent_in(): - self.kw_list.append('"%s"' % (argname)) - - if var.is_scalar(): - if isinstance(typedecl, TypeStmt): - if var.is_intent_in(): - self.pyarg_format_list.append('O&') - self.pyarg_obj_list.append('\npyobj_to_%s_inplace, &%s' % (ti.ctype, argname)) - else: - self.frompyobj_list.append('%s = (%s*)pyobj_from_%s(NULL);' % (argname,ti.otype,ti.ctype)) - if not var.is_intent_out(): - self.clean_frompyobj_list.append('Py_DECREF(%s);' % (argname)) - self.decl_list.append('%s* %s = NULL;' % (ti.otype, argname)) - args_f.append('%s->data' % (argname)) # is_scalar - ctype_args_f.append(ti.ctype) - else: - if var.is_intent_in(): - self.pyarg_format_list.append('O&') - self.pyarg_obj_list.append('\npyobj_to_%s, &%s' % (ti.ctype, argname)) - assert not isinstance(typedecl, TypeDecl) - if ti.ctype=='f2py_string0': - if not var.is_intent_in(): - assert not var.is_intent_out(),'intent(out) not implemented for "%s"' % (var) - self.decl_list.append('%s %s = {NULL,0};' % (ti.ctype, argname)) - args_f.append('%s.data' % argname) # is_scalar - ctype_args_f.append('char*') - extra_ctype_args_f.append('int') - extra_args_f.append('%s.len' % argname) - self.clean_frompyobj_list.append(\ - 'if (%s.len) free(%s.data);' % (argname,argname)) - else: - self.decl_list.append('%s %s;' % (ti.ctype, argname)) - args_f.append('&'+argname) # is_scalar - ctype_args_f.append(ti.ctype+'*') - if var.is_intent_out(): # and is_scalar - if isinstance(typedecl, TypeStmt): - self.return_format_list.append('N') - self.return_obj_list.append('\n%s' % (argname)) - else: - self.return_format_list.append('O&') - self.return_obj_list.append('\npyobj_from_%s, &%s' % (ti.ctype, argname)) - else: - print `ti,var.dimension,var.bounds` - assert var.is_scalar(),'array support not implemented: "%s"' % (var) - - self.call_list.append('%s_f(%s);' % (name,', '.join(args_f+extra_args_f))) - - self.ctype_args_f_list = ctype_args_f + extra_ctype_args_f - if not self.ctype_args_f_list: - self.ctype_args_f_list.append('void') - - - self.clean_pyobjfrom_list.reverse() - self.clean_call_list.reverse() - self.clean_frompyobj_list.reverse() - - if self.return_obj_list: self.return_obj_list.insert(0,'') - - parent.apply_templates(self) - return diff --git a/numpy/f2py/lib/py_wrap_type.py b/numpy/f2py/lib/py_wrap_type.py deleted file mode 100644 index 1c7d8f309..000000000 --- a/numpy/f2py/lib/py_wrap_type.py +++ /dev/null @@ -1,753 +0,0 @@ -__all__ = ['PythonCAPIType', 'PyTypeInterface'] - -from wrapper_base import * -from parser.api import CHAR_BIT, Module, declaration_type_spec, \ - TypeDecl, TypeStmt, Subroutine, Function, Integer, Real,\ - DoublePrecision, Complex, DoubleComplex, Logical, Character, \ - Byte - -class PyTypeInterface: - - def __init__(self, typedecl): - if isinstance(typedecl, TypeStmt): - typedecl = typedecl.get_type_decl(typedecl.name) - self._typedecl = typedecl - if isinstance(typedecl, TypeDecl): - self.name = name = typedecl.name - tname = 'f2py_type_%s_' % (name) - else: - if isinstance(typedecl,(Integer,Byte)): - tname = 'npy_int' - elif isinstance(typedecl,(Real, DoublePrecision)): - tname = 'npy_float' - elif isinstance(typedecl,(Complex, DoubleComplex)): - tname = 'npy_complex' - elif isinstance(typedecl,Logical): - tname = 'f2py_bool' - elif isinstance(typedecl,Character): - tname = 'f2py_string' - else: - raise NotImplementedError,`typedecl.__class__` - bitsize = typedecl.get_bit_size() - self.ctype = ctype = '%s%s' % (tname,bitsize) - self.bits = bitsize - self.bytes = bitsize / CHAR_BIT - - if isinstance(typedecl, TypeDecl): - self.otype = '%sObject' % (ctype) - self.ftype = 'TYPE(%s)' % (name) - return - def __repr__(self): return '%s(%r)' % (self.__class__.__name__, self._typedecl) - def __str__(self): - s = [] - for k,v in self.__dict__.items(): - if k.startswith('_'): continue - s.append('%s=%s' % (k,v)) - return 'PyTypeInterface(%s)' % (', '.join(s)) - -class PythonCAPIType(WrapperBase): - """ - Fortran type hooks. - """ - def __init__(self, parent, typedecl): - WrapperBase.__init__(self) - if isinstance(typedecl, tuple(declaration_type_spec)): - if isinstance(typedecl, TypeStmt): - type_decl = typedecl.get_type_decl(typedecl.name) - assert type_decl is not None,"%s %s" % (typedecl,typedecl.name) - PythonCAPIDerivedType(parent, type_decl) - else: - PythonCAPIIntrinsicType(parent, typedecl) - elif isinstance(typedecl, TypeDecl): - PythonCAPIDerivedType(parent, typedecl) - else: - raise NotImplementedError,`self.__class__,typedecl.__class__` - return - -class PythonCAPIIntrinsicType(WrapperBase): - """ - Fortran intrinsic type hooks. - """ - - capi_code_template_scalar = ''' -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { - PyObject* obj = PyArrayScalar_New(%(Cls)s); -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_from_%(ctype)s(value=%%"%(CTYPE)s_FMT")\\n",*value); -#endif - if (obj==NULL) /* TODO: set exception */ return NULL; - PyArrayScalar_ASSIGN(obj,%(Cls)s,*value); - return obj; -} - -static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (obj==NULL) ; - else if (PyArray_IsScalar(obj,%(Cls)s)) { - *value = PyArrayScalar_VAL(obj,%(Cls)s); - return_value = 1; - } - else if (PySequence_Check(obj)) { - if (PySequence_Size(obj)==1) - return_value = pyobj_to_%(ctype)s(PySequence_GetItem(obj,0),value); - } else { - PyObject* sc = Py%(Cls)sArrType_Type.tp_new( - &Py%(Cls)sArrType_Type,Py_BuildValue("(O)",obj),NULL); - if (sc==NULL) ; - else if (PyArray_IsScalar(sc, Generic)) - return_value = pyobj_to_%(ctype)s(sc,value); - else - return_value = pyobj_to_%(ctype)s(PyArray_ScalarFromObject(sc),value); - } - if (!return_value && !PyErr_Occurred()) { - PyObject* r = PyString_FromString("Failed to convert "); - PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); - PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); - PyErr_SetObject(PyExc_TypeError,r); - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - if (PyErr_Occurred()) { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - else - fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); - } else { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s: value=%%"%(CTYPE)s_FMT"\\n", *value); - else - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - } -#endif - return return_value; -} -''' - - capi_code_template_complex_scalar = ''' -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { - PyObject* obj = PyArrayScalar_New(%(Cls)s); -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_from_%(ctype)s(value=(%%"%(FCTYPE)s_FMT",%%"%(FCTYPE)s_FMT"))\\n",value->real, value->imag); -#endif - if (obj==NULL) /* TODO: set exception */ return NULL; - PyArrayScalar_ASSIGN(obj,%(Cls)s,*value); - return obj; -} - -static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (obj==NULL) ; - else if (PyArray_IsScalar(obj,%(Cls)s)) { - value->real = PyArrayScalar_VAL(obj,%(Cls)s).real; - value->imag = PyArrayScalar_VAL(obj,%(Cls)s).imag; - return_value = 1; - } - else if (PySequence_Check(obj)) { - if (PySequence_Size(obj)==1) - return_value = pyobj_to_%(ctype)s(PySequence_GetItem(obj,0),value); - else if (PySequence_Size(obj)==2) { - return_value = pyobj_to_%(fctype)s(PySequence_GetItem(obj,0),&(value->real)) - && pyobj_to_%(fctype)s(PySequence_GetItem(obj,1),&(value->imag)); - } - } else { - PyObject* sc = Py%(Cls)sArrType_Type.tp_new( - &Py%(Cls)sArrType_Type,Py_BuildValue("(O)",obj),NULL); - if (sc==NULL) ; - else if (PyArray_IsScalar(sc, Generic)) - return_value = pyobj_to_%(ctype)s(sc,value); - else - return_value = pyobj_to_%(ctype)s(PyArray_ScalarFromObject(sc),value); - } - if (!return_value && !PyErr_Occurred()) { - PyObject* r = PyString_FromString("Failed to convert "); - PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); - PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); - PyErr_SetObject(PyExc_TypeError,r); - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - if (PyErr_Occurred()) { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - else - fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); - } else { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s: value=(%%"%(FCTYPE)s_FMT",%%"%(FCTYPE)s_FMT")\\n", - value->real, value->imag); - else - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - } -#endif - return return_value; -} -''' - - capi_code_template_logical_scalar = ''' -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_from_%(ctype)s(value=%%"%(ICTYPE)s_FMT")\\n",*value); -#endif - if (*value) { - PyArrayScalar_RETURN_TRUE; - } else { - PyArrayScalar_RETURN_FALSE; - } -} -static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (obj==NULL) ; - else if (PyArray_IsScalar(obj,Bool)) { - *value = PyArrayScalar_VAL(obj,Bool); - return_value = 1; - } else { - switch (PyObject_IsTrue(obj)) { - case 0: *value = 0; return_value = 1; break; - case -1: break; - default: *value = 1; return_value = 1; - } - } - if (!return_value && !PyErr_Occurred()) { - PyObject* r = PyString_FromString("Failed to convert "); - PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); - PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); - PyErr_SetObject(PyExc_TypeError,r); - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - if (PyErr_Occurred()) { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - else - fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); - } else { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s: value=%%"%(ICTYPE)s_FMT"\\n", *value); - else - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - } -#endif - return return_value; -} -''' - capi_code_template_string_scalar = ''' -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_from_%(ctype)s(value->data=\'%%s\')\\n",value->data); -#endif - PyArray_Descr* descr = PyArray_DescrNewFromType(NPY_STRING); - descr->elsize = %(bytes)s; - PyObject* obj = PyArray_Scalar(value->data, descr, NULL); - if (obj==NULL) /* TODO: set exception */ return NULL; - return obj; -} - -static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (PyString_Check(obj)) { - int s = PyString_GET_SIZE(obj); - memset(value->data, (int)\' \',%(bytes)s); - return_value = !! strncpy(value->data,PyString_AS_STRING(obj),%(bytes)s); - if (return_value && s<%(bytes)s) { - memset(value->data + s, (int)\' \',%(bytes)s-s); - } - } else { - return_value = pyobj_to_%(ctype)s(PyObject_Str(obj), value); - } - if (!return_value && !PyErr_Occurred()) { - PyObject* r = PyString_FromString("Failed to convert "); - PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); - PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); - PyErr_SetObject(PyExc_TypeError,r); - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - if (PyErr_Occurred()) { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - else - fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); - } else { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s: value->data=\'%%s\'\\n", value->data); - else - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - } -#endif - return return_value; -} -''' - capi_code_template_string0_scalar = ''' -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value) { -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_from_%(ctype)s(value->len=%%d, value->data=\'%%s\')\\n",value->len, value->data); -#endif - PyArray_Descr* descr = PyArray_DescrNewFromType(NPY_STRING); - descr->elsize = value->len; - PyObject* obj = PyArray_Scalar(value->data, descr, NULL); - if (obj==NULL) /* TODO: set exception */ return NULL; - return obj; -} - -static int pyobj_to_%(ctype)s(PyObject *obj, %(ctype)s* value) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (PyString_Check(obj)) { - value->len = PyString_GET_SIZE(obj); - value->data = malloc(value->len*sizeof(char)); - return_value = !! strncpy(value->data,PyString_AS_STRING(obj),value->len); - } else { - return_value = pyobj_to_%(ctype)s(PyObject_Str(obj), value); - } - if (!return_value && !PyErr_Occurred()) { - PyObject* r = PyString_FromString("Failed to convert "); - PyString_ConcatAndDel(&r, PyObject_Repr(PyObject_Type(obj))); - PyString_ConcatAndDel(&r, PyString_FromString(" to C %(ctype)s")); - PyErr_SetObject(PyExc_TypeError,r); - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - if (PyErr_Occurred()) { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - else - fprintf(stderr,"pyobj_to_%(ctype)s: PyErr_Occurred()=%%p\\n", PyErr_Occurred()); - } else { - if (return_value) - fprintf(stderr,"pyobj_to_%(ctype)s: value->len=%%d, value->data=\'%%s\'\\n", value->len, value->data); - else - fprintf(stderr,"pyobj_to_%(ctype)s:INCONSISTENCY with return_value=%%d and PyErr_Occurred()=%%p\\n",return_value, PyErr_Occurred()); - } -#endif - return return_value; -} -''' - def __init__(self, parent, typedecl): - WrapperBase.__init__(self) - self.name = name = typedecl.name - ti = PyTypeInterface(typedecl) - self.ctype = ctype = ti.ctype - - defined = parent.defined_types - if ctype in defined: - return - defined.append(ctype) - - self.info('Generating interface for %s: %s' % (typedecl.__class__.__name__, ctype)) - self.parent = parent - if isinstance(typedecl, (Integer,Byte,Real,DoublePrecision)): - self.Cls = ctype[4].upper() + ctype[5:] - self.capi_code_template = self.capi_code_template_scalar - elif isinstance(typedecl, (Complex,DoubleComplex)): - self.Cls = ctype[4].upper() + ctype[5:] - PythonCAPIIntrinsicType(parent, typedecl.get_part_typedecl()) - ti1 = PyTypeInterface(typedecl.get_part_typedecl()) - self.fctype = ti1.ctype - self.capi_code_template = self.capi_code_template_complex_scalar - elif isinstance(typedecl, Logical): - self.ictype = 'npy_int%s' % (typedecl.get_bit_size()) - self.header_template = '#define %(ctype)s %(ictype)s' - self.capi_code_template = self.capi_code_template_logical_scalar - elif isinstance(typedecl, Character): - self.bits = bits = typedecl.get_bit_size() - if bits: - self.bytes = bits/CHAR_BIT - self.header_template = ''' -#include <string.h> -typedef struct { char data[%(bytes)s]; } %(ctype)s; -''' - self.capi_code_template = self.capi_code_template_string_scalar - else: - self.header_template = ''' -#include <string.h> -typedef struct { char* data; size_t len; } %(ctype)s; -''' - self.capi_code_template = self.capi_code_template_string0_scalar - else: - raise NotImplementedError,`name,ctype` - parent.apply_templates(self) - return - -class PythonCAPIDerivedType(WrapperBase): - """ - Fortran 90 derived type hooks. - """ - - header_template_wrapper = '''\ -#define %(otype)s_Check(obj) \\ - PyObject_TypeCheck((PyObject*)obj, &%(otype)sType) -#define %(init_func)s_f \\ - F_FUNC(%(init_func)s,%(INIT_FUNC)s) -''' - - typedef_template_wrapper = '''\ -typedef void * %(ctype)s; -typedef struct { - PyObject_HEAD - %(ptrstruct_list)s - %(ctype)s data; -} %(otype)s; -typedef void (*%(init_func)s_c_functype)(%(init_func_c_ctype_arg_clist)s); -''' - - typedef_template_importer = '''\ -typedef void * %(ctype)s; -typedef struct { - PyObject_HEAD - %(ptrstruct_list)s - %(ctype)s data; -} %(otype)s; -typedef int (*pyobj_to_%(ctype)s_inplace_functype)(PyObject*, %(otype)s** ); -typedef int (*pyobj_to_%(ctype)s_functype)(PyObject*, %(otype)s* ); -typedef PyObject* (*pyobj_from_%(ctype)s_functype)(%(ctype)s*); -#define %(otype)sType (*(PyTypeObject *)PyArray_API[0]) -#define pyobj_from_%(ctype)s ((pyobj_from_%(ctype)s_functype)PyArray_API[1]) -#define pyobj_to_%(ctype)s_inplace ((pyobj_to_%(ctype)s_inplace_functype)PyArray_API[2]) -''' - - extern_template_wrapper = '''\ -static PyTypeObject %(otype)sType; -extern void %(init_func)s_f(%(init_func)s_c_functype, void*, %(ctype)s); -''' - - objdecl_template_wrapper = '''\ -static PyMethodDef %(otype)s_methods[] = { - %(type_method_list)s - {NULL} /* Sentinel */ -}; - -static PyGetSetDef %(otype)s_getseters[] = { - %(type_getseters_list)s - {NULL} /* Sentinel */ -}; - -static PyTypeObject %(otype)sType = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "%(modulename)s.%(name)s", /*tp_name*/ - sizeof(%(otype)s), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)%(otype)s_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - %(otype)s_repr, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "Fortran derived type %(name)s objects", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - %(otype)s_methods, /* tp_methods */ - 0 /*%(otype)s_members*/, /* tp_members */ - %(otype)s_getseters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)%(otype)s_init, /* tp_init */ - 0, /* tp_alloc */ - %(otype)s_new, /* tp_new */ -}; - -void *F2PY_%(otype)s_API[] = { - (void *) &%(otype)sType, - (void *) pyobj_from_%(ctype)s, - (void *) pyobj_to_%(ctype)s_inplace -}; -''' - - objdecl_template_importer = '''\ -static void **F2PY_%(otype)s_API; -''' - module_init_template_wrapper = '''\ -if (PyType_Ready(&%(otype)sType) < 0) goto capi_err; -PyModule_AddObject(f2py_module, "%(name)s", (PyObject *)&%(otype)sType); -{ - PyObject* c_api = PyCObject_FromVoidPtr((void *)F2PY_%(otype)s_API, NULL); - PyModule_AddObject(f2py_module, "_%(NAME)s_API", c_api); - if (PyErr_Occurred()) goto capi_err; -} -''' - module_init_template_importer = '''\ -{ - PyObject *c_api = NULL; - PyObject *wrappermodule = PyImport_ImportModule("%(wrappermodulename)s"); - if (wrappermodule == NULL) goto capi_%(name)s_err; - c_api = PyObject_GetAttrString(wrappermodule, "_%(NAME)s_API"); - if (c_api == NULL) {Py_DECREF(wrappermodule); goto capi_%(name)s_err;} - if (PyCObject_Check(c_api)) { - F2PY_%(otype)s_API = (void **)PyCObject_AsVoidPtr(c_api); - } - Py_DECREF(c_api); - Py_DECREF(wrappermodule); - if (F2PY_%(otype)s_API != NULL) goto capi_%(name)s_ok; -capi_%(name)s_err: - PyErr_Print(); - PyErr_SetString(PyExc_ImportError, "%(wrappermodulename)s failed to import"); - return; -capi_%(name)s_ok: - c_api = PyCObject_FromVoidPtr((void *)F2PY_%(otype)s_API, NULL); - PyModule_AddObject(f2py_module, "_%(NAME)s_API", c_api); - if (PyErr_Occurred()) goto capi_err; -} -''' - - c_code_template_wrapper = '''\ -static void %(init_func)s_c( - %(init_func_c_arg_clist)s) { - %(init_func_c_body_list)s -} -''' - - capi_code_template_wrapper = '''\ -static void %(otype)s_dealloc(%(otype)s* self) { - if (self->data) - PyMem_Free(self->data); - self->ob_type->tp_free((PyObject*)self); -} - -static int pyobj_to_%(ctype)s_inplace(PyObject *obj, - %(otype)s** value_ptr) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (%(otype)s_Check(obj)) { - *value_ptr = (%(otype)s*)obj; - return_value = 1; - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred()); -#endif - return return_value; -} - -static int pyobj_to_%(ctype)s(PyObject *obj, - %(ctype)s* value_ptr) { - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s(type=%%s)\\n",PyString_AS_STRING(PyObject_Repr(PyObject_Type(obj)))); -#endif - if (%(otype)s_Check(obj)) { - if (!memcpy(value_ptr,((%(otype)s *)obj)->data, %(bytes)s)) { - PyErr_SetString(PyExc_MemoryError, - "failed to copy %(name)s instance memory to %(ctype)s object."); - } else { - return_value = 1; - } - } -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"pyobj_to_%(ctype)s: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred()); -#endif - return return_value; -} - -static PyObject* pyobj_from_%(ctype)s(%(ctype)s* value_ptr) { - %(otype)s* obj = (%(otype)s*)(%(otype)sType.tp_alloc(&%(otype)sType, 0)); - if (obj == NULL) - return NULL; - obj->data = PyMem_Malloc(%(bytes)s); - if (obj->data == NULL) { - Py_DECREF(obj); - return PyErr_NoMemory(); - } - if (value_ptr) { - if (!memcpy(obj->data, value_ptr, %(bytes)s)) { - PyErr_SetString(PyExc_MemoryError, - "failed to copy %(ctype)s object memory to %(name)s instance."); - } - } - %(init_func)s_f(%(init_func)s_c, obj, obj->data); - return (PyObject*)obj; -} - -static PyObject * %(otype)s_new(PyTypeObject *type, - PyObject *args, PyObject *kwds) -{ - return pyobj_from_%(ctype)s(NULL); -} - -static int %(otype)s_init(%(otype)s *self, - PyObject *capi_args, PyObject *capi_kwds) -{ - int return_value = 0; -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"%(otype)s_init()\\n"); -#endif - if (!PyArg_ParseTuple(capi_args,"%(attr_format_elist)s" - %(attr_init_clist)s)) - return_value = -1; - -#if defined(F2PY_DEBUG_PYOBJ_TOFROM) - fprintf(stderr,"%(otype)s_init: return_value=%%d, PyErr_Occurred()=%%p\\n", return_value, PyErr_Occurred()); -#endif - return return_value; -} - -static PyObject * %(otype)s_as_tuple(%(otype)s * self) { - return Py_BuildValue("%(as_tuple_format_elist)s" - %(as_tuple_arg_clist)s); -} - -static PyObject * %(otype)s_repr(PyObject * self) { - PyObject* r = PyString_FromString("%(name)s("); - PyString_ConcatAndDel(&r, PyObject_Repr(%(otype)s_as_tuple((%(otype)s*)self))); - PyString_ConcatAndDel(&r, PyString_FromString(")")); - return r; -} - -%(getset_func_list)s -''' - - fortran_code_template_wrapper = '''\ - subroutine %(init_func)s(init_func_c, self, obj) - %(use_stmt_list)s - %(type_decl_list)s - external init_func_c -! self is %(otype)s - external self - %(ftype)s obj - call init_func_c(%(init_func_f_arg_clist)s) - end -''' - - #module_method_template = '''''' - - _defined = [] - def __init__(self, parent, typedecl): - WrapperBase.__init__(self) - ti = PyTypeInterface(typedecl) - self.ctype = ctype = ti.ctype - defined = parent.defined_types - if ctype in defined: - return - defined.append(ctype) - - - - implement_wrappers = True - if isinstance(typedecl.parent,Module) and typedecl.parent.name!=parent.modulename: - implement_wrappers = False - self.info('Using api for %s.%s: %s' % (parent.modulename, typedecl.name, ctype)) - self.wrappermodulename = typedecl.parent.name - else: - self.info('Generating interface for %s.%s: %s' % (parent.modulename, typedecl.name, ctype)) - - parent.isf90 = True - self.parent = parent - self.name = name = typedecl.name - self.otype = otype = ti.otype - self.ctype = ctype = ti.ctype - self.ctype_ptrs = self.ctype + '_ptrs' - self.ftype = ti.ftype - self.bytes = bytes = ti.bytes - - if not implement_wrappers: - self.typedef_template = self.typedef_template_importer - self.objdecl_template = self.objdecl_template_importer - self.module_init_template = self.module_init_template_importer - else: - self.header_template = self.header_template_wrapper - self.typedef_template = self.typedef_template_wrapper - self.extern_template = self.extern_template_wrapper - self.objdecl_template = self.objdecl_template_wrapper - self.module_init_template = self.module_init_template_wrapper - self.c_code_template = self.c_code_template_wrapper - self.capi_code_template = self.capi_code_template_wrapper - self.fortran_code_template = self.fortran_code_template_wrapper - WrapperCPPMacro(parent, 'F_FUNC') - - self.init_func_f_arg_list = ['self'] - self.init_func_c_arg_list = ['%s *self' % (otype)] - self.init_func_c_ctype_arg_list = ['%s *' % (otype)] - self.init_func_c_body_list = [] - self.ptrstruct_list = [] - self.attr_decl_list = [] - self.attr_format_list = [] - self.attr_init_list = [] - self.as_tuple_format_list = [] - self.as_tuple_arg_list = [] - self.getset_func_list = [] - self.type_getseters_list = [] - for n in typedecl.a.component_names: - v = typedecl.a.components[n] - t = v.get_typedecl() - ti1 = PyTypeInterface(t) - PythonCAPIType(parent, t) - ct = ti1.ctype - parent.add(t) - self.ptrstruct_list.append('%s* %s_ptr;' % (ct, n)) - self.init_func_f_arg_list.append('obj %% %s' % (n)) - self.init_func_c_arg_list.append('\n%s * %s_ptr' % (ct, n)) - self.init_func_c_ctype_arg_list.append('\n%s *' % (ct)) - self.init_func_c_body_list.append('''\ -if (!((void*)%(n)s_ptr >= self->data - && (void*)%(n)s_ptr < self->data + %(bytes)s )) - fprintf(stderr,"INCONSISTENCY IN %(name)s WRAPPER: " - "self->data=%%p <= %(n)s_ptr=%%p < self->data+%(bytes)s=%%p\\n", - self->data, %(n)s_ptr, self->data + %(bytes)s); -self->%(n)s_ptr = %(n)s_ptr; -''' % (locals())) - self.attr_format_list.append('O&') - self.attr_init_list.append('\npyobj_to_%s, self->%s_ptr' % (ct,n)) - self.as_tuple_format_list.append('O&') - self.as_tuple_arg_list.append('\npyobj_from_%s, self->%s_ptr' % (ct, n)) - self.getset_func_list.append('''\ -static PyObject * %(otype)s_get_%(n)s(%(otype)s *self, - void *closure) { - return pyobj_from_%(ct)s(self->%(n)s_ptr); -} -static int %(otype)s_set_%(n)s(%(otype)s *self, - PyObject *value, void *closure) -{ - if (value == NULL) { - PyErr_SetString(PyExc_TypeError, - "Cannot delete %(name)s attribute %(n)s"); - return -1; - } - if (pyobj_to_%(ct)s(value, self->%(n)s_ptr)) - return 0; - return -1; -} -''' % (locals())) - self.type_getseters_list.append('{"%(n)s",(getter)%(otype)s_get_%(n)s, (setter)%(otype)s_set_%(n)s,\n "component %(n)s",NULL},' % (locals())) - if self.attr_init_list: self.attr_init_list.insert(0,'') - if self.as_tuple_arg_list: self.as_tuple_arg_list.insert(0,'') - self.init_func = self.ctype + '_init' - - self.type_method_list = [] - self.type_method_list.append('{"as_tuple",(PyCFunction)%(otype)s_as_tuple,METH_NOARGS,\n "Return %(name)s components as tuple."},' % (self.__dict__)) - - self.use_stmt_list = [] - self.type_decl_list = [] - if isinstance(typedecl.parent, Module): - self.use_stmt_list.append('use %s' % (typedecl.parent.name)) - elif isinstance(typedecl.parent, (Subroutine, Function)): - self.type_decl_list.append(typedecl.asfix()) - else: - raise NotImplementedError,'types declared in '+typedecl.parent.__class__.__name__ - parent.apply_templates(self) - return diff --git a/numpy/f2py/lib/setup.py b/numpy/f2py/lib/setup.py deleted file mode 100644 index e35cab1f3..000000000 --- a/numpy/f2py/lib/setup.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python -def configuration(parent_package='',top_path=None): - from numpy.distutils.misc_util import Configuration - config = Configuration('lib',parent_package,top_path) - config.add_subpackage('parser') - config.add_subpackage('extgen') - config.add_data_files('*.txt','parser/*.txt') - config.add_data_dir('src') - return config - -if __name__ == "__main__": - from numpy.distutils.core import setup - setup(configuration=configuration) diff --git a/numpy/f2py/lib/src/F_FUNC.cpp b/numpy/f2py/lib/src/F_FUNC.cpp deleted file mode 100644 index edaa98064..000000000 --- a/numpy/f2py/lib/src/F_FUNC.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#if defined(PREPEND_FORTRAN) -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) _##F -#else -#define F_FUNC(f,F) _##f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) _##F##_ -#else -#define F_FUNC(f,F) _##f##_ -#endif -#endif -#else -#if defined(NO_APPEND_FORTRAN) -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F -#else -#define F_FUNC(f,F) f -#endif -#else -#if defined(UPPERCASE_FORTRAN) -#define F_FUNC(f,F) F##_ -#else -#define F_FUNC(f,F) f##_ -#endif -#endif -#endif -#if defined(UNDERSCORE_G77) -#define F_FUNC_US(f,F) F_FUNC(f##_,F##_) -#else -#define F_FUNC_US(f,F) F_FUNC(f,F) -#endif diff --git a/numpy/f2py/lib/src/pyobj_to_string_len.c b/numpy/f2py/lib/src/pyobj_to_string_len.c deleted file mode 100644 index f082a4b3b..000000000 --- a/numpy/f2py/lib/src/pyobj_to_string_len.c +++ /dev/null @@ -1,11 +0,0 @@ -int pyobj_to_string_len(PyObject* obj, f2py_string* value, size_t length) { - if (PyString_Check(obj)) { - if (strncpy((char*)value,PyString_AS_STRING(obj), length)) - return 1; - } - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "Failed to convert python object to C f2py_string."); - } - return 0; -} diff --git a/numpy/f2py/lib/tests/test_derived_scalar.py b/numpy/f2py/lib/tests/test_derived_scalar.py deleted file mode 100644 index 60c082171..000000000 --- a/numpy/f2py/lib/tests/test_derived_scalar.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -""" -Tests for intent(in,out) derived type arguments in Fortran subroutine's. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * -from numpy.f2py.lib.main import build_extension, compile - -fortran_code = ''' -subroutine foo(a) - type myt - integer flag - end type myt - type(myt) a -!f2py intent(in,out) a - a % flag = a % flag + 1 -end -function foo2(a) - type myt - integer flag - end type myt - type(myt) a - type(myt) foo2 - foo2 % flag = a % flag + 2 -end -''' - -m, = compile(fortran_code, 'test_derived_scalar_ext') - -from numpy import * - -class TestM(TestCase): - - def test_foo_simple(self, level=1): - a = m.myt(2) - assert_equal(a.flag,2) - assert isinstance(a,m.myt),`a` - r = m.foo(a) - assert isinstance(r,m.myt),`r` - assert r is a - assert_equal(r.flag,3) - assert_equal(a.flag,3) - - a.flag = 5 - assert_equal(r.flag,5) - - #s = m.foo((5,)) - - def test_foo2_simple(self, level=1): - a = m.myt(2) - assert_equal(a.flag,2) - assert isinstance(a,m.myt),`a` - r = m.foo2(a) - assert isinstance(r,m.myt),`r` - assert r is not a - assert_equal(a.flag,2) - assert_equal(r.flag,4) - - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/tests/test_module_module.py b/numpy/f2py/lib/tests/test_module_module.py deleted file mode 100644 index 5a3fefa32..000000000 --- a/numpy/f2py/lib/tests/test_module_module.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -""" -Tests for module with scalar derived types and subprograms. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * - -from numpy.f2py.lib.main import build_extension, compile - -fortran_code = ''' -module test_module_module_ext2 - type rat - integer n,d - end type rat - contains - subroutine foo2() - print*,"In foo2" - end subroutine foo2 -end module -module test_module_module_ext - contains - subroutine foo - use test_module_module_ext2 - print*,"In foo" - call foo2 - end subroutine foo - subroutine bar(a) - use test_module_module_ext2 - type(rat) a - print*,"In bar,a=",a - end subroutine bar -end module test_module_module_ext -''' - -m,m2 = compile(fortran_code, modulenames=['test_module_module_ext', - 'test_module_module_ext2', - ]) - -from numpy import * - -class TestM(TestCase): - - def test_foo_simple(self, level=1): - foo = m.foo - foo() - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/tests/test_module_scalar.py b/numpy/f2py/lib/tests/test_module_scalar.py deleted file mode 100644 index acaae0517..000000000 --- a/numpy/f2py/lib/tests/test_module_scalar.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -""" -Tests for module with scalar derived types and subprograms. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * -from numpy.f2py.lib.main import build_extension, compile - -fortran_code = ''' -module test_module_scalar_ext - - contains - subroutine foo(a) - integer a -!f2py intent(in,out) a - a = a + 1 - end subroutine foo - function foo2(a) - integer a - integer foo2 - foo2 = a + 2 - end function foo2 -end module test_module_scalar_ext -''' - -m, = compile(fortran_code, modulenames = ['test_module_scalar_ext']) - -from numpy import * - -class TestM(TestCase): - - def test_foo_simple(self, level=1): - foo = m.foo - r = foo(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,3) - - def test_foo2_simple(self, level=1): - foo2 = m.foo2 - r = foo2(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,4) - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/tests/test_scalar_function_in.py b/numpy/f2py/lib/tests/test_scalar_function_in.py deleted file mode 100644 index bbc37d9f8..000000000 --- a/numpy/f2py/lib/tests/test_scalar_function_in.py +++ /dev/null @@ -1,531 +0,0 @@ -#!/usr/bin/env python -""" -Tests for intent(in) arguments in subroutine-wrapped Fortran functions. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * - -from numpy.f2py.lib.main import build_extension, compile - -fortran_code = '''\ -! -*- f77 -*- - function fooint1(a) - integer*1 a - integer*1 fooint1 - fooint1 = a + 1 - end - function fooint2(a) - integer*2 a - integer*2 fooint2 - fooint2 = a + 1 - end - function fooint4(a) - integer*4 a - integer*4 fooint4 - fooint4 = a + 1 - end - function fooint8(a) - integer*8 a - integer*8 fooint8 - fooint8 = a + 1 - end - function foofloat4(a) - real*4 a - real*4 foofloat4 - foofloat4 = a + 1.0e0 - end - function foofloat8(a) - real*8 a - real*8 foofloat8 - foofloat8 = a + 1.0d0 - end - function foocomplex8(a) - complex*8 a - complex*8 foocomplex8 - foocomplex8 = a + 1.0e0 - end - function foocomplex16(a) - complex*16 a - complex*16 foocomplex16 - foocomplex16 = a + 1.0d0 - end - function foobool1(a) - logical*1 a - logical*1 foobool1 - foobool1 = .not. a - end - function foobool2(a) - logical*2 a - logical*2 foobool2 - foobool2 = .not. a - end - function foobool4(a) - logical*4 a - logical*4 foobool4 - foobool4 = .not. a - end - function foobool8(a) - logical*8 a - logical*8 foobool8 - foobool8 = .not. a - end - function foostring1(a) - character*1 a - character*1 foostring1 - foostring1 = "1" - end - function foostring5(a) - character*5 a - character*5 foostring5 - foostring5 = a - foostring5(1:2) = "12" - end -! function foostringstar(a) -! character*(*) a -! character*(*) foostringstar -! if (len(a).gt.0) then -! foostringstar = a -! foostringstar(1:1) = "1" -! endif -! end -''' - -m, = compile(fortran_code, 'test_scalar_function_in_ext') - -from numpy import * - -class TestM(TestCase): - - def test_foo_integer1(self, level=1): - i = int8(2) - e = int8(3) - func = m.fooint1 - assert isinstance(i,int8),`type(i)` - r = func(i) - assert isinstance(r,int8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - for intx in [int64,int16,int32]: - r = func(intx(2)) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer2(self, level=1): - i = int16(2) - e = int16(3) - func = m.fooint2 - assert isinstance(i,int16),`type(i)` - r = func(i) - assert isinstance(r,int16),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - for intx in [int8,int64,int32]: - r = func(intx(2)) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer4(self, level=1): - i = int32(2) - e = int32(3) - func = m.fooint4 - assert isinstance(i,int32),`type(i)` - r = func(i) - assert isinstance(r,int32),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - for intx in [int8,int16,int64]: - r = func(intx(2)) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer8(self, level=1): - i = int64(2) - e = int64(3) - func = m.fooint8 - assert isinstance(i,int64),`type(i)` - r = func(i) - assert isinstance(r,int64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - for intx in [int8,int16,int32]: - r = func(intx(2)) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_real4(self, level=1): - i = float32(2) - e = float32(3) - func = m.foofloat4 - assert isinstance(i,float32),`type(i)` - r = func(i) - assert isinstance(r,float32),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e+float32(0.2)) - - r = func(float64(2.0)) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_real8(self, level=1): - i = float64(2) - e = float64(3) - func = m.foofloat8 - assert isinstance(i,float64),`type(i)` - r = func(i) - assert isinstance(r,float64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e+float64(0.2)) - - r = func(float32(2.0)) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_complex8(self, level=1): - i = complex64(2) - e = complex64(3) - func = m.foocomplex8 - assert isinstance(i,complex64),`type(i)` - r = func(i) - assert isinstance(r,complex64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(0.2)) - - r = func(2+1j) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(1j)) - - r = func(complex128(2.0)) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func([2,3]) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(3j)) - - self.assertRaises(TypeError,lambda :func([2,1,3])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_complex16(self, level=1): - i = complex128(2) - e = complex128(3) - func = m.foocomplex16 - assert isinstance(i,complex128),`type(i)` - r = func(i) - assert isinstance(r,complex128),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(0.2)) - - r = func(2+1j) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(1j)) - - r = func([2]) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func([2,3]) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(3j)) - - r = func(complex64(2.0)) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func([2,1,3])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_bool1(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool1 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool2(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool2 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool4(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool4 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool8(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool8 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_string1(self, level=1): - i = string0('a') - e = string0('1') - func = m.foostring1 - assert isinstance(i,string0),`type(i)` - r = func(i) - assert isinstance(r,string0),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func('ab') - assert isinstance(r,string0),`type(r)` - assert_equal(r,e) - - r = func('') - assert isinstance(r,string0),`type(r)` - assert_equal(r,e) - - def test_foo_string5(self, level=1): - i = string0('abcde') - e = string0('12cde') - func = m.foostring5 - assert isinstance(i,string0),`type(i)` - r = func(i) - assert isinstance(r,string0),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func('abc') - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12c ') - - r = func('abcdefghi') - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12cde') - - r = func([1]) - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12] ') - - def _check_foo_string0(self, level=1): - i = string0('abcde') - e = string0('12cde') - func = m.foostringstar - r = func('abcde') - assert_equal(r,'1bcde') - r = func('') - assert_equal(r,'') - - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/tests/test_scalar_in_out.py b/numpy/f2py/lib/tests/test_scalar_in_out.py deleted file mode 100644 index 1ffd95f01..000000000 --- a/numpy/f2py/lib/tests/test_scalar_in_out.py +++ /dev/null @@ -1,528 +0,0 @@ -#!/usr/bin/env python -""" -Tests for intent(in,out) arguments in Fortran subroutine's. - ------ -Permission to use, modify, and distribute this software is given under the -terms of the NumPy License. See http://scipy.org. - -NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. -Author: Pearu Peterson <pearu@cens.ioc.ee> -Created: Oct 2006 ------ -""" - -import os -import sys -from numpy.testing import * - -from numpy.f2py.lib.main import build_extension, compile - -fortran_code = ''' - subroutine fooint1(a) - integer*1 a -!f2py intent(in,out) a - a = a + 1 - end - subroutine fooint2(a) - integer*2 a -!f2py intent(in,out) a - a = a + 1 - end - subroutine fooint4(a) - integer*4 a -!f2py intent(in,out) a - a = a + 1 - end - subroutine fooint8(a) - integer*8 a -!f2py intent(in,out) a - a = a + 1 - end - subroutine foofloat4(a) - real*4 a -!f2py intent(in,out) a - a = a + 1.0e0 - end - subroutine foofloat8(a) - real*8 a -!f2py intent(in,out) a - a = a + 1.0d0 - end - subroutine foocomplex8(a) - complex*8 a -!f2py intent(in,out) a - a = a + 1.0e0 - end - subroutine foocomplex16(a) - complex*16 a -!f2py intent(in,out) a - a = a + 1.0d0 - end - subroutine foobool1(a) - logical*1 a -!f2py intent(in,out) a - a = .not. a - end - subroutine foobool2(a) - logical*2 a -!f2py intent(in,out) a - a = .not. a - end - subroutine foobool4(a) - logical*4 a -!f2py intent(in,out) a - a = .not. a - end - subroutine foobool8(a) - logical*8 a -!f2py intent(in,out) a - a = .not. a - end - subroutine foostring1(a) - character*1 a -!f2py intent(in,out) a - a = "1" - end - subroutine foostring5(a) - character*5 a -!f2py intent(in,out) a - a(1:2) = "12" - end - subroutine foostringstar(a) - character*(*) a -!f2py intent(in,out) a - if (len(a).gt.0) then - a(1:1) = "1" - endif - end -''' - -m, = compile(fortran_code, 'test_scalar_in_out_ext', source_ext = '.f') - -from numpy import * - -class TestM(TestCase): - - def test_foo_integer1(self, level=1): - i = int8(2) - e = int8(3) - func = m.fooint1 - assert isinstance(i,int8),`type(i)` - r = func(i) - assert isinstance(r,int8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - for intx in [int64,int16,int32]: - r = func(intx(2)) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int8),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer2(self, level=1): - i = int16(2) - e = int16(3) - func = m.fooint2 - assert isinstance(i,int16),`type(i)` - r = func(i) - assert isinstance(r,int16),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - for intx in [int8,int64,int32]: - r = func(intx(2)) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int16),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer4(self, level=1): - i = int32(2) - e = int32(3) - func = m.fooint4 - assert isinstance(i,int32),`type(i)` - r = func(i) - assert isinstance(r,int32),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - for intx in [int8,int16,int64]: - r = func(intx(2)) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int32),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_integer8(self, level=1): - i = int64(2) - e = int64(3) - func = m.fooint8 - assert isinstance(i,int64),`type(i)` - r = func(i) - assert isinstance(r,int64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - for intx in [int8,int16,int32]: - r = func(intx(2)) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,int64),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_real4(self, level=1): - i = float32(2) - e = float32(3) - func = m.foofloat4 - assert isinstance(i,float32),`type(i)` - r = func(i) - assert isinstance(r,float32),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e+float32(0.2)) - - r = func(float64(2.0)) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,float32),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_real8(self, level=1): - i = float64(2) - e = float64(3) - func = m.foofloat8 - assert isinstance(i,float64),`type(i)` - r = func(i) - assert isinstance(r,float64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e+float64(0.2)) - - r = func(float32(2.0)) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,float64),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func(2.2j)) - self.assertRaises(TypeError,lambda :func([2,1])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_complex8(self, level=1): - i = complex64(2) - e = complex64(3) - func = m.foocomplex8 - assert isinstance(i,complex64),`type(i)` - r = func(i) - assert isinstance(r,complex64),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(0.2)) - - r = func(2+1j) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(1j)) - - r = func(complex128(2.0)) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func([2]) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e) - - r = func([2,3]) - assert isinstance(r,complex64),`type(r)` - assert_equal(r,e+complex64(3j)) - - self.assertRaises(TypeError,lambda :func([2,1,3])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_complex16(self, level=1): - i = complex128(2) - e = complex128(3) - func = m.foocomplex16 - assert isinstance(i,complex128),`type(i)` - r = func(i) - assert isinstance(r,complex128),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func(2) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func(2.0) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func(2.2) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(0.2)) - - r = func(2+1j) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(1j)) - - r = func([2]) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - r = func([2,3]) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e+complex128(3j)) - - r = func(complex64(2.0)) - assert isinstance(r,complex128),`type(r)` - assert_equal(r,e) - - self.assertRaises(TypeError,lambda :func([2,1,3])) - self.assertRaises(TypeError,lambda :func({})) - - def test_foo_bool1(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool1 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool2(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool2 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool4(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool4 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_bool8(self, level=1): - i = bool8(True) - e = bool8(False) - func = m.foobool8 - assert isinstance(i,bool8),`type(i)` - r = func(i) - assert isinstance(r,bool8),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - for tv in [1,2,2.1,-1j,[0],True]: - r = func(tv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,e) - - for fv in [0,0.0,0j,False,(),{},[]]: - r = func(fv) - assert isinstance(r,bool8),`type(r)` - assert_equal(r,not e) - - def test_foo_string1(self, level=1): - i = string0('a') - e = string0('1') - func = m.foostring1 - assert isinstance(i,string0),`type(i)` - r = func(i) - assert isinstance(r,string0),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func('ab') - assert isinstance(r,string0),`type(r)` - assert_equal(r,e) - - r = func('') - assert isinstance(r,string0),`type(r)` - assert_equal(r,e) - - def test_foo_string5(self, level=1): - i = string0('abcde') - e = string0('12cde') - func = m.foostring5 - assert isinstance(i,string0),`type(i)` - r = func(i) - assert isinstance(r,string0),`type(r)` - assert i is not r,`id(i),id(r)` - assert_equal(r,e) - - r = func('abc') - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12c ') - - r = func('abcdefghi') - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12cde') - - r = func([1]) - assert isinstance(r,string0),`type(r)` - assert_equal(r,'12] ') - - def test_foo_string0(self, level=1): - i = string0('abcde') - e = string0('12cde') - func = m.foostringstar - r = func('abcde') - assert_equal(r,'1bcde') - r = func('') - assert_equal(r,'') - - -if __name__ == "__main__": - run_module_suite() diff --git a/numpy/f2py/lib/wrapper_base.py b/numpy/f2py/lib/wrapper_base.py deleted file mode 100644 index 3164e817f..000000000 --- a/numpy/f2py/lib/wrapper_base.py +++ /dev/null @@ -1,178 +0,0 @@ -import os -import sys -import re - -__all__ = ['WrapperBase','WrapperCPPMacro','WrapperCCode'] - -class WrapperBase: - - def __init__(self): - self.srcdir = os.path.join(os.path.dirname(__file__),'src') - return - def warning(self, message): - print >> sys.stderr, message - def info(self, message): - print >> sys.stderr, message - - def get_resource_content(self, name, ext): - if name.startswith('pyobj_to_'): - try: - return self.generate_pyobj_to_ctype_c(name[9:]) - except NotImplementedError: - pass - elif name.startswith('pyobj_from_'): - try: - return self.generate_pyobj_from_ctype_c(name[11:]) - except NotImplementedError: - pass - generator_mth_name = 'generate_' + name + ext.replace('.','_') - generator_mth = getattr(self, generator_mth_name, lambda : None) - body = generator_mth() - if body is not None: - return body - fn = os.path.join(self.srcdir,name+ext) - if os.path.isfile(fn): - f = open(fn,'r') - body = f.read() - f.close() - return body - self.warning('No such file: %r' % (fn)) - return - - def get_dependencies(self, code): - l = [] - for uses in re.findall(r'(?<=depends:)([,\w\s.]+)', code, re.I): - for use in uses.split(','): - use = use.strip() - if not use: continue - l.append(use) - return l - - def resolve_dependencies(self, parent, body): - assert isinstance(body, str),type(body) - for d in self.get_dependencies(body): - if d.endswith('.cpp'): - WrapperCPPMacro(parent, d[:-4]) - elif d.endswith('.c'): - WrapperCCode(parent, d[:-2]) - else: - self.warning('Unknown dependence: %r.' % (d)) - return - - def apply_attributes(self, template): - """ - Apply instance attributes to template string. - - Replace rules for attributes: - _list - will be joined with newline - _clist - _list will be joined with comma - _elist - _list will be joined - ..+.. - attributes will be added - [..] - will be evaluated - """ - replace_names = set(re.findall(r'[ ]*%\(.*?\)s', template)) - d = {} - for name in replace_names: - tab = ' ' * (len(name)-len(name.lstrip())) - name = name.lstrip()[2:-2] - names = name.split('+') - joinsymbol = '\n' - attrs = None - for n in names: - realname = n.strip() - if n.endswith('_clist'): - joinsymbol = ', ' - realname = realname[:-6] + '_list' - elif n.endswith('_elist'): - joinsymbol = '' - realname = realname[:-6] + '_list' - realname_lower = realname.lower() - parent = getattr(self,'parent',None) - if hasattr(self, realname): - attr = getattr(self, realname) - elif hasattr(self, realname_lower): - attr = getattr(self, realname_lower).upper() - elif hasattr(parent, realname): - attr = getattr(parent, realname) - elif hasattr(parent, realname_lower): - attr = getattr(parent, realname_lower).upper() - elif realname.startswith('['): - attr = eval(realname) - else: - self.warning('Undefined %r attribute: %r' % (self.__class__.__name__, realname)) - continue - if attrs is None: - attrs = attr - else: - attrs += attr - if isinstance(attrs, list): - attrs = joinsymbol.join(attrs) - d[name] = str(attrs).replace('\n','\n'+tab) - return template % d - - def apply_templates(self, child): - for n in self.list_names: - l = getattr(self,n + '_list') - c = child.apply_attributes(getattr(child, n+'_template','')) - if c: - l.append(c) - return - -class WrapperCPPMacro(WrapperBase): - """ - CPP macros - """ - def __init__(self, parent, name): - WrapperBase.__init__(self) - defined = parent.defined_cpp_code - if name in defined: - return - defined.append(name) - - body = self.get_resource_content(name,'.cpp') - if body is None: - self.warning('Failed to get CPP macro %r content.' % (name)) - return - self.resolve_dependencies(parent, body) - parent.header_list.append(body) - return - -class WrapperCCode(WrapperBase): - """ - C code - """ - def __init__(self, parent, name): - WrapperBase.__init__(self) - defined = parent.defined_c_code - if name in defined: - return - defined.append(name) - - body = self.get_resource_content(name,'.c') - if body is None: - self.warning('Failed to get C code %r content.' % (name)) - return - if isinstance(body, dict): - for k,v in body.items(): - self.resolve_dependencies(parent, v) - for k,v in body.items(): - l = getattr(parent,k+'_list') - l.append(v) - else: - self.resolve_dependencies(parent, body) - parent.c_code_list.append(body) - return - - def generate_pyobj_to_ctype_c(self, ctype): - from generate_pyobj_tofrom_funcs import pyobj_to_npy_scalar, pyobj_to_f2py_string - if ctype.startswith('npy_'): - return pyobj_to_npy_scalar(ctype) - elif ctype.startswith('f2py_string'): - return pyobj_to_f2py_string(ctype) - raise NotImplementedError,`ctype` - - def generate_pyobj_from_ctype_c(self, ctype): - from generate_pyobj_tofrom_funcs import pyobj_from_npy_scalar - if ctype.startswith('npy_'): - return pyobj_from_npy_scalar(ctype) - raise NotImplementedError,`ctype` |