-- SourceBcd.Mesa  Last edited by Lewis on 30-Dec-80 10:12:07

DIRECTORY
  BcdDefs USING [CTIndex, MTIndex, MTRecord, NameRecord],
  BcdUtilDefs USING [BcdBases, BcdLimits],
  PackEnviron USING [BcdHandle],
  Strings USING [SubString],
  SymTabDefs USING [HTIndex],
  Table USING [Base, Limit];

SourceBcd: DEFINITIONS =
  BEGIN

 -- Source Bcd is obsolete, already repackaged, or was compiled for Alto
  BadSourceBcd: ERROR;


 -- ************************* BCD Table Information *************************

  bcdHeader: PackEnviron.BcdHandle;

  bcdBases: LONG POINTER TO BcdBaseRec;
    BcdBaseRec:  TYPE = BcdUtilDefs.BcdBases;   -- source bcd table bases

  bcdLimits: LONG POINTER TO BcdLimitRec;
    BcdLimitRec: TYPE = BcdUtilDefs.BcdLimits;  -- last indices in table bases

  moduleCount: CARDINAL;

  mtiArray: LONG DESCRIPTOR FOR ARRAY ModuleNum OF BcdMTIndex;

  -- allow general comparisons between BcdDefs.MTIndex values
  BcdMTIndex: TYPE = Table.Base RELATIVE ORDERED POINTER [0..Table.Limit) TO BcdDefs.MTRecord;

  ModuleNum: TYPE = CARDINAL;
    NullModuleNum: ModuleNum = LAST[CARDINAL];


  -- Interface
  Load, Unload: PROC;

  EnumerateConfigs: PROC [
    userProc: PROC [BcdDefs.CTIndex] RETURNS [stop: BOOLEAN]];
  EnumerateModules: PROC [
    userProc: PROC [BcdDefs.MTIndex] RETURNS [stop: BOOLEAN]];

  IsTableCompiled: PROC [mti: BcdDefs.MTIndex] RETURNS [reply: BOOLEAN];

  ModuleNumForMti: PROC [      -- map i-th module index to i
    mti: BcdDefs.MTIndex] RETURNS [mNum: ModuleNum];

  SubStringForName: PROC [ss: Strings.SubString, name: BcdDefs.NameRecord];

  EqualIdAndName: PROC [
      id: SymTabDefs.HTIndex, name: BcdDefs.NameRecord] 
    RETURNS [equal: BOOLEAN];
    


 -- *************************** Configuration Tree ***************************

  configTreeRoot: CTreeIndex;

  ComponentKind: TYPE = {instance, prototype};
 
  CTreeIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO ConfigTreeNode;
    NullCTreeIndex: CTreeIndex = LAST[CTreeIndex];
    
  ConfigTreeNode: TYPE = RECORD [
    father:        CTreeIndex,  -- containing config
    brother:       CTreeIndex,  -- next config/module in containing config
    firstSon:      CTreeIndex,  -- first contained config/module
    prototypeName: BcdDefs.NameRecord,
    anotherNodeWSameProtoName: BOOLEAN,
    instanceLink, prototypeLink: CTreeIndex, -- links nodes w = hash values
    instancePrev, prototypePrev: CTreeIndex, -- links nodes w = ids
    index:         BcdTableLoc,  -- module or config table index
    body: SELECT kind: ComponentKind FROM
      instance  => [instanceName: BcdDefs.NameRecord],
      prototype => [],      -- for prototypes, instanceName = prototypeName
      ENDCASE];

  BcdTableLoc: TYPE = RECORD [
    SELECT kind: * FROM
      config => [cti: BcdDefs.CTIndex],
      module => [mti: BcdDefs.MTIndex],
      ENDCASE];

 -- Conceptually, all components (modules and configurations) stored in the
 -- Configuration Tree have names of the form [instanceName prototypeName].
 -- If the component is a prototype, however, only the prototype name is
 -- actually stored; its instance name is the same as the prototype name.


  -- Interface
  BuildConfigTree, DestroyConfigTree: PROC;

  EnumerateModulesInConfig: PROC [
    kind: ComponentKind,  -- if prototype, no duplications appear in output 
    configTreeNode: CTreeIndex, 
    userProc: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN]];

  FindModuleOrConfig: PROC [
      kind: ComponentKind, 
      ResetIdStream: PROC,
      FirstQualId, NextQualId: PROC RETURNS [id: SymTabDefs.HTIndex]] 
    RETURNS [component: CTreeIndex];

  IsModuleInConfig: PROC [
      kind: ComponentKind, 
      mti: BcdDefs.MTIndex,
      configTreeNode: CTreeIndex] 
    RETURNS [yes: BOOLEAN];

  -- find first node with given instance/prototype id   
  -- (others with same id are found along first node's prev chain)   
  LookupId: PROC [
      id: SymTabDefs.HTIndex, kind: ComponentKind] 
    RETURNS [firstTreeLoc: CTreeIndex];

  LookupName: PROC [
      name: BcdDefs.NameRecord, kind: ComponentKind] 
    RETURNS [firstTreeLoc: CTreeIndex];

  LookupSS: PROC [
      idSS: Strings.SubString, kind: ComponentKind] 
    RETURNS [firstTreeLoc: CTreeIndex];

  END.