* config.gcc <arm>: Add --with-abi=
[official-gcc.git] / gcc / f / stt.c
blobe616d492289a99da41bc11b7edd8caccc30c93de
1 /* stt.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1997, 2003 Free Software Foundation, Inc.
3 Contributed by James Craig Burley.
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
22 Related Modules:
23 None
25 Description:
26 Manages lists of tokens and related info for parsing.
28 Modifications:
31 /* Include files. */
33 #include "proj.h"
34 #include "stt.h"
35 #include "bld.h"
36 #include "expr.h"
37 #include "info.h"
38 #include "lex.h"
39 #include "malloc.h"
40 #include "sta.h"
41 #include "stp.h"
43 /* Externals defined here. */
46 /* Simple definitions and enumerations. */
49 /* Internal typedefs. */
52 /* Private include files. */
55 /* Internal structure definitions. */
58 /* Static objects accessed by functions in this module. */
61 /* Static functions (internal). */
64 /* Internal macros. */
67 /* ffestt_caselist_append -- Append case to list of cases
69 ffesttCaseList list;
70 ffelexToken t;
71 ffestt_caselist_append(list,range,case1,case2,t);
73 list must have already been created by ffestt_caselist_create. The
74 list is allocated out of the scratch pool. The token is consumed. */
76 void
77 ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1,
78 ffebld case2, ffelexToken t)
80 ffesttCaseList new;
82 new = malloc_new_kp (ffesta_scratch_pool, "FFEST case list", sizeof (*new));
83 new->next = list->previous->next;
84 new->previous = list->previous;
85 new->next->previous = new;
86 new->previous->next = new;
87 new->expr1 = case1;
88 new->expr2 = case2;
89 new->range = range;
90 new->t = t;
93 /* ffestt_caselist_create -- Create new list of cases
95 ffesttCaseList list;
96 list = ffestt_caselist_create();
98 The list is allocated out of the scratch pool. */
100 ffesttCaseList
101 ffestt_caselist_create (void)
103 ffesttCaseList new;
105 new = malloc_new_kp (ffesta_scratch_pool, "FFEST case list root",
106 sizeof (*new));
107 new->next = new->previous = new;
108 new->t = NULL;
109 new->expr1 = NULL;
110 new->expr2 = NULL;
111 new->range = FALSE;
112 return new;
115 /* ffestt_caselist_kill -- Kill list of cases
117 ffesttCaseList list;
118 ffestt_caselist_kill(list);
120 The tokens on the list are killed.
122 02-Mar-90 JCB 1.1
123 Don't kill the list itself or change it, since it will be trashed when
124 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
126 void
127 ffestt_caselist_kill (ffesttCaseList list)
129 ffesttCaseList next;
131 for (next = list->next; next != list; next = next->next)
133 ffelex_token_kill (next->t);
137 /* ffestt_dimlist_append -- Append dim to list of dims
139 ffesttDimList list;
140 ffelexToken t;
141 ffestt_dimlist_append(list,lower,upper,t);
143 list must have already been created by ffestt_dimlist_create. The
144 list is allocated out of the scratch pool. The token is consumed. */
146 void
147 ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper,
148 ffelexToken t)
150 ffesttDimList new;
152 new = malloc_new_kp (ffesta_scratch_pool, "FFEST dim list", sizeof (*new));
153 new->next = list->previous->next;
154 new->previous = list->previous;
155 new->next->previous = new;
156 new->previous->next = new;
157 new->lower = lower;
158 new->upper = upper;
159 new->t = t;
162 /* Convert list of dims into ffebld format.
164 ffesttDimList list;
165 ffeinfoRank rank;
166 ffebld array_size;
167 ffebld extents;
168 ffestt_dimlist_as_expr (list, &rank, &array_size, &extents);
170 The dims in the list are converted to a list of ITEMs; the rank of the
171 array, an expression representing the array size, a list of extent
172 expressions, and the list of ITEMs are returned.
174 If is_ugly_assumed, treat a final dimension with no lower bound
175 and an upper bound of 1 as a * bound. */
177 ffebld
178 ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank,
179 ffebld *array_size, ffebld *extents,
180 bool is_ugly_assumed)
182 ffesttDimList next;
183 ffebld expr;
184 ffebld as;
185 ffebld ex; /* List of extents. */
186 ffebld ext; /* Extent of a given dimension. */
187 ffebldListBottom bottom;
188 ffeinfoRank r;
189 ffeinfoKindtype nkt;
190 ffetargetIntegerDefault low;
191 ffetargetIntegerDefault high;
192 bool zero = FALSE; /* Zero-size array. */
193 bool any = FALSE;
194 bool star = FALSE; /* Adjustable array. */
196 assert (list != NULL);
198 r = 0;
199 ffebld_init_list (&expr, &bottom);
200 for (next = list->next; next != list; next = next->next)
202 ++r;
203 if (((next->lower == NULL)
204 || (ffebld_op (next->lower) == FFEBLD_opCONTER))
205 && (ffebld_op (next->upper) == FFEBLD_opCONTER))
207 if (next->lower == NULL)
208 low = 1;
209 else
210 low = ffebld_constant_integerdefault (ffebld_conter (next->lower));
211 high = ffebld_constant_integerdefault (ffebld_conter (next->upper));
212 if (low
213 > high)
214 zero = TRUE;
215 if ((next->next == list)
216 && is_ugly_assumed
217 && (next->lower == NULL)
218 && (high == 1)
219 && (ffebld_conter_orig (next->upper) == NULL))
221 star = TRUE;
222 ffebld_append_item (&bottom,
223 ffebld_new_bounds (NULL, ffebld_new_star ()));
224 continue;
227 else if (((next->lower != NULL)
228 && (ffebld_op (next->lower) == FFEBLD_opANY))
229 || (ffebld_op (next->upper) == FFEBLD_opANY))
230 any = TRUE;
231 else if (ffebld_op (next->upper) == FFEBLD_opSTAR)
232 star = TRUE;
233 ffebld_append_item (&bottom,
234 ffebld_new_bounds (next->lower, next->upper));
236 ffebld_end_list (&bottom);
238 if (zero)
240 as = ffebld_new_conter (ffebld_constant_new_integerdefault_val (0));
241 ffebld_set_info (as, ffeinfo_new
242 (FFEINFO_basictypeINTEGER,
243 FFEINFO_kindtypeINTEGERDEFAULT,
245 FFEINFO_kindENTITY,
246 FFEINFO_whereCONSTANT,
247 FFETARGET_charactersizeNONE));
248 ex = NULL;
250 else if (any)
252 as = ffebld_new_any ();
253 ffebld_set_info (as, ffeinfo_new_any ());
254 ex = ffebld_copy (as);
256 else if (star)
258 as = ffebld_new_star ();
259 ex = ffebld_new_star (); /* ~~Should really be list as below. */
261 else
263 as = NULL;
264 ffebld_init_list (&ex, &bottom);
265 for (next = list->next; next != list; next = next->next)
267 if ((next->lower == NULL)
268 || ((ffebld_op (next->lower) == FFEBLD_opCONTER)
269 && (ffebld_constant_integerdefault (ffebld_conter
270 (next->lower)) == 1)))
271 ext = ffebld_copy (next->upper);
272 else
274 ext = ffebld_new_subtract (next->upper, next->lower);
276 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
277 ffeinfo_kindtype (ffebld_info
278 (next->lower)),
279 ffeinfo_kindtype (ffebld_info
280 (next->upper)));
281 ffebld_set_info (ext,
282 ffeinfo_new (FFEINFO_basictypeINTEGER,
283 nkt,
285 FFEINFO_kindENTITY,
286 ((ffebld_op (ffebld_left (ext))
287 == FFEBLD_opCONTER)
288 && (ffebld_op (ffebld_right
289 (ext))
290 == FFEBLD_opCONTER))
291 ? FFEINFO_whereCONSTANT
292 : FFEINFO_whereFLEETING,
293 FFETARGET_charactersizeNONE));
294 ffebld_set_left (ext,
295 ffeexpr_convert_expr (ffebld_left (ext),
296 next->t, ext, next->t,
297 FFEEXPR_contextLET));
298 ffebld_set_right (ext,
299 ffeexpr_convert_expr (ffebld_right (ext),
300 next->t, ext,
301 next->t,
302 FFEEXPR_contextLET));
303 ext = ffeexpr_collapse_subtract (ext, next->t);
306 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
307 ffeinfo_kindtype (ffebld_info (ext)),
308 FFEINFO_kindtypeINTEGERDEFAULT);
310 = ffebld_new_add (ext,
311 ffebld_new_conter
312 (ffebld_constant_new_integerdefault_val
313 (1)));
314 ffebld_set_info (ffebld_right (ext), ffeinfo_new
315 (FFEINFO_basictypeINTEGER,
316 FFEINFO_kindtypeINTEGERDEFAULT,
318 FFEINFO_kindENTITY,
319 FFEINFO_whereCONSTANT,
320 FFETARGET_charactersizeNONE));
321 ffebld_set_info (ext,
322 ffeinfo_new (FFEINFO_basictypeINTEGER,
323 nkt, 0, FFEINFO_kindENTITY,
324 (ffebld_op (ffebld_left (ext))
325 == FFEBLD_opCONTER)
326 ? FFEINFO_whereCONSTANT
327 : FFEINFO_whereFLEETING,
328 FFETARGET_charactersizeNONE));
329 ffebld_set_left (ext,
330 ffeexpr_convert_expr (ffebld_left (ext),
331 next->t, ext,
332 next->t,
333 FFEEXPR_contextLET));
334 ffebld_set_right (ext,
335 ffeexpr_convert_expr (ffebld_right (ext),
336 next->t, ext,
337 next->t,
338 FFEEXPR_contextLET));
339 ext = ffeexpr_collapse_add (ext, next->t);
341 ffebld_append_item (&bottom, ext);
342 if (as == NULL)
343 as = ext;
344 else
347 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
348 ffeinfo_kindtype (ffebld_info (as)),
349 ffeinfo_kindtype (ffebld_info (ext)));
350 as = ffebld_new_multiply (as, ext);
351 ffebld_set_info (as,
352 ffeinfo_new (FFEINFO_basictypeINTEGER,
353 nkt, 0, FFEINFO_kindENTITY,
354 ((ffebld_op (ffebld_left (as))
355 == FFEBLD_opCONTER)
356 && (ffebld_op (ffebld_right
357 (as))
358 == FFEBLD_opCONTER))
359 ? FFEINFO_whereCONSTANT
360 : FFEINFO_whereFLEETING,
361 FFETARGET_charactersizeNONE));
362 ffebld_set_left (as,
363 ffeexpr_convert_expr (ffebld_left (as),
364 next->t, as, next->t,
365 FFEEXPR_contextLET));
366 ffebld_set_right (as,
367 ffeexpr_convert_expr (ffebld_right (as),
368 next->t, as,
369 next->t,
370 FFEEXPR_contextLET));
371 as = ffeexpr_collapse_multiply (as, next->t);
374 ffebld_end_list (&bottom);
375 as = ffeexpr_convert (as, list->next->t, NULL,
376 FFEINFO_basictypeINTEGER,
377 FFEINFO_kindtypeINTEGERDEFAULT, 0,
378 FFETARGET_charactersizeNONE,
379 FFEEXPR_contextLET);
382 *rank = r;
383 *array_size = as;
384 *extents = ex;
385 return expr;
388 /* ffestt_dimlist_create -- Create new list of dims
390 ffesttDimList list;
391 list = ffestt_dimlist_create();
393 The list is allocated out of the scratch pool. */
395 ffesttDimList
396 ffestt_dimlist_create (void)
398 ffesttDimList new;
400 new = malloc_new_kp (ffesta_scratch_pool, "FFEST dim list root",
401 sizeof (*new));
402 new->next = new->previous = new;
403 new->t = NULL;
404 new->lower = NULL;
405 new->upper = NULL;
406 return new;
409 /* ffestt_dimlist_kill -- Kill list of dims
411 ffesttDimList list;
412 ffestt_dimlist_kill(list);
414 The tokens on the list are killed. */
416 void
417 ffestt_dimlist_kill (ffesttDimList list)
419 ffesttDimList next;
421 for (next = list->next; next != list; next = next->next)
423 ffelex_token_kill (next->t);
427 /* Determine type of list of dimensions.
429 Return KNOWN for all-constant bounds, ADJUSTABLE for constant
430 and variable but no * bounds, ASSUMED for constant and * but
431 not variable bounds, ADJUSTABLEASSUMED for constant and variable
432 and * bounds.
434 If is_ugly_assumed, treat a final dimension with no lower bound
435 and an upper bound of 1 as a * bound. */
437 ffestpDimtype
438 ffestt_dimlist_type (ffesttDimList list, bool is_ugly_assumed)
440 ffesttDimList next;
441 ffestpDimtype type;
443 if (list == NULL)
444 return FFESTP_dimtypeNONE;
446 type = FFESTP_dimtypeKNOWN;
447 for (next = list->next; next != list; next = next->next)
449 bool ugly_assumed = FALSE;
451 if ((next->next == list)
452 && is_ugly_assumed
453 && (next->lower == NULL)
454 && (next->upper != NULL)
455 && (ffebld_op (next->upper) == FFEBLD_opCONTER)
456 && (ffebld_constant_integerdefault (ffebld_conter (next->upper))
457 == 1)
458 && (ffebld_conter_orig (next->upper) == NULL))
459 ugly_assumed = TRUE;
461 if (next->lower != NULL)
463 if (ffebld_op (next->lower) != FFEBLD_opCONTER)
465 if (type == FFESTP_dimtypeASSUMED)
466 type = FFESTP_dimtypeADJUSTABLEASSUMED;
467 else
468 type = FFESTP_dimtypeADJUSTABLE;
471 if (next->upper != NULL)
473 if (ugly_assumed
474 || (ffebld_op (next->upper) == FFEBLD_opSTAR))
476 if (type == FFESTP_dimtypeADJUSTABLE)
477 type = FFESTP_dimtypeADJUSTABLEASSUMED;
478 else
479 type = FFESTP_dimtypeASSUMED;
481 else if (ffebld_op (next->upper) != FFEBLD_opCONTER)
482 type = FFESTP_dimtypeADJUSTABLE;
486 return type;
489 /* ffestt_exprlist_append -- Append expr to list of exprs
491 ffesttExprList list;
492 ffelexToken t;
493 ffestt_exprlist_append(list,expr,t);
495 list must have already been created by ffestt_exprlist_create. The
496 list is allocated out of the scratch pool. The token is consumed. */
498 void
499 ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t)
501 ffesttExprList new;
503 new = malloc_new_kp (ffesta_scratch_pool, "FFEST expr list", sizeof (*new));
504 new->next = list->previous->next;
505 new->previous = list->previous;
506 new->next->previous = new;
507 new->previous->next = new;
508 new->expr = expr;
509 new->t = t;
512 /* ffestt_exprlist_create -- Create new list of exprs
514 ffesttExprList list;
515 list = ffestt_exprlist_create();
517 The list is allocated out of the scratch pool. */
519 ffesttExprList
520 ffestt_exprlist_create (void)
522 ffesttExprList new;
524 new = malloc_new_kp (ffesta_scratch_pool, "FFEST expr list root",
525 sizeof (*new));
526 new->next = new->previous = new;
527 new->expr = NULL;
528 new->t = NULL;
529 return new;
532 /* ffestt_exprlist_drive -- Drive list of token pairs into function
534 ffesttExprList list;
535 void fn(ffebld expr,ffelexToken t);
536 ffestt_exprlist_drive(list,fn);
538 The expr/token pairs in the list are passed to the function one pair
539 at a time. */
541 void
542 ffestt_exprlist_drive (ffesttExprList list, void (*fn) (ffebld, ffelexToken))
544 ffesttExprList next;
546 if (list == NULL)
547 return;
549 for (next = list->next; next != list; next = next->next)
551 (*fn) (next->expr, next->t);
555 /* ffestt_exprlist_kill -- Kill list of exprs
557 ffesttExprList list;
558 ffestt_exprlist_kill(list);
560 The tokens on the list are killed.
562 02-Mar-90 JCB 1.1
563 Don't kill the list itself or change it, since it will be trashed when
564 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
566 void
567 ffestt_exprlist_kill (ffesttExprList list)
569 ffesttExprList next;
571 for (next = list->next; next != list; next = next->next)
573 ffelex_token_kill (next->t);
577 /* ffestt_formatlist_append -- Append null format to list of formats
579 ffesttFormatList list, new;
580 new = ffestt_formatlist_append(list);
582 list must have already been created by ffestt_formatlist_create. The
583 new item is allocated out of the scratch pool. The caller must initialize
584 it appropriately. */
586 ffesttFormatList
587 ffestt_formatlist_append (ffesttFormatList list)
589 ffesttFormatList new;
591 new = malloc_new_kp (ffesta_scratch_pool, "FFEST format list",
592 sizeof (*new));
593 new->next = list->previous->next;
594 new->previous = list->previous;
595 new->next->previous = new;
596 new->previous->next = new;
597 return new;
600 /* ffestt_formatlist_create -- Create new list of formats
602 ffesttFormatList list;
603 list = ffestt_formatlist_create(NULL);
605 The list is allocated out of the scratch pool. */
607 ffesttFormatList
608 ffestt_formatlist_create (ffesttFormatList parent, ffelexToken t)
610 ffesttFormatList new;
612 new = malloc_new_kp (ffesta_scratch_pool, "FFEST format list root",
613 sizeof (*new));
614 new->next = new->previous = new;
615 new->type = FFESTP_formattypeNone;
616 new->t = t;
617 new->u.root.parent = parent;
618 return new;
621 /* ffestt_formatlist_kill -- Kill tokens on list of formats
623 ffesttFormatList list;
624 ffestt_formatlist_kill(list);
626 The tokens on the list are killed. */
628 void
629 ffestt_formatlist_kill (ffesttFormatList list)
631 ffesttFormatList next;
633 /* Always kill from the very top on down. */
635 while (list->u.root.parent != NULL)
636 list = list->u.root.parent->next;
638 /* Kill first token for this list. */
640 if (list->t != NULL)
641 ffelex_token_kill (list->t);
643 /* Kill each item in this list. */
645 for (next = list->next; next != list; next = next->next)
647 ffelex_token_kill (next->t);
648 switch (next->type)
650 case FFESTP_formattypeI:
651 case FFESTP_formattypeB:
652 case FFESTP_formattypeO:
653 case FFESTP_formattypeZ:
654 case FFESTP_formattypeF:
655 case FFESTP_formattypeE:
656 case FFESTP_formattypeEN:
657 case FFESTP_formattypeG:
658 case FFESTP_formattypeL:
659 case FFESTP_formattypeA:
660 case FFESTP_formattypeD:
661 if (next->u.R1005.R1004.t != NULL)
662 ffelex_token_kill (next->u.R1005.R1004.t);
663 if (next->u.R1005.R1006.t != NULL)
664 ffelex_token_kill (next->u.R1005.R1006.t);
665 if (next->u.R1005.R1007_or_R1008.t != NULL)
666 ffelex_token_kill (next->u.R1005.R1007_or_R1008.t);
667 if (next->u.R1005.R1009.t != NULL)
668 ffelex_token_kill (next->u.R1005.R1009.t);
669 break;
671 case FFESTP_formattypeQ:
672 case FFESTP_formattypeDOLLAR:
673 case FFESTP_formattypeP:
674 case FFESTP_formattypeT:
675 case FFESTP_formattypeTL:
676 case FFESTP_formattypeTR:
677 case FFESTP_formattypeX:
678 case FFESTP_formattypeS:
679 case FFESTP_formattypeSP:
680 case FFESTP_formattypeSS:
681 case FFESTP_formattypeBN:
682 case FFESTP_formattypeBZ:
683 case FFESTP_formattypeSLASH:
684 case FFESTP_formattypeCOLON:
685 if (next->u.R1010.val.t != NULL)
686 ffelex_token_kill (next->u.R1010.val.t);
687 break;
689 case FFESTP_formattypeR1016:
690 break; /* Nothing more to do. */
692 case FFESTP_formattypeFORMAT:
693 if (next->u.R1003D.R1004.t != NULL)
694 ffelex_token_kill (next->u.R1003D.R1004.t);
695 next->u.R1003D.format->u.root.parent = NULL; /* Parent already dying. */
696 ffestt_formatlist_kill (next->u.R1003D.format);
697 break;
699 default:
700 assert (FALSE);
705 /* ffestt_implist_append -- Append token pair to list of token pairs
707 ffesttImpList list;
708 ffelexToken t;
709 ffestt_implist_append(list,start_token,end_token);
711 list must have already been created by ffestt_implist_create. The
712 list is allocated out of the scratch pool. The tokens are consumed. */
714 void
715 ffestt_implist_append (ffesttImpList list, ffelexToken first, ffelexToken last)
717 ffesttImpList new;
719 new = malloc_new_kp (ffesta_scratch_pool, "FFEST token list", sizeof (*new));
720 new->next = list->previous->next;
721 new->previous = list->previous;
722 new->next->previous = new;
723 new->previous->next = new;
724 new->first = first;
725 new->last = last;
728 /* ffestt_implist_create -- Create new list of token pairs
730 ffesttImpList list;
731 list = ffestt_implist_create();
733 The list is allocated out of the scratch pool. */
735 ffesttImpList
736 ffestt_implist_create (void)
738 ffesttImpList new;
740 new = malloc_new_kp (ffesta_scratch_pool, "FFEST token list root",
741 sizeof (*new));
742 new->next = new->previous = new;
743 new->first = NULL;
744 new->last = NULL;
745 return new;
748 /* ffestt_implist_drive -- Drive list of token pairs into function
750 ffesttImpList list;
751 void fn(ffelexToken first,ffelexToken last);
752 ffestt_implist_drive(list,fn);
754 The token pairs in the list are passed to the function one pair at a time. */
756 void
757 ffestt_implist_drive (ffesttImpList list, void (*fn) (ffelexToken, ffelexToken))
759 ffesttImpList next;
761 if (list == NULL)
762 return;
764 for (next = list->next; next != list; next = next->next)
766 (*fn) (next->first, next->last);
770 /* ffestt_implist_kill -- Kill list of token pairs
772 ffesttImpList list;
773 ffestt_implist_kill(list);
775 The tokens on the list are killed. */
777 void
778 ffestt_implist_kill (ffesttImpList list)
780 ffesttImpList next;
782 for (next = list->next; next != list; next = next->next)
784 ffelex_token_kill (next->first);
785 if (next->last != NULL)
786 ffelex_token_kill (next->last);
790 /* ffestt_tokenlist_append -- Append token to list of tokens
792 ffesttTokenList tl;
793 ffelexToken t;
794 ffestt_tokenlist_append(tl,t);
796 tl must have already been created by ffestt_tokenlist_create. The
797 list is allocated out of the scratch pool. The token is consumed. */
799 void
800 ffestt_tokenlist_append (ffesttTokenList tl, ffelexToken t)
802 ffesttTokenItem ti;
804 ti = malloc_new_kp (ffesta_scratch_pool, "FFEST token item", sizeof (*ti));
805 ti->next = (ffesttTokenItem) &tl->first;
806 ti->previous = tl->last;
807 ti->next->previous = ti;
808 ti->previous->next = ti;
809 ti->t = t;
810 ++tl->count;
813 /* ffestt_tokenlist_create -- Create new list of tokens
815 ffesttTokenList tl;
816 tl = ffestt_tokenlist_create();
818 The list is allocated out of the scratch pool. */
820 ffesttTokenList
821 ffestt_tokenlist_create (void)
823 ffesttTokenList tl;
825 tl = malloc_new_kp (ffesta_scratch_pool, "FFEST token list", sizeof (*tl));
826 tl->first = tl->last = (ffesttTokenItem) &tl->first;
827 tl->count = 0;
828 return tl;
831 /* ffestt_tokenlist_drive -- Drive list of tokens
833 ffesttTokenList tl;
834 void fn(ffelexToken t);
835 ffestt_tokenlist_drive(tl,fn);
837 The tokens in the list are passed to the given function. */
839 void
840 ffestt_tokenlist_drive (ffesttTokenList tl, void (*fn) (ffelexToken))
842 ffesttTokenItem ti;
844 if (tl == NULL)
845 return;
847 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
849 (*fn) (ti->t);
853 /* ffestt_tokenlist_handle -- Handle list of tokens
855 ffesttTokenList tl;
856 ffelexHandler handler;
857 handler = ffestt_tokenlist_handle(tl,handler);
859 The tokens in the list are passed to the handler(s). */
861 ffelexHandler
862 ffestt_tokenlist_handle (ffesttTokenList tl, ffelexHandler handler)
864 ffesttTokenItem ti;
866 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
867 handler = (ffelexHandler) (*handler) (ti->t);
869 return (ffelexHandler) handler;
872 /* ffestt_tokenlist_kill -- Kill list of tokens
874 ffesttTokenList tl;
875 ffestt_tokenlist_kill(tl);
877 The tokens on the list are killed.
879 02-Mar-90 JCB 1.1
880 Don't kill the list itself or change it, since it will be trashed when
881 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
883 void
884 ffestt_tokenlist_kill (ffesttTokenList tl)
886 ffesttTokenItem ti;
888 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
890 ffelex_token_kill (ti->t);