PWDescrImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Last Edited by: Monier, May 29, 1985 4:18:03 pm PDT
DIRECTORY
CD, PW, PWDescr, Rope;
PWDescrImpl: CEDAR PROGRAM
IMPORTS PW, Rope
EXPORTS PWDescr =
BEGIN OPEN PWDescr;
--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: REFNIL] 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: BOOLFALSE, data: REFNIL] = -- 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: BOOLFALSE, complement: BOOLFALSE, data: REFNIL] =
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: REFNIL] =
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: REFNIL] =
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: BOOLTRUE] =
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};
-- Enumeration procs (the order matters)
EnumerateItems: PUBLIC PROC [descr: Descriptor, forEachItemDo: ForEachItemProc] =
{FOR i: INT IN [0..descr.size) DO forEachItemDo[descr[i]]; ENDLOOP;};
-- Internal utilities
IndexInDescr: PROC [descr: Descriptor, name: ROPE, boundCheck: BOOLTRUE] RETURNS [index: INT] =
BEGIN
index ← -1;
FOR i: INT IN [0..descr.size) DO
IF Rope.Equal[name, descr[i].name] THEN {index ← i; EXIT};
ENDLOOP;
IF index<0 AND boundCheck THEN ERROR;
END;
END.