<> <> <> <> <> <> DIRECTORY Alloc: TYPE USING [Base, Index, Handle, Notifier, OrderedIndex, Selector], CBinary: TYPE USING [DebugTab], CompilerUtil: TYPE USING [StreamId, TableId], ConvertUnsafe: TYPE USING [String], IO: TYPE USING [STREAM], ListerDefs: TYPE USING [AddNotify, Bounds, DropNotify], OutputDefs: TYPE USING [GetOutputStream], Runtime: TYPE USING [GetTableBase, GlobalFrame], Tree: TYPE USING [Base, Index, Link, Node, Scan, Null, NullIndex, treeType], TreeOps: TYPE USING []; FakeCompiler: PROGRAM IMPORTS CBinary, ListerDefs, OutputDefs, Runtime EXPORTS CompilerUtil, Alloc, TreeOps = { <> EndIndex: Tree.Index = LAST[Tree.Index]; EndMark: Tree.Link = [subtree[index: EndIndex]]; tb: PRIVATE Tree.Base; -- tree base UpdateBase: PRIVATE Alloc.Notifier = {tb _ base[Tree.treeType]}; Initialize: PUBLIC PROC [Alloc.Handle, UNCOUNTED ZONE] = { AddNotify[NIL, UpdateBase]}; Finalize: PUBLIC PROC = {DropNotify[NIL, UpdateBase]}; ScanSons: PUBLIC PROC [root: Tree.Link, action: Tree.Scan] = { IF root # Tree.Null THEN WITH root SELECT FROM subtree => { node: Tree.Index = index; FOR i: CARDINAL IN [1 .. SonCount[node]] DO action[tb[node].son[i]] ENDLOOP}; ENDCASE; RETURN}; SonCount: PRIVATE PROC [node: Tree.Index] RETURNS [CARDINAL] = { RETURN [SELECT node FROM Tree.NullIndex, EndIndex => 0, ENDCASE => IF tb[node].name = list AND tb[node].nSons = 0 THEN ListLength[[subtree[index: node]]] + 1 ELSE tb[node].nSons]}; ListLength: PUBLIC PROC [t: Tree.Link] RETURNS [CARDINAL] = { IF t = Tree.Null THEN RETURN [0]; WITH t SELECT FROM subtree => { node: Tree.Index = index; n: CARDINAL; IF tb[node].name # list THEN RETURN [1]; n _ tb[node].nSons; IF n # 0 THEN RETURN [n]; FOR i: CARDINAL _ 1, i+1 UNTIL tb[node].son[i] = EndMark DO n _ n+1 ENDLOOP; RETURN [n]}; ENDCASE => RETURN [1]}; GetNode: PUBLIC PROC [t: Tree.Link] RETURNS [Tree.Index] = { RETURN [WITH t SELECT FROM subtree => index, ENDCASE => ERROR]}; <> Failure: PUBLIC ERROR [h: Alloc.Handle, table: Alloc.Selector] = CODE; GetChunk: PUBLIC PROC [h: Alloc.Handle, size: CARDINAL, table: Alloc.Selector] RETURNS [Alloc.Index] = { IF table # Tree.treeType OR size # SIZE[Tree.Node] THEN ERROR; -- called to reserve empty RETURN [FIRST[Alloc.Index]]}; FreeChunk: PUBLIC PROC [ h: Alloc.Handle, index: Alloc.Index, size: CARDINAL, table: Alloc.Selector] = {}; Words: PUBLIC PROC [h: Alloc.Handle, table: Alloc.Selector, size: CARDINAL] RETURNS [Alloc.OrderedIndex] = {ERROR}; AddNotify: PUBLIC PROC [h: Alloc.Handle, proc: Alloc.Notifier] = { ListerDefs.AddNotify[proc]}; DropNotify: PUBLIC PROC [h: Alloc.Handle, proc: Alloc.Notifier] = { ListerDefs.DropNotify[proc]}; Bounds: PUBLIC PROC [h: Alloc.Handle, table: Alloc.Selector] RETURNS [base: Alloc.Base, size: CARDINAL] = { [base, size] _ ListerDefs.Bounds[table]}; <> AcquireTable: PUBLIC PROC [id: CompilerUtil.TableId] RETURNS [LONG POINTER] = { RETURN[ IF id # debug THEN NIL ELSE Runtime.GetTableBase[Runtime.GlobalFrame[CBinary.DebugTab]]]}; ReleaseTable: PUBLIC PROC [CompilerUtil.TableId] = {}; AcquireStream: PUBLIC PROC [id: CompilerUtil.StreamId] RETURNS [IO.STREAM] = { RETURN[IF id = log THEN OutputDefs.GetOutputStream[] ELSE NIL]}; ReleaseStream: PUBLIC PROC [CompilerUtil.StreamId] = {}; }.