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 _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 _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 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 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 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 _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 _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 _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 __init__(self, parent=None, fmod=None): 'create a unit' self.cmnt = None self.uinfo = None self.decls = [] self.execs = [] self.contains = [] self.ulist = [] self.end = [] self.parent = parent if parent: self.nestLevel = parent.nestLevel + 1 else: self.nestLevel = 0 self.symtab = Symtab(_symtab_of(parent)) self.fmod = fmod self._in_iface = None # this would be set to an InterfaceInfo instance if we are in an interface self._in_drvdType = None # this would be set to the name of the derived type being processed self._drvdTypeDefaultAccess = None # this would be set for access while the derived type is being processed self._in_functionDecl = None # this will be set to the FunctionDeclStmt if a function is being processed self._in_subroutineDecl = None # this will be set to the SubroutineDeclStmt if a subroutine is being processed DebugManager.debug('new unit created: ' + str(self) + ', new symtab being created = ' + str(self.symtab))
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
def _processParameterStmt(aParameterStmt, curr): localSymtab = curr.val.symtab DebugManager.debug('[Line ' + str(aParameterStmt.lineNumber) + ']: stmt2unit._processParameterStmt(' + str(aParameterStmt) + ') with symbol table ' + str(localSymtab)) for aNamedParam in aParameterStmt.namedParamList: try: theSymtabEntry = localSymtab.lookup_name_local(aNamedParam[0]) if theSymtabEntry: DebugManager.debug( '\tvariable "' + aNamedParam[0] + '" already present in local symbol table as ' + theSymtabEntry.debug(aNamedParam[0])) theSymtabEntry.enterConstInit(aNamedParam[2]) else: # try implicit typing implicitLocalType = localSymtab.implicit[aNamedParam[0][0]] if implicitLocalType: # we handle the error condition below theSymtabEntry = SymtabEntry( SymtabEntry.VariableEntryKind(), type=implicitLocalType) DebugManager.warning( sys._getframe().f_code.co_name + ' implicit typing: ' + str(implicitLocalType) + ' ' + str(aNamedParam), aParameterStmt.lineNumber, DebugManager.WarnType.implicit) theSymtabEntry.enterConstInit(aNamedParam[2]) else: raise SymtabError( "Parameter statement uses a variable not found in symtab", symbolName=aNamedParam[0], lineNumber=aParameterStmt.lineNumber) except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or aParameterStmt.lineNumber e.symbolName = e.symbolName or aNamedParam[0] raise e
def enterType(self, newType, localSymtab): DebugManager.debug('\t\t' + sys._getframe().f_code.co_name + ': entering type ' + str(newType) + ' for ' + self.debug()) if not newType: raise SymtabError(sys._getframe().f_code.co_name + ': newType is None!', entry=self) if (self.typetab_id and (not (globalTypeTable.lookupTypeId(self.typetab_id).isExternal() and isinstance(self.entryKind, self.SubroutineEntryKind)))): # assume a name clash raise SymtabError( sys._getframe().f_code.co_name + ': name clash because the declaration for this symbol conflicts with an earlier declaration using the same name', entry=self) if isinstance(self.entryKind, self.ProcedureEntryKind): DebugManager.debug( '\t\t' + sys._getframe().f_code.co_name + ': entering type information tells us that this procedure is a function)' ) self.entryKind = self.FunctionEntryKind() newStmt = newType[0](newType[1], [], []) self.typetab_id = globalTypeTable.getType(newStmt, localSymtab)