[Numpy-svn] r3307 - trunk/numpy/f2py/lib/parser
numpy-svn at scipy.org
numpy-svn at scipy.org
Wed Oct 11 07:25:08 EDT 2006
Author: pearu
Date: 2006-10-11 06:25:02 -0500 (Wed, 11 Oct 2006)
New Revision: 3307
Modified:
trunk/numpy/f2py/lib/parser/base_classes.py
trunk/numpy/f2py/lib/parser/block_statements.py
trunk/numpy/f2py/lib/parser/statements.py
trunk/numpy/f2py/lib/parser/typedecl_statements.py
Log:
F2PY G3: improved public/private spec handling. Added function wrapping support.
Modified: trunk/numpy/f2py/lib/parser/base_classes.py
===================================================================
--- trunk/numpy/f2py/lib/parser/base_classes.py 2006-10-11 00:39:23 UTC (rev 3306)
+++ trunk/numpy/f2py/lib/parser/base_classes.py 2006-10-11 11:25:02 UTC (rev 3307)
@@ -170,6 +170,7 @@
'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
@@ -282,6 +283,7 @@
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
@@ -334,7 +336,7 @@
if self.check:
a.append('CHECK(%s)' % (', '.join(self.check)))
if a:
- s += ', '.join(a) + ' :: '
+ s += ', ' + ', '.join(a) + ' :: '
s += self.name
if self.bounds:
s += '(%s)' % (', '.join(self.bounds))
Modified: trunk/numpy/f2py/lib/parser/block_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/block_statements.py 2006-10-11 00:39:23 UTC (rev 3306)
+++ trunk/numpy/f2py/lib/parser/block_statements.py 2006-10-11 11:25:02 UTC (rev 3307)
@@ -90,6 +90,24 @@
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 = {},
@@ -129,7 +147,6 @@
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:
@@ -143,13 +160,6 @@
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
@@ -254,7 +264,7 @@
class Module(BeginStatement, HasAttributes,
HasImplicitStmt, HasUseStmt, HasVariables,
- HasTypeDecls):
+ HasTypeDecls, AccessSpecs):
"""
MODULE <name>
..
@@ -315,6 +325,7 @@
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+' ')
@@ -358,8 +369,8 @@
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):
+ #HasAttributes, # XXX: why Program needs .attributes?
+ HasImplicitStmt, HasUseStmt, AccessSpecs):
""" PROGRAM [name]
"""
match = re.compile(r'program\s*\w*\Z', re.I).match
@@ -386,7 +397,7 @@
blocktype = 'blockdata'
class BlockData(BeginStatement, HasImplicitStmt, HasUseStmt,
- HasVariables):
+ HasVariables, AccessSpecs):
"""
BLOCK DATA [ <block-data-name> ]
"""
@@ -407,7 +418,7 @@
blocktype = 'interface'
class Interface(BeginStatement, HasImplicitStmt, HasUseStmt,
- HasModuleProcedures, HasAttributes
+ HasModuleProcedures, AccessSpecs
):
"""
INTERFACE [<generic-spec>] | ABSTRACT INTERFACE
@@ -430,8 +441,6 @@
a = AttributeHolder(interface_provides = {})
- known_attributes = ['PUBLIC','PRIVATE']
-
def get_classes(self):
l = intrinsic_type_spec + interface_specification
if self.reader.mode=='pyf':
@@ -453,8 +462,8 @@
return 'ABSTRACT INTERFACE'
return 'INTERFACE '+ str(self.generic_spec)
- def get_provides(self):
- return self.a.interface_provides
+ #def get_provides(self):
+ # return self.a.interface_provides
def analyze(self):
content = self.content[:]
@@ -483,9 +492,6 @@
parent_interface[self.name] = self
return
- def is_public(self):
- return 'PUBLIC' in self.a.attributes
-
def topyf(self, tab=''):
s = tab + self.tostr() + '\n'
s += HasImplicitStmt.topyf(self, tab=tab+' ')
@@ -499,12 +505,11 @@
class SubProgramStatement(BeginStatement, ProgramBlock,
HasImplicitStmt, HasAttributes,
HasUseStmt,
- HasVariables, HasTypeDecls
+ HasVariables, HasTypeDecls, AccessSpecs
):
"""
[ <prefix> ] <FUNCTION|SUBROUTINE> <name> [ ( <args> ) ] [ <suffix> ]
"""
- known_attributes = ['PUBLIC', 'PRIVATE']
a = AttributeHolder(internal_subprogram = {})
@@ -596,12 +601,12 @@
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
+ #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
@@ -612,6 +617,7 @@
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'
@@ -653,6 +659,42 @@
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):
@@ -936,7 +978,7 @@
match = re.compile(r'end\s*type\s*\w*\Z', re.I).match
blocktype = 'type'
-class Type(BeginStatement, HasVariables, HasAttributes):
+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> )
@@ -1053,6 +1095,7 @@
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'
Modified: trunk/numpy/f2py/lib/parser/statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/statements.py 2006-10-11 00:39:23 UTC (rev 3306)
+++ trunk/numpy/f2py/lib/parser/statements.py 2006-10-11 11:25:02 UTC (rev 3307)
@@ -580,13 +580,14 @@
return tab + clsname
def analyze(self):
- clsname = self.__class__.__name__.upper()
+ clsname = self.__class__.__name__
+ l = getattr(self.parent.a, clsname.lower() + '_id_list')
if self.items:
for name in self.items:
- var = self.get_variable(name)
- var.update(clsname)
+ if name not in l: l.append(name)
else:
- self.parent.update_attributes(clsname)
+ if '' not in l:
+ l.append('')
return
class Public(Access):
Modified: trunk/numpy/f2py/lib/parser/typedecl_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/typedecl_statements.py 2006-10-11 00:39:23 UTC (rev 3306)
+++ trunk/numpy/f2py/lib/parser/typedecl_statements.py 2006-10-11 11:25:02 UTC (rev 3307)
@@ -289,6 +289,12 @@
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)
@@ -302,6 +308,9 @@
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
More information about the Numpy-svn
mailing list