CommanderImpl.mesa
Larry Stewart, April 6, 1983 5:12 pm
DIRECTORY
Commander,
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 =
BEGIN
registry: SymTab.Ref;
Export routines to Commander interface
Register:
PUBLIC
ENTRY
PROC[key: Rope.
ROPE, proc: Commander.CommandProc, doc: Rope.
ROPE] = {
IF proc = NIL THEN [] ← SymTab.Delete[x: registry, key: key]
ELSE [] ← SymTab.Store[x: registry, key: key, val: NEW[Commander.ProcCell ← [proc: proc, doc: doc]]];
};
Enumerate:
PUBLIC
ENTRY
PROC[matchProc:
PROC[name: Rope.
ROPE, proc: Commander.CommandProc, doc: Rope.
ROPE]
RETURNS[stop:
BOOL]]
RETURNS
[name: Rope.
ROPE, proc: Commander.CommandProc, doc: Rope.
ROPE] = {
EachPairProc: SymTab.EachPairAction = {
procCell: REF Commander.ProcCell ← NARROW[val, REF Commander.ProcCell];
name ← key;
proc ← procCell.proc;
doc ← procCell.doc;
RETURN[matchProc[name: key, proc: proc, doc: doc]];
};
IF
NOT SymTab.Pairs[x: registry, action: EachPairProc]
THEN {
name ← NIL;
proc ← NIL;
doc ← NIL;
};
};
Lookup:
PUBLIC
PROC[key: Rope.
ROPE]
RETURNS [proc: Commander.CommandProc, doc: Rope.
ROPE] = {
procRef: REF ANY;
found: BOOL;
procCell: REF Commander.ProcCell;
[found: found, val: procRef] ← SymTab.Fetch[x: registry, key: key];
IF procRef # NIL THEN procCell ← NARROW[procRef, REF Commander.ProcCell]
ELSE procCell ← NIL;
IF procCell #
NIL
THEN {
proc ← procCell.proc;
doc ← procCell.doc;
}
ELSE {
proc ← NIL;
doc ← 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.ROPE ← NARROW[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