--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.