1 /* stt.c -- Implementation File (module.c template V1.0)
2 Copyright (C) 1995, 1997 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.ai.mit.edu).
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)
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
26 Manages lists of tokens and related info for parsing.
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
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. */
77 ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1,
78 ffebld case2, ffelexToken t)
82 new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool,
83 "FFEST case list", sizeof (*new));
84 new->next = list->previous->next;
85 new->previous = list->previous;
86 new->next->previous = new;
87 new->previous->next = new;
94 /* ffestt_caselist_create -- Create new list of cases
97 list = ffestt_caselist_create();
99 The list is allocated out of the scratch pool. */
102 ffestt_caselist_create ()
106 new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool,
107 "FFEST case list root",
109 new->next = new->previous = new;
117 /* ffestt_caselist_dump -- Dump list of cases
120 ffestt_caselist_dump(list);
122 The cases in the list are dumped with commas separating them. */
125 ffestt_caselist_dump (ffesttCaseList list)
129 for (next = list->next; next != list; next = next->next)
131 if (next != list->next)
133 if (next->expr1 != NULL)
134 ffebld_dump (next->expr1);
138 if (next->expr2 != NULL)
139 ffebld_dump (next->expr2);
144 /* ffestt_caselist_kill -- Kill list of cases
147 ffestt_caselist_kill(list);
149 The tokens on the list are killed.
152 Don't kill the list itself or change it, since it will be trashed when
153 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
156 ffestt_caselist_kill (ffesttCaseList list)
160 for (next = list->next; next != list; next = next->next)
162 ffelex_token_kill (next->t);
166 /* ffestt_dimlist_append -- Append dim to list of dims
170 ffestt_dimlist_append(list,lower,upper,t);
172 list must have already been created by ffestt_dimlist_create. The
173 list is allocated out of the scratch pool. The token is consumed. */
176 ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper,
181 new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool,
182 "FFEST dim list", sizeof (*new));
183 new->next = list->previous->next;
184 new->previous = list->previous;
185 new->next->previous = new;
186 new->previous->next = new;
192 /* Convert list of dims into ffebld format.
198 ffestt_dimlist_as_expr (list, &rank, &array_size, &extents);
200 The dims in the list are converted to a list of ITEMs; the rank of the
201 array, an expression representing the array size, a list of extent
202 expressions, and the list of ITEMs are returned.
204 If is_ugly_assumed, treat a final dimension with no lower bound
205 and an upper bound of 1 as a * bound. */
208 ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank,
209 ffebld *array_size, ffebld *extents,
210 bool is_ugly_assumed)
215 ffebld ex; /* List of extents. */
216 ffebld ext; /* Extent of a given dimension. */
217 ffebldListBottom bottom;
220 ffetargetIntegerDefault low;
221 ffetargetIntegerDefault high;
222 bool zero = FALSE; /* Zero-size array. */
224 bool star = FALSE; /* Adjustable array. */
226 assert (list != NULL);
229 ffebld_init_list (&expr, &bottom);
230 for (next = list->next; next != list; next = next->next)
233 if (((next->lower == NULL)
234 || (ffebld_op (next->lower) == FFEBLD_opCONTER))
235 && (ffebld_op (next->upper) == FFEBLD_opCONTER))
237 if (next->lower == NULL)
240 low = ffebld_constant_integerdefault (ffebld_conter (next->lower));
241 high = ffebld_constant_integerdefault (ffebld_conter (next->upper));
245 if ((next->next == list)
247 && (next->lower == NULL)
249 && (ffebld_conter_orig (next->upper) == NULL))
252 ffebld_append_item (&bottom,
253 ffebld_new_bounds (NULL, ffebld_new_star ()));
257 else if (((next->lower != NULL)
258 && (ffebld_op (next->lower) == FFEBLD_opANY))
259 || (ffebld_op (next->upper) == FFEBLD_opANY))
261 else if (ffebld_op (next->upper) == FFEBLD_opSTAR)
263 ffebld_append_item (&bottom,
264 ffebld_new_bounds (next->lower, next->upper));
266 ffebld_end_list (&bottom);
270 as = ffebld_new_conter (ffebld_constant_new_integerdefault_val (0));
271 ffebld_set_info (as, ffeinfo_new
272 (FFEINFO_basictypeINTEGER,
273 FFEINFO_kindtypeINTEGERDEFAULT,
276 FFEINFO_whereCONSTANT,
277 FFETARGET_charactersizeNONE));
282 as = ffebld_new_any ();
283 ffebld_set_info (as, ffeinfo_new_any ());
284 ex = ffebld_copy (as);
288 as = ffebld_new_star ();
289 ex = ffebld_new_star (); /* ~~Should really be list as below. */
294 ffebld_init_list (&ex, &bottom);
295 for (next = list->next; next != list; next = next->next)
297 if ((next->lower == NULL)
298 || ((ffebld_op (next->lower) == FFEBLD_opCONTER)
299 && (ffebld_constant_integerdefault (ffebld_conter
300 (next->lower)) == 1)))
301 ext = ffebld_copy (next->upper);
304 ext = ffebld_new_subtract (next->upper, next->lower);
306 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
307 ffeinfo_kindtype (ffebld_info
309 ffeinfo_kindtype (ffebld_info
311 ffebld_set_info (ext,
312 ffeinfo_new (FFEINFO_basictypeINTEGER,
316 ((ffebld_op (ffebld_left (ext))
318 && (ffebld_op (ffebld_right
321 ? FFEINFO_whereCONSTANT
322 : FFEINFO_whereFLEETING,
323 FFETARGET_charactersizeNONE));
324 ffebld_set_left (ext,
325 ffeexpr_convert_expr (ffebld_left (ext),
326 next->t, ext, next->t,
327 FFEEXPR_contextLET));
328 ffebld_set_right (ext,
329 ffeexpr_convert_expr (ffebld_right (ext),
332 FFEEXPR_contextLET));
333 ext = ffeexpr_collapse_subtract (ext, next->t);
336 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
337 ffeinfo_kindtype (ffebld_info (ext)),
338 FFEINFO_kindtypeINTEGERDEFAULT);
340 = ffebld_new_add (ext,
342 (ffebld_constant_new_integerdefault_val
344 ffebld_set_info (ffebld_right (ext), ffeinfo_new
345 (FFEINFO_basictypeINTEGER,
346 FFEINFO_kindtypeINTEGERDEFAULT,
349 FFEINFO_whereCONSTANT,
350 FFETARGET_charactersizeNONE));
351 ffebld_set_info (ext,
352 ffeinfo_new (FFEINFO_basictypeINTEGER,
353 nkt, 0, FFEINFO_kindENTITY,
354 (ffebld_op (ffebld_left (ext))
356 ? FFEINFO_whereCONSTANT
357 : FFEINFO_whereFLEETING,
358 FFETARGET_charactersizeNONE));
359 ffebld_set_left (ext,
360 ffeexpr_convert_expr (ffebld_left (ext),
363 FFEEXPR_contextLET));
364 ffebld_set_right (ext,
365 ffeexpr_convert_expr (ffebld_right (ext),
368 FFEEXPR_contextLET));
369 ext = ffeexpr_collapse_add (ext, next->t);
371 ffebld_append_item (&bottom, ext);
377 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER,
378 ffeinfo_kindtype (ffebld_info (as)),
379 ffeinfo_kindtype (ffebld_info (ext)));
380 as = ffebld_new_multiply (as, ext);
382 ffeinfo_new (FFEINFO_basictypeINTEGER,
383 nkt, 0, FFEINFO_kindENTITY,
384 ((ffebld_op (ffebld_left (as))
386 && (ffebld_op (ffebld_right
389 ? FFEINFO_whereCONSTANT
390 : FFEINFO_whereFLEETING,
391 FFETARGET_charactersizeNONE));
393 ffeexpr_convert_expr (ffebld_left (as),
394 next->t, as, next->t,
395 FFEEXPR_contextLET));
396 ffebld_set_right (as,
397 ffeexpr_convert_expr (ffebld_right (as),
400 FFEEXPR_contextLET));
401 as = ffeexpr_collapse_multiply (as, next->t);
404 ffebld_end_list (&bottom);
405 as = ffeexpr_convert (as, list->next->t, NULL,
406 FFEINFO_basictypeINTEGER,
407 FFEINFO_kindtypeINTEGERDEFAULT, 0,
408 FFETARGET_charactersizeNONE,
418 /* ffestt_dimlist_create -- Create new list of dims
421 list = ffestt_dimlist_create();
423 The list is allocated out of the scratch pool. */
426 ffestt_dimlist_create ()
430 new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool,
431 "FFEST dim list root", sizeof (*new));
432 new->next = new->previous = new;
439 /* ffestt_dimlist_dump -- Dump list of dims
442 ffestt_dimlist_dump(list);
444 The dims in the list are dumped with commas separating them. */
447 ffestt_dimlist_dump (ffesttDimList list)
451 for (next = list->next; next != list; next = next->next)
453 if (next != list->next)
455 if (next->lower != NULL)
456 ffebld_dump (next->lower);
458 if (next->upper != NULL)
459 ffebld_dump (next->upper);
463 /* ffestt_dimlist_kill -- Kill list of dims
466 ffestt_dimlist_kill(list);
468 The tokens on the list are killed. */
471 ffestt_dimlist_kill (ffesttDimList list)
475 for (next = list->next; next != list; next = next->next)
477 ffelex_token_kill (next->t);
481 /* Determine type of list of dimensions.
483 Return KNOWN for all-constant bounds, ADJUSTABLE for constant
484 and variable but no * bounds, ASSUMED for constant and * but
485 not variable bounds, ADJUSTABLEASSUMED for constant and variable
488 If is_ugly_assumed, treat a final dimension with no lower bound
489 and an upper bound of 1 as a * bound. */
492 ffestt_dimlist_type (ffesttDimList list, bool is_ugly_assumed)
498 return FFESTP_dimtypeNONE;
500 type = FFESTP_dimtypeKNOWN;
501 for (next = list->next; next != list; next = next->next)
503 bool ugly_assumed = FALSE;
505 if ((next->next == list)
507 && (next->lower == NULL)
508 && (next->upper != NULL)
509 && (ffebld_op (next->upper) == FFEBLD_opCONTER)
510 && (ffebld_constant_integerdefault (ffebld_conter (next->upper))
512 && (ffebld_conter_orig (next->upper) == NULL))
515 if (next->lower != NULL)
517 if (ffebld_op (next->lower) != FFEBLD_opCONTER)
519 if (type == FFESTP_dimtypeASSUMED)
520 type = FFESTP_dimtypeADJUSTABLEASSUMED;
522 type = FFESTP_dimtypeADJUSTABLE;
525 if (next->upper != NULL)
528 || (ffebld_op (next->upper) == FFEBLD_opSTAR))
530 if (type == FFESTP_dimtypeADJUSTABLE)
531 type = FFESTP_dimtypeADJUSTABLEASSUMED;
533 type = FFESTP_dimtypeASSUMED;
535 else if (ffebld_op (next->upper) != FFEBLD_opCONTER)
536 type = FFESTP_dimtypeADJUSTABLE;
543 /* ffestt_exprlist_append -- Append expr to list of exprs
547 ffestt_exprlist_append(list,expr,t);
549 list must have already been created by ffestt_exprlist_create. The
550 list is allocated out of the scratch pool. The token is consumed. */
553 ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t)
557 new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool,
558 "FFEST expr list", sizeof (*new));
559 new->next = list->previous->next;
560 new->previous = list->previous;
561 new->next->previous = new;
562 new->previous->next = new;
567 /* ffestt_exprlist_create -- Create new list of exprs
570 list = ffestt_exprlist_create();
572 The list is allocated out of the scratch pool. */
575 ffestt_exprlist_create ()
579 new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool,
580 "FFEST expr list root", sizeof (*new));
581 new->next = new->previous = new;
587 /* ffestt_exprlist_drive -- Drive list of token pairs into function
590 void fn(ffebld expr,ffelexToken t);
591 ffestt_exprlist_drive(list,fn);
593 The expr/token pairs in the list are passed to the function one pair
597 ffestt_exprlist_drive (ffesttExprList list, void (*fn) ())
604 for (next = list->next; next != list; next = next->next)
606 (*fn) (next->expr, next->t);
610 /* ffestt_exprlist_dump -- Dump list of exprs
613 ffestt_exprlist_dump(list);
615 The exprs in the list are dumped with commas separating them. */
618 ffestt_exprlist_dump (ffesttExprList list)
622 for (next = list->next; next != list; next = next->next)
624 if (next != list->next)
626 ffebld_dump (next->expr);
630 /* ffestt_exprlist_kill -- Kill list of exprs
633 ffestt_exprlist_kill(list);
635 The tokens on the list are killed.
638 Don't kill the list itself or change it, since it will be trashed when
639 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
642 ffestt_exprlist_kill (ffesttExprList list)
646 for (next = list->next; next != list; next = next->next)
648 ffelex_token_kill (next->t);
652 /* ffestt_formatlist_append -- Append null format to list of formats
654 ffesttFormatList list, new;
655 new = ffestt_formatlist_append(list);
657 list must have already been created by ffestt_formatlist_create. The
658 new item is allocated out of the scratch pool. The caller must initialize
662 ffestt_formatlist_append (ffesttFormatList list)
664 ffesttFormatList new;
666 new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool,
667 "FFEST format list", sizeof (*new));
668 new->next = list->previous->next;
669 new->previous = list->previous;
670 new->next->previous = new;
671 new->previous->next = new;
675 /* ffestt_formatlist_create -- Create new list of formats
677 ffesttFormatList list;
678 list = ffestt_formatlist_create(NULL);
680 The list is allocated out of the scratch pool. */
683 ffestt_formatlist_create (ffesttFormatList parent, ffelexToken t)
685 ffesttFormatList new;
687 new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool,
688 "FFEST format list root", sizeof (*new));
689 new->next = new->previous = new;
690 new->type = FFESTP_formattypeNone;
692 new->u.root.parent = parent;
696 /* ffestt_formatlist_kill -- Kill tokens on list of formats
698 ffesttFormatList list;
699 ffestt_formatlist_kill(list);
701 The tokens on the list are killed. */
704 ffestt_formatlist_kill (ffesttFormatList list)
706 ffesttFormatList next;
708 /* Always kill from the very top on down. */
710 while (list->u.root.parent != NULL)
711 list = list->u.root.parent->next;
713 /* Kill first token for this list. */
716 ffelex_token_kill (list->t);
718 /* Kill each item in this list. */
720 for (next = list->next; next != list; next = next->next)
722 ffelex_token_kill (next->t);
725 case FFESTP_formattypeI:
726 case FFESTP_formattypeB:
727 case FFESTP_formattypeO:
728 case FFESTP_formattypeZ:
729 case FFESTP_formattypeF:
730 case FFESTP_formattypeE:
731 case FFESTP_formattypeEN:
732 case FFESTP_formattypeG:
733 case FFESTP_formattypeL:
734 case FFESTP_formattypeA:
735 case FFESTP_formattypeD:
736 if (next->u.R1005.R1004.t != NULL)
737 ffelex_token_kill (next->u.R1005.R1004.t);
738 if (next->u.R1005.R1006.t != NULL)
739 ffelex_token_kill (next->u.R1005.R1006.t);
740 if (next->u.R1005.R1007_or_R1008.t != NULL)
741 ffelex_token_kill (next->u.R1005.R1007_or_R1008.t);
742 if (next->u.R1005.R1009.t != NULL)
743 ffelex_token_kill (next->u.R1005.R1009.t);
746 case FFESTP_formattypeQ:
747 case FFESTP_formattypeDOLLAR:
748 case FFESTP_formattypeP:
749 case FFESTP_formattypeT:
750 case FFESTP_formattypeTL:
751 case FFESTP_formattypeTR:
752 case FFESTP_formattypeX:
753 case FFESTP_formattypeS:
754 case FFESTP_formattypeSP:
755 case FFESTP_formattypeSS:
756 case FFESTP_formattypeBN:
757 case FFESTP_formattypeBZ:
758 case FFESTP_formattypeSLASH:
759 case FFESTP_formattypeCOLON:
760 if (next->u.R1010.val.t != NULL)
761 ffelex_token_kill (next->u.R1010.val.t);
764 case FFESTP_formattypeR1016:
765 break; /* Nothing more to do. */
767 case FFESTP_formattypeFORMAT:
768 if (next->u.R1003D.R1004.t != NULL)
769 ffelex_token_kill (next->u.R1003D.R1004.t);
770 next->u.R1003D.format->u.root.parent = NULL; /* Parent already dying. */
771 ffestt_formatlist_kill (next->u.R1003D.format);
780 /* ffestt_implist_append -- Append token pair to list of token pairs
784 ffestt_implist_append(list,start_token,end_token);
786 list must have already been created by ffestt_implist_create. The
787 list is allocated out of the scratch pool. The tokens are consumed. */
790 ffestt_implist_append (ffesttImpList list, ffelexToken first, ffelexToken last)
794 new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool,
795 "FFEST token list", sizeof (*new));
796 new->next = list->previous->next;
797 new->previous = list->previous;
798 new->next->previous = new;
799 new->previous->next = new;
804 /* ffestt_implist_create -- Create new list of token pairs
807 list = ffestt_implist_create();
809 The list is allocated out of the scratch pool. */
812 ffestt_implist_create ()
816 new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool,
817 "FFEST token list root",
819 new->next = new->previous = new;
825 /* ffestt_implist_drive -- Drive list of token pairs into function
828 void fn(ffelexToken first,ffelexToken last);
829 ffestt_implist_drive(list,fn);
831 The token pairs in the list are passed to the function one pair at a time. */
834 ffestt_implist_drive (ffesttImpList list, void (*fn) ())
841 for (next = list->next; next != list; next = next->next)
843 (*fn) (next->first, next->last);
847 /* ffestt_implist_dump -- Dump list of token pairs
850 ffestt_implist_dump(list);
852 The token pairs in the list are dumped with commas separating them. */
855 ffestt_implist_dump (ffesttImpList list)
859 for (next = list->next; next != list; next = next->next)
861 if (next != list->next)
863 assert (ffelex_token_type (next->first) == FFELEX_typeNAME);
864 fputs (ffelex_token_text (next->first), dmpout);
865 if (next->last != NULL)
868 assert (ffelex_token_type (next->last) == FFELEX_typeNAME);
869 fputs (ffelex_token_text (next->last), dmpout);
874 /* ffestt_implist_kill -- Kill list of token pairs
877 ffestt_implist_kill(list);
879 The tokens on the list are killed. */
882 ffestt_implist_kill (ffesttImpList list)
886 for (next = list->next; next != list; next = next->next)
888 ffelex_token_kill (next->first);
889 if (next->last != NULL)
890 ffelex_token_kill (next->last);
894 /* ffestt_tokenlist_append -- Append token to list of tokens
898 ffestt_tokenlist_append(tl,t);
900 tl must have already been created by ffestt_tokenlist_create. The
901 list is allocated out of the scratch pool. The token is consumed. */
904 ffestt_tokenlist_append (ffesttTokenList tl, ffelexToken t)
908 ti = (ffesttTokenItem) malloc_new_kp (ffesta_scratch_pool,
909 "FFEST token item", sizeof (*ti));
910 ti->next = (ffesttTokenItem) &tl->first;
911 ti->previous = tl->last;
912 ti->next->previous = ti;
913 ti->previous->next = ti;
918 /* ffestt_tokenlist_create -- Create new list of tokens
921 tl = ffestt_tokenlist_create();
923 The list is allocated out of the scratch pool. */
926 ffestt_tokenlist_create ()
930 tl = (ffesttTokenList) malloc_new_kp (ffesta_scratch_pool,
931 "FFEST token list", sizeof (*tl));
932 tl->first = tl->last = (ffesttTokenItem) &tl->first;
937 /* ffestt_tokenlist_drive -- Dump list of tokens
940 void fn(ffelexToken t);
941 ffestt_tokenlist_drive(tl,fn);
943 The tokens in the list are passed to the given function. */
946 ffestt_tokenlist_drive (ffesttTokenList tl, void (*fn) ())
953 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
959 /* ffestt_tokenlist_dump -- Dump list of tokens
962 ffestt_tokenlist_dump(tl);
964 The tokens in the list are dumped with commas separating them. */
967 ffestt_tokenlist_dump (ffesttTokenList tl)
971 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
975 switch (ffelex_token_type (ti->t))
977 case FFELEX_typeNUMBER:
978 case FFELEX_typeNAME:
979 case FFELEX_typeNAMES:
980 fputs (ffelex_token_text (ti->t), dmpout);
983 case FFELEX_typeASTERISK:
995 /* ffestt_tokenlist_handle -- Handle list of tokens
998 ffelexHandler handler;
999 handler = ffestt_tokenlist_handle(tl,handler);
1001 The tokens in the list are passed to the handler(s). */
1004 ffestt_tokenlist_handle (ffesttTokenList tl, ffelexHandler handler)
1008 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
1009 handler = (ffelexHandler) (*handler) (ti->t);
1011 return (ffelexHandler) handler;
1014 /* ffestt_tokenlist_kill -- Kill list of tokens
1017 ffestt_tokenlist_kill(tl);
1019 The tokens on the list are killed.
1022 Don't kill the list itself or change it, since it will be trashed when
1023 ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */
1026 ffestt_tokenlist_kill (ffesttTokenList tl)
1030 for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next)
1032 ffelex_token_kill (ti->t);