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

📄 varmgrc.c

📁 [随书类]Dos6.0源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*** 
*varmgrc.c - Variable Manager for the BASIC 5.0 Interpreter
*
*  Copyright <C> 1985, Microsoft Corporation
*
*Purpose:
*  Includes code for:
*     - creating and searching for variables
*     - creating and searching for user-defined types
*  Includes a description of namespaces in BASIC.
*
**************************************************************************/


/*
The matrix given below is a representation of the namespaces in BASIC.
Each class of names is listed on both the vertical and horizontal axis';
X's in a square indicate that the two classes share a namespace (and
could thus have name conflicts), while blanks in a square indicates that
the two classes have separate namespaces.

An astrisk ('*') (shown on vertical axis only) indicates that
a type character included at the end of the name counts as
part of the name for determining uniqueness.

NOTE: This is a copy of the identical table in basic40.doc. If there's
      any conflict between this table and that one, the one in basic40.doc
      takes precedence.


           COM  LAB  DEF  SUB  FUNC Type Elem Sclr typd Arry typd Const
           Blk        Fn                           Sclr      Arry
          |    |    |    |    |    |    |    |    |    |    |    |    |
        ---------------------------------------------------------------
COMMON Blk| XX |    |    |    |    |    |    |    |    |    |    |    |
          | XX |    |    |    |    |    |    |    |    |    |    |    |
        ---------------------------------------------------------------
Label     |    | XX |    |    |    |    |    |    |    |    |    |    |
          |    | XX |    |    |    |    |    |    |    |    |    |    |
        ---------------------------------------------------------------
DEF Fn*   |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
          |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
        ---------------------------------------------------------------
SUB       |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
          |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
        ---------------------------------------------------------------
FUNCTION  |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
          |    |    | XX | XX | XX |    |    | XX | XX | XX | XX | XX |
        ---------------------------------------------------------------
Type      |    |    |    |    |    | XX |    |    |    |    |    |    |
          |    |    |    |    |    | XX |    |    |    |    |    |    |
        ---------------------------------------------------------------
Element   |    |    |    |    |    |    | XX |    |    |    |    |    |
          |    |    |    |    |    |    | XX |    |    |    |    |    |
        ---------------------------------------------------------------
Scaler*   |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
          |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
        ---------------------------------------------------------------
typed     |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
  Scaler  |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
        ---------------------------------------------------------------
Array*    |    |    | XX | XX | XX |    |    |    |    | XX | XX |    |
          |    |    | XX | XX | XX |    |    |    |    | XX | XX |    |
        ---------------------------------------------------------------
typed     |    |    | XX | XX | XX |    |    |    |    | XX | XX |    |
  Array   |    |    | XX | XX | XX |    |    |    |    | XX | XX |    |
        ---------------------------------------------------------------
Const     |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
          |    |    | XX | XX | XX |    |    | XX | XX |    |    | XX |
        ---------------------------------------------------------------
*/

#include "version.h"
#if !HEAP_H
#include "heap.h"
#endif
#if !CONINT_H
#include "conint.h"
#endif
#if !CONTEXT_H
#include "context.h"
#endif
#if !VARIABLE_H
#include "variable.h"
#endif
#if !QBIMSGS_H
#include "qbimsgs.h"
#endif
#if !NAMES_H
#include "names.h"
#endif
#if !UTIL_H
#include "util.h"
#endif
#if !EXECUTOR_H
#include "executor.h"
#endif
#if !PARSER_H
#include "parser.h"
#endif
#if !TXTMGR_H
#include "txtmgr.h"
#endif
#if !SCANNER_H
#include "scanner.h"
#endif

/* forward reference of functions used only locally */
ushort   NEAR     CreateVar(ushort, ushort);
boolean  FAR      ModSharedChk(VOID);
void     NEAR     ReDirect(VOID);

ushort   NEAR     StdSearch(VOID);
STATICF(VOID) AdjustStatChain(var *, ushort, ushort);
STATICF(ushort) GrowBdVar(ushort);
ushort NEAR FuncSearch(void);
ushort NEAR GetDefaultType(char);

extern   ushort oNamOfPrsCur;    /* set in ssrude.asm                         */

VOID     FAR      B_ISdUpd(sd *, ushort);
                                 /* runtime entry point to update moving sd's */
VOID     FAR      B_IAdUpd(ad *, ushort);
                                 /* runtime entry point to update moving ad's */

/* varmgr-specific data */
ushort  vm_oVarCur;                 /* offset to current variable table entry */
var *vm_pVarCur;                    /* only guaranteed to be setup immediately
                                       after a search or variable creation    */
ushort vm_oVarTmp;                  /* temporary var entry offset             */
boolean vm_fVarFound;               /* return value from var search routines.
                                       note that, if vm_fVarFound is TRUE, the 
                                       offset to the found var will be in 
                                       vm_oVarCur (a static, also used in 
                                       variable creation).                    */
ushort vm_fPVCur;                   /* currently searching tPV if TRUE        */
STATICV uchar nm_mask;              /* mask to apply to tNam flag for variable*/
STATICV ushort errVal;              /* error return - used for those cases
                                       which must return some other value
                                       (such as routines invoked via
                                        ForEachPrsInMrs ...)                  */
STATICV boolean fConvtdToFun;       /* used by FuncSearch to communicate the
                                       fact that it converted an existing
                                       entry to be a FUNCTION entry.          */

/*##############################################################################
#                                                                              #
#                        Variable Storage Scheme                               #
#                                                                              #
##############################################################################*/
/* 
Variables are stored as follows:

      There is one physical variable table per module, and one logical table
      per procedure and module. This is accomplished by having one hash table
      per logical table, all inter-woven in the physical table.

      Each hash table is initialized to zeros, and contains a fixed number
      of fields, each of which is an offset into the physical table to the
      first variable in a chain of variables that hash to the same hash table
      entry.  The hashing function is based on the name table offset (oNam)
      for the variable.   Note that module hash tables are larger than proc.
      hash tables, in anticipation of more variables per module than per
      procedure (i.e., to help give us reasonable search speed for module
      variables).  As of this writing (Aug. '87), there are 16 hash chains 
      per module hash table, and 8 per procedure hash table.

      The links in each hash chain are (physical) variable table offsets to
      the next variable entry in the chain.  The end-of-chain marker is
      EITHER a 0 or a 1 - - - this is because we also store a flag in the
      low bit of the hash link (we use every bit we can get ...).

      Since variables cannot be dynamically removed and/or reused (i.e.,
      one can unlink an entry, but then that space is dead), variable
      entries and hash tables go into the physical table in whatever order 
      they are encountered.

Variable Entries:

      A variable entry looks like one of the below:

                  If oTyp is User-              If oTyp is I2, I4,
                  Defined or a Fixed            R4, R8, or Sd. oTyp
                  Length String                 is stored in low 3
                                                bits of flags field
                  +----------------+      
		  |   oTyp/cbFS    |
                  +----------------+            +----------------+
                  |      oNam      |            |      oNam      |
                  +----------------+            +----------------+ 
                  |   oHashLink    |            |   oHashLink    |
                  +----------------+            +----------------+
                  |     flags      |            |     flags      |
                  +----------------+            +----------------+
          pVar--->+     value      |    pVar--->|     value      |
                  |                |            |                |
                  +----------------+            +----------------+


      The value field is of variable length, depending on what the variable
      represents. The flag bits allow determination of size and use of the
      value field for any given variable.

      All variable entries are of even size, and must fall on even byte
      boundaries, for 2 reasons:
         (1) The runtime requires SD's to fall on even byte boundaries
         (2) We store a flag bit in the low byte of the oHashLink field,
               so each oVar must be even.
                                                                              */


/*##############################################################################
#                                                                              #
#                        Variable Creation                                     #
#                                                                              #
##############################################################################*/
/***
*GrowBdVar(cbGrowVar) - grow variable table
*Purpose:
*  Given an amount by which we wish to grow the active variable table,
*  grow it if possible, returning FALSE if successful or an error code if not.
*
*  In the event that grs.otxCONT != UNDEFINED, don't call BdGrowVar; instead,
*  succeed if sufficient space exists between cbLogical and cbPhysical, fail
*  otherwise, returning ER_CN.
*Entry:
*  cbGrowVar - number of bytes we wish to grow mrsCur.bdVar by.
*Exit:
*  FALSE if successful, in which case mrsCur.bdVar.cbLogical is increased by
*     cbGrowVar
*  Otherwise, returns an error code for use by CreateVar, below.
*******************************************************************************/
STATICF(ushort) GrowBdVar(cbGrowVar)
ushort cbGrowVar;
   {
   /* [13] ensure that oVar < 0x8000					      */
   if ((mrsCur.bdVar.cbLogical + VAR_STRUCT_SIZE + 2) > 0x7FFF) /* [13]       */
      return (PRS_ER_RE | ER_OM);		   /* [13] out of memory      */

   if (grs.otxCONT == UNDEFINED) {                 /* user can't CONTinue     */
      if (!BdGrowVar(&mrsCur.bdVar, cbGrowVar))
         return (PRS_ER_RE | ER_OM);               /* out of memory           */
      }
   else {            
      /* user is able to CONTinue; fail unless space already exists in table  */
      REG1 ushort temp = mrsCur.bdVar.cbLogical + cbGrowVar;
      if (temp > mrsCur.bdVar.cbPhysical) {	   /* would have to actually  */
						   /* grow table	      */
         DbAssert(!(mkVar.flags2 & MV_fTrashTable))
         return (0x8000 | ER_CN);
         }
      else 
         mrsCur.bdVar.cbLogical = temp;            /* success.                */
      }
   return(FALSE); 
   }

/***
*CreateVar(oPVHash, varFlags) - create a new variable
*Purpose:
*  Create a new variable in the mrsCur.bdVar. If 'oPVHASH' is UNDEFINED, 
*  create it in the tMV, else, use the offset to the tPV hash table.
*  
*Entry:
*  oPVHash - UNDEFINED if we're to create var in the tMV, or an offset
*              into mrsCur.bdVar to the hash table for the tPV.
*  varFlags  - Initial settings for the flags word in the new var entry.
*              FVFNNAME, FVFUN, FVCOMMON, FVFORMAL, FVDECLDVAR, FVSHARED, 

⌨️ 快捷键说明

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