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)
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 = 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;
93 /* ffestt_caselist_create -- Create new list of cases
96 list = ffestt_caselist_create();
98 The list is allocated out of the scratch pool. */
101 ffestt_caselist_create (void)
105 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST case list root",
107 new->next
= new->previous
= new;
115 /* ffestt_caselist_kill -- Kill list of cases
118 ffestt_caselist_kill(list);
120 The tokens on the list are killed.
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. */
127 ffestt_caselist_kill (ffesttCaseList list
)
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
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. */
147 ffestt_dimlist_append (ffesttDimList list
, ffebld lower
, ffebld upper
,
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;
162 /* Convert list of dims into ffebld format.
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. */
178 ffestt_dimlist_as_expr (ffesttDimList list
, ffeinfoRank
*rank
,
179 ffebld
*array_size
, ffebld
*extents
,
180 bool is_ugly_assumed
)
185 ffebld ex
; /* List of extents. */
186 ffebld ext
; /* Extent of a given dimension. */
187 ffebldListBottom bottom
;
190 ffetargetIntegerDefault low
;
191 ffetargetIntegerDefault high
;
192 bool zero
= FALSE
; /* Zero-size array. */
194 bool star
= FALSE
; /* Adjustable array. */
196 assert (list
!= NULL
);
199 ffebld_init_list (&expr
, &bottom
);
200 for (next
= list
->next
; next
!= list
; next
= next
->next
)
203 if (((next
->lower
== NULL
)
204 || (ffebld_op (next
->lower
) == FFEBLD_opCONTER
))
205 && (ffebld_op (next
->upper
) == FFEBLD_opCONTER
))
207 if (next
->lower
== NULL
)
210 low
= ffebld_constant_integerdefault (ffebld_conter (next
->lower
));
211 high
= ffebld_constant_integerdefault (ffebld_conter (next
->upper
));
215 if ((next
->next
== list
)
217 && (next
->lower
== NULL
)
219 && (ffebld_conter_orig (next
->upper
) == NULL
))
222 ffebld_append_item (&bottom
,
223 ffebld_new_bounds (NULL
, ffebld_new_star ()));
227 else if (((next
->lower
!= NULL
)
228 && (ffebld_op (next
->lower
) == FFEBLD_opANY
))
229 || (ffebld_op (next
->upper
) == FFEBLD_opANY
))
231 else if (ffebld_op (next
->upper
) == FFEBLD_opSTAR
)
233 ffebld_append_item (&bottom
,
234 ffebld_new_bounds (next
->lower
, next
->upper
));
236 ffebld_end_list (&bottom
);
240 as
= ffebld_new_conter (ffebld_constant_new_integerdefault_val (0));
241 ffebld_set_info (as
, ffeinfo_new
242 (FFEINFO_basictypeINTEGER
,
243 FFEINFO_kindtypeINTEGERDEFAULT
,
246 FFEINFO_whereCONSTANT
,
247 FFETARGET_charactersizeNONE
));
252 as
= ffebld_new_any ();
253 ffebld_set_info (as
, ffeinfo_new_any ());
254 ex
= ffebld_copy (as
);
258 as
= ffebld_new_star ();
259 ex
= ffebld_new_star (); /* ~~Should really be list as below. */
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
);
274 ext
= ffebld_new_subtract (next
->upper
, next
->lower
);
276 = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER
,
277 ffeinfo_kindtype (ffebld_info
279 ffeinfo_kindtype (ffebld_info
281 ffebld_set_info (ext
,
282 ffeinfo_new (FFEINFO_basictypeINTEGER
,
286 ((ffebld_op (ffebld_left (ext
))
288 && (ffebld_op (ffebld_right
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
),
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
,
312 (ffebld_constant_new_integerdefault_val
314 ffebld_set_info (ffebld_right (ext
), ffeinfo_new
315 (FFEINFO_basictypeINTEGER
,
316 FFEINFO_kindtypeINTEGERDEFAULT
,
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
))
326 ? FFEINFO_whereCONSTANT
327 : FFEINFO_whereFLEETING
,
328 FFETARGET_charactersizeNONE
));
329 ffebld_set_left (ext
,
330 ffeexpr_convert_expr (ffebld_left (ext
),
333 FFEEXPR_contextLET
));
334 ffebld_set_right (ext
,
335 ffeexpr_convert_expr (ffebld_right (ext
),
338 FFEEXPR_contextLET
));
339 ext
= ffeexpr_collapse_add (ext
, next
->t
);
341 ffebld_append_item (&bottom
, ext
);
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
);
352 ffeinfo_new (FFEINFO_basictypeINTEGER
,
353 nkt
, 0, FFEINFO_kindENTITY
,
354 ((ffebld_op (ffebld_left (as
))
356 && (ffebld_op (ffebld_right
359 ? FFEINFO_whereCONSTANT
360 : FFEINFO_whereFLEETING
,
361 FFETARGET_charactersizeNONE
));
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
),
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
,
388 /* ffestt_dimlist_create -- Create new list of dims
391 list = ffestt_dimlist_create();
393 The list is allocated out of the scratch pool. */
396 ffestt_dimlist_create (void)
400 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST dim list root",
402 new->next
= new->previous
= new;
409 /* ffestt_dimlist_kill -- Kill list of dims
412 ffestt_dimlist_kill(list);
414 The tokens on the list are killed. */
417 ffestt_dimlist_kill (ffesttDimList list
)
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
434 If is_ugly_assumed, treat a final dimension with no lower bound
435 and an upper bound of 1 as a * bound. */
438 ffestt_dimlist_type (ffesttDimList list
, bool is_ugly_assumed
)
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
)
453 && (next
->lower
== NULL
)
454 && (next
->upper
!= NULL
)
455 && (ffebld_op (next
->upper
) == FFEBLD_opCONTER
)
456 && (ffebld_constant_integerdefault (ffebld_conter (next
->upper
))
458 && (ffebld_conter_orig (next
->upper
) == NULL
))
461 if (next
->lower
!= NULL
)
463 if (ffebld_op (next
->lower
) != FFEBLD_opCONTER
)
465 if (type
== FFESTP_dimtypeASSUMED
)
466 type
= FFESTP_dimtypeADJUSTABLEASSUMED
;
468 type
= FFESTP_dimtypeADJUSTABLE
;
471 if (next
->upper
!= NULL
)
474 || (ffebld_op (next
->upper
) == FFEBLD_opSTAR
))
476 if (type
== FFESTP_dimtypeADJUSTABLE
)
477 type
= FFESTP_dimtypeADJUSTABLEASSUMED
;
479 type
= FFESTP_dimtypeASSUMED
;
481 else if (ffebld_op (next
->upper
) != FFEBLD_opCONTER
)
482 type
= FFESTP_dimtypeADJUSTABLE
;
489 /* ffestt_exprlist_append -- Append expr to list of exprs
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. */
499 ffestt_exprlist_append (ffesttExprList list
, ffebld expr
, ffelexToken t
)
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;
512 /* ffestt_exprlist_create -- Create new list of exprs
515 list = ffestt_exprlist_create();
517 The list is allocated out of the scratch pool. */
520 ffestt_exprlist_create (void)
524 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST expr list root",
526 new->next
= new->previous
= new;
532 /* ffestt_exprlist_drive -- Drive list of token pairs into function
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
542 ffestt_exprlist_drive (ffesttExprList list
, void (*fn
) (ffebld
, ffelexToken
))
549 for (next
= list
->next
; next
!= list
; next
= next
->next
)
551 (*fn
) (next
->expr
, next
->t
);
555 /* ffestt_exprlist_kill -- Kill list of exprs
558 ffestt_exprlist_kill(list);
560 The tokens on the list are killed.
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. */
567 ffestt_exprlist_kill (ffesttExprList list
)
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
587 ffestt_formatlist_append (ffesttFormatList list
)
589 ffesttFormatList
new;
591 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST format list",
593 new->next
= list
->previous
->next
;
594 new->previous
= list
->previous
;
595 new->next
->previous
= new;
596 new->previous
->next
= 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. */
608 ffestt_formatlist_create (ffesttFormatList parent
, ffelexToken t
)
610 ffesttFormatList
new;
612 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST format list root",
614 new->next
= new->previous
= new;
615 new->type
= FFESTP_formattypeNone
;
617 new->u
.root
.parent
= parent
;
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. */
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. */
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
);
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
);
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
);
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
);
705 /* ffestt_implist_append -- Append token pair to list of token pairs
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. */
715 ffestt_implist_append (ffesttImpList list
, ffelexToken first
, ffelexToken last
)
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;
728 /* ffestt_implist_create -- Create new list of token pairs
731 list = ffestt_implist_create();
733 The list is allocated out of the scratch pool. */
736 ffestt_implist_create (void)
740 new = malloc_new_kp (ffesta_scratch_pool
, "FFEST token list root",
742 new->next
= new->previous
= new;
748 /* ffestt_implist_drive -- Drive list of token pairs into function
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. */
757 ffestt_implist_drive (ffesttImpList list
, void (*fn
) (ffelexToken
, ffelexToken
))
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
773 ffestt_implist_kill(list);
775 The tokens on the list are killed. */
778 ffestt_implist_kill (ffesttImpList list
)
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
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. */
800 ffestt_tokenlist_append (ffesttTokenList tl
, ffelexToken t
)
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
;
813 /* ffestt_tokenlist_create -- Create new list of tokens
816 tl = ffestt_tokenlist_create();
818 The list is allocated out of the scratch pool. */
821 ffestt_tokenlist_create (void)
825 tl
= malloc_new_kp (ffesta_scratch_pool
, "FFEST token list", sizeof (*tl
));
826 tl
->first
= tl
->last
= (ffesttTokenItem
) &tl
->first
;
831 /* ffestt_tokenlist_drive -- Drive list of tokens
834 void fn(ffelexToken t);
835 ffestt_tokenlist_drive(tl,fn);
837 The tokens in the list are passed to the given function. */
840 ffestt_tokenlist_drive (ffesttTokenList tl
, void (*fn
) (ffelexToken
))
847 for (ti
= tl
->first
; ti
!= (ffesttTokenItem
) &tl
->first
; ti
= ti
->next
)
853 /* ffestt_tokenlist_handle -- Handle list of tokens
856 ffelexHandler handler;
857 handler = ffestt_tokenlist_handle(tl,handler);
859 The tokens in the list are passed to the handler(s). */
862 ffestt_tokenlist_handle (ffesttTokenList tl
, ffelexHandler handler
)
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
875 ffestt_tokenlist_kill(tl);
877 The tokens on the list are killed.
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. */
884 ffestt_tokenlist_kill (ffesttTokenList tl
)
888 for (ti
= tl
->first
; ti
!= (ffesttTokenItem
) &tl
->first
; ti
= ti
->next
)
890 ffelex_token_kill (ti
->t
);