a68g-pretty.c
1 //! @file a68g-pretty.c
2 //! @author J. Marcel van der Veer
3 //!
4 //! @section Copyright
5 //!
6 //! This file is part of Algol68G - an Algol 68 compiler-interpreter.
7 //! Copyright 2001-2023 J. Marcel van der Veer [algol68g@xs4all.nl].
8 //!
9 //! @section License
10 //!
11 //! This program is free software; you can redistribute it and/or modify it
12 //! under the terms of the GNU General Public License as published by the
13 //! Free Software Foundation; either version 3 of the License, or
14 //! (at your option) any later version.
15 //!
16 //! This program is distributed in the hope that it will be useful, but
17 //! WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 //! or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 //! more details. You should have received a copy of the GNU General Public
20 //! License along with this program. If not, see [http://www.gnu.org/licenses/].
21
22 //! @section Synopsis
23 //!
24 //! Lay-out formatter for Algol 68.
25
26 // Basic indenter for hopeless code.
27 // It applies one style only.
28
29 #include "a68g.h"
30 #include "a68g-genie.h"
31 #include "a68g-parser.h"
32 #include "a68g-prelude.h"
33 #include "a68g-optimiser.h"
34
35 #define ONE_LINER (A68_TRUE)
36 #define KEYWORD (A68_TRUE)
37 #define BLANK {put_str (" ");}
38
39 #define IS_OPEN_SYMBOL(p) (IS (p, OPEN_SYMBOL) || IS (p, SUB_SYMBOL) || IS (p, ACCO_SYMBOL))
40 #define IS_CLOSE_SYMBOL(p) (IS (p, CLOSE_SYMBOL) || IS (p, BUS_SYMBOL) || IS (p, OCCA_SYMBOL))
41 #define IS_IDENTIFIER(p) (IS (p, IDENTIFIER) || IS (p, DEFINING_IDENTIFIER) || IS (p, FIELD_IDENTIFIER))
42
43 void indent_declarer (NODE_T *);
44 void indent_serial (NODE_T *, BOOL_T, NODE_T **);
45 void indent_statement (NODE_T *);
46 void indent_format (NODE_T *);
47
48 //! @brief Write newline and indent.
49
50 void put_nl (void)
51 {
52 WRITE (A68_INDENT (fd), "\n");
53 for (A68_INDENT (col) = 1; A68_INDENT (col) < A68_INDENT (ind); A68_INDENT (col)++) {
54 WRITE (A68_INDENT (fd), " ");
55 }
56 }
57
58 //! @brief Write a string.
59
60 void put_str (char *txt)
61 {
62 WRITE (A68_INDENT (fd), txt);
63 A68_INDENT (col) += (int) strlen (txt);
64 }
65
66 //! @brief Write a character.
67
68 void put_ch (char ch)
69 {
70 char str[2];
71 str[0] = ch;
72 str[1] = NULL_CHAR;
73 put_str (str);
74 }
75
76 //! @brief Write pragment string.
77
78 void put_pragment (NODE_T * p)
79 {
80 char *txt = NPRAGMENT (p);
81 for (; txt != NO_TEXT && txt[0] != NULL_CHAR; txt++) {
82 if (txt[0] == NEWLINE_CHAR) {
83 put_nl ();
84 } else {
85 put_ch (txt[0]);
86 }
87 }
88 }
89
90 //! @brief Write pragment string.
91
92 void pretty_pragment (NODE_T * p, BOOL_T keyw)
93 {
94 if (NPRAGMENT (p) != NO_TEXT) {
95 if (NPRAGMENT_TYPE (p) == BOLD_COMMENT_SYMBOL || NPRAGMENT_TYPE (p) == BOLD_PRAGMAT_SYMBOL) {
96 if (!keyw) {
97 put_nl ();
98 }
99 put_pragment (p);
100 put_nl ();
101 put_nl ();
102 } else {
103 if (!keyw && (int) strlen (NPRAGMENT (p)) < 20) {
104 if (A68_INDENT (col) > A68_INDENT (ind)) {
105 BLANK;
106 }
107 put_pragment (p);
108 BLANK;
109 } else {
110 if (A68_INDENT (col) > A68_INDENT (ind)) {
111 put_nl ();
112 }
113 put_pragment (p);
114 put_nl ();
115 }
116 }
117 }
118 }
119
120 //! @brief Write with typographic display features.
121
122 void put_sym (NODE_T * p, BOOL_T keyw)
123 {
124 char *txt = NSYMBOL (p);
125 char *sym = NCHAR_IN_LINE (p);
126 int n = 0, size = (int) strlen (txt);
127 pretty_pragment (p, keyw);
128 if (txt[0] != sym[0] || (int) strlen (sym) - 1 <= size) {
129 // Without features..
130 put_str (txt);
131 } else {
132 // With features. Preserves spaces in identifiers etcetera..
133 while (n < size) {
134 put_ch (sym[0]);
135 if (TO_LOWER (txt[0]) == TO_LOWER (sym[0])) {
136 txt++;
137 n++;
138 }
139 sym++;
140 }
141 }
142 }
143
144 //! @brief Count units and separators in a sub-tree.
145
146 void count (NODE_T * p, int *units, int *seps)
147 {
148 for (; p != NO_NODE; FORWARD (p)) {
149 if (IS (p, UNIT)) {
150 (*units)++;
151 count (SUB (p), units, seps);
152 } else if (IS (p, SEMI_SYMBOL)) {
153 (*seps)++;
154 } else if (IS (p, COMMA_SYMBOL)) {
155 (*seps)++;
156 } else if (IS (p, CLOSED_CLAUSE)) {
157 (*units)--;
158 } else if (IS (p, COLLATERAL_CLAUSE)) {
159 (*units)--;
160 count (SUB (p), units, seps);
161 } else {
162 count (SUB (p), units, seps);
163 }
164 }
165 }
166
167 //! @brief Count units and separators in a sub-tree.
168
169 void count_stowed (NODE_T * p, int *units, int *seps)
170 {
171 for (; p != NO_NODE; FORWARD (p)) {
172 if (IS (p, UNIT)) {
173 MOID_T *v = MOID (p);
174 BOOL_T stowed = (BOOL_T) (IS_FLEX (v) || IS_ROW (v) || IS_STRUCT (v));
175 if (stowed) {
176 (*units)++;
177 }
178 } else if (IS (p, SEMI_SYMBOL)) {
179 (*seps)++;
180 } else if (IS (p, COMMA_SYMBOL)) {
181 (*seps)++;
182 } else {
183 count_stowed (SUB (p), units, seps);
184 }
185 }
186 }
187
188 //! @brief Count enclosed_clauses in a sub-tree.
189
190 void count_enclos (NODE_T * p, int *enclos, int *seps)
191 {
192 for (; p != NO_NODE; FORWARD (p)) {
193 if (IS (p, ENCLOSED_CLAUSE)) {
194 (*enclos)++;
195 } else if (IS (p, SEMI_SYMBOL)) {
196 (*seps)++;
197 } else if (IS (p, COMMA_SYMBOL)) {
198 (*seps)++;
199 } else {
200 count_enclos (SUB (p), enclos, seps);
201 }
202 }
203 }
204
205 //! @brief Indent sizety.
206
207 void indent_sizety (NODE_T * p)
208 {
209 for (; p != NO_NODE; FORWARD (p)) {
210 if (IS (p, LONGETY) || IS (p, SHORTETY)) {
211 indent_sizety (SUB (p));
212 } else if (IS (p, LONG_SYMBOL) || IS (p, SHORT_SYMBOL)) {
213 put_sym (p, !KEYWORD);
214 BLANK;
215 }
216 }
217 }
218
219 //! @brief Indent generic list.
220
221 void indent_generic_list (NODE_T * p, NODE_T ** what, BOOL_T one_liner)
222 {
223 for (; p != NULL; FORWARD (p)) {
224 if (IS_OPEN_SYMBOL (p)) {
225 put_sym (p, KEYWORD);
226 A68_INDENT (ind) = A68_INDENT (col);
227 } else if (IS_CLOSE_SYMBOL (p)) {
228 put_sym (p, KEYWORD);
229 } else if (IS (p, BEGIN_SYMBOL)) {
230 put_sym (p, KEYWORD);
231 BLANK;
232 } else if (IS (p, END_SYMBOL)) {
233 BLANK;
234 put_sym (p, KEYWORD);
235 } else if (IS (p, AT_SYMBOL)) {
236 if (NSYMBOL (p)[0] == '@') {
237 put_sym (p, !KEYWORD);
238 } else {
239 BLANK;
240 put_sym (p, !KEYWORD);
241 BLANK;
242 }
243 } else if (IS (p, COLON_SYMBOL)) {
244 BLANK;
245 put_sym (p, !KEYWORD);
246 BLANK;
247 } else if (IS (p, DOTDOT_SYMBOL)) {
248 BLANK;
249 put_sym (p, !KEYWORD);
250 BLANK;
251 } else if (IS (p, UNIT)) {
252 *what = p;
253 indent_statement (SUB (p));
254 } else if (IS (p, SPECIFIER)) {
255 NODE_T *q = SUB (p);
256 put_sym (q, KEYWORD);
257 FORWARD (q);
258 indent_declarer (q);
259 FORWARD (q);
260 if (IS_IDENTIFIER (q)) {
261 BLANK;
262 put_sym (q, !KEYWORD);
263 FORWARD (q);
264 }
265 put_sym (q, !KEYWORD);
266 FORWARD (q);
267 put_sym (NEXT (p), !KEYWORD); // :
268 BLANK;
269 FORWARD (p);
270 } else if (IS (p, COMMA_SYMBOL)) {
271 put_sym (p, !KEYWORD);
272 if (one_liner) {
273 BLANK;
274 } else {
275 put_nl ();
276 }
277 } else {
278 indent_generic_list (SUB (p), what, one_liner);
279 }
280 }
281 }
282
283 //! @brief Indent declarer pack.
284
285 void indent_pack (NODE_T * p)
286 {
287 for (; p != NO_NODE; FORWARD (p)) {
288 if (IS_OPEN_SYMBOL (p) || IS_CLOSE_SYMBOL (p)) {
289 put_sym (p, KEYWORD);
290 } else if (IS (p, COMMA_SYMBOL)) {
291 put_sym (p, !KEYWORD);
292 BLANK;
293 } else if (IS (p, VOID_SYMBOL)) {
294 put_sym (p, !KEYWORD);
295 } else if (IS (p, DECLARER)) {
296 indent_declarer (p);
297 if (NEXT (p) != NO_NODE && IS_IDENTIFIER (NEXT (p))) {
298 BLANK;
299 }
300 } else if (IS_IDENTIFIER (p)) {
301 put_sym (p, !KEYWORD);
302 } else {
303 indent_pack (SUB (p));
304 }
305 }
306 }
307
308 //! @brief Indent declarer.
309
310 void indent_declarer (NODE_T * p)
311 {
312 if (IS (p, DECLARER)) {
313 indent_declarer (SUB (p));
314 } else if (IS (p, LONGETY) || IS (p, SHORTETY)) {
315 indent_sizety (SUB (p));
316 indent_declarer (NEXT (p));
317 } else if (IS (p, VOID_SYMBOL)) {
318 put_sym (p, !KEYWORD);
319 } else if (IS (p, REF_SYMBOL)) {
320 put_sym (p, !KEYWORD);
321 BLANK;
322 indent_declarer (NEXT (p));
323 } else if (IS_FLEX (p)) {
324 put_sym (p, !KEYWORD);
325 BLANK;
326 indent_declarer (NEXT (p));
327 } else if (IS (p, BOUNDS) || IS (p, FORMAL_BOUNDS)) {
328 NODE_T *what = NO_NODE;
329 int pop_ind = A68_INDENT (ind);
330 indent_generic_list (SUB (p), &what, ONE_LINER);
331 A68_INDENT (ind) = pop_ind;
332 BLANK;
333 indent_declarer (NEXT (p));
334 } else if (IS_STRUCT (p) || IS_UNION (p)) {
335 NODE_T *pack = NEXT (p);
336 put_sym (p, !KEYWORD);
337 BLANK;
338 indent_pack (pack);
339 } else if (IS (p, PROC_SYMBOL)) {
340 NODE_T *q = NEXT (p);
341 put_sym (p, KEYWORD);
342 BLANK;
343 if (IS (q, FORMAL_DECLARERS)) {
344 indent_pack (SUB (q));
345 BLANK;
346 FORWARD (q);
347 }
348 indent_declarer (q);
349 return;
350 } else if (IS (p, OP_SYMBOL)) { // Operator plan
351 NODE_T *q = NEXT (p);
352 put_sym (p, KEYWORD);
353 BLANK;
354 if (IS (q, FORMAL_DECLARERS)) {
355 indent_pack (SUB (q));
356 BLANK;
357 FORWARD (q);
358 }
359 indent_declarer (q);
360 return;
361 } else if (IS (p, INDICANT)) {
362 put_sym (p, !KEYWORD);
363 }
364 }
365
366 //! @brief Indent conditional.
367
368 void indent_conditional (NODE_T * p)
369 {
370 for (; p != NO_NODE; FORWARD (p)) {
371 if (IS (p, IF_PART) || IS (p, ELIF_IF_PART)) {
372 NODE_T *what = NO_NODE;
373 int pop_ind = A68_INDENT (col);
374 put_sym (SUB (p), KEYWORD);
375 BLANK;
376 A68_INDENT (ind) = A68_INDENT (col);
377 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
378 A68_INDENT (ind) = pop_ind;
379 put_nl ();
380 } else if (IS (p, THEN_PART)) {
381 NODE_T *what = NO_NODE;
382 int pop_ind = A68_INDENT (col);
383 put_sym (SUB (p), KEYWORD);
384 BLANK;
385 A68_INDENT (ind) = A68_INDENT (col);
386 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
387 A68_INDENT (ind) = pop_ind;
388 put_nl ();
389 } else if (IS (p, ELSE_PART)) {
390 NODE_T *what = NO_NODE;
391 int pop_ind = A68_INDENT (col);
392 put_sym (SUB (p), KEYWORD);
393 BLANK;
394 A68_INDENT (ind) = A68_INDENT (col);
395 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
396 A68_INDENT (ind) = pop_ind;
397 put_nl ();
398 } else if (IS (p, ELIF_PART)) {
399 indent_conditional (SUB (p));
400 } else if (IS (p, FI_SYMBOL)) {
401 put_sym (p, KEYWORD);
402 } else if (IS (p, OPEN_PART)) {
403 NODE_T *what = NO_NODE;
404 put_sym (SUB (p), KEYWORD);
405 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
406 } else if (IS (p, ELSE_OPEN_PART)) {
407 NODE_T *what = NO_NODE;
408 BLANK;
409 put_sym (SUB (p), KEYWORD);
410 BLANK;
411 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
412 } else if (IS (p, CHOICE)) {
413 NODE_T *what = NO_NODE;
414 BLANK;
415 put_sym (SUB (p), KEYWORD);
416 BLANK;
417 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
418 } else if (IS (p, BRIEF_ELIF_PART)) {
419 indent_conditional (SUB (p));
420 } else if (IS_CLOSE_SYMBOL (p)) {
421 put_sym (p, KEYWORD);
422 }
423 }
424 }
425
426 //! @brief Indent integer case clause.
427
428 void indent_case (NODE_T * p)
429 {
430 for (; p != NO_NODE; FORWARD (p)) {
431 if (IS (p, CASE_PART) || IS (p, OUSE_PART)) {
432 NODE_T *what = NO_NODE;
433 int pop_ind = A68_INDENT (col);
434 put_sym (SUB (p), KEYWORD);
435 BLANK;
436 A68_INDENT (ind) = A68_INDENT (col);
437 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
438 A68_INDENT (ind) = pop_ind;
439 put_nl ();
440 } else if (IS (p, CASE_IN_PART)) {
441 NODE_T *what = NO_NODE;
442 int pop_ind = A68_INDENT (col);
443 put_sym (SUB (p), KEYWORD);
444 BLANK;
445 A68_INDENT (ind) = A68_INDENT (col);
446 indent_generic_list (NEXT_SUB (p), &what, ONE_LINER);
447 A68_INDENT (ind) = pop_ind;
448 put_nl ();
449 } else if (IS (p, OUT_PART)) {
450 NODE_T *what = NO_NODE;
451 int pop_ind = A68_INDENT (col);
452 put_sym (SUB (p), KEYWORD);
453 BLANK;
454 A68_INDENT (ind) = A68_INDENT (col);
455 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
456 A68_INDENT (ind) = pop_ind;
457 put_nl ();
458 } else if (IS (p, CASE_OUSE_PART)) {
459 indent_case (SUB (p));
460 } else if (IS (p, ESAC_SYMBOL)) {
461 put_sym (p, KEYWORD);
462 } else if (IS (p, OPEN_PART)) {
463 NODE_T *what = NO_NODE;
464 put_sym (SUB (p), KEYWORD);
465 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
466 } else if (IS (p, ELSE_OPEN_PART)) {
467 NODE_T *what = NO_NODE;
468 BLANK;
469 put_sym (SUB (p), KEYWORD);
470 BLANK;
471 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
472 } else if (IS (p, CASE_CHOICE_CLAUSE)) {
473 NODE_T *what = NO_NODE;
474 BLANK;
475 put_sym (SUB (p), KEYWORD);
476 BLANK;
477 indent_generic_list (NEXT_SUB (p), &what, ONE_LINER);
478 } else if (IS (p, CHOICE)) {
479 NODE_T *what = NO_NODE;
480 BLANK;
481 put_sym (SUB (p), KEYWORD);
482 BLANK;
483 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
484 } else if (IS (p, BRIEF_OUSE_PART)) {
485 indent_case (SUB (p));
486 } else if (IS_CLOSE_SYMBOL (p)) {
487 put_sym (p, KEYWORD);
488 }
489 }
490 }
491
492 //! @brief Indent conformity clause.
493
494 void indent_conformity (NODE_T * p)
495 {
496 for (; p != NO_NODE; FORWARD (p)) {
497 if (IS (p, CASE_PART) || IS (p, OUSE_PART)) {
498 NODE_T *what = NO_NODE;
499 int pop_ind = A68_INDENT (col);
500 put_sym (SUB (p), KEYWORD);
501 BLANK;
502 A68_INDENT (ind) = A68_INDENT (col);
503 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
504 A68_INDENT (ind) = pop_ind;
505 put_nl ();
506 } else if (IS (p, CONFORMITY_IN_PART)) {
507 NODE_T *what = NO_NODE;
508 int pop_ind = A68_INDENT (col);
509 put_sym (SUB (p), KEYWORD);
510 BLANK;
511 A68_INDENT (ind) = A68_INDENT (col);
512 indent_generic_list (NEXT_SUB (p), &what, ONE_LINER);
513 A68_INDENT (ind) = pop_ind;
514 put_nl ();
515 } else if (IS (p, OUT_PART)) {
516 NODE_T *what = NO_NODE;
517 int pop_ind = A68_INDENT (col);
518 put_sym (SUB (p), KEYWORD);
519 BLANK;
520 A68_INDENT (ind) = A68_INDENT (col);
521 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
522 A68_INDENT (ind) = pop_ind;
523 put_nl ();
524 } else if (IS (p, CONFORMITY_OUSE_PART)) {
525 indent_conformity (SUB (p));
526 } else if (IS (p, ESAC_SYMBOL)) {
527 put_sym (p, KEYWORD);
528 } else if (IS (p, OPEN_PART)) {
529 NODE_T *what = NO_NODE;
530 put_sym (SUB (p), KEYWORD);
531 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
532 } else if (IS (p, ELSE_OPEN_PART)) {
533 NODE_T *what = NO_NODE;
534 BLANK;
535 put_sym (SUB (p), KEYWORD);
536 BLANK;
537 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
538 } else if (IS (p, CONFORMITY_CHOICE)) {
539 NODE_T *what = NO_NODE;
540 BLANK;
541 put_sym (SUB (p), KEYWORD);
542 BLANK;
543 indent_generic_list (NEXT_SUB (p), &what, ONE_LINER);
544 } else if (IS (p, CHOICE)) {
545 NODE_T *what = NO_NODE;
546 BLANK;
547 put_sym (SUB (p), KEYWORD);
548 BLANK;
549 indent_serial (NEXT_SUB (p), ONE_LINER, &what);
550 } else if (IS (p, BRIEF_CONFORMITY_OUSE_PART)) {
551 indent_conformity (SUB (p));
552 } else if (IS_CLOSE_SYMBOL (p)) {
553 put_sym (p, KEYWORD);
554 }
555 }
556 }
557
558 //! @brief Indent loop.
559
560 void indent_loop (NODE_T * p)
561 {
562 int parts = 0, pop_ind = A68_INDENT (col);
563 for (; p != NO_NODE; FORWARD (p)) {
564 if (IS (p, FOR_PART)) {
565 put_sym (SUB (p), KEYWORD);
566 BLANK;
567 put_sym (NEXT_SUB (p), !KEYWORD);
568 BLANK;
569 parts++;
570 } else if (is_one_of (p, FROM_PART, BY_PART, TO_PART, STOP)) {
571 put_sym (SUB (p), KEYWORD);
572 BLANK;
573 indent_statement (NEXT_SUB (p));
574 BLANK;
575 parts++;
576 } else if (IS (p, WHILE_PART)) {
577 NODE_T *what = NO_NODE;
578 A68_INDENT (ind) = pop_ind;
579 if (parts > 0) {
580 put_nl ();
581 }
582 put_sym (SUB (p), KEYWORD);
583 BLANK;
584 A68_INDENT (ind) = A68_INDENT (col);
585 indent_serial (NEXT_SUB (p), !ONE_LINER, &what);
586 A68_INDENT (ind) = pop_ind;
587 parts++;
588 } else if (is_one_of (p, DO_PART, ALT_DO_PART, STOP)) {
589 NODE_T *q = SUB (p);
590 NODE_T *what = NO_NODE;
591 A68_INDENT (ind) = pop_ind;
592 if (parts > 0) {
593 put_nl ();
594 }
595 put_sym (q, KEYWORD); // DO
596 BLANK;
597 A68_INDENT (ind) = A68_INDENT (col);
598 FORWARD (q);
599 parts = 0;
600 if (IS (q, SERIAL_CLAUSE)) {
601 indent_serial (SUB (q), !ONE_LINER, &what);
602 FORWARD (q);
603 parts++;
604 }
605 if (IS (q, UNTIL_PART)) {
606 int pop_ind2 = A68_INDENT (ind);
607 if (parts > 0) {
608 put_nl ();
609 }
610 put_sym (SUB (q), KEYWORD);
611 BLANK;
612 A68_INDENT (ind) = A68_INDENT (col);
613 indent_serial (NEXT_SUB (q), !ONE_LINER, &what);
614 A68_INDENT (ind) = pop_ind2;
615 FORWARD (q);
616 }
617 A68_INDENT (ind) = pop_ind;
618 put_nl ();
619 put_sym (q, KEYWORD); // OD
620 parts++;
621 }
622 }
623 }
624
625 //! @brief Indent closed clause.
626
627 void indent_closed (NODE_T * p)
628 {
629 int units = 0, seps = 0;
630 count (SUB_NEXT (p), &units, &seps);
631 if (units <= 3 && seps == (units - 1)) {
632 put_sym (p, KEYWORD);
633 if (IS (p, BEGIN_SYMBOL)) {
634 NODE_T *what = NO_NODE;
635 BLANK;
636 indent_serial (SUB_NEXT (p), ONE_LINER, &what);
637 BLANK;
638 } else {
639 NODE_T *what = NO_NODE;
640 indent_serial (SUB_NEXT (p), ONE_LINER, &what);
641 }
642 put_sym (NEXT_NEXT (p), KEYWORD);
643 } else if (units <= 3 && seps == (units - 1) && IS_OPEN_SYMBOL (p)) {
644 NODE_T *what = NO_NODE;
645 put_sym (p, KEYWORD);
646 indent_serial (SUB_NEXT (p), ONE_LINER, &what);
647 put_sym (NEXT_NEXT (p), KEYWORD);
648 } else {
649 NODE_T *what = NO_NODE;
650 int pop_ind = A68_INDENT (col);
651 put_sym (p, KEYWORD);
652 if (IS (p, BEGIN_SYMBOL)) {
653 BLANK;
654 }
655 A68_INDENT (ind) = A68_INDENT (col);
656 indent_serial (SUB_NEXT (p), !ONE_LINER, &what);
657 A68_INDENT (ind) = pop_ind;
658 if (IS (NEXT_NEXT (p), END_SYMBOL)) {
659 put_nl ();
660 }
661 put_sym (NEXT_NEXT (p), KEYWORD);
662 }
663 }
664
665 //! @brief Indent collateral clause.
666
667 void indent_collateral (NODE_T * p)
668 {
669 int units = 0, seps = 0;
670 NODE_T *what = NO_NODE;
671 int pop_ind = A68_INDENT (col);
672 count_stowed (p, &units, &seps);
673 if (units <= 3) {
674 indent_generic_list (p, &what, ONE_LINER);
675 } else {
676 indent_generic_list (p, &what, !ONE_LINER);
677 }
678 A68_INDENT (ind) = pop_ind;
679 }
680
681 //! @brief Indent enclosed clause.
682
683 void indent_enclosed (NODE_T * p)
684 {
685 if (IS (p, ENCLOSED_CLAUSE)) {
686 indent_enclosed (SUB (p));
687 } else if (IS (p, CLOSED_CLAUSE)) {
688 indent_closed (SUB (p));
689 } else if (IS (p, COLLATERAL_CLAUSE)) {
690 indent_collateral (SUB (p));
691 } else if (IS (p, PARALLEL_CLAUSE)) {
692 put_sym (SUB (p), KEYWORD);
693 indent_enclosed (NEXT_SUB (p));
694 } else if (IS (p, CONDITIONAL_CLAUSE)) {
695 indent_conditional (SUB (p));
696 } else if (IS (p, CASE_CLAUSE)) {
697 indent_case (SUB (p));
698 } else if (IS (p, CONFORMITY_CLAUSE)) {
699 indent_conformity (SUB (p));
700 } else if (IS (p, LOOP_CLAUSE)) {
701 indent_loop (SUB (p));
702 }
703 }
704
705 //! @brief Indent a literal.
706
707 void indent_literal (char *txt)
708 {
709 put_str ("\"");
710 while (txt[0] != NULL_CHAR) {
711 if (txt[0] == '\"') {
712 put_str ("\"\"");
713 } else {
714 put_ch (txt[0]);
715 }
716 txt++;
717 }
718 put_str ("\"");
719 }
720
721 //! @brief Indent denotation.
722
723 void indent_denotation (NODE_T * p)
724 {
725 if (IS (p, ROW_CHAR_DENOTATION)) {
726 indent_literal (NSYMBOL (p));
727 } else if (IS (p, LONGETY) || IS (p, SHORTETY)) {
728 indent_sizety (SUB (p));
729 indent_denotation (NEXT (p));
730 } else {
731 put_sym (p, !KEYWORD);
732 }
733 }
734
735 //! @brief Indent label.
736
737 void indent_label (NODE_T * p)
738 {
739 for (; p != NO_NODE; FORWARD (p)) {
740 if (SUB (p) != NULL) {
741 indent_label (SUB (p));
742 } else if (IS (p, DEFINING_IDENTIFIER)) {
743 put_sym (p, !KEYWORD);
744 put_sym (NEXT (p), KEYWORD);
745 }
746 }
747 }
748
749 //! @brief Indent literal list.
750
751 void indent_collection (NODE_T * p)
752 {
753 for (; p != NO_NODE; FORWARD (p)) {
754 if (IS (p, FORMAT_OPEN_SYMBOL) || IS (p, FORMAT_CLOSE_SYMBOL)) {
755 put_sym (p, !KEYWORD);
756 } else if (IS (p, COMMA_SYMBOL)) {
757 put_sym (p, !KEYWORD);
758 BLANK;
759 } else {
760 indent_format (SUB (p));
761 }
762 }
763 }
764
765 //! @brief Indent format text.
766
767 void indent_format (NODE_T * p)
768 {
769 for (; p != NO_NODE; FORWARD (p)) {
770 if (IS (p, FORMAT_DELIMITER_SYMBOL)) {
771 put_sym (p, !KEYWORD);
772 } else if (IS (p, COLLECTION)) {
773 indent_collection (SUB (p));
774 } else if (IS (p, ENCLOSED_CLAUSE)) {
775 indent_enclosed (SUB (p));
776 } else if (IS (p, LITERAL)) {
777 indent_literal (NSYMBOL (p));
778 } else if (IS (p, STATIC_REPLICATOR)) {
779 indent_denotation (p);
780 } else if (IS (p, COMMA_SYMBOL)) {
781 put_sym (p, !KEYWORD);
782 BLANK;
783 } else {
784 if (SUB (p) != NO_NODE) {
785 indent_format (SUB (p));
786 } else {
787 switch (ATTRIBUTE (p)) {
788 case FORMAT_ITEM_A:
789 put_sym (p, !KEYWORD);
790 break;
791 case FORMAT_ITEM_B:
792 put_sym (p, !KEYWORD);
793 break;
794 case FORMAT_ITEM_C:
795 put_sym (p, !KEYWORD);
796 break;
797 case FORMAT_ITEM_D:
798 put_sym (p, !KEYWORD);
799 break;
800 case FORMAT_ITEM_E:
801 put_sym (p, !KEYWORD);
802 break;
803 case FORMAT_ITEM_ESCAPE:
804 put_sym (p, !KEYWORD);
805 break;
806 case FORMAT_ITEM_F:
807 put_sym (p, !KEYWORD);
808 break;
809 case FORMAT_ITEM_G:
810 put_sym (p, !KEYWORD);
811 break;
812 case FORMAT_ITEM_H:
813 put_sym (p, !KEYWORD);
814 break;
815 case FORMAT_ITEM_I:
816 put_sym (p, !KEYWORD);
817 break;
818 case FORMAT_ITEM_J:
819 put_sym (p, !KEYWORD);
820 break;
821 case FORMAT_ITEM_K:
822 put_sym (p, !KEYWORD);
823 break;
824 case FORMAT_ITEM_L:
825 put_sym (p, !KEYWORD);
826 break;
827 case FORMAT_ITEM_M:
828 put_sym (p, !KEYWORD);
829 break;
830 case FORMAT_ITEM_MINUS:
831 put_sym (p, !KEYWORD);
832 break;
833 case FORMAT_ITEM_N:
834 put_sym (p, !KEYWORD);
835 break;
836 case FORMAT_ITEM_O:
837 put_sym (p, !KEYWORD);
838 break;
839 case FORMAT_ITEM_P:
840 put_sym (p, !KEYWORD);
841 break;
842 case FORMAT_ITEM_PLUS:
843 put_sym (p, !KEYWORD);
844 break;
845 case FORMAT_ITEM_POINT:
846 put_sym (p, !KEYWORD);
847 break;
848 case FORMAT_ITEM_Q:
849 put_sym (p, !KEYWORD);
850 break;
851 case FORMAT_ITEM_R:
852 put_sym (p, !KEYWORD);
853 break;
854 case FORMAT_ITEM_S:
855 put_sym (p, !KEYWORD);
856 break;
857 case FORMAT_ITEM_T:
858 put_sym (p, !KEYWORD);
859 break;
860 case FORMAT_ITEM_U:
861 put_sym (p, !KEYWORD);
862 break;
863 case FORMAT_ITEM_V:
864 put_sym (p, !KEYWORD);
865 break;
866 case FORMAT_ITEM_W:
867 put_sym (p, !KEYWORD);
868 break;
869 case FORMAT_ITEM_X:
870 put_sym (p, !KEYWORD);
871 break;
872 case FORMAT_ITEM_Y:
873 put_sym (p, !KEYWORD);
874 break;
875 case FORMAT_ITEM_Z:
876 put_sym (p, !KEYWORD);
877 break;
878 }
879 }
880 }
881 }
882 }
883
884 //! @brief Constant folder - replace constant statement with value.
885
886 BOOL_T indent_folder (NODE_T * p)
887 {
888 if (MOID (p) == M_INT) {
889 A68_INT k;
890 A68_SP = 0;
891 push_unit (p);
892 POP_OBJECT (p, &k, A68_INT);
893 if (ERROR_COUNT (&A68_JOB) == 0) {
894 ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, A68_LD, VALUE (&k)) >= 0);
895 put_str (A68 (output_line));
896 return A68_TRUE;
897 } else {
898 return A68_FALSE;
899 }
900 } else if (MOID (p) == M_REAL) {
901 A68_REAL x;
902 REAL_T conv;
903 A68_SP = 0;
904 push_unit (p);
905 POP_OBJECT (p, &x, A68_REAL);
906 // Mind overflowing or underflowing values.
907 if (ERROR_COUNT (&A68_JOB) != 0) {
908 return A68_FALSE;
909 } else if (VALUE (&x) == REAL_MAX) {
910 return A68_FALSE;
911 } else if (VALUE (&x) == -REAL_MAX) {
912 return A68_FALSE;
913 } else {
914 ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, "%.*g", REAL_WIDTH, VALUE (&x)) >= 0);
915 errno = 0;
916 conv = strtod (A68 (output_line), NO_VAR);
917 if (errno == ERANGE && conv == 0.0) {
918 put_str ("0.0");
919 return A68_TRUE;
920 } else if (errno == ERANGE) {
921 return A68_FALSE;
922 } else {
923 if (strchr (A68 (output_line), '.') == NO_TEXT && strchr (A68 (output_line), 'e') == NO_TEXT && strchr (A68 (output_line), 'E') == NO_TEXT) {
924 strncat (A68 (output_line), ".0", BUFFER_SIZE - 1);
925 }
926 put_str (A68 (output_line));
927 return A68_TRUE;
928 }
929 }
930 } else if (MOID (p) == M_BOOL) {
931 A68_BOOL b;
932 A68_SP = 0;
933 push_unit (p);
934 POP_OBJECT (p, &b, A68_BOOL);
935 if (ERROR_COUNT (&A68_JOB) != 0) {
936 return A68_FALSE;
937 } else {
938 ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, "%s", (VALUE (&b) ? "TRUE" : "FALSE")) >= 0);
939 put_str (A68 (output_line));
940 return A68_TRUE;
941 }
942 } else if (MOID (p) == M_CHAR) {
943 A68_CHAR c;
944 A68_SP = 0;
945 push_unit (p);
946 POP_OBJECT (p, &c, A68_CHAR);
947 if (ERROR_COUNT (&A68_JOB) == 0) {
948 return A68_FALSE;
949 } else if (VALUE (&c) == '\"') {
950 put_str ("\"\"\"\"");
951 return A68_TRUE;
952 } else {
953 ASSERT (snprintf (A68 (output_line), SNPRINTF_SIZE, "\"%c\"", (int) VALUE (&c)) >= 0);
954 return A68_TRUE;
955 }
956 }
957 return A68_FALSE;
958 }
959
960 //! @brief Indent statement.
961
962 void indent_statement (NODE_T * p)
963 {
964 if (IS (p, LABEL)) {
965 int enclos = 0, seps = 0;
966 indent_label (SUB (p));
967 FORWARD (p);
968 count_enclos (SUB (p), &enclos, &seps);
969 if (enclos == 0) {
970 BLANK;
971 } else {
972 put_nl ();
973 }
974 }
975 if (A68_INDENT (use_folder) && folder_mode (MOID (p)) && constant_unit (p)) {
976 if (indent_folder (p)) {
977 return;
978 };
979 }
980 if (is_coercion (p)) {
981 indent_statement (SUB (p));
982 } else if (is_one_of (p, PRIMARY, SECONDARY, TERTIARY, UNIT, LABELED_UNIT, STOP)) {
983 indent_statement (SUB (p));
984 } else if (IS (p, ENCLOSED_CLAUSE)) {
985 indent_enclosed (SUB (p));
986 } else if (IS (p, DENOTATION)) {
987 indent_denotation (SUB (p));
988 } else if (IS (p, FORMAT_TEXT)) {
989 indent_format (SUB (p));
990 } else if (IS (p, IDENTIFIER)) {
991 put_sym (p, !KEYWORD);
992 } else if (IS (p, CAST)) {
993 NODE_T *decl = SUB (p);
994 NODE_T *rhs = NEXT (decl);
995 indent_declarer (decl);
996 BLANK;
997 indent_enclosed (rhs);
998 } else if (IS (p, CALL)) {
999 NODE_T *primary = SUB (p);
1000 NODE_T *arguments = NEXT (primary);
1001 NODE_T *what = NO_NODE;
1002 int pop_ind = A68_INDENT (col);
1003 indent_statement (primary);
1004 BLANK;
1005 indent_generic_list (arguments, &what, ONE_LINER);
1006 A68_INDENT (ind) = pop_ind;
1007 } else if (IS (p, SLICE)) {
1008 NODE_T *primary = SUB (p);
1009 NODE_T *indexer = NEXT (primary);
1010 NODE_T *what = NO_NODE;
1011 int pop_ind = A68_INDENT (col);
1012 indent_statement (primary);
1013 indent_generic_list (indexer, &what, ONE_LINER);
1014 A68_INDENT (ind) = pop_ind;
1015 } else if (IS (p, SELECTION)) {
1016 NODE_T *selector = SUB (p);
1017 NODE_T *secondary = NEXT (selector);
1018 indent_statement (selector);
1019 indent_statement (secondary);
1020 } else if (IS (p, SELECTOR)) {
1021 NODE_T *identifier = SUB (p);
1022 put_sym (identifier, !KEYWORD);
1023 BLANK;
1024 put_sym (NEXT (identifier), !KEYWORD); // OF
1025 BLANK;
1026 } else if (IS (p, GENERATOR)) {
1027 NODE_T *q = SUB (p);
1028 put_sym (q, !KEYWORD);
1029 BLANK;
1030 indent_declarer (NEXT (q));
1031 } else if (IS (p, FORMULA)) {
1032 NODE_T *lhs = SUB (p);
1033 NODE_T *op = NEXT (lhs);
1034 indent_statement (lhs);
1035 if (op != NO_NODE) {
1036 NODE_T *rhs = NEXT (op);
1037 BLANK;
1038 put_sym (op, !KEYWORD);
1039 BLANK;
1040 indent_statement (rhs);
1041 }
1042 } else if (IS (p, MONADIC_FORMULA)) {
1043 NODE_T *op = SUB (p);
1044 NODE_T *rhs = NEXT (op);
1045 put_sym (op, !KEYWORD);
1046 if (strchr (MONADS, (NSYMBOL (op))[0]) == NO_TEXT) {
1047 BLANK;
1048 }
1049 indent_statement (rhs);
1050 } else if (IS (p, NIHIL)) {
1051 put_sym (p, !KEYWORD);
1052 } else if (IS (p, AND_FUNCTION) || IS (p, OR_FUNCTION)) {
1053 NODE_T *lhs = SUB (p);
1054 NODE_T *op = NEXT (lhs);
1055 NODE_T *rhs = NEXT (op);
1056 indent_statement (lhs);
1057 BLANK;
1058 put_sym (op, !KEYWORD);
1059 BLANK;
1060 indent_statement (rhs);
1061 } else if (IS (p, TRANSPOSE_FUNCTION) || IS (p, DIAGONAL_FUNCTION) || IS (p, ROW_FUNCTION) || IS (p, COLUMN_FUNCTION)) {
1062 NODE_T *q = SUB (p);
1063 if (IS (p, TERTIARY)) {
1064 indent_statement (q);
1065 BLANK;
1066 FORWARD (q);
1067 }
1068 put_sym (q, !KEYWORD);
1069 BLANK;
1070 indent_statement (NEXT (q));
1071 } else if (IS (p, ASSIGNATION)) {
1072 NODE_T *dst = SUB (p);
1073 NODE_T *bec = NEXT (dst);
1074 NODE_T *src = NEXT (bec);
1075 indent_statement (dst);
1076 BLANK;
1077 put_sym (bec, !KEYWORD);
1078 BLANK;
1079 indent_statement (src);
1080 } else if (IS (p, ROUTINE_TEXT)) {
1081 NODE_T *q = SUB (p);
1082 int units, seps;
1083 if (IS (q, PARAMETER_PACK)) {
1084 indent_pack (SUB (q));
1085 BLANK;
1086 FORWARD (q);
1087 }
1088 indent_declarer (q);
1089 FORWARD (q);
1090 put_sym (q, !KEYWORD); // :
1091 FORWARD (q);
1092 units = 0;
1093 seps = 0;
1094 count (q, &units, &seps);
1095 if (units <= 1) {
1096 BLANK;
1097 indent_statement (q);
1098 } else {
1099 put_nl ();
1100 indent_statement (q);
1101 }
1102 } else if (IS (p, IDENTITY_RELATION)) {
1103 NODE_T *lhs = SUB (p);
1104 NODE_T *op = NEXT (lhs);
1105 NODE_T *rhs = NEXT (op);
1106 indent_statement (lhs);
1107 BLANK;
1108 put_sym (op, !KEYWORD);
1109 BLANK;
1110 indent_statement (rhs);
1111 } else if (IS (p, JUMP)) {
1112 NODE_T *q = SUB (p);
1113 if (IS (q, GOTO_SYMBOL)) {
1114 put_sym (q, !KEYWORD);
1115 BLANK;
1116 FORWARD (q);
1117 }
1118 put_sym (q, !KEYWORD);
1119 } else if (IS (p, SKIP)) {
1120 put_sym (p, !KEYWORD);
1121 } else if (IS (p, ASSERTION)) {
1122 NODE_T *q = SUB (p);
1123 put_sym (q, KEYWORD);
1124 BLANK;
1125 indent_enclosed (NEXT (q));
1126 } else if (IS (p, CODE_CLAUSE)) {
1127 NODE_T *q = SUB (p);
1128 put_sym (q, KEYWORD);
1129 BLANK;
1130 FORWARD (q);
1131 indent_collection (SUB (q));
1132 FORWARD (q);
1133 put_sym (q, KEYWORD);
1134 }
1135 }
1136
1137 //! @brief Indent identifier declarations.
1138
1139 void indent_iddecl (NODE_T * p)
1140 {
1141 for (; p != NO_NODE; FORWARD (p)) {
1142 if (IS (p, IDENTITY_DECLARATION) || IS (p, VARIABLE_DECLARATION)) {
1143 indent_iddecl (SUB (p));
1144 } else if (IS (p, QUALIFIER)) {
1145 put_sym (SUB (p), !KEYWORD);
1146 BLANK;
1147 } else if (IS (p, DECLARER)) {
1148 indent_declarer (SUB (p));
1149 BLANK;
1150 } else if (IS (p, DEFINING_IDENTIFIER)) {
1151 NODE_T *q = p;
1152 int pop_ind = A68_INDENT (ind);
1153 put_sym (q, !KEYWORD);
1154 FORWARD (q);
1155 if (q != NO_NODE) { // := unit
1156 BLANK;
1157 put_sym (q, !KEYWORD);
1158 BLANK;
1159 FORWARD (q);
1160 indent_statement (q);
1161 }
1162 A68_INDENT (ind) = pop_ind;
1163 } else if (IS (p, COMMA_SYMBOL)) {
1164 put_sym (p, !KEYWORD);
1165 BLANK;
1166 }
1167 }
1168 }
1169
1170 //! @brief Indent procedure declarations.
1171
1172 void indent_procdecl (NODE_T * p)
1173 {
1174 for (; p != NO_NODE; FORWARD (p)) {
1175 if (IS (p, PROCEDURE_DECLARATION) || IS (p, PROCEDURE_VARIABLE_DECLARATION)) {
1176 indent_procdecl (SUB (p));
1177 } else if (IS (p, PROC_SYMBOL)) {
1178 put_sym (p, KEYWORD);
1179 BLANK;
1180 A68_INDENT (ind) = A68_INDENT (col);
1181 } else if (IS (p, DEFINING_IDENTIFIER)) {
1182 NODE_T *q = p;
1183 int pop_ind = A68_INDENT (ind);
1184 put_sym (q, !KEYWORD);
1185 FORWARD (q);
1186 BLANK;
1187 put_sym (q, !KEYWORD);
1188 BLANK;
1189 FORWARD (q);
1190 indent_statement (q);
1191 A68_INDENT (ind) = pop_ind;
1192 } else if (IS (p, COMMA_SYMBOL)) {
1193 put_sym (p, !KEYWORD);
1194 put_nl ();
1195 }
1196 }
1197 }
1198
1199 //! @brief Indent operator declarations.
1200
1201 void indent_opdecl (NODE_T * p)
1202 {
1203 for (; p != NO_NODE; FORWARD (p)) {
1204 if (IS (p, OPERATOR_DECLARATION) || IS (p, BRIEF_OPERATOR_DECLARATION)) {
1205 indent_opdecl (SUB (p));
1206 } else if (IS (p, OP_SYMBOL)) {
1207 put_sym (p, KEYWORD);
1208 BLANK;
1209 A68_INDENT (ind) = A68_INDENT (col);
1210 } else if (IS (p, OPERATOR_PLAN)) {
1211 indent_declarer (SUB (p));
1212 BLANK;
1213 A68_INDENT (ind) = A68_INDENT (col);
1214 } else if (IS (p, DEFINING_OPERATOR)) {
1215 NODE_T *q = p;
1216 int pop_ind = A68_INDENT (ind);
1217 put_sym (q, !KEYWORD);
1218 FORWARD (q);
1219 BLANK;
1220 put_sym (q, !KEYWORD);
1221 BLANK;
1222 FORWARD (q);
1223 indent_statement (q);
1224 A68_INDENT (ind) = pop_ind;
1225 } else if (IS (p, COMMA_SYMBOL)) {
1226 put_sym (p, !KEYWORD);
1227 put_nl ();
1228 }
1229 }
1230 }
1231
1232 //! @brief Indent priority declarations.
1233
1234 void indent_priodecl (NODE_T * p)
1235 {
1236 for (; p != NO_NODE; FORWARD (p)) {
1237 if (IS (p, PRIORITY_DECLARATION)) {
1238 indent_priodecl (SUB (p));
1239 } else if (IS (p, PRIO_SYMBOL)) {
1240 put_sym (p, KEYWORD);
1241 BLANK;
1242 } else if (IS (p, DEFINING_OPERATOR)) {
1243 NODE_T *q = p;
1244 put_sym (q, !KEYWORD);
1245 FORWARD (q);
1246 BLANK;
1247 put_sym (q, !KEYWORD);
1248 BLANK;
1249 FORWARD (q);
1250 put_sym (q, !KEYWORD);
1251 } else if (IS (p, COMMA_SYMBOL)) {
1252 put_sym (p, !KEYWORD);
1253 BLANK;
1254 }
1255 }
1256 }
1257
1258 //! @brief Indent mode declarations.
1259
1260 void indent_modedecl (NODE_T * p)
1261 {
1262 for (; p != NO_NODE; FORWARD (p)) {
1263 if (IS (p, MODE_DECLARATION)) {
1264 indent_modedecl (SUB (p));
1265 } else if (IS (p, MODE_SYMBOL)) {
1266 put_sym (p, KEYWORD);
1267 BLANK;
1268 A68_INDENT (ind) = A68_INDENT (col);
1269 } else if (IS (p, DEFINING_INDICANT)) {
1270 NODE_T *q = p;
1271 int pop_ind = A68_INDENT (ind);
1272 put_sym (q, !KEYWORD);
1273 FORWARD (q);
1274 BLANK;
1275 put_sym (q, !KEYWORD);
1276 BLANK;
1277 FORWARD (q);
1278 indent_declarer (q);
1279 A68_INDENT (ind) = pop_ind;
1280 } else if (IS (p, COMMA_SYMBOL)) {
1281 put_sym (p, !KEYWORD);
1282 put_nl ();
1283 }
1284 }
1285 }
1286
1287 //! @brief Indent declaration list.
1288
1289 void indent_declist (NODE_T * p, BOOL_T one_liner)
1290 {
1291 for (; p != NO_NODE; FORWARD (p)) {
1292 if (IS (p, IDENTITY_DECLARATION) || IS (p, VARIABLE_DECLARATION)) {
1293 int pop_ind = A68_INDENT (ind);
1294 indent_iddecl (p);
1295 A68_INDENT (ind) = pop_ind;
1296 } else if (IS (p, PROCEDURE_DECLARATION) || IS (p, PROCEDURE_VARIABLE_DECLARATION)) {
1297 int pop_ind = A68_INDENT (ind);
1298 indent_procdecl (p);
1299 A68_INDENT (ind) = pop_ind;
1300 } else if (IS (p, OPERATOR_DECLARATION) || IS (p, BRIEF_OPERATOR_DECLARATION)) {
1301 int pop_ind = A68_INDENT (ind);
1302 indent_opdecl (p);
1303 A68_INDENT (ind) = pop_ind;
1304 } else if (IS (p, PRIORITY_DECLARATION)) {
1305 int pop_ind = A68_INDENT (ind);
1306 indent_priodecl (p);
1307 A68_INDENT (ind) = pop_ind;
1308 } else if (IS (p, MODE_DECLARATION)) {
1309 int pop_ind = A68_INDENT (ind);
1310 indent_modedecl (p);
1311 A68_INDENT (ind) = pop_ind;
1312 } else if (IS (p, COMMA_SYMBOL)) {
1313 put_sym (p, !KEYWORD);
1314 if (one_liner) {
1315 BLANK;
1316 } else {
1317 put_nl ();
1318 }
1319 } else {
1320 indent_declist (SUB (p), one_liner);
1321 }
1322 }
1323 }
1324
1325 //! @brief Indent serial clause.
1326
1327 void indent_serial (NODE_T * p, BOOL_T one_liner, NODE_T ** what)
1328 {
1329 for (; p != NO_NODE; FORWARD (p)) {
1330 if (IS (p, UNIT) || IS (p, LABELED_UNIT)) {
1331 int pop_ind = A68_INDENT (col);
1332 (*what) = p;
1333 indent_statement (p);
1334 A68_INDENT (ind) = pop_ind;
1335 } else if (IS (p, DECLARATION_LIST)) {
1336 (*what) = p;
1337 indent_declist (p, one_liner);
1338 } else if (IS (p, SEMI_SYMBOL)) {
1339 put_sym (p, !KEYWORD);
1340 if (!one_liner) {
1341 put_nl ();
1342 if ((*what) != NO_NODE && IS ((*what), DECLARATION_LIST)) {
1343 // put_nl ();
1344 }
1345 } else {
1346 BLANK;
1347 }
1348 } else if (IS (p, EXIT_SYMBOL)) {
1349 if (NPRAGMENT (p) == NO_TEXT) {
1350 BLANK;
1351 }
1352 put_sym (p, !KEYWORD);
1353 if (!one_liner) {
1354 put_nl ();
1355 } else {
1356 BLANK;
1357 }
1358 } else {
1359 indent_serial (SUB (p), one_liner, what);
1360 }
1361 }
1362 }
1363
1364 //! @brief Do not pretty-print the environ.
1365
1366 void skip_environ (NODE_T * p)
1367 {
1368 for (; p != NO_NODE; FORWARD (p)) {
1369 if (LINE_NUMBER (p) == 0) {
1370 pretty_pragment (p, !KEYWORD);
1371 skip_environ (SUB (p));
1372 } else {
1373 NODE_T *what = NO_NODE;
1374 indent_serial (p, !ONE_LINER, &what);
1375 }
1376 }
1377 }
1378
1379 //! @brief Indenter driver.
1380
1381 void indenter (MODULE_T * q)
1382 {
1383 A68_INDENT (ind) = 1;
1384 A68_INDENT (col) = 1;
1385 A68_INDENT (indentation) = OPTION_INDENT (q);
1386 A68_INDENT (use_folder) = OPTION_FOLD (q);
1387 FILE_PRETTY_FD (q) = open (FILE_PRETTY_NAME (q), O_WRONLY | O_CREAT | O_TRUNC, A68_PROTECTION);
1388 ABEND (FILE_PRETTY_FD (q) == -1, ERROR_ACTION, __func__);
1389 FILE_PRETTY_OPENED (q) = A68_TRUE;
1390 A68_INDENT (fd) = FILE_PRETTY_FD (q);
1391 skip_environ (TOP_NODE (q));
1392 ASSERT (close (A68_INDENT (fd)) == 0);
1393 FILE_PRETTY_OPENED (q) = A68_FALSE;
1394 }