DIRECTORY Buttons USING [SetDisplayStyle], Commander USING [CommandObject, Handle], CommandTool USING [ArgHandleObject, ArgumentVector, Failed, Parse], IO USING [Error, PutF, PutFR, PutChar, PutRope, rope, STREAM], LarkControl USING [LarkData, PaintMode], LarkWork, List USING [CompareProc, Sort], Process USING [Detach], ReadEvalPrint USING [ClientProc, CreateViewerEvaluator, Handle, MainLoop, Stop], Rope USING [Compare, Concat, Equal, Fetch, Length, ROPE, Run]; LarkWorkImpl: CEDAR MONITOR IMPORTS Buttons, CommandTool, IO, LarkControl, List, Process, ReadEvalPrint, Rope EXPORTS LarkWork = BEGIN registry: LIST OF REF ANY _ NIL; ProcObject: TYPE = RECORD [ proc: LarkWork.LarkWorkProc _ NIL, caseMatters: BOOL _ FALSE, key: Rope.ROPE _ NIL, doc: Rope.ROPE _ NIL, usage: Rope.ROPE _ NIL ]; RegisterLarkWorkProc: PUBLIC PROC [proc: LarkWork.LarkWorkProc, key: Rope.ROPE, caseMatters: BOOL _ FALSE, doc: Rope.ROPE _ NIL, usage: Rope.ROPE _ NIL] = { FOR rl: LIST OF REF ANY _ registry, rl.rest WHILE rl # NIL DO pr: REF ProcObject _ NARROW[rl.first]; IF Rope.Equal[key,pr.key, TRUE] AND pr.caseMatters = caseMatters THEN { pr.proc _ proc; pr.doc _ doc; pr.usage _ usage; RETURN; }; ENDLOOP; registry _ CONS[NEW[ProcObject _ [proc, caseMatters, key, doc, usage]], registry]; }; MaybeCreateWorkArea: PUBLIC PROC [lark: LarkControl.LarkData] RETURNS [result: Rope.ROPE] = { IF lark.eval # NIL THEN RETURN["There is already an open work area\n"]; lark.eval _ ReadEvalPrint.CreateViewerEvaluator[clientProc: InteractiveProc, prompt: "%% ", info: [name: Rope.Concat["Debug ", lark.nameRope], column: right, iconic: FALSE], clientData: lark]; lark.h.log _ lark.eval.out; IF lark.debug # NIL THEN Buttons.SetDisplayStyle[button: lark.debug, style: $WhiteOnBlack]; TRUSTED { Process.Detach[FORK RunWorkArea[lark]]; }; RETURN[IO.PutFR["Debug %g\n", IO.rope[lark.nameRope]]]; }; MaybeShutDownWorkArea: PUBLIC PROC [lark: LarkControl.LarkData] RETURNS [result: Rope.ROPE] = { IF lark.eval = NIL THEN RETURN["No work area exists\n"] ELSE ReadEvalPrint.Stop[lark.eval]; }; RunWorkArea: PROC [lark: LarkControl.LarkData] = { eval: ReadEvalPrint.Handle; ReadEvalPrint.MainLoop[lark.eval, FALSE, NIL]; eval _ lark.eval; lark.h.log _ lark.world.out; lark.eval _ NIL; IF eval.viewer # NIL AND NOT eval.viewer.destroyed AND eval.out # NIL THEN eval.out.PutRope["Destroy this viewer\n" ! IO.Error => CONTINUE]; IF lark.debug # NIL THEN Buttons.SetDisplayStyle[button: lark.debug, style: $BlackOnWhite]; lark.larkMode _ 'U; LarkControl.PaintMode[lark]; }; ReParse: PROC [r: Rope.ROPE] RETURNS [argv: CommandTool.ArgumentVector] = { orig: CommandTool.ArgumentVector; cmd: Commander.Handle _ NEW[Commander.CommandObject _ []]; cmd.commandLine _ r; orig _ CommandTool.Parse[cmd ! CommandTool.Failed => CONTINUE]; IF orig = NIL THEN RETURN[NIL]; argv _ NEW[CommandTool.ArgHandleObject[orig.argc - 1]]; FOR i: NAT IN [0..argv.argc) DO argv[i] _ orig[i+1]; ENDLOOP; }; InteractiveProc: ReadEvalPrint.ClientProc = { lark: LarkControl.LarkData _ NARROW[h.clientData]; argv: CommandTool.ArgumentVector _ ReParse[command]; cmd: REF ProcObject _ NIL; matchLength: INT; cmdLength: INT; foundMoreThanOne: BOOL _ FALSE; IF argv = NIL OR argv.argc = 0 THEN RETURN; cmdLength _ argv[0].Length[]; IF cmdLength = 0 THEN RETURN; FOR rl: LIST OF REF ANY _ registry, rl.rest WHILE rl # NIL DO pr: REF ProcObject _ NARROW[rl.first]; keyLength: INT _ pr.key.Length[]; IF cmdLength > keyLength THEN LOOP; matchLength _ Rope.Run[s1: argv[0], s2: pr.key, case: pr.caseMatters]; IF matchLength = keyLength AND cmdLength = matchLength THEN { cmd _ pr; EXIT; }; IF matchLength = cmdLength THEN { IF cmd = NIL THEN cmd _ pr ELSE foundMoreThanOne _ TRUE; }; REPEAT FINISHED => IF foundMoreThanOne THEN RETURN["Ambiguous command\n"]; ENDLOOP; IF cmd # NIL THEN RETURN[cmd.proc[lark: lark, argv: argv, capital: argv[0].Fetch[0] NOT IN ['a..'z]]]; RETURN["Not found\n"]; }; Quit: LarkWork.LarkWorkProc = { ReadEvalPrint.Stop[lark.eval]; }; CommandList: LarkWork.LarkWorkProc = { out: IO.STREAM _ lark.h.log; SortRegistry[]; FOR rl: LIST OF REF ANY _ registry, rl.rest WHILE rl # NIL DO pr: REF ProcObject _ NARROW[rl.first]; IF pr.proc # NIL THEN { out.PutRope[pr.key]; out.PutChar[' ]; }; ENDLOOP; out.PutChar['\n]; }; Help: LarkWork.LarkWorkProc = { out: IO.STREAM _ lark.h.log; matchRope: Rope.ROPE _ NIL; SortRegistry[]; IF argv.argc > 1 THEN matchRope _ argv[1]; FOR rl: LIST OF REF ANY _ registry, rl.rest WHILE rl # NIL DO pr: REF ProcObject _ NARROW[rl.first]; IF pr.proc # NIL THEN { IF Rope.Run[s1: pr.key, s2: matchRope, case: FALSE] = matchRope.Length[] THEN out.PutF["%-10g: %g\n", IO.rope[pr.key], IO.rope[pr.doc]]; }; ENDLOOP; }; Usage: LarkWork.LarkWorkProc = { out: IO.STREAM _ lark.h.log; matchRope: Rope.ROPE _ NIL; SortRegistry[]; IF argv.argc > 1 THEN matchRope _ argv[1]; FOR rl: LIST OF REF ANY _ registry, rl.rest WHILE rl # NIL DO pr: REF ProcObject _ NARROW[rl.first]; IF pr.proc # NIL THEN { IF Rope.Run[s1: pr.key, s2: matchRope, case: FALSE] = matchRope.Length[] THEN out.PutF["%-10g: %g\n", IO.rope[pr.key], IO.rope[pr.usage]]; }; ENDLOOP; }; SortRegistry: PROC = { MyCompare: List.CompareProc = { a: REF ProcObject _ NARROW[ref1]; b: REF ProcObject _ NARROW[ref2]; RETURN[Rope.Compare[a.key, b.key]]; }; registry _ List.Sort[list: registry, compareProc: MyCompare]; }; RegisterLarkWorkProc[proc: Quit, key: "Quit", caseMatters: FALSE, doc: "Close work area"]; RegisterLarkWorkProc[proc: CommandList, key: "?", caseMatters: FALSE, doc: "List available commands"]; RegisterLarkWorkProc[proc: Help, key: "Help", caseMatters: FALSE, doc: "Command documentation", usage: "Help {partialCommandName}"]; RegisterLarkWorkProc[proc: Usage, key: "Usage", caseMatters: FALSE, doc: "Command Usage", usage: "Usage {partialCommandName}"]; END. April 25, 1983 7:36 pm, LCS, created July 6, 1983 3:58 pm, LCS, complete match should now succeed December 22, 1983 1:55 pm, LCS, Cedar 5 RLarkWorkImpl.mesa L. Stewart, December 22, 1983 1:55 pm Built in commands Ę ˜Jšœ™Jšœ%™%J˜šĎk ˜ Jšœœ˜ Jšœ œ˜(Jšœ œ2˜CJšœœ.œ˜>Jšœ œ˜(Jšœ ˜ Jšœœ˜Jšœœ ˜Jšœœ=˜PJšœœ)œ˜>—J˜Jšœœ˜Jšœœ1˜QJšœ ˜Jš˜J˜Jš œ œœœœœ˜ J˜šœ œœ˜Jšœœ˜"Jšœ œœ˜Jšœ œœ˜Jšœ œœ˜Jšœ œ˜J˜—J˜šĎnœœœ)œœœ œœœœ˜œšœœœœœœœ˜=Jšœœœ ˜&šœœœœ˜GJšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜—Jšœ˜—Jšœ œœ?˜RJ˜—J˜š žœœœœœ˜]Jšœ œœœ)˜GJšœŚœ˜ŔJ˜JšœœœC˜[Jšœœ˜4Jšœœœ˜7Jšœ˜—J˜š žœœœœœ˜_Jšœ œœœ˜7Jšœ˜#J˜—J˜šž œœ!˜2Jšœ˜Jšœ" œ˜.Jšœ˜J˜Jšœ œ˜Jšœœœœœ œœ,œ œ˜ŒJšœœœC˜[J˜Jšœ˜J˜—J˜šžœœ œœ'˜KJšœ!˜!Jšœœ˜:Jšœ˜Jšœ5œ˜@J˜Jšœœ-˜7šœœœ˜J˜Jšœ˜—J˜—J˜˜-Jšœœ˜2Jšœ4˜4Jšœœœ˜Jšœ œ˜Jšœ œ˜Jšœœœ˜Jš œœœœœ˜+Jšœ˜Jšœœœ˜šœœœœœœœ˜=Jšœœœ ˜&Jšœ œ˜!Jšœœœ˜#JšœF˜Fšœœœ˜=Jšœ ˜ Jšœ˜J˜—šœœ˜!Jšœœœ ˜Jšœœ˜J˜—Jš˜Jšœœœœ˜CJšœ˜—Jš œœœœ<œœ ˜fJšœ˜J˜—J˜J™J™˜J˜J˜—J˜˜&Jšœœœ˜Jšœ˜šœœœœœœœ˜=Jšœœœ ˜&šœ œœ˜J˜J˜J˜—Jšœ˜—J˜J˜—J˜˜Jšœœœ˜Jšœœœ˜Jšœ˜Jšœœ˜*šœœœœœœœ˜=Jšœœœ ˜&šœ œœ˜Jš œ+œœœœ˜ˆJ˜—Jšœ˜—J˜—J˜˜ Jšœœœ˜Jšœœœ˜J˜Jšœœ˜*šœœœœœœœ˜=Jšœœœ ˜&šœ œœ˜Jš œ+œœœœ˜ŠJ˜—Jšœ˜—J˜—J˜šž œœ˜˜Jšœœœ˜!Jšœœœ˜!Jšœ˜#J˜—Jšœ=˜=J˜—J˜Jšœ;œ˜ZJšœ?œ"˜fJšœ;œD˜„Jšœ=œ=˜J˜Jšœ˜Jšœœ ˜$Jšœœ#˜