InterpreterCommandsImpl.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson, April 15, 1985 2:01:27 pm PST
Paul Rovner, January 11, 1984 1:09 pm
DIRECTORY
AMModel USING [Context, RootContext, Section],
AMEvents USING [BreakAt, DuplicateBreakpoint],
AMTypes USING [TVType, TV],
AMViewerOps USING [ReportProc, SectionFromSource, ViewerFromSection],
BackStop USING [Call],
Commander USING [CommandProc, Register],
CommandTool USING [ArgumentVector, Parse],
Convert USING [IntFromRope],
Interpreter USING [Evaluate],
InterpreterOps USING [EvalHead, WorldFromHead],
InterpreterToolPrivate USING [Break, BreakObject, nextBI],
IO USING [PutF1, PutRope, STREAM],
List USING [Assoc, PutAssoc],
PrintTV USING [Print, PrintType],
ProcessProps USING [GetPropList],
Rope USING [Concat, Fetch, IsEmpty, Length, ROPE, Substr],
SafeStorage USING [IsCollectorActive, NWordsAllocated],
SymTab USING [Create, Ref],
UserProfile USING [Boolean],
WorldVM USING [LocalWorld, World];
InterpreterCommandsImpl: CEDAR MONITOR
IMPORTS AMEvents, AMModel, AMTypes, AMViewerOps, BackStop, Commander, CommandTool, Convert, Interpreter, InterpreterOps, InterpreterToolPrivate, IO, List, PrintTV, ProcessProps, Rope, SafeStorage, SymTab, UserProfile, WorldVM
= BEGIN OPEN InterpreterToolPrivate;
ROPE: TYPE = Rope.ROPE;
Commands registered with Commander
EvalCommand: Commander.CommandProc = {
head: InterpreterOps.EvalHead = NARROW[List.Assoc[$EvalHead, ProcessProps.GetPropList[]]];
line: ROPE ← cmd.commandLine;
context: AMModel.Context;
symTab: SymTab.Ref;
resultTV: AMTypes.TV;
errorRope: ROPE;
noResult: BOOL;
depth: INT ← 4;
width: INT ← 32;
printType: BOOLFALSE;
collections: INT ← SafeStorage.IsCollectorActive[].previousIncarnation;
words: INT ← SafeStorage.NWordsAllocated[];
inner: PROC = {
IF noResult THEN RETURN;
IF printType
THEN {
cmd.out.PutRope["***Printing Type...\n"];
PrintTV.PrintType[
put: cmd.out,
type: AMTypes.TVType[resultTV],
depth: depth,
width: width,
verbose: depth > 4
];
}
ELSE PrintTV.Print[
put: cmd.out,
tv: resultTV,
depth: depth,
width: width,
verbose: depth > 4
];
};
START EvalCommand HERE
TRUSTED{
IF head = NIL
THEN context ← AMModel.RootContext[WorldVM.LocalWorld[]]
ELSE {
context ← head.context;
IF context = NIL
THEN context ← AMModel.RootContext[InterpreterOps.WorldFromHead[head]];
};
symTab ← LOOPHOLE[List.Assoc[$SymTab, cmd.propertyList]];
IF symTab = NIL THEN {
symTab ← SymTab.Create[];
[] ← List.PutAssoc[key: $SymTab, val: symTab, aList: cmd.propertyList];
};
};
line ← Rope.Substr[base: line, len: line.Length[] - 1]; -- remove the CR
UNTIL line.IsEmpty[] -- strip postfix !'s and ?'s
DO
ch: CHAR ← line.Fetch[line.Length[] - 1];
SELECT ch FROM
'! => {depth ← depth + 1; width ← width + width};
'? => printType ← TRUE;
ENDCASE => EXIT;
line ← Rope.Substr[base: line, len: line.Length[] - 1];
ENDLOOP;
line ← line.Concat["\n"]; -- replace the CR
[resultTV, errorRope, noResult]
← Interpreter.Evaluate[rope: Rope.Concat["& ← ", line], context: context, symTab: symTab];
IF errorRope # NIL
THEN IO.PutF1[cmd.out, "Error: %g\n", [rope[errorRope]] ]
ELSE IO.PutF1[cmd.out, "%g\n", [rope[BackStop.Call[inner]]] ]
};
SetBreakCommand: Commander.CommandProc = {
Unify this some day with the stuff in InterpreterToolImpl
out: IO.STREAM = cmd.out;
world: WorldVM.World;
break: Break ← NIL;
argv: CommandTool.ArgumentVector ← CommandTool.Parse[cmd];
HighlightBreakPoint: PROC [break: Break] = {
report: AMViewerOps.ReportProc = -- [msg: ROPE, severity: Severity]
TRUSTED {out.PutRope[msg]};
inner: SAFE PROC = TRUSTED{
[] ← AMViewerOps.ViewerFromSection[break.section, report];
}; -- yekk.
msg: ROPE ← BackStop.Call[inner];
IF msg # NIL THEN out.PutRope[msg];
};
inner: SAFE PROC = TRUSTED {
section: AMModel.Section ← NIL;
warning: REF;
name: ROPE ← argv[1];
index: INT ← Convert.IntFromRope[argv[2]];
out.PutRope["Setting break..."];
[section, warning] ← AMViewerOps.SectionFromSource[world, name, index];
IF warning = NIL THEN out.PutRope["(possible source version mismatch)"];
break ← NEW[BreakObject ← [index: 0, breakID: NIL, world: world, section: section]];
break.breakID ← AMEvents.BreakAt[world, section, break
! AMEvents.DuplicateBreakpoint => {break ← NIL; CONTINUE}];
IF break # NIL THEN {break.index ← nextBI; nextBI ← nextBI + 1};
};
START SetBreakCommand HERE
TRUSTED{world ← WorldVM.LocalWorld[]};
msg ← BackStop.Call[inner];
IF msg.Length[] = 0 AND break # NIL THEN {
IO.PutF1[out, "Break #%g set.\n", [integer[break.index]] ];
HighlightBreakPoint[break: break];
RETURN;
};
IF msg.Length[] # 0
THEN {break ← NIL; result ← $Failure}
ELSE msg ← "a break is already set here.\n";
};
initialization code
showStats: BOOL ← UserProfile.Boolean["ShowEvalStatistics", FALSE];
Commander.Register["←", EvalCommand, "a simple evaluation command", NIL, FALSE];
Commander.Register["eval", EvalCommand, "a simple evaluation command", NIL, FALSE];
Commander.Register["SetBreak", SetBreakCommand, "SetBreak fileName charPos"];
END.