aboutsummaryrefslogtreecommitdiff
path: root/gcc/ch/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ch/parse.c')
-rw-r--r--gcc/ch/parse.c4332
1 files changed, 0 insertions, 4332 deletions
diff --git a/gcc/ch/parse.c b/gcc/ch/parse.c
deleted file mode 100644
index afcf1427fd8..00000000000
--- a/gcc/ch/parse.c
+++ /dev/null
@@ -1,4332 +0,0 @@
-/* Parser for GNU CHILL (CCITT High-Level Language) -*- C -*-
- Copyright (C) 1992, 1993, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/*
- * This is a two-pass parser. In pass 1, we collect declarations,
- * ignoring actions and most expressions. We store only the
- * declarations and close, open and re-lex the input file to save
- * main memory. We anticipate that the compiler will be processing
- * *very* large single programs which are mechanically generated,
- * and so we want to store a minimum of information between passes.
- *
- * yylex detects the end of the main input file and returns the
- * END_PASS_1 token. We then re-initialize each CHILL compiler
- * module's global variables and re-process the input file. The
- * grant file is output. If the user has requested it, GNU CHILL
- * exits at this time - its only purpose was to generate the grant
- * file. Optionally, the compiler may exit if errors were detected
- * in pass 1.
- *
- * As each symbol scope is entered, we install its declarations into
- * the symbol table. Undeclared types and variables are announced
- * now.
- *
- * Then code is generated.
- */
-
-#include "config.h"
-#include "system.h"
-#include "tree.h"
-#include "ch-tree.h"
-#include "lex.h"
-#include "actions.h"
-#include "tasking.h"
-#include "parse.h"
-#include "toplev.h"
-
-/* Since parsers are distinct for each language, put the
- language string definition here. (fnf) */
-const char * const language_string = "GNU CHILL";
-
-/* Common code to be done before expanding any action. */
-#define INIT_ACTION { \
- if (! ignoring) emit_line_note (input_filename, lineno); }
-
-/* Pop a scope for an ON handler. */
-#define POP_USED_ON_CONTEXT pop_handler(1)
-
-/* Pop a scope for an ON handler that wasn't there. */
-#define POP_UNUSED_ON_CONTEXT pop_handler(0)
-
-#define PUSH_ACTION push_action()
-
-/* Cause the `yydebug' variable to be defined. */
-#define YYDEBUG 1
-
-extern struct rtx_def* gen_label_rtx PARAMS ((void));
-extern void emit_jump PARAMS ((struct rtx_def *));
-extern struct rtx_def* emit_label PARAMS ((struct rtx_def *));
-
-/* This is a hell of a lot easier than getting expr.h included in
- by parse.c. */
-extern struct rtx_def *expand_expr PARAMS ((tree, struct rtx_def *,
- enum machine_mode, int));
-
-static int parse_action PARAMS ((void));
-static void ch_parse_init PARAMS ((void));
-static void check_end_label PARAMS ((tree, tree));
-static void end_function PARAMS ((void));
-static tree build_prefix_clause PARAMS ((tree));
-static enum terminal PEEK_TOKEN PARAMS ((void));
-static int peek_token_ PARAMS ((int));
-static void pushback_token PARAMS ((int, tree));
-static void forward_token_ PARAMS ((void));
-static void require PARAMS ((enum terminal));
-static int check_token PARAMS ((enum terminal));
-static int expect PARAMS ((enum terminal, const char *));
-static void define__PROCNAME__ PARAMS ((void));
-
-extern int lineno;
-extern tree generic_signal_type_node;
-extern tree signal_code;
-extern int all_static_flag;
-extern int ignore_case;
-
-#if 0
-static int quasi_signal = 0; /* 1 if processing a quasi signal decl */
-#endif
-
-int parsing_newmode; /* 0 while parsing SYNMODE;
- 1 while parsing NEWMODE. */
-int expand_exit_needed = 0;
-
-/* Gets incremented if we see errors such that we don't want to run pass 2. */
-
-int serious_errors = 0;
-
-static tree current_fieldlist;
-
-/* We don't care about expressions during pass 1, except while we're
- parsing the RHS of a SYN definition, or while parsing a mode that
- we need. NOTE: This also causes mode expressions to be ignored. */
-int ignoring = 1; /* 1 to ignore expressions */
-
-/* True if we have seen an action not in a (user) function. */
-int seen_action = 0;
-int build_constructor = 0;
-
-/* The action_nesting_level of the current procedure body. */
-int proc_action_level = 0;
-
-/* This is the identifier of the label that prefixes the current action,
- or NULL if there was none. It is cleared at the end of an action,
- or when starting a nested action list, so get it while you can! */
-static tree label = NULL_TREE; /* for statement labels */
-
-#if 0
-static tree current_block;
-#endif
-
-int in_pseudo_module = 0;
-int pass = 0; /* 0 for init_decl_processing,
- 1 for pass 1, 2 for pass 2 */
-
-/* re-initialize global variables for pass 2 */
-static void
-ch_parse_init ()
-{
- expand_exit_needed = 0;
- label = NULL_TREE; /* for statement labels */
- current_module = NULL;
- in_pseudo_module = 0;
-}
-
-static void
-check_end_label (start, end)
- tree start, end;
-{
- if (end != NULL_TREE)
- {
- if (start == NULL_TREE && pass == 1)
- error ("there was no start label to match the end label '%s'",
- IDENTIFIER_POINTER(end));
- else if (start != end && pass == 1)
- error ("start label '%s' does not match end label '%s'",
- IDENTIFIER_POINTER(start),
- IDENTIFIER_POINTER(end));
- }
-}
-
-
-/*
- * given a tree which is an id, a type or a decl,
- * return the associated type, or issue an error and
- * return error_mark_node.
- */
-tree
-get_type_of (id_or_decl)
- tree id_or_decl;
-{
- tree type = id_or_decl;
-
- if (id_or_decl == NULL_TREE
- || TREE_CODE (id_or_decl) == ERROR_MARK)
- return error_mark_node;
-
- if (pass == 1 || ignoring == 1)
- return id_or_decl;
-
- if (TREE_CODE (type) == IDENTIFIER_NODE)
- {
- type = lookup_name (id_or_decl);
- if (type == NULL_TREE)
- {
- error ("`%s' not declared", IDENTIFIER_POINTER (id_or_decl));
- type = error_mark_node;
- }
- }
- if (TREE_CODE (type) == TYPE_DECL)
- type = TREE_TYPE (type);
- return type; /* was a type all along */
-}
-
-
-static void
-end_function ()
-{
- if (CH_DECL_PROCESS (current_function_decl))
- {
- /* finishing a process */
- if (! ignoring)
- {
- tree result =
- build_chill_function_call
- (lookup_name (get_identifier ("__stop_process")),
- NULL_TREE);
- expand_expr_stmt (result);
- emit_line_note (input_filename, lineno);
- }
- }
- else
- {
- /* finishing a procedure.. */
- if (! ignoring)
- {
- if (result_never_set
- && TREE_CODE (TREE_TYPE (TREE_TYPE (current_function_decl)))
- != VOID_TYPE)
- warning ("No RETURN or RESULT in procedure");
- chill_expand_return (NULL_TREE, 1);
- }
- }
- finish_chill_function ();
- pop_chill_function_context ();
-}
-
-static tree
-build_prefix_clause (id)
- tree id;
-{
- if (!id)
- {
- if (current_module && current_module->name)
- { const char *module_name = IDENTIFIER_POINTER (current_module->name);
- if (module_name[0] && module_name[0] != '_')
- return current_module->name;
- }
- error ("PREFIXED clause with no prelix in unlabeled module");
- }
- return id;
-}
-
-void
-possibly_define_exit_label (label)
- tree label;
-{
- if (label)
- define_label (input_filename, lineno, munge_exit_label (label));
-}
-
-#define MAX_LOOK_AHEAD 2
-static enum terminal terminal_buffer[MAX_LOOK_AHEAD+1];
-YYSTYPE yylval;
-static YYSTYPE val_buffer[MAX_LOOK_AHEAD+1];
-
-/*enum terminal current_token, lookahead_token;*/
-
-#define TOKEN_NOT_READ dummy_last_terminal
-
-#ifdef __GNUC__
-__inline__
-#endif
-static enum terminal
-PEEK_TOKEN()
-{
- if (terminal_buffer[0] == TOKEN_NOT_READ)
- {
- terminal_buffer[0] = yylex();
- val_buffer[0] = yylval;
- }
- return terminal_buffer[0];
-}
-#define PEEK_TREE() val_buffer[0].ttype
-#define PEEK_TOKEN1() peek_token_ (1)
-#define PEEK_TOKEN2() peek_token_ (2)
-
-static int
-peek_token_ (i)
- int i;
-{
- if (i > MAX_LOOK_AHEAD)
- abort ();
- if (terminal_buffer[i] == TOKEN_NOT_READ)
- {
- terminal_buffer[i] = yylex();
- val_buffer[i] = yylval;
- }
- return terminal_buffer[i];
-}
-
-static void
-pushback_token (code, node)
- int code;
- tree node;
-{
- int i;
- if (terminal_buffer[MAX_LOOK_AHEAD] != TOKEN_NOT_READ)
- abort ();
- for (i = MAX_LOOK_AHEAD; i > 0; i--)
- {
- terminal_buffer[i] = terminal_buffer[i - 1];
- val_buffer[i] = val_buffer[i - 1];
- }
- terminal_buffer[0] = code;
- val_buffer[0].ttype = node;
-}
-
-static void
-forward_token_()
-{
- int i;
- for (i = 0; i < MAX_LOOK_AHEAD; i++)
- {
- terminal_buffer[i] = terminal_buffer[i+1];
- val_buffer[i] = val_buffer[i+1];
- }
- terminal_buffer[MAX_LOOK_AHEAD] = TOKEN_NOT_READ;
-}
-#define FORWARD_TOKEN() forward_token_ ()
-
-/* Skip the next token.
- if it isn't TOKEN, the parser is broken. */
-
-static void
-require (token)
- enum terminal token;
-{
- if (PEEK_TOKEN() != token)
- internal_error ("internal parser error - expected token %d", (int) token);
- FORWARD_TOKEN();
-}
-
-static int
-check_token (token)
- enum terminal token;
-{
- if (PEEK_TOKEN() != token)
- return 0;
- FORWARD_TOKEN ();
- return 1;
-}
-
-/* return 0 if expected token was not found,
- else return 1.
-*/
-static int
-expect(token, message)
- enum terminal token;
- const char *message;
-{
- if (PEEK_TOKEN() != token)
- {
- if (pass == 1)
- error("%s", message ? message : "syntax error");
- return 0;
- }
- else
- FORWARD_TOKEN();
- return 1;
-}
-
-/* define a SYNONYM __PROCNAME__ (__procname__) which holds
- the name of the current procedure.
- This should be quit the same as __FUNCTION__ in C */
-static void
-define__PROCNAME__ ()
-{
- const char *fname;
- tree string;
- tree procname;
-
- if (current_function_decl == NULL_TREE)
- fname = "toplevel";
- else
- fname = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
-
- string = build_chill_string (strlen (fname), fname);
- procname = get_identifier (ignore_case ? "__procname__" : "__PROCNAME__");
- push_syndecl (procname, NULL_TREE, string);
-}
-
-/* Forward declarations. */
-static tree parse_expression PARAMS ((void));
-static tree parse_primval PARAMS ((void));
-static tree parse_mode PARAMS ((void));
-static tree parse_opt_mode PARAMS ((void));
-static tree parse_untyped_expr PARAMS ((void));
-static tree parse_opt_untyped_expr PARAMS ((void));
-static int parse_definition PARAMS ((int));
-static void parse_opt_actions PARAMS ((void));
-static void parse_body PARAMS ((void));
-static tree parse_if_expression_body PARAMS ((void));
-static tree parse_opt_handler PARAMS ((void));
-static tree parse_opt_name_string PARAMS ((int));
-static tree parse_simple_name_string PARAMS ((void));
-static tree parse_name_string PARAMS ((void));
-static tree parse_defining_occurrence PARAMS ((void));
-static tree parse_name PARAMS ((void));
-static tree parse_optlabel PARAMS ((void));
-static void parse_opt_end_label_semi_colon PARAMS ((tree));
-static void parse_modulion PARAMS ((tree));
-static void parse_spec_module PARAMS ((tree));
-static void parse_semi_colon PARAMS ((void));
-static tree parse_defining_occurrence_list PARAMS ((void));
-static void parse_mode_definition PARAMS ((int));
-static void parse_mode_definition_statement PARAMS ((int));
-static void parse_synonym_definition PARAMS ((void));
-static void parse_synonym_definition_statement PARAMS ((void));
-static tree parse_on_exception_list PARAMS ((void));
-static void parse_on_alternatives PARAMS ((void));
-static void parse_loc_declaration PARAMS ((int));
-static void parse_declaration_statement PARAMS ((int));
-static tree parse_optforbid PARAMS ((void));
-static tree parse_postfix PARAMS ((enum terminal));
-static tree parse_postfix_list PARAMS ((enum terminal));
-static void parse_rename_clauses PARAMS ((enum terminal));
-static tree parse_opt_prefix_clause PARAMS ((void));
-static void parse_grant_statement PARAMS ((void));
-static void parse_seize_statement PARAMS ((void));
-static tree parse_param_name_list PARAMS ((void));
-static tree parse_param_attr PARAMS ((void));
-static tree parse_formpar PARAMS ((void));
-static tree parse_formparlist PARAMS ((void));
-static tree parse_opt_result_spec PARAMS ((void));
-static tree parse_opt_except PARAMS ((void));
-static tree parse_opt_recursive PARAMS ((void));
-static tree parse_procedureattr PARAMS ((void));
-static void parse_proc_body PARAMS ((tree, tree));
-static void parse_procedure_definition PARAMS ((int));
-static tree parse_processpar PARAMS ((void));
-static tree parse_processparlist PARAMS ((void));
-static void parse_process_definition PARAMS ((int));
-static void parse_signal_definition PARAMS ((void));
-static void parse_signal_definition_statement PARAMS ((void));
-static void parse_then_clause PARAMS ((void));
-static void parse_opt_else_clause PARAMS ((void));
-static tree parse_expr_list PARAMS ((void));
-static tree parse_range_list_clause PARAMS ((void));
-static void pushback_paren_expr PARAMS ((tree));
-static tree parse_case_label PARAMS ((void));
-static tree parse_case_label_list PARAMS ((tree, int));
-static tree parse_case_label_specification PARAMS ((tree));
-static void parse_single_dimension_case_action PARAMS ((tree));
-static void parse_multi_dimension_case_action PARAMS ((tree));
-static void parse_case_action PARAMS ((tree));
-static tree parse_asm_operands PARAMS ((void));
-static tree parse_asm_clobbers PARAMS ((void));
-static void ch_expand_asm_operands PARAMS ((tree, tree, tree, tree,
- int, const char *, int));
-static void parse_asm_action PARAMS ((void));
-static void parse_begin_end_block PARAMS ((tree));
-static void parse_if_action PARAMS ((tree));
-static void parse_iteration PARAMS ((void));
-static tree parse_delay_case_event_list PARAMS ((void));
-static void parse_delay_case_action PARAMS ((tree));
-static void parse_do_action PARAMS ((tree));
-static tree parse_receive_spec PARAMS ((void));
-static void parse_receive_case_action PARAMS ((tree));
-static void parse_send_action PARAMS ((void));
-static void parse_start_action PARAMS ((void));
-static tree parse_call PARAMS ((tree));
-static tree parse_tuple_fieldname_list PARAMS ((void));
-static tree parse_tuple_element PARAMS ((void));
-static tree parse_opt_element_list PARAMS ((void));
-static tree parse_tuple PARAMS ((tree));
-static tree parse_operand6 PARAMS ((void));
-static tree parse_operand5 PARAMS ((void));
-static tree parse_operand4 PARAMS ((void));
-static tree parse_operand3 PARAMS ((void));
-static tree parse_operand2 PARAMS ((void));
-static tree parse_operand1 PARAMS ((void));
-static tree parse_operand0 PARAMS ((void));
-static tree parse_case_expression PARAMS ((void));
-static tree parse_then_alternative PARAMS ((void));
-static tree parse_else_alternative PARAMS ((void));
-static tree parse_if_expression PARAMS ((void));
-static tree parse_index_mode PARAMS ((void));
-static tree parse_set_mode PARAMS ((void));
-static tree parse_pos PARAMS ((void));
-static tree parse_step PARAMS ((void));
-static tree parse_opt_layout PARAMS ((int));
-static tree parse_field_name_list PARAMS ((void));
-static tree parse_fixed_field PARAMS ((void));
-static tree parse_variant_field_list PARAMS ((void));
-static tree parse_variant_alternative PARAMS ((void));
-static tree parse_field PARAMS ((void));
-static tree parse_structure_mode PARAMS ((void));
-static tree parse_opt_queue_size PARAMS ((void));
-static tree parse_procedure_mode PARAMS ((void));
-static void parse_program PARAMS ((void));
-static void parse_pass_1_2 PARAMS ((void));
-
-static tree
-parse_opt_name_string (allow_all)
- int allow_all; /* 1 if ALL is allowed as a postfix */
-{
- enum terminal token = PEEK_TOKEN();
- tree name;
- if (token != NAME)
- {
- if (token == ALL && allow_all)
- {
- FORWARD_TOKEN ();
- return ALL_POSTFIX;
- }
- return NULL_TREE;
- }
- name = PEEK_TREE();
- for (;;)
- {
- FORWARD_TOKEN ();
- token = PEEK_TOKEN();
- if (token != '!')
- return name;
- FORWARD_TOKEN();
- token = PEEK_TOKEN();
- if (token == ALL && allow_all)
- return get_identifier3(IDENTIFIER_POINTER (name), "!", "*");
- if (token != NAME)
- {
- if (pass == 1)
- error ("'%s!' is not followed by an identifier",
- IDENTIFIER_POINTER (name));
- return name;
- }
- name = get_identifier3(IDENTIFIER_POINTER(name),
- "!", IDENTIFIER_POINTER(PEEK_TREE()));
- }
-}
-
-static tree
-parse_simple_name_string ()
-{
- enum terminal token = PEEK_TOKEN();
- tree name;
- if (token != NAME)
- {
- error ("expected a name here");
- return error_mark_node;
- }
- name = PEEK_TREE ();
- FORWARD_TOKEN ();
- return name;
-}
-
-static tree
-parse_name_string ()
-{
- tree name = parse_opt_name_string (0);
- if (name)
- return name;
- if (pass == 1)
- error ("expected a name string here");
- return error_mark_node;
-}
-
-static tree
-parse_defining_occurrence ()
-{
- if (PEEK_TOKEN () == NAME)
- {
- tree id = PEEK_TREE();
- FORWARD_TOKEN ();
- return id;
- }
- return NULL;
-}
-
-/* Matches: <name_string>
- Returns if pass 1: the identifier.
- Returns if pass 2: a decl or value for identifier. */
-
-static tree
-parse_name ()
-{
- tree name = parse_name_string ();
- if (pass == 1 || ignoring)
- return name;
- else
- {
- tree decl = lookup_name (name);
- if (decl == NULL_TREE)
- {
- error ("`%s' undeclared", IDENTIFIER_POINTER (name));
- return error_mark_node;
- }
- else if (TREE_CODE (TREE_TYPE (decl)) == ERROR_MARK)
- return error_mark_node;
- else if (TREE_CODE (decl) == CONST_DECL)
- return DECL_INITIAL (decl);
- else if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
- return convert_from_reference (decl);
- else
- return decl;
- }
-}
-
-static tree
-parse_optlabel()
-{
- tree label = parse_defining_occurrence();
- if (label != NULL)
- expect(COLON, "expected a ':' here");
- return label;
-}
-
-static void
-parse_semi_colon ()
-{
- enum terminal token = PEEK_TOKEN ();
- if (token == SC)
- FORWARD_TOKEN ();
- else if (pass == 1)
- (token == END ? pedwarn : error) ("expected ';' here");
- label = NULL_TREE;
-}
-
-static void
-parse_opt_end_label_semi_colon (start_label)
- tree start_label;
-{
- if (PEEK_TOKEN() == NAME)
- {
- tree end_label = parse_name_string ();
- check_end_label (start_label, end_label);
- }
- parse_semi_colon ();
-}
-
-static void
-parse_modulion (label)
- tree label;
-{
- tree module_name;
-
- label = set_module_name (label);
- module_name = push_module (label, 0);
- FORWARD_TOKEN();
-
- push_action ();
- parse_body();
- expect(END, "expected END here");
- parse_opt_handler ();
- parse_opt_end_label_semi_colon (label);
- find_granted_decls ();
- pop_module ();
-}
-
-static void
-parse_spec_module (label)
- tree label;
-{
- int save_ignoring = ignoring;
-
- push_module (set_module_name (label), 1);
- ignoring = pass == 2;
- FORWARD_TOKEN(); /* SKIP SPEC */
- expect (MODULE, "expected 'MODULE' here");
-
- while (parse_definition (1)) { }
- if (parse_action ())
- error ("action not allowed in SPEC MODULE");
- expect(END, "expected END here");
- parse_opt_end_label_semi_colon (label);
- find_granted_decls ();
- pop_module ();
- ignoring = save_ignoring;
-}
-
-/* Matches: <name_string> ( "," <name_string> )*
- Returns either a single IDENTIFIER_NODE,
- or a chain (TREE_LIST) of IDENTIFIER_NODES.
- (Since a single identifier is the common case, we avoid wasting space
- (twice, once for each pass) with extra TREE_LIST nodes in that case.)
- (Will not return NULL_TREE even if ignoring is true.) */
-
-static tree
-parse_defining_occurrence_list ()
-{
- tree chain = NULL_TREE;
- tree name = parse_defining_occurrence ();
- if (name == NULL_TREE)
- {
- error("missing defining occurrence");
- return NULL_TREE;
- }
- if (! check_token (COMMA))
- return name;
- chain = build_tree_list (NULL_TREE, name);
- for (;;)
- {
- name = parse_defining_occurrence ();
- if (name == NULL)
- {
- error ("bad defining occurrence following ','");
- break;
- }
- chain = tree_cons (NULL_TREE, name, chain);
- if (! check_token (COMMA))
- break;
- }
- return nreverse (chain);
-}
-
-static void
-parse_mode_definition (is_newmode)
- int is_newmode;
-{
- tree mode, names;
- int save_ignoring = ignoring;
- ignoring = pass == 2;
- names = parse_defining_occurrence_list ();
- expect (EQL, "missing '=' in mode definition");
- mode = parse_mode ();
- if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST)
- {
- for ( ; names != NULL_TREE; names = TREE_CHAIN (names))
- push_modedef (names, mode, is_newmode);
- }
- else
- push_modedef (names, mode, is_newmode);
- ignoring = save_ignoring;
-}
-
-static void
-parse_mode_definition_statement (is_newmode)
- int is_newmode;
-{
- FORWARD_TOKEN (); /* skip SYNMODE or NEWMODE */
- parse_mode_definition (is_newmode);
- while (PEEK_TOKEN () == COMMA)
- {
- FORWARD_TOKEN ();
- parse_mode_definition (is_newmode);
- }
- parse_semi_colon ();
-}
-
-static void
-parse_synonym_definition ()
-{ tree expr = NULL_TREE;
- tree names = parse_defining_occurrence_list ();
- tree mode = parse_opt_mode ();
- if (! expect (EQL, "missing '=' in synonym definition"))
- mode = error_mark_node;
- else
- {
- if (mode)
- expr = parse_untyped_expr ();
- else
- expr = parse_expression ();
- }
- if (names == NULL_TREE || TREE_CODE (names) == TREE_LIST)
- {
- for ( ; names != NULL_TREE; names = TREE_CHAIN (names))
- push_syndecl (names, mode, expr);
- }
- else
- push_syndecl (names, mode, expr);
-}
-
-static void
-parse_synonym_definition_statement()
-{
- int save_ignoring= ignoring;
- ignoring = pass == 2;
- require (SYN);
- parse_synonym_definition ();
- while (PEEK_TOKEN () == COMMA)
- {
- FORWARD_TOKEN ();
- parse_synonym_definition ();
- }
- ignoring = save_ignoring;
- parse_semi_colon ();
-}
-
-/* Attempts to match: "(" <exception list> ")" ":".
- Return NULL_TREE on failure, and non-NULL on success.
- On success, if pass 1, return a TREE_LIST of IDENTIFIER_NODEs. */
-
-static tree
-parse_on_exception_list ()
-{
- tree name;
- tree list = NULL_TREE;
- int tok1 = PEEK_TOKEN ();
- int tok2 = PEEK_TOKEN1 ();
-
- /* This requires a lot of look-ahead, because we cannot
- easily a priori distinguish an exception-list from an expression. */
- if (tok1 != LPRN || tok2 != NAME)
- {
- if (tok1 == NAME && tok2 == COLON && pass == 1)
- error ("missing '(' in exception list");
- return 0;
- }
- require (LPRN);
- name = parse_name_string ();
- if (PEEK_TOKEN () == RPRN && PEEK_TOKEN1 () == COLON)
- {
- /* Matched: '(' <name_string> ')' ':' */
- FORWARD_TOKEN (); FORWARD_TOKEN ();
- return pass == 1 ? build_tree_list (NULL_TREE, name) : name;
- }
- if (PEEK_TOKEN() == COMMA)
- {
- if (pass == 1)
- list = build_tree_list (NULL_TREE, name);
- while (check_token (COMMA))
- {
- tree old_names = list;
- name = parse_name_string ();
- if (pass == 1)
- {
- for ( ; old_names != NULL_TREE; old_names = TREE_CHAIN (old_names))
- {
- if (TREE_VALUE (old_names) == name)
- {
- error ("ON exception names must be unique");
- goto continue_parsing;
- }
- }
- list = tree_cons (NULL_TREE, name, list);
- continue_parsing:
- ;
- }
- }
- if (! check_token (RPRN) || ! check_token(COLON))
- error ("syntax error in exception list");
- return pass == 1 ? nreverse (list) : name;
- }
- /* Matched: '(' name_string
- but it doesn't match the syntax of an exception list.
- It could be the beginning of an expression, so back up. */
- pushback_token (NAME, name);
- pushback_token (LPRN, 0);
- return NULL_TREE;
-}
-
-static void
-parse_on_alternatives ()
-{
- for (;;)
- {
- tree except_list = parse_on_exception_list ();
- if (except_list != NULL)
- chill_handle_on_labels (except_list);
- else if (parse_action ())
- expand_exit_needed = 1;
- else
- break;
- }
-}
-
-static tree
-parse_opt_handler ()
-{
- if (! check_token (ON))
- {
- POP_UNUSED_ON_CONTEXT;
- return NULL_TREE;
- }
- if (check_token (END))
- {
- pedwarn ("empty ON-condition");
- POP_UNUSED_ON_CONTEXT;
- return NULL_TREE;
- }
- if (! ignoring)
- {
- chill_start_on ();
- expand_exit_needed = 0;
- }
- if (PEEK_TOKEN () != ELSE)
- {
- parse_on_alternatives ();
- if (! ignoring && expand_exit_needed)
- expand_exit_something ();
- }
- if (check_token (ELSE))
- {
- chill_start_default_handler ();
- label = NULL_TREE;
- parse_opt_actions ();
- if (! ignoring)
- {
- emit_line_note (input_filename, lineno);
- expand_exit_something ();
- }
- }
- expect (END, "missing 'END' after");
- if (! ignoring)
- chill_finish_on ();
- POP_USED_ON_CONTEXT;
- return integer_zero_node;
-}
-
-static void
-parse_loc_declaration (in_spec_module)
- int in_spec_module;
-{
- tree names = parse_defining_occurrence_list ();
- int save_ignoring = ignoring;
- int is_static, lifetime_bound;
- tree mode, init_value = NULL_TREE;
- int loc_decl = 0;
-
- ignoring = pass == 2;
- mode = parse_mode ();
- ignoring = save_ignoring;
- is_static = check_token (STATIC);
- if (check_token (BASED))
- {
- expect(LPRN, "BASED must be followed by (NAME)");
- do_based_decls (names, mode, parse_name_string ());
- expect(RPRN, "BASED must be followed by (NAME)");
- return;
- }
- if (check_token (LOC))
- {
- /* loc-identity declaration */
- if (pass == 1)
- mode = build_chill_reference_type (mode);
- loc_decl = 1;
- }
- lifetime_bound = check_token (INIT);
- if (lifetime_bound && loc_decl)
- {
- if (pass == 1)
- error ("INIT not allowed at loc-identity declaration");
- lifetime_bound = 0;
- }
- if (PEEK_TOKEN () == ASGN || PEEK_TOKEN() == EQL)
- {
- save_ignoring = ignoring;
- ignoring = pass == 1;
- if (PEEK_TOKEN() == EQL)
- {
- if (pass == 1)
- error ("'=' used where ':=' is required");
- }
- FORWARD_TOKEN();
- if (! lifetime_bound)
- push_handler ();
- init_value = parse_untyped_expr ();
- if (in_spec_module)
- {
- error ("initialization is not allowed in spec module");
- init_value = NULL_TREE;
- }
- if (! lifetime_bound)
- parse_opt_handler ();
- ignoring = save_ignoring;
- }
- if (init_value == NULL_TREE && loc_decl && pass == 1)
- error ("loc-identity declaration without initialisation");
- do_decls (names, mode,
- is_static || global_bindings_p ()
- /* the variable becomes STATIC if all_static_flag is set and
- current functions doesn't have the RECURSIVE attribute */
- || (all_static_flag && !CH_DECL_RECURSIVE (current_function_decl)),
- lifetime_bound, init_value, in_spec_module);
-
- /* Free any temporaries we made while initializing the decl. */
- free_temp_slots ();
-}
-
-static void
-parse_declaration_statement (in_spec_module)
- int in_spec_module;
-{
- int save_ignoring = ignoring;
- ignoring = pass == 2;
- require (DCL);
- parse_loc_declaration (in_spec_module);
- while (PEEK_TOKEN () == COMMA)
- {
- FORWARD_TOKEN ();
- parse_loc_declaration (in_spec_module);
- }
- ignoring = save_ignoring;
- parse_semi_colon ();
-}
-
-static tree
-parse_optforbid ()
-{
- if (check_token (FORBID) == 0)
- return NULL_TREE;
- if (check_token (ALL))
- return ignoring ? NULL_TREE : build_int_2 (-1, -1);
-#if 0
- if (check_token (LPRN))
- {
- tree list = parse_forbidlist ();
- expect (RPRN, "missing ')' after FORBID list");
- return list;
- }
-#endif
- error ("bad syntax following FORBID");
- return NULL_TREE;
-}
-
-/* Matches: <grant postfix> or <seize postfix>
- Returns: A (singleton) TREE_LIST. */
-
-static tree
-parse_postfix (grant_or_seize)
- enum terminal grant_or_seize;
-{
- tree name = parse_opt_name_string (1);
- tree forbid = NULL_TREE;
- if (name == NULL_TREE)
- {
- error ("expected a postfix name here");
- name = error_mark_node;
- }
- if (grant_or_seize == GRANT)
- forbid = parse_optforbid ();
- return build_tree_list (forbid, name);
-}
-
-static tree
-parse_postfix_list (grant_or_seize)
- enum terminal grant_or_seize;
-{
- tree list = parse_postfix (grant_or_seize);
- while (check_token (COMMA))
- list = chainon (list, parse_postfix (grant_or_seize));
- return list;
-}
-
-static void
-parse_rename_clauses (grant_or_seize)
- enum terminal grant_or_seize;
-{
- for (;;)
- {
- tree rename_old_prefix, rename_new_prefix, postfix;
- require (LPRN);
- rename_old_prefix = parse_opt_name_string (0);
- expect (ARROW, "missing '->' in rename clause");
- rename_new_prefix = parse_opt_name_string (0);
- expect (RPRN, "missing ')' in rename clause");
- expect ('!', "missing '!' in rename clause");
- postfix = parse_postfix (grant_or_seize);
-
- if (grant_or_seize == GRANT)
- chill_grant (rename_old_prefix, rename_new_prefix,
- TREE_VALUE (postfix), TREE_PURPOSE (postfix));
- else
- chill_seize (rename_old_prefix, rename_new_prefix,
- TREE_VALUE (postfix));
-
- if (PEEK_TOKEN () != COMMA)
- break;
- FORWARD_TOKEN ();
- if (PEEK_TOKEN () != LPRN)
- {
- error ("expected another rename clause");
- break;
- }
- }
-}
-
-static tree
-parse_opt_prefix_clause ()
-{
- if (check_token (PREFIXED) == 0)
- return NULL_TREE;
- return build_prefix_clause (parse_opt_name_string (0));
-}
-
-static void
-parse_grant_statement ()
-{
- require (GRANT);
- if (PEEK_TOKEN () == LPRN)
- parse_rename_clauses (GRANT);
- else
- {
- tree window = parse_postfix_list (GRANT);
- tree new_prefix = parse_opt_prefix_clause ();
- tree t;
- for (t = window; t; t = TREE_CHAIN (t))
- chill_grant (NULL_TREE, new_prefix, TREE_VALUE (t), TREE_PURPOSE (t));
- }
-}
-
-static void
-parse_seize_statement ()
-{
- require (SEIZE);
- if (PEEK_TOKEN () == LPRN)
- parse_rename_clauses (SEIZE);
- else
- {
- tree seize_window = parse_postfix_list (SEIZE);
- tree old_prefix = parse_opt_prefix_clause ();
- tree t;
- for (t = seize_window; t; t = TREE_CHAIN (t))
- chill_seize (old_prefix, NULL_TREE, TREE_VALUE (t));
- }
-}
-
-/* In pass 1, this returns a TREE_LIST, one node for each parameter.
- In pass 2, we get a list of PARM_DECLs chained together.
- In either case, the list is in reverse order. */
-
-static tree
-parse_param_name_list ()
-{
- tree list = NULL_TREE;
- do
- {
- tree new_link;
- tree name = parse_defining_occurrence ();
- if (name == NULL_TREE)
- {
- error ("syntax error in parameter name list");
- return list;
- }
- if (pass == 1)
- new_link = build_tree_list (NULL_TREE, name);
- /* else if (current_module->is_spec_module) ; nothing */
- else /* pass == 2 */
- {
- new_link = make_node (PARM_DECL);
- DECL_NAME (new_link) = name;
- DECL_ASSEMBLER_NAME (new_link) = name;
- }
-
- TREE_CHAIN (new_link) = list;
- list = new_link;
- } while (check_token (COMMA));
- return list;
-}
-
-static tree
-parse_param_attr ()
-{
- tree attr;
- switch (PEEK_TOKEN ())
- {
- case PARAMATTR: /* INOUT is returned here */
- attr = PEEK_TREE ();
- FORWARD_TOKEN ();
- return attr;
- case IN:
- FORWARD_TOKEN ();
- return ridpointers[(int) RID_IN];
- case LOC:
- FORWARD_TOKEN ();
- return ridpointers[(int) RID_LOC];
-#if 0
- case DYNAMIC:
- FORWARD_TOKEN ();
- return ridpointers[(int) RID_DYNAMIC];
-#endif
- default:
- return NULL_TREE;
- }
-}
-
-/* We wrap CHILL array parameters in a STRUCT. The original parameter
- name is unpacked from the struct at get_identifier time */
-
-/* In pass 1, returns list of types; in pass 2: chain of PARM_DECLs. */
-
-static tree
-parse_formpar ()
-{
- tree names = parse_param_name_list ();
- tree mode = parse_mode ();
- tree paramattr = parse_param_attr ();
- return chill_munge_params (nreverse (names), mode, paramattr);
-}
-
-/*
- * Note: build_process_header depends upon the *exact*
- * representation of STRUCT fields and of formal parameter
- * lists. If either is changed, build_process_header will
- * also need change. Push_extern_process is affected as well.
- */
-static tree
-parse_formparlist ()
-{
- tree list = NULL_TREE;
- if (PEEK_TOKEN() == RPRN)
- return NULL_TREE;
- for (;;)
- {
- list = chainon (list, parse_formpar ());
- if (! check_token (COMMA))
- break;
- }
- return list;
-}
-
-static tree
-parse_opt_result_spec ()
-{
- tree mode;
- int is_nonref, is_loc, is_dynamic;
- if (!check_token (RETURNS))
- return void_type_node;
- expect (LPRN, "expected '(' after RETURNS");
- mode = parse_mode ();
- is_nonref = check_token (NONREF);
- is_loc = check_token (LOC);
- is_dynamic = check_token (DYNAMIC);
- if (is_nonref && !is_loc)
- error ("NONREF specific without LOC in result attribute");
- if (is_dynamic && !is_loc)
- error ("DYNAMIC specific without LOC in result attribute");
- mode = get_type_of (mode);
- if (is_loc && ! ignoring)
- mode = build_chill_reference_type (mode);
- expect (RPRN, "expected ')' after RETURNS");
- return mode;
-}
-
-static tree
-parse_opt_except ()
-{
- tree list = NULL_TREE;
- if (!check_token (EXCEPTIONS))
- return NULL_TREE;
- expect (LPRN, "expected '(' after EXCEPTIONS");
- do
- {
- tree except_name = parse_name_string ();
- tree name;
- for (name = list; name != NULL_TREE; name = TREE_CHAIN (name))
- if (TREE_VALUE (name) == except_name && pass == 1)
- {
- error ("exception names must be unique");
- break;
- }
- if (name == NULL_TREE && !ignoring)
- list = tree_cons (NULL_TREE, except_name, list);
- } while (check_token (COMMA));
- expect (RPRN, "expected ')' after EXCEPTIONS");
- return list;
-}
-
-static tree
-parse_opt_recursive ()
-{
- if (check_token (RECURSIVE))
- return ridpointers[RID_RECURSIVE];
- else
- return NULL_TREE;
-}
-
-static tree
-parse_procedureattr ()
-{
- tree generality;
- tree optrecursive;
- switch (PEEK_TOKEN ())
- {
- case GENERAL:
- FORWARD_TOKEN ();
- generality = ridpointers[RID_GENERAL];
- break;
- case SIMPLE:
- FORWARD_TOKEN ();
- generality = ridpointers[RID_SIMPLE];
- break;
- case INLINE:
- FORWARD_TOKEN ();
- generality = ridpointers[RID_INLINE];
- break;
- default:
- generality = NULL_TREE;
- }
- optrecursive = parse_opt_recursive ();
- if (pass != 1)
- return NULL_TREE;
- if (generality)
- generality = build_tree_list (NULL_TREE, generality);
- if (optrecursive)
- generality = tree_cons (NULL_TREE, optrecursive, generality);
- return generality;
-}
-
-/* Parse the body and last part of a procedure or process definition. */
-
-static void
-parse_proc_body (name, exceptions)
- tree name;
- tree exceptions;
-{
- int save_proc_action_level = proc_action_level;
- proc_action_level = action_nesting_level;
- if (exceptions != NULL_TREE)
- /* set up a handler for reraising exceptions */
- push_handler ();
- push_action ();
- define__PROCNAME__ ();
- parse_body ();
- proc_action_level = save_proc_action_level;
- expect (END, "'END' was expected here");
- parse_opt_handler ();
- if (exceptions != NULL_TREE)
- chill_reraise_exceptions (exceptions);
- parse_opt_end_label_semi_colon (name);
- end_function ();
-}
-
-static void
-parse_procedure_definition (in_spec_module)
- int in_spec_module;
-{
- int save_ignoring = ignoring;
- tree name = parse_defining_occurrence ();
- tree params, result, exceptlist, attributes;
- int save_chill_at_module_level = chill_at_module_level;
- chill_at_module_level = 0;
- if (!in_spec_module)
- ignoring = pass == 2;
- require (COLON); require (PROC);
- expect (LPRN, "missing '(' after PROC");
- params = parse_formparlist ();
- expect (RPRN, "missing ')' in PROC");
- result = parse_opt_result_spec ();
- exceptlist = parse_opt_except ();
- attributes = parse_procedureattr ();
- ignoring = save_ignoring;
- if (in_spec_module)
- {
- expect (END, "missing 'END'");
- parse_opt_end_label_semi_colon (name);
- push_extern_function (name, result, params, exceptlist, 0);
- return;
- }
- push_chill_function_context ();
- start_chill_function (name, result, params, exceptlist, attributes);
- current_module->procedure_seen = 1;
- parse_proc_body (name, TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
- chill_at_module_level = save_chill_at_module_level;
-}
-
-static tree
-parse_processpar ()
-{
- tree names = parse_defining_occurrence_list ();
- tree mode = parse_mode ();
- tree paramattr = parse_param_attr ();
-
- if (names && TREE_CODE (names) == IDENTIFIER_NODE)
- names = build_tree_list (NULL_TREE, names);
- return tree_cons (tree_cons (paramattr, mode, NULL_TREE), names, NULL_TREE);
-}
-
-static tree
-parse_processparlist ()
-{
- tree list = NULL_TREE;
- if (PEEK_TOKEN() == RPRN)
- return NULL_TREE;
- for (;;)
- {
- list = chainon (list, parse_processpar ());
- if (! check_token (COMMA))
- break;
- }
- return list;
-}
-
-static void
-parse_process_definition (in_spec_module)
- int in_spec_module;
-{
- int save_ignoring = ignoring;
- tree name = parse_defining_occurrence ();
- tree params;
- tree tmp;
- if (!in_spec_module)
- ignoring = 0;
- require (COLON); require (PROCESS);
- expect (LPRN, "missing '(' after PROCESS");
- params = parse_processparlist ();
- expect (RPRN, "missing ')' in PROCESS");
- ignoring = save_ignoring;
- if (in_spec_module)
- {
- expect (END, "missing 'END'");
- parse_opt_end_label_semi_colon (name);
- push_extern_process (name, params, NULL_TREE, 0);
- return;
- }
- tmp = build_process_header (name, params);
- parse_proc_body (name, NULL_TREE);
- build_process_wrapper (name, tmp);
-}
-
-static void
-parse_signal_definition ()
-{
- tree signame = parse_defining_occurrence ();
- tree modes = NULL_TREE;
- tree dest = NULL_TREE;
-
- if (check_token (EQL))
- {
- expect (LPRN, "missing '(' after 'SIGNAL <name> ='");
- for (;;)
- {
- tree mode = parse_mode ();
- modes = tree_cons (NULL_TREE, mode, modes);
- if (! check_token (COMMA))
- break;
- }
- expect (RPRN, "missing ')'");
- modes = nreverse (modes);
- }
-
- if (check_token (TO))
- {
- tree decl;
- int save_ignoring = ignoring;
- ignoring = 0;
- decl = parse_name ();
- ignoring = save_ignoring;
- if (pass > 1)
- {
- if (decl == NULL_TREE
- || TREE_CODE (decl) == ERROR_MARK
- || TREE_CODE (decl) != FUNCTION_DECL
- || !CH_DECL_PROCESS (decl))
- error ("must specify a PROCESS name");
- else
- dest = decl;
- }
- }
-
- if (! global_bindings_p ())
- error ("SIGNAL must be in global reach");
- else
- {
- tree struc = build_signal_struct_type (signame, modes, dest);
- tree decl =
- generate_tasking_code_variable (signame,
- &signal_code,
- current_module->is_spec_module);
- /* remember the code variable in the struct type */
- DECL_TASKING_CODE_DECL (struc) = (struct lang_decl *)decl;
- CH_DECL_SIGNAL (struc) = 1;
- add_taskstuff_to_list (decl, "_TT_Signal",
- current_module->is_spec_module ?
- NULL_TREE : signal_code, struc, NULL_TREE);
- }
-
-}
-
-static void
-parse_signal_definition_statement ()
-{
- int save_ignoring = ignoring;
- ignoring = pass == 2;
- require (SIGNAL);
- for (;;)
- {
- parse_signal_definition ();
- if (! check_token (COMMA))
- break;
- if (PEEK_TOKEN () == SC)
- {
- error ("syntax error while parsing signal definition statement");
- break;
- }
- }
- parse_semi_colon ();
- ignoring = save_ignoring;
-}
-
-static int
-parse_definition (in_spec_module)
- int in_spec_module;
-{
- switch (PEEK_TOKEN ())
- {
- case NAME:
- if (PEEK_TOKEN1() == COLON)
- {
- if (PEEK_TOKEN2() == PROC)
- {
- parse_procedure_definition (in_spec_module);
- return 1;
- }
- else if (PEEK_TOKEN2() == PROCESS)
- {
- parse_process_definition (in_spec_module);
- return 1;
- }
- }
- return 0;
- case DCL:
- parse_declaration_statement(in_spec_module);
- break;
- case GRANT:
- parse_grant_statement ();
- break;
- case NEWMODE:
- parse_mode_definition_statement(1);
- break;
- case SC:
- label = NULL_TREE;
- FORWARD_TOKEN();
- return 1;
- case SEIZE:
- parse_seize_statement ();
- break;
- case SIGNAL:
- parse_signal_definition_statement ();
- break;
- case SYN:
- parse_synonym_definition_statement();
- break;
- case SYNMODE:
- parse_mode_definition_statement(0);
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-static void
-parse_then_clause ()
-{
- expect (THEN, "expected 'THEN' after 'IF'");
- if (! ignoring)
- emit_line_note (input_filename, lineno);
- parse_opt_actions ();
-}
-
-static void
-parse_opt_else_clause ()
-{
- while (check_token (ELSIF))
- {
- tree cond = parse_expression ();
- if (! ignoring)
- expand_start_elseif (truthvalue_conversion (cond));
- parse_then_clause ();
- }
- if (check_token (ELSE))
- {
- if (! ignoring)
- { emit_line_note (input_filename, lineno);
- expand_start_else ();
- }
- parse_opt_actions ();
- }
-}
-
-static tree parse_expr_list ()
-{
- tree expr = parse_expression ();
- tree list = ignoring ? NULL_TREE : build_tree_list (NULL_TREE, expr);
- while (check_token (COMMA))
- {
- expr = parse_expression ();
- if (! ignoring)
- list = tree_cons (NULL_TREE, expr, list);
- }
- return list;
-}
-
-static tree
-parse_range_list_clause ()
-{
- tree name = parse_opt_name_string (0);
- if (name == NULL_TREE)
- return NULL_TREE;
- while (check_token (COMMA))
- {
- name = parse_name_string ();
- }
- if (check_token (SC))
- {
- sorry ("case range list");
- return error_mark_node;
- }
- pushback_token (NAME, name);
- return NULL_TREE;
-}
-
-static void
-pushback_paren_expr (expr)
- tree expr;
-{
- if (pass == 1 && !ignoring)
- expr = build1 (PAREN_EXPR, NULL_TREE, expr);
- pushback_token (EXPR, expr);
-}
-
-/* Matches: <case label> */
-
-static tree
-parse_case_label ()
-{
- tree expr;
- if (check_token (ELSE))
- return case_else_node;
- /* Does this also handle the case of a mode name? FIXME */
- expr = parse_expression ();
- if (check_token (COLON))
- {
- tree max_expr = parse_expression ();
- if (! ignoring)
- expr = build (RANGE_EXPR, NULL_TREE, expr, max_expr);
- }
- return expr;
-}
-
-/* Parses: <case_label_list>
- Fails if not followed by COMMA or COLON.
- If it fails, it backs up if needed, and returns NULL_TREE.
- IN_TUPLE is true if we are parsing a tuple element,
- and 0 if we are parsing a case label specification. */
-
-static tree
-parse_case_label_list (selector, in_tuple)
- tree selector;
- int in_tuple;
-{
- tree expr, list;
- if (! check_token (LPRN))
- return NULL_TREE;
- if (check_token (MUL))
- {
- expect (RPRN, "missing ')' after '*' case label list");
- if (ignoring)
- return integer_zero_node;
- expr = build (RANGE_EXPR, NULL_TREE, NULL_TREE, NULL_TREE);
- expr = build_tree_list (NULL_TREE, expr);
- return expr;
- }
- expr = parse_case_label ();
- if (check_token (RPRN))
- {
- if ((in_tuple || PEEK_TOKEN () != COMMA) && PEEK_TOKEN () != COLON)
- {
- /* Ooops! It looks like it was the start of an action or
- unlabelled tuple element, and not a case label, so back up. */
- if (expr != NULL_TREE && TREE_CODE (expr) == RANGE_EXPR)
- {
- error ("misplaced colon in case label");
- expr = error_mark_node;
- }
- pushback_paren_expr (expr);
- return NULL_TREE;
- }
- list = build_tree_list (NULL_TREE, expr);
- if (expr == case_else_node && selector != NULL_TREE)
- ELSE_LABEL_SPECIFIED (selector) = 1;
- return list;
- }
- list = build_tree_list (NULL_TREE, expr);
- if (expr == case_else_node && selector != NULL_TREE)
- ELSE_LABEL_SPECIFIED (selector) = 1;
-
- while (check_token (COMMA))
- {
- expr = parse_case_label ();
- list = tree_cons (NULL_TREE, expr, list);
- if (expr == case_else_node && selector != NULL_TREE)
- ELSE_LABEL_SPECIFIED (selector) = 1;
- }
- expect (RPRN, "missing ')' at end of case label list");
- return nreverse (list);
-}
-
-/* Parses: <case_label_specification>
- Must be followed by a COLON.
- If it fails, it backs up if needed, and returns NULL_TREE. */
-
-static tree
-parse_case_label_specification (selectors)
- tree selectors;
-{
- tree list_list = NULL_TREE;
- tree list;
- list = parse_case_label_list (selectors, 0);
- if (list == NULL_TREE)
- return NULL_TREE;
- list_list = build_tree_list (NULL_TREE, list);
- while (check_token (COMMA))
- {
- if (selectors != NULL_TREE)
- selectors = TREE_CHAIN (selectors);
- list = parse_case_label_list (selectors, 0);
- if (list == NULL_TREE)
- {
- error ("unrecognized case label list after ','");
- return list_list;
- }
- list_list = tree_cons (NULL_TREE, list, list_list);
- }
- return nreverse (list_list);
-}
-
-static void
-parse_single_dimension_case_action (selector)
- tree selector;
-{
- int no_completeness_check = 0;
-
-/* The case label/action toggle. It is 0 initially, and when an action
- was last seen. It is 1 integer_zero_node when a label was last seen. */
- int caseaction_flag = 0;
-
- if (! ignoring)
- {
- expand_exit_needed = 0;
- selector = check_case_selector (selector);
- expand_start_case (1, selector, TREE_TYPE (selector), "CASE statement");
- push_momentary ();
- }
-
- for (;;)
- {
- tree label_spec = parse_case_label_specification (selector);
- if (label_spec != NULL_TREE)
- {
- expect (COLON, "missing ':' in case alternative");
- if (! ignoring)
- {
- no_completeness_check |= chill_handle_single_dimension_case_label (
- selector, label_spec, &expand_exit_needed, &caseaction_flag);
- }
- }
- else if (parse_action ())
- {
- expand_exit_needed = 1;
- caseaction_flag = 0;
- }
- else
- break;
- }
-
- if (! ignoring)
- {
- if (expand_exit_needed || caseaction_flag == 1)
- expand_exit_something ();
- }
- if (check_token (ELSE))
- {
- if (! ignoring)
- chill_handle_case_default ();
- parse_opt_actions ();
- if (! ignoring)
- {
- emit_line_note (input_filename, lineno);
- expand_exit_something ();
- }
- }
- else if (! ignoring && TREE_CODE (selector) != ERROR_MARK &&
- ! no_completeness_check)
- check_missing_cases (TREE_TYPE (selector));
-
- expect (ESAC, "missing 'ESAC' after 'CASE'");
- if (! ignoring)
- {
- expand_end_case (selector);
- pop_momentary ();
- }
-}
-
-static void
-parse_multi_dimension_case_action (selector)
- tree selector;
-{
- struct rtx_def *begin_test_label = 0, *end_case_label = 0, *new_label;
- tree action_labels = NULL_TREE;
- tree tests = NULL_TREE;
- int save_lineno = lineno;
- const char *save_filename = input_filename;
-
- /* We can't compute the range of an (ELSE) label until all of the CASE
- label specifications have been seen, however, the code for the actions
- between them is generated on the fly. We can still generate everything in
- one pass is we use the following form:
-
- Compile a CASE of the form
-
- case S1,...,Sn of
- (X11),...,(X1n): A1;
- ...
- (Xm1),...,(Xmn): Am;
- else Ae;
- esac;
-
- into:
-
- goto L0;
- L1: A1; goto L99;
- ...
- Lm: Am; goto L99;
- Le: Ae; goto L99;
- L0:
- T1 := s1; ...; Tn := Sn;
- if (T1 = X11 and ... and Tn = X1n) GOTO L1;
- ...
- if (T1 = Xm1 and ... and Tn = Xmn) GOTO Lm;
- GOTO Le;
- L99;
- */
-
- if (! ignoring)
- {
- selector = check_case_selector_list (selector);
- begin_test_label = gen_label_rtx ();
- end_case_label = gen_label_rtx ();
- emit_jump (begin_test_label);
- }
-
- for (;;)
- {
- tree label_spec = parse_case_label_specification (selector);
- if (label_spec != NULL_TREE)
- {
- expect (COLON, "missing ':' in case alternative");
- if (! ignoring)
- {
- tests = tree_cons (label_spec, NULL_TREE, tests);
-
- if (action_labels != NULL_TREE)
- emit_jump (end_case_label);
-
- new_label = gen_label_rtx ();
- emit_label (new_label);
- emit_line_note (input_filename, lineno);
- action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);
- TREE_CST_RTL (action_labels) = new_label;
- }
- }
- else if (! parse_action ())
- {
- if (action_labels != NULL_TREE)
- emit_jump (end_case_label);
- break;
- }
- }
-
- if (check_token (ELSE))
- {
- if (! ignoring)
- {
- new_label = gen_label_rtx ();
- emit_label (new_label);
- emit_line_note (input_filename, lineno);
- action_labels = tree_cons (NULL_TREE, NULL_TREE, action_labels);
- TREE_CST_RTL (action_labels) = new_label;
- }
- parse_opt_actions ();
- if (! ignoring)
- emit_jump (end_case_label);
- }
-
- expect (ESAC, "missing 'ESAC' after 'CASE'");
-
- if (! ignoring)
- {
- emit_label (begin_test_label);
- emit_line_note (save_filename, save_lineno);
- if (tests != NULL_TREE)
- {
- tree cond;
- tests = nreverse (tests);
- action_labels = nreverse (action_labels);
- compute_else_ranges (selector, tests);
-
- cond = build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));
- expand_start_cond (truthvalue_conversion (cond), label ? 1 : 0);
- emit_jump (TREE_CST_RTL (action_labels));
-
- for (tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels);
- tests != NULL_TREE && action_labels != NULL_TREE;
- tests = TREE_CHAIN (tests), action_labels = TREE_CHAIN (action_labels))
- {
- cond =
- build_multi_case_selector_expression (selector, TREE_PURPOSE (tests));
- expand_start_elseif (truthvalue_conversion (cond));
- emit_jump (TREE_CST_RTL (action_labels));
- }
- if (action_labels != NULL_TREE)
- {
- expand_start_else ();
- emit_jump (TREE_CST_RTL (action_labels));
- }
- expand_end_cond ();
- }
- emit_label (end_case_label);
- }
-}
-
-static void
-parse_case_action (label)
- tree label;
-{
- tree selector;
- int multi_dimension_case = 0;
-
- require (CASE);
- selector = parse_expr_list ();
- selector = nreverse (selector);
- expect (OF, "missing 'OF' after 'CASE'");
- parse_range_list_clause ();
-
- PUSH_ACTION;
- if (label)
- pushlevel (1);
-
- if (! ignoring)
- {
- expand_exit_needed = 0;
- if (TREE_CODE (selector) == TREE_LIST)
- {
- if (TREE_CHAIN (selector) != NULL_TREE)
- multi_dimension_case = 1;
- else
- selector = TREE_VALUE (selector);
- }
- }
-
- /* We want to use the regular CASE support for the single dimension case. The
- multi dimension case requires different handling. Note that when "ignoring"
- is true we parse using the single dimension code. This is OK since it will
- still parse correctly. */
- if (multi_dimension_case)
- parse_multi_dimension_case_action (selector);
- else
- parse_single_dimension_case_action (selector);
-
- if (label)
- {
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
- }
-}
-
-/* Matches: [ <asm_operand> { "," <asm_operand> }* ],
- where <asm_operand> = STRING '(' <expression> ')'
- These are the operands other than the first string and colon
- in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */
-
-static tree
-parse_asm_operands ()
-{
- tree list = NULL_TREE;
- if (PEEK_TOKEN () != STRING)
- return NULL_TREE;
- for (;;)
- {
- tree string, expr;
- if (PEEK_TOKEN () != STRING)
- {
- error ("bad ASM operand");
- return list;
- }
- string = PEEK_TREE();
- FORWARD_TOKEN ();
- expect (LPRN, "missing '(' in ASM operand");
- expr = parse_expression ();
- expect (RPRN, "missing ')' in ASM operand");
- list = tree_cons (string, expr, list);
- if (! check_token (COMMA))
- break;
- }
- return nreverse (list);
-}
-
-/* Matches: STRING { ',' STRING }* */
-
-static tree
-parse_asm_clobbers ()
-{
- tree list = NULL_TREE;
- for (;;)
- {
- tree string;
- if (PEEK_TOKEN () != STRING)
- {
- error ("bad ASM operand");
- return list;
- }
- string = PEEK_TREE();
- FORWARD_TOKEN ();
- list = tree_cons (NULL_TREE, string, list);
- if (! check_token (COMMA))
- break;
- }
- return list;
-}
-
-static void
-ch_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
- tree string, outputs, inputs, clobbers;
- int vol;
- const char *filename;
- int line;
-{
- int noutputs = list_length (outputs);
- register int i;
- /* o[I] is the place that output number I should be written. */
- register tree *o = (tree *) alloca (noutputs * sizeof (tree));
- register tree tail;
-
- if (TREE_CODE (string) == ADDR_EXPR)
- string = TREE_OPERAND (string, 0);
- if (TREE_CODE (string) != STRING_CST)
- {
- error ("asm template is not a string constant");
- return;
- }
-
- /* Record the contents of OUTPUTS before it is modified. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- o[i] = TREE_VALUE (tail);
-
-#if 0
- /* Perform default conversions on array and function inputs. */
- /* Don't do this for other types--
- it would screw up operands expected to be in memory. */
- for (i = 0, tail = inputs; tail; tail = TREE_CHAIN (tail), i++)
- if (TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == ARRAY_TYPE
- || TREE_CODE (TREE_TYPE (TREE_VALUE (tail))) == FUNCTION_TYPE)
- TREE_VALUE (tail) = default_conversion (TREE_VALUE (tail));
-#endif
-
- /* Generate the ASM_OPERANDS insn;
- store into the TREE_VALUEs of OUTPUTS some trees for
- where the values were actually stored. */
- expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
-
- /* Copy all the intermediate outputs into the specified outputs. */
- for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- {
- if (o[i] != TREE_VALUE (tail))
- {
- expand_expr (build_chill_modify_expr (o[i], TREE_VALUE (tail)),
- 0, VOIDmode, 0);
- free_temp_slots ();
- }
- /* Detect modification of read-only values.
- (Otherwise done by build_modify_expr.) */
- else
- {
- tree type = TREE_TYPE (o[i]);
- if (TYPE_READONLY (type)
- || ((TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE)
- && TYPE_FIELDS_READONLY (type)))
- warning ("readonly location modified by 'asm'");
- }
- }
-
- /* Those MODIFY_EXPRs could do autoincrements. */
- emit_queue ();
-}
-
-static void
-parse_asm_action ()
-{
- tree insn;
- require (ASM_KEYWORD);
- expect (LPRN, "missing '('");
- PUSH_ACTION;
- if (!ignoring)
- emit_line_note (input_filename, lineno);
- insn = parse_expression ();
- if (check_token (COLON))
- {
- tree output_operand, input_operand, clobbered_regs;
- output_operand = parse_asm_operands ();
- if (check_token (COLON))
- input_operand = parse_asm_operands ();
- else
- input_operand = NULL_TREE;
- if (check_token (COLON))
- clobbered_regs = parse_asm_clobbers ();
- else
- clobbered_regs = NULL_TREE;
- expect (RPRN, "missing ')'");
- if (!ignoring)
- ch_expand_asm_operands (insn, output_operand, input_operand,
- clobbered_regs, FALSE,
- input_filename, lineno);
- }
- else
- {
- expect (RPRN, "missing ')'");
- STRIP_NOPS (insn);
- if (ignoring) { }
- else if ((TREE_CODE (insn) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (insn, 0)) == STRING_CST)
- || TREE_CODE (insn) == STRING_CST)
- expand_asm (insn);
- else
- error ("argument of `asm' is not a constant string");
- }
-}
-
-static void
-parse_begin_end_block (label)
- tree label;
-{
- require (BEGINTOKEN);
-#if 0
- /* don't make a linenote at BEGIN */
- INIT_ACTION;
-#endif
- pushlevel (1);
- if (! ignoring)
- {
- clear_last_expr ();
- push_momentary ();
- expand_start_bindings (label ? 1 : 0);
- }
- push_handler ();
- parse_body ();
- expect (END, "missing 'END'");
- /* Note that the opthandler comes before the poplevel
- - hence a handler is in the scope of the block. */
- parse_opt_handler ();
- possibly_define_exit_label (label);
- if (! ignoring)
- {
- emit_line_note (input_filename, lineno);
- expand_end_bindings (getdecls (), kept_level_p (), 0);
- }
- poplevel (kept_level_p (), 0, 0);
- if (! ignoring)
- pop_momentary ();
- parse_opt_end_label_semi_colon (label);
-}
-
-static void
-parse_if_action (label)
- tree label;
-{
- tree cond;
- require (IF);
- PUSH_ACTION;
- cond = parse_expression ();
- if (label)
- pushlevel (1);
- if (! ignoring)
- {
- expand_start_cond (truthvalue_conversion (cond),
- label ? 1 : 0);
- }
- parse_then_clause ();
- parse_opt_else_clause ();
- expect (FI, "expected 'FI' after 'IF'");
- if (! ignoring)
- {
- emit_line_note (input_filename, lineno);
- expand_end_cond ();
- }
- if (label)
- {
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
- }
-}
-
-/* Matches: <iteration> (as in a <for control>). */
-
-static void
-parse_iteration ()
-{
- tree loop_counter = parse_defining_occurrence ();
- if (check_token (ASGN))
- {
- tree start_value = parse_expression ();
- tree step_value
- = check_token (BY) ? parse_expression () : NULL_TREE;
- int going_down = check_token (DOWN);
- tree end_value;
- if (check_token (TO))
- end_value = parse_expression ();
- else
- {
- error ("expected 'TO' in step enumeration");
- end_value = error_mark_node;
- }
- if (!ignoring)
- build_loop_iterator (loop_counter, start_value, step_value,
- end_value, going_down, 0, 0);
- }
- else
- {
- int going_down = check_token (DOWN);
- tree expr;
- if (check_token (IN))
- expr = parse_expression ();
- else
- {
- error ("expected 'IN' in FOR control here");
- expr = error_mark_node;
- }
- if (!ignoring)
- {
- tree low_bound, high_bound;
- if (expr && TREE_CODE (expr) == TYPE_DECL)
- {
- expr = TREE_TYPE (expr);
- /* FIXME: expr must be an array or powerset */
- low_bound = convert (expr, TYPE_MIN_VALUE (expr));
- high_bound = convert (expr, TYPE_MAX_VALUE (expr));
- }
- else
- {
- low_bound = expr;
- high_bound = NULL_TREE;
- }
- build_loop_iterator (loop_counter, low_bound,
- NULL_TREE, high_bound,
- going_down, 1, 0);
- }
- }
-}
-
-/* Matches: '(' <event list> ')' ':'.
- Or; returns NULL_EXPR. */
-
-static tree
-parse_delay_case_event_list ()
-{
- tree event_list = NULL_TREE;
- tree event;
- if (! check_token (LPRN))
- return NULL_TREE;
- event = parse_expression ();
- if (PEEK_TOKEN () == ')' && PEEK_TOKEN1 () != ':')
- {
- /* Oops. */
- require (RPRN);
- pushback_paren_expr (event);
- return NULL_TREE;
- }
- for (;;)
- {
- if (! ignoring)
- event_list = tree_cons (NULL_TREE, event, event_list);
- if (! check_token (COMMA))
- break;
- event = parse_expression ();
- }
- expect (RPRN, "missing ')'");
- expect (COLON, "missing ':'");
- return ignoring ? error_mark_node : event_list;
-}
-
-static void
-parse_delay_case_action (label)
- tree label;
-{
- tree label_cnt = NULL_TREE, set_location, priority;
- tree combined_event_list = NULL_TREE;
- require (DELAY);
- require (CASE);
- PUSH_ACTION;
- pushlevel (1);
- expand_exit_needed = 0;
- if (check_token (SET))
- {
- set_location = parse_expression ();
- parse_semi_colon ();
- }
- else
- set_location = NULL_TREE;
- if (check_token (PRIORITY))
- {
- priority = parse_expression ();
- parse_semi_colon ();
- }
- else
- priority = NULL_TREE;
- if (! ignoring)
- label_cnt = build_delay_case_start (set_location, priority);
- for (;;)
- {
- tree event_list = parse_delay_case_event_list ();
- if (event_list)
- {
- if (! ignoring )
- {
- int if_or_elseif = combined_event_list == NULL_TREE;
- build_delay_case_label (event_list, if_or_elseif);
- combined_event_list = chainon (combined_event_list, event_list);
- }
- }
- else if (parse_action ())
- {
- if (! ignoring)
- {
- expand_exit_needed = 1;
- if (combined_event_list == NULL_TREE)
- error ("missing DELAY CASE alternative");
- }
- }
- else
- break;
- }
- expect (ESAC, "missing 'ESAC' in DELAY CASE'");
- if (! ignoring)
- build_delay_case_end (combined_event_list);
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
-}
-
-static void
-parse_do_action (label)
- tree label;
-{
- tree condition;
- int token;
- require (DO);
- if (check_token (WITH))
- {
- tree list = NULL_TREE;
- for (;;)
- {
- tree name = parse_primval ();
- if (! ignoring && TREE_CODE (name) != ERROR_MARK)
- {
- if (TREE_CODE (TREE_TYPE (name)) == REFERENCE_TYPE)
- name = convert (TREE_TYPE (TREE_TYPE (name)), name);
- else
- {
- int is_loc = chill_location (name);
- if (is_loc == 1) /* This is probably not possible */
- warning ("non-referable location in DO WITH");
-
- if (is_loc > 1)
- name = build_chill_arrow_expr (name, 1);
- name = decl_temp1 (get_identifier ("__with_element"),
- TREE_TYPE (name),
- 0, name, 0, 0);
- if (is_loc > 1)
- name = build_chill_indirect_ref (name, NULL_TREE, 0);
-
- }
- if (TREE_CODE (TREE_TYPE (name)) != RECORD_TYPE)
- error ("WITH element must be of STRUCT mode");
- else
- list = tree_cons (NULL_TREE, name, list);
- }
- if (! check_token (COMMA))
- break;
- }
- pushlevel (1);
- push_action ();
- for (list = nreverse (list); list != NULL_TREE; list = TREE_CHAIN (list))
- shadow_record_fields (TREE_VALUE (list));
-
- parse_semi_colon ();
- parse_opt_actions ();
- expect (OD, "missing 'OD' in 'DO WITH'");
- if (! ignoring)
- emit_line_note (input_filename, lineno);
- possibly_define_exit_label (label);
- parse_opt_handler ();
- parse_opt_end_label_semi_colon (label);
- poplevel (0, 0, 0);
- return;
- }
- token = PEEK_TOKEN();
- if (token != FOR && token != WHILE)
- {
- push_handler ();
- parse_opt_actions ();
- expect (OD, "Missing 'OD' after 'DO'");
- parse_opt_handler ();
- parse_opt_end_label_semi_colon (label);
- return;
- }
- if (! ignoring)
- emit_line_note (input_filename, lineno);
- push_loop_block ();
- if (check_token (FOR))
- {
- if (check_token (EVER))
- {
- if (!ignoring)
- build_loop_iterator (NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE,
- 0, 0, 1);
- }
- else
- {
- parse_iteration ();
- while (check_token (COMMA))
- parse_iteration ();
- }
- }
- else if (!ignoring)
- build_loop_iterator (NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE,
- 0, 0, 1);
-
- begin_loop_scope ();
- if (! ignoring)
- build_loop_start (label);
- condition = check_token (WHILE) ? parse_expression () : NULL_TREE;
- if (! ignoring)
- top_loop_end_check (condition);
- parse_semi_colon ();
- parse_opt_actions ();
- if (! ignoring)
- build_loop_end ();
- expect (OD, "Missing 'OD' after 'DO'");
- /* Note that the handler is inside the reach of the DO. */
- parse_opt_handler ();
- end_loop_scope (label);
- pop_loop_block ();
- parse_opt_end_label_semi_colon (label);
-}
-
-/* Matches: '(' <signal name> [ 'IN' <defining occurrence list> ']' ')' ':'
- or: '(' <buffer location> IN (defining occurrence> ')' ':'
- or: returns NULL_TREE. */
-
-static tree
-parse_receive_spec ()
-{
- tree val;
- tree name_list = NULL_TREE;
- if (!check_token (LPRN))
- return NULL_TREE;
- val = parse_primval ();
- if (check_token (IN))
- {
-#if 0
- if (flag_local_loop_counter)
- name_list = parse_defining_occurrence_list ();
- else
-#endif
- {
- for (;;)
- {
- tree loc = parse_primval ();
- if (! ignoring)
- name_list = tree_cons (NULL_TREE, loc, name_list);
- if (! check_token (COMMA))
- break;
- }
- }
- }
- if (! check_token (RPRN))
- {
- error ("missing ')' in signal/buffer receive alternative");
- return NULL_TREE;
- }
- if (check_token (COLON))
- {
- if (ignoring || val == NULL_TREE || TREE_CODE (val) == ERROR_MARK)
- return error_mark_node;
- else
- return build_receive_case_label (val, name_list);
- }
-
- /* We saw: '(' <primitive value> ')' not followed by ':'.
- Presumably the start of an action. Backup and fail. */
- if (name_list != NULL_TREE)
- error ("misplaced 'IN' in signal/buffer receive alternative");
- pushback_paren_expr (val);
- return NULL_TREE;
-}
-
-/* To understand the code generation for this, see ch-tasking.c,
- and the 2-page comments preceding the
- build_chill_receive_case_start () definition. */
-
-static void
-parse_receive_case_action (label)
- tree label;
-{
- tree instance_location;
- tree have_else_actions;
- int spec_seen = 0;
- tree alt_list = NULL_TREE;
- require (RECEIVE);
- require (CASE);
- push_action ();
- pushlevel (1);
- if (! ignoring)
- {
- expand_exit_needed = 0;
- }
-
- if (check_token (SET))
- {
- instance_location = parse_expression ();
- parse_semi_colon ();
- }
- else
- instance_location = NULL_TREE;
- if (! ignoring)
- instance_location = build_receive_case_start (instance_location);
-
- for (;;)
- {
- tree receive_spec = parse_receive_spec ();
- if (receive_spec)
- {
- if (! ignoring)
- alt_list = tree_cons (NULL_TREE, receive_spec, alt_list);
- spec_seen++;
- }
- else if (parse_action ())
- {
- if (! spec_seen && pass == 1)
- error ("missing RECEIVE alternative");
- if (! ignoring)
- expand_exit_needed = 1;
- spec_seen = 1;
- }
- else
- break;
- }
- if (check_token (ELSE))
- {
- if (! ignoring)
- {
- emit_line_note (input_filename, lineno);
- if (build_receive_case_if_generated ())
- expand_start_else ();
- }
- parse_opt_actions ();
- have_else_actions = integer_one_node;
- }
- else
- have_else_actions = integer_zero_node;
- expect (ESAC, "missing 'ESAC' matching 'RECEIVE CASE'");
- if (! ignoring)
- {
- build_receive_case_end (nreverse (alt_list), have_else_actions);
- }
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
-}
-
-static void
-parse_send_action ()
-{
- tree signal = NULL_TREE;
- tree buffer = NULL_TREE;
- tree value_list;
- tree with_expr, to_expr, priority;
- require (SEND);
- /* The tricky part is distinguishing between a SEND buffer action,
- and a SEND signal action. */
- if (pass != 2 || PEEK_TOKEN () != NAME)
- {
- /* If this is pass 2, it's a SEND buffer action.
- If it's pass 1, we don't care. */
- buffer = parse_primval ();
- }
- else
- {
- /* We have to specifically check for signalname followed by
- a '(', since we allow a signalname to be used (syntactically)
- as a "function". */
- tree name = parse_name ();
- if (TREE_CODE (name) == TYPE_DECL && CH_DECL_SIGNAL (name))
- signal = name; /* It's a SEND signal action! */
- else
- {
- /* It's not a legal SEND signal action.
- Back up and try as a SEND buffer action. */
- pushback_token (EXPR, name);
- buffer = parse_primval ();
- }
- }
- if (check_token (LPRN))
- {
- value_list = NULL_TREE;
- for (;;)
- {
- tree expr = parse_untyped_expr ();
- if (! ignoring)
- value_list = tree_cons (NULL_TREE, expr, value_list);
- if (! check_token (COMMA))
- break;
- }
- value_list = nreverse (value_list);
- expect (RPRN, "missing ')'");
- }
- else
- value_list = NULL_TREE;
- if (check_token (WITH))
- with_expr = parse_expression ();
- else
- with_expr = NULL_TREE;
- if (check_token (TO))
- to_expr = parse_expression ();
- else
- to_expr = NULL_TREE;
- if (check_token (PRIORITY))
- priority = parse_expression ();
- else
- priority = NULL_TREE;
- PUSH_ACTION;
- if (ignoring)
- return;
-
- if (signal)
- { /* It's a <send signal action>! */
- tree sigdesc = build_signal_descriptor (signal, value_list);
- if (sigdesc != NULL_TREE && TREE_CODE (sigdesc) != ERROR_MARK)
- {
- tree sendto = to_expr ? to_expr : IDENTIFIER_SIGNAL_DEST (signal);
- expand_send_signal (sigdesc, with_expr,
- sendto, priority, DECL_NAME (signal));
- }
- }
- else
- {
- /* all checks are done in expand_send_buffer */
- expand_send_buffer (buffer, value_list, priority, with_expr, to_expr);
- }
-}
-
-static void
-parse_start_action ()
-{
- tree name, copy_number, param_list, startset;
- require (START);
- name = parse_name_string ();
- expect (LPRN, "missing '(' in START action");
- PUSH_ACTION;
- /* copy number is a required parameter */
- copy_number = parse_expression ();
- if (!ignoring
- && (copy_number == NULL_TREE
- || TREE_CODE (copy_number) == ERROR_MARK
- || TREE_CODE (TREE_TYPE (copy_number)) != INTEGER_TYPE))
- {
- error ("PROCESS copy number must be integer");
- copy_number = integer_zero_node;
- }
- if (check_token (COMMA))
- param_list = parse_expr_list (); /* user parameters */
- else
- param_list = NULL_TREE;
- expect (RPRN, "missing ')'");
- startset = check_token (SET) ? parse_primval () : NULL;
- build_start_process (name, copy_number, param_list, startset);
-}
-
-static void
-parse_opt_actions ()
-{
- while (parse_action ()) ;
-}
-
-static int
-parse_action ()
-{
- tree label = NULL_TREE;
- tree expr, rhs, loclist;
- enum tree_code op;
-
- if (current_function_decl == global_function_decl
- && PEEK_TOKEN () != SC
- && PEEK_TOKEN () != END)
- seen_action = 1, build_constructor = 1;
-
- if (PEEK_TOKEN () == NAME && PEEK_TOKEN1 () == COLON)
- {
- label = parse_defining_occurrence ();
- require (COLON);
- INIT_ACTION;
- define_label (input_filename, lineno, label);
- }
-
- switch (PEEK_TOKEN ())
- {
- case AFTER:
- {
- int delay;
- require (AFTER);
- expr = parse_primval ();
- delay = check_token (DELAY);
- expect (IN, "missing 'IN'");
- push_action ();
- pushlevel (1);
- build_after_start (expr, delay);
- parse_opt_actions ();
- expect (TIMEOUT, "missing 'TIMEOUT'");
- build_after_timeout_start ();
- parse_opt_actions ();
- expect (END, "missing 'END'");
- build_after_end ();
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
- }
- goto bracketed_action;
- case ASM_KEYWORD:
- parse_asm_action ();
- goto no_handler_action;
- case ASSERT:
- require (ASSERT);
- PUSH_ACTION;
- expr = parse_expression ();
- if (! ignoring)
- { tree assertfail = ridpointers[(int) RID_ASSERTFAIL];
- expr = build (TRUTH_ORIF_EXPR, void_type_node, expr,
- build_cause_exception (assertfail, 0));
- expand_expr_stmt (fold (expr));
- }
- goto handler_action;
- case AT:
- require (AT);
- PUSH_ACTION;
- expr = parse_primval ();
- expect (IN, "missing 'IN'");
- pushlevel (1);
- if (! ignoring)
- build_at_action (expr);
- parse_opt_actions ();
- expect (TIMEOUT, "missing 'TIMEOUT'");
- if (! ignoring)
- expand_start_else ();
- parse_opt_actions ();
- expect (END, "missing 'END'");
- if (! ignoring)
- expand_end_cond ();
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
- goto bracketed_action;
- case BEGINTOKEN:
- parse_begin_end_block (label);
- return 1;
- case CASE:
- parse_case_action (label);
- goto bracketed_action;
- case CAUSE:
- require (CAUSE);
- expr = parse_name_string ();
- PUSH_ACTION;
- if (! ignoring && TREE_CODE (expr) != ERROR_MARK)
- expand_cause_exception (expr);
- goto no_handler_action;
- case CONTINUE:
- require (CONTINUE);
- expr = parse_expression ();
- PUSH_ACTION;
- if (! ignoring)
- expand_continue_event (expr);
- goto handler_action;
- case CYCLE:
- require (CYCLE);
- PUSH_ACTION;
- expr = parse_primval ();
- expect (IN, "missing 'IN' after 'CYCLE'");
- pushlevel (1);
- /* We a tree list where TREE_VALUE is the label
- and TREE_PURPOSE is the variable denotes the timeout id. */
- expr = build_cycle_start (expr);
- parse_opt_actions ();
- expect (END, "missing 'END'");
- if (! ignoring)
- build_cycle_end (expr);
- possibly_define_exit_label (label);
- poplevel (0, 0, 0);
- goto bracketed_action;
- case DELAY:
- if (PEEK_TOKEN1 () == CASE)
- {
- parse_delay_case_action (label);
- goto bracketed_action;
- }
- require (DELAY);
- PUSH_ACTION;
- expr = parse_primval ();
- rhs = check_token (PRIORITY) ? parse_expression () : NULL_TREE;
- if (! ignoring)
- build_delay_action (expr, rhs);
- goto handler_action;
- case DO:
- parse_do_action (label);
- return 1;
- case EXIT:
- require (EXIT);
- expr = parse_name_string ();
- PUSH_ACTION;
- lookup_and_handle_exit (expr);
- goto no_handler_action;
- case GOTO:
- require (GOTO);
- expr = parse_name_string ();
- PUSH_ACTION;
- lookup_and_expand_goto (expr);
- goto no_handler_action;
- case IF:
- parse_if_action (label);
- goto bracketed_action;
- case RECEIVE:
- if (PEEK_TOKEN1 () != CASE)
- return 0;
- parse_receive_case_action (label);
- goto bracketed_action;
- case RESULT:
- require (RESULT);
- PUSH_ACTION;
- expr = parse_untyped_expr ();
- if (! ignoring)
- chill_expand_result (expr, 1);
- goto handler_action;
- case RETURN:
- require (RETURN);
- PUSH_ACTION;
- expr = parse_opt_untyped_expr ();
- if (! ignoring)
- {
- /* Do this as RESULT expr and RETURN to get exceptions */
- chill_expand_result (expr, 0);
- expand_goto_except_cleanup (proc_action_level);
- chill_expand_return (NULL_TREE, 0);
- }
- if (expr)
- goto handler_action;
- else
- goto no_handler_action;
- case SC:
- require (SC);
- return 1;
- case SEND:
- parse_send_action ();
- goto handler_action;
- case START:
- parse_start_action ();
- goto handler_action;
- case STOP:
- require (STOP);
- PUSH_ACTION;
- if (! ignoring)
- { tree func = lookup_name (get_identifier ("__stop_process"));
- tree result = build_chill_function_call (func, NULL_TREE);
- expand_expr_stmt (result);
- }
- goto no_handler_action;
- case CALL:
- require (CALL);
- /* Fall through to here ... */
- case EXPR:
- case LPRN:
- case NAME:
- /* This handles calls and assignments. */
- PUSH_ACTION;
- expr = parse_primval ();
- switch (PEEK_TOKEN ())
- {
- case END:
- parse_semi_colon (); /* Emits error message. */
- case ON:
- case SC:
- if (!ignoring && TREE_CODE (expr) != ERROR_MARK)
- {
- if (TREE_CODE (expr) != CALL_EXPR
- && TREE_TYPE (expr) != void_type_node
- && ! TREE_SIDE_EFFECTS (expr))
- {
- if (TREE_CODE (expr) == FUNCTION_DECL)
- error ("missing parenthesis for procedure call");
- else
- error ("expression is not an action");
- expr = error_mark_node;
- }
- else
- expand_expr_stmt (expr);
- }
- goto handler_action;
- default:
- loclist
- = ignoring ? NULL_TREE : build_tree_list (NULL_TREE, expr);
- while (PEEK_TOKEN () == COMMA)
- {
- FORWARD_TOKEN ();
- expr = parse_primval ();
- if (!ignoring && TREE_CODE (expr) != ERROR_MARK)
- loclist = tree_cons (NULL_TREE, expr, loclist);
- }
- }
- switch (PEEK_TOKEN ())
- {
- case OR: op = BIT_IOR_EXPR; break;
- case XOR: op = BIT_XOR_EXPR; break;
- case ORIF: op = TRUTH_ORIF_EXPR; break;
- case AND: op = BIT_AND_EXPR; break;
- case ANDIF: op = TRUTH_ANDIF_EXPR; break;
- case PLUS: op = PLUS_EXPR; break;
- case SUB: op = MINUS_EXPR; break;
- case CONCAT: op = CONCAT_EXPR; break;
- case MUL: op = MULT_EXPR; break;
- case DIV: op = TRUNC_DIV_EXPR; break;
- case MOD: op = FLOOR_MOD_EXPR; break;
- case REM: op = TRUNC_MOD_EXPR; break;
-
- default:
- error ("syntax error in action");
- case SC: case ON:
- case ASGN: op = NOP_EXPR; break;
- ;
- }
-
- /* Looks like it was an assignment action. */
- FORWARD_TOKEN ();
- if (op != NOP_EXPR)
- expect (ASGN, "expected ':=' here");
- rhs = parse_untyped_expr ();
- if (!ignoring)
- expand_assignment_action (loclist, op, rhs);
- goto handler_action;
-
- default:
- return 0;
- }
-
- bracketed_action:
- /* We've parsed a bracketed action. */
- parse_opt_handler ();
- parse_opt_end_label_semi_colon (label);
- return 1;
-
- no_handler_action:
- if (parse_opt_handler () != NULL_TREE && pass == 1)
- error ("no handler is permitted on this action.");
- parse_semi_colon ();
- return 1;
-
- handler_action:
- parse_opt_handler ();
- parse_semi_colon ();
- return 1;
-}
-
-static void
-parse_body ()
-{
- again:
- while (parse_definition (0)) ;
-
- while (parse_action ()) ;
-
- if (parse_definition (0))
- {
- if (pass == 1)
- pedwarn ("definition follows action");
- goto again;
- }
-}
-
-static tree
-parse_opt_untyped_expr ()
-{
- switch (PEEK_TOKEN ())
- {
- case ON:
- case END:
- case SC:
- case COMMA:
- case COLON:
- case RPRN:
- return NULL_TREE;
- default:
- return parse_untyped_expr ();
- }
-}
-
-static tree
-parse_call (function)
- tree function;
-{
- tree arg1, arg2, arg_list = NULL_TREE;
- enum terminal tok;
- require (LPRN);
- arg1 = parse_opt_untyped_expr ();
- if (arg1 != NULL_TREE)
- {
- tok = PEEK_TOKEN ();
- if (tok == UP || tok == COLON)
- {
- FORWARD_TOKEN ();
-#if 0
- /* check that arg1 isn't untyped (or mode);*/
-#endif
- arg2 = parse_expression ();
- expect (RPRN, "expected ')' to terminate slice");
- if (ignoring)
- return integer_zero_node;
- else if (tok == UP)
- return build_chill_slice_with_length (function, arg1, arg2);
- else
- return build_chill_slice_with_range (function, arg1, arg2);
- }
- if (!ignoring)
- arg_list = build_tree_list (NULL_TREE, arg1);
- while (check_token (COMMA))
- {
- arg2 = parse_untyped_expr ();
- if (!ignoring)
- arg_list = tree_cons (NULL_TREE, arg2, arg_list);
- }
- }
-
- expect (RPRN, "expected ')' here");
- return ignoring ? function
- : build_generalized_call (function, nreverse (arg_list));
-}
-
-/* Matches: <field name list>
- Returns: A list of IDENTIFIER_NODEs (or NULL_TREE if ignoring),
- in reverse order. */
-
-static tree
-parse_tuple_fieldname_list ()
-{
- tree list = NULL_TREE;
- do
- {
- tree name;
- if (!check_token (DOT))
- {
- error ("bad tuple field name list");
- return NULL_TREE;
- }
- name = parse_simple_name_string ();
- list = ignoring ? NULL_TREE : tree_cons (NULL_TREE, name, list);
- } while (check_token (COMMA));
- return list;
-}
-
-/* Returns one or nore TREE_LIST nodes, in reverse order. */
-
-static tree
-parse_tuple_element ()
-{
- /* The tupleelement chain is built in reverse order,
- and put in forward order when the list is used. */
- tree value, label;
- if (PEEK_TOKEN () == DOT)
- {
- /* Parse a labelled structure tuple. */
- tree list = parse_tuple_fieldname_list (), field;
- expect (COLON, "missing ':' in tuple");
- value = parse_untyped_expr ();
- if (ignoring)
- return NULL_TREE;
- /* FIXME: Should use save_expr(value), but that
- confuses nested calls to digest_init! */
- /* Re-use the list of field names as a list of name-value pairs. */
- for (field = list; field != NULL_TREE; field = TREE_CHAIN (field))
- { tree field_name = TREE_VALUE (field);
- TREE_PURPOSE (field) = field_name;
- TREE_VALUE (field) = value;
- TUPLE_NAMED_FIELD (field) = 1;
- }
- return list;
- }
-
- label = parse_case_label_list (NULL_TREE, 1);
- if (label)
- {
- expect (COLON, "missing ':' in tuple");
- value = parse_untyped_expr ();
- if (ignoring || label == NULL_TREE)
- return NULL_TREE;
- if (TREE_CODE (label) != TREE_LIST)
- {
- error ("invalid syntax for label in tuple");
- return NULL_TREE;
- }
- else
- {
- /* FIXME: Should use save_expr(value), but that
- confuses nested calls to digest_init! */
- tree link = label;
- for (; link != NULL_TREE; link = TREE_CHAIN (link))
- { tree index = TREE_VALUE (link);
- if (pass == 1 && TREE_CODE (index) != TREE_LIST)
- index = build1 (PAREN_EXPR, NULL_TREE, index);
- TREE_VALUE (link) = value;
- TREE_PURPOSE (link) = index;
- }
- return nreverse (label);
- }
- }
-
- value = parse_untyped_expr ();
- if (check_token (COLON))
- {
- /* A powerset range [or possibly a labeled Array?] */
- tree value2 = parse_untyped_expr ();
- return ignoring ? NULL_TREE : build_tree_list (value, value2);
- }
- return ignoring ? NULL_TREE : build_tree_list (NULL_TREE, value);
-}
-
-/* Matches: a COMMA-separated list of tuple elements.
- Returns a list (of TREE_LIST nodes). */
-static tree
-parse_opt_element_list ()
-{
- tree list = NULL_TREE;
- if (PEEK_TOKEN () == RPC)
- return NULL_TREE;
- for (;;)
- {
- tree element = parse_tuple_element ();
- list = chainon (element, list); /* Built in reverse order */
- if (PEEK_TOKEN () == RPC)
- break;
- if (!check_token (COMMA))
- {
- error ("bad syntax in tuple");
- return NULL_TREE;
- }
- }
- return nreverse (list);
-}
-
-/* Parses: '[' elements ']'
- If modename is non-NULL it prefixed the tuple. */
-
-static tree
-parse_tuple (modename)
- tree modename;
-{
- tree list;
- require (LPC);
- list = parse_opt_element_list ();
- expect (RPC, "missing ']' after tuple");
- if (ignoring)
- return integer_zero_node;
- list = build_nt (CONSTRUCTOR, NULL_TREE, list);
- if (modename == NULL_TREE)
- return list;
- else if (pass == 1)
- TREE_TYPE (list) = modename;
- else if (TREE_CODE (modename) != TYPE_DECL)
- {
- error ("non-mode name before tuple");
- return error_mark_node;
- }
- else
- list = chill_expand_tuple (TREE_TYPE (modename), list);
- return list;
-}
-
-static tree
-parse_primval ()
-{
- tree val;
- switch (PEEK_TOKEN ())
- {
- case NUMBER:
- case FLOATING:
- case STRING:
- case SINGLECHAR:
- case BITSTRING:
- case CONST:
- case EXPR:
- val = PEEK_TREE();
- FORWARD_TOKEN ();
- break;
- case THIS:
- val = build_chill_function_call (PEEK_TREE (), NULL_TREE);
- FORWARD_TOKEN ();
- break;
- case LPRN:
- FORWARD_TOKEN ();
- val = parse_expression ();
- expect (RPRN, "missing right parenthesis");
- if (pass == 1 && ! ignoring)
- val = build1 (PAREN_EXPR, NULL_TREE, val);
- break;
- case LPC:
- val = parse_tuple (NULL_TREE);
- break;
- case NAME:
- val = parse_name ();
- if (PEEK_TOKEN() == LPC)
- val = parse_tuple (val); /* Matched: <mode_name> <tuple> */
- break;
- default:
- if (!ignoring)
- error ("invalid expression/location syntax");
- val = error_mark_node;
- }
- for (;;)
- {
- tree name, args;
- switch (PEEK_TOKEN ())
- {
- case DOT:
- FORWARD_TOKEN ();
- name = parse_simple_name_string ();
- val = ignoring ? val : build_chill_component_ref (val, name);
- continue;
- case ARROW:
- FORWARD_TOKEN ();
- name = parse_opt_name_string (0);
- val = ignoring ? val : build_chill_indirect_ref (val, name, 1);
- continue;
- case LPRN:
- /* The SEND buffer action syntax is ambiguous, at least when
- parsed left-to-right. In the example 'SEND foo(v) ...' the
- phrase 'foo(v)' could be a buffer location procedure call
- (which then must be followed by the value to send).
- On the other hand, if 'foo' is a buffer, stop parsing
- after 'foo', and let parse_send_action pick up '(v) as
- the value ot send.
-
- We handle the ambiguity for SEND signal action differently,
- since we allow (as an extension) a signal to be used as
- a "function" (see build_generalized_call). */
- if (TREE_TYPE (val) != NULL_TREE
- && CH_IS_BUFFER_MODE (TREE_TYPE (val)))
- return val;
- val = parse_call (val);
- continue;
- case STRING:
- case BITSTRING:
- case SINGLECHAR:
- case NAME:
- /* Handle string repetition. (See comment in parse_operand5.) */
- args = parse_primval ();
- val = ignoring ? val : build_generalized_call (val, args);
- continue;
- default:
- break;
- }
- break;
- }
- return val;
-}
-
-static tree
-parse_operand6 ()
-{
- if (check_token (RECEIVE))
- {
- tree location ATTRIBUTE_UNUSED = parse_primval ();
- sorry ("RECEIVE expression");
- return integer_one_node;
- }
- else if (check_token (ARROW))
- {
- tree location = parse_primval ();
- return ignoring ? location : build_chill_arrow_expr (location, 0);
- }
- else
- return parse_primval();
-}
-
-static tree
-parse_operand5()
-{
- enum tree_code op;
- /* We are supposed to be looking for a <string repetition operator>,
- but in general we can't distinguish that from a parenthesized
- expression. This is especially difficult if we allow the
- string operand to be a constant expression (as requested by
- some users), and not just a string literal.
- Consider: LPRN expr RPRN LPRN expr RPRN
- Is that a function call or string repetition?
- Instead, we handle string repetition in parse_primval,
- and build_generalized_call. */
- tree rarg;
- switch (PEEK_TOKEN())
- {
- case NOT: op = BIT_NOT_EXPR; break;
- case SUB: op = NEGATE_EXPR; break;
- default:
- op = NOP_EXPR;
- }
- if (op != NOP_EXPR)
- FORWARD_TOKEN();
- rarg = parse_operand6();
- return (op == NOP_EXPR || ignoring) ? rarg
- : build_chill_unary_op (op, rarg);
-}
-
-static tree
-parse_operand4 ()
-{
- tree larg = parse_operand5(), rarg;
- enum tree_code op;
- for (;;)
- {
- switch (PEEK_TOKEN())
- {
- case MUL: op = MULT_EXPR; break;
- case DIV: op = TRUNC_DIV_EXPR; break;
- case MOD: op = FLOOR_MOD_EXPR; break;
- case REM: op = TRUNC_MOD_EXPR; break;
- default:
- return larg;
- }
- FORWARD_TOKEN();
- rarg = parse_operand5();
- if (!ignoring)
- larg = build_chill_binary_op (op, larg, rarg);
- }
-}
-
-static tree
-parse_operand3 ()
-{
- tree larg = parse_operand4 (), rarg;
- enum tree_code op;
- for (;;)
- {
- switch (PEEK_TOKEN())
- {
- case PLUS: op = PLUS_EXPR; break;
- case SUB: op = MINUS_EXPR; break;
- case CONCAT: op = CONCAT_EXPR; break;
- default:
- return larg;
- }
- FORWARD_TOKEN();
- rarg = parse_operand4();
- if (!ignoring)
- larg = build_chill_binary_op (op, larg, rarg);
- }
-}
-
-static tree
-parse_operand2 ()
-{
- tree larg = parse_operand3 (), rarg;
- enum tree_code op;
- for (;;)
- {
- if (check_token (IN))
- {
- rarg = parse_operand3();
- if (! ignoring)
- larg = build_chill_binary_op (SET_IN_EXPR, larg, rarg);
- }
- else
- {
- switch (PEEK_TOKEN())
- {
- case GT: op = GT_EXPR; break;
- case GTE: op = GE_EXPR; break;
- case LT: op = LT_EXPR; break;
- case LTE: op = LE_EXPR; break;
- case EQL: op = EQ_EXPR; break;
- case NE: op = NE_EXPR; break;
- default:
- return larg;
- }
- FORWARD_TOKEN();
- rarg = parse_operand3();
- if (!ignoring)
- larg = build_compare_expr (op, larg, rarg);
- }
- }
-}
-
-static tree
-parse_operand1 ()
-{
- tree larg = parse_operand2 (), rarg;
- enum tree_code op;
- for (;;)
- {
- switch (PEEK_TOKEN())
- {
- case AND: op = BIT_AND_EXPR; break;
- case ANDIF: op = TRUTH_ANDIF_EXPR; break;
- default:
- return larg;
- }
- FORWARD_TOKEN();
- rarg = parse_operand2();
- if (!ignoring)
- larg = build_chill_binary_op (op, larg, rarg);
- }
-}
-
-static tree
-parse_operand0 ()
-{
- tree larg = parse_operand1(), rarg;
- enum tree_code op;
- for (;;)
- {
- switch (PEEK_TOKEN())
- {
- case OR: op = BIT_IOR_EXPR; break;
- case XOR: op = BIT_XOR_EXPR; break;
- case ORIF: op = TRUTH_ORIF_EXPR; break;
- default:
- return larg;
- }
- FORWARD_TOKEN();
- rarg = parse_operand1();
- if (!ignoring)
- larg = build_chill_binary_op (op, larg, rarg);
- }
-}
-
-static tree
-parse_expression ()
-{
- return parse_operand0 ();
-}
-
-static tree
-parse_case_expression ()
-{
- tree selector_list;
- tree else_expr;
- tree case_expr;
- tree case_alt_list = NULL_TREE;
-
- require (CASE);
- selector_list = parse_expr_list ();
- selector_list = nreverse (selector_list);
-
- expect (OF, "missing 'OF'");
- while (PEEK_TOKEN () == LPRN)
- {
- tree label_spec = parse_case_label_specification (selector_list);
- tree sub_expr;
- expect (COLON, "missing ':' in value case alternative");
- sub_expr = parse_expression ();
- expect (SC, "missing ';'");
- if (! ignoring)
- case_alt_list = tree_cons (label_spec, sub_expr, case_alt_list);
- }
- if (check_token (ELSE))
- {
- else_expr = parse_expression ();
- if (check_token (SC) && pass == 1)
- warning("there should not be a ';' here");
- }
- else
- else_expr = NULL_TREE;
- expect (ESAC, "missing 'ESAC' in 'CASE' expression");
-
- if (ignoring)
- return integer_zero_node;
-
- /* If this is a multi dimension case, then transform it into an COND_EXPR
- here. This must be done before store_expr is called since it has some
- special handling for COND_EXPR expressions. */
- if (TREE_CHAIN (selector_list) != NULL_TREE)
- {
- case_alt_list = nreverse (case_alt_list);
- compute_else_ranges (selector_list, case_alt_list);
- case_expr =
- build_chill_multi_dimension_case_expr (selector_list, case_alt_list, else_expr);
- }
- else
- case_expr = build_chill_case_expr (selector_list, case_alt_list, else_expr);
-
- return case_expr;
-}
-
-static tree
-parse_then_alternative ()
-{
- expect (THEN, "missing 'THEN' in 'IF' expression");
- return parse_expression ();
-}
-
-static tree
-parse_else_alternative ()
-{
- if (check_token (ELSIF))
- return parse_if_expression_body ();
- else if (check_token (ELSE))
- return parse_expression ();
- error ("missing ELSE/ELSIF in IF expression");
- return error_mark_node;
-}
-
-/* Matches: <boolean expression> <then alternative> <else alternative> */
-
-static tree
-parse_if_expression_body ()
-{
- tree bool_expr, then_expr, else_expr;
- bool_expr = parse_expression ();
- then_expr = parse_then_alternative ();
- else_expr = parse_else_alternative ();
- if (ignoring)
- return integer_zero_node;
- else
- return build_nt (COND_EXPR, bool_expr, then_expr, else_expr);
-}
-
-static tree
-parse_if_expression ()
-{
- tree expr;
- require (IF);
- expr = parse_if_expression_body ();
- expect (FI, "missing 'FI' at end of conditional expression");
- return expr;
-}
-
-/* An <untyped_expr> is a superset of <expr>. It also includes
- <conditional expressions> and untyped <tuples>, whose types
- are not given by their constituents. Hence, these are only
- allowed in certain contexts that expect a certain type.
- You should call convert() to fix up the <untyped_expr>. */
-
-static tree
-parse_untyped_expr ()
-{
- tree val;
- switch (PEEK_TOKEN())
- {
- case IF:
- return parse_if_expression ();
- case CASE:
- return parse_case_expression ();
- case LPRN:
- switch (PEEK_TOKEN1())
- {
- case IF:
- case CASE:
- if (pass == 1)
- pedwarn ("conditional expression not allowed inside parentheses");
- goto skip_lprn;
- case LPC:
- if (pass == 1)
- pedwarn ("mode-less tuple not allowed inside parentheses");
- skip_lprn:
- FORWARD_TOKEN ();
- val = parse_untyped_expr ();
- expect (RPRN, "missing ')'");
- return val;
- default: ;
- /* fall through */
- }
- default:
- return parse_operand0 ();
- }
-}
-
-/* Matches: <index mode> */
-
-static tree
-parse_index_mode ()
-{
- /* This is another one that is nasty to parse!
- Let's feel our way ahead ... */
- tree lower, upper;
- if (PEEK_TOKEN () == NAME)
- {
- tree name = parse_name ();
- switch (PEEK_TOKEN ())
- {
- case COMMA:
- case RPRN:
- case SC: /* An error */
- /* This can only (legally) be a discrete mode name. */
- return name;
- case LPRN:
- /* This could be named discrete range,
- a cast, or some other expression (maybe). */
- require (LPRN);
- lower = parse_expression ();
- if (check_token (COLON))
- {
- upper = parse_expression ();
- expect (RPRN, "missing ')'");
- /* Matched: <mode_name> '(' <expr> ':' <expr> ')' */
- if (ignoring)
- return NULL_TREE;
- else
- return build_chill_range_type (name, lower, upper);
- }
- /* Looks like a cast or procedure call or something.
- Backup, and try again. */
- pushback_token (EXPR, lower);
- pushback_token (LPRN, NULL_TREE);
- lower = parse_call (name);
- goto parse_literal_range_colon;
- default:
- /* This has to be the start of an expression. */
- pushback_token (EXPR, name);
- goto parse_literal_range;
- }
- }
- /* It's not a name. But it could still be a discrete mode. */
- lower = parse_opt_mode ();
- if (lower)
- return lower;
- parse_literal_range:
- /* Nope, it's a discrete literal range. */
- lower = parse_expression ();
- parse_literal_range_colon:
- expect (COLON, "expected ':' here");
-
- upper = parse_expression ();
- return ignoring ? NULL_TREE
- : build_chill_range_type (NULL_TREE, lower, upper);
-}
-
-static tree
-parse_set_mode ()
-{
- int set_name_cnt = 0; /* count of named set elements */
- int set_is_numbered = 0; /* TRUE if set elements have explicit values */
- int set_is_not_numbered = 0;
- tree list = NULL_TREE;
- tree mode = ignoring ? void_type_node : start_enum (NULL_TREE);
- require (SET);
- expect (LPRN, "missing left parenthesis after SET");
- for (;;)
- {
- tree name, value = NULL_TREE;
- if (check_token (MUL))
- name = NULL_TREE;
- else
- {
- name = parse_defining_occurrence ();
- if (check_token (EQL))
- {
- value = parse_expression ();
- set_is_numbered = 1;
- }
- else
- set_is_not_numbered = 1;
- set_name_cnt++;
- }
- name = build_enumerator (name, value);
- if (pass == 1)
- list = chainon (name, list);
- if (! check_token (COMMA))
- break;
- }
- expect (RPRN, "missing right parenthesis after SET");
- if (!ignoring)
- {
- if (set_is_numbered && set_is_not_numbered)
- /* Z.200 doesn't allow mixed numbered and unnumbered set elements,
- but we can do it. Print a warning */
- pedwarn ("mixed numbered and unnumbered set elements is not standard");
- mode = finish_enum (mode, list);
- if (set_name_cnt == 0)
- error ("SET mode must define at least one named value");
- CH_ENUM_IS_NUMBERED(mode) = set_is_numbered ? 1 : 0;
- }
- return mode;
-}
-
-/* parse layout POS:
- returns a tree with following layout
-
- treelist
- pupose=treelist value=NULL_TREE (to indicate POS)
- pupose=word value=treelist | NULL_TREE
- pupose=startbit value=treelist | NULL_TREE
- purpose= value=
- integer_zero | integer_one length | endbit
-*/
-static tree
-parse_pos ()
-{
- tree word;
- tree startbit = NULL_TREE, endbit = NULL_TREE;
- tree what = NULL_TREE;
-
- require (LPRN);
- word = parse_untyped_expr ();
- if (check_token (COMMA))
- {
- startbit = parse_untyped_expr ();
- if (check_token (COMMA))
- {
- what = integer_zero_node;
- endbit = parse_untyped_expr ();
- }
- else if (check_token (COLON))
- {
- what = integer_one_node;
- endbit = parse_untyped_expr ();
- }
- }
- require (RPRN);
-
- /* build the tree as described above */
- if (what != NULL_TREE)
- what = tree_cons (what, endbit, NULL_TREE);
- if (startbit != NULL_TREE)
- startbit = tree_cons (startbit, what, NULL_TREE);
- endbit = tree_cons (word, startbit, NULL_TREE);
- return tree_cons (endbit, NULL_TREE, NULL_TREE);
-}
-
-/* parse layout STEP
- returns a tree with the following layout
-
- treelist
- pupose=NULL_TREE value=treelist (to indicate STEP)
- pupose=POS(see baove) value=stepsize | NULL_TREE
-*/
-static tree
-parse_step ()
-{
- tree pos;
- tree stepsize = NULL_TREE;
-
- require (LPRN);
- require (POS);
- pos = parse_pos ();
- if (check_token (COMMA))
- stepsize = parse_untyped_expr ();
- require (RPRN);
- TREE_VALUE (pos) = stepsize;
- return tree_cons (NULL_TREE, pos, NULL_TREE);
-}
-
-/* returns layout for fields or array elements.
- NULL_TREE no layout specified
- integer_one_node PACK specified
- integer_zero_node NOPACK specified
- tree_list PURPOSE POS
- tree_list VALUE STEP
-*/
-static tree
-parse_opt_layout (in)
- int in; /* 0 ... parse structure, 1 ... parse array */
-{
- tree val = NULL_TREE;
-
- if (check_token (PACK))
- {
- return integer_one_node;
- }
- else if (check_token (NOPACK))
- {
- return integer_zero_node;
- }
- else if (check_token (POS))
- {
- val = parse_pos ();
- if (in == 1 && pass == 1)
- {
- error ("POS not allowed for ARRAY");
- val = NULL_TREE;
- }
- return val;
- }
- else if (check_token (STEP))
- {
- val = parse_step ();
- if (in == 0 && pass == 1)
- {
- error ("STEP not allowed in field definition");
- val = NULL_TREE;
- }
- return val;
- }
- else
- return NULL_TREE;
-}
-
-static tree
-parse_field_name_list ()
-{
- tree chain = NULL_TREE;
- tree name = parse_defining_occurrence ();
- if (name == NULL_TREE)
- {
- error("missing field name");
- return NULL_TREE;
- }
- chain = build_tree_list (NULL_TREE, name);
- while (check_token (COMMA))
- {
- name = parse_defining_occurrence ();
- if (name == NULL)
- {
- error ("bad field name following ','");
- break;
- }
- if (! ignoring)
- chain = tree_cons (NULL_TREE, name, chain);
- }
- return chain;
-}
-
-/* Matches: <fixed field> or <variant field>, i.e.:
- <field name defining occurrence list> <mode> [ <field layout> ].
- Returns: A chain of FIELD_DECLs.
- NULL_TREE is returned if ignoring is true or an error is seen. */
-
-static tree
-parse_fixed_field ()
-{
- tree field_names = parse_field_name_list ();
- tree mode = parse_mode ();
- tree layout = parse_opt_layout (0);
- return ignoring ? NULL_TREE
- : grok_chill_fixedfields (field_names, mode, layout);
-}
-
-
-/* Matches: [ <variant field> { "," <variant field> }* ]
- Returns: A chain of FIELD_DECLs.
- NULL_TREE is returned if ignoring is true or an error is seen. */
-
-static tree
-parse_variant_field_list ()
-{
- tree fields = NULL_TREE;
- if (PEEK_TOKEN () != NAME)
- return NULL_TREE;
- for (;;)
- {
- fields = chainon (fields, parse_fixed_field ());
- if (PEEK_TOKEN () != COMMA || PEEK_TOKEN1 () != NAME)
- break;
- require (COMMA);
- }
- return fields;
-}
-
-/* Matches: <variant alternative>
- Returns a TREE_LIST node, whose TREE_PURPOSE (if non-NULL) is the label,
- and whose TREE_VALUE is the list of FIELD_DECLs. */
-
-static tree
-parse_variant_alternative ()
-{
- tree labels;
-
- if (PEEK_TOKEN () == LPRN)
- labels = parse_case_label_specification (NULL_TREE);
- else
- labels = NULL_TREE;
- if (! check_token (COLON))
- {
- error ("expected ':' in structure variant alternative");
- return NULL_TREE;
- }
-
- /* We now read a list a variant fields, until we come to the end
- of the variant alternative. But since both variant fields
- *and* variant alternatives are separated by COMMAs,
- we will have to look ahead to distinguish the start of a variant
- field from the start of a new variant alternative.
- We use the fact that a variant alternative must start with
- either a LPRN or a COLON, while a variant field must start with a NAME.
- This look-ahead is handled by parse_simple_fields. */
- return build_tree_list (labels, parse_variant_field_list ());
-}
-
-/* Parse <field> (which is <fixed field> or <alternative field>).
- Returns: A chain of FIELD_DECLs (or NULL_TREE on error or if ignoring). */
-
-static tree
-parse_field ()
-{
- if (check_token (CASE))
- {
- tree tag_list = NULL_TREE, variants, opt_variant_else;
- if (PEEK_TOKEN () == NAME)
- {
- tag_list = nreverse (parse_field_name_list ());
- if (pass == 1)
- tag_list = lookup_tag_fields (tag_list, current_fieldlist);
- }
- expect (OF, "missing 'OF' in alternative structure field");
-
- variants = parse_variant_alternative ();
- while (check_token (COMMA))
- variants = chainon (parse_variant_alternative (), variants);
- variants = nreverse (variants);
-
- if (check_token (ELSE))
- opt_variant_else = parse_variant_field_list ();
- else
- opt_variant_else = NULL_TREE;
- expect (ESAC, "missing 'ESAC' following alternative structure field");
- if (ignoring)
- return NULL_TREE;
- return grok_chill_variantdefs (tag_list, variants, opt_variant_else);
- }
- else if (PEEK_TOKEN () == NAME)
- return parse_fixed_field ();
- else
- {
- if (pass == 1)
- error ("missing field");
- return NULL_TREE;
- }
-}
-
-static tree
-parse_structure_mode ()
-{
- tree save_fieldlist = current_fieldlist;
- tree fields;
- require (STRUCT);
- expect (LPRN, "expected '(' after STRUCT");
- current_fieldlist = fields = parse_field ();
- while (check_token (COMMA))
- fields = chainon (fields, parse_field ());
- expect (RPRN, "expected ')' after STRUCT");
- current_fieldlist = save_fieldlist;
- return ignoring ? void_type_node : build_chill_struct_type (fields);
-}
-
-static tree
-parse_opt_queue_size ()
-{
- if (check_token (LPRN))
- {
- tree size = parse_expression ();
- expect (RPRN, "missing ')'");
- return size;
- }
- else
- return NULL_TREE;
-}
-
-static tree
-parse_procedure_mode ()
-{
- tree param_types = NULL_TREE, result_spec, except_list, recursive;
- require (PROC);
- expect (LPRN, "missing '(' after PROC");
- if (! check_token (RPRN))
- {
- for (;;)
- {
- tree pmode = parse_mode ();
- tree paramattr = parse_param_attr ();
- if (! ignoring)
- {
- pmode = get_type_of (pmode);
- param_types = tree_cons (paramattr, pmode, param_types);
- }
- if (! check_token (COMMA))
- break;
- }
- expect (RPRN, "missing ')' after PROC");
- }
- result_spec = parse_opt_result_spec ();
- except_list = parse_opt_except ();
- recursive = parse_opt_recursive ();
- if (ignoring)
- return void_type_node;
- return build_chill_pointer_type (build_chill_function_type
- (result_spec, nreverse (param_types),
- except_list, recursive));
-}
-
-/* Matches: <mode>
- A NAME will be assumed to be a <mode name>, and thus a <mode>.
- Returns NULL_TREE if no mode is seen.
- (If ignoring is true, the return value may be an arbitrary tree node,
- but will be non-NULL if something that could be a mode is seen.) */
-
-static tree
-parse_opt_mode ()
-{
- switch (PEEK_TOKEN ())
- {
- case ACCESS:
- {
- tree index_mode, record_mode;
- int dynamic = 0;
- require (ACCESS);
- if (check_token (LPRN))
- {
- index_mode = parse_index_mode ();
- expect (RPRN, "mssing ')'");
- }
- else
- index_mode = NULL_TREE;
- record_mode = parse_opt_mode ();
- if (record_mode)
- dynamic = check_token (DYNAMIC);
- return ignoring ? void_type_node
- : build_access_mode (index_mode, record_mode, dynamic);
- }
- case ARRAY:
- {
- tree index_list = NULL_TREE, base_mode;
- int varying;
- int num_index_modes = 0;
- int i;
- tree layouts = NULL_TREE;
- FORWARD_TOKEN ();
- expect (LPRN, "missing '(' after ARRAY");
- for (;;)
- {
- tree index = parse_index_mode ();
- num_index_modes++;
- if (!ignoring)
- index_list = tree_cons (NULL_TREE, index, index_list);
- if (! check_token (COMMA))
- break;
- }
- expect (RPRN, "missing ')' after ARRAY");
- varying = check_token (VARYING);
- base_mode = parse_mode ();
- /* Allow a layout specification for each index mode */
- for (i = 0; i < num_index_modes; ++i)
- {
- tree new_layout = parse_opt_layout (1);
- if (new_layout == NULL_TREE)
- break;
- if (!ignoring)
- layouts = tree_cons (NULL_TREE, new_layout, layouts);
- }
- if (ignoring)
- return base_mode;
- return build_chill_array_type (get_type_of (base_mode),
- index_list, varying, layouts);
- }
- case ASSOCIATION:
- require (ASSOCIATION);
- return association_type_node;
- case BIN:
- { tree length;
- FORWARD_TOKEN();
- expect (LPRN, "missing left parenthesis after BIN");
- length = parse_expression ();
- expect (RPRN, "missing right parenthesis after BIN");
- return ignoring ? void_type_node : build_chill_bin_type (length);
- }
- case BOOLS:
- {
- tree length;
- FORWARD_TOKEN ();
- expect (LPRN, "missing '(' after BOOLS");
- length = parse_expression ();
- expect (RPRN, "missing ')' after BOOLS");
- if (check_token (VARYING))
- error ("VARYING bit-strings not implemented");
- return ignoring ? void_type_node : build_bitstring_type (length);
- }
- case BUFFER:
- {
- tree qsize, element_mode;
- require (BUFFER);
- qsize = parse_opt_queue_size ();
- element_mode = parse_mode ();
- return ignoring ? element_mode
- : build_buffer_type (element_mode, qsize);
- }
- case CHARS:
- {
- tree length;
- int varying;
- tree type;
- FORWARD_TOKEN ();
- expect (LPRN, "missing '(' after CHARS");
- length = parse_expression ();
- expect (RPRN, "missing ')' after CHARS");
- varying = check_token (VARYING);
- if (ignoring)
- return void_type_node;
- type = build_string_type (char_type_node, length);
- if (varying)
- type = build_varying_struct (type);
- return type;
- }
- case EVENT:
- {
- tree qsize;
- require (EVENT);
- qsize = parse_opt_queue_size ();
- return ignoring ? void_type_node : build_event_type (qsize);
- }
- case NAME:
- {
- tree mode = get_type_of (parse_name ());
- if (check_token (LPRN))
- {
- tree min_value = parse_expression ();
- if (check_token (COLON))
- {
- tree max_value = parse_expression ();
- expect (RPRN, "syntax error - expected ')'");
- /* Matched: <mode_name> '(' <expr> ':' <expr> ')' */
- if (ignoring)
- return mode;
- else
- return build_chill_range_type (mode, min_value, max_value);
- }
- if (check_token (RPRN))
- {
- int varying = check_token (VARYING);
- if (! ignoring)
- {
- if (mode == char_type_node || varying)
- {
- if (mode != char_type_node
- && mode != ridpointers[(int) RID_CHAR])
- error ("strings must be composed of chars");
- mode = build_string_type (char_type_node, min_value);
- if (varying)
- mode = build_varying_struct (mode);
- }
- else
- {
- /* Parameterized mode,
- or old-fashioned CHAR(N) string declaration.. */
- tree pmode = make_node (LANG_TYPE);
- TREE_TYPE (pmode) = mode;
- TYPE_DOMAIN (pmode) = min_value;
- mode = pmode;
- }
- }
- }
- }
- return mode;
- }
- case POWERSET:
- { tree mode;
- FORWARD_TOKEN ();
- mode = parse_mode ();
- if (ignoring || TREE_CODE (mode) == ERROR_MARK)
- return mode;
- return build_powerset_type (get_type_of (mode));
- }
- case PROC:
- return parse_procedure_mode ();
- case RANGE:
- { tree low, high;
- FORWARD_TOKEN();
- expect (LPRN, "missing left parenthesis after RANGE");
- low = parse_expression ();
- expect (COLON, "missing colon");
- high = parse_expression ();
- expect (RPRN, "missing right parenthesis after RANGE");
- return ignoring ? void_type_node
- : build_chill_range_type (NULL_TREE, low, high);
- }
- case READ:
- FORWARD_TOKEN ();
- {
- tree mode2 = get_type_of (parse_mode ());
- if (ignoring || TREE_CODE (mode2) == ERROR_MARK)
- return mode2;
- if (mode2
- && TREE_CODE_CLASS (TREE_CODE (mode2)) == 'd'
- && CH_IS_BUFFER_MODE (mode2))
- {
- error ("BUFFER modes may not be readonly");
- return mode2;
- }
- if (mode2
- && TREE_CODE_CLASS (TREE_CODE (mode2)) == 'd'
- && CH_IS_EVENT_MODE (mode2))
- {
- error ("EVENT modes may not be readonly");
- return mode2;
- }
- return build_readonly_type (mode2);
-
- }
- case REF:
- { tree mode;
- FORWARD_TOKEN ();
- mode = parse_mode ();
- if (ignoring)
- return mode;
- mode = get_type_of (mode);
- return (TREE_CODE (mode) == ERROR_MARK) ? mode
- : build_chill_pointer_type (mode);
- }
- case SET:
- return parse_set_mode ();
- case SIGNAL:
- if (pedantic)
- error ("SIGNAL is not a valid mode");
- return generic_signal_type_node;
- case STRUCT:
- return parse_structure_mode ();
- case TEXT:
- {
- tree length, index_mode;
- int dynamic;
- require (TEXT);
- expect (LPRN, "missing '('");
- length = parse_expression ();
- expect (RPRN, "missing ')'");
- /* FIXME: This should actually look for an optional index_mode,
- but that is tricky to do. */
- index_mode = parse_opt_mode ();
- dynamic = check_token (DYNAMIC);
- return ignoring ? void_type_node
- : build_text_mode (length, index_mode, dynamic);
- }
- case USAGE:
- require (USAGE);
- return usage_type_node;
- case WHERE:
- require (WHERE);
- return where_type_node;
- default:
- return NULL_TREE;
- }
-}
-
-static tree
-parse_mode ()
-{
- tree mode = parse_opt_mode ();
- if (mode == NULL_TREE)
- {
- if (pass == 1)
- error ("syntax error - missing mode");
- mode = error_mark_node;
- }
- return mode;
-}
-
-static void
-parse_program()
-{
- /* Initialize global variables for current pass. */
- int i;
- expand_exit_needed = 0;
- label = NULL_TREE; /* for statement labels */
- current_module = NULL;
- current_function_decl = NULL_TREE;
- in_pseudo_module = 0;
-
- for (i = 0; i <= MAX_LOOK_AHEAD; i++)
- terminal_buffer[i] = TOKEN_NOT_READ;
-
-#if 0
- /* skip some junk */
- while (PEEK_TOKEN() == HEADEREL)
- FORWARD_TOKEN();
-#endif
-
- start_outer_function ();
-
- for (;;)
- {
- tree label = parse_optlabel ();
- if (PEEK_TOKEN() == MODULE || PEEK_TOKEN() == REGION)
- parse_modulion (label);
- else if (PEEK_TOKEN() == SPEC)
- parse_spec_module (label);
- else break;
- }
-
- finish_outer_function ();
-}
-
-static void
-parse_pass_1_2()
-{
- parse_program();
- if (PEEK_TOKEN() != END_PASS_1)
- {
- error ("syntax error - expected a module or end of file");
- serious_errors++;
- }
- chill_finish_compile ();
- if (serious_errors)
- exit (FATAL_EXIT_CODE);
- switch_to_pass_2 ();
- ch_parse_init ();
- except_init_pass_2 ();
- ignoring = 0;
- parse_program();
- chill_finish_compile ();
-}
-
-int yyparse ()
-{
- parse_pass_1_2 ();
- return 0;
-}
-
-/*
- * We've had an error. Move the compiler's state back to
- * the global binding level. This prevents the loop in
- * compile_file in toplev.c from looping forever, since the
- * CHILL poplevel() has *no* effect on the value returned by
- * global_bindings_p().
- */
-void
-to_global_binding_level ()
-{
- while (! global_bindings_p ())
- current_function_decl = DECL_CONTEXT (current_function_decl);
- serious_errors++;
-}
-
-#if 1
-int yydebug;
-/* Sets the value of the 'yydebug' variable to VALUE.
- This is a function so we don't have to have YYDEBUG defined
- in order to build the compiler. */
-void
-set_yydebug (value)
- int value;
-{
-#if YYDEBUG != 0
- yydebug = value;
-#else
- warning ("YYDEBUG not defined.");
-#endif
-}
-#endif