ðSyntax10.Scn.Fntõÿÿÿ`=ðIStampElemsAlloc11 Mar 98\Syntax10i.Scn.FntSyntax10b.Scn.Fnt5";(@!ÿÿÿÿ€8ÀÔFoldElemsNew*ÿÿÿÿ€8ÀÔ;ÿÿÿÿ€8ÀÔoÿÿÿÿ€8ÀÔ>ÿÿÿÿ€8ÀÔíÿÿÿÿ€8ÀÔ8ÿÿÿÿ€8ÀÔÇÿÿÿÿ€8ÀÔJÿÿÿÿ€8ÀÔÎÿÿÿ€8ÀÔ$Syntax10i.Scn.Fntlevel not emptyÿÿÿÿ€8ÀÔ1ÿÿÿÿ€8ÀÔ  )ÿÿÿÿ€8ÀÔóÿÿÿÿ€8ÀÔ <ÿÿÿÿ€8ÀÔÈÿÿÿÿ€8ÀÔ'ÿÿÿÿ€8ÀÔ$ÿÿÿÿ€8ÀÔ-ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ,ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ7  ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÛÿÿÿÿ€8ÀÔ  <ÿÿÿÿ€8ÀÔµ,*ÿÿÿÿ€8ÀÔ2ßMODULE RefElems; (* HM  *) IMPORT S := SYSTEM, Modules, Ref, Texts, FoldElems(*, Out*); CONST maxArrLen = 256; (*longer arrays are not expanded*) nofWriters = 3; TYPE Elem* = POINTER TO ElemDesc; ElemDesc* = RECORD (FoldElems.ElemDesc) indent: INTEGER; p-: S.PTR; m: Modules.Module; (* if p # NIL then m = module in which pointer var is declared*) form: SHORTINT; (* if p # NIL then form = pointer base form *) refpos: LONGINT (* if p # NIL then refpos = pos after pointer base form in ref info *) END ; VAR writers: ARRAY nofWriters OF Texts.Writer; used, allocated: SET; PROCEDURE^ WriteRider* (VAR w: Texts.Writer; VAR r: Ref.Rider; indent: INTEGER); PROCEDURE^ HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg); PROCEDURE OpenWriter (VAR w: Texts.Writer; VAR nr: INTEGER);  BEGIN IF used * {0..nofWriters - 1} = {0..nofWriters - 1} THEN Texts.OpenWriter(w); nr := nofWriters ELSE nr := 0; WHILE nr IN used DO INC(nr) END ; IF ~(nr IN allocated) THEN Texts.OpenWriter(writers[nr]); INCL(allocated, nr) END ; w := writers[nr]; INCL(used, nr) END END OpenWriter;  PROCEDURE CloseWriter (VAR w: Texts.Writer; nr: INTEGER);  BEGIN IF nr < nofWriters THEN Texts.OpenBuf(w.buf); writers[nr] := w; EXCL(used, nr) END END CloseWriter;  PROCEDURE NewLeft (indent: INTEGER; visible: BOOLEAN): Elem;  VAR e: Elem; BEGIN NEW(e); e.mode := FoldElems.colLeft; e.W := FoldElems.elemW; e.H := FoldElems.elemH; e.handle := HandleElem; e.visible := visible; e.indent := indent; NEW(e.hidden); Texts.OpenBuf(e.hidden); RETURN e END NewLeft;  PROCEDURE NewRight (visible: BOOLEAN): FoldElems.Elem;  VAR e: FoldElems.Elem; BEGIN NEW(e); e.mode := FoldElems.colRight; e.W := FoldElems.elemW; e.H := FoldElems.elemH; e.handle := FoldElems.FoldHandler; e.visible := visible; RETURN e END NewRight;  PROCEDURE WriteRec (VAR w: Texts.Writer; r: Ref.Rider; indent: INTEGER);  VAR e: Elem; BEGIN IF r.extLevel > 0 THEN e := NewLeft(indent, TRUE); DEC(r.extLevel); WriteRec(w, r, indent); INC(r.extLevel); Texts.Copy(w.buf, e.hidden); Texts.OpenBuf(w.buf); Texts.WriteElem(w, e); Texts.WriteElem(w, NewRight(TRUE)); r.SetTo(r.extLevel) END ; IF r.level <= r.extLevel THEN WriteRider(w, r, indent) END END WriteRec;  PROCEDURE HandleElem* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR r: Ref.Rider; e1: Elem; w: Texts.Writer; nr: INTEGER; BEGIN WITH e: Elem DO WITH m: FoldElems.PrepSwitchMsg DO IF (e.mode = FoldElems.colLeft) & (e.hidden.len = 0) THEN r.form := e.form; r.pos := e.refpos; r.m := e.m; IF r.m # NIL THEN COPY(r.m.name, r.mod) END ; Ref.OpenPtr(e.p, r); OpenWriter(w, nr); IF r.type = NIL THEN WriteRider(w, r, e.indent) ELSE WriteRec(w, r, e.indent) END ; Texts.Copy(w.buf, e.hidden); Texts.OpenBuf(w.buf); CloseWriter(w, nr) END | m: Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1) ELSE e1 := m.e(Elem) END ; Texts.CopyElem(e, e1); e1.mode := e.mode; e1.visible := e.visible; IF e.mode IN {FoldElems.colLeft, FoldElems.expLeft, FoldElems.tempLeft, FoldElems.findLeft} THEN NEW(e1.hidden); Texts.OpenBuf(e1.hidden); Texts.Copy(e.hidden, e1.hidden) END ; e1.indent := e.indent; e1.p := e.p; e1.m := e.m; e1.form := e.form; e1.refpos := e.refpos; m.e := e1 ELSE FoldElems.FoldHandler(e, m) END END END HandleElem;  PROCEDURE WriteVal* (VAR w: Texts.Writer; VAR r: Ref.Rider; indent: INTEGER);  VAR si: SHORTINT; i, j: INTEGER; li: LONGINT; re: REAL; lr: LONGREAL; ch: CHAR; b: BOOLEAN; s: SET; proc: Ref.ProcVar; r1: Ref.Rider; p: S.PTR; str: ARRAY 1024 OF CHAR; PROCEDURE Ch (ch: CHAR);  BEGIN Texts.Write(w, ch) END Ch;  PROCEDURE Str (s: ARRAY OF CHAR);  BEGIN Texts.WriteString(w, s) END Str;  PROCEDURE Int (i: LONGINT);  BEGIN Texts.WriteInt(w, i, 0) END Int;  PROCEDURE Folds;  VAR e: Elem; w1: Texts.Writer; r1: Ref.Rider; nr: INTEGER; BEGIN e := NewLeft(indent+1, TRUE); IF r.form = Ref.Pointer THEN r.ReadPtr(e.p); S.GET(r.pos, e.form); e.refpos := r.pos + 1; e.m := r.m ELSE r.Zoom(r1); OpenWriter(w1, nr); IF r.form = Ref.Record THEN WriteRec(w1, r1, e.indent) ELSE (*Array, DynArr*) IF r1.len <= maxArrLen THEN WriteRider(w1, r1, e.indent) ELSE Texts.WriteString(w1, "array too long") END END ; Texts.Copy(w1.buf, e.hidden); CloseWriter(w1, nr) END ; Texts.WriteElem(w, e); Texts.WriteElem(w, NewRight(TRUE)) END Folds;  PROCEDURE FoldsNIL;  VAR e: Elem; w1: Texts.Writer; BEGIN Texts.OpenWriter(w1); e := NewLeft(indent+1, FALSE); Texts.WriteString(w1, "NIL"); Texts.Copy(w1.buf, e.hidden); Texts.WriteElem(w, e); Texts.WriteString(w, "NIL"); Texts.WriteElem(w, NewRight(FALSE)) END FoldsNIL;  BEGIN CASE r.form OF Ref.Byte, Ref.Char: r.Read(ch); IF (ch < " ") OR (ch > "~") THEN Str("CHR("); Int(ORD(ch)); Ch(")"); ELSE Ch('"'); Ch(ch); Ch('"') END | Ref.Bool: r.ReadBool(b); IF b THEN Str("TRUE") ELSE Str("FALSE") END | Ref.SInt: r.ReadSInt(si); Int(si) | Ref.Int: r.ReadInt(i); Int(i) | Ref.LInt: r.ReadLInt(li); Int(li) | Ref.Real: r.ReadReal(re); Texts.WriteReal(w, re, 10) | Ref.LReal: r.ReadLReal(lr); Texts.WriteLongReal(w, lr, 10) | Ref.Set: r.ReadSet(s); Ch("{"); b := TRUE; FOR i := 0 TO MAX(SET) DO IF i IN s THEN IF b THEN b := FALSE ELSE Ch(",") END ; Int(i); j := i+1; WHILE (j <= MAX(SET)) & (j IN s) DO INC(j) END ; IF j > i+1 THEN Str(".."); Int(j-1) END ; i := j END END ; Ch("}") | Ref.Procedure: r.ReadProc(proc); S.GET(S.ADR(proc), li); Ref.OpenProc(li, r1); IF r1.mod = "" THEN Texts.WriteHex(w, li); Ch("H") ELSE Str(r1.mod); Ch("."); Str(r1.name) END | Ref.Pointer: r.ReadPtr(p); IF p = NIL THEN FoldsNIL ELSE Str("^ "); Folds END | Ref.Record: Folds | Ref.Array, Ref.DynArr: r.Zoom(r1); IF r1.form = Ref.Char THEN r.ReadString(str); Ch('"'); Str(str); Ch('"') ELSE Folds END END END WriteVal;  PROCEDURE WriteRider* (VAR w: Texts.Writer; VAR r: Ref.Rider; indent: INTEGER);  VAR i: INTEGER; BEGIN WHILE r.mode # Ref.End DO IF r.name # "@" THEN Texts.WriteLn(w); FOR i := 1 TO indent DO Texts.Write(w, 09X) END ; IF r.mode = Ref.Elem THEN Texts.WriteInt(w, r.idx, 0) ELSE Texts.WriteString(w, r.name); IF r.vis = Ref.external THEN Texts.Write(w, "*") ELSIF r.vis = Ref.externalR THEN Texts.Write(w, "-") END END ; Texts.WriteString(w, " = "); WriteVal(w, r, indent) (* ELSE dummy variable for return type of procedure *) END ; r.Next END END WriteRider;  BEGIN used := {}; allocated := {} END RefElems.