CommanderImpl.mesa
Larry Stewart, November 3, 1983 2:09 pm
DIRECTORY
Commander,
CommandExtras,
List USING [AList, Assoc, PutAssoc],
Rope USING [Equal, FromRefText, ROPE],
SymTab USING [Create, Delete, EachPairAction, Fetch, Pairs, Ref, Store];
CommanderImpl: CEDAR MONITOR
IMPORTS List, Rope, SymTab
EXPORTS Commander, CommandExtras =
BEGIN
Export routines to CommandExtras interface
uninterpreted: LIST OF Commander.CommandProcHandle ← NIL;
MakeUninterpreted: PUBLIC PROC [cp: Commander.CommandProcHandle] = {
IF NOT IsUninterpreted[cp] THEN uninterpreted ← CONS[cp, uninterpreted];
};
IsUninterpreted: PUBLIC PROC [cp: Commander.CommandProcHandle] RETURNS [BOOL] = {
list: LIST OF Commander.CommandProcHandle ← uninterpreted;
UNTIL list = NIL DO
IF list.first = cp THEN RETURN[TRUE];
list ← list.rest;
ENDLOOP;
RETURN[FALSE];
};
registry: SymTab.Ref;
Export routines to Commander interface
Register: PUBLIC ENTRY PROC[key: Rope.ROPE, proc: Commander.CommandProc, doc: Rope.ROPE, clientData: REF ANYNIL] = {
IF proc = NIL THEN [] ← SymTab.Delete[x: registry, key: key]
ELSE [] ← SymTab.Store[x: registry, key: key, val: NEW[Commander.CommandProcObject ← [proc: proc, doc: doc, clientData: clientData]]];
};
Enumerate: PUBLIC ENTRY PROC[matchProc: PROC[key: Rope.ROPE, procData: Commander.CommandProcHandle] RETURNS[stop: BOOL]] RETURNS
[key: Rope.ROPE, procData: Commander.CommandProcHandle] = {
outerKey: Rope.ROPE;
outerProcData: Commander.CommandProcHandle;
EachPairProc: SymTab.EachPairAction = {
outerProcData ← NARROW[val, Commander.CommandProcHandle];
outerKey ← key;
RETURN[matchProc[key: outerKey, procData: outerProcData]];
};
IF NOT SymTab.Pairs[x: registry, action: EachPairProc] THEN {
outerKey ← NIL;
outerProcData ← NIL;
};
RETURN[key: outerKey, procData: outerProcData];
};
Lookup: PUBLIC PROC[key: Rope.ROPE] RETURNS [procData: Commander.CommandProcHandle] = {
procRef: REF ANY;
found: BOOL;
[found: found, val: procRef] ← SymTab.Fetch[x: registry, key: key];
IF found AND procRef # NIL THEN procData ← NARROW[procRef, Commander.CommandProcHandle]
ELSE procData ← NIL;
};
Useful procedures for property lists
This procedure is much like List.Assoc, except it works more sensibly for ROPEs
GetProperty: PUBLIC ENTRY PROCEDURE [key: REF ANY, aList: List.AList] RETURNS [val: REF ANY] = {
ropeKey: Rope.ROPE;
val ← List.Assoc[key: key, aList: aList];
IF val # NIL THEN RETURN;
handle it differently if key is a ROPE
WITH key SELECT FROM
r: Rope.ROPE => ropeKey ← r;
t: REF TEXT => ropeKey ← Rope.FromRefText[t];
ENDCASE;
IF ropeKey # NIL THEN {
FOR l: List.AList ← aList, l.rest WHILE l # NIL DO
WITH l.first.key SELECT FROM
r: Rope.ROPE => IF Rope.Equal[s1: ropeKey, s2: r, case: TRUE] THEN RETURN[l.first.val];
t: REF TEXT => IF Rope.Equal[s1: ropeKey, s2: Rope.FromRefText[t], case: TRUE] THEN RETURN[l.first.val];
ENDCASE;
ENDLOOP;
};
RETURN[NIL];
};
This procedure is much like List.PutAssoc, except it works more sensibly for ROPEs
PutProperty: PUBLIC ENTRY PROCEDURE [key: REF ANY, val: REF ANY, aList: List.AList] RETURNS [List.AList] = {
handle it differently if key is a ROPE and already present on the list
IF ISTYPE[key, Rope.ROPE] THEN {
ropeKey: Rope.ROPENARROW[key];
FOR l: List.AList ← aList, l.rest WHILE l # NIL DO
IF ISTYPE[l.first.key, Rope.ROPE] THEN {
IF Rope.Equal[s1: ropeKey, s2: NARROW[l.first.key, Rope.ROPE], case: TRUE] THEN {
l.first.val ← val;
RETURN[aList];
};
};
ENDLOOP;
};
RETURN[List.PutAssoc[key: key, val: val, aList: aList]];
};
Init: PROCEDURE = {
registry ← SymTab.Create[mod: 59, case: FALSE];
};
Initialization
Init[];
END.
March 28, 1983 12:26 pm, L. Stewart, created
September 9, 1983 11:04 am, L. Stewart, Cedar 5
November 3, 1983 2:10 pm, L. Stewart, add CommandExtras