block_statements.py :  » Business-Application » PDB2PQR » pdb2pqr-1.6 » contrib » numpy-1.1.0 » numpy » f2py » lib » parser » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Business Application » PDB2PQR 
PDB2PQR » pdb2pqr 1.6 » contrib » numpy 1.1.0 » numpy » f2py » lib » parser » block_statements.py
"""
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 ]
w_w__w_.ja___va___2_s_.___co__m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.