Utilities
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];
};
User Callable procs
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[];
};