--FILE: RandomCodeTestImpl.mesa
--Last Edited by: Sturgis, May 16, 1984 12:42:51 pm PDT



DIRECTORY
 IO USING[card, Close, int, PutF, STREAM],
 RandomCode USING[],
 RandomCodeRandom USING[InitRandom, RandomState],
 RandomCodeTypes USING[CreatePointerType, CreateProcedureType, CreateSeqType, CreateTypeSet, FillSeqType, GetOrdinaryWordType, SeqType, TypeSet, WordType],
 RandomCodeDragonMemory USING[CreateMemory, GenMemoryBytes, MemoryLayout, ShowMemory, TearDownProcedures, TypeCheckMemory],
 Rope USING[ROPE],
 ViewerIO USING[CreateViewerStreams];

RandomCodeTestImpl: CEDAR MONITOR IMPORTS IO, RandomCodeRandom, RandomCodeTypes, RandomCodeDragonMemory, ViewerIO EXPORTS RandomCode =

BEGIN
OPEN RandomCodeRandom, RandomCodeTypes, RandomCodeDragonMemory;




-- module main procedures

-- to test:
 -- bind RandomCodePackage
 -- run RandomCodePackage
 -- ← RandomCodeTestImpl.QuickeeTestA[5]
 -- ← RandomCodeTestImpl.QuickeeTestB[1, 4]

QuickeeTestA: PROCEDURE[seed: CARDINAL] =
 BEGIN
 dribble: IO.STREAM ← ViewerIO.CreateViewerStreams[name: "QuickeeTest", backingFile: "QuickeeTest"].out; 
 dropTheByte: PROC[[0..255]] = {NULL};

 dribble.PutF["info for randomSeed = %g\N", IO.card[seed]];
 GenerateRandomProgramBytes[0, seed, dropTheByte, dribble];
 dribble.PutF["\N\N\N"];

 dribble.Close[];
 END;

QuickeeTestB: PROCEDURE[firstSeed: CARDINAL, nSeeds: CARDINAL] =
 BEGIN
 dribble: IO.STREAM ← ViewerIO.CreateViewerStreams[name: "QuickeeTest", backingFile: "QuickeeTest"].out; 
 dropTheByte: PROC[[0..255]] = {NULL};

 FOR I: CARDINAL IN [firstSeed..firstSeed+nSeeds) DO
  GenerateRandomProgramBytes[0, I, dropTheByte, NIL];
  dribble.PutF["correctly ran for seed %g\N", IO.card[I]];
  ENDLOOP;

 dribble.Close[];
 END;

GenerateRandomProgramBytes: PUBLIC PROCEDURE[
 initialByteAddress: INT,
 randomSeed: CARDINAL,
 seeOneByte: PROC[[0..255]],
 dribble: IO.STREAM] =

 BEGIN
 pointerRootSeqType: WordType; 
 memoryLayout: MemoryLayout;
 currentMemByteAddress: INT;
 randomState: RandomState ← InitRandom[randomSeed];
     
 EachByte: PROCEDURE[byte: [0..255]] =
  BEGIN
  IF dribble # NIL THEN
   BEGIN
   IF currentMemByteAddress MOD 4 = 0 THEN dribble.PutF[" "];
   IF currentMemByteAddress MOD 16 = 0 THEN
    dribble.PutF["\N%g:", IO.int[currentMemByteAddress]];
   dribble.PutF[" %g", IO.card[byte]];
   currentMemByteAddress ← currentMemByteAddress + 1;
   END;
  seeOneByte[byte];
  END;
     
  
 pointerRootSeqType ← ConstructRootSeqType[];
 memoryLayout ← CreateMemory[initialByteAddress, pointerRootSeqType, randomState];
 IF dribble # NIL THEN ShowMemory[memoryLayout, dribble];
 TypeCheckMemory[memoryLayout];
 currentMemByteAddress ← initialByteAddress;
 GenMemoryBytes[memoryLayout, EachByte];
 TearDownProcedures[memoryLayout];
 END;

ConstructRootSeqType: PROCEDURE RETURNS[pointerToRootSeqType: WordType] =
 BEGIN
 typeSet: TypeSet ← CreateTypeSet[10];
 ordinaryWordType: WordType ← GetOrdinaryWordType[typeSet];
 rootSeqType: SeqType ← CreateSeqType[typeSet, "rootSeq", 7];
 rootProcArgs: SeqType ← CreateSeqType[typeSet, "rootProcArgs", 1];
 seqType2: SeqType ← CreateSeqType[typeSet, "r2", 3]; 
 seqType3: SeqType ← CreateSeqType[typeSet, "r3", 3]; 
 seqType4: SeqType ← CreateSeqType[typeSet, "r4", 3]; 
 seqType5: SeqType ← CreateSeqType[typeSet, "r5", 5];
 pointerRootSeqType: WordType;
 rootProcType: WordType ← CreateProcedureType[typeSet, "rootProc", rootProcArgs, NIL];
 pointerT2: WordType ← CreatePointerType[typeSet, seqType2];
 pointerT3: WordType ← CreatePointerType[typeSet, seqType3];
 pointerT4: WordType ← CreatePointerType[typeSet, seqType4];
 pointerT5: WordType ← CreatePointerType[typeSet, seqType5];


 GenRootSeqType: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  BEGIN
  rootType: ARRAY [0..6) OF WordType ← [pointerRootSeqType, rootProcType, pointerT2, pointerT3, pointerT4, pointerT5];
  IF i < 6 THEN RETURN[rootType[i]];
  RETURN[ordinaryWordType];
  END;
  
 GenRootProcArgs: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  {IF i = 0 THEN RETURN[pointerRootSeqType] ELSE ERROR};
  
 GenSeqType2: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  {RETURN[ordinaryWordType]};
  
 GenSeqType3: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  {RETURN[ordinaryWordType]};
  
 GenSeqType4: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  BEGIN
  IF i = 0 THEN RETURN[pointerT2]
   ELSE RETURN[ordinaryWordType]
  END;
  
 GenSeqType5: PROCEDURE[i: CARDINAL] RETURNS[WordType] =
  BEGIN
  type5: ARRAY [0..4) OF WordType ← [pointerT2, pointerT3, pointerT4, pointerT5];
  IF i < 4 THEN RETURN[type5[i]];
  RETURN[ordinaryWordType];
  END;

 pointerRootSeqType ← CreatePointerType[typeSet, rootSeqType]; 
 FillSeqType[rootSeqType, GenRootSeqType];
 FillSeqType[rootProcArgs, GenRootProcArgs];
 FillSeqType[seqType2, GenSeqType2];
 FillSeqType[seqType3, GenSeqType3];
 FillSeqType[seqType4, GenSeqType4];
 FillSeqType[seqType5, GenSeqType5];
 RETURN[pointerRootSeqType];
 END;

END.
MODULE HISTORY
Initial by: Sturgis, April 26, 1984 5:00:16 pm PST
Remark: April 29, 1984 3:10:20 pm PDT: first more or less random, presumably type safe, graph produced. 97 nodes. Some choices that should be random are not yet. some information (in praticular ordinary word type) transmitted by wrong path, should be handed about during type checking, rather than during construction, and subsequently saved? No random choices of making loops and branches yet. Need another word type for loop variables, so I can assure that loops all complete. need code to introduce procedure calls. need preamble and post amble. need real dragon ops. etc.
Remark: May 3, 1984 4:50:49 pm PDT: Today I generated my first graph with only dragon ops in it. Yet to do: procedure call, procedure body preamble and postamble, tighter control on the loop control, and control on the depth of procedure call nesting. Finally, must also generate "binary" output, which means assigning addresses to the op codes, and watching out for the jumps whose addresses won't fit.
Remark: May 7, 1984 4:04:55 pm PDT: now have preamble and postamble constructed, including the stack pointer manipulation. Discovered that sometimes one pushes onto the end of the local variables, rather than onto the stack (stack must be empty). Do not have procedure call, control on loops or control on procedure call nesting. Have not yet generated binary output.
Remark: May 15, 1984 12:05:14 pm PDT: now able to generate the bytes of a program, and the associated global data. Have not yet tested it by calls from the IDL world.
RTE: May 17, 1984 12:22:22 pm PDT: the bytes of an INT to be used in a 5 byte instruction must be delivered in reverse order.
RTE: May 17, 1984 3:46:14 pm PDT: initial code contained byte pointers, rather than word pointers.
Change: October 10, 1984 4:24:03 pm PDT: lots of code removed and placed in new modules.