Пример #1
0
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
Пример #2
0
def _makeFunctionSymtabEntry(aFunctionStmt, localSymtab):
    if aFunctionStmt.ty is not None:
        typeId = globalTypeTable.getType(
            aFunctionStmt.ty[0](aFunctionStmt.ty[1], [], []), localSymtab)
    else:
        typeId = None
    return SymtabEntry(SymtabEntry.FunctionEntryKind(), typetab_id=typeId)
Пример #3
0
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
Пример #4
0
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
Пример #5
0
class C1(TestCase):
    topSE = SymtabEntry(SymtabEntry.GenericEntryKind())
    fooSE = SymtabEntry(SymtabEntry.GenericEntryKind())

    def setUp(self):
        t = Symtab()
        t.enter_name('TOP', C1.topSE)

        ts = Symtab(t)
        ts.enter_name('fOo', C1.fooSE)
        self.ts = ts

    def test1(self):
        'local lookup'
        ts = self.ts
        ae(ts.lookup_name('foo'), C1.fooSE)

    def test2(self):
        'remote lookup'
        ts = self.ts
        ae(ts.lookup_name('top'), C1.topSE)

    def test3(self):
        'no entry'
        ts = self.ts
        a_(not ts.lookup_name('bar'))
Пример #6
0
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
Пример #7
0
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 test4(self):
        'scalar * range w open lbound'
        ae = self.assertEquals

        theTypeId = globalTypeTable.getType(RealStmt([],[],['x']),theSymtab)
        theSymtab.enter_name('x',SymtabEntry(SymtabEntry.VariableEntryKind, type=RealStmt,typetab_id=theTypeId))
        stmt = 'real, dimension(2,3) :: y'
        ps = pps(stmt)
        theTypeId = globalTypeTable.getType(ps,theSymtab)
        theSymtab.enter_name('y', SymtabEntry(SymtabEntry.VariableEntryKind,
                                              type=RealStmt,
                                              dimensions=['2','3'],
                                              typetab_id=theTypeId))
        e1 = ep('x * y(1,:2)')
        ae(str(expressionShape(e1,theSymtab,lineNumber=0)),
           str([Ops(':','1','2')]))
    def test1(self):
        'scalar * subscripted array'
        ae = self.assertEquals

        theTypeId = globalTypeTable.getType(RealStmt([],[],['x']),theSymtab)
        theSymtab.enter_name('x',SymtabEntry(SymtabEntry.VariableEntryKind, type=RealStmt,typetab_id=theTypeId))
        stmt = 'real, dimension(2,3) :: y'
        ps = pps(stmt)
        theTypeId = globalTypeTable.getType(ps,theSymtab)
        theSymtab.enter_name('y', SymtabEntry(SymtabEntry.VariableEntryKind,
                                              type=RealStmt,
                                              dimensions=['2','3'],
                                              typetab_id=theTypeId))
        e1 = ep('x * y(1,:)')
        ae(expressionShape(e1,theSymtab,lineNumber=0),
           ['3'])
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
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
Пример #15
0
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
Пример #16
0
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
Пример #17
0
def _makeSubroutineSymtabEntry(self, localSymtab):
    return SymtabEntry(SymtabEntry.SubroutineEntryKind())
Пример #18
0
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
Пример #19
0
class C1(TestCase):
    topSE = SymtabEntry(SymtabEntry.GenericEntryKind())
    fooSE = SymtabEntry(SymtabEntry.GenericEntryKind())

    def setUp(self):
        self.typetab = Typetab()
        s = Symtab()
        s.enter_name('TOP', C1.topSE)
        ts = Symtab(s)
        ts.enter_name('foo', C1.fooSE)
        self.symtab = ts

    def test1(self):
        '''look up built in type integer'''
        integerStmt = fs.IntegerStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(integerStmt, self.symtab)
        ae(typeid, 5)

    def test2(self):
        '''lookup built in type real'''
        realStmt = fs.RealStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(realStmt, self.symtab)
        ae(typeid, 7)

    def test3(self):
        '''look up built in type double'''
        doubleStmt = fs.DoubleStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(doubleStmt, self.symtab)
        ae(typeid, 8)

    def test4(self):
        '''look up built in type complex'''
        complexStmt = fs.ComplexStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(complexStmt, self.symtab)
        ae(typeid, 9)

    def test5(self):
        '''look up built in type double complex'''
        doubleComplexStmt = fs.DoubleCplexStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(doubleComplexStmt, self.symtab)
        ae(typeid, 10)

    def test6(self):
        '''look up built in type logical'''
        logicalStmt = fs.LogicalStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(logicalStmt, self.symtab)
        ae(typeid, 2)

    def test7(self):
        '''look up built in type character'''
        characterStmt = fs.CharacterStmt([], [], ['foo'])
        typeid = self.typetab.lookupType(characterStmt, self.symtab)
        ae(typeid, 1)

    def test8(self):
        '''test named type entry'''
        drvdType = fs.DrvdTypeDecl(['t'], [], [fs._NoInit('bar')])
        typeid = self.typetab.getType(drvdType, self.symtab)
        ae(typeid, 12)

    def test9(self):
        '''test named type lookup'''
        drvdType = fs.DrvdTypeDecl(['t'], [], [fs._NoInit('bar')])
        typeid1 = self.typetab.getType(drvdType, self.symtab)
        typeid2 = self.typetab.lookupType(drvdType, self.symtab)
        ae(typeid1, typeid2)

    def test10(self):
        '''test array type entry and lookup'''
        arrayStmt = fs.RealStmt([], [fe.App('dimension', [10])], ['foo'])
        typeid1 = self.typetab.getType(arrayStmt, self.symtab)
        typeid2 = self.typetab.lookupType(arrayStmt, self.symtab)
        ae(typeid1, typeid2)

    def test11(self):
        '''test built in type pointer entry and lookup'''
        integerPtrStmt = fs.IntegerStmt([], [
            'pointer',
        ], ['foo'])
        typeid1 = self.typetab.getType(integerPtrStmt, self.symtab)
        typeid2 = self.typetab.lookupType(integerPtrStmt, self.symtab)
        ae(typeid1, self.typetab.type_counter - 1)
        ae(typeid1, typeid2)

    def test12(self):
        '''test named type pointer entry and lookup'''
        drvdType = fs.DrvdTypeDecl(['t'], [], [fs._NoInit('bar')])
        self.typetab.getType(drvdType, self.symtab)
        drvdTypePtr = fs.DrvdTypeDecl(['t'], ['pointer'], [fs._NoInit('foo')])
        typeid1 = self.typetab.getType(drvdTypePtr, self.symtab)
        typeid2 = self.typetab.lookupType(drvdTypePtr, self.symtab)
        ae(typeid1, self.typetab.type_counter - 1)
        ae(typeid1, typeid2)

    def test13(self):
        '''test array type pointer entry and lookup'''
        arrayStmt = fs.RealStmt(
            [], ['pointer', fe.App('dimension', [10])], ['foo'])
        typeid1 = self.typetab.getType(arrayStmt, self.symtab)
        typeid2 = self.typetab.lookupType(arrayStmt, self.symtab)
        ae(typeid1, typeid2)

    def test14(self):
        '''test type equivalence, which matches type, kind & rank'''
        arrayStmt1 = fs.RealStmt([], [fe.App('dimension', [10, 2])], ['foo'])
        arrayStmt2 = fs.RealStmt([], [fe.App('dimension', [10, 4])], ['foo'])
        typeid1 = self.typetab.getType(arrayStmt1, self.symtab)
        typeid2 = self.typetab.getType(arrayStmt2, self.symtab)
        typeEntry1 = self.typetab.lookupTypeId(typeid1)
        typeEntry2 = self.typetab.lookupTypeId(typeid2)
        equivalentBool = self.typetab.equivalence(typeEntry1, typeEntry2)
        ae(True, equivalentBool)