-- ExecuteImpl.mesa -- written by Bill Paxton, May 1981 -- last edit by Bill Paxton, 21-May-81 14:44:54 -- This package implements the Execute command in Tioga DIRECTORY Execute, RopeReader, TextEdit, TreeEdit, TextNode, TreeEdit, TiogaAlloc, TiogaJaM; ExecuteImpl: PROGRAM IMPORTS TextEdit, TreeEdit, jamI:TiogaJaM, rdrI:RopeReader, allocI:TiogaAlloc, treeI:TreeEdit EXPORTS Execute = BEGIN OPEN Execute, nodeI:TextNode; -- ***** Execute Exec: PUBLIC PROC [keyNode: RefTextNode, keyStart, keyLen: Card, dictList: NodeList] RETURNS [foundIt: BOOLEAN, exec: Rope] = { DoAbbreviation: PROC = { looks: looksI.Looks; allcaps, initialcap: BOOLEAN _ FALSE; child: RefTextNode _ nodeI.NarrowToTextNode[nodeI.FirstChild[node]]; childSize: Card; IF AllCaps[] THEN allcaps _ TRUE ELSE IF editI.FetchChar[keyNode,keyStart] IN ['A..'Z] THEN initialcap _ TRUE; editI.ReplaceText[keyNode,keyStart,keyLen,child]; IF child=NIL THEN RETURN; childSize _ editI.Size[child]; IF (looks _ editI.FetchLooks[keyNode,keyStart]) # looksI.noLooks THEN editI.AddLooks[keyNode,looks,keyStart,childSize]; IF allcaps THEN editI.InitialCaps[keyNode,keyStart,childSize] ELSE IF initialcap AND childSize > 0 THEN editI.AllCaps[keyNode,keyStart,1]; IF nodeI.FirstChild[child] # NIL THEN -- insert as children of keyNode treeI.CopyNodes[keyNode,nodeI.FirstChild[child],nodeI.LastChild[child]]; IF nodeI.Next[child] # NIL THEN -- insert as siblings of keyNode treeI.CopyNodes[keyNode,nodeI.Next[child],nodeI.LastSibling[child],FALSE]; }; AllCaps: PROC RETURNS [upper:BOOLEAN] = { rdr1 _ rdr3; -- set for start of key upper _ FALSE; THROUGH [0..keyLen) DO SELECT rdrI.Get[rdr1] FROM IN ['a..'z] => RETURN [FALSE]; IN ['A..'Z] => upper _ TRUE; -- must have at least one uppercase ENDCASE; ENDLOOP }; DoCommand: PROC = { child: RefTextNode _ nodeI.NarrowToTextNode[nodeI.FirstChild[node]]; childSize: Card; IF child=NIL THEN RETURN; exec _ child.rope }; rdr1, rdr2, rdr3: rdrI.Ref; keyRope: Rope _ keyNode.rope; node: RefTextNode; rope: Rope; size: Card; foundIt _ FALSE; rdr1 _ allocI.GetRopeReader[]; rdr2 _ allocI.GetRopeReader[]; rdr3 _ allocI.GetRopeReader[]; rdrI.SetPosition[rdr3,keyRope,keyStart]; -- leave this one permanently set at key [] _ rdrI.Peek[rdr3]; FOR dict:Ref _ dictList, dict.next UNTIL dict=NIL DO FOR entry:Ref _ dict.child, nodeI.Next[entry] UNTIL entry=NIL DO IF (node _ nodeI.NarrowToTextNode[entry])=NIL THEN LOOP; IF (size _ ropeI.Size[rope _ node.rope]) # keyLen THEN LOOP; rdr1 _ rdr3; -- already primed to read key IF rdrI.CompareSubstrs[keyRope,rope,keyStart,keyLen,0,size,rdr1,rdr2,FALSE] = 0 THEN { foundIt _ TRUE; -- have found a match SELECT node.typename FROM nodeI.nullTypeName, abbrevTypeName => DoAbbreviation[]; commandTypeName => DoCommand[]; ENDCASE; GOTO Finis }; ENDLOOP; REPEAT Finis => NULL; ENDLOOP; allocI.FreeRopeReader[rdr1]; allocI.FreeRopeReader[rdr2]; allocI.FreeRopeReader[rdr3] }; -- ***** Initialization abbrevTypeName, commandTypeName: nodeI.TypeName; Start: PUBLIC PROC = { -- for initialization only abbrevTypeName _ jamI.MakeTypeName["abbrev"]; commandTypeName _ jamI.MakeTypeName["command"]; }; END.