WrapDragoman.mesa
Created by Bertrand Serlet, April 2, 1985 11:55:39 am PST
Last Edited by: Serlet, April 26, 1985 11:40:41 pm PST
DIRECTORY
AMBridge, AMModel, AMModelBridge, AMTypes,
Atom, Basics, BasicTime,
CacheModels,
Commander,
CommandTool,
Convert, IO, List,
PrincOps, PrincOpsUtils,
ProcessProps,
RESIDisp, RESInterpreter, RESIStats, WrapRESIUtil, RESIXfer,
Rope,
ViewerIO USING [CreateViewerStreams],
WorldVM;
WrapDragoman: CEDAR PROGRAM
IMPORTS AMBridge, AMModel, AMModelBridge, Atom, BasicTime, CommandTool, Convert, IO, List, PrincOpsUtils, ProcessProps, RESIDisp, RESInterpreter, RESIStats, WrapRESIUtil, RESIXfer, Rope, ViewerIO, WorldVM =
BEGIN
Types
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Machine: TYPE = RESInterpreter.Machine;
Handle: TYPE = REF HandleRec; -- a REF to the data for a particular instance of the sample tool; multiple instances can be created.
HandleRec: TYPE = RECORD [ -- the data for a particular tool instance
modelCache: BOOL,
m: Machine,
workingDir: Atom.PropList,
parent: Commander.Handle,
tsIn, tsOut: STREAM];
Utilities
Output: 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 [h: Handle] = {
line: ROPENARROW[Atom.GetProp[$HACK, $HACKPROP]];
IF line = NIL OR Rope.Length[line] = 0 THEN RETURN;
[] ← CommandTool.DoCommand[line, h.parent];
};
User Callable procs
Start: PROC [backingFile: ROPE ← "WrapDragoman.ts", instr, data: WrapRESIUtil.CacheIndex ← 1, traceOps: BOOLFALSE, countOps: BOOLFALSE, recordXferOut: BOOLTRUE, modelCache: BOOLTRUE, flushOnCall: BOOLFALSE] RETURNS [handle: Handle] = {
cpl: Atom.PropList ← ProcessProps.GetPropList[];
wd: ROPENARROW[List.Assoc[$WorkingDirectory, cpl]];
handle ← NEW [HandleRec ← [modelCache: modelCache]];
handle.parent ← NARROW[List.Assoc[$CommanderHandle, cpl]];
handle.workingDir ← Atom.PutPropOnList[propList: NIL, prop: $WorkingDirectory, val: wd];
handle.m ← NEW[RESInterpreter.MachineStateRec ← [
cacheData: NEW [WrapRESIUtil.CacheInfoRec ← [iCaches: instr, dCaches: data]],
history: NEW [RESInterpreter.OpHistoryRec],
traceOps: traceOps,
flushOnCall: flushOnCall,
countOps: countOps,
recordXferOut: recordXferOut,
opCount: NEW [ARRAY Basics.Byte OF INTALL[0]],
interestingGfi: NEW [RESInterpreter.BitVector ← ALL[FALSE]]]];
[handle.tsIn, handle.tsOut] ← ViewerIO.CreateViewerStreams [
name: backingFile, viewer: NIL, backingFile: backingFile, editedStream: FALSE];
};
SetInstructionCache: PROC [handle: Handle, number: WrapRESIUtil.CacheIndex, cache: CacheModels.Cache] = {
cacheInfo: WrapRESIUtil.CacheInfo ← NARROW[handle.m.cacheData];
cacheInfo.iCache[number] ← cache;
};
SetDataCache: PROC [handle: Handle, number: WrapRESIUtil.CacheIndex, cache: CacheModels.Cache] = {
cacheInfo: WrapRESIUtil.CacheInfo ← NARROW[handle.m.cacheData];
cacheInfo.dCache[number] ← cache;
};
MarkGFI: PROC [handle: Handle, name1, name2, name3, name4, name5, name6: ROPENIL] = {
MarkGFIInternal: PROC [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;
};
MarkGFIInternal[name1]; MarkGFIInternal[name2]; MarkGFIInternal[name3]; MarkGFIInternal[name4]; MarkGFIInternal[name5]; MarkGFIInternal[name6];
};
Run: 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];
RESIXfer.Xfer[
m: h.m, dst: link, src: RESInterpreter.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 {RESIDisp.Execute[handle.m]};
gf: PrincOps.GlobalFrameHandle;
gf ← PrincOpsUtils.GlobalFrame[CommandTool.DoCommand];
TRUSTED {commandToolGfi ← gf.gfi};
Output[handle, "Initializing to run command tool\n"];
Atom.PutProp[$HACK, $HACKPROP, name];
Init[handle, LOOPHOLE[CallCommandTool]]; -- we're going to push parameters
WrapRESIUtil.Push2[handle.m, LOOPHOLE[handle]];
MarkInteresting[handle.m, commandToolGfi];
BEGIN
ENABLE {
UNWIND => {};
RESInterpreter.FinishedExecution => {GO TO done};
ABORTED => {Output[handle, " aborted"]; GO TO done}};
handle.m.breakPC ← 0;
handle.m.breakGF ← LOOPHOLE[0];
handle.m.recordXferOut ← recordXferOut;
WrapRESIUtil.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 RESIStats.PrintProcCounts[handle.tsOut, handle.m];
WrapRESIUtil.PrintCacheStats[handle.tsOut, handle.m];
};
END;
};
End: PROC [handle: Handle] = {
handle.tsOut.Close[];
};
END.