HexDisplayer.mesa
Last edited by: McCreight, April 6, 1984 10:08:37 am PST
DIRECTORY
AMTypes, AMBridge, Convert, Dragon, Process, Rope, VFonts, ViewRec;
HexDisplayer: CEDAR PROGRAM IMPORTS AMTypes, AMBridge, Convert, Process, Rope, VFonts, ViewRec =
BEGIN
hexHandler: ViewRec.SimpleHandler = NEW [ViewRec.SimpleHandlerRep ← [
Parse: ParseHex,
UnParse: UnParseHex,
Max: MaxHex,
Butt: NIL]];
hexWordInstance: REF Dragon.HexWord = NEW[Dragon.HexWord];
tvHexWordInstance: AMTypes.TypedVariable;
wordMax: REF Dragon.HexWord = NEW[Dragon.HexWord ← LAST[Dragon.HexWord]];
byteMax: REF Dragon.HexWord = NEW[Dragon.HexWord ← LAST[Dragon.HexByte]];
ParseHex: PROC [asRope: Rope.ROPE, tv: AMTypes.TypedVariable, targType: AMTypes.Type, handlerData: REF ANY] RETURNS [ok: BOOLEAN] -- ViewRec.ParseProc -- =
BEGIN
ok ← TRUE;
hexWordInstance^ ← Convert.CardFromWholeNumberLiteral[asRope !Convert.Error => {ok ← FALSE; CONTINUE}];
IF NARROW[handlerData, REF Dragon.HexWord]^ < hexWordInstance^ THEN ok ← FALSE;
IF ok THEN
BEGIN
AMTypes.Assign[tv, tvHexWordInstance !AMTypes.Error =>
{ok ← FALSE; CONTINUE}];
END;
END;
UnParseHex: PROC [tv: AMTypes.TypedVariable, targType: AMTypes.Type, handlerData: REF ANY] RETURNS [asRope: Rope.ROPE] -- ViewRec.UnParseProc -- =
BEGIN
AMTypes.Assign[tvHexWordInstance, tv];
asRope ← Convert.RopeFromCard[from: hexWordInstance^, base: 16, showRadix: TRUE];
END;
MaxHex: PROC [tv: AMTypes.TypedVariable, targType: AMTypes.Type, handlerData: REF ANY] RETURNS [maxWidthNeeded: INTEGER, lines: REAL ← 1] -- ViewRec.MaxProc -- =
BEGIN
maxWidthNeeded ← VFonts.StringWidth[Convert.RopeFromCard[from: NARROW[handlerData, REF Dragon.HexWord]^, base: 16, showRadix: TRUE]];
END;
HexRecognizer: PROC [
t: AMTypes.Type,  --unreduced
onlyRecognize: BOOLEAN,--don't bother to produce the handler and handlerData
specs: ViewRec.BindingList, --what will apply to this element
createOptions: ViewRec.CreateOptions--for aggregate containing this elt
]
RETURNS [
IKnowYou: BOOLEAN,
handler: ViewRec.Handler,
handlerData: REF ANYNIL] -- ViewRec.Recognizer -- =
BEGIN
handler ← hexHandler;
IKnowYou ← FALSE;
WHILE NOT IKnowYou DO
name: Rope.ROPE = AMTypes.TypeToName[t];
SELECT TRUE FROM
Rope.Equal[name, "HexWord"] => {IKnowYou ← TRUE; handlerData ← wordMax};
Rope.Equal[name, "HexByte"] => {IKnowYou ← TRUE; handlerData ← byteMax};
AMTypes.TypeClass[t] = definition => t ← AMTypes.Ground[t];
AMTypes.TypeClass[t] = subrange => t ← AMTypes.Ground[t];
ENDCASE => EXIT;
ENDLOOP;
END;
Calculator: TYPE = RECORD [
byteAddressHex: Dragon.HexWord ← 0,
byteAddressDec: Dragon.Word ← 0,
wordAddressHex: Dragon.HexWord ← 0,
wordAddressDec: Dragon.Word ← 0,
byteOffset: [0..4) ← 0
];
calc: REF Calculator = NEW[Calculator ← []];
CalculatorUpdater: PROC =
BEGIN
maxBytesInWords: Dragon.Word = Dragon.Word[32768]*Dragon.Word[32768]; -- 2^30
byte: [0..4) ← 0;
word: Dragon.Word ← 0;
DO
SELECT TRUE FROM
(calc.wordAddressHex # word) OR (calc.byteOffset # byte) => {word ← calc.wordAddressHex; byte ← calc.byteOffset};
(calc.wordAddressDec # word) OR (calc.byteOffset # byte) => {word ← calc.wordAddressDec; byte ← calc.byteOffset};
((calc.byteAddressHex/4) # (word MOD maxBytesInWords)) OR ((calc.byteAddressHex MOD 4) # byte) =>
{word ← calc.byteAddressHex/4; byte ← calc.byteAddressHex MOD 4};
((calc.byteAddressDec/4) # (word MOD maxBytesInWords)) OR ((calc.byteAddressDec MOD 4) # byte) =>
{word ← calc.byteAddressDec/4; byte ← calc.byteAddressDec MOD 4};
ENDCASE => NULL;
calc.byteAddressHex ← calc.byteAddressDec ← 4*(word MOD maxBytesInWords)+byte;
calc.wordAddressHex ← calc.wordAddressDec ← word;
calc.byteOffset ← byte;
Process.Pause[Process.MsecToTicks[500]];
ENDLOOP;
END;
TRUSTED {tvHexWordInstance ← AMBridge.TVForReferent[hexWordInstance]};
ViewRec.RegisterRecognizerBeforeReductions[r: HexRecognizer, end: Front, applyBefore: EquivalenceClass];
[] ← ViewRec.ViewRef[agg: calc, label: "Dragon radix calculator "];
TRUSTED {Process.Detach[FORK CalculatorUpdater[]]};
END.