-- PLStoreImpl.Mesa, stolen from Jim Morris -- Last Modified On 27-Oct-81 8:47:55 By Paul Rovner -- Last Modified On September 28, 1982 5:27 pm by Schmidt -- used to be PStore.Mesa DIRECTORY Environment: TYPE USING[Comparison], PL: TYPE USING [LSTNode, LSTNodeRecord, NewNail, Node, NodeRecord, PBug, rASS, rCAT, rCATL, rCLOSURE, rCOMB, rDELETE, rEQUAL, rFAIL, rFCN, rGOBBLE, rGTR, rHOLE, rID, rITER, rLST, rMAPPLY, rMINUS, rOPT, rPALT, rPAPPLY, rPATTERN, rPLUS, rPROG, rSEQ, rSEQOF, rSEQOFC, rSTR, rTILDE, rUNDEFINED, rWILD, SN, Symbol, SymbolRecord, Z], Rope: TYPE USING [Compare, ROPE]; PLStoreImpl: CEDAR PROGRAM IMPORTS P:PL, Rope EXPORTS PL = { OPEN PL; -- Node: TYPE = PL.Node; LSTNode: TYPE = PL.LSTNode; NodeRecord: TYPE = PL.NodeRecord; Symbol: TYPE = PL.Symbol; SymbolRecord: TYPE = PL.SymbolRecord; -- nSyms: CARDINAL = 250; -- -- N: ZONE = P.Z; Fail: rFAIL = N.NEW[FAIL NodeRecord←[TRUE,FAIL[]]]; MTSt: rSTR = N.NEW[STR NodeRecord←[TRUE,STR[""]]]; Nail: LSTNode = N.NEW[PL.LSTNodeRecord←[TRUE,LST[NIL,NIL]]]; SymbolTree: Symbol; GetSpecialNodes: PUBLIC PROC RETURNS[rFAIL,rSTR,LSTNode] = { RETURN[Fail,MTSt,Nail]; }; Insert: PUBLIC PROC[s: Rope.ROPE, r: PL.SymbolRecord] RETURNS[t: Symbol] = { -- these are never freed t ← Lookup1[s, r, TRUE]; }; Lookup: PUBLIC PROC[s: Rope.ROPE] RETURNS[t: Symbol] = { t ← Lookup1[s, [,,VAL[NIL]], FALSE]; }; Lookup1: PROC[s: Rope.ROPE, R: PL.SymbolRecord, inserting: BOOLEAN] RETURNS[t: Symbol] = { whichSon: INTEGER ← 0; father: Symbol ← SymbolTree; t ← father.son[0]; UNTIL t=NIL DO i: Environment.Comparison ← Rope.Compare[s, t.name]; IF i=equal THEN RETURN[t]; IF i=less THEN {whichSon ← 0; father ← t; t ← t.son[0]} ELSE {whichSon ← 1; father ← t; t ← t.son[1]} ENDLOOP; IF inserting THEN { father.son[whichSon] ← t ← N.NEW[SymbolRecord ← R]; t.name ← s} }; StoreCleanup: PUBLIC PROC = { SymbolTree ← NIL; }; StoreSetup: PUBLIC PROC = { SymbolTree ← N.NEW[SymbolRecord ← [,,VAL[NIL]]]; [] ← Insert["symbol",[,,ZARY[SymbolRoutine]]]; }; SymbolRoutine: PUBLIC PROC[Node] RETURNS[ans:Node] = { -- zary n: LSTNode ← P.NewNail[]; R: PROC[s: Symbol] = { IF s = NIL THEN RETURN; R[s.son[0]]; n↑ ← [TRUE, LST[P.SN[s.name], P.NewNail[]]]; n ← n.listtail; R[s.son[1]]}; ans ← n; R[SymbolTree.son[0]]; }; Preorder: PUBLIC PROC[n: Node,p: PROC[Node] RETURNS[BOOLEAN]] = BEGIN -- this proc applies p recursively to node n and in preorder all nodes accessible from it -- if p returns false node n's descendants are not searched DO IF n = NIL THEN RETURN; IF ~p[n] THEN RETURN; WITH n SELECT FROM x: rFAIL => RETURN; x: rID => RETURN; x: rWILD => RETURN; x: rHOLE => RETURN; x: rUNDEFINED => RETURN; x: rSTR => RETURN; x: rCOMB => n ← x.parm; x: rASS => n ← x.rhs; x: rLST => {Preorder[x.listhead,p]; n ← x.listtail}; x: rSEQOF => RETURN; x: rSEQOFC => RETURN; x: rOPT => RETURN; x: rDELETE => n ← x.pat; x: rCAT=> {Preorder[x.left,p]; n ← x.right}; x: rCATL=> {Preorder[x.left,p]; n ← x.right}; x: rGTR=> {Preorder[x.left,p]; n ← x.right}; x: rPALT=> {Preorder[x.left,p]; n ← x.right}; x: rPAPPLY=> {Preorder[x.left,p]; n ← x.right}; x: rMAPPLY=> {Preorder[x.left,p]; n ← x.right}; x: rGOBBLE=> {Preorder[x.left,p]; n ← x.right}; x: rITER=> {Preorder[x.left,p]; n ← x.right}; x: rPROG=> {Preorder[x.left,p]; n ← x.right}; x: rSEQ=> {Preorder[x.left,p]; n ← x.right}; x: rPLUS=> {Preorder[x.left,p]; n ← x.right}; x: rMINUS=> {Preorder[x.left,p]; n ← x.right}; x: rEQUAL=> {Preorder[x.left,p]; n ← x.right}; x: rEQUAL=> {Preorder[x.left,p]; n ← x.right}; x: rTILDE => n ← x.not; x: rPATTERN => n ← x.pattern; x: rCLOSURE => n ← x.exp; x: rFCN=> {Preorder[x.parms,p]; n ← x.fcn}; ENDCASE => P.PBug["Unknown variant"]; ENDLOOP; END; }.