--User-level procs for manipulating descriptors
--Turn a list of ropes in a vanilla descriptor of the appropriate size
RopesToDescr:
PUBLIC
PROC [names:
LIST
OF
ROPE, genRef:
REF ←
NIL]
RETURNS [descr: Descriptor] =
BEGIN
n: INT ← 0;
-- Size of the list?
FOR l: LIST OF ROPE ← names, l.rest WHILE l#NIL DO n ← n+1; ENDLOOP;
-- Now create the descriptor. . .
descr ← NEW[DescriptorRec[n]];
descr.genRef ← genRef;
-- . . . and precise only the names
n ← -1; -- just reusing the variable
FOR l:
LIST
OF
ROPE ← names, l.rest
WHILE l#
NIL
DO
descr[n ← n+1] ← NEW[ItemRec ← [l.first]];
ENDLOOP;
END;
-- Set the type of an item
SetTypeBit:
PUBLIC
PROC [descr: Descriptor, name:
ROPE, initVal:
BOOL ←
FALSE, data:
REF ←
NIL] =
-- data useless???
BEGIN
i: INT ← IndexInDescr[descr, name];
descr[i].specificRef ← NEW[BitRec ← [initVal]];
descr[i].data ← data; -- ???
END;
SetTypeBool:
PUBLIC
PROC [descr: Descriptor, name:
ROPE, initVal:
BOOL ←
FALSE, complement:
BOOL ←
FALSE, data:
REF ←
NIL] =
BEGIN
i: INT ← IndexInDescr[descr, name];
descr[i].specificRef ←
NEW[BoolRec ← [initVal, IF complement THEN ~initVal ELSE initVal]];
descr[i].data ← data; -- ???
END;
SetTypeInt:
PUBLIC
PROC [descr: Descriptor, name:
ROPE, nbBits:
INT, initVal:
INT ← 0
, complement:
INT ← 0, data:
REF ←
NIL] =
BEGIN
index: INT ← IndexInDescr[descr, name];
intRef: IntRef ← NEW[IntRec[nbBits]];
intRef.val ← initVal MOD PW.TwoToThe[nbBits];
intRef.mask ← complement MOD PW.TwoToThe[nbBits];
-- Decompose the integer in a sequence of booleans
FOR i:
INT
DECREASING
IN [0..nbBits)
DO
intRef[i] ←
NEW[BoolRec ← [
PW.ODD[initVal],
IF PW.ODD[complement] THEN ~PW.ODD[initVal] ELSE PW.ODD[initVal]]];
initVal ← initVal/2; -- shift
complement ← complement/2;
ENDLOOP;
descr[index].specificRef ← intRef;
descr[index].data ← data; -- ???
END;
SetTypePad:
PUBLIC
PROC [descr: Descriptor, name:
ROPE, padRef: PadRef, data:
REF ←
NIL]
=
BEGIN
i: INT ← IndexInDescr[descr, name];
descr[i].specificRef ← padRef;
descr[i].data ← data;
END;
-- Set the value of an item
SetBit:
PUBLIC PROC [descr: Descriptor, name:
ROPE, val:
BOOL] =
BEGIN
item: Item ← NameToItem[descr, name];
r: BitRef ← NARROW[item.specificRef];
r.val ← val;
END;
SetBool:
PUBLIC PROC [descr: Descriptor, name:
ROPE, val:
BOOL, complement:
BOOL ←
TRUE] =
BEGIN
item: Item ← NameToItem[descr, name];
r: BoolRef ← NARROW[item.specificRef];
r.val0 ← val;
r.val1 ← IF complement THEN ~val ELSE val;
END;
SetInt:
PUBLIC PROC [descr: Descriptor, name:
ROPE, val:
INT, complement:
INT ← allOnes] =
BEGIN
item: Item ← NameToItem[descr, name];
intRef: IntRef ← NARROW[item.specificRef];
nbBits: INT ← intRef.nbBits;
intRef.val ← val MOD PW.TwoToThe[nbBits];
intRef.mask ← complement MOD PW.TwoToThe[nbBits];
FOR i:
INT
DECREASING
IN [0..nbBits)
DO
-- get low-order
intRef[i].val0 ← PW.ODD[val];
intRef[i].val1 ← IF PW.ODD[complement] THEN ~PW.ODD[val] ELSE PW.ODD[val];
val ← val/2; -- shift
complement ← complement/2;
ENDLOOP;
END;
SetMask: PUBLIC PROC [descr: Descriptor, name: ROPE, mask: INT] =
BEGIN
item: Item ← NameToItem[descr, name];
WITH item.specificRef SELECT FROM
boolRef: BoolRef => boolRef.mask ← PW.ODD[mask];
intRef: IntRef => {
nbBits: INT ← intRef.nbBits;
intRef.mask ← mask;
FOR i: INT DECREASING IN [0..nbBits) DO
intRef[i].mask ← PW.ODD[mask]; -- get low-order
mask ← mask/2; -- shift
ENDLOOP;
};
ENDCASE => ERROR;
END;
SetData:
PUBLIC PROC [descr: Descriptor, name:
ROPE, data:
REF] =
{NameToItem[descr, name].data ← data};
NameToItem:
PUBLIC PROC [descr: Descriptor, name:
ROPE]
RETURNS [item: Item] =
{item ← descr[IndexInDescr[descr, name]]};
IsInDescr:
PUBLIC PROC [descr: Descriptor, name:
ROPE]
RETURNS [yes:
BOOL] =
{yes ← IndexInDescr[descr, name, FALSE]>=0};