diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2006-09-16 05:56:18 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2006-09-16 05:56:18 +0000 |
commit | 617b46e97017ca4614d04090db5c7d999d1be422 (patch) | |
tree | 31fe8bd3b9a28b01d233eceae83735631789ee9b /numpy/f2py/lib/block_statements.py | |
parent | 8b6db6e885dec95dda7bbe2001d95bdee63e6cf1 (diff) | |
download | numpy-617b46e97017ca4614d04090db5c7d999d1be422.tar.gz |
4G f2py: first working example.
Diffstat (limited to 'numpy/f2py/lib/block_statements.py')
-rw-r--r-- | numpy/f2py/lib/block_statements.py | 149 |
1 files changed, 137 insertions, 12 deletions
diff --git a/numpy/f2py/lib/block_statements.py b/numpy/f2py/lib/block_statements.py index 446b1610c..fa08fc470 100644 --- a/numpy/f2py/lib/block_statements.py +++ b/numpy/f2py/lib/block_statements.py @@ -14,7 +14,7 @@ class HasImplicitStmt: a = AttributeHolder(implicit_rules = {}) - def get_type(self, name): + 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' @@ -74,7 +74,18 @@ class HasUseStmt: class HasVariables: - a = AttributeHolder(variables = {}) + a = AttributeHolder(variables = {}, + variable_names = [] # defines the order of declarations + ) + + def get_variable_by_name(self, name): + variables = self.a.variables + if variables.has_key(name): + var = variables[name] + else: + var = variables[name] = Variable(self, name) + self.a.variable_names.append(name) + return var def topyf(self,tab=''): s = '' @@ -92,8 +103,17 @@ class HasTypeDecls: 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) + raise NotImplementedError,'get type_decl from use modules' + return type_decl + class HasAttributes: + known_attributes = [] a = AttributeHolder(attributes = []) def topyf(self, tab=''): @@ -102,6 +122,29 @@ class HasAttributes: s += tab + attr + '\n' return s + def is_private(self): + attributes = self.a.attributes + if 'PUBLIC' in attributes: return False + if 'PRIVATE' in attributes: return True + return + def is_public(self): return not self.is_private() + + 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 known_attributes(uattr): + self.warning('unknown attribute %r' % (attr)) + attributes.append(uattr) + return + class HasModuleProcedures: a = AttributeHolder(module_procedures = []) @@ -196,10 +239,15 @@ class Module(BeginStatement, HasAttributes, """ match = re.compile(r'module\s*\w+\Z', re.I).match end_stmt_cls = EndModule + a = AttributeHolder(module_subprogram = {}, - module_data = {}, + module_provides = {}, # all symbols that are public and so + # can be imported via USE statement + # by other blocks ) + known_attributes = ['PUBLIC', 'PRIVATE'] + def get_classes(self): return access_spec + specification_part + module_subprogram_part @@ -208,6 +256,9 @@ class Module(BeginStatement, HasAttributes, self.name = name return BeginStatement.process_item(self) + def get_provides(self): + return self.a.module_provides + def analyze(self): content = self.content[:] @@ -225,11 +276,19 @@ class Module(BeginStatement, HasAttributes, 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 module_provides.has_key(name): + 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 += HasAttributesStmt.topyf(self, tab=tab+' ') s += HasTypeDecls.topyf(self, tab=tab+' ') s += HasVariables.topyf(self, tab=tab+' ') s += tab + ' CONTAINS\n' @@ -270,7 +329,7 @@ class EndProgram(EndStatement): match = re.compile(r'end(\s*program\s*\w*|)\Z', re.I).match class Program(BeginStatement, ProgramBlock, - HasAttributes, + HasAttributes, # XXX: why Program needs .attributes? HasImplicitStmt, HasUseStmt): """ PROGRAM [name] """ @@ -340,6 +399,8 @@ class Interface(BeginStatement, HasImplicitStmt, HasUseStmt, end_stmt_cls = EndInterface blocktype = 'interface' + a = AttributeHolder(interface_provides = {}) + def get_classes(self): return intrinsic_type_spec + interface_specification @@ -358,6 +419,29 @@ class Interface(BeginStatement, HasImplicitStmt, HasUseStmt, 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) + + parent_provides = self.parent.get_provides() + if parent_provides is not None: + if self.is_public(): + if parent_provides.has_key(self.name): + self.warning('interface name conflict with %s, overriding.' % (self.name)) + parent_provides[self.name] = self + + return # Subroutine @@ -369,6 +453,8 @@ class SubProgramStatement(BeginStatement, ProgramBlock, """ [ <prefix> ] <FUNCTION|SUBROUTINE> <name> [ ( <args> ) ] [ <suffix> ] """ + known_attributes = ['PUBLIC', 'PRIVATE'] + a = AttributeHolder(internal_subprogram = {}) def process_item(self): @@ -430,7 +516,7 @@ class SubProgramStatement(BeginStatement, ProgramBlock, content = self.content[:] if self.prefix: - self.a.attributes.extend(prefix.upper().split()) + self.update_attributes(prefix.upper().split()) variables = self.a.variables for a in self.args: @@ -459,6 +545,13 @@ class SubProgramStatement(BeginStatement, ProgramBlock, 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 parent_provides.has_key(self.name): + self.warning('module subprogram name conflict with %s, overriding.' % (self.name)) + parent_provides[self.name] = self + return def topyf(self, tab=''): @@ -486,6 +579,7 @@ class Subroutine(SubProgramStatement): """ 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 @@ -506,6 +600,7 @@ class Function(SubProgramStatement): """ 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 # Handle subprogram prefixes @@ -800,7 +895,11 @@ class Type(BeginStatement, HasVariables, HasAttributes): end_stmt_cls = EndType a = AttributeHolder(extends = None, - parameters = []) + parameters = {}, + component_names = [], # specifies component order for sequence types + components = {} + ) + known_attributes = re.compile(r'\A(PUBLIC|PRIVATE|SEQUENCE|ABSTRACT|BIND\s*\(.*\))\Z').match def process_item(self): line = self.item.get_line()[4:].lstrip() @@ -858,15 +957,41 @@ class Type(BeginStatement, HasVariables, HasAttributes): spec = 'BIND(%s)' % (', '.join(args)) else: spec = '%s(%s)' % (s,n) - self.warning('Unknown type-attr-spec %r' % (spec)) else: spec = spec.upper() - if spec not in ['PUBLIC', 'PRIVATE', 'ABSTRACT']: - self.warning('Unknown type-attr-spec %r' % (spec)) - self.a.attributes.append(spec) - self.a.parameters.extend(self.params) - assert isinstance(self.parent,HasTypeDecls),`self.parent.__class__` + 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 parent_provides.has_key(self.name): + self.warning('type declaration name conflict with %s, overriding.' % (self.name)) + parent_provides[self.name] = self + return def topyf(self, tab=''): |