Skip to content

Commit

Permalink
BF in variables, better handling of exceptions, version 0.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastienRietteMTO committed Nov 7, 2024
1 parent 999a259 commit 90c5f13
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 87 deletions.
2 changes: 1 addition & 1 deletion src/pyfortool/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
FORTRAN files to apply source-to-source transformations.
"""

__version__ = "0.2.0"
__version__ = "0.2.1"

# NAMESPACE should be defined first
NAMESPACE = 'http://fxtran.net/#syntax'
Expand Down
36 changes: 17 additions & 19 deletions src/pyfortool/scripting.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,27 @@ def task(filename):
allArgs, orderedOptions = allFileArgs[filename]
try:
# Opening and reading of the FORTRAN file
pft = PYFT(filename, filename, parser=allArgs.parser,
parserOptions=getParserOptions(allArgs), verbosity=allArgs.logLevel,
wrapH=allArgs.wrapH,
enableCache=allArgs.enableCache)

# apply the transformation in the order they were specified
for arg in orderedOptions:
logging.debug('Applying %s on %s', arg, filename)
applyTransfo(pft, arg, allArgs,
filename if filename == allArgs.plotCentralFile else None)
logging.debug(' -> Done')

# Writing
if not allArgs.dryRun:
pft.write()

# Closing and reporting
pft.close()
with PYFT(filename, filename, parser=allArgs.parser,
parserOptions=getParserOptions(allArgs), verbosity=allArgs.logLevel,
wrapH=allArgs.wrapH,
enableCache=allArgs.enableCache) as pft:

# apply the transformation in the order they were specified
for arg in orderedOptions:
logging.debug('Applying %s on %s', arg, filename)
applyTransfo(pft, arg, allArgs,
filename if filename == allArgs.plotCentralFile else None)
logging.debug(' -> Done')

# Writing
if not allArgs.dryRun:
pft.write()

# Reporting
return (0, filename)

except Exception as exc: # pylint: disable=broad-except
logging.error("The following error has occurred in the file %s", filename)
PYFT.unlockFile(filename, silence=True)
traceback.print_exception(exc, file=sys.stdout)
sys.stdout.flush()
return (1, filename)
Expand Down
144 changes: 77 additions & 67 deletions src/pyfortool/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -1442,85 +1442,95 @@ def insertInArgList(varName, varNameToUse, pos, callFuncStmt):
if len(self.path.split('/')) == 1:
filename, scopePathInterface = self.tree.findScopeInterface(self.path)
if filename is not None:
if self.getFileName() == os.path.normpath(filename):
# interface declared in same file
xml = self.mainScope
pft = None
else:
pft = pyfortool.pyfortoolconservativePYFT(
filename, parser, parserOptions, wrapH, tree=self.tree,
clsPYFT=self._mainScope.__class__)
xml = pft
scopeInterface = xml.getScopeNode(scopePathInterface)
varInterface = scopeInterface.varList.findVar(varName, exactScope=True)
if varInterface is None:
scopeInterface.addVar([[scopePathInterface, varName, declStmt, pos]])
if moduleVarList is not None:
# Module variables must be added when var is added
xml.addModuleVar([(scopePathInterface, moduleName, moduleVarNames)
for (moduleName,
moduleVarNames) in moduleVarList])
if pft is not None:
pft.write()
pft.close()

if var is None and self.path not in stopScopes:
# We must propagates upward
# scopes calling the current scope
for scopePathUp in self.tree.calledByScope(self.path):
if scopePathUp in stopScopes or self.tree.isUnderStopScopes(scopePathUp,
stopScopes):
# We are on the path to a scope in the stopScopes list, or scopePathUp is
# one of the stopScopes
# can be defined several times?
for filename in self.tree.scopeToFiles(scopePathUp):
pft = None
try:
if self.getFileName() == os.path.normpath(filename):
# Upper scope is in the same file
# interface declared in same file
xml = self.mainScope
pft = None
else:
pft = pyfortool.pyfortool.conservativePYFT(
filename, parser, parserOptions, wrapH, tree=self.tree,
clsPYFT=self._mainScope.__class__)
xml = pft
scopeUp = xml.getScopeNode(scopePathUp)
# Add the argument and propagate upward
scopeUp.addArgInTree(
varName, declStmt, pos,
stopScopes, moduleVarList, otherNames,
parser=parser, parserOptions=parserOptions,
wrapH=wrapH)
# Add the argument to calls (subroutine or function)
name = self.path.split('/')[-1].split(':')[1].upper()
isCalled = False
varNameToUse = varName
if otherNames is not None:
vOther = [scopeUp.varList.findVar(v, exactScope=True)
for v in otherNames]
vOther = [v for v in vOther if v is not None]
if len(vOther) > 0:
varNameToUse = vOther[-1]['n']
if self.path.split('/')[-1].split(':')[0] == 'sub':
# We look for call statements
for callStmt in scopeUp.findall('.//{*}call-stmt'):
callName = n2name(callStmt.find('./{*}procedure-designator/' +
'{*}named-E/{*}N')).upper()
if callName == name:
insertInArgList(varName, varNameToUse, pos, callStmt)
isCalled = True
else:
# We look for function use
for funcCall in scopeUp.findall(
'.//{*}named-E/{*}R-LT/{*}parens-R/' +
'{*}element-LT/../../..'):
funcName = n2name(funcCall.find('./{*}N')).upper()
if funcName == name:
insertInArgList(varName, varNameToUse, pos, funcCall)
isCalled = True
scopeInterface = xml.getScopeNode(scopePathInterface)
varInterface = scopeInterface.varList.findVar(varName, exactScope=True)
if varInterface is None:
scopeInterface.addVar([[scopePathInterface, varName,
declStmt, pos]])
if moduleVarList is not None:
# Module variables must be added when var is added
xml.addModuleVar(
[(scopePathInterface, moduleName, moduleVarNames)
for (moduleName, moduleVarNames) in moduleVarList])
if pft is not None:
pft.write()
finally:
if pft is not None:
pft.close()

if var is None and self.path not in stopScopes:
# We must propagates upward
# scopes calling the current scope
for scopePathUp in self.tree.calledByScope(self.path):
if scopePathUp in stopScopes or self.tree.isUnderStopScopes(scopePathUp,
stopScopes):
# We are on the path to a scope in the stopScopes list, or scopePathUp is
# one of the stopScopes
# can be defined several times?
for filename in self.tree.scopeToFiles(scopePathUp):
pft = None
try:
if self.getFileName() == os.path.normpath(filename):
# Upper scope is in the same file
xml = self.mainScope
pft = None
else:
pft = pyfortool.pyfortool.conservativePYFT(
filename, parser, parserOptions, wrapH,
tree=self.tree,
clsPYFT=self._mainScope.__class__)
xml = pft
scopeUp = xml.getScopeNode(scopePathUp)
# Add the argument and propagate upward
scopeUp.addArgInTree(
varName, declStmt, pos,
stopScopes, moduleVarList, otherNames,
parser=parser, parserOptions=parserOptions,
wrapH=wrapH)
# Add the argument to calls (subroutine or function)
name = self.path.split('/')[-1].split(':')[1].upper()
isCalled = False
varNameToUse = varName
if otherNames is not None:
vOther = [scopeUp.varList.findVar(v, exactScope=True)
for v in otherNames]
vOther = [v for v in vOther if v is not None]
if len(vOther) > 0:
varNameToUse = vOther[-1]['n']
if self.path.split('/')[-1].split(':')[0] == 'sub':
# We look for call statements
for callStmt in scopeUp.findall('.//{*}call-stmt'):
callName = n2name(callStmt.find(
'./{*}procedure-designator/{*}named-E/{*}N')).upper()
if callName == name:
insertInArgList(varName, varNameToUse, pos, callStmt)
isCalled = True
else:
# We look for function use
for funcCall in scopeUp.findall(
'.//{*}named-E/{*}R-LT/{*}parens-R/' +
'{*}element-LT/../../..'):
funcName = n2name(funcCall.find('./{*}N')).upper()
if funcName == name:
insertInArgList(varName, varNameToUse, pos, funcCall)
isCalled = True
if pft is not None:
pft.write()
finally:
if pft is not None:
pft.close()

if isCalled:
# We must check in the scope (or upper scopes) if an interface
# block declares the routine
Expand Down

0 comments on commit 90c5f13

Please sign in to comment.