-- CGenDebugVar.mesa  Edited by Sweet,  June 23, 1980  12:01 PM

DIRECTORY
  AllocDebugDefs USING [TableBase],
  CGenDebugDefs USING [],
  CodeDefs USING [StackNull, VarComponent, VarIndex, VarItem, VarSpace, VarTag],
  DebugUsefulDefs USING [ShortCopyREAD],
  IODefs USING [TAB],
  Literals USING [LTNull],
  RESOut USING [PChar, PCr, PNext, PNextUnsigned, PNull, PString, PUnsigned],
  Symbols USING [lG, lL, lZ],
  Table USING [Base];

CGenDebugVar: PROGRAM 
  IMPORTS AllocDebugDefs, DebugUsefulDefs, RESOut
  EXPORTS CGenDebugDefs =
  BEGIN OPEN CodeDefs, RESOut;

  PutAsVar: PUBLIC PROCEDURE [index: CodeDefs.VarIndex] =
    BEGIN OPEN CodeDefs;
    cbr: CodeDefs.VarItem;
    cb: Table.Base ← AllocDebugDefs.TableBase[];

    DebugUsefulDefs.ShortCopyREAD[
      to: @cbr,
      from: @cb[index],
      nwords: SIZE[CodeDefs.VarItem]];
    PUnsigned[LOOPHOLE[index]];
    PChar[':];
    IF cbr.free THEN 
      BEGIN
      PString["	Free!"L];
      RETURN;
      END;
    IF cbr.tag ~IN VarTag THEN
      BEGIN
      PString["	tag: ?["L]; PUnsigned[LOOPHOLE[cbr.tag]]; PChar[']];
      RETURN
      END;
    WITH cc: cbr SELECT FROM
      o => PutComponent["var"L, @cc.var];
      bo =>
	BEGIN
	PutComponent["base"L,@cc.base];
	PCr[]; PutComponent["offset"L, @cc.offset];
	END;
      bdo =>
	BEGIN
	PutComponent["base",@cc.base];
	PCr[]; PutComponent["disp"L, @cc.disp];
	PCr[]; PutComponent["offset"L, @cc.offset];
	END;
      ind =>
	BEGIN
	PutComponent["base",@cc.base];
	PCr[]; PutComponent["index"L, @cc.index];
	WITH cc SELECT FROM
	  packed =>
	    BEGIN
	    PNext["grain: "L, 1, 10];
	    PUnsigned[grain];
	    END;
	  notPacked => PNextUnsigned["eWords"L, eWords, 10];
	  ENDCASE;
	IF cc.simple THEN PNext["simple"L];
	PCr[]; PutComponent["offset"L, @cc.offset];
	END;
      ENDCASE;
    END;

  PutAsComponent: PUBLIC PROCEDURE [cp: POINTER] =
    BEGIN
    var: VarComponent;
    DebugUsefulDefs.ShortCopyREAD[to: @var, from: cp, nwords: SIZE[VarComponent]];
    PutComponentFields[@var, 2];
    END;

  PutComponent: PROCEDURE [name: STRING, c: POINTER TO CodeDefs.VarComponent] =
    BEGIN
    PChar[IODefs.TAB];
    PString[name]; PString[" - "L];
    PutComponentFields[c, 10];
    END;
  
  PutComponentFields: PROCEDURE
      [c: POINTER TO CodeDefs.VarComponent, indent: CARDINAL] =
    BEGIN
    SpaceName: ARRAY VarSpace OF STRING = [
      "faddr"L, "frame"L, "frameup"L, "caddr"L,
      "code"L, "link"L, "linkup"L, "stack"L, "const", "pdesc"L];
    PString["wSize: "L];
    PUnsigned[c.wSize];
    IF c.bSize # 0 THEN PNextUnsigned["bSize"L,c.bSize,indent];
    IF c.tag ~IN VarSpace THEN
      BEGIN
      PNextUnsigned["Invalid tag"L, c.tag, indent];
      RETURN
      END
    ELSE PNext[SpaceName[c.tag], 1, indent];
    PChar['[];
    WITH c SELECT FROM
      frame =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	IF bd # 0 THEN PNextUnsigned["bd"L, bd, indent];
	PNext["level: "L, 1, indent];
	SELECT level FROM
	  Symbols.lZ => PChar['Z];
	  Symbols.lG => PChar['G];
	  Symbols.lL => PChar['L];
	  ENDCASE => PUnsigned[level];
        IF immutable THEN PNext["immutable"L,,indent];
	END;
      frameup =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	PNext["pwSize: "L, 1, indent];
	PUnsigned[pwSize];
	PNext["level: "L, 1, indent];
	SELECT level FROM
	  Symbols.lZ => PChar['Z];
	  Symbols.lG => PChar['G];
	  Symbols.lL => PChar['L];
	  ENDCASE => PUnsigned[level];
	PNextUnsigned["delta"L, delta, indent];
	END;
      faddr =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	PNext["level: "L, 1, indent];
	SELECT level FROM
	  Symbols.lZ => PChar['Z];
	  Symbols.lG => PChar['G];
	  Symbols.lL => PChar['L];
	  ENDCASE => PUnsigned[level];
	END;
      caddr, link =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	END;
      linkup =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	PNextUnsigned["delta"L, delta, indent];
	END;
      code =>
	BEGIN
	PString["wd: "L];
	PUnsigned[wd];
	IF bd # 0 THEN PNextUnsigned["bd"L, bd, indent];
	IF lti # Literals.LTNull THEN PNextUnsigned["lti"L, lti, indent];
	END;
      stack =>
	BEGIN
	PString["sti: "L];
	PNull[sti, StackNull];
	IF wd # 0 THEN PNextUnsigned["wd"L, wd, indent];
	IF bd # 0 THEN PNextUnsigned["bd"L, bd, indent];
	END;
      const =>
	BEGIN
	PString["d1: "L];
	PUnsigned[d1];
	IF c.wSize = 2 OR c.wSize = 1 AND c.bSize # 0 THEN
	  PNextUnsigned["d2"L, d2, indent];
	IF bd # 0 THEN PNextUnsigned["bd"L, bd, indent];
	END;
      pdesc =>
	BEGIN
	PString["ep: "L];
	PUnsigned[ep];
	END;
      ENDCASE;
    PChar[']];
    END;

  END.