1 /* Parser for GNU CHILL (CCITT High-Level Language) -*- C -*-
2 Copyright (C) 1992, 1993, 1998, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 * This is a two-pass parser. In pass 1, we collect declarations,
23 * ignoring actions and most expressions. We store only the
24 * declarations and close, open and re-lex the input file to save
25 * main memory. We anticipate that the compiler will be processing
26 * *very* large single programs which are mechanically generated,
27 * and so we want to store a minimum of information between passes.
29 * yylex detects the end of the main input file and returns the
30 * END_PASS_1 token. We then re-initialize each CHILL compiler
31 * module's global variables and re-process the input file. The
32 * grant file is output. If the user has requested it, GNU CHILL
33 * exits at this time - its only purpose was to generate the grant
34 * file. Optionally, the compiler may exit if errors were detected
37 * As each symbol scope is entered, we install its declarations into
38 * the symbol table. Undeclared types and variables are announced
41 * Then code is generated.
54 /* Since parsers are distinct for each language, put the
55 language string definition here. (fnf) */
56 char *language_string = "GNU CHILL";
58 /* Common code to be done before expanding any action. */
59 #define INIT_ACTION { \
60 if (! ignoring) emit_line_note (input_filename, lineno); }
62 /* Pop a scope for an ON handler. */
63 #define POP_USED_ON_CONTEXT pop_handler(1)
65 /* Pop a scope for an ON handler that wasn't there. */
66 #define POP_UNUSED_ON_CONTEXT pop_handler(0)
68 #define PUSH_ACTION push_action()
70 /* Cause the `yydebug' variable to be defined. */
73 extern struct rtx_def* gen_label_rtx PROTO((void));
74 extern void emit_jump PROTO((struct rtx_def *));
75 extern struct rtx_def* emit_label PROTO((struct rtx_def *));
77 /* This is a hell of a lot easier than getting expr.h included in
79 extern struct rtx_def *expand_expr PROTO((tree, struct rtx_def *,
80 enum machine_mode, int));
82 static int parse_action PROTO((void));
85 extern char *input_filename;
86 extern tree generic_signal_type_node;
87 extern tree signal_code;
88 extern int all_static_flag;
89 extern int ignore_case;
92 static int quasi_signal = 0; /* 1 if processing a quasi signal decl */
95 int parsing_newmode; /* 0 while parsing SYNMODE;
96 1 while parsing NEWMODE. */
97 int expand_exit_needed = 0;
99 /* Gets incremented if we see errors such that we don't want to run pass 2. */
101 int serious_errors = 0;
103 static tree current_fieldlist;
105 /* We don't care about expressions during pass 1, except while we're
106 parsing the RHS of a SYN definition, or while parsing a mode that
107 we need. NOTE: This also causes mode expressions to be ignored. */
108 int ignoring = 1; /* 1 to ignore expressions */
110 /* True if we have seen an action not in a (user) function. */
112 int build_constructor = 0;
114 /* The action_nesting_level of the current procedure body. */
115 int proc_action_level = 0;
117 /* This is the identifier of the label that prefixes the current action,
118 or NULL if there was none. It is cleared at the end of an action,
119 or when starting a nested action list, so get it while you can! */
120 static tree label = NULL_TREE; /* for statement labels */
123 static tree current_block;
126 int in_pseudo_module = 0;
127 int pass = 0; /* 0 for init_decl_processing,
128 1 for pass 1, 2 for pass 2 */
130 /* re-initialize global variables for pass 2 */
134 expand_exit_needed = 0;
135 label = NULL_TREE; /* for statement labels */
136 current_module = NULL;
137 in_pseudo_module = 0;
141 check_end_label (start, end)
144 if (end != NULL_TREE)
146 if (start == NULL_TREE && pass == 1)
147 error ("there was no start label to match the end label '%s'",
148 IDENTIFIER_POINTER(end));
149 else if (start != end && pass == 1)
150 error ("start label '%s' does not match end label '%s'",
151 IDENTIFIER_POINTER(start),
152 IDENTIFIER_POINTER(end));
158 * given a tree which is an id, a type or a decl,
159 * return the associated type, or issue an error and
160 * return error_mark_node.
163 get_type_of (id_or_decl)
166 tree type = id_or_decl;
168 if (id_or_decl == NULL_TREE
169 || TREE_CODE (id_or_decl) == ERROR_MARK)
170 return error_mark_node;
172 if (pass == 1 || ignoring == 1)
175 if (TREE_CODE (type) == IDENTIFIER_NODE)
177 type = lookup_name (id_or_decl);
178 if (type == NULL_TREE)
180 error ("`%s' not declared", IDENTIFIER_POINTER (id_or_decl));
181 type = error_mark_node;
184 if (TREE_CODE (type) == TYPE_DECL)
185 type = TREE_TYPE (type);
186 return type; /* was a type all along */
193 if (CH_DECL_PROCESS (current_function_decl))
195 /* finishing a process */
199 build_chill_function_call
200 (lookup_name (get_identifier ("__stop_process")),
202 expand_expr_stmt (result);
203 emit_line_note (input_filename, lineno);
208 /* finishing a procedure.. */
212 && TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl)))
214 warning ("No RETURN or RESULT in procedure");
215 chill_expand_return (NULL_TREE, 1);
218 finish_chill_function ();
219 pop_chill_function_context ();
223 build_prefix_clause (id)
228 if (current_module && current_module->name)
229 { char *module_name = IDENTIFIER_POINTER (current_module->name);
230 if (module_name[0] && module_name[0] != '_')
231 return current_module->name;
233 error ("PREFIXED clause with no prelix in unlabeled module");
239 possibly_define_exit_label (label)
243 define_label (input_filename, lineno, munge_exit_label (label));
246 #define MAX_LOOK_AHEAD 2
247 static enum terminal terminal_buffer[MAX_LOOK_AHEAD+1];
249 static YYSTYPE val_buffer[MAX_LOOK_AHEAD+1];
251 /*enum terminal current_token, lookahead_token;*/
253 #define TOKEN_NOT_READ dummy_last_terminal
261 if (terminal_buffer[0] == TOKEN_NOT_READ)
263 terminal_buffer[0] = yylex();
264 val_buffer[0] = yylval;
266 return terminal_buffer[0];
268 #define PEEK_TREE() val_buffer[0].ttype
269 #define PEEK_TOKEN1() peek_token_(1)
270 #define PEEK_TOKEN2() peek_token_(2)
275 if (i > MAX_LOOK_AHEAD)
276 fatal ("internal error - too much lookahead");
277 if (terminal_buffer[i] == TOKEN_NOT_READ)
279 terminal_buffer[i] = yylex();
280 val_buffer[i] = yylval;
282 return terminal_buffer[i];
286 pushback_token (code, node)
291 if (terminal_buffer[MAX_LOOK_AHEAD] != TOKEN_NOT_READ)
292 fatal ("internal error - cannot pushback token");
293 for (i = MAX_LOOK_AHEAD; i > 0; i--)
295 terminal_buffer[i] = terminal_buffer[i - 1];
296 val_buffer[i] = val_buffer[i - 1];
298 terminal_buffer[0] = code;
299 val_buffer[0].ttype = node;
306 for (i = 0; i < MAX_LOOK_AHEAD; i++)
308 terminal_buffer[i] = terminal_buffer[i+1];
309 val_buffer[i] = val_buffer[i+1];
311 terminal_buffer[MAX_LOOK_AHEAD] = TOKEN_NOT_READ;
313 #define FORWARD_TOKEN() forward_token_()
315 /* Skip the next token.
316 if it isn't TOKEN, the parser is broken. */
322 if (PEEK_TOKEN() != token)
325 sprintf (buf, "internal parser error - expected token %d", (int)token);
335 if (PEEK_TOKEN() != token)
341 /* return 0 if expected token was not found,
345 expect(token, message)
349 if (PEEK_TOKEN() != token)
352 error(message ? message : "syntax error");
360 /* define a SYNONYM __PROCNAME__ (__procname__) which holds
361 the name of the current procedure.
362 This should be quit the same as __FUNCTION__ in C */
364 define__PROCNAME__ ()
370 if (current_function_decl == NULL_TREE)
373 fname = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
375 string = build_chill_string (strlen (fname), fname);
376 procname = get_identifier (ignore_case ? "__procname__" : "__PROCNAME__");
377 push_syndecl (procname, NULL_TREE, string);
380 /* Forward declarations. */
381 static tree parse_expression ();
382 static tree parse_primval ();
383 static tree parse_mode PROTO((void));
384 static tree parse_opt_mode PROTO((void));
385 static tree parse_untyped_expr ();
386 static tree parse_opt_untyped_expr ();
387 static int parse_definition PROTO((int));
388 static void parse_opt_actions ();
389 static void parse_body PROTO((void));
390 static tree parse_if_expression_body PROTO((void));
391 static tree parse_opt_handler PROTO((void));
394 parse_opt_name_string (allow_all)
395 int allow_all; /* 1 if ALL is allowed as a postfix */
397 enum terminal token = PEEK_TOKEN();
401 if (token == ALL && allow_all)
412 token = PEEK_TOKEN();
416 token = PEEK_TOKEN();
417 if (token == ALL && allow_all)
418 return get_identifier3(IDENTIFIER_POINTER (name), "!", "*");
422 error ("'%s!' is not followed by an identifier",
423 IDENTIFIER_POINTER (name));
426 name = get_identifier3(IDENTIFIER_POINTER(name),
427 "!", IDENTIFIER_POINTER(PEEK_TREE()));
432 parse_simple_name_string ()
434 enum terminal token = PEEK_TOKEN();
438 error ("expected a name here");
439 return error_mark_node;
449 tree name = parse_opt_name_string (0);
453 error ("expected a name string here");
454 return error_mark_node;
458 parse_defining_occurrence ()
460 if (PEEK_TOKEN () == NAME)
462 tree id = PEEK_TREE();
469 /* Matches: <name_string>
470 Returns if pass 1: the identifier.
471 Returns if pass 2: a decl or value for identifier. */
476 tree name = parse_name_string ();
477 if (pass == 1 || ignoring)
481 tree decl = lookup_name (name);
482 if (decl == NULL_TREE)
484 error ("`%s' undeclared", IDENTIFIER_POINTER (name));
485 return error_mark_node;
487 else if (TREE_CODE (TREE_TYPE (decl)) == ERROR_MARK)
488 return error_mark_node;
489 else if (TREE_CODE (decl) == CONST_DECL)
490 return DECL_INITIAL (decl);
491 else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
492 return convert_from_reference (decl);
501 tree label = parse_defining_occurrence();
503 expect(COLON, "expected a ':' here");
510 enum terminal token = PEEK_TOKEN ();
514 (token == END ? pedwarn : error) ("expected ';' here");
519 parse_opt_end_label_semi_colon (start_label)
522 if (PEEK_TOKEN() == NAME)
524 tree end_label = parse_name_string ();
525 check_end_label (start_label, end_label);
531 parse_modulion (label)
536 label = set_module_name (label);
537 module_name = push_module (label, 0);
542 expect(END, "expected END here");
543 parse_opt_handler ();
544 parse_opt_end_label_semi_colon (label);
545 find_granted_decls ();
550 parse_spec_module (label)
553 int save_ignoring = ignoring;
555 push_module (set_module_name (label), 1);
556 ignoring = pass == 2;
557 FORWARD_TOKEN(); /* SKIP SPEC */
558 expect (MODULE, "expected 'MODULE' here");
560 while (parse_definition (1)) { }
562 error ("action not allowed in SPEC MODULE");
563 expect(END, "expected END here");
564 parse_opt_end_label_semi_colon (label);
565 find_granted_decls ();
567 ignoring = save_ignoring;
570 /* Matches: <name_string> ( "," <name_string> )*
571 Returns either a single IDENTIFIER_NODE,
572 or a chain (TREE_LIST) of IDENTIFIER_NODES.
573 (Since a single identifier is the common case, we avoid wasting space
574 (twice, once for each pass) with extra TREE_LIST nodes in that case.)
575 (Will not return NULL_TREE even if ignoring is true.) */
578 parse_defining_occurrence_list ()
580 tree chain = NULL_TREE;
581 tree name = parse_defining_occurrence ();
582 if (name == NULL_TREE)
584 error("missing defining occurrence");
587 if (! check_token (COMMA))
589 chain = build_tree_list (NULL_TREE, name);
592 name = parse_defining_occurrence ();
595 error ("bad defining occurrence following ','");
598 chain = tree_cons (NULL_TREE, name, chain);
599 if (! check_token (COMMA))
602 return nreverse (chain);
606 parse_mode_definition (is_newmode)
610 int save_ignoring = ignoring;
611 ignoring = pass == 2;
612 names = parse_defining_occurrence_list ();
613 expect (EQL, "missing '=' in mode definition");
614 mode = parse_mode ();
615 if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST)
617 for ( ; names != NULL_TREE; names = TREE_CHAIN (names))
618 push_modedef (names, mode, is_newmode);
621 push_modedef (names, mode, is_newmode);
622 ignoring = save_ignoring;
626 parse_mode_definition_statement (is_newmode)
629 FORWARD_TOKEN (); /* skip SYNMODE or NEWMODE */
630 parse_mode_definition (is_newmode);
631 while (PEEK_TOKEN () == COMMA)
634 parse_mode_definition (is_newmode);
640 parse_synonym_definition ()
641 { tree expr = NULL_TREE;
642 tree names = parse_defining_occurrence_list ();
643 tree mode = parse_opt_mode ();
644 if (! expect (EQL, "missing '=' in synonym definition"))
645 mode = error_mark_node;
649 expr = parse_untyped_expr ();
651 expr = parse_expression ();
653 if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST)
655 for ( ; names != NULL_TREE; names = TREE_CHAIN (names))
656 push_syndecl (names, mode, expr);
659 push_syndecl (names, mode, expr);
663 parse_synonym_definition_statement()
665 int save_ignoring= ignoring;
666 ignoring = pass == 2;
668 parse_synonym_definition ();
669 while (PEEK_TOKEN () == COMMA)
672 parse_synonym_definition ();
674 ignoring = save_ignoring;
678 /* Attempts to match: "(" <exception list> ")" ":".
679 Return NULL_TREE on failure, and non-NULL on success.
680 On success, if pass 1, return a TREE_LIST of IDENTIFIER_NODEs. */
683 parse_on_exception_list ()
686 tree list = NULL_TREE;
687 int tok1 = PEEK_TOKEN ();
688 int tok2 = PEEK_TOKEN1 ();
690 /* This requires a lot of look-ahead, because we cannot
691 easily a priori distinguish an exception-list from an expression. */
692 if (tok1 != LPRN || tok2 != NAME)
694 if (tok1 == NAME && tok2 == COLON && pass == 1)
695 error ("missing '(' in exception list");
699 name = parse_name_string ();
700 if (PEEK_TOKEN () == RPRN && PEEK_TOKEN1 () == COLON)
702 /* Matched: '(' <name_string> ')' ':' */
703 FORWARD_TOKEN (); FORWARD_TOKEN ();
704 return pass == 1 ? build_tree_list (NULL_TREE, name) : name;
706 if (PEEK_TOKEN() == COMMA)
709 list = build_tree_list (NULL_TREE, name);
710 while (check_token (COMMA))
712 tree old_names = list;
713 name = parse_name_string ();
716 for ( ; old_names != NULL_TREE; old_names = TREE_CHAIN (old_names))
718 if (TREE_VALUE (old_names) == name)
720 error ("ON exception names must be unique");
721 goto continue_parsing;
724 list = tree_cons (NULL_TREE, name, list);
729 if (! check_token (RPRN) || ! check_token(COLON))
730 error ("syntax error in exception list");
731 return pass == 1 ? nreverse (list) : name;
733 /* Matched: '(' name_string
734 but it doesn't match the syntax of an exception list.
735 It could be the beginning of an expression, so back up. */
736 pushback_token (NAME, name);
737 pushback_token (LPRN, 0);
742 parse_on_alternatives ()
746 tree except_list = parse_on_exception_list ();
747 if (except_list != NULL)
748 chill_handle_on_labels (except_list);
749 else if (parse_action ())
750 expand_exit_needed = 1;
759 if (! check_token (ON))
761 POP_UNUSED_ON_CONTEXT;
764 if (check_token (END))
766 pedwarn ("empty ON-condition");
767 POP_UNUSED_ON_CONTEXT;
773 expand_exit_needed = 0;
775 if (PEEK_TOKEN () != ELSE)
777 parse_on_alternatives ();
778 if (! ignoring && expand_exit_needed)
779 expand_exit_something ();
781 if (check_token (ELSE))
783 chill_start_default_handler ();
785 parse_opt_actions ();
788 emit_line_note (input_filename, lineno);
789 expand_exit_something ();
792 expect (END, "missing 'END' after");
796 return integer_zero_node;
800 parse_loc_declaration (in_spec_module)
803 tree names = parse_defining_occurrence_list ();
804 int save_ignoring = ignoring;
805 int is_static, lifetime_bound;
806 tree mode, init_value = NULL_TREE;
809 ignoring = pass == 2;
810 mode = parse_mode ();
811 ignoring = save_ignoring;
812 is_static = check_token (STATIC);
813 if (check_token (BASED))
815 expect(LPRN, "BASED must be followed by (NAME)");
816 do_based_decls (names, mode, parse_name_string ());
817 expect(RPRN, "BASED must be followed by (NAME)");
820 if (check_token (LOC))
822 /* loc-identity declaration */
824 mode = build_chill_reference_type (mode);
827 lifetime_bound = check_token (INIT);
828 if (lifetime_bound && loc_decl)
831 error ("INIT not allowed at loc-identity declaration");
834 if (PEEK_TOKEN () == ASGN || PEEK_TOKEN() == EQL)
836 save_ignoring = ignoring;
837 ignoring = pass == 1;
838 if (PEEK_TOKEN() == EQL)
841 error ("'=' used where ':=' is required");
844 if (! lifetime_bound)
846 init_value = parse_untyped_expr ();
849 error ("initialization is not allowed in spec module");
850 init_value = NULL_TREE;
852 if (! lifetime_bound)
853 parse_opt_handler ();
854 ignoring = save_ignoring;
856 if (init_value == NULL_TREE && loc_decl && pass == 1)
857 error ("loc-identity declaration without initialisation");
858 do_decls (names, mode,
859 is_static || global_bindings_p ()
860 /* the variable becomes STATIC if all_static_flag is set and
861 current functions doesn't have the RECURSIVE attribute */
862 || (all_static_flag && !CH_DECL_RECURSIVE (current_function_decl)),
863 lifetime_bound, init_value, in_spec_module);
865 /* Free any temporaries we made while initializing the decl. */
870 parse_declaration_statement (in_spec_module)
873 int save_ignoring = ignoring;
874 ignoring = pass == 2;
876 parse_loc_declaration (in_spec_module);
877 while (PEEK_TOKEN () == COMMA)
880 parse_loc_declaration (in_spec_module);
882 ignoring = save_ignoring;
889 if (check_token (FORBID) == 0)
891 if (check_token (ALL))
892 return ignoring ? NULL_TREE : build_int_2 (-1, -1);
894 if (check_token (LPRN))
896 tree list = parse_forbidlist ();
897 expect (RPRN, "missing ')' after FORBID list");
901 error ("bad syntax following FORBID");
905 /* Matches: <grant postfix> or <seize postfix>
906 Returns: A (singleton) TREE_LIST. */
909 parse_postfix (grant_or_seize)
910 enum terminal grant_or_seize;
912 tree name = parse_opt_name_string (1);
913 tree forbid = NULL_TREE;
914 if (name == NULL_TREE)
916 error ("expected a postfix name here");
917 name = error_mark_node;
919 if (grant_or_seize == GRANT)
920 forbid = parse_optforbid ();
921 return build_tree_list (forbid, name);
925 parse_postfix_list (grant_or_seize)
926 enum terminal grant_or_seize;
928 tree list = parse_postfix (grant_or_seize);
929 while (check_token (COMMA))
930 list = chainon (list, parse_postfix (grant_or_seize));
935 parse_rename_clauses (grant_or_seize)
936 enum terminal grant_or_seize;
940 tree rename_old_prefix, rename_new_prefix, postfix;
942 rename_old_prefix = parse_opt_name_string (0);
943 expect (ARROW, "missing '->' in rename clause");
944 rename_new_prefix = parse_opt_name_string (0);
945 expect (RPRN, "missing ')' in rename clause");
946 expect ('!', "missing '!' in rename clause");
947 postfix = parse_postfix (grant_or_seize);
949 if (grant_or_seize == GRANT)
950 chill_grant (rename_old_prefix, rename_new_prefix,
951 TREE_VALUE (postfix), TREE_PURPOSE (postfix));
953 chill_seize (rename_old_prefix, rename_new_prefix,
954 TREE_VALUE (postfix));
956 if (PEEK_TOKEN () != COMMA)
959 if (PEEK_TOKEN () != LPRN)
961 error ("expected another rename clause");
968 parse_opt_prefix_clause ()
970 if (check_token (PREFIXED) == 0)
972 return build_prefix_clause (parse_opt_name_string (0));
976 parse_grant_statement ()
979 if (PEEK_TOKEN () == LPRN)
980 parse_rename_clauses (GRANT);
983 tree window = parse_postfix_list (GRANT);
984 tree new_prefix = parse_opt_prefix_clause ();
986 for (t = window; t; t = TREE_CHAIN (t))
987 chill_grant (NULL_TREE, new_prefix, TREE_VALUE (t), TREE_PURPOSE (t));
992 parse_seize_statement ()
995 if (PEEK_TOKEN () == LPRN)
996 parse_rename_clauses (SEIZE);
999 tree seize_window = parse_postfix_list (SEIZE);
1000 tree old_prefix = parse_opt_prefix_clause ();
1002 for (t = seize_window; t; t = TREE_CHAIN (t))
1003 chill_seize (old_prefix, NULL_TREE, TREE_VALUE (t));
1007 /* In pass 1, this returns a TREE_LIST, one node for each parameter.
1008 In pass 2, we get a list of PARM_DECLs chained together.
1009 In either case, the list is in reverse order. */
1012 parse_param_name_list ()
1014 tree list = NULL_TREE;
1018 tree name = parse_defining_occurrence ();
1019 if (name == NULL_TREE)
1021 error ("syntax error in parameter name list");
1025 new_link = build_tree_list (NULL_TREE, name);
1026 /* else if (current_module->is_spec_module) ; nothing */
1027 else /* pass == 2 */
1029 new_link = make_node (PARM_DECL);
1030 DECL_NAME (new_link) = name;
1031 DECL_ASSEMBLER_NAME (new_link) = name;
1034 TREE_CHAIN (new_link) = list;
1036 } while (check_token (COMMA));
1044 switch (PEEK_TOKEN ())
1046 case PARAMATTR: /* INOUT is returned here */
1047 attr = PEEK_TREE ();
1052 return ridpointers[(int) RID_IN];
1055 return ridpointers[(int) RID_LOC];
1059 return ridpointers[(int) RID_DYNAMIC];
1066 /* We wrap CHILL array parameters in a STRUCT. The original parameter
1067 name is unpacked from the struct at get_identifier time */
1069 /* In pass 1, returns list of types; in pass 2: chain of PARM_DECLs. */
1074 tree names = parse_param_name_list ();
1075 tree mode = parse_mode ();
1076 tree paramattr = parse_param_attr ();
1077 return chill_munge_params (nreverse (names), mode, paramattr);
1081 * Note: build_process_header depends upon the *exact*
1082 * representation of STRUCT fields and of formal parameter
1083 * lists. If either is changed, build_process_header will
1084 * also need change. Push_extern_process is affected as well.
1087 parse_formparlist ()
1089 tree list = NULL_TREE;
1090 if (PEEK_TOKEN() == RPRN)
1094 list = chainon (list, parse_formpar ());
1095 if (! check_token (COMMA))
1102 parse_opt_result_spec ()
1105 int is_nonref, is_loc, is_dynamic;
1106 if (!check_token (RETURNS))
1107 return void_type_node;
1108 expect (LPRN, "expected '(' after RETURNS");
1109 mode = parse_mode ();
1110 is_nonref = check_token (NONREF);
1111 is_loc = check_token (LOC);
1112 is_dynamic = check_token (DYNAMIC);
1113 if (is_nonref && !is_loc)
1114 error ("NONREF specific without LOC in result attribute");
1115 if (is_dynamic && !is_loc)
1116 error ("DYNAMIC specific without LOC in result attribute");
1117 mode = get_type_of (mode);
1118 if (is_loc && ! ignoring)
1119 mode = build_chill_reference_type (mode);
1120 expect (RPRN, "expected ')' after RETURNS");
1127 tree list = NULL_TREE;
1128 if (!check_token (EXCEPTIONS))
1130 expect (LPRN, "expected '(' after EXCEPTIONS");
1133 tree except_name = parse_name_string ();
1135 for (name = list; name != NULL_TREE; name = TREE_CHAIN (name))
1136 if (TREE_VALUE (name) == except_name && pass == 1)
1138 error ("exception names must be unique");
1141 if (name == NULL_TREE && !ignoring)
1142 list = tree_cons (NULL_TREE, except_name, list);
1143 } while (check_token (COMMA));
1144 expect (RPRN, "expected ')' after EXCEPTIONS");
1149 parse_opt_recursive ()
1151 if (check_token (RECURSIVE))
1152 return ridpointers[RID_RECURSIVE];
1158 parse_procedureattr ()
1162 switch (PEEK_TOKEN ())
1166 generality = ridpointers[RID_GENERAL];
1170 generality = ridpointers[RID_SIMPLE];
1174 generality = ridpointers[RID_INLINE];
1177 generality = NULL_TREE;
1179 optrecursive = parse_opt_recursive ();
1183 generality = build_tree_list (NULL_TREE, generality);
1185 generality = tree_cons (NULL_TREE, optrecursive, generality);
1189 /* Parse the body and last part of a procedure or process definition. */
1192 parse_proc_body (name, exceptions)
1196 int save_proc_action_level = proc_action_level;
1197 proc_action_level = action_nesting_level;
1198 if (exceptions != NULL_TREE)
1199 /* set up a handler for reraising exceptions */
1202 define__PROCNAME__ ();
1204 proc_action_level = save_proc_action_level;
1205 expect (END, "'END' was expected here");
1206 parse_opt_handler ();
1207 if (exceptions != NULL_TREE)
1208 chill_reraise_exceptions (exceptions);
1209 parse_opt_end_label_semi_colon (name);
1214 parse_procedure_definition (in_spec_module)
1217 int save_ignoring = ignoring;
1218 tree name = parse_defining_occurrence ();
1219 tree params, result, exceptlist, attributes;
1220 int save_chill_at_module_level = chill_at_module_level;
1221 chill_at_module_level = 0;
1222 if (!in_spec_module)
1223 ignoring = pass == 2;
1224 require (COLON); require (PROC);
1225 expect (LPRN, "missing '(' after PROC");
1226 params = parse_formparlist ();
1227 expect (RPRN, "missing ')' in PROC");
1228 result = parse_opt_result_spec ();
1229 exceptlist = parse_opt_except ();
1230 attributes = parse_procedureattr ();
1231 ignoring = save_ignoring;
1234 expect (END, "missing 'END'");
1235 parse_opt_end_label_semi_colon (name);
1236 push_extern_function (name, result, params, exceptlist, 0);
1239 push_chill_function_context ();
1240 start_chill_function (name, result, params, exceptlist, attributes);
1241 current_module->procedure_seen = 1;
1242 parse_proc_body (name, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
1243 chill_at_module_level = save_chill_at_module_level;
1249 tree names = parse_defining_occurrence_list ();
1250 tree mode = parse_mode ();
1251 tree paramattr = parse_param_attr ();
1253 if (names && TREE_CODE (names) == IDENTIFIER_NODE)
1254 names = build_tree_list (NULL_TREE, names);
1255 return tree_cons (tree_cons (paramattr, mode, NULL_TREE), names, NULL_TREE);
1259 parse_processparlist ()
1261 tree list = NULL_TREE;
1262 if (PEEK_TOKEN() == RPRN)
1266 list = chainon (list, parse_processpar ());
1267 if (! check_token (COMMA))
1274 parse_process_definition (in_spec_module)
1277 int save_ignoring = ignoring;
1278 tree name = parse_defining_occurrence ();
1281 if (!in_spec_module)
1283 require (COLON); require (PROCESS);
1284 expect (LPRN, "missing '(' after PROCESS");
1285 params = parse_processparlist (in_spec_module);
1286 expect (RPRN, "missing ')' in PROCESS");
1287 ignoring = save_ignoring;
1290 expect (END, "missing 'END'");
1291 parse_opt_end_label_semi_colon (name);
1292 push_extern_process (name, params, NULL_TREE, 0);
1295 tmp = build_process_header (name, params);
1296 parse_proc_body (name, NULL_TREE);
1297 build_process_wrapper (name, tmp);
1301 parse_signal_definition ()
1303 tree signame = parse_defining_occurrence ();
1304 tree modes = NULL_TREE;
1305 tree dest = NULL_TREE;
1307 if (check_token (EQL))
1309 expect (LPRN, "missing '(' after 'SIGNAL <name> ='");
1312 tree mode = parse_mode ();
1313 modes = tree_cons (NULL_TREE, mode, modes);
1314 if (! check_token (COMMA))
1317 expect (RPRN, "missing ')'");
1318 modes = nreverse (modes);
1321 if (check_token (TO))
1324 int save_ignoring = ignoring;
1326 decl = parse_name ();
1327 ignoring = save_ignoring;
1330 if (decl == NULL_TREE
1331 || TREE_CODE (decl) == ERROR_MARK
1332 || TREE_CODE (decl) != FUNCTION_DECL
1333 || !CH_DECL_PROCESS (decl))
1334 error ("must specify a PROCESS name");
1340 if (! global_bindings_p ())
1341 error ("SIGNAL must be in global reach");
1344 tree struc = build_signal_struct_type (signame, modes, dest);
1346 generate_tasking_code_variable (signame,
1348 current_module->is_spec_module);
1349 /* remember the code variable in the struct type */
1350 DECL_TASKING_CODE_DECL (struc) = (struct lang_decl *)decl;
1351 CH_DECL_SIGNAL (struc) = 1;
1352 add_taskstuff_to_list (decl, "_TT_Signal",
1353 current_module->is_spec_module ?
1354 NULL_TREE : signal_code, struc, NULL_TREE);
1360 parse_signal_definition_statement ()
1362 int save_ignoring = ignoring;
1363 ignoring = pass == 2;
1367 parse_signal_definition ();
1368 if (! check_token (COMMA))
1370 if (PEEK_TOKEN () == SC)
1372 error ("syntax error while parsing signal definition statement");
1376 parse_semi_colon ();
1377 ignoring = save_ignoring;
1381 parse_definition (in_spec_module)
1384 switch (PEEK_TOKEN ())
1387 if (PEEK_TOKEN1() == COLON)
1389 if (PEEK_TOKEN2() == PROC)
1391 parse_procedure_definition (in_spec_module);
1394 else if (PEEK_TOKEN2() == PROCESS)
1396 parse_process_definition (in_spec_module);
1402 parse_declaration_statement(in_spec_module);
1405 parse_grant_statement ();
1408 parse_mode_definition_statement(1);
1415 parse_seize_statement ();
1418 parse_signal_definition_statement ();
1421 parse_synonym_definition_statement();
1424 parse_mode_definition_statement(0);
1433 parse_then_clause ()
1435 expect (THEN, "expected 'THEN' after 'IF'");
1437 emit_line_note (input_filename, lineno);
1438 parse_opt_actions ();
1442 parse_opt_else_clause ()
1444 while (check_token (ELSIF))
1446 tree cond = parse_expression ();
1448 expand_start_elseif (truthvalue_conversion (cond));
1449 parse_then_clause ();
1451 if (check_token (ELSE))
1454 { emit_line_note (input_filename, lineno);
1455 expand_start_else ();
1457 parse_opt_actions ();
1461 static tree parse_expr_list ()
1463 tree expr = parse_expression ();
1464 tree list = ignoring ? NULL_TREE : build_tree_list (NULL_TREE, expr);
1465 while (check_token (COMMA))
1467 expr = parse_expression ();
1469 list = tree_cons (NULL_TREE, expr, list);
1475 parse_range_list_clause ()
1477 tree name = parse_opt_name_string (0);
1478 if (name == NULL_TREE)
1480 while (check_token (COMMA))
1482 name = parse_name_string (0);
1484 if (check_token (SC))
1486 sorry ("case range list");
1487 return error_mark_node;
1489 pushback_token (NAME, name);
1494 pushback_paren_expr (expr)
1497 if (pass == 1 && !ignoring)
1498 expr = build1 (PAREN_EXPR, NULL_TREE, expr);
1499 pushback_token (EXPR, expr);
1502 /* Matches: <case label> */
1508 if (check_token (ELSE))
1509 return case_else_node;
1510 /* Does this also handle the case of a mode name? FIXME */
1511 expr = parse_expression ();
1512 if (check_token (COLON))
1514 tree max_expr = parse_expression ();
1516 expr = build (RANGE_EXPR, NULL_TREE, expr, max_expr);
1521 /* Parses: <case_label_list>
1522 Fails if not followed by COMMA or COLON.
1523 If it fails, it backs up if needed, and returns NULL_TREE.
1524 IN_TUPLE is true if we are parsing a tuple element,
1525 and 0 if we are parsing a case label specification. */
1528 parse_case_label_list (selector, in_tuple)
1533 if (! check_token (LPRN))
1535 if (check_token (MUL))
1537 expect (RPRN, "missing ')' after '*' case label list");
1539 return integer_zero_node;
1540 expr = build (RANGE_EXPR, NULL_TREE, NULL_TREE, NULL_TREE);
1541 expr = build_tree_list (NULL_TREE, expr);
1544 expr = parse_case_label ();
1545 if (check_token (RPRN))
1547 if ((in_tuple || PEEK_TOKEN () != COMMA) && PEEK_TOKEN () != COLON)
1549 /* Ooops! It looks like it was the start of an action or
1550 unlabelled tuple element, and not a case label, so back up. */
1551 if (expr != NULL_TREE && TREE_CODE (expr) == RANGE_EXPR)
1553 error ("misplaced colon in case label");
1554 expr = error_mark_node;
1556 pushback_paren_expr (expr);
1559 list = build_tree_list (NULL_TREE, expr);
1560 if (expr == case_else_node && selector != NULL_TREE)
1561 ELSE_LABEL_SPECIFIED (selector) = 1;
1564 list = build_tree_list (NULL_TREE, expr);
1565 if (expr == case_else_node && selector != NULL_TREE)
1566 ELSE_LABEL_SPECIFIED (selector) = 1;
1568 while (check_token (COMMA))
1570 expr = parse_case_label ();
1571 list = tree_cons (NULL_TREE, expr, list);
1572 if (expr == case_else_node && selector != NULL_TREE)
1573 ELSE_LABEL_SPECIFIED (selector) = 1;
1575 expect (RPRN, "missing ')' at end of case label list");
1576 return nreverse (list);
1579 /* Parses: <case_label_specification>
1580 Must be followed by a COLON.
1581 If it fails, it backs up if needed, and returns NULL_TREE. */
1584 parse_case_label_specification (selectors)
1587 tree list_list = NULL_TREE;
1589 list = parse_case_label_list (selectors, 0);
1590 if (list == NULL_TREE)
1592 list_list = build_tree_list (NULL_TREE, list);
1593 while (check_token (COMMA))
1595 if (selectors != NULL_TREE)
1596 selectors = TREE_CHAIN (selectors);
1597 list = parse_case_label_list (selectors, 0);
1598 if (list == NULL_TREE)
1600 error ("unrecognized case label list after ','");
1603 list_list = tree_cons (NULL_TREE, list, list_list);
1605 return nreverse (list_list);
1609 parse_single_dimension_case_action (selector)
1612 int no_completeness_check = 0;
1614 /* The case label/action toggle. It is 0 initially, and when an action
1615 was last seen. It is 1 integer_zero_node when a label was last seen. */
1616 int caseaction_flag = 0;
1620 expand_exit_needed = 0;
1621 selector = check_case_selector (selector);
1622 expand_start_case (1, selector, TREE_TYPE (selector), "CASE statement");
1628 tree label_spec = parse_case_label_specification (selector);
1629 if (label_spec != NULL_TREE)
1631 expect (COLON, "missing ':' in case alternative");
1634 no_completeness_check |= chill_handle_single_dimension_case_label (
1635 selector, label_spec, &expand_exit_needed, &caseaction_flag);
1638 else if (parse_action ())
1640 expand_exit_needed = 1;
1641 caseaction_flag = 0;
1649 if (expand_exit_needed || caseaction_flag == 1)
1650 expand_exit_something ();
1652 if (check_token (ELSE))
1655 chill_handle_case_default ();
1656 parse_opt_actions ();
1659 emit_line_note (input_filename, lineno);
1660 expand_exit_something ();
1663 else if (! ignoring && TREE_CODE (selector) != ERROR_MARK &&
1664 ! no_completeness_check)
1665 check_missing_cases (TREE_TYPE (selector));
1667 expect (ESAC, "missing 'ESAC' after 'CASE'");
1670 expand_end_case (selector);
1676 parse_multi_dimension_case_action (selector)
1679 struct rtx_def *begin_test_label = 0, *end_case_label = 0, *new_label;
1680 tree action_labels = NULL_TREE;
1681 tree tests = NULL_TREE;
1682 int save_lineno = lineno;
1683 char *save_filename = input_filename;
1685 /* We can't compute the range of an (ELSE) label until all of the CASE
1686 label specifications have been seen, however, the code for the actions
1687 between them is generated on the fly. We can still generate everything in
1688 one pass is we use the following form:
1690 Compile a CASE of the form
1693 (X11),...,(X1n): A1;
1695 (Xm1),...,(Xmn): Am;
1707 T1 := s1; ...; Tn := Sn;
1708 if (T1 = X11 and ... and Tn = X1n) GOTO L1;
1710 if (T1 = Xm1 and ... and Tn = Xmn) GOTO Lm;
1717 selector = check_case_selector_list (selector);
1718 begin_test_label = gen_label_rtx ();
1719 end_case_label = gen_label_rtx ();
1720 emit_jump (begin_test_label);
1725 tree label_spec = parse_case_label_specification (selector);
1726 if (label_spec != NULL_TREE)
1728 expect (COLON, "missing ':' in case alternative");
1731 tests = tree_cons (label_spec, NULL_TREE, tests);
1733 if (action_labels != NULL_TREE)
1734 emit_jump (end_case_label);
1736 new_label = gen_label_rtx ();
1737 emit_label (new_label);
1738 emit_line_note (input_filename, lineno);
1739 action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);
1740 TREE_CST_RTL (action_labels) = new_label;
1743 else if (! parse_action ())
1745 if (action_labels != NULL_TREE)
1746 emit_jump (end_case_label);
1751 if (check_token (ELSE))
1755 new_label = gen_label_rtx ();
1756 emit_label (new_label);
1757 emit_line_note (input_filename, lineno);
1758 action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);
1759 TREE_CST_RTL (action_labels) = new_label;
1761 parse_opt_actions ();
1763 emit_jump (end_case_label);
1766 expect (ESAC, "missing 'ESAC' after 'CASE'");
1770 emit_label (begin_test_label);
1771 emit_line_note (save_filename, save_lineno);
1772 if (tests != NULL_TREE)
1775 tests = nreverse (tests);
1776 action_labels = nreverse (action_labels);
1777 compute_else_ranges (selector, tests);
1779 cond = build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));
1780 expand_start_cond (truthvalue_conversion (cond), label ? 1 : 0);
1781 emit_jump (TREE_CST_RTL (action_labels));
1783 for (tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels);
1784 tests != NULL_TREE && action_labels != NULL_TREE;
1785 tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels))
1788 build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));
1789 expand_start_elseif (truthvalue_conversion (cond));
1790 emit_jump (TREE_CST_RTL (action_labels));
1792 if (action_labels != NULL_TREE)
1794 expand_start_else ();
1795 emit_jump (TREE_CST_RTL (action_labels));
1799 emit_label (end_case_label);
1804 parse_case_action (label)
1808 int multi_dimension_case = 0;
1811 selector = parse_expr_list ();
1812 selector = nreverse (selector);
1813 expect (OF, "missing 'OF' after 'CASE'");
1814 parse_range_list_clause ();
1822 expand_exit_needed = 0;
1823 if (TREE_CODE (selector) == TREE_LIST)
1825 if (TREE_CHAIN (selector) != NULL_TREE)
1826 multi_dimension_case = 1;
1828 selector = TREE_VALUE (selector);
1832 /* We want to use the regular CASE support for the single dimension case. The
1833 multi dimension case requires different handling. Note that when "ignoring"
1834 is true we parse using the single dimension code. This is OK since it will
1835 still parse correctly. */
1836 if (multi_dimension_case)
1837 parse_multi_dimension_case_action (selector);
1839 parse_single_dimension_case_action (selector);
1843 possibly_define_exit_label (label);
1848 /* Matches: [ <asm_operand> { "," <asm_operand> }* ],
1849 where <asm_operand> = STRING '(' <expression> ')'
1850 These are the operands other than the first string and colon
1851 in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
1854 parse_asm_operands ()
1856 tree list = NULL_TREE;
1857 if (PEEK_TOKEN () != STRING)
1862 if (PEEK_TOKEN () != STRING)
1864 error ("bad ASM operand");
1867 string = PEEK_TREE();
1869 expect (LPRN, "missing '(' in ASM operand");
1870 expr = parse_expression ();
1871 expect (RPRN, "missing ')' in ASM operand");
1872 list = tree_cons (string, expr, list);
1873 if (! check_token (COMMA))
1876 return nreverse (list);
1879 /* Matches: STRING { ',' STRING }* */
1882 parse_asm_clobbers ()
1884 tree list = NULL_TREE;
1888 if (PEEK_TOKEN () != STRING)
1890 error ("bad ASM operand");
1893 string = PEEK_TREE();
1895 list = tree_cons (NULL_TREE, string, list);
1896 if (! check_token (COMMA))
1903 ch_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
1904 tree string, outputs, inputs, clobbers;
1909 int noutputs = list_length (outputs);
1911 /* o[I] is the place that output number I should be written. */
1912 register tree *o = (tree *) alloca (noutputs * sizeof (tree));
1915 if (TREE_CODE (string) == ADDR_EXPR)
1916 string = TREE_OPERAND (string, 0);
1917 if (TREE_CODE (string) != STRING_CST)
1919 error ("asm template is not a string constant");
1923 /* Record the contents of OUTPUTS before it is modified. */
1924 for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
1925 o[i] = TREE_VALUE (tail);
1928 /* Perform default conversions on array and function inputs. */
1929 /* Don't do this for other types--
1930 it would screw up operands expected to be in memory. */
1931 for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
1932 if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE
1933 || TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
1934 TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
1937 /* Generate the ASM_OPERANDS insn;
1938 store into the TREE_VALUEs of OUTPUTS some trees for
1939 where the values were actually stored. */
1940 expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
1942 /* Copy all the intermediate outputs into the specified outputs. */
1943 for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
1945 if (o[i] != TREE_VALUE (tail))
1947 expand_expr (build_chill_modify_expr (o[i], TREE_VALUE (tail)),
1951 /* Detect modification of read-only values.
1952 (Otherwise done by build_modify_expr.) */
1955 tree type = TREE_TYPE (o[i]);
1956 if (TYPE_READONLY (type)
1957 || ((TREE_CODE (type) == RECORD_TYPE
1958 || TREE_CODE (type) == UNION_TYPE)
1959 && TYPE_FIELDS_READONLY (type)))
1960 warning ("readonly location modified by 'asm'");
1964 /* Those MODIFY_EXPRs could do autoincrements. */
1972 require (ASM_KEYWORD);
1973 expect (LPRN, "missing '('");
1976 emit_line_note (input_filename, lineno);
1977 insn = parse_expression ();
1978 if (check_token (COLON))
1980 tree output_operand, input_operand, clobbered_regs;
1981 output_operand = parse_asm_operands ();
1982 if (check_token (COLON))
1983 input_operand = parse_asm_operands ();
1985 input_operand = NULL_TREE;
1986 if (check_token (COLON))
1987 clobbered_regs = parse_asm_clobbers ();
1989 clobbered_regs = NULL_TREE;
1990 expect (RPRN, "missing ')'");
1992 ch_expand_asm_operands (insn, output_operand, input_operand,
1993 clobbered_regs, FALSE,
1994 input_filename, lineno);
1998 expect (RPRN, "missing ')'");
2001 else if ((TREE_CODE (insn) == ADDR_EXPR
2002 && TREE_CODE (TREE_OPERAND (insn, 0)) == STRING_CST)
2003 || TREE_CODE (insn) == STRING_CST)
2006 error ("argument of `asm' is not a constant string");
2011 parse_begin_end_block (label)
2014 require (BEGINTOKEN);
2016 /* don't make a linenote at BEGIN */
2024 expand_start_bindings (label ? 1 : 0);
2028 expect (END, "missing 'END'");
2029 /* Note that the opthandler comes before the poplevel
2030 - hence a handler is in the scope of the block. */
2031 parse_opt_handler ();
2032 possibly_define_exit_label (label);
2035 emit_line_note (input_filename, lineno);
2036 expand_end_bindings (getdecls (), kept_level_p (), 0);
2038 poplevel (kept_level_p (), 0, 0);
2041 parse_opt_end_label_semi_colon (label);
2045 parse_if_action (label)
2051 cond = parse_expression ();
2056 expand_start_cond (truthvalue_conversion (cond),
2059 parse_then_clause ();
2060 parse_opt_else_clause ();
2061 expect (FI, "expected 'FI' after 'IF'");
2064 emit_line_note (input_filename, lineno);
2069 possibly_define_exit_label (label);
2074 /* Matches: <iteration> (as in a <for control>). */
2079 tree loop_counter = parse_defining_occurrence ();
2080 if (check_token (ASGN))
2082 tree start_value = parse_expression ();
2084 = check_token (BY) ? parse_expression () : NULL_TREE;
2085 int going_down = check_token (DOWN);
2087 if (check_token (TO))
2088 end_value = parse_expression ();
2091 error ("expected 'TO' in step enumeration");
2092 end_value = error_mark_node;
2095 build_loop_iterator (loop_counter, start_value, step_value,
2096 end_value, going_down, 0, 0);
2100 int going_down = check_token (DOWN);
2102 if (check_token (IN))
2103 expr = parse_expression ();
2106 error ("expected 'IN' in FOR control here");
2107 expr = error_mark_node;
2111 tree low_bound, high_bound;
2112 if (expr && TREE_CODE (expr) == TYPE_DECL)
2114 expr = TREE_TYPE (expr);
2115 /* FIXME: expr must be an array or powerset */
2116 low_bound = convert (expr, TYPE_MIN_VALUE (expr));
2117 high_bound = convert (expr, TYPE_MAX_VALUE (expr));
2122 high_bound = NULL_TREE;
2124 build_loop_iterator (loop_counter, low_bound,
2125 NULL_TREE, high_bound,
2131 /* Matches: '(' <event list> ')' ':'.
2132 Or; returns NULL_EXPR. */
2135 parse_delay_case_event_list ()
2137 tree event_list = NULL_TREE;
2139 if (! check_token (LPRN))
2141 event = parse_expression ();
2142 if (PEEK_TOKEN () == ')' && PEEK_TOKEN1 () != ':')
2146 pushback_paren_expr (event);
2152 event_list = tree_cons (NULL_TREE, event, event_list);
2153 if (! check_token (COMMA))
2155 event = parse_expression ();
2157 expect (RPRN, "missing ')'");
2158 expect (COLON, "missing ':'");
2159 return ignoring ? error_mark_node : event_list;
2163 parse_delay_case_action (label)
2166 tree label_cnt = NULL_TREE, set_location, priority;
2167 tree combined_event_list = NULL_TREE;
2172 expand_exit_needed = 0;
2173 if (check_token (SET))
2175 set_location = parse_expression ();
2176 parse_semi_colon ();
2179 set_location = NULL_TREE;
2180 if (check_token (PRIORITY))
2182 priority = parse_expression ();
2183 parse_semi_colon ();
2186 priority = NULL_TREE;
2188 label_cnt = build_delay_case_start (set_location, priority);
2191 tree event_list = parse_delay_case_event_list ();
2196 int if_or_elseif = combined_event_list == NULL_TREE;
2197 build_delay_case_label (event_list, if_or_elseif);
2198 combined_event_list = chainon (combined_event_list, event_list);
2201 else if (parse_action ())
2205 expand_exit_needed = 1;
2206 if (combined_event_list == NULL_TREE)
2207 error ("missing DELAY CASE alternative");
2213 expect (ESAC, "missing 'ESAC' in DELAY CASE'");
2215 build_delay_case_end (combined_event_list);
2216 possibly_define_exit_label (label);
2221 parse_do_action (label)
2227 if (check_token (WITH))
2229 tree list = NULL_TREE;
2232 tree name = parse_primval ();
2233 if (! ignoring && TREE_CODE (name) != ERROR_MARK)
2235 if (TREE_CODE (TREE_TYPE (name)) == REFERENCE_TYPE)
2236 name = convert (TREE_TYPE (TREE_TYPE (name)), name);
2239 int is_loc = chill_location (name);
2240 if (is_loc == 1) /* This is probably not possible */
2241 warning ("non-referable location in DO WITH");
2244 name = build_chill_arrow_expr (name, 1);
2245 name = decl_temp1 (get_identifier ("__with_element"),
2249 name = build_chill_indirect_ref (name, NULL_TREE, 0);
2252 if (TREE_CODE (TREE_TYPE (name)) != RECORD_TYPE)
2253 error ("WITH element must be of STRUCT mode");
2255 list = tree_cons (NULL_TREE, name, list);
2257 if (! check_token (COMMA))
2262 for (list = nreverse (list); list != NULL_TREE; list = TREE_CHAIN (list))
2263 shadow_record_fields (TREE_VALUE (list));
2265 parse_semi_colon ();
2266 parse_opt_actions ();
2267 expect (OD, "missing 'OD' in 'DO WITH'");
2269 emit_line_note (input_filename, lineno);
2270 possibly_define_exit_label (label);
2271 parse_opt_handler ();
2272 parse_opt_end_label_semi_colon (label);
2276 token = PEEK_TOKEN();
2277 if (token != FOR && token != WHILE)
2280 parse_opt_actions ();
2281 expect (OD, "Missing 'OD' after 'DO'");
2282 parse_opt_handler ();
2283 parse_opt_end_label_semi_colon (label);
2287 emit_line_note (input_filename, lineno);
2289 if (check_token (FOR))
2291 if (check_token (EVER))
2294 build_loop_iterator (NULL_TREE, NULL_TREE,
2295 NULL_TREE, NULL_TREE,
2301 while (check_token (COMMA))
2306 build_loop_iterator (NULL_TREE, NULL_TREE,
2307 NULL_TREE, NULL_TREE,
2310 begin_loop_scope ();
2312 build_loop_start (label);
2313 condition = check_token (WHILE) ? parse_expression () : NULL_TREE;
2315 top_loop_end_check (condition);
2316 parse_semi_colon ();
2317 parse_opt_actions ();
2320 expect (OD, "Missing 'OD' after 'DO'");
2321 /* Note that the handler is inside the reach of the DO. */
2322 parse_opt_handler ();
2323 end_loop_scope (label);
2325 parse_opt_end_label_semi_colon (label);
2328 /* Matches: '(' <signal name> [ 'IN' <defining occurrence list> ']' ')' ':'
2329 or: '(' <buffer location> IN (defining occurrence> ')' ':'
2330 or: returns NULL_TREE. */
2333 parse_receive_spec ()
2336 tree name_list = NULL_TREE;
2337 if (!check_token (LPRN))
2339 val = parse_primval ();
2340 if (check_token (IN))
2343 if (flag_local_loop_counter)
2344 name_list = parse_defining_occurrence_list ();
2350 tree loc = parse_primval ();
2352 name_list = tree_cons (NULL_TREE, loc, name_list);
2353 if (! check_token (COMMA))
2358 if (! check_token (RPRN))
2360 error ("missing ')' in signal/buffer receive alternative");
2363 if (check_token (COLON))
2365 if (ignoring || val == NULL_TREE || TREE_CODE (val) == ERROR_MARK)
2366 return error_mark_node;
2368 return build_receive_case_label (val, name_list);
2371 /* We saw: '(' <primitive value> ')' not followed by ':'.
2372 Presumably the start of an action. Backup and fail. */
2373 if (name_list != NULL_TREE)
2374 error ("misplaced 'IN' in signal/buffer receive alternative");
2375 pushback_paren_expr (val);
2379 /* To understand the code generation for this, see ch-tasking.c,
2380 and the 2-page comments preceding the
2381 build_chill_receive_case_start () definition. */
2384 parse_receive_case_action (label)
2387 tree instance_location;
2388 tree have_else_actions;
2390 tree alt_list = NULL_TREE;
2397 expand_exit_needed = 0;
2400 if (check_token (SET))
2402 instance_location = parse_expression ();
2403 parse_semi_colon ();
2406 instance_location = NULL_TREE;
2408 instance_location = build_receive_case_start (instance_location);
2412 tree receive_spec = parse_receive_spec ();
2416 alt_list = tree_cons (NULL_TREE, receive_spec, alt_list);
2419 else if (parse_action ())
2421 if (! spec_seen && pass == 1)
2422 error ("missing RECEIVE alternative");
2424 expand_exit_needed = 1;
2430 if (check_token (ELSE))
2434 emit_line_note (input_filename, lineno);
2435 if (build_receive_case_if_generated ())
2436 expand_start_else ();
2438 parse_opt_actions ();
2439 have_else_actions = integer_one_node;
2442 have_else_actions = integer_zero_node;
2443 expect (ESAC, "missing 'ESAC' matching 'RECEIVE CASE'");
2446 build_receive_case_end (nreverse (alt_list), have_else_actions);
2448 possibly_define_exit_label (label);
2453 parse_send_action ()
2455 tree signal = NULL_TREE;
2456 tree buffer = NULL_TREE;
2458 tree with_expr, to_expr, priority;
2460 /* The tricky part is distinguishing between a SEND buffer action,
2461 and a SEND signal action. */
2462 if (pass != 2 || PEEK_TOKEN () != NAME)
2464 /* If this is pass 2, it's a SEND buffer action.
2465 If it's pass 1, we don't care. */
2466 buffer = parse_primval ();
2470 /* We have to specifically check for signalname followed by
2471 a '(', since we allow a signalname to be used (syntactically)
2473 tree name = parse_name ();
2474 if (TREE_CODE (name) == TYPE_DECL && CH_DECL_SIGNAL (name))
2475 signal = name; /* It's a SEND signal action! */
2478 /* It's not a legal SEND signal action.
2479 Back up and try as a SEND buffer action. */
2480 pushback_token (EXPR, name);
2481 buffer = parse_primval ();
2484 if (check_token (LPRN))
2486 value_list = NULL_TREE;
2489 tree expr = parse_untyped_expr ();
2491 value_list = tree_cons (NULL_TREE, expr, value_list);
2492 if (! check_token (COMMA))
2495 value_list = nreverse (value_list);
2496 expect (RPRN, "missing ')'");
2499 value_list = NULL_TREE;
2500 if (check_token (WITH))
2501 with_expr = parse_expression ();
2503 with_expr = NULL_TREE;
2504 if (check_token (TO))
2505 to_expr = parse_expression ();
2507 to_expr = NULL_TREE;
2508 if (check_token (PRIORITY))
2509 priority = parse_expression ();
2511 priority = NULL_TREE;
2517 { /* It's a <send signal action>! */
2518 tree sigdesc = build_signal_descriptor (signal, value_list);
2519 if (sigdesc != NULL_TREE && TREE_CODE (sigdesc) != ERROR_MARK)
2521 tree sendto = to_expr ? to_expr : IDENTIFIER_SIGNAL_DEST (signal);
2522 expand_send_signal (sigdesc, with_expr,
2523 sendto, priority, DECL_NAME (signal));
2528 /* all checks are done in expand_send_buffer */
2529 expand_send_buffer (buffer, value_list, priority, with_expr, to_expr);
2534 parse_start_action ()
2536 tree name, copy_number, param_list, startset;
2538 name = parse_name_string ();
2539 expect (LPRN, "missing '(' in START action");
2541 /* copy number is a required parameter */
2542 copy_number = parse_expression ();
2544 && (copy_number == NULL_TREE
2545 || TREE_CODE (copy_number) == ERROR_MARK
2546 || TREE_CODE (TREE_TYPE (copy_number)) != INTEGER_TYPE))
2548 error ("PROCESS copy number must be integer");
2549 copy_number = integer_zero_node;
2551 if (check_token (COMMA))
2552 param_list = parse_expr_list (); /* user parameters */
2554 param_list = NULL_TREE;
2555 expect (RPRN, "missing ')'");
2556 startset = check_token (SET) ? parse_primval () : NULL;
2557 build_start_process (name, copy_number, param_list, startset);
2561 parse_opt_actions ()
2563 while (parse_action ()) ;
2569 tree label = NULL_TREE;
2570 tree expr, rhs, loclist;
2573 if (current_function_decl == global_function_decl
2574 && PEEK_TOKEN () != SC
2575 && PEEK_TOKEN () != END)
2576 seen_action = 1, build_constructor = 1;
2578 if (PEEK_TOKEN () == NAME && PEEK_TOKEN1 () == COLON)
2580 label = parse_defining_occurrence ();
2583 define_label (input_filename, lineno, label);
2586 switch (PEEK_TOKEN ())
2592 expr = parse_primval ();
2593 delay = check_token (DELAY);
2594 expect (IN, "missing 'IN'");
2597 build_after_start (expr, delay);
2598 parse_opt_actions ();
2599 expect (TIMEOUT, "missing 'TIMEOUT'");
2600 build_after_timeout_start ();
2601 parse_opt_actions ();
2602 expect (END, "missing 'END'");
2604 possibly_define_exit_label (label);
2607 goto bracketed_action;
2609 parse_asm_action ();
2610 goto no_handler_action;
2614 expr = parse_expression ();
2616 { tree assertfail = ridpointers[(int) RID_ASSERTFAIL];
2617 expr = build (TRUTH_ORIF_EXPR, void_type_node, expr,
2618 build_cause_exception (assertfail, 0));
2619 expand_expr_stmt (fold (expr));
2621 goto handler_action;
2625 expr = parse_primval ();
2626 expect (IN, "missing 'IN'");
2629 build_at_action (expr);
2630 parse_opt_actions ();
2631 expect (TIMEOUT, "missing 'TIMEOUT'");
2633 expand_start_else ();
2634 parse_opt_actions ();
2635 expect (END, "missing 'END'");
2638 possibly_define_exit_label (label);
2640 goto bracketed_action;
2642 parse_begin_end_block (label);
2645 parse_case_action (label);
2646 goto bracketed_action;
2649 expr = parse_name_string ();
2651 if (! ignoring && TREE_CODE (expr) != ERROR_MARK)
2652 expand_cause_exception (expr);
2653 goto no_handler_action;
2656 expr = parse_expression ();
2659 expand_continue_event (expr);
2660 goto handler_action;
2664 expr = parse_primval ();
2665 expect (IN, "missing 'IN' after 'CYCLE'");
2667 /* We a tree list where TREE_VALUE is the label
2668 and TREE_PURPOSE is the variable denotes the timeout id. */
2669 expr = build_cycle_start (expr);
2670 parse_opt_actions ();
2671 expect (END, "missing 'END'");
2673 build_cycle_end (expr);
2674 possibly_define_exit_label (label);
2676 goto bracketed_action;
2678 if (PEEK_TOKEN1 () == CASE)
2680 parse_delay_case_action (label);
2681 goto bracketed_action;
2685 expr = parse_primval ();
2686 rhs = check_token (PRIORITY) ? parse_expression () : NULL_TREE;
2688 build_delay_action (expr, rhs);
2689 goto handler_action;
2691 parse_do_action (label);
2695 expr = parse_name_string ();
2697 lookup_and_handle_exit (expr);
2698 goto no_handler_action;
2701 expr = parse_name_string ();
2703 lookup_and_expand_goto (expr);
2704 goto no_handler_action;
2706 parse_if_action (label);
2707 goto bracketed_action;
2709 if (PEEK_TOKEN1 () != CASE)
2711 parse_receive_case_action (label);
2712 goto bracketed_action;
2716 expr = parse_untyped_expr ();
2718 chill_expand_result (expr, 1);
2719 goto handler_action;
2723 expr = parse_opt_untyped_expr ();
2726 /* Do this as RESULT expr and RETURN to get exceptions */
2727 chill_expand_result (expr, 0);
2728 expand_goto_except_cleanup (proc_action_level);
2729 chill_expand_return (NULL_TREE, 0);
2732 goto handler_action;
2734 goto no_handler_action;
2739 parse_send_action ();
2740 goto handler_action;
2742 parse_start_action ();
2743 goto handler_action;
2748 { tree func = lookup_name (get_identifier ("__stop_process"));
2749 tree result = build_chill_function_call (func, NULL_TREE);
2750 expand_expr_stmt (result);
2752 goto no_handler_action;
2755 /* Fall through to here ... */
2759 /* This handles calls and assignments. */
2761 expr = parse_primval ();
2762 switch (PEEK_TOKEN ())
2765 parse_semi_colon (); /* Emits error message. */
2768 if (!ignoring && TREE_CODE (expr) != ERROR_MARK)
2770 if (TREE_CODE (expr) != CALL_EXPR
2771 && TREE_TYPE (expr) != void_type_node
2772 && ! TREE_SIDE_EFFECTS (expr))
2774 if (TREE_CODE (expr) == FUNCTION_DECL)
2775 error ("missing parenthesis for procedure call");
2777 error ("expression is not an action");
2778 expr = error_mark_node;
2781 expand_expr_stmt (expr);
2783 goto handler_action;
2786 = ignoring ? NULL_TREE : build_tree_list (NULL_TREE, expr);
2787 while (PEEK_TOKEN () == COMMA)
2790 expr = parse_primval ();
2791 if (!ignoring && TREE_CODE (expr) != ERROR_MARK)
2792 loclist = tree_cons (NULL_TREE, expr, loclist);
2795 switch (PEEK_TOKEN ())
2797 case OR: op = BIT_IOR_EXPR; break;
2798 case XOR: op = BIT_XOR_EXPR; break;
2799 case ORIF: op = TRUTH_ORIF_EXPR; break;
2800 case AND: op = BIT_AND_EXPR; break;
2801 case ANDIF: op = TRUTH_ANDIF_EXPR; break;
2802 case PLUS: op = PLUS_EXPR; break;
2803 case SUB: op = MINUS_EXPR; break;
2804 case CONCAT: op = CONCAT_EXPR; break;
2805 case MUL: op = MULT_EXPR; break;
2806 case DIV: op = TRUNC_DIV_EXPR; break;
2807 case MOD: op = FLOOR_MOD_EXPR; break;
2808 case REM: op = TRUNC_MOD_EXPR; break;
2811 error ("syntax error in action");
2813 case ASGN: op = NOP_EXPR; break;
2817 /* Looks like it was an assignment action. */
2820 expect (ASGN, "expected ':=' here");
2821 rhs = parse_untyped_expr ();
2823 expand_assignment_action (loclist, op, rhs);
2824 goto handler_action;
2831 /* We've parsed a bracketed action. */
2832 parse_opt_handler ();
2833 parse_opt_end_label_semi_colon (label);
2837 if (parse_opt_handler () != NULL_TREE && pass == 1)
2838 error ("no handler is permitted on this action.");
2839 parse_semi_colon ();
2843 parse_opt_handler ();
2844 parse_semi_colon ();
2852 while (parse_definition (0)) ;
2854 while (parse_action ()) ;
2856 if (parse_definition (0))
2859 pedwarn ("definition follows action");
2865 parse_opt_untyped_expr ()
2867 switch (PEEK_TOKEN ())
2877 return parse_untyped_expr ();
2882 parse_call (function)
2885 tree arg1, arg2, arg_list = NULL_TREE;
2888 arg1 = parse_opt_untyped_expr ();
2889 if (arg1 != NULL_TREE)
2891 tok = PEEK_TOKEN ();
2892 if (tok == UP || tok == COLON)
2896 /* check that arg1 isn't untyped (or mode);*/
2898 arg2 = parse_expression ();
2899 expect (RPRN, "expected ')' to terminate slice");
2901 return integer_zero_node;
2903 return build_chill_slice_with_length (function, arg1, arg2);
2905 return build_chill_slice_with_range (function, arg1, arg2);
2908 arg_list = build_tree_list (NULL_TREE, arg1);
2909 while (check_token (COMMA))
2911 arg2 = parse_untyped_expr ();
2913 arg_list = tree_cons (NULL_TREE, arg2, arg_list);
2917 expect (RPRN, "expected ')' here");
2918 return ignoring ? function
2919 : build_generalized_call (function, nreverse (arg_list));
2922 /* Matches: <field name list>
2923 Returns: A list of IDENTIFIER_NODEs (or NULL_TREE if ignoring),
2924 in reverse order. */
2927 parse_tuple_fieldname_list ()
2929 tree list = NULL_TREE;
2933 if (!check_token (DOT))
2935 error ("bad tuple field name list");
2938 name = parse_simple_name_string ();
2939 list = ignoring ? NULL_TREE : tree_cons (NULL_TREE, name, list);
2940 } while (check_token (COMMA));
2944 /* Returns one or nore TREE_LIST nodes, in reverse order. */
2947 parse_tuple_element ()
2949 /* The tupleelement chain is built in reverse order,
2950 and put in forward order when the list is used. */
2952 if (PEEK_TOKEN () == DOT)
2954 /* Parse a labelled structure tuple. */
2955 tree list = parse_tuple_fieldname_list (), field;
2956 expect (COLON, "missing ':' in tuple");
2957 value = parse_untyped_expr ();
2960 /* FIXME: Should use save_expr(value), but that
2961 confuses nested calls to digest_init! */
2962 /* Re-use the list of field names as a list of name-value pairs. */
2963 for (field = list; field != NULL_TREE; field = TREE_CHAIN (field))
2964 { tree field_name = TREE_VALUE (field);
2965 TREE_PURPOSE (field) = field_name;
2966 TREE_VALUE (field) = value;
2967 TUPLE_NAMED_FIELD (field) = 1;
2972 label = parse_case_label_list (NULL_TREE, 1);
2975 expect (COLON, "missing ':' in tuple");
2976 value = parse_untyped_expr ();
2977 if (ignoring || label == NULL_TREE)
2979 if (TREE_CODE (label) != TREE_LIST)
2981 error ("invalid syntax for label in tuple");
2986 /* FIXME: Should use save_expr(value), but that
2987 confuses nested calls to digest_init! */
2989 for (; link != NULL_TREE; link = TREE_CHAIN (link))
2990 { tree index = TREE_VALUE (link);
2991 if (pass == 1 && TREE_CODE (index) != TREE_LIST)
2992 index = build1 (PAREN_EXPR, NULL_TREE, index);
2993 TREE_VALUE (link) = value;
2994 TREE_PURPOSE (link) = index;
2996 return nreverse (label);
3000 value = parse_untyped_expr ();
3001 if (check_token (COLON))
3003 /* A powerset range [or possibly a labeled Array?] */
3004 tree value2 = parse_untyped_expr ();
3005 return ignoring ? NULL_TREE : build_tree_list (value, value2);
3007 return ignoring ? NULL_TREE : build_tree_list (NULL_TREE, value);
3010 /* Matches: a COMMA-separated list of tuple elements.
3011 Returns a list (of TREE_LIST nodes). */
3013 parse_opt_element_list ()
3015 tree list = NULL_TREE;
3016 if (PEEK_TOKEN () == RPC)
3020 tree element = parse_tuple_element ();
3021 list = chainon (element, list); /* Built in reverse order */
3022 if (PEEK_TOKEN () == RPC)
3024 if (!check_token (COMMA))
3026 error ("bad syntax in tuple");
3030 return nreverse (list);
3033 /* Parses: '[' elements ']'
3034 If modename is non-NULL it prefixed the tuple. */
3037 parse_tuple (modename)
3042 list = parse_opt_element_list ();
3043 expect (RPC, "missing ']' after tuple");
3045 return integer_zero_node;
3046 list = build_nt (CONSTRUCTOR, NULL_TREE, list);
3047 if (modename == NULL_TREE)
3050 TREE_TYPE (list) = modename;
3051 else if (TREE_CODE (modename) != TYPE_DECL)
3053 error ("non-mode name before tuple");
3054 return error_mark_node;
3057 list = chill_expand_tuple (TREE_TYPE (modename), list);
3065 switch (PEEK_TOKEN ())
3078 val = build_chill_function_call (PEEK_TREE (), NULL_TREE);
3083 val = parse_expression ();
3084 expect (RPRN, "missing right parenthesis");
3085 if (pass == 1 && ! ignoring)
3086 val = build1 (PAREN_EXPR, NULL_TREE, val);
3089 val = parse_tuple (NULL_TREE);
3092 val = parse_name ();
3093 if (PEEK_TOKEN() == LPC)
3094 val = parse_tuple (val); /* Matched: <mode_name> <tuple> */
3098 error ("invalid expression/location syntax");
3099 val = error_mark_node;
3104 switch (PEEK_TOKEN ())
3108 name = parse_simple_name_string ();
3109 val = ignoring ? val : build_chill_component_ref (val, name);
3113 name = parse_opt_name_string (0);
3114 val = ignoring ? val : build_chill_indirect_ref (val, name, 1);
3117 /* The SEND buffer action syntax is ambiguous, at least when
3118 parsed left-to-right. In the example 'SEND foo(v) ...' the
3119 phrase 'foo(v)' could be a buffer location procedure call
3120 (which then must be followed by the value to send).
3121 On the other hand, if 'foo' is a buffer, stop parsing
3122 after 'foo', and let parse_send_action pick up '(v) as
3125 We handle the ambiguity for SEND signal action differently,
3126 since we allow (as an extension) a signal to be used as
3127 a "function" (see build_generalized_call). */
3128 if (TREE_TYPE (val) != NULL_TREE
3129 && CH_IS_BUFFER_MODE (TREE_TYPE (val)))
3131 val = parse_call (val);
3137 /* Handle string repetition. (See comment in parse_operand5.) */
3138 args = parse_primval ();
3139 val = ignoring ? val : build_generalized_call (val, args);
3152 if (check_token (RECEIVE))
3154 tree location ATTRIBUTE_UNUSED = parse_primval ();
3155 sorry ("RECEIVE expression");
3156 return integer_one_node;
3158 else if (check_token (ARROW))
3160 tree location = parse_primval ();
3161 return ignoring ? location : build_chill_arrow_expr (location, 0);
3164 return parse_primval();
3171 /* We are supposed to be looking for a <string repetition operator>,
3172 but in general we can't distinguish that from a parenthesized
3173 expression. This is especially difficult if we allow the
3174 string operand to be a constant expression (as requested by
3175 some users), and not just a string literal.
3176 Consider: LPRN expr RPRN LPRN expr RPRN
3177 Is that a function call or string repetition?
3178 Instead, we handle string repetition in parse_primval,
3179 and build_generalized_call. */
3181 switch (PEEK_TOKEN())
3183 case NOT: op = BIT_NOT_EXPR; break;
3184 case SUB: op = NEGATE_EXPR; break;
3190 rarg = parse_operand6();
3191 return (op == NOP_EXPR || ignoring) ? rarg
3192 : build_chill_unary_op (op, rarg);
3198 tree larg = parse_operand5(), rarg;
3202 switch (PEEK_TOKEN())
3204 case MUL: op = MULT_EXPR; break;
3205 case DIV: op = TRUNC_DIV_EXPR; break;
3206 case MOD: op = FLOOR_MOD_EXPR; break;
3207 case REM: op = TRUNC_MOD_EXPR; break;
3212 rarg = parse_operand5();
3214 larg = build_chill_binary_op (op, larg, rarg);
3221 tree larg = parse_operand4 (), rarg;
3225 switch (PEEK_TOKEN())
3227 case PLUS: op = PLUS_EXPR; break;
3228 case SUB: op = MINUS_EXPR; break;
3229 case CONCAT: op = CONCAT_EXPR; break;
3234 rarg = parse_operand4();
3236 larg = build_chill_binary_op (op, larg, rarg);
3243 tree larg = parse_operand3 (), rarg;
3247 if (check_token (IN))
3249 rarg = parse_operand3();
3251 larg = build_chill_binary_op (SET_IN_EXPR, larg, rarg);
3255 switch (PEEK_TOKEN())
3257 case GT: op = GT_EXPR; break;
3258 case GTE: op = GE_EXPR; break;
3259 case LT: op = LT_EXPR; break;
3260 case LTE: op = LE_EXPR; break;
3261 case EQL: op = EQ_EXPR; break;
3262 case NE: op = NE_EXPR; break;
3267 rarg = parse_operand3();
3269 larg = build_compare_expr (op, larg, rarg);
3277 tree larg = parse_operand2 (), rarg;
3281 switch (PEEK_TOKEN())
3283 case AND: op = BIT_AND_EXPR; break;
3284 case ANDIF: op = TRUTH_ANDIF_EXPR; break;
3289 rarg = parse_operand2();
3291 larg = build_chill_binary_op (op, larg, rarg);
3298 tree larg = parse_operand1(), rarg;
3302 switch (PEEK_TOKEN())
3304 case OR: op = BIT_IOR_EXPR; break;
3305 case XOR: op = BIT_XOR_EXPR; break;
3306 case ORIF: op = TRUTH_ORIF_EXPR; break;
3311 rarg = parse_operand1();
3313 larg = build_chill_binary_op (op, larg, rarg);
3320 return parse_operand0 ();
3324 parse_case_expression ()
3329 tree case_alt_list = NULL_TREE;
3332 selector_list = parse_expr_list ();
3333 selector_list = nreverse (selector_list);
3335 expect (OF, "missing 'OF'");
3336 while (PEEK_TOKEN () == LPRN)
3338 tree label_spec = parse_case_label_specification (selector_list);
3340 expect (COLON, "missing ':' in value case alternative");
3341 sub_expr = parse_expression ();
3342 expect (SC, "missing ';'");
3344 case_alt_list = tree_cons (label_spec, sub_expr, case_alt_list);
3346 if (check_token (ELSE))
3348 else_expr = parse_expression ();
3349 if (check_token (SC) && pass == 1)
3350 warning("there should not be a ';' here");
3353 else_expr = NULL_TREE;
3354 expect (ESAC, "missing 'ESAC' in 'CASE' expression");
3357 return integer_zero_node;
3359 /* If this is a multi dimension case, then transform it into an COND_EXPR
3360 here. This must be done before store_expr is called since it has some
3361 special handling for COND_EXPR expressions. */
3362 if (TREE_CHAIN (selector_list) != NULL_TREE)
3364 case_alt_list = nreverse (case_alt_list);
3365 compute_else_ranges (selector_list, case_alt_list);
3367 build_chill_multi_dimension_case_expr (selector_list, case_alt_list, else_expr);
3370 case_expr = build_chill_case_expr (selector_list, case_alt_list, else_expr);
3376 parse_then_alternative ()
3378 expect (THEN, "missing 'THEN' in 'IF' expression");
3379 return parse_expression ();
3383 parse_else_alternative ()
3385 if (check_token (ELSIF))
3386 return parse_if_expression_body ();
3387 else if (check_token (ELSE))
3388 return parse_expression ();
3389 error ("missing ELSE/ELSIF in IF expression");
3390 return error_mark_node;
3393 /* Matches: <boolean expression> <then alternative> <else alternative> */
3396 parse_if_expression_body ()
3398 tree bool_expr, then_expr, else_expr;
3399 bool_expr = parse_expression ();
3400 then_expr = parse_then_alternative ();
3401 else_expr = parse_else_alternative ();
3403 return integer_zero_node;
3405 return build_nt (COND_EXPR, bool_expr, then_expr, else_expr);
3409 parse_if_expression ()
3413 expr = parse_if_expression_body ();
3414 expect (FI, "missing 'FI' at end of conditional expression");
3418 /* An <untyped_expr> is a superset of <expr>. It also includes
3419 <conditional expressions> and untyped <tuples>, whose types
3420 are not given by their constituents. Hence, these are only
3421 allowed in certain contexts that expect a certain type.
3422 You should call convert() to fix up the <untyped_expr>. */
3425 parse_untyped_expr ()
3428 switch (PEEK_TOKEN())
3431 return parse_if_expression ();
3433 return parse_case_expression ();
3435 switch (PEEK_TOKEN1())
3440 pedwarn ("conditional expression not allowed inside parentheses");
3444 pedwarn ("mode-less tuple not allowed inside parentheses");
3447 val = parse_untyped_expr ();
3448 expect (RPRN, "missing ')'");
3454 return parse_operand0 ();
3458 /* Matches: <index mode> */
3463 /* This is another one that is nasty to parse!
3464 Let's feel our way ahead ... */
3466 if (PEEK_TOKEN () == NAME)
3468 tree name = parse_name ();
3469 switch (PEEK_TOKEN ())
3473 case SC: /* An error */
3474 /* This can only (legally) be a discrete mode name. */
3477 /* This could be named discrete range,
3478 a cast, or some other expression (maybe). */
3480 lower = parse_expression ();
3481 if (check_token (COLON))
3483 upper = parse_expression ();
3484 expect (RPRN, "missing ')'");
3485 /* Matched: <mode_name> '(' <expr> ':' <expr> ')' */
3489 return build_chill_range_type (name, lower, upper);
3491 /* Looks like a cast or procedure call or something.
3492 Backup, and try again. */
3493 pushback_token (EXPR, lower);
3494 pushback_token (LPRN, NULL_TREE);
3495 lower = parse_call (name);
3496 goto parse_literal_range_colon;
3498 /* This has to be the start of an expression. */
3499 pushback_token (EXPR, name);
3500 goto parse_literal_range;
3503 /* It's not a name. But it could still be a discrete mode. */
3504 lower = parse_opt_mode ();
3507 parse_literal_range:
3508 /* Nope, it's a discrete literal range. */
3509 lower = parse_expression ();
3510 parse_literal_range_colon:
3511 expect (COLON, "expected ':' here");
3513 upper = parse_expression ();
3514 return ignoring ? NULL_TREE
3515 : build_chill_range_type (NULL_TREE, lower, upper);
3521 int set_name_cnt = 0; /* count of named set elements */
3522 int set_is_numbered = 0; /* TRUE if set elements have explicit values */
3523 int set_is_not_numbered = 0;
3524 tree list = NULL_TREE;
3525 tree mode = ignoring ? void_type_node : start_enum (NULL_TREE);
3527 expect (LPRN, "missing left parenthesis after SET");
3530 tree name, value = NULL_TREE;
3531 if (check_token (MUL))
3535 name = parse_defining_occurrence ();
3536 if (check_token (EQL))
3538 value = parse_expression ();
3539 set_is_numbered = 1;
3542 set_is_not_numbered = 1;
3545 name = build_enumerator (name, value);
3547 list = chainon (name, list);
3548 if (! check_token (COMMA))
3551 expect (RPRN, "missing right parenthesis after SET");
3554 if (set_is_numbered && set_is_not_numbered)
3555 /* Z.200 doesn't allow mixed numbered and unnumbered set elements,
3556 but we can do it. Print a warning */
3557 pedwarn ("mixed numbered and unnumbered set elements is not standard");
3558 mode = finish_enum (mode, list);
3559 if (set_name_cnt == 0)
3560 error ("SET mode must define at least one named value");
3561 CH_ENUM_IS_NUMBERED(mode) = set_is_numbered ? 1 : 0;
3566 /* parse layout POS:
3567 returns a tree with following layout
3570 pupose=treelist value=NULL_TREE (to indicate POS)
3571 pupose=word value=treelist | NULL_TREE
3572 pupose=startbit value=treelist | NULL_TREE
3574 integer_zero | integer_one length | endbit
3580 tree startbit = NULL_TREE, endbit = NULL_TREE;
3581 tree what = NULL_TREE;
3584 word = parse_untyped_expr ();
3585 if (check_token (COMMA))
3587 startbit = parse_untyped_expr ();
3588 if (check_token (COMMA))
3590 what = integer_zero_node;
3591 endbit = parse_untyped_expr ();
3593 else if (check_token (COLON))
3595 what = integer_one_node;
3596 endbit = parse_untyped_expr ();
3601 /* build the tree as described above */
3602 if (what != NULL_TREE)
3603 what = tree_cons (what, endbit, NULL_TREE);
3604 if (startbit != NULL_TREE)
3605 startbit = tree_cons (startbit, what, NULL_TREE);
3606 endbit = tree_cons (word, startbit, NULL_TREE);
3607 return tree_cons (endbit, NULL_TREE, NULL_TREE);
3610 /* parse layout STEP
3611 returns a tree with the following layout
3614 pupose=NULL_TREE value=treelist (to indicate STEP)
3615 pupose=POS(see baove) value=stepsize | NULL_TREE
3621 tree stepsize = NULL_TREE;
3626 if (check_token (COMMA))
3627 stepsize = parse_untyped_expr ();
3629 TREE_VALUE (pos) = stepsize;
3630 return tree_cons (NULL_TREE, pos, NULL_TREE);
3633 /* returns layout for fields or array elements.
3634 NULL_TREE no layout specified
3635 integer_one_node PACK specified
3636 integer_zero_node NOPACK specified
3637 tree_list PURPOSE POS
3638 tree_list VALUE STEP
3641 parse_opt_layout (in)
3642 int in; /* 0 ... parse structure, 1 ... parse array */
3644 tree val = NULL_TREE;
3646 if (check_token (PACK))
3648 return integer_one_node;
3650 else if (check_token (NOPACK))
3652 return integer_zero_node;
3654 else if (check_token (POS))
3657 if (in == 1 && pass == 1)
3659 error ("POS not allowed for ARRAY");
3664 else if (check_token (STEP))
3666 val = parse_step ();
3667 if (in == 0 && pass == 1)
3669 error ("STEP not allowed in field definition");
3679 parse_field_name_list ()
3681 tree chain = NULL_TREE;
3682 tree name = parse_defining_occurrence ();
3683 if (name == NULL_TREE)
3685 error("missing field name");
3688 chain = build_tree_list (NULL_TREE, name);
3689 while (check_token (COMMA))
3691 name = parse_defining_occurrence ();
3694 error ("bad field name following ','");
3698 chain = tree_cons (NULL_TREE, name, chain);
3703 /* Matches: <fixed field> or <variant field>, i.e.:
3704 <field name defining occurrence list> <mode> [ <field layout> ].
3705 Returns: A chain of FIELD_DECLs.
3706 NULL_TREE is returned if ignoring is true or an error is seen. */
3709 parse_fixed_field ()
3711 tree field_names = parse_field_name_list ();
3712 tree mode = parse_mode ();
3713 tree layout = parse_opt_layout (0);
3714 return ignoring ? NULL_TREE
3715 : grok_chill_fixedfields (field_names, mode, layout);
3719 /* Matches: [ <variant field> { "," <variant field> }* ]
3720 Returns: A chain of FIELD_DECLs.
3721 NULL_TREE is returned if ignoring is true or an error is seen. */
3724 parse_variant_field_list ()
3726 tree fields = NULL_TREE;
3727 if (PEEK_TOKEN () != NAME)
3731 fields = chainon (fields, parse_fixed_field ());
3732 if (PEEK_TOKEN () != COMMA || PEEK_TOKEN1 () != NAME)
3739 /* Matches: <variant alternative>
3740 Returns a TREE_LIST node, whose TREE_PURPOSE (if non-NULL) is the label,
3741 and whose TREE_VALUE is the list of FIELD_DECLs. */
3744 parse_variant_alternative ()
3748 if (PEEK_TOKEN () == LPRN)
3749 labels = parse_case_label_specification (NULL_TREE);
3752 if (! check_token (COLON))
3754 error ("expected ':' in structure variant alternative");
3758 /* We now read a list a variant fields, until we come to the end
3759 of the variant alternative. But since both variant fields
3760 *and* variant alternatives are separated by COMMAs,
3761 we will have to look ahead to distinguish the start of a variant
3762 field from the start of a new variant alternative.
3763 We use the fact that a variant alternative must start with
3764 either a LPRN or a COLON, while a variant field must start with a NAME.
3765 This look-ahead is handled by parse_simple_fields. */
3766 return build_tree_list (labels, parse_variant_field_list ());
3769 /* Parse <field> (which is <fixed field> or <alternative field>).
3770 Returns: A chain of FIELD_DECLs (or NULL_TREE on error or if ignoring). */
3775 if (check_token (CASE))
3777 tree tag_list = NULL_TREE, variants, opt_variant_else;
3778 if (PEEK_TOKEN () == NAME)
3780 tag_list = nreverse (parse_field_name_list ());
3782 tag_list = lookup_tag_fields (tag_list, current_fieldlist);
3784 expect (OF, "missing 'OF' in alternative structure field");
3786 variants = parse_variant_alternative ();
3787 while (check_token (COMMA))
3788 variants = chainon (parse_variant_alternative (), variants);
3789 variants = nreverse (variants);
3791 if (check_token (ELSE))
3792 opt_variant_else = parse_variant_field_list ();
3794 opt_variant_else = NULL_TREE;
3795 expect (ESAC, "missing 'ESAC' following alternative structure field");
3798 return grok_chill_variantdefs (tag_list, variants, opt_variant_else);
3800 else if (PEEK_TOKEN () == NAME)
3801 return parse_fixed_field ();
3805 error ("missing field");
3811 parse_structure_mode ()
3813 tree save_fieldlist = current_fieldlist;
3816 expect (LPRN, "expected '(' after STRUCT");
3817 current_fieldlist = fields = parse_field ();
3818 while (check_token (COMMA))
3819 fields = chainon (fields, parse_field ());
3820 expect (RPRN, "expected ')' after STRUCT");
3821 current_fieldlist = save_fieldlist;
3822 return ignoring ? void_type_node : build_chill_struct_type (fields);
3826 parse_opt_queue_size ()
3828 if (check_token (LPRN))
3830 tree size = parse_expression ();
3831 expect (RPRN, "missing ')'");
3839 parse_procedure_mode ()
3841 tree param_types = NULL_TREE, result_spec, except_list, recursive;
3843 expect (LPRN, "missing '(' after PROC");
3844 if (! check_token (RPRN))
3848 tree pmode = parse_mode ();
3849 tree paramattr = parse_param_attr ();
3852 pmode = get_type_of (pmode);
3853 param_types = tree_cons (paramattr, pmode, param_types);
3855 if (! check_token (COMMA))
3858 expect (RPRN, "missing ')' after PROC");
3860 result_spec = parse_opt_result_spec ();
3861 except_list = parse_opt_except ();
3862 recursive = parse_opt_recursive ();
3864 return void_type_node;
3865 return build_chill_pointer_type (build_chill_function_type
3866 (result_spec, nreverse (param_types),
3867 except_list, recursive));
3871 A NAME will be assumed to be a <mode name>, and thus a <mode>.
3872 Returns NULL_TREE if no mode is seen.
3873 (If ignoring is true, the return value may be an arbitrary tree node,
3874 but will be non-NULL if something that could be a mode is seen.) */
3879 switch (PEEK_TOKEN ())
3883 tree index_mode, record_mode;
3886 if (check_token (LPRN))
3888 index_mode = parse_index_mode ();
3889 expect (RPRN, "mssing ')'");
3892 index_mode = NULL_TREE;
3893 record_mode = parse_opt_mode ();
3895 dynamic = check_token (DYNAMIC);
3896 return ignoring ? void_type_node
3897 : build_access_mode (index_mode, record_mode, dynamic);
3901 tree index_list = NULL_TREE, base_mode;
3903 int num_index_modes = 0;
3905 tree layouts = NULL_TREE;
3907 expect (LPRN, "missing '(' after ARRAY");
3910 tree index = parse_index_mode ();
3913 index_list = tree_cons (NULL_TREE, index, index_list);
3914 if (! check_token (COMMA))
3917 expect (RPRN, "missing ')' after ARRAY");
3918 varying = check_token (VARYING);
3919 base_mode = parse_mode ();
3920 /* Allow a layout specification for each index mode */
3921 for (i = 0; i < num_index_modes; ++i)
3923 tree new_layout = parse_opt_layout (1);
3924 if (new_layout == NULL_TREE)
3927 layouts = tree_cons (NULL_TREE, new_layout, layouts);
3931 return build_chill_array_type (get_type_of (base_mode),
3932 index_list, varying, layouts);
3935 require (ASSOCIATION);
3936 return association_type_node;
3940 expect (LPRN, "missing left parenthesis after BIN");
3941 length = parse_expression ();
3942 expect (RPRN, "missing right parenthesis after BIN");
3943 return ignoring ? void_type_node : build_chill_bin_type (length);
3949 expect (LPRN, "missing '(' after BOOLS");
3950 length = parse_expression ();
3951 expect (RPRN, "missing ')' after BOOLS");
3952 if (check_token (VARYING))
3953 error ("VARYING bit-strings not implemented");
3954 return ignoring ? void_type_node : build_bitstring_type (length);
3958 tree qsize, element_mode;
3960 qsize = parse_opt_queue_size ();
3961 element_mode = parse_mode ();
3962 return ignoring ? element_mode
3963 : build_buffer_type (element_mode, qsize);
3971 expect (LPRN, "missing '(' after CHARS");
3972 length = parse_expression ();
3973 expect (RPRN, "missing ')' after CHARS");
3974 varying = check_token (VARYING);
3976 return void_type_node;
3977 type = build_string_type (char_type_node, length);
3979 type = build_varying_struct (type);
3986 qsize = parse_opt_queue_size ();
3987 return ignoring ? void_type_node : build_event_type (qsize);
3991 tree mode = get_type_of (parse_name ());
3992 if (check_token (LPRN))
3994 tree min_value = parse_expression ();
3995 if (check_token (COLON))
3997 tree max_value = parse_expression ();
3998 expect (RPRN, "syntax error - expected ')'");
3999 /* Matched: <mode_name> '(' <expr> ':' <expr> ')' */
4003 return build_chill_range_type (mode, min_value, max_value);
4005 if (check_token (RPRN))
4007 int varying = check_token (VARYING);
4010 if (mode == char_type_node || varying)
4012 if (mode != char_type_node
4013 && mode != ridpointers[(int) RID_CHAR])
4014 error ("strings must be composed of chars");
4015 mode = build_string_type (char_type_node, min_value);
4017 mode = build_varying_struct (mode);
4021 /* Parameterized mode,
4022 or old-fashioned CHAR(N) string declaration.. */
4023 tree pmode = make_node (LANG_TYPE);
4024 TREE_TYPE (pmode) = mode;
4025 TYPE_DOMAIN (pmode) = min_value;
4036 mode = parse_mode ();
4037 if (ignoring || TREE_CODE (mode) == ERROR_MARK)
4039 return build_powerset_type (get_type_of (mode));
4042 return parse_procedure_mode ();
4046 expect (LPRN, "missing left parenthesis after RANGE");
4047 low = parse_expression ();
4048 expect (COLON, "missing colon");
4049 high = parse_expression ();
4050 expect (RPRN, "missing right parenthesis after RANGE");
4051 return ignoring ? void_type_node
4052 : build_chill_range_type (NULL_TREE, low, high);
4057 tree mode2 = get_type_of (parse_mode ());
4058 if (ignoring || TREE_CODE (mode2) == ERROR_MARK)
4061 && TREE_CODE_CLASS (TREE_CODE (mode2)) == 'd'
4062 && CH_IS_BUFFER_MODE (mode2))
4064 error ("BUFFER modes may not be readonly");
4068 && TREE_CODE_CLASS (TREE_CODE (mode2)) == 'd'
4069 && CH_IS_EVENT_MODE (mode2))
4071 error ("EVENT modes may not be readonly");
4074 return build_readonly_type (mode2);
4080 mode = parse_mode ();
4083 mode = get_type_of (mode);
4084 return (TREE_CODE (mode) == ERROR_MARK) ? mode
4085 : build_chill_pointer_type (mode);
4088 return parse_set_mode ();
4091 error ("SIGNAL is not a valid mode");
4092 return generic_signal_type_node;
4094 return parse_structure_mode ();
4097 tree length, index_mode;
4100 expect (LPRN, "missing '('");
4101 length = parse_expression ();
4102 expect (RPRN, "missing ')'");
4103 /* FIXME: This should actually look for an optional index_mode,
4104 but that is tricky to do. */
4105 index_mode = parse_opt_mode ();
4106 dynamic = check_token (DYNAMIC);
4107 return ignoring ? void_type_node
4108 : build_text_mode (length, index_mode, dynamic);
4112 return usage_type_node;
4115 return where_type_node;
4124 tree mode = parse_opt_mode ();
4125 if (mode == NULL_TREE)
4128 error ("syntax error - missing mode");
4129 mode = error_mark_node;
4137 /* Initialize global variables for current pass. */
4139 expand_exit_needed = 0;
4140 label = NULL_TREE; /* for statement labels */
4141 current_module = NULL;
4142 current_function_decl = NULL_TREE;
4143 in_pseudo_module = 0;
4145 for (i = 0; i <= MAX_LOOK_AHEAD; i++)
4146 terminal_buffer[i] = TOKEN_NOT_READ;
4149 /* skip some junk */
4150 while (PEEK_TOKEN() == HEADEREL)
4154 start_outer_function ();
4158 tree label = parse_optlabel ();
4159 if (PEEK_TOKEN() == MODULE || PEEK_TOKEN() == REGION)
4160 parse_modulion (label);
4161 else if (PEEK_TOKEN() == SPEC)
4162 parse_spec_module (label);
4166 finish_outer_function ();
4173 if (PEEK_TOKEN() != END_PASS_1)
4175 error ("syntax error - expected a module or end of file");
4178 chill_finish_compile ();
4180 exit (FATAL_EXIT_CODE);
4181 switch_to_pass_2 ();
4183 except_init_pass_2 ();
4186 chill_finish_compile ();
4196 * We've had an error. Move the compiler's state back to
4197 * the global binding level. This prevents the loop in
4198 * compile_file in toplev.c from looping forever, since the
4199 * CHILL poplevel() has *no* effect on the value returned by
4200 * global_bindings_p().
4203 to_global_binding_level ()
4205 while (! global_bindings_p ())
4206 current_function_decl = DECL_CONTEXT (current_function_decl);
4212 /* Sets the value of the 'yydebug' variable to VALUE.
4213 This is a function so we don't have to have YYDEBUG defined
4214 in order to build the compiler. */
4222 warning ("YYDEBUG not defined.");