-- BcdDefs.Mesa
-- last edited by Satterthwaite on 19-Apr-82 12:59:52

DIRECTORY
  PrincOps: TYPE USING [EPIndex, GFTIndex, GFTNull, MaxFrameSize, MaxNGfi],
  Table: TYPE USING [Base, Limit, Selector],
  TimeStamp: TYPE USING [Null, Stamp];

BcdDefs: DEFINITIONS = {

  Base: TYPE = Table.Base;

  -- allocation codes for the binder

  BinderNTables: CARDINAL = 20;

  treetype: Table.Selector = 0; -- trees
  httype: Table.Selector = 1; -- hash table
  sstype: Table.Selector = 2; -- (packed) string table
  cttype: Table.Selector = 3; -- config table
  mttype: Table.Selector = 4; -- module table
  imptype: Table.Selector = 5; -- import table
  exptype: Table.Selector = 6; -- export table
  sgtype: Table.Selector = 7; -- segment table
  fttype: Table.Selector = 8; -- file table
  sttype: Table.Selector = 9; -- semantic table
  cxtype: Table.Selector = 10; -- context table
  nttype: Table.Selector = 11; -- name table
  evtype: Table.Selector = 12; -- external variable table
  sptype: Table.Selector = 13; -- space table
  fptype: Table.Selector = 14; -- frame pack table
  typtype: Table.Selector = 15; -- type table
  tmtype: Table.Selector = 16; -- type table
  lftype: Table.Selector = 17; -- link fragment table
  rftype: Table.Selector = 18; -- ref literal and atom fragment table
  tftype: Table.Selector = 19; -- type fragment table
  
  -- version identification

  VersionStamp: TYPE = TimeStamp.Stamp;
  NullVersion: TimeStamp.Stamp = TimeStamp.Null;

  -- BCD Header

  VersionID: CARDINAL = 01280;

  BCD: TYPE = RECORD [
    versionIdent: CARDINAL,
    version: VersionStamp,
    creator: VersionStamp,
    sourceVersion: VersionStamp,
    source: NameRecord,
    spare1, spare2: BOOLEAN,
    nPages: [0..512),
    nConfigs, nModules: CARDINAL,
    nImports, nExports: CARDINAL,
    definitions, repackaged, typeExported, tableCompiled: BOOLEAN,
    versions, extended: BOOLEAN,
    firstdummy: GFTIndex,
    nDummies: CARDINAL,
    ssOffset: CARDINAL, -- string table
    ssLimit: CARDINAL,
    ctOffset: CARDINAL, -- config table
    ctLimit: CTIndex,
    mtOffset: CARDINAL, -- module table
    mtLimit: MTIndex,
    impOffset: CARDINAL, -- import table
    impLimit: IMPIndex,
    expOffset: CARDINAL, -- export table
    expLimit: EXPIndex,
    evOffset: CARDINAL, -- external variable table
    evLimit: EVIndex,
    sgOffset: CARDINAL, -- segment table
    sgLimit: SGIndex,
    ftOffset: CARDINAL, -- file table
    ftLimit: FTIndex,
    spOffset: CARDINAL, -- space table
    spLimit: SPIndex,
    ntOffset: CARDINAL, -- name table
    ntLimit: NTIndex,
    typOffset: CARDINAL, -- type table
    typLimit: TYPIndex,
    tmOffset: CARDINAL, -- type map table
    tmLimit: TMIndex,
    fpOffset: CARDINAL, -- frame pack table
    fpLimit: FPIndex,
   -- following only if extended = TRUE
    lfOffset: CARDINAL, -- link fragment table
    lfLimit: LFIndex,
    rfOffset: CARDINAL, -- ref literal fragment table
    rfLimit: RFIndex,
    tfOffset: CARDINAL, -- type fragment table
    tfLimit: TFIndex,
    rtPages: RECORD [relPageBase, pages: [0..256)]];	-- atom print names, type table, etc.

  -- Portable Type

  Portable: TYPE = {module, interface};

  -- Name Table

  PackedString: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      string => [string: StringBody],
      size => [size: PACKED ARRAY [-3..-3) OF [0..256)]
      ENDCASE];

  NameRecord: TYPE = RECORD [CARDINAL];
  NullName: NameRecord = [1];

  NTRecord: TYPE = RECORD [name: NameRecord, item: Namee];

  Namee: TYPE = RECORD [
    SELECT type: * FROM
      config => [cti: CTIndex],
      module => [mti: MTIndex],
      import => [impi: IMPIndex],
      export => [expi: EXPIndex]
      ENDCASE];

  NTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO NTRecord;
  NTNull: NTIndex = LAST[NTIndex];

  -- Configuration Table

  CTRecord: TYPE = --MACHINE DEPENDENT-- RECORD [
    name: NameRecord,
    namedInstance: BOOLEAN,
    file: FTIndex,
    config: CTIndex,
    nControls: CARDINAL,
    controls: ARRAY [0..0) OF ControlItem];

  ControlItem: TYPE = --MACHINE DEPENDENT-- RECORD [
    SELECT kind: * FROM
      module => [mti: MTIndex],		-- kind = 0 for compatibility
      config => [cti: CTIndex]
      ENDCASE];

  CTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO CTRecord;
  CTNull: CTIndex = LAST[CTIndex];

  -- Module Table

  LinkLocation: TYPE = {frame, code};

  MTRecord: TYPE = --MACHINE DEPENDENT-- RECORD [
    name: NameRecord,
    namedInstance: BOOLEAN,
    initial: BOOLEAN,
    file: FTIndex,
    linkLoc: LinkLocation,
    config: CTIndex,
    code: CodeDesc,
    sseg: SGIndex,
    long, tableCompiled, boundsChecks, nilChecks: BOOLEAN,
    frameRefs: BOOLEAN,
    frameType: [0..Table.Limit/2),		-- type frag index	
    framesize: [0..PrincOps.MaxFrameSize),
    altoCode, residentFrame, crossJumped, packageable: BOOLEAN,
    gfi: GFTIndex,
    variables: EVIndex,
    ngfi: [1..PrincOps.MaxNGfi],
    extension: SELECT kind: * FROM
      direct => [length: [0..Table.Limit), frag: ARRAY [0..0) OF Link],
      indirect => [links: LFIndex],
      multiple => [
        links: LFIndex,
	refLiterals: RFIndex,
	types: TFIndex]
      ENDCASE];

  CodeDesc: TYPE = RECORD [
    sgi: SGIndex, packed: BOOLEAN, linkspace: BOOLEAN, offset, length: CARDINAL];

  MTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO MTRecord;
  MTNull: MTIndex = LAST[MTIndex];


  -- Import Table

  IMPRecord: TYPE = RECORD [
    name: NameRecord,
    port: Portable,
    namedInstance: BOOLEAN,
    file: FTIndex,
    gfi: GFTIndex,
    ngfi: [1..PrincOps.MaxNGfi]];

  IMPIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO IMPRecord;
  IMPNull: IMPIndex = LAST[IMPIndex];

  -- Export Table

  EXPRecord: TYPE = --MACHINE DEPENDENT-- RECORD [
    name: NameRecord,
    size: [0..377b],
    port: Portable,
    namedInstance, typeExported: BOOLEAN,
    file: FTIndex,
    links: ARRAY [0..0) OF Link];

  EXPIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO EXPRecord;
  EXPNull: EXPIndex = LAST[EXPIndex];

  -- External Variable Table

  EVRecord: TYPE = RECORD [length: CARDINAL, offsets: ARRAY [1..1) OF CARDINAL];

  EVIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO EVRecord;
  EVNull: EVIndex = LAST[EVIndex];

  -- Segment Table

  SegClass: TYPE = {code, symbols, acMap, other};

  SGRecord: TYPE = RECORD [
    class: SegClass, file: FTIndex, base: CARDINAL, pages, extraPages: [0..256)];

  SGIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO SGRecord;
  SGNull: SGIndex = LAST[SGIndex];

  -- File Table

  FTRecord: TYPE = RECORD [name: NameRecord, version: VersionStamp];

  FTIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO FTRecord;
  FTNull: FTIndex = LAST[FTIndex];
  FTSelf: FTIndex = LAST[FTIndex] - 1;

  -- Space Table

  SPRecord: TYPE = --MACHINE DEPENDENT-- RECORD [
    seg: SGIndex, length: CARDINAL, spaces: ARRAY [0..0) OF SpaceID];

  SpaceID: TYPE = RECORD [
    name: NameRecord, resident: BOOLEAN, offset: [0..256), pages: [1..128]];

  SPIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO SPRecord;
  SPNull: SPIndex = LAST[SPIndex];

  -- Frame Pack Table

  FPRecord: TYPE = --MACHINE DEPENDENT-- RECORD [
    name: NameRecord, length: CARDINAL, modules: ARRAY [0..0) OF MTIndex];

  FPIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO FPRecord;
  FPNull: FPIndex = LAST[FPIndex];

  -- Type Table

  TYPRecord: TYPE = RECORD [version: VersionStamp, id: RECORD [UNSPECIFIED]];

  TYPIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO TYPRecord;
  TYPNull: TYPIndex = LAST[TYPIndex];

  -- Type Map Table

  TMRecord: TYPE = RECORD [
    version: VersionStamp, offset: CARDINAL, map: TYPIndex];

  TMIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO TMRecord;
  TMNull: TMIndex = LAST[TMIndex];

  -- Links

  GFTIndex: TYPE = PrincOps.GFTIndex;
  GFTNull: GFTIndex = PrincOps.GFTNull;

  EPIndex: TYPE = PrincOps.EPIndex;
  EPLimit: CARDINAL = LAST[EPIndex] + 1;

  VarIndex: TYPE = [0..17b];
  VarLimit: CARDINAL = LAST[VarIndex] + 1;

  NullLink: Link = [procedure[0, 0, FALSE]];
  UnboundLink: Link = [procedure[0, 0, TRUE]];

  LinkTag: TYPE = {variable, procedure, type};
  VarTag: TYPE = MACHINE DEPENDENT {var(0), proc0(1), type(2), proc1(3)};

  LinkFrag: TYPE = RECORD [frag: SEQUENCE length: NAT OF Link];

  Link: TYPE = MACHINE DEPENDENT RECORD [
    rep(0): SELECT OVERLAID LinkTag FROM	-- decoded by self.vtag
      variable => [vgfi(0:0..9): GFTIndex, var(0:10..13): VarIndex, vtag(0:14..15): VarTag],
      procedure => [gfi(0:0..9): GFTIndex, ep(0:10..14): EPIndex, tag(0:15..15): BOOLEAN],
      type => [typeID(0:0..13): TYPIndex, type(0:14..14): BOOLEAN, proc(0:15..15): BOOLEAN]
      ENDCASE];

  LFIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO LinkFrag;
  LFNull: LFIndex = LAST[LFIndex];

  -- Atoms and REFs to literals (Cedar only)
  
  RefLitFrag: TYPE = RECORD [offset: CARDINAL, frag: SEQUENCE length: NAT OF RefLitIndex];
  RefLitIndex: TYPE = RECORD [NAT];
  
  RFIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO RefLitFrag;
  RFNull: RFIndex = LAST[RFIndex];
  
  -- Types (Cedar only)
  
  TypeFrag: TYPE = RECORD [offset: CARDINAL, frag: SEQUENCE length: NAT OF TypeIndex];
  TypeIndex: TYPE = RECORD [NAT];
  
  TFIndex: TYPE = Table.Base RELATIVE POINTER [0..Table.Limit) TO TypeFrag;
  TFNull: TFIndex = LAST[TFIndex];

  }.