<> <> <> <> DIRECTORY Dragoman, DragomanPrivate, AMBridge, AMModel, AMModelBridge, AMTypes, Atom, Basics, BasicTime, CacheModels, Commander, CommandTool, Convert, IO, List, PrincOps, PrincOpsUtils, ProcessProps, Rope, ViewerIO USING [CreateViewerStreams], WorldVM; <<>> DragomanImpl: CEDAR PROGRAM IMPORTS DragomanPrivate, AMBridge, AMModel, AMModelBridge, Atom, BasicTime, CommandTool, Convert, IO, List, PrincOpsUtils, ProcessProps, Rope, ViewerIO, WorldVM EXPORTS Dragoman = BEGIN OPEN Dragoman; <> Output: PUBLIC PROC [handle: Handle, r1, r2, r3, r4, r5, r6, r7, r8: ROPE _ NIL] = { IO.PutRope[handle.tsOut, Rope.Cat[Rope.Cat[r1, r2, r3, r4], Rope.Cat[r5, r6, r7, r8]]]; }; GfiRange: PROC [gfi: PrincOps.GFTIndex] RETURNS [first, last: PrincOps.GFTIndex] = TRUSTED { gfItem: PrincOps.GFTItem _ PrincOps.GFT[gfi]; gf: PrincOps.GlobalFrameHandle; code: PrincOps.FrameCodeBase; cb: LONG POINTER TO PrincOps.CSegPrefix; gfItem.epbias _ 0; gf _ gfItem.framePtr; IF gf = NIL THEN RETURN [gfi, gfi]; first _ gf.gfi; code _ gf.code; code.out _ FALSE; cb _ code.longbase; last _ first + cb.header.info.ngfi - 1}; CallCommandTool: PROC [handle: Handle] = { parent: Commander.Handle _ NEW[Commander.CommandObject _ [ in: IO.noInputStream, out: handle.tsOut, err: IO.noWhereStream]]; prompt: ROPE _ "%l%% %l"; directory: ROPE _ "///Commands/"; IF Rope.Length[handle.line] = 0 THEN RETURN; parent.propertyList _ List.PutAssoc[ key: $ErrorInputStream, val: IO.noInputStream, aList: parent.propertyList]; parent.propertyList _ List.PutAssoc[ key: $Prompt, val: prompt, aList: parent.propertyList]; parent.propertyList _ List.PutAssoc[ key: $SearchRules, val: LIST[directory], aList: parent.propertyList]; [] _ CommandTool.DoCommand[handle.line, parent]; }; <> Start: PUBLIC PROC [backingFile: ROPE _ NIL, instr, data: DragomanPrivate.CacheIndex _ 1, traceOps: BOOL _ FALSE, countOps: BOOL _ FALSE, recordXferOut: BOOL _ TRUE, modelCache: BOOL _ TRUE, flushOnCall: BOOL _ FALSE] RETURNS [handle: Handle] = { wd: ROPE _ NARROW[List.Assoc[$WorkingDirectory, ProcessProps.GetPropList[]]]; IF backingFile=NIL THEN backingFile _ "Dragoman.ts"; handle _ NEW [HandleRec _ [modelCache: modelCache]]; handle.workingDir _ Atom.PutPropOnList[propList: NIL, prop: $WorkingDirectory, val: wd]; handle.m _ NEW[DragomanPrivate.MachineStateRec _ [ cacheData: NEW [DragomanPrivate.CacheInfoRec _ [iCaches: instr, dCaches: data]], history: NEW [DragomanPrivate.OpHistoryRec], traceOps: traceOps, flushOnCall: flushOnCall, countOps: countOps, recordXferOut: recordXferOut, opCount: NEW [ARRAY Basics.Byte OF INT _ ALL[0]], interestingGfi: NEW [DragomanPrivate.BitVector _ ALL[FALSE]]]]; handle.tsOut _ ViewerIO.CreateViewerStreams[ name: backingFile, viewer: NIL, backingFile: backingFile, editedStream: FALSE].out; }; SetInstructionCache: PUBLIC PROC [handle: Handle, number: DragomanPrivate.CacheIndex, cache: CacheModels.Cache] = { cacheInfo: DragomanPrivate.CacheInfo _ NARROW[handle.m.cacheData]; cacheInfo.iCache[number] _ cache; }; SetDataCache: PUBLIC PROC [handle: Handle, number: DragomanPrivate.CacheIndex, cache: CacheModels.Cache] = { cacheInfo: DragomanPrivate.CacheInfo _ NARROW[handle.m.cacheData]; cacheInfo.dCache[number] _ cache; }; MarkGFIInternal: PROC [handle: Handle, name: ROPE] = { wc, cc: AMModel.Context; NoteMod: PROC [cx: AMModel.Context] RETURNS [stop: BOOL _ FALSE] = TRUSTED { SELECT AMModel.ContextClass[cx] FROM model => [] _ AMModel.ContextChildren[cx, NoteMod]; prog => { tx: AMTypes.TV = AMModelBridge.FrameFromContext[cx]; gf: PrincOps.GlobalFrameHandle = AMBridge.GFHFromTV[tx]; first, last: CARDINAL; [first, last] _ GfiRange[gf.gfi]; min _ MIN[min, first]; max _ MAX[max, last]}; ENDCASE; }; min: CARDINAL _ CARDINAL.LAST; max: CARDINAL _ CARDINAL.FIRST; TRUSTED {wc _ AMModel.RootContext[WorldVM.LocalWorld[]]}; IF name = NIL THEN RETURN; TRUSTED {cc _ AMModel.MostRecentNamedContext[name, wc]}; IF cc = NIL THEN {Output[handle, "*** MarkGFI: ", name, " not found\n"]; RETURN}; [] _ NoteMod[cc]; Output[handle, "MarkGFI: ", name, " gfi's are marked (", Convert.RopeFromInt[min], "-", Convert.RopeFromInt[max], ")\n"]; FOR i: CARDINAL IN [min..max] DO handle.m.interestingGfi[i] _ TRUE; ENDLOOP; }; MarkGFI: PUBLIC PROC [handle: Handle, name1, name2, name3, name4, name5, name6: ROPE _ NIL] = { MarkGFIInternal[handle, name1]; MarkGFIInternal[handle, name2]; MarkGFIInternal[handle, name3]; MarkGFIInternal[handle, name4]; MarkGFIInternal[handle, name5]; MarkGFIInternal[handle, name6]; }; MarkGFIs: PUBLIC PROC [handle: Handle, names: LIST OF ROPE _ NIL] = { WHILE names#NIL DO MarkGFIInternal[handle, names.first]; names _ names.rest ENDLOOP; }; Run: PUBLIC PROC [handle: Handle, name: ROPE, recordXferOut: BOOL _ TRUE] = { commandToolGfi: CARDINAL; Init: PROC [h: Handle, topProc: PROC] = TRUSTED { link: PrincOps.ControlLink = LOOPHOLE[topProc]; MarkInteresting[h.m, link.gfi]; DragomanPrivate.Xfer[ m: h.m, dst: link, src: DragomanPrivate.MagicReturn, push: FALSE]; }; MarkInteresting: PROC [m: Machine, gfi: PrincOps.GFTIndex] = { first, last: CARDINAL; [first, last] _ GfiRange[gfi]; FOR i: CARDINAL IN [first..last] DO m.interestingGfi[i] _ TRUE; ENDLOOP; }; RunInContext: SAFE PROC = TRUSTED {DragomanPrivate.Execute[handle.m]}; gf: PrincOps.GlobalFrameHandle; gf _ PrincOpsUtils.GlobalFrame[LOOPHOLE[CommandTool.DoCommand]]; TRUSTED {commandToolGfi _ gf.gfi}; Output[handle, "Initializing to run command tool\n"]; handle.line _ name; Init[handle, LOOPHOLE[CallCommandTool]]; -- we're going to push parameters DragomanPrivate.Push2[handle.m, LOOPHOLE[handle]]; MarkInteresting[handle.m, commandToolGfi]; BEGIN ENABLE { UNWIND => {}; DragomanPrivate.FinishedExecution => {GO TO done}; ABORTED => {Output[handle, " aborted"]; GO TO done}}; handle.m.breakPC _ 0; handle.m.breakGF _ LOOPHOLE[0]; handle.m.recordXferOut _ recordXferOut; DragomanPrivate.EnableCaches[m: handle.m, state: handle.modelCache]; handle.m.singleStep _ FALSE; handle.m.startOps _ handle.m.iCount; handle.m.startPulses _ BasicTime.GetClockPulses[]; ProcessProps.AddPropList[handle.workingDir, RunInContext]; GO TO done; EXITS done => { et: REAL; et _ BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[] - handle.m.startPulses]; Output[handle, IO.PutFR["Executed %g instr in %g secs (%g/sec)\n", [cardinal[handle.m.iCount - handle.m.startOps]], [real[et]], [real[(handle.m.iCount - handle.m.startOps)/et]]]]; IF recordXferOut THEN DragomanPrivate.PrintProcCounts[handle.tsOut, handle.m]; DragomanPrivate.PrintCacheStats[handle.tsOut, handle.m]; }; END; }; End: PUBLIC PROC [handle: Handle] = { handle.tsOut.Close[]; }; END.