~ubuntu-branches/ubuntu/trusty/kate/trusty

« back to all changes in this revision

Viewing changes to tests/data/indent/pascal/test2/origin

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-12-18 16:28:23 UTC
  • mfrom: (1.1.38)
  • Revision ID: package-import@ubuntu.com-20131218162823-nea1os5bnvlya9km
Tags: 4:4.12.0-0ubuntu1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// kate: space-indent on; indent-width 4; replace-tabs on; remove-trailing-spaces all;
2
 
// kate: syntax pascal; indent-mode pascal;
3
 
 
4
 
// these variables are understood by the pascal indenter ...
5
 
// kate: cfgIndentCase false;          // indent elements in a case statement
6
 
// kate: cfgIndentBegin 2;            // indent 'begin' this many spaces
7
 
// kate: debugMode false;              // show how indent is determined
8
 
// kate: cfgAutoInsertStar true;      // auto insert '*' in (* ... *)-comments
9
 
// kate: cfgSnapParen true;           // snap ')' to '*)' in comments
10
 
 
11
 
(**********************************************   // check: indent OK?
12
 
 *                                            *
13
 
 *       Commment to test alignment           *
14
 
 *                                            *
15
 
 *                                            *
16
 
 **********************************************)
17
 
 
18
 
 (*************************************************************************
19
 
 Another Comment
20
 
 
21
 
 Relative alignment should be kept ...
22
 
       After indent, first character of this line should 
23
 
       still remain under the 'v' in relative
24
 
 
25
 
 *************************************************************************)
26
 
 
27
 
        program fred;
28
 
 
29
 
        uses bbb;
30
 
 
31
 
        label fred001;
32
 
        var   i: integer;
33
 
 
34
 
        const const0 = 0;
35
 
c33 = 12;
36
 
const1 = 17;
37
 
const2 = 18.4;
38
 
 
39
 
        type x = record a: real; c : char end;
40
 
 
41
 
   // r = record ... vs unfinished typedef
42
 
rType = record  // cr here ==> type def
43
 
a: aType;       // this can be realigned manually
44
 
b: bType;       // should follow line above
45
 
c: cType
46
 
end;
47
 
 
48
 
                  colourType = 
49
 
                     { unfinished type declaration }
50
 
                     ( red,    // CHECK: everything should line up below this
51
 
                                          orange, // this must follow line above
52
 
                                                   green,
53
 
                                                   blue,
54
 
                                                   indigo,
55
 
                                                   yellow,
56
 
                                                   violet
57
 
                                                   // CHECK: the comments should line up as well
58
 
                                                   // closing paren should align to list when it's left shifted
59
 
                                                   //                            to opening paren otherwise
60
 
                                                );
61
 
 
62
 
            otherTypeDef = integer;
63
 
 
64
 
// CHECK: next line should keep its relative alignment
65
 
           {ant}
66
 
            ant = RECORD CASE F: BOOLEAN OF
67
 
TRUE: ( fred : REAL;
68
 
joe  : INTEGER;
69
 
);  // parens should line up
70
 
FALSE: (  ted : ARRAY[
71
 
1..16
72
 
] OF BOOLEAN;
73
 
moe: CHAR;
74
 
        );
75
 
                                    END; // 'case' + 'record' share same 'end'
76
 
 
77
 
 
78
 
 
79
 
                        var a: real;
80
 
 
81
 
RW:  ARRAY [AASY..ZZSY]
82
 
OF   (*RESERVED WORDS*)   PACKED ARRAY [1..RWLENGTH,
83
 
2..66 ]     // CHECK: this line should be indented
84
 
OF CHAR;    // CHECK: this line should be indented from array
85
 
 
86
 
                           RW:  ARRAY [AASY..ZZSY] OF   (*RESERVED WORDS*)
87
 
                                 PACKED ARRAY [1..RWLENGTH] OF CHAR;
88
 
 
89
 
                        var
90
 
                           sym : keysymbol;
91
 
                           pos : hashIndex;
92
 
                           len : charLenType;
93
 
 
94
 
 
95
 
                        type tR = record
96
 
                                     i: integer;   // CHECK: can be aligned manually, but default indented from record
97
 
                                    r: real;      // should align with line immediately above
98
 
                                    a: array[1..11] of char;
99
 
 
100
 
                                       case boolean of
101
 
                                          true: ( fred : real;
102
 
                                                   joe  : integer;
103
 
                                                );  // parens should line up
104
 
                                          false: (  ted : array[
105
 
                                                                  1..16
106
 
                                                               ] of boolean;
107
 
                                                   moe: char;
108
 
                                                );
109
 
                                    end; // 'case' + 'record' share same 'end'
110
 
 
111
 
                              tArray = array[0..17] of real; // should indent wrt 'type'
112
 
 
113
 
                           type    colourType = (
114
 
                                         red,    // CHECK: this line can be adjusted manually
115
 
                                                   orange, // this must follow line above
116
 
                                                   green,
117
 
                                                   blue,
118
 
                                                   indigo,
119
 
                                                   yellow,
120
 
                                                   violet
121
 
                                                   // CHECK: the comments should line up as well
122
 
                                                   // closing paren should align to list when it's left shifted
123
 
                                                   //                            to opening paren otherwise
124
 
                                                );
125
 
 
126
 
                     blah = char;  // should align after type
127
 
 
128
 
                     optionset = set of options;
129
 
 
130
 
                  var
131
 
                     r1: record
132
 
                            i:    integer;
133
 
r:    real;                   // should line up with first member
134
 
a:    array[0..7] of char;
135
 
end;  // CHECK: end is outdented relative to first member
136
 
 
137
 
optionset : set of options;
138
 
 
139
 
                  options : (    crsupp,crbefore,blinbefore,
140
 
                                 dindonkey,dindent,spbef,
141
 
                                 spaft,gobsym,
142
 
                                 inbytab,   { indent current margin (was indent from symbol pos) }
143
 
                                 crafter,
144
 
                                 finl            { force symbol to follow on same line as previous symbol }
145
 
                            );
146
 
 
147
 
optionset = set of options;
148
 
 
149
 
aa: array[   1..9, // should be indented after cr
150
 
3..22 ]
151
 
          of ( crsupp,crbefore,blinbefore,
152
 
                dindonkey,dindent,spbef,
153
 
                  spaft,gobsym,
154
 
                  inbytab,   { indent current margin (was indent from symbol pos) }
155
 
                  crafter,
156
 
                  finl            { force symbol to follow on same line as previous symbol }
157
 
               );
158
 
 
159
 
aaa: array[ 1..3,
160
 
            4..5,
161
 
            12..11 ]
162
 
 of record // cr after here should indent from record
163
 
 a: array[1..6] of char;
164
 
 i: integer;
165
 
end;
166
 
 
167
 
 { CHECK: following text should keep indent relative to open/close brace
168
 
          when annotating, behavior of "external", "end" and possibly other keywords
169
 
          depends on whether we are in procedure declaration,
170
 
          item (var/const/type) declaration, or statements
171
 
   NOTE:  here we see why it's better to make the comment align with the 
172
 
          following line (ie the procedure call) rather than the preceding
173
 
          line (ie the 'end'.  Easy in theory, messy in practice.
174
 
 }
175
 
 
176
 
 
177
 
   procedure AVeryVeryLongFunctionName(const A : tRealArrayType;
178
 
                                       N : tIntegerType;
179
 
                                       var H : tRealArrayType); forward;
180
 
 
181
 
   (*************************************************************************
182
 
   CHECK:   comment is correctly aligned with precedinging statement
183
 
 
184
 
   Input parameters:
185
 
   A       -   description
186
 
 
187
 
   N       -   longer description, but
188
 
               still preserving relative format
189
 
 
190
 
   Output parameters:
191
 
   H       - other meaningful description
192
 
 
193
 
   Result:
194
 
      True, if successful
195
 
      False, otherwise
196
 
   *************************************************************************)
197
 
 
198
 
     var size : (small, medium, large); 
199
 
fred : real;
200
 
 
201
 
var   r : record i: integer; c: char end;
202
 
 
203
 
   a: array[ 1..9,    // should be indented after var
204
 
             'a'..'z'        // non-code, should line up with opening arg
205
 
           ] of integer;
206
 
 
207
 
        begin (* AVeryVeryLongFunctionName *)
208
 
 
209
 
if a then 
210
 
begin
211
 
s1;
212
 
             16:   f(32);  //CHECK: label forced to margin, statement is on new line with comment
213
 
end;
214
 
 
215
 
for i := 0 to 100 do
216
 
begin
217
 
with p^ do
218
 
begin s1; s2; s3 end
219
 
end;
220
 
 
221
 
with p^ do
222
 
begin s1; s2; s3 end;
223
 
 
224
 
                        for i := firstCh to lastCh do chtype[chr(i)] := none;
225
 
                        value['0'] := 0; value['1'] := 1; value['2'] := 2;
226
 
                        value['3'] := 3; value['4'] := 4; value['5'] := 5;
227
 
                        value['6'] := 6; value['7'] := 7; value['8'] := 8;
228
 
                        value['9'] := 9;
229
 
                        value['A'] := 10; value['B'] := 11; value['C'] := 12;
230
 
                        value['D'] := 13; value['E'] := 14; value['F'] := 15;
231
 
                        value['a'] := 10; value['b'] := 11; value['c'] := 12;
232
 
                        value['d'] := 13; value['e'] := 14; value['f'] := 15;
233
 
 
234
 
IF NOT (CH IN ['{','}']) THEN
235
 
// comment
236
 
BEGIN  IF CH <= 'Z' THEN CMDCH := CH ELSE CMDCH := CHR(ORD(CH)-ORD('a')+ORD('A') );
237
 
NEXTCH;
238
 
IF CMDCH = 'L' THEN
239
 
COMMAND(LISTON)
240
 
ELSE IF CMDCH = 'T' THEN
241
 
COMMAND(TRACEON)
242
 
ELSE IF CMDCH = 'I' THEN
243
 
COMMAND(INCLUDE)
244
 
ELSE IF CMDCH = 'Z' THEN
245
 
REPEAT
246
 
BEGIN
247
 
www.fred.com;
248
 
REPEAT commandIn UNTIL numRem = 0;
249
 
s1;
250
 
s2;
251
 
END;
252
 
UNTIL False
253
 
ELSE IF CMDCH = 'Q' THEN begin
254
 
COMMAND(QUIET)
255
 
end ELSE IF CMDCH = 'V' THEN
256
 
COMMAND(VERBOSE)
257
 
else if COMMAND.STRVAL = 'unknown' then
258
 
begin
259
 
IF
260
 
(numStr[0] >= 0) AND
261
 
(numStr[1] IN ['+', '-', '0' .. '9', '?']) // CHECK: indent
262
 
THEN
263
 
Power.Supply := '"AC' ELSE Power.Supply := '"DC'
264
 
end else  if CommandResult.Str = 'helpIamLost' then begin
265
 
Power.Supply := SetPowerSupplyCommands(Plus15V.Increase(Amps));
266
 
end else if (line = 'SHORT') OR (line = 'OPEN') THEN  BEGIN
267
 
OpenCircuit;
268
 
{*smoke billows out*}
269
 
IF SPARKS THEN
270
 
BEGIN
271
 
SPARKS := FALSE;
272
 
ShutDown
273
 
END
274
 
END ELSE IF
275
 
(line = 'OPEN') OR (line = 'CLOSED') THEN
276
 
BEGIN;
277
 
AddFuse(Low);
278
 
IF SPARKS THEN
279
 
BEGIN;
280
 
SPARKS := False;
281
 
CircuitBreaker(wishfulThinking)
282
 
END else if cond then
283
 
statement;
284
 
END ELSE IF (line = 'PLUS') OR (line = 'MINUS') THEN Transform(RedPhase)
285
 
ELSE IF (line = 'RED') OR (line = 'BLACK') THEN Transform(BluePhase)
286
 
ELSE IF line = 'XX' THEN Transistor
287
 
ELSE IF line = 'YYYY' THEN SetCurrent(FiveAmps)
288
 
ELSE IF line = 'QQQQ' THEN SetPower(FiveWatts)
289
 
ELSE IF line = 'AAAAA' THEN Power(FiveAmps)
290
 
ELSE IF
291
 
   {* QWERTY COMMENT LLLLLLLLL ####### *}
292
 
   line = 'SSSSS' THEN
293
 
BEGIN
294
 
actualphase := YellowPhase;
295
 
AdjustLinePhase(NewPhase);
296
 
END
297
 
ELSE IF
298
 
line = 'Noisy' THEN Filter
299
 
ELSE IF line = 'BLUE' THEN
300
 
BEGIN
301
 
AdjustLinePhase(XPhase);
302
 
Erase := True
303
 
END ELSE IF
304
 
line = 'RED' THEN BEGIN Swap; Hope END
305
 
ELSE IF
306
 
   line = '415' THEN iNumPut415
307
 
ELSE IF
308
 
   // a statement like this has no chance of being correctly indented ...
309
 
   // otoh, it shouldn't turn out catastrophically wrong.
310
 
   line = 'REFL' THEN FOR i := 1 TO numLines DO
311
 
WriteLn('level=', powerLevel[i], ' ', name[i]+'='+power[i])
312
 
ELSE IF
313
 
   line = 'HIGH' THEN reduce
314
 
ELSE IF
315
 
   line = 'LOW' THEN increase
316
 
ELSE IF
317
 
   line = 'END' THEN
318
 
BEGIN
319
 
WHILE powerlevel[NumPowers] = level DO NumPowers := NumPowers-1;
320
 
level := level-1;
321
 
END
322
 
ELSE IF
323
 
   line = 'WAIT' THEN
324
 
BEGIN
325
 
Z := ReActivate;
326
 
Z := X*240.0 + i*Y*240;
327
 
ROTATE(ABS(Z))
328
 
END
329
 
ELSE IF line = 'HILD' THEN motor(induction)
330
 
ELSE IF (line = 'REV') THEN        BEGIN
331
 
v := YellowPhase;
332
 
IF (NOT(v IN [#14..#240])) THEN
333
 
WriteLn(' POWER SUPPLY OUT OF SPEC') ELSE specValue := v;
334
 
specValidate
335
 
END
336
 
ELSE IF (line = 'OK') THEN BEGIN
337
 
IncomingSupply := True; specValidate END
338
 
ELSE IF (line = 'NOK') THEN BEGIN IncomingSupply := False; specValidate END
339
 
else    begin
340
 
GeneratedPowerLine.IncreasePower(
341
 
              'Unknown input power "%s"', [SwitchPower.Current]);    // CHECK: string should not cause problems
342
 
end;
343
 
END;
344
 
 
345
 
 
346
 
end (* AVeryVeryLongFunctionName *) ;  // check that only necessary work is done to align
347
 
 
348
 
 
349
 
FUNCTION f(
350
 
            alf : real;
351
 
fred : integer;  // should line up with alf
352
 
bill : boolean;
353
 
joe: char;
354
 
);
355
 
VAR s : string;
356
 
BEGIN s := do; WriteLn(s) END;
357
 
 
358
 
 
359
 
procedure getbyte;   // CHECK: cr after this line is **not** indented
360
 
 
361
 
var  // CHECK: cr after this line **is** indented
362
 
ch : char;
363
 
 
364
 
                                             begin
365
 
 
366
 
                                                // need to consider:
367
 
                                                // if c then begin s1; s2 end; // strip these lines
368
 
                                                // begin   // normal case
369
 
                                                // end     // normal case
370
 
                                                // end else if begin // should be OK since /end/ tested last
371
 
                                                // need to consider ...
372
 
                                                //                  if c1 then begin s1; s2 end
373
 
                                                //                  else s3;
374
 
                                        // <-- align this line
375
 
 
376
 
                                        { checking multi line statements }
377
 
 
378
 
 
379
 
                                                while aaaaaaaaaaaaaaaaaaaaaaa
380
 
         and bbbbbbbbbbb  do
381
 
if c1 then begin
382
 
s1;
383
 
for i := 1
384
 
      to 10 do
385
 
s3
386
 
end;
387
 
s4;
388
 
s5; // the ';' here links to the ';' after the 'case' below
389
 
 
390
 
if c1 then
391
 
case e01 of
392
 
111111111:    s1;
393
 
23:
394
 
writeln(x, 
395
 
'fred', 
396
 
notCaseValue:4,
397
 
 x);
398
 
 
399
 
2:
400
 
case e05 of
401
 
1: s1;   // CHECK: cr here should go to new case value!
402
 
88:
403
 
s3;
404
 
 
405
 
2:  begin
406
 
s2;
407
 
s3;
408
 
end;
409
 
 
410
 
3:
411
 
case e09 of
412
 
1: s1;   // CHECK: cr here should go to new case value!
413
 
88:
414
 
s3;
415
 
 
416
 
2:  
417
 
begin
418
 
s2;
419
 
s3;
420
 
end;
421
 
 
422
 
3: s3;
423
 
4,5,6..9: s6;
424
 
 
425
 
otherwise
426
 
writeln('lots');
427
 
writeln(' and lots');
428
 
end; {case}
429
 
 
430
 
4,5,6..9: s6;
431
 
 
432
 
otherwise
433
 
writeln('lots');
434
 
writeln(' and lots');
435
 
end; {case}
436
 
 
437
 
4: if e then
438
 
begin   // CHECK: should be indented after case value
439
 
s1;
440
 
s2
441
 
end
442
 
else if ee
443
 
and ee1
444
 
then begin
445
 
s1;
446
 
s2;
447
 
end;
448
 
 
449
 
99: a:= 13;
450
 
100: if e then s1;
451
 
 
452
 
333333: if c then 
453
 
begin // CKECK: should indent one level from case value
454
 
s3; // CHECK: should be indented another level
455
 
s4
456
 
end;
457
 
 
458
 
30:
459
 
if c then begin // cr here is OK
460
 
s3;
461
 
s4
462
 
end;
463
 
4: writeln('fred',
464
 
notCaseValue:4,
465
 
x
466
 
);
467
 
s4;             // incorrect code, indenter should expect a case value here
468
 
88:
469
 
if c1 then 
470
 
begin
471
 
s6;
472
 
s7
473
 
else
474
 
s8
475
 
end;     // stress test: else/end crossed over !!
476
 
end; {case}
477
 
s6;
478
 
 
479
 
a := 1;
480
 
a := 2;
481
 
a := 3;
482
 
if c1
483
 
and c2 then begin // can be aligned manually
484
 
a := 12;             // should be indented one level from if statement
485
 
f(x)
486
 
end;
487
 
if c1
488
 
and c2  // can be aligned manually
489
 
then 
490
 
begin
491
 
a := 12;             // should be indented one level from if statement
492
 
f(x)
493
 
end;
494
 
if c then
495
 
if c then
496
 
if c then
497
 
repeat s1 until c
498
 
else
499
 
a[    i,
500
 
j,
501
 
zzzzzzzzzz[ a,
502
 
b
503
 
],
504
 
    vvvvv   // CHECK: indent lines with zzzzzzzzz
505
 
] := x
506
 
+ 10;
507
 
if a then
508
 
if b then
509
 
if c then begin
510
 
s1;
511
 
s2;
512
 
end; {if}
513
 
while z do s1;
514
 
 
515
 
 
516
 
while not (  ((currchar.value = '*') and (nextchar.value = ')'))
517
 
or (currchar.value = '}') // args should line up inside parens
518
 
or (nextchar.name = endofline)
519
 
or ( sym^.length >= maxsymbolsize-2 )
520
 
or (nextchar.name = filemark)) do
521
 
storenextchar(sym^.length,sym^.value);  // should be indented from while
522
 
 
523
 
while not (currchar.value = '*') and (nextchar.value = ')')
524
 
      or (currchar.value = '}')           // possible to realign first line manually
525
 
or (nextchar.name = endofline)      // CHECK: other lines should follow first line  // CHECK:: indents line up
526
 
          or ( sym^.length >= maxsymbolsize-2 )
527
 
  or (nextchar.name = filemark) do
528
 
 storenextchar(sym^.length,sym^.value);  // should be indented from while
529
 
 
530
 
while not (currchar.value = '*') and (nextchar.value = ')')
531
 
      or (currchar.value = '}')           // possible to realign first line manually
532
 
or (nextchar.name = endofline)      // CHECK: other lines should follow first line  // CHECK:: indents line up
533
 
          or ( sym^.length >= maxsymbolsize-2 )
534
 
  or (nextchar.name = filemark) 
535
 
do
536
 
 storenextchar(sym^.length,sym^.value);  // should be indented from while
537
 
 
538
 
dblchar[becomes] := ':=';
539
 
dblchar[opencomment] := '(*';  // not start of comment!
540
 
sglchar[semicolon] := ';';
541
 
sglchar[colon]     := ':';
542
 
sglchar[equals]    := '=';
543
 
sglchar[openparen] := '(';
544
 
sglchar[closeparen] := ')';
545
 
sglchar[period]    := '.';
546
 
sglchar[opencomment] := '{';
547
 
sglchar[closecomment] := '}';
548
 
 
549
 
with nextchar do
550
 
if eof(infile) then 
551
 
begin
552
 
name := filemark;
553
 
if ch in ['0'..'9'] then
554
 
name := digit
555
 
else if ch = '''' then begin
556
 
name := quote
557
 
end else if (ch = blank) or (ch = chr(tab)) then
558
 
name := space
559
 
else name := otherchar
560
 
value := blank
561
 
end
562
 
else if eoln(infile) then 
563
 
begin
564
 
name := endofline;
565
 
value := blank;
566
 
if c1 then begin s1; s2 end
567
 
else s7;
568
 
inlines := inlines + 1;
569
 
readln(infile)
570
 
end
571
 
else
572
 
begin
573
 
read(infile,ch);
574
 
value := ch;
575
 
if ch in ['a'..'z','A'..'Z','_'] then
576
 
name := letter
577
 
else
578
 
if ch in ['0'..'9'] then
579
 
name := digit
580
 
else if ch = '''' then while c do
581
 
 begin
582
 
s1;
583
 
name := quote
584
 
end;
585
 
else if (ch = blank) or (ch = chr(tab)) then
586
 
name := space
587
 
else name := otherchar
588
 
      end;
589
 
 
590
 
      { CHECK:
591
 
                # pp lines go to start of line, unless they are in a comment
592
 
      }
593
 
 
594
 
                #if
595
 
                #endif
596
 
                cccccc; // CHECK: this aligns with code
597
 
                # // CHECK: preprocessor lines go to start of line
598
 
 
599
 
if c1 then
600
 
if c2 then while c do
601
 
s
602
 
else
603
 
s2;
604
 
s3;
605
 
s4;
606
 
 
607
 
end; { getbyte }
608
 
 
609
 
 
610
 
function f1( var z: integer;
611
 
var p,q : real;
612
 
t : boolean        ) : integer; // indentation should line up
613
 
 
614
 
type   tArray = array[0..17] of real;
615
 
 
616
 
r= record a: integer; c: char; end;
617
 
 
618
 
// nested variant record - too hard to get right. tough
619
 
MyRec = Record
620
 
X : Longint;
621
 
Case byte of
622
 
1,2,8 : (Y : Longint;
623
 
               case byte of
624
 
               3 : (Z : Longint);   // CHECK: parens inside parens aligned correctly
625
 
         );
626
 
end;
627
 
 
628
 
                                                   commands = (    crsupp,crbefore,blinbefore,
629
 
                                                                  dindonkey,dindent,spbef,
630
 
spaft,gobsym,
631
 
inbytab,   { indent current margin (was indent from symbol pos) }
632
 
crafter,
633
 
finl            { force symbol to follow on same line as previous symbol }
634
 
);
635
 
 
636
 
tR = record
637
 
i: integer;  // should indent after record
638
 
r: real;
639
 
a: array[1..11] of char;
640
 
 
641
 
case boolean of
642
 
true:( a: int);
643
 
dontKnow:
644
 
(z: real;
645
 
 fred : real;       // should be indented after case value
646
 
joe  : integer;
647
 
);
648
 
false:
649
 
(  ted : array[
650
 
                  1..16
651
 
] of boolean;
652
 
moe: char; // should align to ''ted''
653
 
);
654
 
end; // end of case + end of record
655
 
 
656
 
commandset = set of commands;       // should be aligned to 'record', not 'case'
657
 
 
658
 
begin { f1 }
659
 
case currsym^.name of
660
 
 
661
 
   { for procs, etc just record that we have one, wait for name }
662
 
progsym, procsym, funcsym: begin
663
 
symbol_seen := procsym;
664
 
proc_state := proc_header;
665
 
annotate_push( procsym );
666
 
end;
667
 
s1;                   // coding error, a case value should be here
668
 
   { remember we are in the declaraions part }
669
 
                        varsym, typesym, constsym, labelsym:
670
 
                           proc_state := proc_declarations;
671
 
 
672
 
                           { if it's a proc, there will be no begin/end ==> pop info we just saved
673
 
                           if it's an external var ==> do nothing  }
674
 
                        forwardsym, externalsym:
675
 
if proc_state = proc_header then 
676
 
begin
677
 
sym := annotate_pop;
678
 
tok := annotate_pop_tok;
679
 
if annotate_trace in traceFlags then
680
 
writeln( 'undo ', tok.val:tok.len );
681
 
end;
682
 
 
683
 
{ if a proc has just occurred, this is its name
684
 
otherwise, remember it, just in case it's a record name }
685
 
othersym: 
686
 
begin
687
 
if symbol_seen = procsym then begin
688
 
tok.val := currsym^.value;
689
 
tok.len := currsym^.length;
690
 
annotate_push_tok( tok );
691
 
symbol_seen := othersym;
692
 
end
693
 
else begin
694
 
annotate_temp_tok.val := currsym^.value;
695
 
annotate_temp_tok.len := currsym^.length;
696
 
end;
697
 
end;
698
 
 
699
 
{ we have the name, push it so the end symbol can get it back }
700
 
recordsym: begin
701
 
annotate_push_tok(annotate_temp_tok);
702
 
annotate_push( recordsym );
703
 
symbol_seen := recordsym;
704
 
end;
705
 
 
706
 
{ we must remember these so they can pushed if the begin symbol occurs }
707
 
ifsym, forsym, whilesym, withsym: 
708
 
begin
709
 
symbol_seen := currsym^.name;
710
 
end;
711
 
 
712
 
{ this is the second part of an if statement }
713
 
elsesym:
714
 
symbol_seen := ifsym;
715
 
 
716
 
{ if in a declaration ==> ignore
717
 
if in a statement (assume case statement) ==> prepare for possible begin following }
718
 
colon:
719
 
if proc_state = proc_statements then
720
 
   symbol_seen := colon;
721
 
 
722
 
{ reset symbol_seen }
723
 
semicolon:
724
 
symbol_seen := semicolon;
725
 
 
726
 
{ could be the begin of a proc
727
 
==> get value, leaving it for the corresponding end symbol
728
 
or it could be part of an if, etc,
729
 
==> push the symbol so the end symbol knows what to do  }
730
 
beginsym: begin
731
 
proc_state := proc_statements;
732
 
if symbol_seen in [ifsym, forsym, whilesym, withsym, elsesym, colon] then begin
733
 
annotate_push( symbol_seen );
734
 
end
735
 
else begin
736
 
sym := annotate_peek;
737
 
if sym = procsym then begin
738
 
   { this is a proc begin, add annotation }
739
 
annotate_pending_tok := true;
740
 
annotate_temp_tok := annotate_peek_tok;
741
 
end
742
 
else
743
 
 begin
744
 
if annotate_trace in traceFlags then
745
 
writeln( infilename,' line ', inlines, ': orphaned begin found' );
746
 
annotate_push( nosymbol );
747
 
end
748
 
end;
749
 
end;
750
 
 
751
 
{ push the symbol so the end symbol can get it back }
752
 
                                 casesym: annotate_push( casesym );
753
 
 
754
 
                                    { end of proc, end of record  ==> pop name
755
 
                                    end of if, etc statement    ==> pop symbol
756
 
                                    end of case item (colon)    ==> ignore
757
 
                                    end of record ==> check if named record  }
758
 
endsym:
759
 
 begin
760
 
symbol_seen := endsym;
761
 
sym := annotate_pop;
762
 
if sym = recordsym then begin
763
 
   annotate_temp_tok := annotate_pop_tok;
764
 
   if annotate_temp_tok.val[1] in ['A'..'Z','a'..'z'] then
765
 
      annotate_pending_tok := true;
766
 
end
767
 
else if sym = procsym then 
768
 
begin
769
 
   annotate_pending_tok := true;
770
 
   annotate_temp_tok := annotate_pop_tok;
771
 
end
772
 
else if sym = ifsym then begin
773
 
   { if there's an else part, don't do an annotation here }
774
 
   if nextsym^.name <> elsesym then
775
 
 begin
776
 
      annotate_pending := true;
777
 
      annotate_temp := sym;
778
 
   end
779
 
end
780
 
else if sym in [forsym, whilesym, withsym, casesym] then begin
781
 
   annotate_pending := true;
782
 
   annotate_temp := sym;
783
 
end
784
 
else if sym = colon then 
785
 
begin
786
 
         if annotate_trace in traceFlags then
787
 
            writeln( 'case item not annotated' );
788
 
      end
789
 
      else begin
790
 
         if annotate_trace in traceFlags then
791
 
            writeln( infilename,' line: ', inlines, ' end symbol found but not handled' );
792
 
      end;
793
 
   end;
794
 
end; { case }
795
 
 
796
 
if annotate_pending then begin
797
 
if nextsym^.crsbefore > 0 then
798
 
 begin
799
 
   { rest of line is empty }
800
 
                              insert_annotation(annotate_temp);
801
 
                              annotate_pending := false;
802
 
                           end else if nextsym^.name in [opencomment,
803
 
                           closecomment] then 
804
 
begin
805
 
                              { there's another comment already on the same line }
806
 
if annotate_trace in traceFlags then
807
 
writeln( infilename,' line: ', inlines, ' annotate ', keyword[annotate_temp], ' abandoned' );
808
 
annotate_pending := false;
809
 
end
810
 
else if (nextsym^.name <> semicolon) then begin
811
 
insert_annotation(annotate_temp);
812
 
annotate_pending := false;
813
 
end;
814
 
end;
815
 
 
816
 
if annotate_pending_tok then
817
 
 begin
818
 
if nextsym^.crsbefore > 0 then begin
819
 
   { rest of line is empty }
820
 
   insert_annotation_tok( annotate_temp_tok );
821
 
   annotate_pending_tok := false;
822
 
end
823
 
else if nextsym^.name in [opencomment, closecomment] then begin
824
 
   { there's another comment already on the same line }
825
 
if annotate_trace in traceFlags then
826
 
writeln( infilename,
827
 
         ' line: ', inlines,
828
 
' annotate ', annotate_temp_tok.val:annotate_temp_tok.len, ' abandoned'
829
 
);
830
 
annotate_pending_tok := false;
831
 
end
832
 
else if not (nextsym^.name in [semicolon, period]) then begin
833
 
   insert_annotation_tok( annotate_temp_tok );
834
 
   annotate_pending_tok := false;
835
 
end;
836
 
end;
837
 
end; { f1 }
838
 
 
839
 
 
840
 
function f2( p: boolean;
841
 
             var q: real;
842
 
var x: ttype;              // should line up with first param
843
 
var c: char;
844
 
 
845
 
var i1, i2: integer;
846
 
 
847
 
ch: char;
848
 
z: boolean
849
 
) : real;
850
 
 
851
 
var
852
 
a: integer;
853
 
b: boolean;
854
 
 
855
 
begin { f2 }
856
 
 
857
 
with floodlePtr^ do
858
 
begin name := '        '; id := nil; next := nil; floodleAddr := 0;
859
 
cow := grass + floodle  // should be indented
860
 
end;
861
 
 
862
 
case e of
863
 
1: s1;   // CHECK: cr here should go to new case value!
864
 
88:
865
 
s3;
866
 
 
867
 
2:  begin
868
 
s2;
869
 
s3;
870
 
end;
871
 
 
872
 
3: s3;
873
 
4,5,6..9: s6;
874
 
 
875
 
otherwise
876
 
writeln('lots');
877
 
writeln(' and lots');
878
 
end; {case}
879
 
 
880
 
if c then begin
881
 
s1;
882
 
a := func( 12,
883
 
fffff( 89,
884
 
t
885
 
),
886
 
a // should align with '12'
887
 
);
888
 
end; // this must be aligned to the 'if' statement
889
 
 
890
 
 
891
 
fredzarmplezzzzzzzzzzzz(       arg1,
892
 
arg1,
893
 
arg2,
894
 
arg3
895
 
);
896
 
 
897
 
x := f(a) + f(b);
898
 
 
899
 
 
900
 
if (e111) + e2 then fffffffffffff(    func0(  func1(    func2( f3(       arg1,
901
 
 
902
 
 
903
 
                                                                         arg2,
904
 
   arg3,
905
 
   arg4
906
 
),
907
 
 
908
 
 
909
 
a1,  // should be aligned with arg f3, not '('
910
 
a2,
911
 
a3,
912
 
a4
913
 
),
914
 
 
915
 
aa2,
916
 
aa3,
917
 
aa4,
918
 
aa5
919
 
),
920
 
bb1,
921
 
bb2,
922
 
bb3,
923
 
bb4
924
 
),
925
 
cc1,
926
 
cc2,
927
 
cc3,
928
 
cc4
929
 
)
930
 
else if c1 then begin
931
 
s1;
932
 
end;
933
 
 
934
 
nextStmt := 13;
935
 
 
936
 
while c1 do
937
 
if q then
938
 
s1
939
 
else if qq then
940
 
 begin
941
 
s2;
942
 
s3
943
 
end;
944
 
 
945
 
 
946
 
if c1
947
 
and c2 then begin // this can be aligned manually
948
 
a := 12;
949
 
s1;
950
 
f(x)
951
 
end;
952
 
 
953
 
if c1
954
 
and c2 
955
 
then begin
956
 
a := 12;
957
 
s1;
958
 
f(x)
959
 
end;
960
 
 
961
 
if c1
962
 
and c2 then 
963
 
begin
964
 
a := 12;
965
 
s1;
966
 
f(x)
967
 
end;
968
 
 
969
 
if c1
970
 
and c2
971
 
 then
972
 
 begin
973
 
a := 12;
974
 
s1;
975
 
f(x)
976
 
end;
977
 
 
978
 
if cc1 then
979
 
while c2 do
980
 
f(x);
981
 
 
982
 
while c1 do f(  arg1,
983
 
arg2  // this should line up with arg1
984
 
);
985
 
 
986
 
if c4 then f( arg1,
987
 
arg2
988
 
);
989
 
 
990
 
f1        ( arg1,
991
 
arg2
992
 
);
993
 
fred      (  arg1,
994
 
arg2
995
 
arg3
996
 
arg4,
997
 
 
998
 
arg5
999
 
);
1000
 
 
1001
 
ff( arg1,
1002
 
arg2
1003
 
);
1004
 
 
1005
 
a[1] := 13;
1006
 
repeat
1007
 
s1;
1008
 
while c3 do begin
1009
 
s3;
1010
 
while c2 do
1011
 
 begin
1012
 
s4;
1013
 
while c4 do begin
1014
 
if c3 then
1015
 
begin
1016
 
s1;
1017
 
s2;
1018
 
end else
1019
 
s3;
1020
 
if c3 then begin
1021
 
s1
1022
 
end else
1023
 
 
1024
 
if a then b
1025
 
else
1026
 
if c then d
1027
 
else
1028
 
 
1029
 
s2;
1030
 
if c3 then
1031
 
if c4 then
1032
 
s5;
1033
 
 
1034
 
s3
1035
 
end;
1036
 
end
1037
 
end
1038
 
until c3;
1039
 
 
1040
 
 
1041
 
s5;
1042
 
 
1043
 
s3;
1044
 
while c7 do begin
1045
 
s3;
1046
 
s4
1047
 
end;
1048
 
 
1049
 
s4
1050
 
end;
1051
 
 
1052
 
s2
1053
 
until c1;  // there is no matching repeat here
1054
 
 
1055
 
end;  { f2 }
1056
 
 
1057
 
 
1058
 
begin {main program }
1059
 
 
1060
 
if f1 > 0 then result := f1-1
1061
 
else begin
1062
 
f1 :=  -23;
1063
 
end;
1064
 
 
1065
 
case e012 of
1066
 
2:
1067
 
if eeeeeeeeeeeeeeeeee
1068
 
or e33333333333
1069
 
then
1070
 
a := 12
1071
 
else
1072
 
for iiiiiiiiiii := 12
1073
 
                to 89 // CHECK 89 lines up with 12  
1074
 
do begin
1075
 
if very_long_expression
1076
 
or another_very_long_expression
1077
 
and yet_another_very_long_expression then
1078
 
s1;
1079
 
s11;
1080
 
end;
1081
 
1:
1082
 
if e
1083
 
+e2
1084
 
                             +e3
1085
 
  +e2
1086
 
      or 75  // CHECK: follows first continue line
1087
 
   then
1088
 
   for i := 1
1089
 
 to 89
1090
 
 do begin
1091
 
 a := 12 + 24
1092
 
           3 +  // CHECK 3 lines up with 24 above
1093
 
                          19 +
1094
 
                            25;
1095
 
                          s1 := e1
1096
 
  + e2;
1097
 
   end;
1098
 
5:
1099
 
f32verylongfunctionnamezzzzzzzzzzzzzzz(
1100
 
                       z, // user can realign this anywhere
1101
 
                                 a,b, // this should line up with 'z'''
1102
 
                                 c,
1103
 
                                 d,
1104
 
                                 e
1105
 
                              );
1106
 
 
1107
 
3: begin
1108
 
s0;
1109
 
s3;        // bad code, 'end' is missing
1110
 
//end;            // missing end, so next few case values interpreted as labels
1111
 
5:
1112
 
if q then z;
1113
 
 
1114
 
s3;              // code error - case value belongs here, not statement
1115
 
5:
1116
 
if c2 then s2;
1117
 
 
1118
 
16:
1119
 
if c2 then
1120
 
s1;
1121
 
17:
1122
 
if c2 then begin s1; s2 end;
1123
 
 
1124
 
4:
1125
 
if a then begin
1126
 
s2;
1127
 
s3 // no trailing semi, but it indents
1128
 
end;
1129
 
end; { ** bad code ** }   // crossed begin/end - matches '3: begin' above
1130
 
 
1131
 
 
1132
 
2: s2;
1133
 
3: while c4
1134
 
            and e3  do // CHECK: should indent beyond while
1135
 
s8;
1136
 
1: s1;
1137
 
{
1138
 
23:
1139
 
}
1140
 
23: s1;
1141
 
s2:
1142
 
 begin
1143
 
s2
1144
 
s3 // no trailing semi in line above, but it indents correctly
1145
 
end;         // need ';' to force alignment with new case value
1146
 
otherwise if a then b;
1147
 
if c0 then  begin
1148
 
if c1 then begin
1149
 
// it does!!
1150
 
if c3 then
1151
 
write(              // CHECK: deeply nested levels of parens
1152
 
      f(5.5),
1153
 
'test',   // should be aligned
1154
 
notCaseValue:4,
1155
 
f1(8,8),
1156
 
ff( a,
1157
 
b( f(13),
1158
 
12,
1159
 
x
1160
 
),
1161
 
c( g(55) ),
1162
 
 
1163
 
));
1164
 
 
1165
 
end else  // statement unfinished
1166
 
otherwise       // duplicate eotherwise
1167
 
if a then begin
1168
 
b
1169
 
end else if a1 then begin
1170
 
c;
1171
 
c;
1172
 
if a
1173
 
and a1 then
1174
 
b
1175
 
else
1176
 
c;   { CHECK: outdents only when 'c' is followed by ';' }
1177
 
if a then begin
1178
 
b;
1179
 
b1;
1180
 
end else
1181
 
s3;
1182
 
if a then b else c;
1183
 
if a then
1184
 
b
1185
 
else
1186
 
c;
1187
 
if a then b
1188
 
else f( arg,
1189
 
arg2,
1190
 
a1,
1191
 
a2
1192
 
            # this is a pp line!!     // bug! silly place to put a pp line
1193
 
 f( a,
1194
 
b
1195
 
  ));
1196
 
 
1197
 
if a then
1198
 
b
1199
 
else if c1 then
1200
 
s1;
1201
 
if c2 then begin
1202
 
s33;
1203
 
s34
1204
 
end;    { !!! classic error, shouldn't be a semi colon here }
1205
 
else if c3 then begin
1206
 
s44;
1207
 
s45
1208
 
end else begin
1209
 
s;
1210
 
s;
1211
 
end
1212
 
 
1213
 
end else if c1 then begin // comment
1214
 
s3
1215
 
end;
1216
 
 
1217
 
while c3 do
1218
 
s4;
1219
 
end;     // spurious end
1220
 
 
1221
 
s0;
1222
 
s1;
1223
 
s2;
1224
 
s3;
1225
 
end // case e012 of
1226
 
else if c2 then begin  // spurious else
1227
 
 
1228
 
ss;
1229
 
 
1230
 
if c1 then begin
1231
 
write( 'test',
1232
 
notCaseValue:4
1233
 
)
1234
 
end else      // this else has no statement
1235
 
end    else begin { should still be in sync }
1236
 
 
1237
 
s1;
1238
 
 
1239
 
s1;
1240
 
 
1241
 
 
1242
 
 
1243
 
s2
1244
 
end;
1245
 
 
1246
 
f(   a,
1247
 
b,
1248
 
)
1249
 
 
1250
 
ff(  a,
1251
 
b,
1252
 
c
1253
 
)
1254
 
))
1255
 
 
1256
 
writeln( 'this is a string ', n:1, ' ', ' ', r:10:2 );
1257
 
 
1258
 
with p do
1259
 
begin
1260
 
 
1261
 
end;
1262
 
 
1263
 
with p065 do
1264
 
begin
1265
 
x := 2;
1266
 
end;
1267
 
case e07 of
1268
 
0:
1269
 
1:  s1;
1270
 
2:  begin
1271
 
s2;
1272
 
s3;
1273
 
end;
1274
 
3: s3;
1275
 
12:
1276
 
 
1277
 
15:
1278
 
4,5,6..9: begin s1; end;
1279
 
otherwise
1280
 
s6;
1281
 
 
1282
 
 
1283
 
s3;
1284
 
s1;
1285
 
 
1286
 
s2;
1287
 
 
1288
 
while e and
1289
 
e2 DO begin { comment }
1290
 
s0;
1291
 
s33;
1292
 
s44;
1293
 
end;
1294
 
 
1295
 
if e97 then begin
1296
 
s3;
1297
 
label:
1298
 
while c103 do begin
1299
 
s4;
1300
 
q := 0;
1301
 
case e of
1302
 
12,13..16,20: begin
1303
 
s2;
1304
 
s3;
1305
 
end;
1306
 
8: writeln( 'test',
1307
 
   x,
1308
 
   r:4
1309
 
   );
1310
 
9:
1311
 
 
1312
 
end;
1313
 
while c1
1314
 
   and c2 do begin
1315
 
s5;
1316
 
s9;
1317
 
end;
1318
 
 
1319
 
s;
1320
 
s;
1321
 
s1;
1322
 
if e105 then
1323
 
if c2 then begin
1324
 
 
1325
 
s3;
1326
 
end; // if
1327
 
 
1328
 
case e11 of
1329
 
2..4,5: begin
1330
 
s1;
1331
 
s2
1332
 
end;
1333
 
 
1334
 
 
1335
 
3: a:= 13;
1336
 
 
1337
 
 
1338
 
89:
1339
 
 
1340
 
case e12 of
1341
 
2,3:
1342
 
a:=13;
1343
 
2: begin
1344
 
a:= 13
1345
 
end;
1346
 
5,6,
1347
 
7:
1348
 
otherwise
1349
 
 
1350
 
s3;
1351
 
s4;
1352
 
end;  // case e12 of
1353
 
 
1354
 
otherwise
1355
 
 
1356
 
 
1357
 
s4;
1358
 
s5;
1359
 
if c2 then
1360
 
s5
1361
 
end; // case e11 of
1362
 
 
1363
 
s3;
1364
 
 
1365
 
end; // while c103
1366
 
 
1367
 
end; // if e97
1368
 
 
1369
 
repeat
1370
 
s3;
1371
 
s4;
1372
 
until c1;
1373
 
 
1374
 
s0;
1375
 
s1;
1376
 
 
1377
 
if e then begin
1378
 
s3;
1379
 
s4;
1380
 
s0;
1381
 
 
1382
 
s1;
1383
 
 
1384
 
s1;
1385
 
s1;
1386
 
end;
1387
 
 
1388
 
repeat
1389
 
ss;
1390
 
s2;
1391
 
if e then
1392
 
ss;
1393
 
s3;
1394
 
s1;
1395
 
until e;
1396
 
 
1397
 
if e then begin
1398
 
s1;
1399
 
s3;
1400
 
if e then begin
1401
 
s3;
1402
 
s5;
1403
 
end;
1404
 
s6;
1405
 
s2;
1406
 
end;
1407
 
 
1408
 
 
1409
 
of:=2; // more bad code
1410
 
 
1411
 
repeat
1412
 
s1
1413
 
until c;
1414
 
 
1415
 
 
1416
 
a := 123456789;
1417
 
IF (e1) or  (* comment *)
1418
 
(e2)  then
1419
 
 
1420
 
begin // CHECK: the begin should follow 'if' line, not 'then' line
1421
 
 
1422
 
if e then begin s end
1423
 
else begin
1424
 
s1;
1425
 
s2;
1426
 
end;
1427
 
 
1428
 
if e then
1429
 
s0;
1430
 
if e then begin
1431
 
s1;
1432
 
s2;       (  // unattached parens
1433
 
 
1434
 
         )
1435
 
         s;  // problem caused by unattached parens
1436
 
end
1437
 
123456
1438
 
{ comment }
1439
 
 
1440
 
if e4 then
1441
 
while e5 do begin
1442
 
(* ...
1443
 
    *  CHECK: stars should line up
1444
 
 *
1445
 
        *
1446
 
    *)
1447
 
(aa)
1448
 
if a then b;   (* qwe
1449
 
                *rty *)
1450
 
   cc;
1451
 
s;
1452
 
// comment
1453
 
 
1454
 
end;
1455
 
 
1456
 
 
1457
 
f( a, b)
1458
 
 
1459
 
case e of
1460
 
12,13: a:=12;
1461
 
1,2,3,4..6: writeln(
1462
 
a, 'TODO:', b );
1463
 
 
1464
 
567:
1465
 
s2;
1466
 
 
1467
 
88: writeln( 'zzzzzzzzzz',
1468
 
a:12,
1469
 
b
1470
 
);
1471
 
99: writeln(
1472
 
z:13,
1473
 
b
1474
 
);
1475
 
13: begin
1476
 
// no statement
1477
 
end;
1478
 
 
1479
 
 
1480
 
 
1481
 
0: f( a,
1482
 
b
1483
 
);
1484
 
12: ff (  a,
1485
 
b
1486
 
);
1487
 
(13+12): f( a,
1488
 
37,508.18
1489
 
);
1490
 
 
1491
 
 
1492
 
 
1493
 
2: if a = 12 then
1494
 
s1;
1495
 
else begin
1496
 
s2;
1497
 
end;
1498
 
 
1499
 
0: writeln( 'zzzzzzzzz',
1500
 
 
1501
 
a:3,
1502
 
b:4,
1503
 
'xxxxxxxxxx'
1504
 
 
1505
 
);
1506
 
 
1507
 
1: s1;
1508
 
3:
1509
 
 
1510
 
 
1511
 
 
1512
 
2: begin
1513
 
 
1514
 
s1;
1515
 
s2;
1516
 
s3;
1517
 
end;
1518
 
 
1519
 
5 :
1520
 
writeln( 'this is ',
1521
 
'multiline arg list'
1522
 
);
1523
 
 
1524
 
 
1525
 
 
1526
 
 
1527
 
5:
1528
 
6:
1529
 
s1;
1530
 
 
1531
 
9:
1532
 
c := 13;
1533
 
 
1534
 
c2,3,4..7: begin
1535
 
 
1536
 
s4;
1537
 
sl;
1538
 
a := 13;
1539
 
 
1540
 
label:  // this is a label, not case value
1541
 
cc;
1542
 
 
1543
 
b := 17;
1544
 
 
1545
 
writeln( 'strrrrrr', a:4 );
1546
 
 
1547
 
end;
1548
 
c9 :
1549
 
s1;
1550
 
 
1551
 
end; { case e of }
1552
 
            // comment
1553
 
ff(   a,      // this line aligns with 'end'
1554
 
b,     // CHECK: keep relative indent
1555
 
c
1556
 
)
1557
 
;
1558
 
 
1559
 
end;  // begin CHECK:
1560
 
 
1561
 
ggggg:
1562
 
 
1563
 
 
1564
 
f(
1565
 
a,
1566
 
b,
1567
 
c
1568
 
);
1569
 
 
1570
 
 
1571
 
writeln( a,
1572
 
 
1573
 
b,
1574
 
 
1575
 
b,    { check indent after cr here }
1576
 
);
1577
 
 
1578
 
f(13);
1579
 
end; // case e07
1580
 
 
1581
 
end. // main