MODULEPUBLICM3ASTDisplay EXPORTSM3ASTDisplay ,AST_DisplayRep ; IMPORT Wr, M3AST, ASTWalk; IMPORT AST_DisplayRep, M3ASTDisplay_handle; REVEAL AST_DisplayRep.Handle = M3ASTDisplay_handle.T BRANDED OBJECT ignoreChildren: BOOLEAN := FALSE; callOnEntry: BOOLEAN := FALSE; callOnExit: BOOLEAN := FALSE; closure: Closure := NIL; OVERRIDES Visit := DoVisit; END; REVEAL Closure = ASTWalk.Closure BRANDED OBJECT handle: Handle := NIL; END; PROCEDURENodes ( n: M3AST.NODE; s: Wr.T) RAISES {Wr.Failure}= VAR handle := NEW(Handle); BEGIN DoNodes(handle, n, s); END Nodes; PROCEDUREModeNodes ( n: M3AST.NODE; c: Closure; vm : ASTWalk.VisitModeControl; s: Wr.T) RAISES {Wr.Failure} = VAR handle := NEW(Handle, closure := c); BEGIN c.handle := handle; handle.callOnEntry := ASTWalk.VisitMode.Entry IN vm; handle.callOnExit := ASTWalk.VisitMode.Exit IN vm; DoNodes(handle, n, s); END ModeNodes; PROCEDUREDoNodes ( handle: Handle; n: M3AST.NODE; s: Wr.T) RAISES {Wr.Failure}= <*FATAL ANY*> BEGIN handle.stream := s; TRY DoVisit(handle, n); EXCEPT ASTWalk.Aborted => END; END DoNodes; PROCEDUREDoVisit (handle: Handle; n: M3AST.NODE) RAISES ANY= BEGIN IF handle.callOnEntry THEN handle.closure.callback(n); END; IF NOT handle.ignoreChildren THEN n.display(handle) END; IF handle.callOnExit THEN handle.closure.callback(n); END; handle.ignoreChildren := FALSE; END DoVisit;
PROCEDUREIgnoreChildren (c: Closure) RAISES {} = BEGIN c.handle.ignoreChildren := TRUE; END IgnoreChildren; BEGIN END M3ASTDisplay.