M2Impl.mesa
Last Edited by: Gutknecht, October 2, 1985 3:00:03 pm PDT
Satterthwaite December 12, 1985 10:35:30 am PST
DIRECTORY
Rope: TYPE USING [ROPE],
FS: TYPE USING [StreamOpen, Error],
ViewerIO: TYPE USING [CreateViewerStreams],
IO: TYPE USING [STREAM, GetChar, PutChar, Put, char, card, int, real, rope, Close],
Commander: TYPE USING [Handle, Register],
CommandTool: TYPE USING [ArgumentVector, Parse, Failed],
M2P: TYPE USING [InitP];
M2Impl: CEDAR PROGRAM
IMPORTS FS, ViewerIO, IO, Commander, CommandTool, M2P =
BEGIN
M2: PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] =
{ arg: CommandTool.ArgumentVector =
CommandTool.Parse [cmd: cmd ! CommandTool.Failed => msg ← "failed"];
FOR i: NAT IN [1..arg.argc) DO
(cmd.out).Put [IO.rope ["[ "], IO.rope [arg[i]], IO.char [' ]];
M2P.InitP [cmd.out, arg[i]]; (cmd.out).Put [IO.char[']], IO.char['\n]]
ENDLOOP;
(cmd.out).PutChar ['\n] };
Decode: PROC [cmd: Commander.Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL] =
{ OBJFILE: CARDINAL = 220;
mnem: PACKED ARRAY [0..34*48) OF CHAR;
id: CARDINAL ← 0;
Enter: PROC [s: REF TEXT] = {
FOR i: CARDINAL IN [0..48) DO mnem[id] ← s[i]; id ← id+1 ENDLOOP };
DecodeFile: PROC [file, outmed: Rope.ROPE] =
{ f, g: IO.STREAM; ch, ch1, ch2, ch3: CHAR; opened: BOOLTRUE;
n: LONG CARDINAL; N, i, j, k: CARDINAL; pc: CARDINAL ← 0; len: REAL;
nextno: PROC RETURNS [CARDINAL] =
{ ch: CHAR = f.GetChar; ch1: CHAR = f.GetChar;
RETURN [ch.ORD*256 + ch1.ORD] };
PutTab: PROC =
{ N: CARDINAL = nextno [];
FOR n: CARDINAL IN [0..N) DO
ch: CHAR = f.GetChar; ch1: CHAR = f.GetChar;
g.Put [IO.card[ch.ORD*256 + ch1.ORD], IO.char['\n]];
ENDLOOP;
g.PutChar ['\n] };
f ← FS.StreamOpen [file ! FS.Error => { opened ← FALSE; CONTINUE }];
IF opened THEN
{ IF outmed # "*" THEN g ← FS.StreamOpen [outmed, $create]
ELSE [out: g] ← ViewerIO.CreateViewerStreams ["Decode Files"];
g.Put [IO.rope[file], IO.char['\n], IO.char['\n]];
IF nextno [] = OBJFILE THEN
{ g.Put [IO.rope["imports"], IO.char['\n]];
N ← nextno []; i ← 0;
WHILE i # N DO
g.Put [IO.card[nextno []], IO.card[nextno []], IO.char[' ]];
ch ← f.GetChar; j ← ch.ORD-1;
WHILE j # 0 DO g.PutChar [f.GetChar]; j ← j - 1 ENDLOOP;
g.PutChar ['\n];
i ← i + 1
ENDLOOP;
g.PutChar ['\n];
g.Put [IO.rope["code"], IO.char['\n]];
k ← 0; N ← nextno [];
WHILE pc # N DO g.Put [IO.card[pc], IO.char[' ]];
ch ← f.GetChar; i ← ch.ORD*6;
WHILE mnem[i] < 'a DO g.PutChar [mnem[i]]; i ← i+1 ENDLOOP;
g.PutChar [' ];
SELECT mnem[i] FROM
'a, 'f => { pc ← pc + 1 };
'b, 'g => { ch ← f.GetChar; g.Put [IO.card[ch.ORD]]; pc ← pc + 2 };
'c, 'l => { ch ← f.GetChar; ch1 ← f.GetChar;
  IF mnem[i] = 'l THEN g.Put [IO.int[ch.ORD*256+ch1.ORD]]
  ELSE g.Put [IO.card[ch.ORD*256+ch1.ORD]];
  pc ← pc + 3 };
'd, 'm => { ch ← f.GetChar; ch1 ← f.GetChar;
  ch2 ← f.GetChar; ch3 ← f.GetChar;
  n ← ch3.ORD+(ch2.ORD+(ch1.ORD+ch.ORD*256)*256)*256;
  IF mnem[i] = 'm THEN { i ← 32*48 + n*6;
   WHILE mnem[i] # '. DO g.PutChar [mnem[i]]; i ← i+1 ENDLOOP }
  ELSE g.Put [IO.int[ LOOPHOLE [n, LONG INTEGER]]];
  pc ← pc + 5 };
'e => { ch ← f.GetChar;
  g.Put [IO.int [IF ch.ORD >= 128 THEN ch.ORD - 256 ELSE ch.ORD]];
  g.PutChar [' ];
  ch ← f.GetChar; g.Put [IO.card[ch.ORD]];
  pc ← pc + 3 };
'h => { ch ← f.GetChar; g.Put [IO.card[ch.ORD], IO.char [' ]];
  ch ← f.GetChar;
  g.Put [IO.card[ch.ORD/16], IO.char [' ], IO.card[ch.ORD MOD 16]];
  pc ← pc + 3 };
'i => { ch ← f.GetChar;
  g.Put [IO.card[ch.ORD/128], IO.card[(ch.ORD/64) MOD 2]];
  g.Put [IO.card[(ch.ORD/32) MOD 2], IO.card[(ch.ORD/16) MOD 2]];
  g.PutChar [' ];
  g.Put [IO.card[ch.ORD MOD 16], IO.char [' ]];
  ch ← f.GetChar;
  g.Put [IO.card[ch.ORD/16], IO.char[' ], IO.card[ch.ORD MOD 16]];
  pc ← pc + 3 };
'j => { ch ← f.GetChar;
  g.Put [IO.card[(ch.ORD/32) MOD 2], IO.char[' ]];
  g.Put [IO.card[(ch.ORD/16) MOD 2], IO.char[' ]];
  g.Put [IO.card[ch.ORD MOD 16]];
  pc ← pc + 2 };
'k => { ch ← f.GetChar;
  g.Put [IO.card[ch.ORD/128], IO.card[(ch.ORD/64) MOD 2]];
  g.Put [IO.card[(ch.ORD/32) MOD 2], IO.card[(ch.ORD/16) MOD 2]];
  g.PutChar [' ];
  g.Put [IO.card[ch.ORD MOD 16], IO.char [' ]];
  ch ← f.GetChar;
  g.Put [IO.int[IF ch.ORD >= 128 THEN ch.ORD - 256 ELSE ch.ORD]];
  pc ← pc + 3 };
ENDCASE;
g.PutChar ['\n]; k ← k + 1
ENDLOOP;
IF k > 0 THEN { len ← N;
g.Put [IO.rope ["average instruction length "], IO.real[len/k], IO.char['\n]] };
g.PutChar ['\n];
g.Put [IO.rope["entries"], IO.char['\n]]; PutTab;
g.Put [IO.rope["linkages"], IO.char['\n]]; PutTab;
g.Put [IO.rope["data"], IO.char['\n]];
g.Put [IO.card[nextno []], IO.char['\n], IO.char['\n]];
g.Put [IO.rope["literals"], IO.char['\n]];
N ← nextno []; g.Put [IO.card[N], IO.char['\n]];
FOR i: CARDINAL IN [0..N) DO ch ← f.GetChar;
g.PutChar [IF ch = '\000 THEN '\n ELSE ch]
ENDLOOP;
g.PutChar ['\n];
IF outmed # "*" THEN IO.Close [g];
IO.Close [f] }
ELSE (cmd.out).Put [IO.rope ["not an obj file"], IO.char['\n]] }
ELSE (cmd.out).Put [IO.rope ["failed"], IO.char['\n]] };
arg: CommandTool.ArgumentVector =
CommandTool.Parse [cmd: cmd ! CommandTool.Failed => msg ← "failed"];
i: CARDINAL ← 1;
Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "];
Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "];
Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "];
Enter ["XOPa XOPa XOPa XOPa XOPa XOPa XOPa XOPa "];
Enter ["XOPd XOPd XOPd XOPd XOPd XOPd XOPd XOPd "];
Enter ["XOPd XOPd XOPd XOPd XOPd XOPd XOPd XOPd "];
Enter ["XOPd DFCd LIQBd XOPd XOPd XOPd J5d DJd "];
Enter ["CALLm XOPd XOPd XOPd XOPd XOPd XOPd XOPd "];
Enter ["***a ***a RXa BCa ADDa SUBa LADDa LSUBa "];
Enter ["DUPa DISa EXCHa EXDISaSFCa SFCIa RETNa XOPa "];
Enter ["XOPa SMULa UDIVa XOPa KFCa XOPa J1a SJa "];
Enter ["LC0a LC1a LC2a LC3a LC4a LC5a LC6a LC7a "];
Enter ["LR0f LR1f LR2f LR3f LR4f LR5f LR6f LR7f "];
Enter ["LR8f LR9f LR10f LR11f LR12f LR13f LR14f LR15f "];
Enter ["SR0f SR1f SR2f SR3f SR4f SR5f SR6f SR7f "];
Enter ["SR8f SR9f SR10f SR11f SR12f SR13f SR14f SR15f "];
Enter ["QORj QANDj QRXj QBCj QADDj QSUBj QLADDjQLSUBj"];
Enter ["ALSb ALb ASLb ASb CSTb XOPb RETb RETKb "];
Enter ["LIPb SIPb LIBb SFPb ADDBb SUBBb J2b JBb "];
Enter ["RBb WBb RSBb WSBb PINb POUTb XOPb PSBb "];
Enter ["LRI0g LRI1g LRI2g LRI3g LRI4g LRI5g LRI6g LRI7g "];
Enter ["LRI8g LRI9g LRI10gLRI11gLRI12gLRI13gLRI14gLRI15g"];
Enter ["SRI0g SRI1g SRI2g SRI3g SRI4g SRI5g SRI6g SRI7g "];
Enter ["SRI8g SRI9g SRI10gSRI11gSRI12gSRI13gSRI14gSRI15g"];
Enter ["RORi RANDi RRXi RBCi RADDi RSUBi RLADDiRLSUBi"];
Enter ["RXORi ***i RFUi ***i RVADDiRVSUBiRUADDiRUSUBi"];
Enter ["LGFc LFCl LIDBc XOPc ADDDBcSUBDBcJ3c JDBl "];
Enter ["RAIh WAIh RRIh WRIh INb OUTb XOPh XOPh "];
Enter ["***k RJEBk RJLBk RJLEBk***k RJNEBkRJGEBkRJGBk "];
Enter ["***k RJNEJkRJGEJkRJGBJk***k RJEBJkRJLBJkRJLEJk"];
Enter ["JEBBe JNEBBeJEBBJeJNEBJeXOPe XOPe XOPe XOPe "];
Enter ["SHLc SHRc SHDc FSDBc FLIPc FLOPc XOPc XOPc "];
Enter ["Trap. Move. IMul. IDiv. Mod. RAdd. RSub. RMul. "];
Enter ["RDiv. Alloc.Dlloc.Bit. Bits. ***. ***. ***. "];
WHILE i+1 < arg.argc DO
DecodeFile [arg[i], arg[i+1]];
i ← i + 2
ENDLOOP;
IF i < arg.argc THEN DecodeFile [arg[i], "*"] };
Commander.Register [key: "modula", proc: M2, doc: "Modula-2 compiler"];
Commander.Register[key: "decode", proc: Decode, doc: "Decode Modula-2 object file"];
END.