-- 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.