DIRECTORY Ascii USING [Lower], MobCommandUtil USING [PairList, Switches], IO USING [GetChar, GetIndex, PutChar, PutRope, SetIndex, STREAM, EndOfStream], Rope USING [Cat, Concat, Equal, Fetch, Find, FromChar, Length, ROPE, Substr]; MobCommandUtilImpl: PROGRAM IMPORTS Ascii, IO, Rope EXPORTS MobCommandUtil = { PairList: TYPE = MobCommandUtil.PairList; ROPE: TYPE = Rope.ROPE; TokenClass: TYPE = CHAR; id: TokenClass = 'I; eom: TokenClass = '\003; -- ControlC State: TYPE = [0..17]; Failed: PUBLIC ERROR = CODE; Parse: PUBLIC PROC [s: IO.STREAM] RETURNS [operator: ROPE, argList, resultList: PairList, switches: ROPE] = { token: TokenClass ¬ 0C; idString: ROPE; tIndex: CARDINAL; c: CHAR ¬ ' ; NextToken: PROC = INLINE { WHILE c = ' OR c = '\012 OR c = '\015 DO c ¬ IO.GetChar[s ! IO.EndOfStream => {c ¬ eom; CONTINUE}] ENDLOOP; tIndex ¬ IO.GetIndex[s] - 1; SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '<, '., '+, '~, '!, '$ => { idString ¬ NIL; DO SELECT c FROM IN ['a..'z], IN ['A..'Z], IN ['0..'9], '<, '>, '., '+, '~, '!, '$ => { idString ¬ Rope.Concat[idString, Rope.FromChar[c]]; c ¬ IO.GetChar[s ! IO.EndOfStream => {c ¬ eom; CONTINUE}]}; ENDCASE => EXIT; ENDLOOP; token ¬ id}; '_, '[, '], ':, '- => {token ¬ c; c ¬ IO.GetChar[s ! IO.EndOfStream => {c ¬ eom; CONTINUE}]}; ',, ';, eom => token ¬ c; ENDCASE => BadCommand[]}; pair: ARRAY [0..1] OF ROPE; PushArg: PROC = INLINE {argList ¬ CONS[[pair[0], pair[1]], argList]}; PushResult: PROC = INLINE {resultList ¬ CONS[[pair[0], pair[1]], resultList]}; RestoreToken: PROC = {IO.SetIndex[s, tIndex]}; BadCommand: PROC = {ERROR Failed}; state: State ¬ 0; operator ¬ switches ¬ NIL; argList ¬ resultList ¬ NIL; UNTIL state = 17 DO NextToken[]; SELECT token FROM id => SELECT state FROM 0 => {operator ¬ idString; state ¬ 1}; 2, 8 => {operator ¬ idString; state ¬ 9}; 3 => {pair[0] ¬ idString; state ¬ 4}; 5 => {pair[1] ¬ idString; PushResult[]; state ¬ 6}; 10 => {pair[0] ¬ idString; state ¬ 11}; 12 => {pair[1] ¬ idString; PushArg[]; state ¬ 13}; 15 => {switches ¬ switches.Concat[idString]; state ¬ 16}; 1, 9, 14, 16 => {RestoreToken[]; state ¬ 17}; ENDCASE => BadCommand[]; '_ => SELECT state FROM 1 => { pair[0] ¬ NIL; pair[1] ¬ operator; operator ¬ NIL; PushResult[]; state ¬ 2}; 7 => state ¬ 8; ENDCASE => BadCommand[]; '[ => SELECT state FROM 0 => state ¬ 3; 1, 9 => state ¬ 10; 14 => {RestoreToken[]; state ¬ 17}; ENDCASE => BadCommand[]; '] => SELECT state FROM 3, 6 => state ¬ 7; 10, 13 => state ¬ 14; ENDCASE => BadCommand[]; ': => SELECT state FROM 4 => state ¬ 5; 11 => state ¬ 12; ENDCASE => BadCommand[]; ', => SELECT state FROM 6 => {state ¬ 3; c ¬ IO.GetChar[s ! IO.EndOfStream => {c ¬ eom; CONTINUE}]}; 13 => {state ¬ 10; c ¬ IO.GetChar[s ! IO.EndOfStream => {c ¬ eom; CONTINUE}]}; 1, 9, 14, 15, 16 => state ¬ 17; ENDCASE => BadCommand[]; '- => SELECT state FROM 0, 1, 9, 14, 16 => state ¬ 15; ENDCASE => BadCommand[]; '; => SELECT state FROM 1, 9, 14, 15, 16 => state ¬ 17; ENDCASE => BadCommand[]; eom => SELECT state FROM 0, 1, 9, 14, 15, 16 => state ¬ 17; ENDCASE => BadCommand[]; ENDCASE; ENDLOOP; RETURN}; Echo: PUBLIC PROC [ d: IO.STREAM, operator: ROPE, argList, resultList: PairList, switches: ROPE] = { PutList: PROC [list: PairList] = { d.PutChar['[]; FOR p: PairList ¬ list, p.rest UNTIL p = NIL DO IF p.first.key # NIL THEN {IO.PutRope[d, p.first.key]; IO.PutRope[d, ": "]}; IO.PutRope[d, p.first.val]; IF p.rest # NIL THEN IO.PutRope[d, ", "]; ENDLOOP; d.PutChar[']]}; IF resultList # NIL THEN { IF resultList.rest = NIL AND resultList.first.key = NIL THEN IO.PutRope[d, resultList.first.val] ELSE PutList[resultList]; IO.PutRope[d, " _ "]}; IO.PutRope[d, operator]; IF argList # NIL THEN PutList[argList]; IF switches # NIL AND switches.Length[] > 0 THEN { d.PutChar['-]; IO.PutRope[d, switches]}}; GetSwitches: PUBLIC PROC [switches: ROPE, default: MobCommandUtil.Switches] RETURNS[MobCommandUtil.Switches] = { sense: BOOL ¬ TRUE; length: INT ¬ switches.Length[]; FOR i: INT IN [0..length) DO c: CHAR = switches.Fetch[i]; temp: CHAR = Ascii.Lower[c]; SELECT temp FROM '~ => sense ¬ ~sense; IN ['a..'z] => {default[c] ¬ sense; sense ¬ TRUE}; ENDCASE; ENDLOOP; RETURN[default]}; GetNthPair: PUBLIC PROC [list: PairList, n: CARDINAL, delete: BOOL¬FALSE] RETURNS [key, value: ROPE¬NIL] = { i: CARDINAL ¬ 0; FOR p: PairList ¬ list, p.rest UNTIL p = NIL DO IF i = n THEN {key ¬ p.first.key; value ¬ p.first.val; IF delete THEN p.first.key ¬ p.first.val ¬ NIL; EXIT}; i ¬ i+1; ENDLOOP; RETURN}; ListLength: PUBLIC PROC [list: PairList] RETURNS [n: CARDINAL¬0] = { FOR p: PairList ¬ list, p.rest UNTIL p = NIL DO n ¬ n+1 ENDLOOP; RETURN}; KeyValue: PUBLIC PROC [key: ROPE, list: PairList, delete: BOOL¬FALSE] RETURNS [s: ROPE¬NIL] = { FOR p: PairList ¬ list, p.rest UNTIL p = NIL DO IF Rope.Equal[p.first.key, key, FALSE] THEN { s ¬ p.first.val; IF delete THEN p.first.val ¬ NIL; EXIT}; ENDLOOP; RETURN}; SetExtension: PUBLIC PROC [root, defaultExt: ROPE] RETURNS [name: ROPE] = { IF Rope.Find[root, "."] < 0 THEN root ¬ Rope.Cat[root, ".", defaultExt]; RETURN[root]}; GetRootName: PUBLIC PROC [name: ROPE] RETURNS [root: ROPE] = { dotIndex: INT ¬ Rope.Find[name, "."]; RETURN[IF dotIndex < 0 THEN name ELSE Rope.Substr[name, 0, dotIndex]]}; }. ΄ MobCommandUtilImpl.Mesa Copyright Σ 1985, 1989, 1991 by Xerox Corporation. All rights reserved. Satterthwaite, December 10, 1982 10:47 am Maxwell, August 29, 1983 8:11 am Paul Rovner, December 2, 1983 5:35 pm Russ Atkinson (RRA) March 7, 1985 4:26:00 am PST Andy Litman May 31, 1988 10:34:19 pm PDT JKF July 22, 1989 3:51:48 pm PDT 0: 1: id 2: id _ 3: [ ?{id : id}, 4: [ ?{id : id}, id 5: [ ?{id : id}, id : 6: [ ?{id : id}, id : id 7: [ ?{id : id}, ] 8: [ ?{id : id}, ] _ 9: LHS _ id 10: ?(LHS _) id [ ?{id : id}, 11: ?(LHS _) id [ ?{id : id}, id 12: ?(LHS _) id [ ?{id : id}, id : 13: ?(LHS _) id [ ?{id : id}, id : id 14: ?(LHS _) id [ ?{id : id}, ] 15: ?(LHS) id ?([ ?{id : id}, ])) - 16: ?(?(LHS) id ?([ ?{id : id}, ])) - id 17: ?(?(LHS) id ?([ ?{id : id}, ])) ?(- ?id) (;|eom) | eom where LHS = id | [ ?{id : id}, ] external parsing routine PairList utilities file naming utilities Κ –(cedarcode) style•NewlineDelimiter ™codešœ™Kšœ Οeœ=™HKšΟy)™)Kšž ™ Kšž%™%K™0Kšž(™(K™ K™—šΟk ˜ KšœŸœ ˜KšœŸœ˜*KšŸœŸœ1Ÿœ˜NšœŸœ5Ÿœ ˜MK˜——šΟnœŸ˜KšŸœŸœ˜KšŸœ˜K˜Kšœ Ÿœ˜)KšŸœŸœŸœ˜K˜šœ ŸœŸœ˜K˜KšœΟc ˜$K˜—šœŸœ ˜Kšœ™Kšœ™Kšœ ™ Kšœ™Kšœ™Kšœ™Kšœ™Kšœ™Kšœ™KšœŸœ™Kšœ Ÿœ™ Kšœ Ÿœ™#Kšœ Ÿœ™%Kšœ Ÿœ™(Kšœ Ÿœ™"Kšœ Ÿœ™&Kšœ Ÿœ™+Kšœ Ÿœ/™=KšœŸœ™ K˜K˜—Kš œŸœŸœŸœ˜K˜˜Kšœ™K˜š œŸœŸœŸœŸœŸœ Ÿœ+Ÿœ˜mK˜K˜Kšœ Ÿœ˜KšœŸœ˜KšœŸœ˜ K˜š  œŸœŸœ˜šŸœŸœ Ÿœ ˜&Kš ŸœŸœ ŸœŸœŸœ˜E—Kšœ Ÿœ˜šŸœŸ˜ šŸœ Ÿœ Ÿœ&˜BKšœ Ÿœ˜šŸ˜šŸœŸ˜ KšŸœ Ÿœ Ÿœ ˜&˜Kšœ4˜4KšœŸœ ŸœŸœ˜;—KšŸœŸœ˜—KšŸœ˜—K˜ —šœ˜KšœŸœ ŸœŸœ˜G—K˜KšŸœ˜K˜——KšœŸœŸœŸœ˜K˜Kš œŸœŸœ Ÿœ˜EKš  œŸœŸœŸœ"˜NKš  œŸœŸœ˜.š  œŸœŸœ ˜"K˜—K˜KšœŸœŸœ˜7K˜šŸœ Ÿ˜K˜ šŸœŸ˜˜šŸœŸ˜Kšœ)˜)K˜)K˜)K˜7K˜*K˜5Kšœ;˜;K˜-KšŸœ˜——˜šŸœŸ˜˜Kšœ Ÿœ"Ÿœ˜3K˜—K˜KšŸœ˜——˜šŸœŸ˜K˜K˜K˜#KšŸœ˜——˜šŸœŸ˜K˜K˜KšŸœ˜——˜šŸœŸ˜K˜K˜KšŸœ˜——˜šŸœŸ˜KšœŸœ ŸœŸœ˜LKšœŸœ ŸœŸœ˜NK˜KšŸœ˜——˜šŸœŸ˜K˜KšŸœ˜——˜šŸœŸ˜K˜KšŸœ˜——˜šŸœŸ˜K˜"KšŸœ˜——KšŸœ˜—KšŸœ˜—K˜KšŸœ˜K˜K˜—š œŸœŸœ˜KšœŸœŸœ˜ Kšœ Ÿœ+Ÿœ˜BK˜š œŸœ˜"K˜šŸœŸœŸœŸ˜/Kš ŸœŸœŸœŸœŸœ˜MKšŸœ˜KšŸœ ŸœŸœŸœ˜)KšŸœ˜—K˜K˜—šŸœŸœŸœ˜šŸœŸœŸœŸœ˜8KšŸœŸœ!˜(KšŸœ˜—KšŸœ˜—KšŸœ˜KšŸœ ŸœŸœ˜'šŸœ ŸœŸœŸœ˜2KšœŸœ˜)——K˜š  œŸœŸœ Ÿœ$˜LKšŸœ˜$KšœŸœŸœ˜KšœŸœ˜ šŸœŸœŸœ Ÿ˜KšœŸœ˜KšœŸœ˜šŸœŸ˜K˜KšŸœ*Ÿœ˜2KšŸœ˜—KšŸœ˜—KšŸœ ˜K˜——Kšœ™˜š   œŸœŸœŸœ Ÿ œ˜IKšŸœŸœ˜"KšœŸœ˜šŸœŸœŸœŸ˜/šŸœŸœ*˜7KšŸœŸœŸœŸœ˜6—K˜KšŸœ˜—KšŸœ˜K˜—š   œŸœŸœŸœŸ œ˜DKš ŸœŸœŸœŸœ Ÿœ˜@KšŸœ˜K˜—š  œŸœŸœŸœŸ œ˜EKšŸœŸœ˜šŸœŸœŸœŸ˜/šŸœŸœŸœ˜-Kš œŸœŸœŸœŸœ˜9—KšŸœ˜—KšŸœ˜K˜——Kšœ™˜š   œŸœŸœŸœŸœŸœ˜KKšŸœŸœ(˜HKšŸœ˜—K˜š   œŸœŸœŸœŸœŸœ˜>Kšœ Ÿœ˜%KšŸœŸœŸœŸœ"˜G—˜K˜—K˜K˜———…—¬!`