Cx:
CEDAR
PROGRAM
IMPORTS Basics, VM
= BEGIN
Runs: TYPE = RECORD[start, num: CARDINAL];
Cp1:
PROC[srcL, dstL:
LONG
CARDINAL, count:
CARDINAL]
RETURNS[total: CARDINAL, lc: LIST OF Runs] = TRUSTED {
dst: LONG POINTER TO WORD ← LOOPHOLE[dstL];
src: LONG POINTER TO WORD ← LOOPHOLE[srcL];
lastBad: CARDINAL ← 0;
total ← 0;
lc ← LIST[[0, 1]];
FOR i:
CARDINAL
IN [0..count)
DO
IF dst^ # src^
THEN {
total ← total + 1;
IF i = lastBad + 1
THEN lc.first.num ← lc.first.num + 1
ELSE {
IF lc.first.num = 1 THEN lc.first.start ← i ELSE lc ← CONS[[i, 1], lc];
};
lastBad ← i;
};
dst ← LOOPHOLE[dst + 1];
src ← LOOPHOLE[src + 1];
ENDLOOP;
};
Cpx:
PROC[srcL, dstL:
LONG
CARDINAL, count:
CARDINAL]
RETURNS[total: CARDINAL, lc: LIST OF Runs] = TRUSTED {
dst: LONG POINTER TO WORD ← LOOPHOLE[dstL];
src: LONG POINTER TO WORD ← LOOPHOLE[srcL];
lastBad: CARDINAL ← 0;
total ← 0;
FOR i:
CARDINAL
IN [0..count)
DO
IF dst^ # src^
THEN {
total ← total + 1;
IF i = lastBad + 1
THEN lc.first.num ← lc.first.num + 1
ELSE lc ← CONS[[i, 1], lc];
lastBad ← i;
};
dst ← LOOPHOLE[dst + 1];
src ← LOOPHOLE[src + 1];
ENDLOOP;
};
Find:
PROC[start, badGuy:
LONG
POINTER
TO
WORD, length:
INT]
RETURNS[LONG POINTER TO WORD] = TRUSTED {
firstbad: WORD = badGuy^;
FOR i:
INT ← 0, i+400B
UNTIL i >= length
DO
BEGIN ENABLE VM.AddressFault => GOTO tryNext;
maybe: LONG POINTER TO WORD;
didMatch: BOOL ← TRUE;
IF (start+i)^ # firstbad THEN LOOP;
maybe ← LOOPHOLE[start+i];
FOR j:
INT
IN [0.. 400B)
DO
IF (maybe+j)^ # (badGuy+j)^ THEN GOTO noMatch;
ENDLOOP;
RETURN[maybe];
EXITS
noMatch => NULL;
tryNext => NULL;
END;
ENDLOOP;
RETURN[NIL];
};
Cp:
PROC[srcL, dstL:
LONG
POINTER, count:
CARDINAL]
RETURNS[lc: LIST OF CARDINAL] = TRUSTED {
dst: LONG POINTER TO WORD ← LOOPHOLE[dstL];
src: LONG POINTER TO WORD ← LOOPHOLE[srcL];
FOR i:
CARDINAL
IN [0..count)
DO
IF dst^ # src^ THEN lc ← CONS[i, lc];
dst ← LOOPHOLE[dst + 1];
src ← LOOPHOLE[src + 1];
ENDLOOP;
};
Zr:
PROC[srcL:
LONG
POINTER, count:
CARDINAL]
RETURNS[total: CARDINAL, lc: LIST OF Runs] = TRUSTED {
src: LONG POINTER TO WORD ← LOOPHOLE[srcL];
lastBad: CARDINAL ← 0;
total ← 0;
FOR i:
CARDINAL
IN [0..count)
DO
IF src^ # 0
THEN {
total ← total + 1;
IF i = lastBad + 1
THEN lc.first.num ← lc.first.num + 1
ELSE lc ← CONS[[i, 1], lc];
lastBad ← i;
};
src ← LOOPHOLE[src + 1];
ENDLOOP;
};
Xor:
PROC[a, b:
WORD]
RETURNS[
WORD] =
{ RETURN[Basics.BITXOR[a, b]] };