]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-compiler/M2DebugStack.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-compiler / M2DebugStack.mod
CommitLineData
1eee94d3
GM
1(* M2DebugStack.mod display parameter stack.
2
a945c346 3Copyright (C) 2011-2024 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Modula-2; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. *)
21
22IMPLEMENTATION MODULE M2DebugStack ;
23
24FROM DynamicStrings IMPORT InitString, KillString, Dup, Index, Slice, char,
25 ConCat, ConCatChar, InitStringCharStar, Length, Mark ;
26
27FROM SymbolTable IMPORT IsConstLit, IsConstSet, IsConstructor, IsConst,
28 IsArray, IsVar, IsEnumeration, IsFieldEnumeration,
29 IsUnbounded, IsProcType, IsProcedure, IsPointer, IsParameter,
30 IsParameterVar, IsType, IsRecord, IsRecordField, IsVarient,
31 IsModule, IsDefImp, IsSet, IsSubrange, GetSymName, NulSym ;
32
33FROM StringConvert IMPORT CardinalToString ;
34FROM NameKey IMPORT Name, KeyToCharStar ;
35FROM FIO IMPORT File, StdOut ;
36FROM SFIO IMPORT WriteS ;
37FROM M2Error IMPORT InternalError ;
38FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ;
39
40CONST
41 Debugging = FALSE ;
42
43VAR
44 OperandTok,
45 OperandT,
46 OperandF,
47 OperandA,
48 OperandD,
49 OperandRW : ProcedureWord ;
50 OperandAnno: ProcedureString ;
51
52
53(*
54 x - checks to see that a=b.
55*)
56
57PROCEDURE x (a, b: String) : String ;
58BEGIN
59 IF a#b
60 THEN
61 InternalError ('different string returned')
62 END ;
63 RETURN( a )
64END x ;
65
66
67(*
68 IsWhite - returns TRUE if, ch, is a space.
69*)
70
71PROCEDURE IsWhite (ch: CHAR) : BOOLEAN ;
72BEGIN
73 RETURN( ch=' ' )
74END IsWhite ;
75
76
77(*
78 ConCatWord - joins sentances, a, b, together.
79*)
80
81PROCEDURE ConCatWord (a, b: String) : String ;
82BEGIN
83 IF (Length(a)=1) AND (char(a, 0)='a')
84 THEN
85 a := x(a, ConCatChar(a, 'n'))
86 ELSIF (Length(a)>1) AND (char(a, -1)='a') AND IsWhite(char(a, -2))
87 THEN
88 a := x(a, ConCatChar(a, 'n'))
89 END ;
90 IF (Length(a)>0) AND (NOT IsWhite(char(a, -1)))
91 THEN
92 a := x(a, ConCatChar(a, ' '))
93 END ;
94 RETURN( x(a, ConCat(a, b)) )
95END ConCatWord ;
96
97
98(*
99 symDesc -
100*)
101
102PROCEDURE symDesc (sym: CARDINAL; o: String) : String ;
103BEGIN
104 IF sym = NulSym
105 THEN
106 RETURN( ConCatWord(o, Mark(InitString('NulSym'))) )
107 ELSIF IsConstLit(sym)
108 THEN
109 RETURN( ConCatWord(o, Mark(InitString('constant literal'))) )
110 ELSIF IsConstSet(sym)
111 THEN
112 RETURN( ConCatWord(o, Mark(InitString('constant set'))) )
113 ELSIF IsConstructor(sym)
114 THEN
115 RETURN( ConCatWord(o, Mark(InitString('constructor'))) )
116 ELSIF IsConst(sym)
117 THEN
118 RETURN( ConCatWord(o, Mark(InitString('constant'))) )
119 ELSIF IsArray(sym)
120 THEN
121 RETURN( ConCatWord(o, Mark(InitString('array'))) )
122 ELSIF IsVar(sym)
123 THEN
124 RETURN( ConCatWord(o, Mark(InitString('variable'))) )
125 ELSIF IsEnumeration(sym)
126 THEN
127 RETURN( ConCatWord(o, Mark(InitString('enumeration type'))) )
128 ELSIF IsFieldEnumeration(sym)
129 THEN
130 RETURN( ConCatWord(o, Mark(InitString('enumeration field'))) )
131 ELSIF IsUnbounded(sym)
132 THEN
133 RETURN( ConCatWord(o, Mark(InitString('unbounded parameter'))) )
134 ELSIF IsProcType(sym)
135 THEN
136 RETURN( ConCatWord(o, Mark(InitString('procedure type'))) )
137 ELSIF IsProcedure(sym)
138 THEN
139 RETURN( ConCatWord(o, Mark(InitString('procedure'))) )
140 ELSIF IsPointer(sym)
141 THEN
142 RETURN( ConCatWord(o, Mark(InitString('pointer'))) )
143 ELSIF IsParameter(sym)
144 THEN
145 IF IsParameterVar(sym)
146 THEN
147 RETURN( ConCatWord(o, Mark(InitString('var parameter'))) )
148 ELSE
149 RETURN( ConCatWord(o, Mark(InitString('parameter'))) )
150 END
151 ELSIF IsType(sym)
152 THEN
153 RETURN( ConCatWord(o, Mark(InitString('type'))) )
154 ELSIF IsRecord(sym)
155 THEN
156 RETURN( ConCatWord(o, Mark(InitString('record'))) )
157 ELSIF IsRecordField(sym)
158 THEN
159 RETURN( ConCatWord(o, Mark(InitString('record field'))) )
160 ELSIF IsVarient(sym)
161 THEN
162 RETURN( ConCatWord(o, Mark(InitString('varient record'))) )
163 ELSIF IsModule(sym)
164 THEN
165 RETURN( ConCatWord(o, Mark(InitString('module'))) )
166 ELSIF IsDefImp(sym)
167 THEN
168 RETURN( ConCatWord(o, Mark(InitString('definition or implementation module'))) )
169 ELSIF IsSet(sym)
170 THEN
171 RETURN( ConCatWord(o, Mark(InitString('set'))) )
172 ELSIF IsSubrange(sym)
173 THEN
174 RETURN( ConCatWord(o, Mark(InitString('subrange'))) )
175 ELSE
176 RETURN( o )
177 END
178END symDesc ;
179
180
181(*
182 Output - output string, s, to Stdout. It also disposes of the string, s.
183*)
184
185PROCEDURE Output (s: String) ;
186BEGIN
187 s := WriteS(StdOut, s) ;
188 s := KillString(s)
189END Output ;
190
191
192(*
193 GetComment -
194*)
195
196PROCEDURE GetComment (s: String) : INTEGER ;
197VAR
198 c: INTEGER ;
199BEGIN
200 c := Index(s, '|', 0) ;
201 WHILE c>=0 DO
202 INC(c) ;
203 IF c>=VAL(INTEGER, Length(s))
204 THEN
205 RETURN -1
206 ELSIF char(s, c)='|'
207 THEN
208 RETURN c+1
209 END ;
210 c := Index(s, '|', c)
211 END ;
212 RETURN -1
213END GetComment ;
214
215
216(*
217 doName - concatenate namekey, o, to, p.
218*)
219
220PROCEDURE doName (p: String; o: WORD) : String ;
221BEGIN
222 RETURN ConCat(p, InitStringCharStar(KeyToCharStar(o))) ;
223END doName ;
224
225
226(*
227 doSymName - concatenate symbol, o, name to, p.
228*)
229
230PROCEDURE doSymName (p: String; o: WORD) : String ;
231BEGIN
232 RETURN ConCat(p, InitStringCharStar(KeyToCharStar(GetSymName(o)))) ;
233END doSymName ;
234
235
236(*
237 doNumber - convert, o, to a cardinal and increment the length, l,
238 by the number of characters required to represent, o.
239*)
240
241PROCEDURE doNumber (p: String; o: WORD) : String ;
242BEGIN
243 RETURN ConCat(p, CardinalToString(VAL(CARDINAL, o), 0, ' ', 10, TRUE))
244END doNumber ;
245
246
247(*
248 doSymbol - handles a symbol indicated by, o.
249*)
250
251PROCEDURE doSymbol (p: String; o: WORD) : String ;
252BEGIN
253 RETURN symDesc(o, p)
254END doSymbol ;
255
256
257(*
258 doOperand -
259*)
260
261PROCEDURE doOperand (p, s: String; VAR i: INTEGER; e: INTEGER; o: WORD) : String ;
262BEGIN
263 INC(i) ;
264 IF i<e
265 THEN
266 CASE char(s, i) OF
267
268 's': (* symbol number *)
269 INC(i) ;
270 RETURN doSymbol(p, o) |
271 'd': (* decimal number *)
272 INC(i) ;
273 RETURN doNumber(p, o) |
274 'a': (* symbol name key *)
275 INC(i) ;
276 RETURN doSymName(p, o) |
277 'n': (* ascii name key *)
278 INC(i) ;
279 RETURN doName(p, o)
280
281 ELSE
282 InternalError ("incorrect format specifier expecting one of 's', 'd' or 'a'")
283 END
284 END ;
285 RETURN p
286END doOperand ;
287
288
289(*
290 doPercent -
291*)
292
293PROCEDURE doPercent (o, s: String;
294 VAR i: INTEGER; e: INTEGER; n: CARDINAL) : String ;
295BEGIN
296 INC(i) ;
297 IF i<e
298 THEN
299 CASE char(s, i) OF
300
301 '1': RETURN doOperand(o, s, i, e, OperandT(n)) |
302 '2': RETURN doOperand(o, s, i, e, OperandF(n)) |
303 '3': RETURN doOperand(o, s, i, e, OperandTok(n))
304
305 ELSE
306 InternalError ('unrecognised format specifier - expecting 1, 2 or 3 after the %')
307 END
308 END ;
309 InternalError ('end of field found before format specifier - expecting 1, 2 or 3 after the %')
310END doPercent ;
311
312
313(*
314 doNameLength - increment, l, by the ascii length of string determined by, o.
315*)
316
317PROCEDURE doNameLength (VAR l: CARDINAL; o: WORD) ;
318VAR
319 s: String ;
320BEGIN
321 s := InitStringCharStar(KeyToCharStar(o)) ;
322 INC(l, Length(s)) ;
323 s := KillString(s)
324END doNameLength ;
325
326
327(*
328 doSymNameLength - increment, l, by the ascii length of symbol, o.
329*)
330
331PROCEDURE doSymNameLength (VAR l: CARDINAL; o: WORD) ;
332VAR
333 s: String ;
334BEGIN
335 s := InitStringCharStar(KeyToCharStar(GetSymName(o))) ;
336 INC(l, Length(s)) ;
337 s := KillString(s)
338END doSymNameLength ;
339
340
341(*
342 doNumberLength - convert, o, to a cardinal and increment the length, l,
343 by the number of characters required to represent, o.
344*)
345
346PROCEDURE doNumberLength (VAR l: CARDINAL; o: WORD) ;
347VAR
348 s: String ;
349BEGIN
350 s := CardinalToString(VAL(CARDINAL, o), 0, ' ', 10, TRUE) ;
351 INC(l, Length(s)) ;
352 s := KillString(s)
353END doNumberLength ;
354
355
356(*
357 doSymbolLength - handles a symbol indicated by, o.
358*)
359
360PROCEDURE doSymbolLength (VAR l: CARDINAL; o: WORD) ;
361VAR
362 s: String ;
363BEGIN
364 s := symDesc(o, InitString('')) ;
365 INC(l, Length(s)) ;
366 s := KillString(s)
367END doSymbolLength ;
368
369
370(*
371 doOperandLength -
372*)
373
374PROCEDURE doOperandLength (s: String; VAR i: INTEGER; e: INTEGER; VAR l: CARDINAL; o: WORD) ;
375BEGIN
376 INC(i) ;
377 IF i<e
378 THEN
379 CASE char(s, i) OF
380
381 's': (* symbol number *)
382 INC(i) ;
383 doSymbolLength(l, o) |
384 'd': (* decimal number *)
385 INC(i) ;
386 doNumberLength(l, o) |
387 'a': (* ascii name key *)
388 INC(i) ;
389 doSymNameLength(l, o) |
390 'n': (* ascii name key *)
391 INC(i) ;
392 doNameLength(l, o)
393
394 ELSE
395 InternalError ("incorrect format specifier expecting one of 's', 'd' or 'a'")
396 END
397 END
398END doOperandLength ;
399
400
401(*
402 doPercentLength -
403*)
404
405PROCEDURE doPercentLength (s: String; VAR i: INTEGER; e: INTEGER;
406 VAR l: CARDINAL; n: CARDINAL) ;
407BEGIN
408 INC(i) ;
409 IF i<e
410 THEN
411 CASE char(s, i) OF
412
413 '1': doOperandLength(s, i, e, l, OperandT(n)) |
414 '2': doOperandLength(s, i, e, l, OperandF(n)) |
415 '3': doOperandLength(s, i, e, l, OperandTok(n)) |
416
417 ELSE
418 InternalError ('unrecognised format specifier - expecting 1, 2 or 3 after the %')
419 END
420 END
421END doPercentLength ;
422
423
424(*
425 doFieldLength - compute the string length given in annotation
426 at position, n, on the stack between characters
427 b and e.
428
429 The string description between: b..e can contain any
430 of these patterns:
431
432 %a ascii name key.
433 %s symbol number.
434 %d decimal cardinal number.
435 | indicates the next field.
436*)
437
438PROCEDURE doFieldLength (b, e: INTEGER; n: CARDINAL) : CARDINAL ;
439VAR
440 l: CARDINAL ;
441 i: INTEGER ;
442 s: String ;
443BEGIN
444 IF b=-1
445 THEN
446 RETURN( 0 )
447 END ;
448 s := OperandAnno(n) ;
449 IF e=-1
450 THEN
451 e := Length(s)
452 END ;
453 l := 0 ;
454 i := b ;
455 WHILE i<e DO
456 CASE char(s, i) OF
457
458 '|': RETURN l |
459 '%': doPercentLength(s, i, e, l, n) ;
460
461 ELSE
462 INC(l)
463 END ;
464 INC(i)
465 END ;
466 RETURN l
467END doFieldLength ;
468
469
470(*
471 stop -
472*)
473
474PROCEDURE stop ;
475BEGIN
476END stop ;
477
478
479(*
480 doMaxCard - returns the maximum of two CARDINALs.
481*)
482
483PROCEDURE doMaxCard (a, b: CARDINAL) : CARDINAL ;
484BEGIN
485 IF (a>100) OR (b>100)
486 THEN
487 stop
488 END ;
489 IF a>b
490 THEN
491 RETURN a
492 ELSE
493 RETURN b
494 END
495END doMaxCard ;
496
497
498(*
499 GetAnnotationFieldLength -
500*)
501
502PROCEDURE GetAnnotationFieldLength (n: CARDINAL; f: CARDINAL) : CARDINAL ;
503VAR
504 c, e: INTEGER ;
505BEGIN
506 c := GetComment(OperandAnno(n)) ;
507 IF c>0
508 THEN
509 IF Debugging
510 THEN
511 printf0('full anno is: ') ; Output(Dup(OperandAnno(n))) ; printf0('\n') ;
512 printf0('comment field is: ') ; Output(Slice(OperandAnno(n), c, 0)) ; printf0('\n')
513 END ;
514 e := Index(OperandAnno(n), '|', c) ;
515 IF f=0
516 THEN
517 RETURN doFieldLength(c, e, n)
518 ELSE
519 IF e>=0
520 THEN
521 INC(e)
522 END ;
523 RETURN doFieldLength(e, -1, n)
524 END
525 ELSE
526 RETURN 0
527 END
528END GetAnnotationFieldLength ;
529
530
531(*
532 GetAnnotationLength -
533*)
534
535PROCEDURE GetAnnotationLength (n: CARDINAL; f: CARDINAL) : CARDINAL ;
536VAR
537 l: CARDINAL ;
538BEGIN
539 IF OperandAnno(n)=NIL
540 THEN
541 l := 0 ;
542 IF f=0
543 THEN
544 doNumberLength(l, OperandT(n))
545 ELSE
546 doNumberLength(l, OperandF(n))
547 END ;
548 RETURN l
549 ELSE
550 RETURN GetAnnotationFieldLength(n, f)
551 END
552END GetAnnotationLength ;
553
554
555(*
556 GetFieldLength - returns the number of characters used in field, f,
557 at position, n, on the stack.
558*)
559
560PROCEDURE GetFieldLength (n: CARDINAL; f: CARDINAL) : CARDINAL ;
561VAR
562 c, b, e: INTEGER ;
563BEGIN
564 c := GetComment(OperandAnno(n)) ;
565 IF c>1
566 THEN
567 e := c-2
568 ELSE
569 e := Length(OperandAnno(n))
570 END ;
571 IF f=0
572 THEN
573 b := 0
574 ELSE
575 b := Index(OperandAnno(n), '|', 0) ;
576 IF b=-1
577 THEN
578 RETURN 0
579 ELSE
580 INC(b)
581 END
582 END ;
583 RETURN doFieldLength(b, e, n)
584END GetFieldLength ;
585
586
587(*
588 GetMaxFieldAnno - returns the maximum number of characters required
589 by either the annotation or field, f, at position, n,
590 on the stack.
591*)
592
593PROCEDURE GetMaxFieldAnno (n: CARDINAL; f: CARDINAL) : CARDINAL ;
594BEGIN
595 RETURN doMaxCard(GetAnnotationLength(n, f), GetFieldLength(n, f))
596END GetMaxFieldAnno ;
597
598
599(*
600 GetStackFieldLengths - assigns, tn, and, fn, with the
601 maximum field width values.
602*)
603
604PROCEDURE GetStackFieldLengths (VAR tn, fn, tk: CARDINAL; amount: CARDINAL) ;
605VAR
606 i: CARDINAL ;
607BEGIN
608 i := 1 ;
609 tn := 0 ;
610 fn := 0 ;
611 tk := 0 ;
612 WHILE i<=amount DO
613 tn := doMaxCard(tn, GetMaxFieldAnno(i, 0)) ;
614 fn := doMaxCard(fn, GetMaxFieldAnno(i, 1)) ;
615 tk := doMaxCard(tk, GetMaxFieldAnno(i, 2)) ;
616 INC(i)
617 END
618END GetStackFieldLengths ;
619
620
621(*
622 DisplayRow -
623*)
624
625PROCEDURE DisplayRow (tn, fn, tk: CARDINAL; initOrFinal: BOOLEAN) ;
626VAR
627 i: CARDINAL ;
628BEGIN
629 printf0('+-') ;
630 FOR i := 1 TO tn DO
631 printf0('-')
632 END ;
633 IF (fn=0) AND (tk=0)
634 THEN
635 IF initOrFinal
636 THEN
637 printf0('-+-')
638 ELSE
639 printf0('-|-')
640 END
641 ELSE
642 IF initOrFinal
643 THEN
644 printf0('-+-')
645 ELSE
646 printf0('-|-')
647 END ;
648 IF fn#0
649 THEN
650 FOR i := 1 TO fn DO
651 printf0('-')
652 END
653 END ;
654 IF initOrFinal
655 THEN
656 printf0('-+-')
657 ELSE
658 printf0('-|-')
659 END ;
660 IF tk#0
661 THEN
662 FOR i := 1 TO tk DO
663 printf0('-')
664 END ;
665 printf0('-+\n')
666 END
667 END
668END DisplayRow ;
669
670
671(*
672 SkipToField -
673*)
674
675PROCEDURE SkipToField (s: String; n: CARDINAL) : INTEGER ;
676VAR
677 i, h: INTEGER ;
678BEGIN
679 i := 0 ;
680 h := Length(s) ;
681 WHILE (n>0) AND (i<h) DO
682 IF Index(s, '|', i)>0
683 THEN
684 DEC(n) ;
685 IF (i<h) AND (char(s, i+1)='|')
686 THEN
687 (* comment seen, no field available *)
688 RETURN -1
689 END ;
690 i := Index(s, '|', i)
691 ELSE
692 RETURN -1
693 END ;
694 INC(i)
695 END ;
696 IF i=h
697 THEN
698 i := -1
699 END ;
700 RETURN i
701END SkipToField ;
702
703
704(*
705 Pad - padds out string, s, to paddedLength characters.
706*)
707
708PROCEDURE Pad (o: String; paddedLength: CARDINAL) : String ;
709VAR
710 i: CARDINAL ;
711BEGIN
712 i := Length(o) ;
713 IF i<paddedLength
714 THEN
715 REPEAT
716 o := ConCatChar(o, ' ') ;
717 INC(i)
718 UNTIL i=paddedLength
719 END ;
720 RETURN o
721END Pad ;
722
723
724(*
725 doField - compute the string length given in annotation
726 at position, n, on the stack between characters
727 b and e.
728
729 The string description between: b..e can contain any
730 of these patterns:
731
732 %a ascii name key.
733 %s symbol number.
734 %d decimal cardinal number.
735 | indicates the next field.
736*)
737
738PROCEDURE doField (s: String; n: CARDINAL; f: CARDINAL; l: CARDINAL) : String ;
739VAR
740 h, i, j: INTEGER ;
741 o : String ;
742BEGIN
743 h := Length(s) ;
744 i := SkipToField(s, f) ;
745 o := InitString('') ;
746 IF i>=0
747 THEN
748 j := SkipToField(s, f+1) ;
749 IF j=-1
750 THEN
751 j := h
752 END ;
753 WHILE i<h DO
754 CASE char(s, i) OF
755
756 '|': i := h |
757 '%': o := doPercent(o, s, i, h, n)
758
759 ELSE
760 o := ConCatChar(o, char(s, i)) ;
761 INC(i)
762 END
763 END
764 END ;
765 o := Pad(o, l) ;
766 RETURN o
767END doField ;
768
769
770(*
771 doAnnotation -
772*)
773
774PROCEDURE doAnnotation (s: String; n: CARDINAL;
775 field: CARDINAL; width: CARDINAL) : String ;
776VAR
777 c : INTEGER ;
778 cf, o: String ;
779BEGIN
780 c := GetComment(s) ;
781 IF c>=0
782 THEN
783 cf := Slice(s, c, 0) ;
784 o := doField(cf, n, field, width) ;
785 cf := KillString(cf) ;
786 RETURN o
787 ELSE
788 RETURN InitString('')
789 END
790END doAnnotation ;
791
792
793(*
794 DisplayFields -
795*)
796
797PROCEDURE DisplayFields (n: CARDINAL; tn, fn, tk: CARDINAL) ;
798VAR
799 s : String ;
800 t, f, k: CARDINAL ;
801BEGIN
802 s := OperandAnno(n) ;
803 IF s=NIL
804 THEN
805 t := OperandT(n) ;
806 f := OperandF(n) ;
807 k := OperandTok(n) ;
808 printf0('| ') ;
809 Output(Pad(CardinalToString(VAL(CARDINAL, t), 0, ' ', 10, TRUE), tn)) ;
810 printf0(' | ') ;
811 Output(Pad(CardinalToString(VAL(CARDINAL, f), 0, ' ', 10, TRUE), fn)) ;
812 printf0(' | ') ;
813 Output(Pad(CardinalToString(VAL(CARDINAL, k), 0, ' ', 10, TRUE), tk)) ;
814 printf0(' |\n')
815 ELSE
816 IF tn>0
817 THEN
818 printf0('| ') ;
819 Output(doField(s, n, 0, tn))
820 END ;
821 IF fn>0
822 THEN
823 printf0(' | ') ;
824 Output(doField(s, n, 1, fn))
825 END ;
826 IF tk>0
827 THEN
828 printf0(' | ') ;
829 Output(doField(s, n, 2, tk))
830 END ;
831 printf0(' |\n') ;
832 IF tn>0
833 THEN
834 printf0('| ') ;
835 Output(doAnnotation(s, n, 0, tn))
836 END ;
837 IF fn>0
838 THEN
839 printf0(' | ') ;
840 Output(doAnnotation(s, n, 1, fn))
841 END ;
842 IF tk>0
843 THEN
844 printf0(' | ') ;
845 Output(doAnnotation(s, n, 2, tk))
846 END ;
847 printf0(' |\n')
848 END
849END DisplayFields ;
850
851
852(*
853 DebugStack - displays the stack.
854*)
855
856PROCEDURE DebugStack (amount: CARDINAL;
857 opt, opf, opa, opd, oprw, optk: ProcedureWord;
858 opanno: ProcedureString) ;
859VAR
860 i : CARDINAL ;
861 tn, fn, tk: CARDINAL ;
862BEGIN
863 OperandT := opt ;
864 OperandF := opf ;
865 OperandA := opa ;
866 OperandD := opd ;
867 OperandRW := oprw ;
868 OperandAnno := opanno ;
869 OperandTok := optk ;
870 GetStackFieldLengths(tn, fn, tk, amount) ;
871 i := 1 ;
872 WHILE i<=amount DO
873 IF i=1
874 THEN
875 DisplayRow(tn, fn, tk, TRUE)
876 END ;
877 DisplayFields(i, tn, fn, tk) ;
878 DisplayRow(tn, fn, tk, i=amount) ;
879 INC(i)
880 END
881END DebugStack ;
882
883
884END M2DebugStack.