]> gcc.gnu.org Git - gcc.git/blame - gcc/m2/gm2-compiler/M2LexBuf.mod
Remove unused parameter warning via introducing attribute unused.
[gcc.git] / gcc / m2 / gm2-compiler / M2LexBuf.mod
CommitLineData
7401123f
GM
1(* M2LexBuf.mod provides a buffer for m2.lex.
2
3d864fce 3Copyright (C) 2001-2022 Free Software Foundation, Inc.
7401123f
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 M2LexBuf ;
23
24IMPORT m2flex ;
25
26FROM libc IMPORT strlen ;
27FROM SYSTEM IMPORT ADDRESS ;
28FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
29FROM DynamicStrings IMPORT string, InitString, InitStringCharStar, Equal, Mark, KillString ;
30FROM FormatStrings IMPORT Sprintf1 ;
31FROM NameKey IMPORT NulName, Name, makekey, MakeKey, KeyToCharStar ;
32FROM M2Reserved IMPORT toktype, tokToTok ;
33FROM M2Printf IMPORT printf0, printf1, printf2, printf3 ;
34FROM M2Debug IMPORT Assert ;
35FROM NameKey IMPORT makekey ;
36FROM m2linemap IMPORT location_t, GetLocationBinary ;
37FROM M2Emit IMPORT UnknownLocation, BuiltinsLocation ;
38FROM M2Error IMPORT WarnStringAt ;
39
40CONST
41 MaxBucketSize = 100 ;
42 Debugging = FALSE ;
fd948137 43 DebugRecover = FALSE ;
7401123f
GM
44 InitialSourceToken = 2 ; (* 0 is unknown, 1 is builtin. *)
45
46TYPE
fd948137 47 SourceList = POINTER TO RECORD
7401123f
GM
48 left,
49 right: SourceList ;
50 name : String ;
51 line : CARDINAL ;
52 col : CARDINAL ;
53 END ;
54
55 TokenDesc = RECORD
fd948137
GM
56 token : toktype ;
57 str : Name ; (* ident name or string literal. *)
58 int : INTEGER ;
59 line : CARDINAL ;
60 col : CARDINAL ;
61 file : SourceList ;
62 loc : location_t ;
63 insert: TokenBucket ; (* contains any inserted tokens. *)
7401123f
GM
64 END ;
65
fd948137 66 TokenBucket = POINTER TO RECORD
7401123f
GM
67 buf : ARRAY [0..MaxBucketSize] OF TokenDesc ;
68 len : CARDINAL ;
69 next: TokenBucket ;
70 END ;
71
72 ListDesc = RECORD
73 head,
74 tail : TokenBucket ;
75 LastBucketOffset: CARDINAL ;
76 END ;
77
78VAR
79 CurrentSource : SourceList ;
80 UseBufferedTokens,
81 CurrentUsed : BOOLEAN ;
82 ListOfTokens : ListDesc ;
83 CurrentTokNo : CARDINAL ;
fd948137 84 InsertionIndex : CARDINAL ;
7401123f
GM
85
86
87(*
88 InitTokenList - creates an empty token list, which starts the first source token
89 at position 2. This allows position 0 to be for unknown location
90 and position 1 for builtin token.
91*)
92
93PROCEDURE InitTokenList ;
94BEGIN
fd948137 95 NEW (ListOfTokens.head) ;
7401123f 96 ListOfTokens.tail := ListOfTokens.head ;
fd948137
GM
97 WITH ListOfTokens.tail^.buf[0] DO
98 token := eoftok ;
99 str := NulName ;
100 int := 0 ;
101 line := 0 ;
102 col := 0 ;
103 file := NIL ;
104 loc := UnknownLocation ()
105 END ;
106 WITH ListOfTokens.tail^.buf[1] DO
107 token := eoftok ;
108 str := NulName ;
109 int := 0 ;
110 line := 0 ;
111 col := 0 ;
112 file := NIL ;
113 loc := BuiltinsLocation ()
114 END ;
7401123f
GM
115 ListOfTokens.tail^.len := InitialSourceToken
116END InitTokenList ;
117
118
119(*
120 Init - initializes the token list and source list.
121*)
122
123PROCEDURE Init ;
124BEGIN
fd948137 125 InsertionIndex := 0 ;
7401123f
GM
126 currenttoken := eoftok ;
127 CurrentTokNo := InitialSourceToken ;
128 CurrentSource := NIL ;
129 ListOfTokens.head := NIL ;
130 ListOfTokens.tail := NIL ;
131 UseBufferedTokens := FALSE ;
132 InitTokenList
133END Init ;
134
135
136(*
137 AddTo - adds a new element to the end of SourceList, CurrentSource.
138*)
139
140PROCEDURE AddTo (l: SourceList) ;
141BEGIN
142 l^.right := CurrentSource ;
143 l^.left := CurrentSource^.left ;
144 CurrentSource^.left^.right := l ;
145 CurrentSource^.left := l ;
146 WITH l^.left^ DO
147 line := m2flex.GetLineNo() ;
148 col := m2flex.GetColumnNo()
149 END
150END AddTo ;
151
152
153(*
154 SubFrom - subtracts, l, from the source list.
155*)
156
157PROCEDURE SubFrom (l: SourceList) ;
158BEGIN
159 l^.left^.right := l^.right ;
160 l^.right^.left := l^.left
161END SubFrom ;
162
163
164(*
165 NewElement - returns a new SourceList
166*)
167
168PROCEDURE NewElement (s: ADDRESS) : SourceList ;
169VAR
170 l: SourceList ;
171BEGIN
fd948137
GM
172 NEW (l) ;
173 IF l = NIL
7401123f
GM
174 THEN
175 HALT
176 ELSE
177 WITH l^ DO
178 name := InitStringCharStar(s) ;
179 left := NIL ;
180 right := NIL
181 END
182 END ;
fd948137 183 RETURN l
7401123f
GM
184END NewElement ;
185
186
187(*
188 NewList - initializes an empty list with the classic dummy header element.
189*)
190
191PROCEDURE NewList () : SourceList ;
192VAR
193 l: SourceList ;
194BEGIN
fd948137 195 NEW (l) ;
7401123f
GM
196 WITH l^ DO
197 left := l ;
198 right := l ;
199 name := NIL
200 END ;
fd948137 201 RETURN l
7401123f
GM
202END NewList ;
203
204
205(*
206 CheckIfNeedToDuplicate - checks to see whether the CurrentSource has
207 been used, if it has then duplicate the list.
208*)
209
210PROCEDURE CheckIfNeedToDuplicate ;
211VAR
212 l, h: SourceList ;
213BEGIN
214 IF CurrentUsed
215 THEN
216 l := CurrentSource^.right ;
217 h := CurrentSource ;
218 CurrentSource := NewList() ;
219 WHILE l#h DO
fd948137 220 AddTo (NewElement (l^.name)) ;
7401123f
GM
221 l := l^.right
222 END
223 END
224END CheckIfNeedToDuplicate ;
225
226
227(*
228 PushFile - indicates that, filename, has just been included.
229*)
230
231PROCEDURE PushFile (filename: ADDRESS) ;
232VAR
233 l: SourceList ;
234BEGIN
235 CheckIfNeedToDuplicate ;
fd948137 236 AddTo (NewElement (filename)) ;
7401123f
GM
237 IF Debugging
238 THEN
239 IF CurrentSource^.right#CurrentSource
240 THEN
241 l := CurrentSource ;
242 REPEAT
243 printf3('name = %s, line = %d, col = %d\n', l^.name, l^.line, l^.col) ;
244 l := l^.right
245 UNTIL l=CurrentSource
246 END
247 END
248END PushFile ;
249
250
251(*
252 PopFile - indicates that we are returning to, filename, having finished
253 an include.
254*)
255
256PROCEDURE PopFile (filename: ADDRESS) ;
257VAR
258 l: SourceList ;
259BEGIN
260 CheckIfNeedToDuplicate ;
261 IF (CurrentSource#NIL) AND (CurrentSource^.left#CurrentSource)
262 THEN
263 l := CurrentSource^.left ; (* last element *)
264 SubFrom (l) ;
265 DISPOSE (l) ;
266 IF (CurrentSource^.left#CurrentSource) AND
267 (NOT Equal(CurrentSource^.name, Mark(InitStringCharStar(filename))))
268 THEN
269 (* mismatch in source file names after preprocessing files *)
270 END
271 ELSE
272 (* source file list is empty, cannot pop an include.. *)
273 END
274END PopFile ;
275
276
277(*
278 KillList - kills the SourceList providing that it has not been used.
279*)
280
281PROCEDURE KillList ;
282VAR
283 l, k: SourceList ;
284BEGIN
285 IF (NOT CurrentUsed) AND (CurrentSource#NIL)
286 THEN
287 l := CurrentSource ;
288 REPEAT
289 k := l ;
290 l := l^.right ;
291 DISPOSE(k)
292 UNTIL l=CurrentSource
293 END
294END KillList ;
295
296
297(*
298 ReInitialize - re-initialize the all the data structures.
299*)
300
301PROCEDURE ReInitialize ;
302VAR
303 s, t: TokenBucket ;
304BEGIN
305 IF ListOfTokens.head#NIL
306 THEN
307 t := ListOfTokens.head ;
308 REPEAT
309 s := t ;
310 t := t^.next ;
311 DISPOSE(s) ;
312 UNTIL t=NIL ;
313 CurrentUsed := FALSE ;
314 KillList
315 END ;
316 Init
317END ReInitialize ;
318
319
320(*
321 SetFile - sets the current filename to, filename.
322*)
323
324PROCEDURE SetFile (filename: ADDRESS) ;
325BEGIN
326 KillList ;
327 CurrentUsed := FALSE ;
fd948137
GM
328 CurrentSource := NewList () ;
329 AddTo (NewElement (filename))
7401123f
GM
330END SetFile ;
331
332
333(*
334 OpenSource - Attempts to open the source file, s.
335 The success of the operation is returned.
336*)
337
338PROCEDURE OpenSource (s: String) : BOOLEAN ;
339BEGIN
340 IF UseBufferedTokens
341 THEN
342 GetToken ;
343 RETURN TRUE
344 ELSE
345 IF m2flex.OpenSource (string (s))
346 THEN
347 SetFile (string (s)) ;
348 SyncOpenWithBuffer ;
349 GetToken ;
350 RETURN TRUE
351 ELSE
352 RETURN FALSE
353 END
354 END
355END OpenSource ;
356
357
358(*
359 CloseSource - closes the current open file.
360*)
361
362PROCEDURE CloseSource ;
363BEGIN
364 IF UseBufferedTokens
365 THEN
366 WHILE currenttoken#eoftok DO
367 GetToken
368 END
369 ELSE
370 (* a subsequent call to m2flex.OpenSource will really close the file *)
371 END
372END CloseSource ;
373
374
375(*
376 ResetForNewPass - reset the buffer pointers to the beginning ready for
377 a new pass
378*)
379
380PROCEDURE ResetForNewPass ;
381BEGIN
fd948137 382 InsertionIndex := 0 ;
7401123f
GM
383 CurrentTokNo := InitialSourceToken ;
384 UseBufferedTokens := TRUE
385END ResetForNewPass ;
386
387
388(*
fd948137 389 DisplayToken - display the token name using printf0 no newline is emitted.
7401123f
GM
390*)
391
392PROCEDURE DisplayToken (tok: toktype) ;
393BEGIN
394 CASE tok OF
395
fd948137
GM
396 eoftok: printf0('eoftok') |
397 plustok: printf0('plustok') |
398 minustok: printf0('minustok') |
399 timestok: printf0('timestok') |
400 dividetok: printf0('dividetok') |
401 becomestok: printf0('becomestok') |
402 ambersandtok: printf0('ambersandtok') |
403 periodtok: printf0('periodtok') |
404 commatok: printf0('commatok') |
405 semicolontok: printf0('semicolontok') |
406 lparatok: printf0('lparatok') |
407 rparatok: printf0('rparatok') |
408 lsbratok: printf0('lsbratok') |
409 rsbratok: printf0('rsbratok') |
410 lcbratok: printf0('lcbratok') |
411 rcbratok: printf0('rcbratok') |
412 uparrowtok: printf0('uparrowtok') |
413 singlequotetok: printf0('singlequotetok') |
414 equaltok: printf0('equaltok') |
415 hashtok: printf0('hashtok') |
416 lesstok: printf0('lesstok') |
417 greatertok: printf0('greatertok') |
418 lessgreatertok: printf0('lessgreatertok') |
419 lessequaltok: printf0('lessequaltok') |
420 greaterequaltok: printf0('greaterequaltok') |
421 periodperiodtok: printf0('periodperiodtok') |
422 colontok: printf0('colontok') |
423 doublequotestok: printf0('doublequotestok') |
424 bartok: printf0('bartok') |
425 andtok: printf0('andtok') |
426 arraytok: printf0('arraytok') |
427 begintok: printf0('begintok') |
428 bytok: printf0('bytok') |
429 casetok: printf0('casetok') |
430 consttok: printf0('consttok') |
431 definitiontok: printf0('definitiontok') |
432 divtok: printf0('divtok') |
433 dotok: printf0('dotok') |
434 elsetok: printf0('elsetok') |
435 elsiftok: printf0('elsiftok') |
436 endtok: printf0('endtok') |
437 exittok: printf0('exittok') |
438 exporttok: printf0('exporttok') |
439 fortok: printf0('fortok') |
440 fromtok: printf0('fromtok') |
441 iftok: printf0('iftok') |
442 implementationtok: printf0('implementationtok') |
443 importtok: printf0('importtok') |
444 intok: printf0('intok') |
445 looptok: printf0('looptok') |
446 modtok: printf0('modtok') |
447 moduletok: printf0('moduletok') |
448 nottok: printf0('nottok') |
449 oftok: printf0('oftok') |
450 ortok: printf0('ortok') |
451 pointertok: printf0('pointertok') |
452 proceduretok: printf0('proceduretok') |
453 qualifiedtok: printf0('qualifiedtok') |
454 unqualifiedtok: printf0('unqualifiedtok') |
455 recordtok: printf0('recordtok') |
456 repeattok: printf0('repeattok') |
457 returntok: printf0('returntok') |
458 settok: printf0('settok') |
459 thentok: printf0('thentok') |
460 totok: printf0('totok') |
461 typetok: printf0('typetok') |
462 untiltok: printf0('untiltok') |
463 vartok: printf0('vartok') |
464 whiletok: printf0('whiletok') |
465 withtok: printf0('withtok') |
466 asmtok: printf0('asmtok') |
467 volatiletok: printf0('volatiletok') |
468 periodperiodperiodtok: printf0('periodperiodperiodtok') |
469 datetok: printf0('datetok') |
470 linetok: printf0('linetok') |
471 filetok: printf0('filetok') |
472 integertok: printf0('integertok') |
473 identtok: printf0('identtok') |
474 realtok: printf0('realtok') |
475 stringtok: printf0('stringtok')
7401123f
GM
476
477 ELSE
478 END
479END DisplayToken ;
480
481
482(*
483 UpdateFromBucket - updates the global variables: currenttoken,
484 currentstring, currentcolumn and currentinteger
485 from TokenBucket, b, and, offset.
486*)
487
488PROCEDURE UpdateFromBucket (b: TokenBucket; offset: CARDINAL) ;
489BEGIN
fd948137
GM
490 IF InsertionIndex > 0
491 THEN
492 (* we have an inserted token to use. *)
493 Assert (b^.buf[offset].insert # NIL) ;
494 WITH b^.buf[offset].insert^.buf[InsertionIndex] DO
495 currenttoken := token ;
496 currentstring := KeyToCharStar(str) ;
497 currentcolumn := col ;
498 currentinteger := int ;
499 IF Debugging
500 THEN
501 printf3('line %d (# %d %d) ', line, offset, CurrentTokNo)
502 END
503 END ;
504 INC (InsertionIndex) ;
505 IF InsertionIndex = b^.buf[offset].insert^.len
7401123f 506 THEN
fd948137
GM
507 InsertionIndex := 0 ; (* finished consuming the inserted tokens. *)
508 INC (CurrentTokNo)
509 END
510 ELSIF (b^.buf[offset].insert # NIL) AND (InsertionIndex = 0)
511 THEN
512 (* this source token has extra tokens appended after it by the error recovery. *)
513 Assert (b^.buf[offset].insert^.len > 0) ; (* we must have at least one token. *)
514 InsertionIndex := 1 ; (* so set the index ready for the next UpdateFromBucket. *)
515 (* and read the original token. *)
516 WITH b^.buf[offset] DO
517 currenttoken := token ;
518 currentstring := KeyToCharStar(str) ;
519 currentcolumn := col ;
520 currentinteger := int ;
521 IF Debugging
522 THEN
523 printf3('line %d (# %d %d) ', line, offset, CurrentTokNo)
524 END
7401123f 525 END
fd948137
GM
526 ELSE
527 (* no inserted tokens after this token so read it and move on. *)
528 WITH b^.buf[offset] DO
529 currenttoken := token ;
530 currentstring := KeyToCharStar(str) ;
531 currentcolumn := col ;
532 currentinteger := int ;
533 IF Debugging
534 THEN
535 printf3('line %d (# %d %d) ', line, offset, CurrentTokNo)
536 END
537 END ;
538 INC (CurrentTokNo)
7401123f
GM
539 END
540END UpdateFromBucket ;
541
542
fd948137
GM
543(*
544 DisplayTokenEntry -
545*)
546
547PROCEDURE DisplayTokenEntry (topBucket: TokenBucket; index, total: CARDINAL) ;
548VAR
549 i: CARDINAL ;
550BEGIN
551 printf1 ("%d: ", total) ;
552 DisplayToken (topBucket^.buf[index].token) ;
553 printf1 (" %a ", topBucket^.buf[index].str) ;
554 IF total = GetTokenNo ()
555 THEN
556 printf0 (" <- current token")
557 END ;
558 printf0 ("\n") ;
559 (* now check for inserted tokens. *)
560 IF topBucket^.buf[index].insert # NIL
561 THEN
562 i := 1 ;
563 WHILE i < topBucket^.buf[index].insert^.len DO
564 printf1 (" %d: ", i) ;
565 DisplayToken (topBucket^.buf[index].insert^.buf[i].token) ;
566 printf1 (" %a\n", topBucket^.buf[index].insert^.buf[i].str) ;
567 INC (i)
568 END
569 END
570END DisplayTokenEntry ;
571
572
573(*
574 DumpTokens - developer debugging aid.
575*)
576
577PROCEDURE DumpTokens ;
578VAR
579 tb : TokenBucket ;
580 i,
581 tokenNo,
582 total,
583 length : CARDINAL ;
584BEGIN
585 tokenNo := GetTokenNo () ;
586 tb := ListOfTokens.head ;
587 total := 0 ;
588 WHILE tb # NIL DO
589 length := tb^.len ;
590 i := 0 ;
591 WHILE i < length DO
592 DisplayTokenEntry (tb, i, total) ;
593 INC (i) ;
594 INC (total)
595 END ;
596 tb := tb^.next
597 END ;
598 printf2 ("%d: tokenNo, %d: total\n", tokenNo, total) ;
599 IF (total # 0) AND (tokenNo = total)
600 THEN
601 printf1 ("%d: end of buffer ", total) ;
602 printf0 (" <- current token") ;
603 printf0 ("\n") ;
604 END ;
605END DumpTokens ;
606
607
7401123f
GM
608(*
609 GetToken - gets the next token into currenttoken.
610*)
611
612PROCEDURE GetToken ;
613VAR
614 t: CARDINAL ;
615 b: TokenBucket ;
616BEGIN
617 IF UseBufferedTokens
618 THEN
619 t := CurrentTokNo ;
620 b := FindTokenBucket(t) ;
fd948137 621 UpdateFromBucket (b, t)
7401123f
GM
622 ELSE
623 IF ListOfTokens.tail=NIL
624 THEN
625 m2flex.GetToken () ;
626 IF ListOfTokens.tail=NIL
627 THEN
628 HALT
629 END
630 END ;
631 IF CurrentTokNo>=ListOfTokens.LastBucketOffset
632 THEN
633 (* CurrentTokNo is in the last bucket or needs to be read *)
634 IF CurrentTokNo-ListOfTokens.LastBucketOffset<ListOfTokens.tail^.len
635 THEN
fd948137
GM
636 UpdateFromBucket (ListOfTokens.tail,
637 CurrentTokNo-ListOfTokens.LastBucketOffset)
7401123f
GM
638 ELSE
639 (* call the lexical phase to place a new token into the last bucket *)
640 m2flex.GetToken () ;
641 GetToken ; (* and call ourselves again to collect the token from bucket *)
642 RETURN
643 END
644 ELSE
645 t := CurrentTokNo ;
646 b := FindTokenBucket (t) ;
647 UpdateFromBucket (b, t)
648 END
fd948137 649 END
7401123f
GM
650END GetToken ;
651
652
653(*
654 SyncOpenWithBuffer - synchronise the buffer with the start of a file.
655 Skips all the tokens to do with the previous file.
656*)
657
658PROCEDURE SyncOpenWithBuffer ;
659BEGIN
660 IF ListOfTokens.tail#NIL
661 THEN
662 WITH ListOfTokens.tail^ DO
663 CurrentTokNo := ListOfTokens.LastBucketOffset+len
664 END
665 END
666END SyncOpenWithBuffer ;
667
668
fd948137
GM
669(*
670 GetInsertBucket - returns the insertion bucket associated with token count
671 and the topBucket. It creates a new TokenBucket if necessary.
672*)
673
674PROCEDURE GetInsertBucket (topBucket: TokenBucket; count: CARDINAL) : TokenBucket ;
675BEGIN
676 IF topBucket^.buf[count].insert = NIL
677 THEN
678 NEW (topBucket^.buf[count].insert) ;
679 topBucket^.buf[count].insert^.buf[0] := topBucket^.buf[count] ;
680 topBucket^.buf[count].insert^.buf[0].insert := NIL ;
681 topBucket^.buf[count].insert^.len := 1 (* empty, slot 0 contains the original token for ease. *)
682 END ;
683 RETURN topBucket^.buf[count].insert
684END GetInsertBucket ;
685
686
687(*
688 AppendToken - appends desc to the end of the insertionBucket.
689*)
690
691PROCEDURE AppendToken (insertionBucket: TokenBucket; desc: TokenDesc) ;
692BEGIN
693 IF insertionBucket^.len < MaxBucketSize
694 THEN
695 insertionBucket^.buf[insertionBucket^.len] := desc ;
696 INC (insertionBucket^.len)
697 END
698END AppendToken ;
699
700
7401123f
GM
701(*
702 InsertToken - inserts a symbol, token, infront of the current token
703 ready for the next pass.
704*)
705
706PROCEDURE InsertToken (token: toktype) ;
fd948137
GM
707VAR
708 topBucket, insertionBucket: TokenBucket ;
709 count : CARDINAL ;
710 desc : TokenDesc ;
7401123f 711BEGIN
fd948137
GM
712 Assert (ListOfTokens.tail # NIL) ;
713 count := GetTokenNo () -1 ;
714 topBucket := FindTokenBucket (count) ;
715 insertionBucket := GetInsertBucket (topBucket, count) ;
716 desc := topBucket^.buf[count] ;
717 desc.token := token ;
718 desc.insert := NIL ;
719 AppendToken (insertionBucket, desc) ;
720 IF DebugRecover
7401123f 721 THEN
fd948137 722 DumpTokens
7401123f
GM
723 END
724END InsertToken ;
725
726
727(*
728 InsertTokenAndRewind - inserts a symbol, token, infront of the current token
729 and then moves the token stream back onto the inserted token.
730*)
731
732PROCEDURE InsertTokenAndRewind (token: toktype) ;
fd948137
GM
733VAR
734 offset : CARDINAL ;
735 topBucket: TokenBucket ;
7401123f 736BEGIN
fd948137 737 IF GetTokenNo () > 0
7401123f 738 THEN
fd948137
GM
739 InsertToken (token) ;
740 offset := CurrentTokNo -2 ;
741 topBucket := FindTokenBucket (offset) ;
742 InsertionIndex := topBucket^.buf[offset].insert^.len -1 ;
743 DEC (CurrentTokNo, 2) ;
744 GetToken
7401123f
GM
745 END
746END InsertTokenAndRewind ;
747
748
749(*
750 GetPreviousTokenLineNo - returns the line number of the previous token.
751*)
752
753PROCEDURE GetPreviousTokenLineNo () : CARDINAL ;
754BEGIN
755 (*
756 IF GetTokenNo()>0
757 THEN
758 RETURN( TokenToLineNo(GetTokenNo()-1, 0) )
759 ELSE
760 RETURN( 0 )
761 END
762 *)
fd948137 763 RETURN GetLineNo ()
7401123f
GM
764END GetPreviousTokenLineNo ;
765
766
767(*
768 GetLineNo - returns the current line number where the symbol occurs in
769 the source file.
770*)
771
772PROCEDURE GetLineNo () : CARDINAL ;
773BEGIN
fd948137 774 IF CurrentTokNo = 0
7401123f 775 THEN
fd948137 776 RETURN 0
7401123f 777 ELSE
fd948137 778 RETURN TokenToLineNo (GetTokenNo (), 0)
7401123f
GM
779 END
780END GetLineNo ;
781
782
783(*
784 GetColumnNo - returns the current column where the symbol occurs in
785 the source file.
786*)
787
788PROCEDURE GetColumnNo () : CARDINAL ;
789BEGIN
fd948137 790 IF CurrentTokNo = 0
7401123f 791 THEN
fd948137 792 RETURN 0
7401123f 793 ELSE
fd948137 794 RETURN TokenToColumnNo (GetTokenNo (), 0)
7401123f
GM
795 END
796END GetColumnNo ;
797
798
799(*
800 GetTokenNo - returns the current token number.
801*)
802
803PROCEDURE GetTokenNo () : CARDINAL ;
804BEGIN
fd948137 805 IF CurrentTokNo = 0
7401123f
GM
806 THEN
807 RETURN 0
808 ELSE
809 RETURN CurrentTokNo-1
810 END
811END GetTokenNo ;
812
813
814(*
815 GetTokenName - returns the token name given the tokenno.
816*)
817
818PROCEDURE GetTokenName (tokenno: CARDINAL) : Name ;
819VAR
820 b: TokenBucket ;
821 n: Name ;
822BEGIN
fd948137 823 b := FindTokenBucket (tokenno) ;
7401123f
GM
824 IF b=NIL
825 THEN
826 RETURN NulName
827 ELSE
828 WITH b^.buf[tokenno] DO
829 n := tokToTok (token) ;
830 IF n=NulName
831 THEN
832 RETURN str
833 ELSE
834 RETURN n
835 END
836 END
837 END
838END GetTokenName ;
839
840
841(*
842 FindTokenBucket - returns the TokenBucket corresponding to the TokenNo.
843*)
844
845PROCEDURE FindTokenBucket (VAR TokenNo: CARDINAL) : TokenBucket ;
846VAR
847 b: TokenBucket ;
848BEGIN
849 b := ListOfTokens.head ;
850 WHILE b#NIL DO
851 WITH b^ DO
852 IF TokenNo<len
853 THEN
854 RETURN b
855 ELSE
fd948137 856 DEC (TokenNo, len)
7401123f
GM
857 END
858 END ;
859 b := b^.next
860 END ;
fd948137 861 RETURN NIL
7401123f
GM
862END FindTokenBucket ;
863
864
865(*
866 TokenToLineNo - returns the line number of the current file for the
867 TokenNo. The depth refers to the include depth.
868 A depth of 0 is the current file, depth of 1 is the file
869 which included the current file. Zero is returned if the
870 depth exceeds the file nesting level.
871*)
872
873PROCEDURE TokenToLineNo (TokenNo: CARDINAL; depth: CARDINAL) : CARDINAL ;
874VAR
875 b: TokenBucket ;
876 l: SourceList ;
877BEGIN
878 IF (TokenNo = UnknownTokenNo) OR (TokenNo = BuiltinTokenNo)
879 THEN
880 RETURN 0
881 ELSE
fd948137
GM
882 b := FindTokenBucket (TokenNo) ;
883 IF b = NIL
7401123f 884 THEN
fd948137 885 RETURN 0
7401123f 886 ELSE
fd948137 887 IF depth = 0
7401123f 888 THEN
fd948137 889 RETURN b^.buf[TokenNo].line
7401123f
GM
890 ELSE
891 l := b^.buf[TokenNo].file^.left ;
892 WHILE depth>0 DO
893 l := l^.left ;
894 IF l=b^.buf[TokenNo].file^.left
895 THEN
896 RETURN 0
897 END ;
fd948137 898 DEC (depth)
7401123f
GM
899 END ;
900 RETURN l^.line
901 END
902 END
903 END
904END TokenToLineNo ;
905
906
907(*
908 TokenToColumnNo - returns the column number of the current file for the
909 TokenNo. The depth refers to the include depth.
910 A depth of 0 is the current file, depth of 1 is the file
911 which included the current file. Zero is returned if the
912 depth exceeds the file nesting level.
913*)
914
915PROCEDURE TokenToColumnNo (TokenNo: CARDINAL; depth: CARDINAL) : CARDINAL ;
916VAR
917 b: TokenBucket ;
918 l: SourceList ;
919BEGIN
920 IF (TokenNo = UnknownTokenNo) OR (TokenNo = BuiltinTokenNo)
921 THEN
922 RETURN 0
923 ELSE
fd948137 924 b := FindTokenBucket (TokenNo) ;
7401123f
GM
925 IF b=NIL
926 THEN
927 RETURN 0
928 ELSE
fd948137 929 IF depth = 0
7401123f 930 THEN
fd948137 931 RETURN b^.buf[TokenNo].col
7401123f
GM
932 ELSE
933 l := b^.buf[TokenNo].file^.left ;
934 WHILE depth>0 DO
935 l := l^.left ;
936 IF l=b^.buf[TokenNo].file^.left
937 THEN
938 RETURN 0
939 END ;
fd948137 940 DEC (depth)
7401123f
GM
941 END ;
942 RETURN l^.col
943 END
944 END
945 END
946END TokenToColumnNo ;
947
948
949(*
950 TokenToLocation - returns the location_t corresponding to, TokenNo.
951*)
952
953PROCEDURE TokenToLocation (TokenNo: CARDINAL) : location_t ;
954VAR
955 b: TokenBucket ;
956BEGIN
957 IF TokenNo = UnknownTokenNo
958 THEN
959 RETURN UnknownLocation ()
960 ELSIF TokenNo = BuiltinTokenNo
961 THEN
962 RETURN BuiltinsLocation ()
963 ELSE
fd948137 964 b := FindTokenBucket (TokenNo) ;
7401123f
GM
965 IF b=NIL
966 THEN
967 RETURN UnknownLocation ()
968 ELSE
fd948137 969 RETURN b^.buf[TokenNo].loc
7401123f
GM
970 END
971 END
972END TokenToLocation ;
973
974
975(*
976 FindFileNameFromToken - returns the complete FileName for the appropriate
977 source file yields the token number, TokenNo.
978 The, Depth, indicates the include level: 0..n
979 Level 0 is the current. NIL is returned if n+1
980 is requested.
981*)
982
983PROCEDURE FindFileNameFromToken (TokenNo: CARDINAL; depth: CARDINAL) : String ;
984VAR
985 b: TokenBucket ;
986 l: SourceList ;
987BEGIN
fd948137 988 b := FindTokenBucket (TokenNo) ;
7401123f
GM
989 IF b=NIL
990 THEN
991 RETURN NIL
992 ELSE
993 IF TokenNo = UnknownTokenNo
994 THEN
995 RETURN NIL
996 ELSIF TokenNo = BuiltinTokenNo
997 THEN
998 RETURN NIL
999 ELSE
1000 l := b^.buf[TokenNo].file^.left ;
1001 WHILE depth>0 DO
1002 l := l^.left ;
1003 IF l=b^.buf[TokenNo].file^.left
1004 THEN
fd948137 1005 RETURN NIL
7401123f 1006 END ;
fd948137 1007 DEC (depth)
7401123f 1008 END ;
fd948137 1009 RETURN l^.name
7401123f
GM
1010 END
1011 END
1012END FindFileNameFromToken ;
1013
1014
1015(*
1016 GetFileName - returns a String defining the current file.
1017*)
1018
1019PROCEDURE GetFileName () : String ;
1020BEGIN
1021 RETURN FindFileNameFromToken (GetTokenNo (), 0)
1022END GetFileName ;
1023
1024
7401123f
GM
1025(*
1026 AddTokToList - adds a token to a dynamic list.
1027*)
1028
1029PROCEDURE AddTokToList (t: toktype; n: Name;
1030 i: INTEGER; l: CARDINAL; c: CARDINAL;
1031 f: SourceList; location: location_t) ;
1032BEGIN
1033 IF ListOfTokens.head=NIL
1034 THEN
fd948137 1035 NEW (ListOfTokens.head) ;
7401123f
GM
1036 IF ListOfTokens.head=NIL
1037 THEN
1038 (* list error *)
1039 END ;
1040 ListOfTokens.tail := ListOfTokens.head ;
1041 ListOfTokens.tail^.len := 0
1042 ELSIF ListOfTokens.tail^.len=MaxBucketSize
1043 THEN
1044 Assert(ListOfTokens.tail^.next=NIL) ;
fd948137 1045 NEW (ListOfTokens.tail^.next) ;
7401123f
GM
1046 IF ListOfTokens.tail^.next=NIL
1047 THEN
1048 (* list error *)
1049 ELSE
1050 ListOfTokens.tail := ListOfTokens.tail^.next ;
1051 ListOfTokens.tail^.len := 0
1052 END ;
fd948137 1053 INC (ListOfTokens.LastBucketOffset, MaxBucketSize)
7401123f
GM
1054 END ;
1055 WITH ListOfTokens.tail^ DO
1056 next := NIL ;
1057 WITH buf[len] DO
fd948137
GM
1058 token := t ;
1059 str := n ;
1060 int := i ;
1061 line := l ;
1062 col := c ;
1063 file := f ;
1064 loc := location ;
1065 insert := NIL ;
7401123f 1066 END ;
fd948137 1067 INC (len)
7401123f
GM
1068 END
1069END AddTokToList ;
1070
1071
1072(*
1073 IsLastTokenEof - returns TRUE if the last token was an eoftok
1074*)
1075
1076PROCEDURE IsLastTokenEof () : BOOLEAN ;
1077VAR
1078 b: TokenBucket ;
1079BEGIN
1080 IF ListOfTokens.tail#NIL
1081 THEN
1082 IF ListOfTokens.tail^.len=0
1083 THEN
1084 b := ListOfTokens.head ;
1085 IF b=ListOfTokens.tail
1086 THEN
1087 RETURN FALSE
1088 END ;
1089 WHILE b^.next#ListOfTokens.tail DO
1090 b := b^.next
1091 END ;
1092 ELSE
1093 b := ListOfTokens.tail
1094 END ;
1095 WITH b^ DO
1096 Assert (len>0) ; (* len should always be >0 *)
1097 RETURN buf[len-1].token=eoftok
1098 END
1099 END ;
1100 RETURN FALSE
1101END IsLastTokenEof ;
1102
1103
1104(*
1105 PrintTokenNo - displays token and the location of the token.
1106*)
1107
1108PROCEDURE PrintTokenNo (tokenno: CARDINAL) ;
1109VAR
1110 s: String ;
1111BEGIN
1112 printf1 ("tokenno = %d, ", tokenno) ;
1113 s := InitStringCharStar (KeyToCharStar (GetTokenName (tokenno))) ;
1114 printf1 ("%s\n", s) ;
1115 s := KillString (s)
1116END PrintTokenNo ;
1117
1118
1119(*
1120 isSrcToken -
1121*)
1122
1123PROCEDURE isSrcToken (tokenno: CARDINAL) : BOOLEAN ;
1124BEGIN
1125 RETURN (tokenno # UnknownTokenNo) AND (tokenno # BuiltinTokenNo)
1126END isSrcToken ;
1127
1128
1129(*
1130 MakeVirtualTok - providing caret, left, right are associated with a source file
1131 and exist on the same src line then
1132 create and return a new tokenno which is created from
1133 tokenno range1 and range2. Otherwise return caret.
1134*)
1135
1136PROCEDURE MakeVirtualTok (caret, left, right: CARDINAL) : CARDINAL ;
1137VAR
1138 bufLeft, bufRight: TokenBucket ;
1139 lc, ll, lr : location_t ;
1140BEGIN
1141 IF FALSE
1142 THEN
1143 RETURN caret
1144 END ;
1145 IF isSrcToken (caret) AND isSrcToken (left) AND isSrcToken (right)
1146 THEN
1147 lc := TokenToLocation (caret) ;
1148 ll := TokenToLocation (left) ;
1149 lr := TokenToLocation (right) ;
1150 bufLeft := FindTokenBucket (left) ; (* left maybe changed now. *)
1151 bufRight := FindTokenBucket (right) ; (* right maybe changed now. *)
1152
1153 IF (bufLeft^.buf[left].line = bufRight^.buf[right].line) AND
1154 (bufLeft^.buf[left].file = bufRight^.buf[right].file)
1155 THEN
1156 (* on the same line, create a new token and location. *)
1157 AddTokToList (virtualrangetok, NulName, 0,
1158 bufLeft^.buf[left].line, bufLeft^.buf[left].col, bufLeft^.buf[left].file,
1159 GetLocationBinary (lc, ll, lr)) ;
7401123f
GM
1160 RETURN ListOfTokens.LastBucketOffset + ListOfTokens.tail^.len - 1
1161 END
1162 END ;
1163 RETURN caret
1164END MakeVirtualTok ;
1165
1166
1167(* ***********************************************************************
1168 *
1169 * These functions allow m2.flex to deliver tokens into the buffer
1170 *
1171 ************************************************************************* *)
1172
1173(*
1174 AddTok - adds a token to the buffer.
1175*)
1176
1177PROCEDURE AddTok (t: toktype) ;
1178VAR
1179 s: String ;
1180BEGIN
1181 IF NOT ((t=eoftok) AND IsLastTokenEof())
1182 THEN
1183 AddTokToList(t, NulName, 0,
1184 m2flex.GetLineNo(), m2flex.GetColumnNo(), CurrentSource,
1185 m2flex.GetLocation()) ;
1186 CurrentUsed := TRUE ;
1187 IF Debugging
1188 THEN
1189 (* display each token as a warning. *)
1190 s := InitStringCharStar (KeyToCharStar (GetTokenName (GetTokenNo ()))) ;
1191 WarnStringAt (s, GetTokenNo ())
1192 END
1193 END
1194END AddTok ;
1195
1196
1197(*
1198 AddTokCharStar - adds a token to the buffer and an additional string, s.
1199 A copy of string, s, is made.
1200*)
1201
1202PROCEDURE AddTokCharStar (t: toktype; s: ADDRESS) ;
1203BEGIN
7401123f
GM
1204 AddTokToList(t, makekey(s), 0, m2flex.GetLineNo(),
1205 m2flex.GetColumnNo(), CurrentSource, m2flex.GetLocation()) ;
1206 CurrentUsed := TRUE
1207END AddTokCharStar ;
1208
1209
1210(*
1211 AddTokInteger - adds a token and an integer to the buffer.
1212*)
1213
1214PROCEDURE AddTokInteger (t: toktype; i: INTEGER) ;
1215VAR
1216 s: String ;
1217 c,
1218 l: CARDINAL ;
1219BEGIN
1220 l := m2flex.GetLineNo() ;
1221 c := m2flex.GetColumnNo() ;
1222 s := Sprintf1(Mark(InitString('%d')), i) ;
1223 AddTokToList(t, makekey(string(s)), i, l, c, CurrentSource, m2flex.GetLocation()) ;
1224 s := KillString(s) ;
1225 CurrentUsed := TRUE
1226END AddTokInteger ;
1227
1228
1229BEGIN
1230 Init
1231END M2LexBuf.
This page took 0.205654 seconds and 5 git commands to generate.