RMTWTestSubjectImpl.mesa
Sturgis, March 13, 1990 2:53 pm PST
DIRECTORY
IO USING[card, PutF, rope, STREAM],
Process USING[CheckForAbort],
RMTWTestSubject USING[],
Rope USING[ActionType, Equal, Index, Length, Map, ROPE, Substr],
StackCirio USING[InterpretTextLine, Stack, WalkStack];
RMTWTestSubjectImpl: CEDAR PROGRAM IMPORTS IO, Process, StackCirio, Rope EXPORTS RMTWTestSubject =
BEGIN
Subject Stack Examination
TestDescriptor: TYPE = RECORD[
expression: Rope.ROPE,
expectedResult: Rope.ROPE,
compareNCharsOnly: CARD ← 0,
validity: Validity ← valid];
Validity: TYPE = {valid, proc, uninitializedVar, WRONG};
ExamineSubjectStack: PUBLIC PROC[stack: StackCirio.Stack, local: BOOLEAN, reports: IO.STREAM] =
BEGIN
nUnexpectedResults: CARD ← 0;
now we examine the located frame
(commented out until we can show the global frame in less than n-squared time)
BEGIN
frameText: Rope.ROPE ← StackCirio.ShowCurrentFrame[stack, reports];
IO.PutF[reports, "\n\n%g\n\n", IO.rope[frameText]];
END;
now we perform the individual expression tests
BEGIN
frame2Tests: LIST OF TestDescriptor ← LIST[
 ["c", "'a"],
 ["quit", "FALSE"],
 ["bool1", "FALSE"],
 ["bool2", "TRUE"],
 ["charA", "'A"],
 ["charB", "'b"],
 ["array1", "(7)[6, 8, 10, 12, 14, 16, 18]"],
 ["array2", "(6)[11, 13, 15, 17, 19, 21]"],
 ["refR", "^[a:7, b:8]"],
 ["bb", "[ref:^[ref:NIL, a:45, b:46], a:47, b:48]"],
 ["refSeq", "^[x:10, (5)[3, 7, 11, 15, 19]]"],
 ["refSeq2", "^[y:45, (7)[TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE]]"],
 ["ref2Seq2", "^[y:77, (32)[TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, ...]]"],
 ["b", "[a:6, b:7]"],
 ["w", "[x:[a:4, b:5], y:[u:6, v:7]]"],
 ["y", "failure due to illegal operation: y undefined"],
 ["action", "RMTWTestSubjectImpl.bar.action(pc=137CE78h, descr at 2BF10Ch, src=8557)", 29, proc],
 ["foo", "RMTWTestSubjectImpl.(no name)(pc=137CCE0h, descr at 139B880h, src=8208)", 28, proc],
 ["bar", "RMTWTestSubjectImpl.bar(pc=137CCF4h, descr at 139B878h, src=8228)", 24, proc],
 ["x", "10", 6, proc],
 ["veryBad", "RMTWTestSubjectImpl(pc=1379868h, descr at 139B898h, src=372)", 18, proc],
 ["CallDebugger", "failure due to illegal operation: CallDebugger undefined"]];
nUnexpectedResults ← ExamineOneFrame[stack, frame2Tests, reports] + nUnexpectedResults;
END;
lets skip a frame and look at the following frame
[] ← StackCirio.WalkStack[stack, 2, reports];
and examine
(commented out until we can show the global frame in less than n-squared time)
BEGIN
frameText: Rope.ROPE ← StackCirio.ShowCurrentFrame[stack, reports];
IO.PutF[reports, "\n\n%g\n\n", IO.rope[frameText]];
END;
now we perform the individual expression tests
BEGIN
frame3Tests: LIST OF TestDescriptor ← LIST[
 ["deep", "1606016"],
 ["rope", "^[(text)[..., (3)[[...]]]]"],
 ["arg1", "1234"],
 ["arg2", "5678"],
 ["res1", "2468"],
 ["res2", "22712"],
 ["z", "8518320"],
 ["yy", "3807"],
 ["ll", "x"],
 ["mm", "f"],
 ["q", "RMTWTestSubjectImpl.bar.q(pc=137D8F0h, descr at 2BF104h, src=9735)", 24, proc],
 ["b", "[a:6, b:7]"],
 ["w", "[x:[a:4, b:5], y:[u:6, v:7]]"],
 ["y", "failure due to illegal operation: y undefined"],
 ["action", "RMTWTestSubjectImpl.bar.action(pc=137CE78h, descr at 2BF10Ch, src=8557)", 29, proc],
 ["foo", "RMTWTestSubjectImpl.(no name)(pc=137CCE0h, descr at 139B880h, src=8208)", 28, proc],
 ["bar", "RMTWTestSubjectImpl.bar(pc=137CCF4h, descr at 139B878h, src=8228)", 22, proc],
 ["x", "10"],
 ["veryBad", "RMTWTestSubjectImpl(pc=1379868h, descr at 139B898h, src=372)", 18, proc],
 ["CallDebugger", "failure due to illegal operation: CallDebugger undefined"],
 ["r", ""],
 ["rData", "3456"],
 ["rData ← 34", "34"],
 ["rData", "34"]];
frame3LocalTests: LIST OF TestDescriptor ← LIST[
 ["rData", "34"],
 ["r[4567]", "34"],
 ["rData", "4567"]];
nUnexpectedResults ← ExamineOneFrame[stack, frame3Tests, reports] + nUnexpectedResults;
IF local THEN
nUnexpectedResults ← ExamineOneFrame[stack, frame3LocalTests, reports] + nUnexpectedResults;
END;
overall result:
IF nUnexpectedResults = 0 THEN IO.PutF[reports, "\N\NThere were NO unexpected results\N\N"]
ELSE IO.PutF[reports, "\N\NThere were %g unexpected results\N\N", IO.card[nUnexpectedResults]];
END;
ExamineOneFrame: PROC[stack: StackCirio.Stack, tryThis: LIST OF TestDescriptor, reports: IO.STREAM] RETURNS[--nUnexpectedResults-- CARD] =
BEGIN
ResultDescriptor: TYPE = RECORD[
expression: Rope.ROPE,
expectedResult: Rope.ROPE,
actualResult: Rope.ROPE];
deltas: LIST OF ResultDescriptor ← NIL;
lastDelta: LIST OF ResultDescriptor ← NIL;
news: LIST OF TestDescriptor ← NIL;
lastNew: LIST OF TestDescriptor ← NIL;
nUnexpectedResults: CARD ← 0;
FOR tests: LIST OF TestDescriptor ← tryThis, tests.rest WHILE tests # NIL DO
result: Rope.ROPE ← StackCirio.InterpretTextLine[stack, tests.first.expression, reports];
new: LIST OF TestDescriptor ← LIST[[tests.first.expression, result, tests.first.compareNCharsOnly, tests.first.validity]];
nChars: CARDIF tests.first.compareNCharsOnly > 0 THEN tests.first.compareNCharsOnly ELSE Rope.Length[tests.first.expectedResult];
Process.CheckForAbort[];
IF news = NIL THEN news ← new ELSE lastNew.rest ← new;
lastNew ← new;
IO.PutF[reports, "for expression: %g we get\N\T%g\N", IO.rope[tests.first.expression], IO.rope[result]];
IF (tests.first.validity # uninitializedVar) AND NOT Rope.Equal[Rope.Substr[result, 0, nChars], Rope.Substr[tests.first.expectedResult, 0, nChars]] THEN
BEGIN
delta: LIST OF ResultDescriptor ← LIST[[tests.first.expression, tests.first.expectedResult, result]];
IO.PutF[reports, " THIS IS WRONG, we expected\N\T%g\N\N", IO.rope[tests.first.expectedResult]];
IF deltas = NIL THEN deltas ← delta ELSE lastDelta.rest ← delta;
lastDelta ← delta;
nUnexpectedResults ← nUnexpectedResults + 1;
END;
ENDLOOP;
IO.PutF[reports, "\N\Nhere is a list of expressions with their actual results\N"];
FOR items: LIST OF TestDescriptor ← news, items.rest WHILE items # NIL DO
IO.PutF[reports, "\T[\"%g\", \"%g\"", IO.rope[items.first.expression], IO.rope[items.first.expectedResult]];
SELECT items.first.validity FROM
valid =>
IF items.first.compareNCharsOnly > 0 THEN
IO.PutF[reports, ", %g", IO.card[items.first.compareNCharsOnly]]
ELSE NULL;
proc =>
BEGIN
nChars: CARD ← Rope.Index[items.first.expectedResult, 0, "(pc="]+4;
IO.PutF[reports, ", %g, proc", IO.card[nChars]];
END;
uninitializedVar =>
IO.PutF[reports, ", 0, uninitializedVar"];
WRONG =>
IO.PutF[reports, ", 0, WRONG"];
ENDCASE => ERROR;
IO.PutF[reports, "],\N"];
ENDLOOP;
IF deltas # NIL THEN
BEGIN
IO.PutF[reports, "\N\Nthere were unexpected results\N"];
FOR items: LIST OF ResultDescriptor ← deltas, items.rest WHILE items # NIL DO
IO.PutF[reports, "\Texpression: %g\N", IO.rope[items.first.expression]];
IO.PutF[reports, "\Texpected result: %g\N", IO.rope[items.first.expectedResult]];
IO.PutF[reports, "\Tactual result: %g\N", IO.rope[items.first.actualResult]];
ENDLOOP;
END
ELSE IO.PutF[reports, "\N\Nthere were NO unexpected results\N\N"];
RETURN[nUnexpectedResults];
END;
Test Subject
R: TYPE = RECORD[a, b: INT];
S: TYPE = RECORD[x: R, y: RECORD[u: INT, v: CARD]];
b: R ← [6, 7];
w: S ← [[4, 5], [6, 7]];
Subject: PUBLIC PROC[local: BOOLEAN, inner: PROC[CARD32]] =
{[] ← bar[1234, 5678, inner]};
foo: PROC ← {NULL};
bar: PROC[arg1: INT, arg2: INT, debug: PROC[key: CARD32]] RETURNS[res1: INT, res2: INT] =
BEGIN
ENABLE UNWIND => NULL;
z: INT ← 8518320; -- should be placed in the frame extension because it is referenced from q
yy: INT ← 3807;
LL: TYPE = {w, x, y, z};
ll: LL ← x;
MM: TYPE = MACHINE DEPENDENT { a (0), b (1), c(2), d(3), f(5), end (25)};
mm: MM ← f;
action: Rope.ActionType =
BEGIN
bool1: BOOLEANFALSE;
bool2: BOOLEANTRUE;
charA: CHAR ← 'A;
charB: CHARACTER ← 'b;
array1: ARRAY [3..9] OF INT;
array2: PACKED ARRAY [5..10] OF INT[0..128);
refR: REF R ← NEW[R←[7, 8]];
B: TYPE = RECORD[ref: REF B, a, b: INT];
bb: B ← [NEW[B←[NIL, 45, 46]], 47, 48];
Seq: TYPE = RECORD[x: INT, fields: SEQUENCE nFields: CARD16 OF INT];
we use CARD16 so that this will compile on a D-machine.
we need to compile on a D-Machine because our companion code, ExamineOneFrame, will be executed on a D-machine. It would be better if we could test with CARD.
refSeq: REF Seq ← NEW[Seq[5]];
Seq2: TYPE = RECORD[y: INT, fields: PACKED SEQUENCE nFields: [0..45) OF BOOLEAN];
refSeq2: REF Seq2 ← NEW[Seq2[7]];
ref2Seq2: REF Seq2 ← NEW[Seq2[32]];
FOR I: INT IN [3..9] DO array1[I] ← 2*I ENDLOOP;
FOR I: INT IN [5..10] DO array2[I] ← 2*I+1 ENDLOOP;
refSeq.x ← 10;
FOR I: INT IN [0..5) DO refSeq.fields[I] ← 4*I+3 ENDLOOP;
refSeq2.y ← 45;
FOR I: INT IN [0..7) DO refSeq2.fields[I] ← SELECT I FROM
0 => TRUE,
1 => TRUE,
2 => FALSE,
3 => TRUE,
4 => FALSE,
5 => FALSE,
6 => TRUE,
ENDCASE => ERROR
ENDLOOP;
ref2Seq2.y ← 77;
FOR I: INT IN [0..32) DO
x: CARD ← (I/4)+1;
bit: CARD ← I MOD 4;
ref2Seq2.fields[I] ← SELECT bit FROM
0 => (x MOD 2) = 1,
1 => (x/2 MOD 2) = 1,
2 => (x/4 MOD 2) = 1,
3 => (x/8 MOD 2) = 1,
ENDCASE => ERROR
ENDLOOP;
debug[444444];
RETURN[FALSE];
END;
q: PROC[a: INT] =
BEGIN
ENABLE UNWIND => NULL;
deep: INT ← 1606016;
rope: Rope.ROPE ← "abc";
[] ← Rope.Map[rope, 0, Rope.Length[rope], action];
debug[8511261];
x ← z-9;
END;
rData: INT ← 3456;
r: PROC[a: INT] RETURNS[INT] =
{res: INT ← rData; rData ← a; RETURN[res]};
res1 ← arg1*2; res2 ← arg2*4;
foo[!veryBad =>
BEGIN
q[33333];
x ← x+11
END];
inner block of bar
BEGIN
fluff: INT ← 45;
q[22222];
END;
END;
x: INT ← 10;
veryBad: SIGNAL[y: INT] RETURNS[BOOLEAN] = CODE;
END..