⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varmgrc.c

📁 这是DOS系统的源代码,汇编写的,值得看看,对开发操作系统的人员有价值
💻 C
📖 第 1 页 / 共 5 页
字号:
##############################################################################*/

/***
*ReDirect() - unlink entry @ vm_oVarCur, set FVREDIRECT, put vm_oVarTmp in value
*Purpose:
*  'ReDirect' a variable entry, i.e., unlink it from its hash chain, set
*  the FVREDIRECT flag in the entry, and put the offset to the 'real'
*  entry (in vm_oVarTmp) into the value field.
*
*  Redirection is performed whenever an existing entry is made invalid
*  by some new instance of a matching variable, for example, what looked
*  like an array at first encounter might be found to be a FUNCTION at
*  a later encounter - - - all such array entries (in tMV and all tPV's)
*  are redirected to this newly created FUNCTION entry. The scanner
*  can then go through and fix up the pcode for each redirected entry,
*  since we'll put the oVar for the new entry in the redirected entry.
*Entry:
*  vm_fPVCur - module static flag, TRUE if hash table is in tPV, FALSE if tMV.
*  mrsCur.bdVar assumed set up, and if vm_fPVCur is TRUE, prsCur is assumed
*     to be set up, and the oVarHash field to contain an offset into
*     mrsCur.bdVar to the tPV hash table.
*  vm_oVarCur is an offset into mrsCur.bdVar to the entry to be redirected.
*  vm_oVarTmp is an offset into mrsCur.bdVar to the entry it is to be
*     redirected to.
*Exit:
*  none.
*Exceptions:
*  none.
*******************************************************************************/
VOID NEAR ReDirect()
   {
   REG1 var *pVar;                     
   REG2 char *pVarBase = mrsCur.bdVar.pb;
   REG3 ushort *pHash;
   REG4 var *pVarPrev;
   REG5 ushort oHashTmp;

   /*--------------------------------------------------------------------------
   | calculate pointer into hash table to offset to the first entry in the    |
   |  chain; this is just:                                                    |
   |     (base of physical table) + (offset to start of hash table) +         |
   |     (offset into hash table)                                             |
   --------------------------------------------------------------------------*/
   DbAssertIf(vm_fPVCur, prsCur.oVarHash != UNDEFINED)
   pHash = (ushort *)(mrsCur.bdVar.pb +
                     (vm_fPVCur ? 
                           (prsCur.oVarHash + (mkVar.oNam & HASH_PV_NAMMASK)) :
                           (0 + (mkVar.oNam & HASH_MV_NAMMASK))));

   pVar = (var *)(pVarBase + *pHash);           /* point to first entry       */

   if (*pHash == vm_oVarCur)                    /* entry is @ start of chain  */
      *pHash = OHashLinkOf(pVar) & 0xFFFE;      /* unlink first entry         */
   else {
      while ((oHashTmp = OHashLinkOf(pVar) & 0xFFFE) != vm_oVarCur) {
         DbAssert(oHashTmp != 0)                /* better not be end of chain */
         pVar = (var *)(pVarBase + oHashTmp);
         }
      pVarPrev = pVar;                          /* point to entry prior to one
                                                   we wish to unlink          */
      pVar = (var *)(pVarBase + oHashTmp);
      OHashLinkOf(pVarPrev) = OHashLinkOf(pVar);/* unlink the entry           */
      }
   
   /* at this point, pVar points to the entry being redirected                */
   FlagsOf(pVar) |= FVREDIRECT;
   ValueOf(pVar, oMV) = vm_oVarTmp;

   }  /* ReDirect */

/***
*FuncSearch() - search the appropriate hash table for FUNCTION case
*Purpose:
*  Search the appropriate table (tPV or tMV) in the case where we've
*  encountered [DECLARE] FUNCTION.
*Entry:
*  vm_fPVCur - module static flag, TRUE if we're to search tPV, FALSE if tMV.
*  mrsCur.bdVar assumed set up, and if vm_fPVCur is TRUE, prsCur is assumed
*     to be set up, and the oVarHash field is either UNDEFINED (in which
*     case we just return), or contains an offset into mrsCur.bdVar to the 
*     tPV hash table.
*
*  mkVar set up as per MakeVariable (below).
*Exit:
*  FALSE = no error
*  otherwise, the same error code is returned as described for MakeVariable,
*     below.
*  If no error is returned, then the static vm_fVarFound indicates success or
*     failure. 
*  If vm_fVarFound == TRUE, vm_oVarCur is set to the offset into mrsCur.bdVar to
*     the found variable entry, and vm_pVarCur points to the entry.
*  If an existing entry has been converted to a FUNCTION entry by the search,
*     the static flag fConvtdToFun will be set TRUE.
*Exceptions:
*  none.
*******************************************************************************/
ushort NEAR FuncSearch()
   {
   REG1 var *pVar;                     
   REG2 char *pVarBase = mrsCur.bdVar.pb;

   /*--------------------------------------------------------------------------
   | calculate offset into mrsCur.bdVar to first entry in appropriate hash    |
   |  chain; this is the contents of:                                         |
   |     (base of physical table) + (offset to start of hash table) +         |
   |     (offset into hash table)                                             |
   --------------------------------------------------------------------------*/
   REG3 ushort oVar = *(ushort *)(mrsCur.bdVar.pb +
                     (vm_fPVCur ? 
                           (prsCur.oVarHash + (mkVar.oNam & HASH_PV_NAMMASK)) :
                           (0 + (mkVar.oNam & HASH_MV_NAMMASK))));
   fConvtdToFun = vm_fVarFound = FALSE;      /* initialize                    */

   if ((oVar == 0) || (vm_fPVCur && (prsCur.oVarHash == UNDEFINED)))
      return(FALSE);                         /* empty hash chain - not found  */

   for (pVar = (var *)(pVarBase + oVar);     /* loop init.                    */
        pVar != (var *)pVarBase;             /* oVar = 0 ==> end of chain     */
        pVar = (var *)(pVarBase + (OHashLinkOf(pVar) & 0xFFFE))) {   
                                             /* loop re-init   */
      if (mkVar.oNam != ONamOf(pVar))
         continue;
      if (!(FlagsOf(pVar) & FVFUN)) {
         if (FlagsOf(pVar) & (FVFORMAL | FVCOMMON | FVSTATIC | FVCONST |
                                                      FVSHARED | FVDECLDVAR))
            return (PRS_ER_RE | ER_DD);
         if (OTypOf(pVar) != mkVar.oTyp)
            if (FlagsOf(pVar) & FVEVEREXPLICIT)
               return (PRS_ER_RE | ER_DD);
            else {
               DbAssert(mkVar.oTyp <= ET_MAX)
               FlagsOf(pVar) = (FlagsOf(pVar) & ~ 0x07 | mkVar.oTyp);
               }
         fConvtdToFun = TRUE;                /* set flag if converting to FUN */
         ValueOf(pVar, oPrs) = PrsRef(mkVar.oNam, PT_FUNCTION, mkVar.oTyp);
                                             /* set value field               */
         DbAssert(ValueOf(pVar, oPrs) != UNDEFINED)
                                             /* error if prs not found        */
         FlagsOf(pVar) |= (FVFUN | FVDECLDVAR | FVEVEREXPLICIT);
         FlagsOf(pVar) &= ~FVARRAY;
         }  /* if entry flag FVFUN is FALSE */
      if (vm_fVarFound)                      /* is this a second match in the */
         return(PRS_ER_RE | ER_DD);          /*    same chain? If so error    */
      /* now, note that we've found a match and save this oVar, but keep
         looking, in case there's another matching name, which would trigger
         the above error ...                                                  */
      vm_fVarFound = TRUE;
      vm_oVarCur = (char *)pVar - mrsCur.bdVar.pb;
      vm_pVarCur = pVar;
      }  /* while not at end of hash chain */
   return (FALSE);                           /* no errors                     */
   }  /* FuncSearch */

/***
*ModSharedChk() - check tPV for matches to a new module SHARED variable
*Purpose:
*  Check the tPV (of prsCur) for a match to a given (new) module SHARED
*  variable. If a match is found, redirect it, i.e., unlink the tPV entry
*  from its hash chain, set the FVREDIRECT flag in it, and place
*  the offset to the new module SHARED variable in its value field.
*
*  Note: This is now optimized based on the knowledge that it's ONLY used
*        used for FUNCTION declarations or definitions.
*  
*Entry:
*  vm_oVarTmp = offset into mrsCur.bdVar to a new module SHARED variable.
*  vm_fPVCur assumed to be TRUE
*  other inputs set up as for FuncSearch (above)
*Exit:
*  TRUE - no error.
*  FALSE - some error from FuncSearch, assumed to be a rude edit case
*           (so we can count on mrsCur.bdVar being tossed out).
*           In this event, the static variable 'errVal' will be contain the 
*           error return, and (non-RELEASE only) the mkVar.flags2 bit
*           MV_fTrashTable will be set.
*Exceptions:
*  none.
*******************************************************************************/
boolean ModSharedChk()
   {
   if (errVal = FuncSearch()) {
      return(FALSE);                /* some error found - quit looking        */
      }
   if (vm_fVarFound)
      ReDirect();
   return (TRUE);
   }  /* ModSharedChk */

/***
*GetDefaultType - given the logical 1st char of a var name,  get default oTyp
*Purpose:
*  Given the logical first char of a name, return the default oTyp of that name.
*  Note that 'logical first char' implies the third char of a name which starts
*  with 'FN' and the first char of any other name.
*Entry:
*  namChar
*Exit:
*  oTyp
*Exceptions:
*  none.
*
*******************************************************************************/
ushort NEAR GetDefaultType(namChar)
char namChar;
   {
   namChar &= 0xDF;   /* convert to upper case */
   DbAssert ((namChar == ('.' & 0xDF)) ||
             ((namChar >= 'A') && (namChar <= 'Z')));
   return(namChar == ('.' & 0xDF)) ? ET_R4 : (ushort)ps.tEtCur[(namChar) - 'A'];
   } /* GetDefaultType */


/***
*MakeVariable - Search for var, create if req'd, return offset to it
*Purpose:
*  Given a variable encountered by the parser or scanner, search for the
*  variable; if not found (and no error conditions detected), create the
*  variable in the tMV or the appropriate tPV and return an offset into
*  mrsCur.bdVar ('oVar') to the value field in the variable entry; this offset 
*  goes in the pcode stream.
*
*Entry:
*  mrsCur set up; it is assumed that bdVar is a heap owner.
*  prsCur either set up, or grs.oPrsCur is UNDEFINED if no procedure is
*     currently active
*  mkVar.oNam - global name table offset for the name of the input variable
*  mkVar.oTyp - global type table offset for the (perhaps assumed) type of the
*              input variable. In the case of an implicitly typed variable,
*              ET_IMP should be passed; in this instance, MakeVariable will 
*              determine the appropriate default type, based on the oNam.
*              In the case of a reference to a record element, the oTyp of the
*              record variable cannot be set by the caller; in this special 
*              case, mkVar.oTyp must be set to UNDEFINED by the caller.
*  mkVar.flags - global 2-bytes of bit flags used to describe the variable
*              encountered. One byte contains flags which are set in 
*              atypical situations, the other contains flags to be tested
*              in common situations.
*              Note that the FVIMPLICIT and FVFNNAME flags are not inputs,
*              however - - - these can be set or reset on input: MakeVariable
*              (now) sets these based on the oTyp and oNam fields (respectively)
*  mkVar.cDimensions - number of dimensions in an array variable; required
*              for correctly allocating the array descriptor, and setting
*              the dimension count for array variables. Only meaningful
*              when FVINDEXED is set, and FVFUNCTION is not (and the variable
*              name does not start with 'FN') (Note that FVINDEXED is 
*              considered to be set whenever FVFORCEARRAY is set).
*  mkVar.flags2 & MV_fONamInOTyp - set when the oType field is either ET_FS or
*	       ET_FT and the fsLength field is the oNam of a CONSTant
*	       which gives the length of the fixed length string/text.
*  mkVar.flags2 & MV_fDontCreate - set when MakeVariable is called JUST to 
*              search for an existing variable. Does not create a new variable 
*              if one is not found with this flag set. Non-RELEASE code checks 
*              that no other modification of the variable table takes place 
*              when this is TRUE.
*
*Exit:
*  The return value is an oVar if the high bit (bit 15) is clear, and
*  it's an error code if the high bit is set. 
*
*  If the high bit is not set (and retval is an oVar), if the input mkVar.oTyp 
*  was incorrectly assumed by the caller (i.e., implicitly typed), mkVar.oTyp
*  will contain the correct oTyp on exit. 
*
*  If the high bit is not set, if a CONSTant var entry was found, mkVar.flags2 
*  will have the MV_fConstFound bit set (always reset on exit otherwise).
*
*  If the high bit is set, the LSB is a scanner error code and the MSB
*  minus bit 15 is a parser action code.  The scanner error code is an

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -