ViewRecAux.Mesa
Last Edited by: Spreitzer, March 10, 1983 4:55 pm
Last Edited by: Maxwell, March 11, 1983 10:56 am
DIRECTORY
AMBridge, AMTypes, Atom, Convert, IO, Rope, UserExec, VFonts, ViewRec;
ViewRecAux: CEDAR PROGRAM
IMPORTS AMBridge, AMTypes, Atom, Convert, IO, Rope, UserExec, VF:VFonts, ViewRec
EXPORTS ViewRec =
BEGIN OPEN ViewRec;
EnumData: TYPE = REF EnumDataRep;
EnumDataRep: TYPE = RECORD [
wideType: Type];
enumerationHandler: SimpleHandler ← NEW [SimpleHandlerRep ← [
Parse: ParseEnumeration,
UnParse: UnParseEnumeration,
Max: MaxEnumeration,
Butt: ButtEnumeration,
blueDoc: "Shift Blue => previous member of enumeration,
Not-Shift Blue => next member of enumeration,\n"]];
ParseEnumeration: ParseProc =
BEGIN
ed: EnumData ← NARROW[handlerData];
new: TypedVariable;
index: CARDINAL;
ok ← TRUE;
index ← AMTypes.NameToIndex[type: ed.wideType, name: asRope !AMTypes.Error => {ok ← FALSE; CONTINUE}];
IF NOT ok THEN {[index, ok] ← ParseCard[asRope]; index ← index+1};
IF NOT ok THEN RETURN [FALSE];
new ← AMTypes.Value[type: ed.wideType, index: index !AMTypes.Error => {ok ← FALSE; CONTINUE}];
IF ok THEN AMTypes.Assign[lhs: tv, rhs: new];
END;
ParseCard: PROC [asRope: ROPE] RETURNS [card: LONG CARDINAL, ok: BOOLEAN] =
BEGIN
v: Convert.Value;
stopPlace: INT;
TRUSTED {[v, stopPlace] ← Convert.Parse[text: [rope[asRope]], template: Convert.DefaultUnsigned]};
IF stopPlace < asRope.Length[] THEN RETURN [0, FALSE];
WITH v SELECT FROM
unsigned => RETURN [unsigned, TRUE];
ENDCASE => RETURN [0, FALSE];
END;
UnParseEnumeration: UnParseProc =
BEGIN
asRope ← MyTVToName[tv];
END;
MyTVToName: PROC [et: AMTypes.TypedVariable --of an enumerated type--]
RETURNS [r: ROPE] =
BEGIN
r ← AMTypes.TVToName[et !AMTypes.Error =>
TRUSTED {r ← IO.PutFR["%g", IO.card[AMBridge.TVToCardinal[et]]];
CONTINUE}];
END;
MaxEnumeration: MaxProc =
BEGIN
maxWidthNeeded ← 20;
FOR tv ← AMTypes.First[targType], AMTypes.Next[tv] WHILE tv # NIL DO
maxWidthNeeded ← MAX[maxWidthNeeded, VF.StringWidth[AMTypes.TVToName[tv !AMTypes.Error => EXIT]]];
ENDLOOP;
END;
ButtEnumeration: ButtProc =
BEGIN
IF shift THEN new ← EnumPrev[tv, targType] ELSE IF (new ← AMTypes.Next[tv]) = NIL THEN new ← AMTypes.First[targType];
END;
EnumPrev: PROC [of: TypedVariable, type: Type] RETURNS [is: TypedVariable] =
BEGIN
is ← AMTypes.First[type];
WHILE is # NIL DO
next: TypedVariable ← AMTypes.Next[is];
IF AMTypes.TVEqual[next, of] THEN RETURN;
is ← next;
ENDLOOP;
is ← AMTypes.Last[type];
END;
RecognizeEnumerations: PUBLIC Recognizer =
BEGIN
IF NOT onlyRecognize THEN
BEGIN
ed: EnumData ← NEW [EnumDataRep ← [
wideType: AMTypes.GroundStar[t] ]];
handler ← enumerationHandler;
handlerData ← ed;
END;
IKnowYou ← TRUE;
END;
NumData: TYPE = REF NumDataRep;
NumDataRep: TYPE = RECORD [
typeClass: AMTypes.Class,
cvt: ConvertProc,
parseTemplate: Convert.Value,
tempAsTV: TypedVariable ← NIL,
tempAsRef: REF ANY];
ConvertProc: TYPE = PROC [nd: NumData, v: Convert.Value]
RETURNS [ok: BOOLEAN];
numHandlerDatas: ARRAY AMTypes.Class OF NumData ← ALL[NIL];
numberHandler: SimpleHandler ← NEW [SimpleHandlerRep ← [
Parse: ParseNumber,
UnParse: UnParseNumber,
Max: MaxNumber,
Butt: NIL]];
ParseNumber: ParseProc =
BEGIN
nd: NumData ← NARROW[handlerData];
v: Convert.Value;
stopPlace: INT;
TRUSTED {[v, stopPlace] ← Convert.Parse[text: [rope[asRope]], template: nd.parseTemplate]};
IF stopPlace < asRope.Length[] THEN RETURN [FALSE];
IF (ok ← nd.cvt[nd, v]) THEN
BEGIN
AMTypes.Assign[tv, nd.tempAsTV !AMTypes.Error =>
{ok ← FALSE; CONTINUE}];
END;
END;
ToC: ConvertProc =
BEGIN
c: REF CARDINALNARROW[nd.tempAsRef];
WITH v SELECT FROM
unsigned => IF (ok ← unsigned IN [0..65536)) THEN c^ ← unsigned;
signed => IF (ok ← signed IN [0..65536)) THEN c^ ← signed;
ENDCASE => ok ← FALSE;
END;
ToI: ConvertProc =
BEGIN
i: REF INTEGERNARROW[nd.tempAsRef];
WITH v SELECT FROM
unsigned => IF (ok ← unsigned IN [0..32768)) THEN i^ ← unsigned;
signed => IF (ok ← (((ABS[signed] = 32768) AND (signed < 0)) OR (ABS[signed] <= 32767))) THEN i^ ← signed;
ENDCASE => ok ← FALSE;
END;
ToLC: ConvertProc =
BEGIN
c: REF LONG CARDINALNARROW[nd.tempAsRef];
WITH v SELECT FROM
unsigned => {ok ← TRUE; c^ ← unsigned};
signed => IF (ok ← signed >= 0) THEN c^ ← signed;
ENDCASE => ok ← FALSE;
END;
ToLI: ConvertProc =
BEGIN
i: REF LONG INTEGERNARROW[nd.tempAsRef];
limit: LONG CARDINAL = LAST[LONG INTEGER];
WITH v SELECT FROM
unsigned => IF (ok ← unsigned <= limit) THEN
i^ ← unsigned;
signed => {ok ← TRUE; i^ ← signed};
ENDCASE => ok ← FALSE;
END;
ToR: ConvertProc =
BEGIN
r: REF REALNARROW[nd.tempAsRef];
WITH v SELECT FROM
real => {r^ ← real; ok ← TRUE};
ENDCASE => ok ← FALSE;
END;
UnParseNumber: UnParseProc =
BEGIN
nd: NumData ← NARROW[handlerData];
AMTypes.Assign[nd.tempAsTV, tv];
BEGIN
v: Convert.Value ← SELECT nd.typeClass FROM
cardinal => [unsigned[NARROW[nd.tempAsRef, REF CARDINAL]^]],
integer => [signed[NARROW[nd.tempAsRef, REF INTEGER]^]],
longCardinal => [unsigned[NARROW[nd.tempAsRef, REF LONG CARDINAL]^]],
longInteger => [signed[NARROW[nd.tempAsRef, REF INT]^]],
real => [real[NARROW[nd.tempAsRef, REF REAL]^]],
ENDCASE => ERROR;
RETURN [Convert.ValueToRope[v]];
END;
END;
MaxNumber: MaxProc =
BEGIN
nd: NumData ← NARROW[handlerData];
maxWidthNeeded ← VF.StringWidth[SELECT nd.typeClass FROM
cardinal => "65,536",
integer => "-29,860",
longCardinal => "0,123,456,789",
longInteger => "-0,123,456,789",
real => "-3.456789E-29",
ENDCASE => ERROR];
END;
RecognizeNumber: PUBLIC Recognizer =
BEGIN
IF NOT onlyRecognize THEN
BEGIN
wt: Type ← AMTypes.GroundStar[t];
tc: AMTypes.Class ← AMTypes.TypeClass[wt];
handler ← numberHandler;
handlerData ← numHandlerDatas[tc];
END;
IKnowYou ← TRUE;
END;
ropeHandler: SimpleHandler ← NEW [SimpleHandlerRep ← [
Parse: ParseRope,
UnParse: UnParseRope,
Max: MaxRope,
Butt: NIL]];
ParseRope: ParseProc = TRUSTED
BEGIN
asTV: TypedVariable ← AMBridge.TVForROPE[asRope];
ok ← TRUE;
AMTypes.Assign[tv, asTV !AMTypes.Error => {ok ← FALSE; CONTINUE}];
END;
UnParseRope: UnParseProc =
BEGIN
asRope ← AMTypes.TVToName[tv];
END;
MaxRope: MaxProc = {RETURN [1024, 2]};
RecognizeRope: PUBLIC Recognizer =
BEGIN
IF NOT onlyRecognize THEN {handler ← ropeHandler; handlerData ← NIL};
IKnowYou ← TRUE;
END;
Setup: PROC =
BEGIN
countAsAny: REF ANY;
numHandlerDatas[cardinal] ← NEW [NumDataRep ← [typeClass: cardinal, cvt: ToC, parseTemplate: Convert.DefaultUnsigned, tempAsRef: NEW [CARDINAL] ]];
numHandlerDatas[integer] ← NEW [NumDataRep ← [typeClass: integer, cvt: ToI, parseTemplate: Convert.DefaultSigned, tempAsRef: NEW [INTEGER] ]];
numHandlerDatas[longCardinal] ← NEW [NumDataRep ← [typeClass: longCardinal, cvt: ToLC, parseTemplate: Convert.DefaultUnsigned, tempAsRef: NEW [LONG CARDINAL] ]];
numHandlerDatas[longInteger] ← NEW [NumDataRep ← [typeClass: longInteger, cvt: ToLI, parseTemplate: Convert.DefaultSigned, tempAsRef: NEW [LONG INTEGER] ]];
numHandlerDatas[real] ← NEW [NumDataRep ← [typeClass: real, cvt: ToR, parseTemplate: Convert.DefaultReal, tempAsRef: NEW [REAL] ]];
FOR c: AMTypes.Class IN AMTypes.Class DO
TRUSTED {
IF numHandlerDatas[c] # NIL THEN numHandlerDatas[c].tempAsTV ← AMBridge.TVForReferent[numHandlerDatas[c].tempAsRef]};
ENDLOOP;
RegisterRecognizerByType[r: RecognizeEnumerations, end: Back, type: CODE[ViewRec.AddPlace], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeNumber, end: Back, type: CODE[INTEGER], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeNumber, end: Back, type: CODE[CARDINAL], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeNumber, end: Back, type: CODE[LONG INTEGER], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeNumber, end: Back, type: CODE[LONG CARDINAL], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeNumber, end: Back, type: CODE[REAL], reductions: TypeClass];
RegisterRecognizerByType[r: RecognizeRope, end: Back, type: CODE[ROPE], reductions: TypeClass];
countAsAny ← Atom.GetProp[atom: $ViewRecCount, prop: $ViewRecCount];
IF countAsAny = NIL THEN
Atom.PutProp[atom: $ViewRecCount, prop: $ViewRecCount, val: NEW [INT ← 1]]
ELSE BEGIN
ri: REF INTNARROW[countAsAny];
eh: UserExec.ExecHandle ← UserExec.GetExecHandle[];
ri^ ← ri^ + 1;
eh.GetStreams[].out.PutF[
"ViewRec has been loaded %g times!
Confusion is likely to result.
I recommend you rollback and do things right.", IO.int[ri^]];
END;
END;
Setup[];
END.