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 _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 _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