-- file: OpNames.mesa, edited by Bruce, July 8, 1980  9:32 AM

DIRECTORY
  AltoDefs USING [BYTE],
  BinaryDefs USING [MopcodeNames],
  MiscDefs USING [DestroyFakeModule],
  OpTableDefs USING [],
  SegmentDefs USING [FileSegmentAddress, FileSegmentHandle, SwapIn, Unlock],
  String USING [
    AppendSubString, EquivalentSubStrings, SubString, SubStringDescriptor];

OpNames: PROGRAM
  IMPORTS BinaryDefs, MiscDefs, SegmentDefs, String EXPORTS OpTableDefs =
  BEGIN
  
  BYTE: TYPE = AltoDefs.BYTE;
  
  CompStringDesc: TYPE = RECORD [offset, length: CARDINAL];
  
  Names: POINTER TO RECORD [
    base: STRING, mnemonic: ARRAY BYTE OF CompStringDesc] ← NIL;
  
  s: STRING ← [16];
  ss: String.SubStringDescriptor;
  
  InstName: PUBLIC PROCEDURE [op: BYTE] RETURNS [STRING] =
    BEGIN
    SetupArray[];
    [ss.offset, ss.length] ← Names.mnemonic[op];
    s.length ← 0;
    String.AppendSubString[s, @ss];
    ReleaseArray[];
    RETURN[s]
    END;
    
  UnknownInstruction: PUBLIC SIGNAL [name: STRING] = CODE;
  
  InstCode: PUBLIC PROCEDURE [name: STRING] RETURNS [i: BYTE] =
    BEGIN
    s: String.SubString ← @ss;
    ssname: String.SubStringDescriptor ← [name, 0, name.length];
    sname: String.SubString ← @ssname;
    SetupArray[];
    FOR i IN BYTE DO
      [s.offset, s.length] ← Names.mnemonic[i];
      IF String.EquivalentSubStrings[s, sname] THEN EXIT;
      REPEAT FINISHED => BEGIN i ← 0; SIGNAL UnknownInstruction[name] END;
      ENDLOOP;
    ReleaseArray[];
    RETURN;
    END;
    
  arraysegment: SegmentDefs.FileSegmentHandle ← MiscDefs.DestroyFakeModule[
    LOOPHOLE[BinaryDefs.MopcodeNames]].seg;
  
  SetupArray: PROCEDURE =
    BEGIN OPEN SegmentDefs;
    SwapIn[arraysegment];
    Names ← FileSegmentAddress[arraysegment];
    ss.base ← Names.base + LOOPHOLE[Names, CARDINAL];
    END;
    
  ReleaseArray: PROCEDURE = BEGIN OPEN SegmentDefs; Unlock[arraysegment]; END;
    
  
  END.