-- TiogaExecuteImpl.mesa -- written by Bill Paxton, May 1981 -- last edit by Bill Paxton, 14-Jul-81 10:16:19 -- This package implements the Execute command in Tioga DIRECTORY TiogaExecute, RopeReader, TextEdit, EditSpan, TextNode, TextLooks, RopeEdit, NameSymbolTable; TiogaExecuteImpl: PROGRAM IMPORTS nsI:NameSymbolTable, rdrI:RopeReader, spanI:EditSpan, nodeI:TextNode, ropeI:RopeEdit, editI:TextEdit EXPORTS TiogaExecute = BEGIN OPEN TiogaExecute, looksI:TextLooks; Ref: TYPE = nodeI.Ref; -- ***** Execute Exec: PUBLIC PROC [keyNode: RefTextNode, keyStart, keyLen: Offset, dictList: NodeList, event: Event ← NIL] RETURNS [foundIt: BOOLEAN, exec: Rope, resultStart, resultLen: Offset] = { DoAbbreviation: PROC = { looks: looksI.Looks; allcaps, initialcap: BOOLEAN ← FALSE; child: RefTextNode ← nodeI.NarrowToTextNode[nodeI.FirstChild[node]]; childSize: Offset; IF AllCaps[] THEN allcaps ← TRUE ELSE IF editI.FetchChar[keyNode,keyStart] IN ['A..'Z] THEN initialcap ← TRUE; [resultStart,resultLen] ← editI.ReplaceText[keyNode,keyStart,keyLen,child,0,editI.MaxLen,event]; 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 [] ← spanI.Copy[nodeI.MakeNodeLoc[keyNode], nodeI.MakeNodeSpan[nodeI.FirstChild[child], nodeI.LastWithin[child]], FALSE,after,1,event]; IF nodeI.Next[child] # NIL THEN -- insert as siblings of keyNode [] ← spanI.Copy[nodeI.MakeNodeLoc[keyNode], nodeI.MakeNodeSpan[nodeI.Next[child], nodeI.LastWithin[nodeI.LastSibling[child]]], FALSE,after,0,event]; }; AllCaps: PROC RETURNS [upper:BOOLEAN] = { rdr1 ← rdr3; -- set for start of key upper ← FALSE; FOR i:Offset ← 0, i+1 UNTIL i >= 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]]; IF child=NIL THEN RETURN; exec ← child.rope }; rdr1, rdr2, rdr3: rdrI.Ref; keyRope: Rope ← keyNode.rope; node: RefTextNode; rope: Rope; size: Offset; foundIt ← FALSE; rdr1 ← rdrI.GetRopeReader[]; rdr2 ← rdrI.GetRopeReader[]; rdr3 ← rdrI.GetRopeReader[]; rdrI.SetPosition[rdr3,keyRope,keyStart]; -- leave this one permanently set at key [] ← rdrI.Peek[rdr3]; FOR lst:NodeList ← dictList, lst.next UNTIL lst=NIL DO FOR entry:Ref ← lst.node.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, abbrev, abbreviation => DoAbbreviation[]; command => DoCommand[]; ENDCASE; GOTO Finis }; ENDLOOP; REPEAT Finis => NULL; ENDLOOP; rdrI.FreeRopeReader[rdr1]; rdrI.FreeRopeReader[rdr2]; rdrI.FreeRopeReader[rdr3] }; -- ***** Initialization abbrev, abbreviation, command: nodeI.TypeName; Start: PUBLIC PROC = { -- for initialization only abbrev ← nsI.MakeName["abbrev"]; abbreviation ← nsI.MakeName["abbreviation"]; command ← nsI.MakeName["command"]; }; END.