x<Syntax10.Scn.FntSyntax10b.Scn.Fnt Syntax10i.Scn.Fnt/zIStampElemsAlloc6 Aug 978FoldElemsNew#Syntax10.Scn.Fnt VAR i, j, len: INTEGER; BEGIN len := SHORT(LEN(s)) - 1; i := 0; WHILE s[i] # 0X DO INC(i) END; j := 0; WHILE (i < len) & (ext[j] # 0X) DO s[i] := ext[j]; INC(i); INC(j) END; s[i] := 0X END Append; 8.c8#Syntax10.Scn.Fnt{{ VAR i, j: INTEGER; m: LONGINT; help : ViewDataDesc; BEGIN i := l; j := r; m := a[(i+j) DIV 2].amount; REPEAT WHILE a[i].amount > m DO INC(i) END; WHILE a[j].amount < m DO DEC(j) END; IF i <= j THEN help := a[i]; a[i] := a[j]; a[j] := help; INC(i); DEC(j) END UNTIL i > j; IF l < j THEN Sort(a, l, j) END; IF i < r THEN Sort(a, i, r) END END Sort; 8y8#Syntax10.Scn.Fnt(( VAR v: Viewers.Viewer; x, y: INTEGER; BEGIN TextFrames.Open(f, f.text, 0); f.handle := handle; IF userTrack THEN Oberon.AllocateUserViewer(0, x, y) ELSE Oberon.AllocateSystemViewer(0, x, y) END; v := MenuViewers.New(TextFrames.NewMenu(title,menu), f, TextFrames.menuH, x, y) END Browse; 8,l8#Syntax10.Scn.Fntrr BEGIN Out.Ln; Out.String("pos "); Out.Int(pos, 0); Out.String(" source must be free of error") END ErrProc; 8)8#Syntax10.Scn.Fnt VAR i, j, k : INTEGER; BEGIN i := 0; WHILE s[i] # 0X DO INC(i) END; k := i - 1; WHILE (k >= 0) & (s[k] # PFBasic.SeparationMark) DO IF s[k] = "." THEN i := k; s[k] := 0X END; DEC(k) END; IF k >= 0 THEN FOR j := k + 1 TO i DO s[j - k - 1] := s[j] END END END Strip; 828#Syntax10.Scn.Fnt VAR clone: Texts.Text; buf: Texts.Buffer; BEGIN clone := TextFrames.Text(""); NEW(buf); Texts.OpenBuf(buf); Texts.Save(t, 0, t.len, buf); Texts.Append(clone, buf); RETURN clone END TextClone; 8-8#Syntax10.Scn.Fnt   VAR i: INTEGER; BEGIN i := 0; WHILE s[i] # 0X DO INC(i) END; IF (s[i-4] # ".") OR (s[i-3] # "M") OR (s[i-2] # "o") OR (s[i-1] # "d") THEN s[i] := "."; INC(i); s[i] := "M"; INC(i); s[i] := "o"; INC(i); s[i] := "d"; INC(i); s[i] := 0X; END END AppendMod; 88#Syntax10.Scn.Fnt VAR i : LONGINT; ch : CHAR; BEGIN IF (s.class = Texts.Char) & (s.c = '~') THEN RETURN FALSE END; IF s.class # Texts.Name THEN RETURN FALSE END; COPY(s.s, name); AppendMod(name); text := TextFrames.Text(name); Texts.Scan(s); WHILE (s.class = Texts.Char) & (s.c = OptionMark) DO Texts.Scan(s); IF s.class = Texts.Int THEN columns := SHORT(s.i); Texts.Scan(s) ELSIF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s, option); Texts.Scan(s) END; END; RETURN TRUE; END GetNextInputText; 88s8#Syntax10.Scn.Fnt>> VAR i : LONGINT; ch : CHAR; BEGIN Texts.Scan(s); WHILE (s.class = Texts.Char) & (s.c = OptionMark) DO Texts.Scan(s); IF s.class = Texts.Int THEN columns := SHORT(s.i) ELSIF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s, option) END; Texts.Scan(s) END END ScanOption; 8888#Syntax10.Scn.Fnt VAR clone: ProfFrame; BEGIN IF m.F = NIL THEN NEW(clone); m.F := clone END; TextFrames.Handle(F, m); m.F(ProfFrame).lastbeg := F.lastbeg; m.F(ProfFrame).lastend := F.lastend; m.F(ProfFrame).mod := F.mod END Copy; 8;8#Syntax10.Scn.Fnt VAR beg, end: LONGINT; BEGIN beg := F.org; end := TextFrames.Pos(F, F.X + F.W, F.Y); IF ((beg < begSel) OR (endSel < end)) & ((begSel < beg) OR (end < endSel)) THEN TextFrames.Show(F, begSel) END END Scroll; 89U8#Syntax10.Scn.Fnt VAR clone: TimerFrame; BEGIN IF m.F = NIL THEN NEW(clone); m.F := clone END; TF.Copy^(m); m.F(TimerFrame).data := TF.data END Copy; 8( 8#Syntax10.Scn.Fnt VAR i, j : INTEGER; BEGIN j := TF.mod.NOfCounters(); NEW(TF.data,j); DEC(j); FOR i := 0 TO j DO TF.data[i].amount := TF.mod.GetDataOf(i); TF.data[i].index := i END; Sort(TF.data,0,j) END CopyData; 8Bs8#Syntax10.Scn.Fntkk VAR i: INTEGER; BEGIN i := 0; WHILE TF.data[i].index # index DO INC(i) END; RETURN i END FindCounter; 8$8#Syntax10.Scn.Fnt VAR copy: Texts.CopyMsg; i, percent : INTEGER; pos, fullSum, sum, amount, calls, beg, end : LONGINT; indicator : Indicator.IndicatorElem; BEGIN TF.CopyData(); sum := 0; FOR i := 0 TO SHORT(LEN(TF.data^) - 1) DO sum := sum + TF.data[i].amount END; fullSum := sum; IF sum = 0 THEN sum := 1 END; Texts.Delete(TF.text, 0, TF.text.len); TextFrames.defParc.handle(TextFrames.defParc, copy); copy.e(TextFrames.Parc).tab[0] := timeW; copy.e(TextFrames.Parc).tab[1] := copy.e(TextFrames.Parc).tab[0] + percentW; copy.e(TextFrames.Parc).tab[2] := copy.e(TextFrames.Parc).tab[1] + indicatorW; copy.e(TextFrames.Parc).tab[3] := copy.e(TextFrames.Parc).tab[2] + callsW; copy.e(TextFrames.Parc).tab[4] := copy.e(TextFrames.Parc).tab[3] + timeW + 2*chW; copy.e(TextFrames.Parc).nofTabs := 5; Texts.WriteElem(w, copy.e); Texts.Append(TF.text, w.buf); Texts.WriteString(w,"time [ms] "); Texts.Write(w, Tab); Texts.Write(w, Tab); Texts.WriteString(w,"calls"); Texts.Write(w, Tab); Texts.WriteString(w,"t/call [ms]"); Texts.Write(w, Tab); Texts.WriteString(w,"procedure name"); Texts.WriteLn(w); FOR i := 0 TO SHORT(LEN(TF.data^) - 1) DO amount := TF.data[i].amount DIV 10; Texts.WriteInt(w, amount, 0); IF amount < 10 THEN Texts.Write(w, "."); Texts.WriteInt(w,TF.data[i].amount MOD 10, 0) END; percent := SHORT((TF.data[i].amount* 1000) DIV sum); INC(percent,5); percent := percent DIV 10; Texts.Write(w, Tab); indicator := Indicator.NewIndicator(W, H, percent); Texts.WriteInt(w, percent,0); Texts.Write(w,'%');Texts.Write(w, Tab); Texts.WriteElem(w,indicator); Texts.Write(w, Tab); calls := TF.mod(PFBasic.ModuleTime).GetFrequencyOf(TF.data[i].index); Texts.WriteInt(w, calls, 0); Texts.Write(w, Tab); IF calls # 0 THEN amount := TF.data[i].amount DIV calls ELSE amount := 0 END; Texts.WriteInt(w, amount DIV 10, 0); IF (amount < 10) & (calls > 0) THEN IF calls > 1000 THEN amount := TF.data[i].amount DIV (calls DIV 10) ELSE amount := (TF.data[i].amount*10) DIV calls END; Texts.Write(w, "."); Texts.WriteInt(w, (amount MOD 40) DIV 4, 0) END; Texts.Write(w, Tab); TF.mod(PFBasic.ModuleTime).GetNameScope(TF.data[i].index, beg, end); Texts.Save(TF.sourceText, beg, end, w.buf); Texts.WriteLn(w); END; Texts.WriteLn(w); Texts.WriteInt(w, fullSum DIV 10, 0); IF fullSum < 100 THEN Texts.Write(w, "."); Texts.WriteInt(w, (fullSum MOD 10), 0) END; Texts.WriteString(w, " consumed time"); Texts.Append(TF.text, w.buf) END GenText; 8H8#Syntax10.Scn.Fnt VAR r : Texts.Reader; ch : CHAR; BEGIN Texts.OpenReader(r, TF.text,0); REPEAT Texts.Read(r, ch) UNTIL ch = CR; IF (Texts.Pos(r) <= pos) & (Texts.Pos(r) < TF.text.len) THEN index := 0; Texts.Read(r, ch); WHILE (Texts.Pos(r) <= pos) & (Texts.Pos(r) < TF.text.len) DO IF (ch = CR) OR (ch = TF.breakCh) THEN INC(index) END; Texts.Read(r, ch) END; IF index >= TF.mod.NOfCounters() THEN index := -1 END ELSE index := -1 END END GetIndex; 8N^8#Syntax10.Scn.Fnt VAR r : Texts.Reader; ch : CHAR; i : INTEGER; BEGIN Texts.OpenReader(r, TF.text,0); REPEAT Texts.Read(r, ch) UNTIL ch = CR; i := 0; beg := Texts.Pos(r); Texts.Read(r, ch); WHILE i # index DO IF (ch = CR) OR (ch = TF.breakCh) THEN beg := Texts.Pos(r); INC(i) END; Texts.Read(r, ch) END; WHILE ch >= " " DO Texts.Read(r,ch) END; end := Texts.Pos(r) - 1 END GetBegEnd; 8=?8#Syntax10.Scn.Fnt VAR clone: CounterFrame; BEGIN IF m.F = NIL THEN NEW(clone); m.F := clone END; CT.Copy^(m); m.F(CounterFrame).countersALine := CT.countersALine END Copy; 8'8#Syntax10.Scn.Fnt   VAR copy: Texts.CopyMsg; i : INTEGER; BEGIN CT.CopyData(); Texts.Delete(CT.text, 0, CT.text.len); TextFrames.defParc.handle(TextFrames.defParc, copy); i := 0; WHILE (i < 32) & (i< CT.countersALine) DO copy.e(TextFrames.Parc).tab[i] := 8*chW + tabW; INC(i) END; copy.e(TextFrames.Parc).nofTabs := i; Texts.WriteElem(w, copy.e); Texts.Append(CT.text, w.buf); FOR i := 1 TO CT.countersALine - 1 DO Texts.WriteString(w, "frequency"); Texts.Write(w, Tab) END; Texts.WriteString(w, "frequency"); Texts.Write(w, CR); FOR i := 0 TO SHORT(LEN(CT.data^) - 1) DO Texts.WriteInt(w, CT.data[i].amount, 0); IF ((i MOD CT.countersALine) + 1) = CT.countersALine THEN Texts.WriteLn(w) ELSE Texts.Write(w, Tab) END END; Texts.Append(CT.text, w.buf) END GenText; 8 ./8#Syntax10.Scn.Fnt VAR beg, end, pos: LONGINT; index: INTEGER; msg: ProfMsg; BEGIN WITH f: ProfFrame DO WITH m: Oberon.InputMsg DO IF (m.id = Oberon.track) & (m.keys # {}) THEN IF m.X >= f.X + TextFrames.barW THEN pos := TextFrames.Pos(f, m.X, m.Y); IF f.mod.FindCounter(pos, index) THEN msg.index := index; msg.mod := f.mod; Viewers.Broadcast(msg) END; REPEAT Input.Mouse(m.keys, m.X, m.Y); Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, m.X, m.Y) UNTIL m.keys = {} ELSE TextFrames.Handle(f, m) END END | m: ProfMsg DO IF m.mod = f.mod THEN f.mod.GetScopeOf(m.index, beg, end); IF ~f.hasSel OR (beg # f.lastbeg) OR (end # f.lastend) THEN f.lastbeg := beg; f.lastend := end; f.Scroll(beg, end); TextFrames.SetSelection(f, beg, end) END END | m: Oberon.CopyMsg DO f.Copy(m) ELSE TextFrames.Handle(f, m) END ELSE END END SrcHandler; 8 .8#Syntax10.Scn.Fnt VAR beg, end, pos: LONGINT; index: INTEGER; msg: ProfMsg; BEGIN WITH f: TimerFrame DO WITH m: Oberon.InputMsg DO IF (m.id = Oberon.track) & (m.keys # {}) THEN IF m.X >= f.X + TextFrames.barW THEN REPEAT pos := TextFrames.Pos(f, m.X, m.Y); f.GetIndex(pos, index); IF index >= 0 THEN msg.mod := f.mod; msg.index := f.data[index].index; Viewers.Broadcast(msg) END; Input.Mouse(m.keys, m.X, m.Y); Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, m.X, m.Y) UNTIL m.keys = {} ELSE TextFrames.Handle(f, m) END END | m: ProfMsg DO IF (m.mod = f.mod) & (m.index >= 0) THEN f.GetBegEnd(f.FindCounter(m.index), beg, end); IF ~f.hasSel OR (beg # f.lastbeg) OR (end # f.lastend) THEN f.Scroll(beg , end); TextFrames.SetSelection(f, beg, end) END END | m: UpdateMsg DO IF f.mod = m.mod THEN f.GenText(); TextFrames.Show(f, 0) END | m: Oberon.CopyMsg DO f.Copy(m) ELSE TextFrames.Handle(f, m) END ELSE END END Handler; 8;88#Syntax10.Scn.FntAA VAR x, y, h: INTEGER; BEGIN y := Display.Bottom; x := Display.Width-1; h := Viewers.minH; Viewers.minH := 1; v := MenuViewers.New(TextFrames.NewMenu("", ""), TextFrames.NewText(t, 0), TextFrames.menuH, x, y); Oberon.Pointer.X := x; Oberon.Pointer.Y := y; Viewers.minH := h END OpenTempViewer; 8[Syntax14.Scn.Fnt8 8#Syntax10.Scn.Fnt VAR name, dummy: ARRAY 128 OF CHAR; x, y, columns: INTEGER; sf: ProfFrame; cf : CounterFrame; f : TimerFrame; s : Texts.Scanner; BEGIN NEW(sf); GetFirstInputText(sf.text, name, dummy, columns, s); REPEAT IF (sf.text = NIL) OR ((sf.text # NIL) & (sf.text.len = 0)) THEN Out.Ln; Out.String("file '"); Out.String(name); Out.String("' not found"); RETURN END; Strip(name); sf.mod := PFBasic.GetModule(name); sf.lastbeg := -1; sf.lastend := -1; IF (sf.mod = NIL) THEN Out.Ln; Out.String(name); Out.String(" is not executed"); RETURN END; Strip(name); IF sf.mod IS PFBasic.ModuleTime THEN NEW(f); f.breakCh := CR; Append(name, ".Times") ELSE NEW(cf); cf.breakCh := Tab; IF columns > 0 THEN cf.countersALine := columns ELSE cf.countersALine := 1 END; f := cf; Append(name, ".Frequencies") END; f.mod := sf.mod; f.lastbeg := -1; f.lastend := -1; FoldElems.ExpandAll(sf.text,0,TRUE); f.sourceText := sf.text; f.text := TextFrames.Text(""); f.GenText(); Browse(f, FALSE, Handler, name,"^Profiler.Menu.Text"); Strip(name); Append(name,".Source"); Browse(sf, TRUE, SrcHandler, name,"^Profiler.Menu.Text"); NEW(sf); UNTIL ~GetNextInputText (sf.text, name, dummy, columns, s); END Show; 8  8#Syntax10.Scn.Fnt VAR i : PFBasic.Iterator; n : ARRAY 32 OF CHAR; BEGIN i := PFBasic.NewIterator(); Out.Ln; Out.String("executed modules"); WHILE i.NextModName(n) DO Out.Ln; Out.String(" "); Out.String(n) END END ShowModules; 8 8#Syntax10.Scn.Fnt33 VAR name, dummy : ARRAY 128 OF CHAR; t: Texts.Text; m : PFBasic.Module; columns: INTEGER; msg: UpdateMsg; s: Texts.Scanner; BEGIN GetFirstInputText(t, name, dummy, columns, s); Strip(name); m := PFBasic.GetModule(name); IF m # NIL THEN msg.mod := m; Viewers.Broadcast(msg) END END Refresh; 8 ]8#Syntax10.Scn.Fnt VAR name, d : ARRAY 128 OF CHAR; dummy: Texts.Text; columns: INTEGER; s: Texts.Scanner; BEGIN GetFirstInputText(dummy, name, d, columns, s); Strip( name); dummy := NIL; IF PFBasic.DelModule(name) THEN Out.String("Profiler.Remove "); Out.String(name); Out.String(" removed ") ELSE Out.String("Profiler.Remove "); Out.String(name); Out.String(" failed ") END END Remove; 8 J8#Syntax10.Scn.Fnt VAR name, dummy : ARRAY 128 OF CHAR; t: Texts.Text; m : PFBasic.Module; columns: INTEGER; msg : UpdateMsg; s: Texts.Scanner; BEGIN GetFirstInputText(t, name, dummy, columns, s); Strip( name); m := PFBasic.GetModule(name); IF m # NIL THEN m.Reset; msg.mod := m; Viewers.Broadcast(msg); ELSE Out.Ln; Out.String("module "); Out.String(name); Out.String(" not found") END END Reset; 8r8#Syntax10.Scn.Fntll tabW := LONG(35)*LONG(mm DIV 10); Display.GetChar(Fonts.Default.raster, "0", dx, x, y, cw, ch, pat); chW := LONG(dx)* LONG(Unit); timeW := chW*7 + tabW; Display.GetChar(Fonts.Default.raster, "%", dx, x, y, cw, ch, pat); percentW := chW*3 + LONG(dx)*LONG(Unit) + tabW; indicatorW := LONG(W)*LONG(Unit) + tabW; callsW := chW*6 + tabW; Texts.OpenWriter(w) 8MODULE Profiler; (* Christian Mayrhofer, Friedrich Traunmueller  *) IMPORT Display, Oberon, Input, Texts, TextFrames, Files, Fonts, Viewers, MenuViewers, Out, ParcElems, PFBasic, FoldElems, PFP, PFS, Indicator; CONST Tab = 9X; CR = 0DX; OptionMark = '\'; Unit = TextFrames.Unit; mm = TextFrames.mm; W = 80; H = 9; TYPE ViewDataDesc = RECORD amount : LONGINT; index : INTEGER; pos : LONGINT END; ViewData = POINTER TO ARRAY OF ViewDataDesc; UpdateMsg = RECORD (Display.FrameMsg) mod: PFBasic.Module END; ProfMsg = RECORD (Display.FrameMsg) mod: PFBasic.Module; index : INTEGER END; ProfFrame = POINTER TO ProfFrameDesc; ProfFrameDesc = RECORD (TextFrames.FrameDesc) mod: PFBasic.Module; lastbeg, lastend: LONGINT END; TimerFrame = POINTER TO TimerFrameDesc; TimerFrameDesc = RECORD (ProfFrameDesc) sourceText: Texts.Text; data : ViewData; breakCh: CHAR END; CounterFrame = POINTER TO CounterFrameDesc; CounterFrameDesc = RECORD (TimerFrameDesc) countersALine : INTEGER END; VAR w : Texts.Writer; chW, timeW, percentW, tabW, indicatorW, callsW: LONGINT; pat: LONGINT; dx, x, y, cw, ch: INTEGER; PROCEDURE Append (VAR s: ARRAY OF CHAR; ext: ARRAY OF CHAR); PROCEDURE Sort (a: ViewData ; l, r: INTEGER); PROCEDURE Browse (f: TextFrames.Frame; userTrack: BOOLEAN; handle: Display.Handler; title,menu: ARRAY OF CHAR); PROCEDURE ErrProc(n:INTEGER; pos: LONGINT); PROCEDURE Strip (VAR s: ARRAY OF CHAR); PROCEDURE TextClone (t: Texts.Text) : Texts.Text; PROCEDURE AppendMod (VAR s: ARRAY OF CHAR); PROCEDURE GetNextInputText (VAR text: Texts.Text; VAR name, option: ARRAY OF CHAR; VAR columns: INTEGER; VAR s : Texts.Scanner) : BOOLEAN; PROCEDURE GetFirstInputText (VAR text: Texts.Text; VAR name, option: ARRAY OF CHAR; VAR columns: INTEGER; VAR s : Texts.Scanner); VAR f: Display.Frame; parT: Texts.Text; v: Viewers.Viewer; time, beg, end: LONGINT; PROCEDURE ScanOption; BEGIN text := NIL; option[0] := 0X; name[0] := 0X; columns := 0; Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN (* get modulename from menuviewer *) Texts.OpenScanner(s, Oberon.Par.vwr.dsc(TextFrames.Frame).text, 0); Texts.Scan(s); IF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s,name) END; f := Oberon.Par.frame.next; IF (f # NIL) & (f IS TextFrames.Frame) THEN Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); ScanOption; text := TextClone( f(TextFrames.Frame).text) END ELSIF s.class = Texts.Char THEN IF s.c = "*" THEN ScanOption; v := Oberon.MarkedViewer(); IF (v # NIL) & (v.dsc # NIL) & (v.dsc.next IS TextFrames.Frame) THEN Texts.OpenScanner(s, v.dsc(TextFrames.Frame).text, 0); Texts.Scan(s); IF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s,name); text := TextClone(v.dsc.next(TextFrames.Frame).text); Texts.Scan(s) END END ELSIF s.c = "^" THEN ScanOption; Oberon.GetSelection(parT, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(s, parT, beg); Texts.Scan(s); IF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s, name); AppendMod(name); text := TextFrames.Text(name); ScanOption END END END ELSIF (s.class = Texts.Name) OR (s.class = Texts.String) THEN COPY(s.s, name); AppendMod(name); ScanOption; text := TextFrames.Text(name) END; END GetFirstInputText ;  PROCEDURE (F: ProfFrame) Copy (VAR m: Oberon.CopyMsg); PROCEDURE (F: ProfFrame) Scroll (begSel, endSel: LONGINT); PROCEDURE (TF: TimerFrame) Copy(VAR m: Oberon.CopyMsg); PROCEDURE (TF: TimerFrame) CopyData (); PROCEDURE (TF: TimerFrame) FindCounter (index: INTEGER): INTEGER; PROCEDURE (TF: TimerFrame) GenText; PROCEDURE (TF: TimerFrame) GetIndex (pos: LONGINT; VAR index: INTEGER); PROCEDURE (TF: TimerFrame) GetBegEnd (index: INTEGER; VAR beg, end: LONGINT); PROCEDURE (CT : CounterFrame) Copy (VAR m: Oberon.CopyMsg); PROCEDURE (CT : CounterFrame) GenText; PROCEDURE SrcHandler* (f: Display.Frame; VAR m: Display.FrameMsg); PROCEDURE Handler* (f: Display.Frame; VAR m: Display.FrameMsg); (*-----------------commandos----------------*) PROCEDURE Compile*; VAR v: MenuViewers.Viewer; par: Oberon.ParList; f : TextFrames.Frame; t : Texts.Text ; name, option : ARRAY 132 OF CHAR; dummy: INTEGER; id, res : INTEGER; pos : LONGINT; s : Texts.Scanner; PROCEDURE OpenTempViewer (t: Texts.Text; VAR v: MenuViewers.Viewer); BEGIN GetFirstInputText(t, name, option, dummy, s); Out.Ln; LOOP Out.String("Profiler "); Out.String(name);Out.String(option); IF (t = NIL) OR (t.len = 0) THEN Out.String(" not found !"); Out.Ln ELSE FoldElems.ExpandAll(t,0,TRUE); PFS.Reset(t,0,ErrProc); PFP.time := option # "count"; PFP.out := TextClone(t); PFP.Parse; NEW(f); f.text:= PFP.out; OpenTempViewer(f.text, v); par := Oberon.Par; par.text := TextFrames.Text(""); Texts.Write(w, "*"); Texts.Append(par.text, w.buf); par.pos := 0; Oberon.Call( "Compiler.Compile", par, FALSE, res); Viewers.Close(v); IF option = "debug" THEN Browse (TextFrames.NewText(PFP.out, 0), TRUE, TextFrames.Handle, "Source", "^Edit.Menu.Text") END; END; option[0] := 0X; IF ~GetNextInputText(t, name, option, dummy, s) THEN EXIT END END END Compile;  PROCEDURE Show*; PROCEDURE ShowModules*; PROCEDURE Refresh*; PROCEDURE Remove*; PROCEDURE Reset*; BEGIN END Profiler.