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 _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 _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 _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 _processCommonStmt(aCommonStmt, curr): localSymtab = curr.val.symtab DebugManager.debug('[Line ' + str(aCommonStmt.lineNumber) + ']: ' + sys._getframe().f_code.co_name + ' called on "' + repr(aCommonStmt) + '" with localSymtab ' + localSymtab.debug()) commonTypeId = None updateDeclTypeList = [] for aDecl in aCommonStmt.declList: try: aDeclName = "" if isinstance(aDecl, fe.App): aDeclName = aDecl.head else: aDeclName = aDecl theSymtabEntry = localSymtab.lookup_name(aDeclName) if not theSymtabEntry: # symtab entry will be added by declaration newSymtabEntry = SymtabEntry( SymtabEntry.VariableEntryKind(), origin=Symtab._ourCommonScopePrefix + aCommonStmt.name) localSymtab.enter_name(aDeclName, newSymtabEntry) if isinstance(aDecl, fe.App): newSymtabEntry.enterDimensions(aDecl.args) if commonTypeId: newSymtabEntry.typetab_id = commonTypeId else: updateDeclTypeList.append(newSymtabEntry) DebugManager.debug( '\tcommon variable NOT already present in symbol table -- adding ' + newSymtabEntry.debug(aDeclName)) else: DebugManager.debug( '\tcommon variable already has SymtabEntry' + theSymtabEntry.debug(aDeclName)) theSymtabEntry.enterEntryKind(SymtabEntry.VariableEntryKind()) if isinstance(aDecl, fe.App): theSymtabEntry.enterDimensions(aDecl.args) theSymtabEntry.updateOrigin(Symtab._ourCommonScopePrefix + aCommonStmt.name) commonTypeId = theSymtabEntry.typetab_id except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or aCommonStmt.lineNumber e.symbolName = e.symbolName or aDeclName raise e
def _processProcedureStmt(aProcedureStmt, curr): localSymtab = curr.val.symtab DebugManager.debug('[Line ' + str(aProcedureStmt.lineNumber) + ']: stmt2unit._processProcedureStmt: called on "' + str(aProcedureStmt) + '" with localSymtab ' + str(localSymtab)) for aProcedureName in aProcedureStmt.procedureList: try: theSymtabEntry = localSymtab.lookup_name(aProcedureName) if not theSymtabEntry: newSymtabEntry = SymtabEntry(SymtabEntry.ProcedureEntryKind()) localSymtab.enter_name(aProcedureName, newSymtabEntry) DebugManager.debug( '\t_processProcedureStmt: module procedure NOT already present in symbol table -- adding ' + newSymtabEntry.debug(aProcedureName)) else: DebugManager.debug( '\t_processProcedureStmt: module procedure 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.ProcedureEntryKind theSymtabEntry.enterEntryKind(newEntryKind()) theGenericSymtabEntry = localSymtab.lookup_name( curr.val._in_iface.name) if (theGenericSymtabEntry.genericInfo): if (theGenericSymtabEntry.genericInfo.genericName != curr.val._in_iface.name.lower()): raise SymtabError('mismatched generic name') if (not (aProcedureName in theGenericSymtabEntry. genericInfo.resolvableTo.keys())): theGenericSymtabEntry.genericInfo.resolvableTo[ aProcedureName] = theSymtabEntry else: theGenericSymtabEntry.genericInfo = GenericInfo() theGenericSymtabEntry.genericInfo.genericName = curr.val._in_iface.name.lower( ) theGenericSymtabEntry.genericInfo.resolvableTo[ aProcedureName] = theSymtabEntry 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 _processEntry(self, cur): ''' add the entry name to 1. The local symtab for the object 2. The unit symtab 3. The parent of the unit (if there is one) ''' currentSymtab = cur.val.symtab if (currentSymtab.parent and (self.name in currentSymtab.parent.ids)): # this must be the definition of a previously declared module procedure mpSymTabEntry = currentSymtab.parent.ids[self.name] if (not isinstance(mpSymTabEntry.entryKind, SymtabEntry.ProcedureEntryKind) or mpSymTabEntry.genericInfo is None): raise SymtabError('parent symbol is not a module procedure') entry = SymtabEntry( currentSymtab.lookup_name(cur.val.uinfo.name).entryKind) mpSymTabEntry.entryKind = entry.entryKind mpSymTabEntry.typetab_id = entry.typetab_id entry.genericInfo = mpSymTabEntry.genericInfo currentSymtab.enter_name(self.name, entry) else: entry = SymtabEntry( currentSymtab.lookup_name(cur.val.uinfo.name).entryKind) currentSymtab.enter_name(self.name, entry) DebugManager.debug('[Line ' + str(self.lineNumber) + ']: new unit symtab entry ' + entry.debug(self.name)) if currentSymtab.parent: currentSymtab.replicateEntry(self.name, "local", self.name, currentSymtab.parent, replicatingUp=True) DebugManager.debug('[Line ' + str(self.lineNumber) + ']: new PARENT unit symtab entry (see above)') DebugManager.debug('[Line ' + str(self.lineNumber) + ']: stmt2unit._processEntry() for ' + str(self) + ': with symtab ' + str(currentSymtab) + ' with parent symtab ' + str(currentSymtab.parent)) if (isinstance(self, fs.FunctionStmt)): cur.val._in_functionDecl = self return self
def _processTypedeclStmt(aTypeDeclStmt, curr): 'type declaration -- record type in symbol table' localSymtab = curr.val.symtab newType = (aTypeDeclStmt.__class__, aTypeDeclStmt.mod) newLength = None DebugManager.debug('[Line ' + str(aTypeDeclStmt.lineNumber) + ']: ' + sys._getframe().f_code.co_name + ' for ' + repr(aTypeDeclStmt) + ' with default dimensions ' + str(aTypeDeclStmt.dimension)) access = None inDrvdTypeDefn = curr.val._in_drvdType for anAttribute in aTypeDeclStmt.attrs: if isinstance( anAttribute, str) and anAttribute.lower() in Symtab.ourSpecificAccessKWs: access = anAttribute.lower() for aDecl in aTypeDeclStmt.decls: DebugManager.debug('\tProcessing decl ' + repr(aDecl) + ' ... ', newLine=False) (name, newDimensions) = typesep(aDecl, aTypeDeclStmt.dimension) if inDrvdTypeDefn: name = inDrvdTypeDefn + ":" + name try: # set the length for character statements if (aTypeDeclStmt.kw_str == 'character'): newLength = aTypeDeclStmt.mod and aTypeDeclStmt.mod[0] \ or 1 # extract the name and length for character declarations such as "character foo*7" if (isinstance(aDecl, fs._NoInit) or isinstance(aDecl, fs._AssignInit)): if (isinstance(aDecl.lhs, fe.Ops) and aDecl.lhs.op == '*'): DebugManager.debug( '(recognized as a character statement with asterisk length specification) ... ', newLine=False) name = aDecl.lhs.a1 newLength = aDecl.lhs.a2 theSymtabEntry = localSymtab.lookup_name_local(name) if isinstance(aDecl, fs._AssignInit): theTmpDeclStmt = aTypeDeclStmt.__class__( aTypeDeclStmt.get_mod(), aTypeDeclStmt.get_attrs(), [aDecl.lhs]) else: theTmpDeclStmt = aTypeDeclStmt.__class__( aTypeDeclStmt.get_mod(), aTypeDeclStmt.get_attrs(), [aDecl]) if theSymtabEntry: # already in symtab -> enter new information (taking exception to any conflicts) DebugManager.debug( 'decl "' + str(aDecl) + '" already present in local symbol table as ' + str(theSymtabEntry.debug(name))) theSymtabEntry.enterType(newType, localSymtab) if (theSymtabEntry.dimensions and (newDimensions is None)): theTmpDeclStmt.dimension = theSymtabEntry.dimensions else: theSymtabEntry.enterDimensions(newDimensions) theSymtabEntry.enterLength(newLength) if (isinstance(aDecl, fs._PointerInit) or isinstance(aDecl, fs._AssignInit) and localSymtab.isConstInit(aDecl.rhs)): theSymtabEntry.enterConstInit( localSymtab.getConstInit(aDecl.rhs)) if inDrvdTypeDefn: theSymtabEntry.enterDrvdTypeName(inDrvdTypeDefn) # for function/subroutine entries, also update this information in the parent symbol table if localSymtab.parent and theSymtabEntry.entryKind.__class__ in ( SymtabEntry.FunctionEntryKind, SymtabEntry.SubroutineEntryKind ) and not (theSymtabEntry.origin == 'external'): parentSymtabEntry = localSymtab.parent.lookup_name_local( name) if (not parentSymtabEntry): localSymtab.replicateEntry(name, 'local', name, localSymtab.parent, replicatingUp=True) DebugManager.debug( '[Line ' + str(aTypeDeclStmt.lineNumber) + ']: new PARENT unit symtab entry (see above)') else: localSymtab.augmentParentEntry(theSymtabEntry, parentSymtabEntry, name) DebugManager.debug( '[Line ' + str(aTypeDeclStmt.lineNumber) + ']: updated PARENT unit symtab entry ' + parentSymtabEntry.debug(name)) typetab_id = globalTypeTable.getType(theTmpDeclStmt, localSymtab) theSymtabEntry.typetab_id = typetab_id else: # no symtab entry -> create one if aTypeDeclStmt.parameter: newSymtabEntry = SymtabEntry( SymtabEntry.VariableEntryKind(), type=newType, dimensions=newDimensions, length=newLength, origin='local', access=access) else: newSymtabEntry = SymtabEntry( SymtabEntry.GenericEntryKind(), type=newType, dimensions=newDimensions, length=newLength, origin='local', access=access) if (isinstance(aDecl, fs._PointerInit) or isinstance(aDecl, fs._AssignInit) and localSymtab.isConstInit(aDecl.rhs)): newSymtabEntry.enterConstInit( localSymtab.getConstInit(aDecl.rhs)) elif aTypeDeclStmt.parameter and isinstance( aDecl, fs._AssignInit): newSymtabEntry.enterConstInit(aDecl.rhs) if inDrvdTypeDefn: newSymtabEntry.enterDrvdTypeName(inDrvdTypeDefn) localSymtab.enter_name(name, newSymtabEntry) typetab_id = globalTypeTable.getType(theTmpDeclStmt, localSymtab) newSymtabEntry.typetab_id = typetab_id DebugManager.debug( 'decl "' + str(aDecl) + '" NOT already present in symbol table => adding ' + str(newSymtabEntry.debug(name))) unitSymbolEntry = localSymtab.lookup_name_level(curr.val.name())[0] if (unitSymbolEntry and isinstance(unitSymbolEntry.entryKind, SymtabEntry.FunctionEntryKind) and unitSymbolEntry.genericInfo and unitSymbolEntry.genericInfo.genericName): genericSymbolEntry = localSymtab.lookup_name( unitSymbolEntry.genericInfo.genericName) if (genericSymbolEntry is None): raise SymtabError('cannot find generic ' + unitSymbolEntry.genericInfo.genericName + ' for specific ' + curr.val.name() + ' entry: ' + unitSymbolEntry.debug(curr.val.name())) if (genericSymbolEntry.genericInfo is None or (not curr.val.name().lower() in genericSymbolEntry.genericInfo.resolvableTo)): raise SymtabError( 'no info available for specific ' + curr.val.name() + ' in generic entry: ' + genericSymbolEntry.debug( unitSymbolEntry.genericInfo.genericName)) specificFormalArgs = localSymtab.lookup_name( unitSymbolEntry.genericInfo.genericName ).genericInfo.resolvableTo[curr.val.name().lower()] if (specificFormalArgs is None): raise SymtabError( 'no arguments set for specific ' + curr.val.name() + ' under generic ' + unitSymbolEntry.genericInfo.genericName + ' entry: ' + localSymtab.lookup_name( unitSymbolEntry.genericInfo.genericName).debug( unitSymbolEntry.genericInfo.genericName)) if name.lower() in specificFormalArgs: se = localSymtab.lookup_name_local(name) specificFormalArgs[name.lower()] = (se.typetab_id, se.dimensions) DebugManager.debug('recorded type in ' + str(id(specificFormalArgs)) + str(specificFormalArgs)) except SymtabError, e: # add lineNumber and symbol name to any SymtabError we encounter e.lineNumber = e.lineNumber or aTypeDeclStmt.lineNumber e.symbolName = e.symbolName or name raise e