JaMAndStyleAnalysesImpl.mesa
Last tweaked by Mike Spreitzer on March 23, 1987 12:47:16 pm PST
DIRECTORY Atom, BasicTime, EditNotify, IO, JaMAndStyleAnalyses, TDJaMScanner, MessageWindow, NodeProps, Rope, RopeReader, TextNode, TiogaRopes;
JaMAndStyleAnalysesImpl: CEDAR PROGRAM
IMPORTS Atom, BasicTime, EditNotify, IO, TDJaMScanner, MessageWindow, NodeProps, Rope, RopeReader, TextNode, TiogaRopes
EXPORTS JaMAndStyleAnalyses
=
BEGIN OPEN JaMAndStyleAnalyses;
LORA: TYPE = LIST OF REF ANY;
analysisProp: ATOM ← Atom.MakeAtom[IO.PutFR["JaMAndStyleAnalysesImpl, loaded at %g, analysisProp", [time[BasicTime.Now[]]]]];
debug: BOOLFALSE;
Invalidate: PROC [root: TiogaNode] = {
NodeProps.PutProp[root, analysisProp, NIL];
IF debug THEN MessageWindow.Append["Flushing a JaM/Style Analysis", TRUE];
};
EventWatcher: PROC [change: REF READONLY EditNotify.Change] --EditNotify.EditNotifyProc-- = {
WITH change SELECT FROM
x: REF READONLY ChangingView EditNotify.Change => NULL;
x: REF READONLY ChangingText EditNotify.Change => {
anal: JSAnalysis ← NARROW[NodeProps.GetProp[x.root, analysisProp]];
IF anal # NIL THEN {
startPosition: INT = TextNode.LocOffset[[x.root, 0], [x.text, x.start]];
IF startPosition <= anal.prefixEnd THEN Invalidate[x.root];
};
};
x: REF READONLY ChangingTextForPaste EditNotify.Change => NULL;
x: REF READONLY ChangingSpanForPaste EditNotify.Change => NULL;
x: REF READONLY ChangingFormat EditNotify.Change => NULL;
x: REF READONLY ChangingProp EditNotify.Change => IF x.propAtom = $Comment THEN {
anal: JSAnalysis ← NARROW[NodeProps.GetProp[x.root, analysisProp]];
IF anal # NIL THEN {
startPosition: INT = TextNode.LocOffset[[x.root, 0], [x.node, 0]];
IF startPosition <= anal.prefixEnd THEN Invalidate[x.root];
};
};
x: REF READONLY MovingNodes EditNotify.Change => NULL--wrong, but I don't understand this kind, and it probably won't happen anyway--;
x: REF READONLY NodeNesting EditNotify.Change => NULL;
x: REF READONLY InsertingNode EditNotify.Change => {
anal: JSAnalysis ← NARROW[NodeProps.GetProp[x.root, analysisProp]];
IF anal # NIL THEN {
startPosition: INT = TextNode.LocOffset[[x.root, 0], [x.new, 0]];
IF startPosition <= anal.prefixEnd THEN Invalidate[x.root];
};
};
ENDCASE => ERROR;
};
GetAnalysis: PUBLIC PROC [doc: TiogaNode, docName: ROPE, verbose: BOOL] RETURNS [anal: JSAnalysis] = {
anal ← NARROW[NodeProps.GetProp[doc, analysisProp]];
IF anal # NIL THEN RETURN;
IF verbose THEN MessageWindow.Append[Rope.Cat["Analyzing ", docName, " ..."], TRUE];
anal ← Analyze[doc, docName];
IF verbose THEN MessageWindow.Append[" done", FALSE];
NodeProps.PutProp[doc, analysisProp, anal];
};
SyntaxError: ERROR = CODE;
Token: TYPE = TDJaMScanner.Token;
Analyze: PROC [doc: TiogaNode, docName: ROPE] RETURNS [anal: JSAnalysis] = {
asRope: ROPE = TiogaRopes.RopeFromTioga[node: doc, skipCommentNode: TRUE];
reader: RopeReader.Ref = RopeReader.Create[];
stack: LORANIL;
before: INT;
reader.SetPosition[asRope, 0];
anal ← NEW [JSAnalysisPrivate ← []];
{ENABLE SyntaxError => {
posn: INT = reader.GetIndex[];
MessageWindow.Append[
message: IO.PutFR["Syntax error in %g before %g", [rope[docName]], [integer[posn]]],
clearFirst: TRUE];
anal.bodyStart ← anal.prefixEnd ← posn;
CONTINUE;
};
DO
before ← reader.GetIndex[];
{token: Token = TDJaMScanner.GetToken[reader];
SELECT token.type FROM
nil => EXIT--end of file, right?--;
name => {
a: ATOM = NARROW[TDJaMScanner.ParseToken[token, asRope]];
SELECT a FROM
$BeginStyle => NULL;
$AttachStyle => IF stack # NIL
THEN WITH stack.first SELECT FROM
fileName: ROPE => anal.attachs ← CONS[fileName, anal.attachs];
ENDCASE => SyntaxError
ELSE SyntaxError;
run => IF stack # NIL
THEN WITH stack.first SELECT FROM
fileName: ROPE => anal.runs ← CONS[fileName, anal.runs];
ENDCASE => SyntaxError
ELSE SyntaxError;
equal => IF stack # NIL THEN stack ← stack.rest ELSE SyntaxError;
ENDCASE => EXIT--unrecognized operator, must be end of prefix--;
};
string, int, real => stack ← CONS[TDJaMScanner.ParseToken[token, asRope], stack];
lbrace, rbrace => EXIT--end of prefix--;
comment => NULL;
ENDCASE => ERROR;
}ENDLOOP;
anal.bodyStart ← before;
anal.prefixEnd ← reader.GetIndex[];
}};
run: ATOM = Atom.MakeAtom[".run"];
equal: ATOM = Atom.MakeAtom["="];
EditNotify.AddNotifyProc[EventWatcher, after, low];
END.