<> <> 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 ANY _ NIL] -- 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.