def _beginDrvdTypeDefn(aDrvdTypeDefn, curr): 'derived type definition -- record type in symbol table and set the name on the unit' localSymtab = curr.val.symtab theSymtabEntry = localSymtab.lookup_name_local(aDrvdTypeDefn.name) access = None # DrvdTypeDefn currently cannot parse qualifiers curr.val._in_drvdType = aDrvdTypeDefn.name if theSymtabEntry: # already in symtab, shouldn't happen theSymtabEntry.enterEntryKind( SymtabEntry.DerivedTypeEntryKind(aDrvdTypeDefn.base_type)) else: newSymtabEntry = SymtabEntry(SymtabEntry.DerivedTypeEntryKind( aDrvdTypeDefn.base_type), dimensions=None, length=None, origin='local', access=access) typetab_id = globalTypeTable.enterNamedType(curr.val._in_drvdType, curr.val.symtab) newSymtabEntry.typetab_id = typetab_id DebugManager.debug('defn "' + str(aDrvdTypeDefn) + '" NOT already present in symbol table => adding ' + str(newSymtabEntry.debug(aDrvdTypeDefn.name))) localSymtab.enter_name(aDrvdTypeDefn.name, newSymtabEntry) # add to type table & set typetab_id return aDrvdTypeDefn
def setCanonFlags(config): setPrePostFlags(config) # configure forward/reverse mode if config.mode: if config.mode[0] == 'f': UnitCanonicalizer.setHoistConstantsFlag(False) UnitCanonicalizer.setHoistStringsFlag(False) elif config.mode[0] == 'r': UnitCanonicalizer.setHoistConstantsFlag(True) UnitCanonicalizer.setHoistStringsFlag(False) # set symtab type defaults if config.r8: Symtab.setTypeDefaults((fs.DoubleStmt, []), (fs.IntegerStmt, [])) if config.removeFunction: UnitCanonicalizer.setKeepFunctionDef(False) if config.hoistConstantsFlag: UnitCanonicalizer.setHoistConstantsFlag(config.hoistConstantsFlag) if config.hoistStringsFlag: UnitCanonicalizer.setHoistStringsFlag(config.hoistStringsFlag) if config.subroutinizeIntegerFunctions: UnitCanonicalizer.setSubroutinizeIntegerFunctions(True) if config.keepGoing: CanonError.keepGoing() if config.warn: DebugManager.warnOnlyOn(config.warn) if config.progress: DebugManager.dumpProgress() if config.includePaths: Ffile.setIncludeSearchPath(config.includePaths) if config.nonStandard: useNonStandard(config.nonStandard) if (config.overloading): UnitCanonicalizer.setOverloadingMode()
def updateTypeDecl(aDecl, outParam, declList): DebugManager.debug(10*'-'+'>'+'called function2subroutine.updateTypeDecl ' \ + 'on declaration statement "'+str(aDecl)+'",' \ +' outParam = "'+str(outParam)+'",' \ +' declList = "'+str(declList)+'"') resultDeclCreated = False newDecl = None declCopy = copy.deepcopy(aDecl) if (len(declCopy.decls) == 1) and \ updateResultDecl(declCopy.get_decls()[0],outParam): newDecl = createTypeDecl(declCopy.kw, declCopy.get_mod(), declCopy.get_attrs(), outParam, declCopy.lead) declCopy = None resultDeclCreated = True else: for decl in declCopy.get_decls(): if updateResultDecl(decl, outParam): # deep copy attrs so declCopy attrs aren't modified newDecl = createTypeDecl(declCopy.kw, declCopy.get_mod(), fe.copyExp(declCopy.get_attrs()), outParam, declCopy.lead) declCopy.decls.remove(decl) declCopy.modified = True resultDeclCreated = True return (declCopy, newDecl, resultDeclCreated)
def _module_exit(stmt, cur): '''exit a module ''' DebugManager.debug('[Line ' + str(stmt.lineNumber) + ']: ' + sys._getframe().f_code.co_name + ' for ' + str(stmt)) cur.val.symtab.markTypesAsReferenced(True) return stmt
def replicateEntry(self, aKey, theOrigin, newName, otherSymtab, replicatingUp=False): ''' create and return a new symbol table entry that is for use in another context we do not set the access attribute from theOrigin here because the access is determined by the new context the entry is added under otherName to newSymtab ''' theLocalEntry = self.ids[aKey] theNewEntry = SymtabEntry(theLocalEntry.entryKind) # set the type theNewEntry.typetab_id = theLocalEntry.typetab_id # set the dimensions theNewEntry.dimensions = theLocalEntry.dimensions # set the length theNewEntry.length = theLocalEntry.length # set the constInit theNewEntry.constInit = theLocalEntry.constInit # set the origin theNewEntry.updateOrigin(theOrigin) # keep a ref to the same generic Info, arg list theNewEntry.genericInfo = theLocalEntry.genericInfo theNewEntry.specificFormalArgs = theLocalEntry.specificFormalArgs otherSymtab.enter_name(newName, theNewEntry) DebugManager.debug(sys._getframe().f_code.co_name + ': original < ' + theLocalEntry.debug(aKey) + ' > replicated as < ' + theNewEntry.debug(newName) + ' >') return theNewEntry
def _endProcedureUnit(anEndProcedureStmt, cur): ''' called for function/subroutine end statements within an interface block ''' if cur.val._in_iface._in_procedureFuncDecl: theSymtabEntry = cur.val.symtab.lookup_name( cur.val._in_iface._in_procedureFuncDecl.name) if (theSymtabEntry.typetab_id is None and cur.val._in_iface._in_procedureFuncDecl.result): # try to get the tupe from the result symbol theResultEntry = cur.val.symtab.lookup_name( cur.val._in_iface._in_procedureFuncDecl.name) if (theResultEntry): theSymtabEntry.copyAndEnterType(theResultEntry.typetab_id) cur.val._in_iface._in_procedureFuncDecl = None if cur.val.symtab.parent: DebugManager.debug('[Line '+str(anEndProcedureStmt.lineNumber)+']: stmt2unit._endProcedureUnit:' \ +' called on "'+str(anEndProcedureStmt)+'"' \ +' ACTION: on unit '+str(cur.val)+' reverting from symtab "'+str(cur.val.symtab)+'"' \ +' to parent symtab "'+str(cur.val.symtab.parent)+'"') cur.val.symtab = cur.val.symtab.parent else: raise SymtabError('stmt2unit._endProcedureUnit('+str(anEndProcedureStmt)+'):' \ +' cannot revert from symtab "'+str(cur.val.symtab)+'"' \ +' to parent symtab, because there is no parent symtab.', symbolName=None, entry=None, lineNumber=anEndProcedureStmt.lineNumber) return anEndProcedureStmt
def _is_stmt_fn(s, cur): 'determine if assignment s is a statement function, based on "unit" symtab' DebugManager.debug('checking assignment ' + str(s) + ' for stmt fn') lhs = s.lhs look = cur.val.symtab.lookupDimensions return isinstance(lhs, fe.App) and isinstance(lhs.head, str) and not look(lhs.head)
def _endInterface(anEndInterfaceStmt, cur): # get all the procedurenames from the mock symtab... mockSymtab = cur.val.symtab if (cur.val._in_iface.name): ifName = cur.val._in_iface.name cur.val.symtab = cur.val.symtab.parent genericSymtabEntry = cur.val.symtab.lookup_name(ifName) for name in mockSymtab.ids.keys(): try: specificSymtabEntry = cur.val.symtab.lookup_name(name) if not specificSymtabEntry: specifcSymtabEntry = SymtabEntry( SymtabEntry.ProcedureEntryKind()) cur.val.symtab.enter_name(name, specifcSymtabEntry) DebugManager.debug( '\tmodule procedure NOT already present in symbol table -- adding ' + specifcSymtabEntry.debug(name)) else: DebugManager.debug( '\tmodule procedure already has SymtabEntry' + specificSymtabEntry.debug(name)) # if the entry has a type, we know it's a function newEntryKind = specificSymtabEntry.typetab_id and SymtabEntry.FunctionEntryKind \ or SymtabEntry.ProcedureEntryKind specificSymtabEntry.enterEntryKind(newEntryKind()) genericSymtabEntry.addResolveName(name, specifcSymtabEntry) except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or aProcedureStmt.lineNumber e.symbolName = e.symbolName or aProcedureName raise e
def lookupTypeId(self, typeid): '''check for typeid in the type table''' DebugManager.debug('Typetab.lookupTypeId called on "' + str(typeid) + '"') if typeid in self.ids: return self.ids[typeid] else: return None
def _generic_exit(stmt, cur): '''exit something - check if it is a module ''' DebugManager.debug('[Line ' + str(stmt.lineNumber) + ']: ' + sys._getframe().f_code.co_name + ' for ' + str(stmt)) if (isinstance(cur.val.uinfo, fs.ModuleStmt)): return _module_exit(stmt, cur) return stmt
def updateResultDecl(decl, outParam): DebugManager.debug(10*'-'+'>'+'called function2subroutine.updateResultDecl ' \ + 'on declaration statement "'+str(decl)+'",' \ +' outParam = "'+str(outParam)+'"') if (str(outParam) == decl) or \ (hasattr(decl,'lhs') and (str(outParam) == decl.lhs)): return True else: return False
def createResultDecl(functionStmt, outParam): DebugManager.debug(10*'-'+'>'+'called function2subroutine.createResultDecl ' \ + 'on function statement "'+str(functionStmt)+'"' \ +' with out parameter "'+str(outParam)+'"') if functionStmt.ty is not None: (type_name, mod) = functionStmt.ty newDecl = createTypeDecl(type_name.kw, mod, [], outParam, functionStmt.lead) return newDecl return None
def enterDimensions(self, newDimensions): DebugManager.debug('\t\tSymtab.enterDimensions: called on ' + str(self) + ' and setting dimensions to ' + str(newDimensions)) if self.dimensions and (self.dimensions != newDimensions): raise SymtabError( 'SymtabEntry.enterDimensions: Error -- current dimensions "' + str(self.dimensions) + '" and new dimensions "' + str(newDimensions) + '" conflict!', entry=self) self.dimensions = newDimensions
def getType(self, theType, localSymtab): '''look up the given type decl in the type table, or add it if necessary, and return the typeid''' DebugManager.debug('Typetab.getType called on "' + str(theType) + '"') if isinstance(theType, UPClassStmt): # unlimited polymorphic entity=> not declared to have a type return None typeid = self.lookupType(theType, localSymtab) if not typeid: newType = self.__enterNewType(theType, localSymtab) self.currentUnitTypeEntries.add(newType) return newType return typeid
def _unit_exit(self, cur): '''exit a subroutine or function ''' DebugManager.debug('[Line ' + str(self.lineNumber) + ']: stmt2unit._unit_exit() for ' + str(self)) parentSymtabEntry = None theSymtabEntry = None theArgs = None if cur.val._in_functionDecl: theSymtabEntry = cur.val.symtab.lookup_name( cur.val._in_functionDecl.name) if cur.val.symtab.parent: parentSymtabEntry = cur.val.symtab.parent.lookup_name( cur.val._in_functionDecl.name) theArgs = cur.val._in_functionDecl.args if (theSymtabEntry.typetab_id is None and cur.val._in_functionDecl.result): # try to get the type from the result symbol theResultEntry = cur.val.symtab.lookup_name( cur.val._in_functionDecl.result) if (theResultEntry): theSymtabEntry.copyAndEnterType(theResultEntry.typetab_id) if parentSymtabEntry: # update the copy in the parent parentSymtabEntry.copyAndEnterType( theResultEntry.typetab_id) else: if parentSymtabEntry: # update the copy in the parent parentSymtabEntry.copyAndEnterType(theSymtabEntry.typetab_id) cur.val._in_functionDecl = None if cur.val._in_subroutineDecl: theSymtabEntry = cur.val.symtab.lookup_name( cur.val._in_subroutineDecl.name) if cur.val.symtab.parent: parentSymtabEntry = cur.val.symtab.parent.lookup_name( cur.val._in_subroutineDecl.name) theArgs = cur.val._in_subroutineDecl.args cur.val._in_subroutineDecl = None # handle the arguments list: theSymtabEntry.specificFormalArgs = FormalArgs() if parentSymtabEntry: parentSymtabEntry.specificFormalArgs = FormalArgs() for pos, arg in enumerate(theArgs): argSymtabEntry = cur.val.symtab.lookup_name(arg) if (not argSymtabEntry): argSymtabEntry = SymtabEntry(SymtabEntry.GenericEntryKind()) cur.val.symtab.enter_name(arg, argSymtabEntry) argSymtabEntry.origin = "dummy" theSymtabEntry.specificFormalArgs.args[arg] = (pos, argSymtabEntry) if (parentSymtabEntry): parentSymtabEntry.specificFormalArgs.args[arg] = ( pos, copy.deepcopy(cur.val.symtab.lookup_name(arg))) return self
def _use_module(aUseStmt, cur): ''' incorporate the used module symbol table into the current unit symbol table issue a warning if the module has not been seen yet ''' DebugManager.debug('[Line ' + str(aUseStmt.lineNumber) + ']: stmt2unit._use_module() for ' + str(aUseStmt) + ': with symtab ' + str(cur.val.symtab) + ' and parent symtab ' + str(cur.val.symtab.parent)) module_unit = cur.module_handler.get_module(aUseStmt.moduleName) if module_unit: DebugManager.debug('updating ' + str(cur.val.symtab) + ') with module "' + aUseStmt.moduleName + '", which has unit ' + str(module_unit), newLine=False) try: if isinstance(aUseStmt, fs.UseAllStmt): DebugManager.debug(' where we are using ALL') cur.val.symtab.update_w_module_all(module_unit, aUseStmt.renameList) elif isinstance(aUseStmt, fs.UseOnlyStmt): DebugManager.debug(' where we are using ONLY ' + str(aUseStmt.onlyList)) cur.val.symtab.update_w_module_only(module_unit, aUseStmt.onlyList) except KeyError, e: raise SymtabError('KeyError for key "'+str(e)+'"' \ +' while updating '+cur.val.symtab.debug() \ +' according to use statement "'+str(aUseStmt)+'"', symbolName=str(e), entry=None, lineNumber=aUseStmt.lineNumber)
def getBaseTypeId(self): 'return the id for the base type of the pointer, allocatable, or array entry kind' DebugManager.debug('TypetabEntry.getBaseTypeId called on type: ' + self.debug()) if isinstance(self.entryKind, TypetabEntry.ArrayEntryKind): return self.entryKind.typetab_id elif isinstance(self.entryKind, TypetabEntry.ArrayPointerEntryKind): return self.entryKind.getArrayTypeEntry().getBaseTypeId() elif isinstance(self.entryKind, TypetabEntry.BuiltInPointerEntryKind): return self.entryKind.typetab_id elif isinstance(self.entryKind, TypetabEntry.AllocatableEntryKind): return self.entryKind.typetab_id else: return self.typetab_id
def _beginInterface(anInterfaceStmt, cur): if (anInterfaceStmt.name): cur.val.symtab.enter_name( anInterfaceStmt.name, SymtabEntry(SymtabEntry.InterfaceEntryKind())) cur.val._in_iface = InterfaceInfo(anInterfaceStmt.name, cur.val._in_iface) DebugManager.debug('[Line ' + str(anInterfaceStmt.lineNumber) + ']: stmt2unit._beginInterface(' + str(anInterfaceStmt) + ')') if (anInterfaceStmt.name): # collect all the procedurenames in a mock symtab... localSymtab = Symtab(cur.val.symtab) cur.val.symtab = localSymtab # local attribute added on to convey the name to _endInterface return anInterfaceStmt
def markTypeAsReferenced(self, markAlsoAsGlobal): # for checking that all entries in type table are referenced by a symtab entry DebugManager.debug(self.__class__.__name__ + ":" + sys._getframe().f_code.co_name + " for " + self.debug()) if self.typetab_id: aTypeTabEntry = globalTypeTable.lookupTypeId(self.typetab_id) aTypeTabEntry.setReferenced() if markAlsoAsGlobal: aTypeTabEntry.setTypeEntryToGlobal() if (isinstance(self.entryKind, SymtabEntry.InterfaceEntryKind)): for gi in self.genericInfo.resolvableTo.values(): gi.markTypeAsReferenced(markAlsoAsGlobal) for arg in gi.specificFormalArgs.args.values(): arg[1].markTypeAsReferenced(markAlsoAsGlobal)
def _assign2stmtfn(anAssignmentStmt, curr): 'convert assign stmt to stmtfn, and enter in unit symtab' DebugManager.debug('[Line ' + str(anAssignmentStmt.lineNumber) + ']: converting ' + str(anAssignmentStmt) + ' to stmt fn') newStmtFn = fs.StmtFnStmt(anAssignmentStmt.lhs.head, anAssignmentStmt.lhs.args, anAssignmentStmt.rhs, lineNumber=anAssignmentStmt.lineNumber, label=anAssignmentStmt.label, lead=anAssignmentStmt.lead) newStmtFn.rawline = anAssignmentStmt.rawline newSymtabEntry = SymtabEntry(SymtabEntry.StatementFunctionEntryKind(), origin='local') curr.val.symtab.enter_name(anAssignmentStmt.lhs.head, newSymtabEntry) return newStmtFn
def _beginProcedureUnit(aProcedureDeclStmt, cur): ''' called for function/subroutine statements within an interface block ''' localSymtab = Symtab(cur.val.symtab) DebugManager.debug('[Line '+str(aProcedureDeclStmt.lineNumber)+']: stmt2unit._beginProcedureUnit:' \ +' called for '+aProcedureDeclStmt.__class__.__name__+': "'+str(aProcedureDeclStmt)+'"' \ +' changing from current symtab "'+str(cur.val.symtab)+'"' \ +' to local symtab "'+str(localSymtab)+'"') entry = aProcedureDeclStmt.makeSymtabEntry(localSymtab) localSymtab.enter_name(aProcedureDeclStmt.name, entry) cur.val.symtab.enter_name(aProcedureDeclStmt.name, entry) cur.val.symtab = localSymtab if (isinstance(aProcedureDeclStmt, fs.FunctionStmt)): cur.val._in_iface._in_procedureFuncDecl = aProcedureDeclStmt return aProcedureDeclStmt
def convertFunctionOrEntryStmt(theStmt, theUnit): DebugManager.debug( 10 * '-' + '>' + 'called function2subroutine.convertFunctionOrEntryStmt on ' + str(theStmt)) if (not (isinstance(theStmt, fs.FunctionStmt) or isinstance(theStmt, fs.EntryStmt))): raise FunToSubError(sys._getframe().f_code.co_name + ': convertFunctionOrEntryStmt called for ' + str(theStmt)) if theStmt.result is None: outParam = fs._NoInit(theStmt.name.lower()) else: outParam = fs._NoInit(theStmt.result.lower()) args = [] for arg in theStmt.args: symtabEntry = theUnit.symtab.lookup_name(arg) if (symtabEntry and isinstance(symtabEntry.entryKind, SymtabEntry.FunctionEntryKind) and symtabEntry.origin == "dummy"): args.append(fe.copyExp(name_init + arg.lower())) else: args.append(fe.copyExp(arg)) args.append(outParam) name = name_init + theStmt.name.lower() if isinstance(theStmt, fs.FunctionStmt): convertedStmt = fs.SubroutineStmt(name, args, theStmt.qualifiers, lead=theStmt.lead) else: convertedStmt = fs.EntryStmt(name, args, lead=theStmt.lead) global ourConvertedScopedNameList scopedName = '' funUnitParent = theUnit.parent while (funUnitParent): scopedName = funUnitParent.uinfo.name + ':' + scopedName funUnitParent = funUnitParent.parent scopedName += theStmt.name ourConvertedScopedNameList.append(scopedName.lower()) if (wasReferencedBeforeSeen(scopedName)): raise FunToSubError( sys._getframe().f_code.co_name + ': function ' + theStmt.name + ' was referenced before we saw this definition and the reference was not subroutinized; try to move up the definition before the reference' ) return (outParam, convertedStmt)
def _implicit(self, cur): '''update the implicit table ''' alphabet = string.ascii_lowercase for (type_spec, letter_spec) in self.lst: for e in letter_spec: if isinstance( e, fe.Ops ): # something like 'q-t' for which we get Ops('-','q','t') for letter in alphabet[ord(e.a1.lower()) - ord(alphabet[0]):ord(e.a2.lower()) - ord(alphabet[0]) + 1]: cur.val.symtab.implicit[letter] = type_spec else: cur.val.symtab.implicit[e] = type_spec DebugManager.debug('[Line ' + str(self.lineNumber) + ']: stmt2unit._implicit() implicit table is now ' + str(cur.val.symtab.implicit) + str(cur.val.symtab)) return self
def createTypeDecl(type_kw, mod, attrs, outParam, aLead): DebugManager.debug(10*'-'+'>'+'called function2subroutine.createTypeDecl ' \ + 'with type keyword "'+type_kw+'",' \ +' mod = "'+str(mod)+'",' \ +' attrs = "'+str(attrs)+'",' \ +' outParam = "'+str(outParam)+'",'\ +' lead = "'+str(aLead)+'"') newAttrs = attrs # should be deepcopied already, if necessary newAttrs.append(fe.App('intent', ['out'])) # look up the class in the kwBuiltInTypesTbl and invoke the ctor which has the same signature for all type classes if (type_kw in fs.kwBuiltInTypesTbl.keys()): return (fs.kwBuiltInTypesTbl[type_kw])(mod=mod, attrs=newAttrs, decls=[outParam], lead=aLead) else: # must be derived type return fs.DrvdTypeDecl(mod=mod, attrs=newAttrs, decls=[outParam], lead=aLead)
def setSourceProcessingFlags(config): # set outputFormat explicitly if format or output file are supplied by user. # otherwise, outputFormat is set to inputFormat during parsing if config.outputFormat == None: if config.outputFile: ext = os.path.splitext(config.outputFile)[1] config.outputFormat = Ffile.get_format(ext) setOutputFormat(config.outputFormat) elif (config.outputFormat <> 'fixed') and (config.outputFormat <> 'free'): opt.error( "outputFormat option must be specified with either 'fixed' or 'free' as an argument" ) else: setOutputFormat(config.outputFormat) if config.outputLineLength: setOutputLineLength(config.outputLineLength) if config.inputLineLength: setInputLineLength(config.inputLineLength) # set symtab type defaults Symtab.setTypeDefaults((fs.RealStmt, []), (fs.IntegerStmt, [])) # parse info units if config.infoUnitFile: from PyFort.fortUnit import fortUnitIterator for aUnit in fortUnitIterator(config.infoUnitFile, config.inputFormat): # need to parse this so the type information is available, but do not modify or print units pass # set verbosity DebugManager.setVerbose(config.isVerbose) DebugManager.setQuiet(config.noWarnings) DebugManager.setCheck(config.check)
def _processDimensionStmt(aDimensionStmt, curr): localSymtab = curr.val.symtab DebugManager.debug('[Line ' + str(aDimensionStmt.lineNumber) + ']: stmt2unit._processDimensionStmt(' + str(aDimensionStmt) + ') with symbol table ' + str(localSymtab)) for aDimensionSpec in aDimensionStmt.lst: try: theSymtabEntry = localSymtab.lookup_name_local( aDimensionSpec.arrayName) if theSymtabEntry: DebugManager.debug( '\tvariable "' + aDimensionSpec.arrayName + '" already present in local symbol table as ' + theSymtabEntry.debug(aDimensionSpec.arrayName)) theSymtabEntry.enterDimensions(tuple(aDimensionSpec.arraySpec)) else: newSymtabEntry = SymtabEntry(SymtabEntry.VariableEntryKind(), dimensions=tuple( aDimensionSpec.arraySpec), origin='local') DebugManager.debug( '\tvariable "' + aDimensionSpec.arrayName + '" NOT already present in symbol table -- adding ' + newSymtabEntry.debug(aDimensionSpec.arrayName)) localSymtab.enter_name(aDimensionSpec.arrayName, newSymtabEntry) except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or aDimensionStmt.lineNumber e.symbolName = e.symbolName or aDimensionSpec.arrayName raise e
def _processExternalStmt(anExternalStmt, curr): localSymtab = curr.val.symtab DebugManager.debug('[Line ' + str(anExternalStmt.lineNumber) + ']: stmt2unit._processExternalStmt: called on "' + str(anExternalStmt) + '" with localSymtab ' + str(localSymtab)) for aProcedureName in anExternalStmt.procedureNames: try: theSymtabEntry = localSymtab.lookup_name(aProcedureName) if not theSymtabEntry: # first guess - assume it is an external subroutine newSymtabEntry = SymtabEntry( SymtabEntry.SubroutineEntryKind(), typetab_id=globalTypeTable.getType(anExternalStmt, localSymtab), origin='external') localSymtab.enter_name(aProcedureName, newSymtabEntry) DebugManager.debug( '\tprocedure NOT already present in symbol table -- adding ' + newSymtabEntry.debug(aProcedureName)) else: DebugManager.debug('\tprocedure already has SymtabEntry' + theSymtabEntry.debug(aProcedureName)) # if the entry has a type, we know it's a function newEntryKind = theSymtabEntry.typetab_id and SymtabEntry.FunctionEntryKind \ or SymtabEntry.SubroutineEntryKind theSymtabEntry.enterEntryKind(newEntryKind()) except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or anExternalStmt.lineNumber e.symbolName = e.symbolName or aProcedureName raise e
def convertFunctionDecl(aDecl, oldFuncnewSubPairs): DebugManager.debug(10*'-'+'>'+'called function2subroutine.convertFunctionDecl ' \ + 'on declaration statement "'+str(aDecl)+'"' \ +' with oldFuncnewSubPairs = "'+str(oldFuncnewSubPairs)+'"') newDecl = copy.deepcopy(aDecl) modified = False if hasattr(newDecl, "_sons"): # list of attribute names of Decl instances for anAttrName in newDecl.get_sons(): anAttrValue = getattr(newDecl, anAttrName) if isinstance(anAttrValue, list): if isinstance(newDecl, fs.VarAttrib): newAttrValue = [] for anOldNewPair in oldFuncnewSubPairs: for anAttrValuePart in anAttrValue: if (isinstance(anAttrValuePart, str) and anOldNewPair[0].lower() == anAttrValuePart.lower()): newAttrValue.append(anOldNewPair[1]) modified = True break newDecl.set_son(anAttrName, newAttrValue) else: for anOldNewPair in oldFuncnewSubPairs: for anAttrValuePart in anAttrValue: if (isinstance(anAttrValuePart, str) and anOldNewPair[0].lower() == anAttrValuePart.lower()): anAttrValue.remove(anAttrValuePart) anAttrValue.append(anOldNewPair[1]) newDecl.modified = True modified = True break else: # not a list for anOldNewPair in oldFuncnewSubPairs: if (isinstance(anAttrValue, str) and anAttrValue.lower() == anOldNewPair[0].lower()): newDecl.set_son(anAttrName, anOldNewPair[1]) modified = True return (newDecl, modified)
def __rename(self, anExpression, targetEntrySymtab, replicatingUp=False): if isinstance(anExpression, str): origExp = anExpression parentEntry = targetEntrySymtab.lookup_name(anExpression) if replicatingUp: if parentEntry is None: #if there is no entry in the parent symtab, and there is a rename defined, rename to source if anExpression in self.renames.values(): anExpression = self.__renamedToSource(anExpression) #if there is a rename defined in the parent symtab for the mod, sourceToRenamed if anExpression in targetEntrySymtab.renames: anExpression = targetEntrySymtab.__sourceToRenamed( anExpression) #else if mod is not defined in parent, issue warning elif targetEntrySymtab.lookup_name( anExpression) is None: DebugManager.warning( "a SymtabEntry has been replicated up, and modifier '" + str(origExp) + "' has been renamed to its source '" + str(anExpression) + "', which is not defined in the parent context." ) elif anExpression in targetEntrySymtab.renames: anExpression = targetEntrySymtab.__sourceToRenamed( anExpression) elif parentEntry is None and anExpression in targetEntrySymtab.renames: #if there is no entry in the symtab, but there is a rename defined in the target entry symtab, rename anExpression = targetEntrySymtab.__sourceToRenamed( anExpression) elif isinstance(anExpression, App): anExpression.args = map( lambda anArg: self.__rename(anArg, targetEntrySymtab, replicatingUp), anExpression.args) else: raise SymtabError(sys._getframe().f_code.co_name + ': expression' + str(anExpression) + 'is not a string and not an App!') return anExpression
def _setAccess(anAccessStmt, cur): ''' set the access attributes ''' DebugManager.debug('[Line ' + str(anAccessStmt.lineNumber) + ']: stmt2unit._setAccess() for ' + str(anAccessStmt)) accessAttr = anAccessStmt.__class__.kw if (not anAccessStmt.vlist): if (cur.val._in_drvdType): cur.val._drvdTypeDefaultAccess = accessAttr # and process it at the end of rhe derived type definition else: cur.val.symtab.setDefaultAccess(accessAttr) else: for v in anAccessStmt.vlist: if (cur.val._in_drvdType): v = cur.val._in_drvdType + ':' + v theEntry = cur.val.symtab.lookup_name(v) if (theEntry): theEntry.setSpecificAccess(accessAttr) else: # forward access declaration theEntry = SymtabEntry(SymtabEntry.GenericEntryKind(), access=accessAttr) cur.val.symtab.enter_name(v, theEntry) return anAccessStmt