<> <> 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: BOOL _ FALSE; 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: LORA _ NIL; 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.