DragomanImpl.mesa
Created by Bertrand Serlet, October 17, 1985 4:47:55 pm PDT
Last Edited by: Serlet, April 26, 1985 11:40:41 pm PST
Pradeep Sindhu October 19, 1985 11:40:13 pm PDT
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;
Utilities
Output: PUBLIC PROC [handle: Handle, r1, r2, r3, r4, r5, r6, r7, r8: ROPENIL] = {
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];
};
User Callable procs
Start: PUBLIC PROC [backingFile: ROPENIL, instr, data: DragomanPrivate.CacheIndex ← 1, traceOps: BOOLFALSE, countOps: BOOLFALSE, recordXferOut: BOOLTRUE, modelCache: BOOLTRUE, flushOnCall: BOOLFALSE] RETURNS [handle: Handle] = {
wd: ROPENARROW[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 INTALL[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: BOOLFALSE] = 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: CARDINALCARDINAL.LAST;
max: CARDINALCARDINAL.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: ROPENIL] = {
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 ROPENIL] = {
WHILE names#NIL DO MarkGFIInternal[handle, names.first]; names ← names.rest ENDLOOP;
};
Run: PUBLIC PROC [handle: Handle, name: ROPE, recordXferOut: BOOLTRUE] = {
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.