OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [treelang/] [parse.y] - Diff between revs 154 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
/* -*- c -*- emacs mode c */
/* -*- c -*- emacs mode c */
/* TREELANG Compiler parser.
/* TREELANG Compiler parser.
---------------------------------------------------------------------
---------------------------------------------------------------------
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
Free Software Foundation, Inc.
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
Free Software Foundation; either version 3, or (at your option) any
later version.
later version.
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
along with this program; see the file COPYING3.  If not see
.
.
In other words, you are welcome to use, share and improve this program.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
You are forbidden to forbid anyone else to use, share and improve
what you give them.   Help stamp out software-hoarding!
what you give them.   Help stamp out software-hoarding!
---------------------------------------------------------------------
---------------------------------------------------------------------
Written by Tim Josling 1999-2001, based in part on other parts of
Written by Tim Josling 1999-2001, based in part on other parts of
the GCC compiler.  */
the GCC compiler.  */
/* Grammar Conflicts
/* Grammar Conflicts
   *****************
   *****************
   There are no conflicts in this grammar.  Please keep it that way.  */
   There are no conflicts in this grammar.  Please keep it that way.  */
%{
%{
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "timevar.h"
#include "timevar.h"
#include "tree.h"
#include "tree.h"
#include "treelang.h"
#include "treelang.h"
#include "treetree.h"
#include "treetree.h"
#include "toplev.h"
#include "toplev.h"
#define YYDEBUG 1
#define YYDEBUG 1
#define YYPRINT(file, type, value) print_token (file, type, value)
#define YYPRINT(file, type, value) print_token (file, type, value)
#define YYERROR_VERBOSE YES
#define YYERROR_VERBOSE YES
  /* My yylex routine used to intercept calls to flex generated code, to
  /* My yylex routine used to intercept calls to flex generated code, to
     record lex time.  */
     record lex time.  */
  int yylex (void);
  int yylex (void);
  static inline int my_yylex (void);
  static inline int my_yylex (void);
  /* Call lex, but ensure time is charged to TV_LEX.  */
  /* Call lex, but ensure time is charged to TV_LEX.  */
  static inline int
  static inline int
    my_yylex (void)
    my_yylex (void)
    {
    {
      int res;
      int res;
      timevar_push (TV_LEX);
      timevar_push (TV_LEX);
      res = yylex ();
      res = yylex ();
      timevar_pop (TV_LEX);
      timevar_pop (TV_LEX);
      return res;
      return res;
    }
    }
#define yylex my_yylex
#define yylex my_yylex
  extern int option_parser_trace;
  extern int option_parser_trace;
  /* Local prototypes.  */
  /* Local prototypes.  */
  static void yyerror (const char *error_message);
  static void yyerror (const char *error_message);
  int yyparse (void);
  int yyparse (void);
  void print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED,
  void print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED,
                    YYSTYPE value);
                    YYSTYPE value);
  static struct prod_token_parm_item *reverse_prod_list
  static struct prod_token_parm_item *reverse_prod_list
    (struct prod_token_parm_item *old_first);
    (struct prod_token_parm_item *old_first);
  static void ensure_not_void (unsigned int type,
  static void ensure_not_void (unsigned int type,
                               struct prod_token_parm_item *name);
                               struct prod_token_parm_item *name);
  static int check_type_match (int type_num, struct prod_token_parm_item *exp);
  static int check_type_match (int type_num, struct prod_token_parm_item *exp);
  static int get_common_type (struct prod_token_parm_item *type1,
  static int get_common_type (struct prod_token_parm_item *type1,
                              struct prod_token_parm_item *type2);
                              struct prod_token_parm_item *type2);
  static struct prod_token_parm_item *make_integer_constant
  static struct prod_token_parm_item *make_integer_constant
    (struct prod_token_parm_item *value);
    (struct prod_token_parm_item *value);
  static struct prod_token_parm_item *make_plus_expression
  static struct prod_token_parm_item *make_plus_expression
    (struct prod_token_parm_item *tok, struct prod_token_parm_item *op1,
    (struct prod_token_parm_item *tok, struct prod_token_parm_item *op1,
     struct prod_token_parm_item *op2, int type_code, int prod_code);
     struct prod_token_parm_item *op2, int type_code, int prod_code);
  static void set_storage (struct prod_token_parm_item *prod);
  static void set_storage (struct prod_token_parm_item *prod);
  /* File global variables.  */
  /* File global variables.  */
  static struct prod_token_parm_item *current_function = NULL;
  static struct prod_token_parm_item *current_function = NULL;
%}
%}
/* Not %raw - seems to have bugs.  */
/* Not %raw - seems to have bugs.  */
%token_table
%token_table
/* Punctuation.  */
/* Punctuation.  */
%token RIGHT_BRACE
%token RIGHT_BRACE
%token LEFT_BRACE
%token LEFT_BRACE
%token RIGHT_SQUARE_BRACKET
%token RIGHT_SQUARE_BRACKET
%token LEFT_SQUARE_BRACKET
%token LEFT_SQUARE_BRACKET
%token RIGHT_PARENTHESIS
%token RIGHT_PARENTHESIS
%token LEFT_PARENTHESIS
%token LEFT_PARENTHESIS
%token SEMICOLON
%token SEMICOLON
%token ASTERISK
%token ASTERISK
%token COMMA
%token COMMA
%right EQUALS
%right EQUALS
%right ASSIGN
%right ASSIGN
%left  tl_PLUS
%left  tl_PLUS
%left  tl_MINUS
%left  tl_MINUS
/* Literals.  */
/* Literals.  */
%token INTEGER
%token INTEGER
/* Keywords.  */
/* Keywords.  */
%token IF
%token IF
%token ELSE
%token ELSE
%token tl_RETURN
%token tl_RETURN
%token CHAR
%token CHAR
%token INT
%token INT
%token UNSIGNED
%token UNSIGNED
%token VOID
%token VOID
%token TYPEDEF
%token TYPEDEF
%token NAME
%token NAME
%token STATIC
%token STATIC
%token AUTOMATIC
%token AUTOMATIC
%token EXTERNAL_DEFINITION
%token EXTERNAL_DEFINITION
%token EXTERNAL_REFERENCE
%token EXTERNAL_REFERENCE
/* Tokens not passed to parser.  */
/* Tokens not passed to parser.  */
%token WHITESPACE
%token WHITESPACE
%token COMMENT
%token COMMENT
/* Pseudo tokens - productions.  */
/* Pseudo tokens - productions.  */
%token PROD_VARIABLE_NAME
%token PROD_VARIABLE_NAME
%token PROD_TYPE_NAME
%token PROD_TYPE_NAME
%token PROD_FUNCTION_NAME
%token PROD_FUNCTION_NAME
%token PROD_INTEGER_CONSTANT
%token PROD_INTEGER_CONSTANT
%token PROD_PLUS_EXPRESSION
%token PROD_PLUS_EXPRESSION
%token PROD_MINUS_EXPRESSION
%token PROD_MINUS_EXPRESSION
%token PROD_ASSIGN_EXPRESSION
%token PROD_ASSIGN_EXPRESSION
%token PROD_VARIABLE_REFERENCE_EXPRESSION
%token PROD_VARIABLE_REFERENCE_EXPRESSION
%token PROD_PARAMETER
%token PROD_PARAMETER
%token PROD_FUNCTION_INVOCATION
%token PROD_FUNCTION_INVOCATION
%expect 0
%expect 0
%%
%%
file:
file:
/* Nil.  */ {
/* Nil.  */ {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|declarations {
|declarations {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
declarations:
declarations:
declaration {
declaration {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
| declarations declaration {
| declarations declaration {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
declaration:
declaration:
variable_def {
variable_def {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|function_prototype {
|function_prototype {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|function {
|function {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
variable_def:
variable_def:
storage typename NAME init_opt SEMICOLON {
storage typename NAME init_opt SEMICOLON {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $3;
  tok = $3;
  prod = make_production (PROD_VARIABLE_NAME, tok);
  prod = make_production (PROD_VARIABLE_NAME, tok);
  SYMBOL_TABLE_NAME (prod) = tok;
  SYMBOL_TABLE_NAME (prod) = tok;
  EXPRESSION_TYPE (prod) = $2;
  EXPRESSION_TYPE (prod) = $2;
  VAR_INIT (prod) = $4;
  VAR_INIT (prod) = $4;
  NUMERIC_TYPE (prod) =
  NUMERIC_TYPE (prod) =
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
  ensure_not_void (NUMERIC_TYPE (prod), tok);
  ensure_not_void (NUMERIC_TYPE (prod), tok);
  if (insert_tree_name (prod))
  if (insert_tree_name (prod))
    {
    {
      YYERROR;
      YYERROR;
    }
    }
  STORAGE_CLASS_TOKEN (prod) = $1;
  STORAGE_CLASS_TOKEN (prod) = $1;
  set_storage (prod);
  set_storage (prod);
  if (VAR_INIT (prod))
  if (VAR_INIT (prod))
    {
    {
      gcc_assert (((struct prod_token_parm_item *)
      gcc_assert (((struct prod_token_parm_item *)
                   VAR_INIT (prod))->tp.pro.code);
                   VAR_INIT (prod))->tp.pro.code);
      if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
      if (STORAGE_CLASS (prod) == EXTERNAL_REFERENCE_STORAGE)
        {
        {
          error("%Hexternal reference variable %q.*s has an initial value",
          error("%Hexternal reference variable %q.*s has an initial value",
                &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
                &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
          YYERROR;
          YYERROR;
          VAR_INIT (prod) = NULL;
          VAR_INIT (prod) = NULL;
        }
        }
    }
    }
  prod->tp.pro.code = tree_code_create_variable
  prod->tp.pro.code = tree_code_create_variable
    (STORAGE_CLASS (prod),
    (STORAGE_CLASS (prod),
     ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
     ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
     ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
     ((struct prod_token_parm_item *)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
     NUMERIC_TYPE (prod),
     NUMERIC_TYPE (prod),
     VAR_INIT (prod) ?
     VAR_INIT (prod) ?
     ((struct prod_token_parm_item *)VAR_INIT (prod))->tp.pro.code : NULL,
     ((struct prod_token_parm_item *)VAR_INIT (prod))->tp.pro.code : NULL,
     tok->tp.tok.location);
     tok->tp.tok.location);
  gcc_assert (prod->tp.pro.code);
  gcc_assert (prod->tp.pro.code);
}
}
;
;
storage:
storage:
STATIC
STATIC
|AUTOMATIC
|AUTOMATIC
|EXTERNAL_DEFINITION
|EXTERNAL_DEFINITION
|EXTERNAL_REFERENCE
|EXTERNAL_REFERENCE
;
;
parameter:
parameter:
typename NAME {
typename NAME {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod2;
  struct prod_token_parm_item *prod2;
  tok = $2;
  tok = $2;
  prod = make_production (PROD_VARIABLE_NAME, tok);
  prod = make_production (PROD_VARIABLE_NAME, tok);
  SYMBOL_TABLE_NAME (prod) = $2;
  SYMBOL_TABLE_NAME (prod) = $2;
  EXPRESSION_TYPE (prod) = $1;
  EXPRESSION_TYPE (prod) = $1;
  NUMERIC_TYPE (prod) =
  NUMERIC_TYPE (prod) =
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
  ensure_not_void (NUMERIC_TYPE (prod), tok);
  ensure_not_void (NUMERIC_TYPE (prod), tok);
  if (insert_tree_name (prod))
  if (insert_tree_name (prod))
    {
    {
      YYERROR;
      YYERROR;
    }
    }
  prod2 = make_production (PROD_PARAMETER, tok);
  prod2 = make_production (PROD_PARAMETER, tok);
  VARIABLE (prod2) = prod;
  VARIABLE (prod2) = prod;
  $$ = prod2;
  $$ = prod2;
}
}
;
;
function_prototype:
function_prototype:
storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLON {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *type;
  struct prod_token_parm_item *type;
  struct prod_token_parm_item *first_parms;
  struct prod_token_parm_item *first_parms;
  struct prod_token_parm_item *last_parms;
  struct prod_token_parm_item *last_parms;
  struct prod_token_parm_item *this_parms;
  struct prod_token_parm_item *this_parms;
  struct prod_token_parm_item *this_parm;
  struct prod_token_parm_item *this_parm;
  struct prod_token_parm_item *this_parm_var;
  struct prod_token_parm_item *this_parm_var;
  tok = $3;
  tok = $3;
  prod = make_production (PROD_FUNCTION_NAME, $3);
  prod = make_production (PROD_FUNCTION_NAME, $3);
  SYMBOL_TABLE_NAME (prod) = $3;
  SYMBOL_TABLE_NAME (prod) = $3;
  EXPRESSION_TYPE (prod) = $2;
  EXPRESSION_TYPE (prod) = $2;
  NUMERIC_TYPE (prod) =
  NUMERIC_TYPE (prod) =
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
    NUMERIC_TYPE (( (struct prod_token_parm_item *)EXPRESSION_TYPE (prod)));
  PARAMETERS (prod) = reverse_prod_list ($5);
  PARAMETERS (prod) = reverse_prod_list ($5);
  insert_tree_name (prod);
  insert_tree_name (prod);
  STORAGE_CLASS_TOKEN (prod) = $1;
  STORAGE_CLASS_TOKEN (prod) = $1;
  set_storage (prod);
  set_storage (prod);
  switch (STORAGE_CLASS (prod))
  switch (STORAGE_CLASS (prod))
    {
    {
    case STATIC_STORAGE:
    case STATIC_STORAGE:
    case EXTERNAL_DEFINITION_STORAGE:
    case EXTERNAL_DEFINITION_STORAGE:
    case EXTERNAL_REFERENCE_STORAGE:
    case EXTERNAL_REFERENCE_STORAGE:
      break;
      break;
    case AUTOMATIC_STORAGE:
    case AUTOMATIC_STORAGE:
      error ("%Hfunction %q.*s cannot be automatic",
      error ("%Hfunction %q.*s cannot be automatic",
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
      YYERROR;
      YYERROR;
      break;
      break;
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
  type = EXPRESSION_TYPE (prod);
  type = EXPRESSION_TYPE (prod);
  /* Create a parameter list in a non-front end specific format.  */
  /* Create a parameter list in a non-front end specific format.  */
  for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
  for (first_parms = NULL, last_parms = NULL, this_parm = PARAMETERS (prod);
       this_parm;
       this_parm;
       this_parm = this_parm->tp.pro.next)
       this_parm = this_parm->tp.pro.next)
    {
    {
      gcc_assert (this_parm->category == production_category);
      gcc_assert (this_parm->category == production_category);
      this_parm_var = VARIABLE (this_parm);
      this_parm_var = VARIABLE (this_parm);
      gcc_assert (this_parm_var);
      gcc_assert (this_parm_var);
      gcc_assert (this_parm_var->category == production_category);
      gcc_assert (this_parm_var->category == production_category);
      gcc_assert (this_parm_var->tp.pro.main_token);
      gcc_assert (this_parm_var->tp.pro.main_token);
      this_parms = my_malloc (sizeof (struct prod_token_parm_item));
      this_parms = my_malloc (sizeof (struct prod_token_parm_item));
      this_parms->tp.par.variable_name =
      this_parms->tp.par.variable_name =
        this_parm_var->tp.pro.main_token->tp.tok.chars;
        this_parm_var->tp.pro.main_token->tp.tok.chars;
      this_parms->category = parameter_category;
      this_parms->category = parameter_category;
      this_parms->type = NUMERIC_TYPE
      this_parms->type = NUMERIC_TYPE
        (( (struct prod_token_parm_item *)EXPRESSION_TYPE (this_parm_var)));
        (( (struct prod_token_parm_item *)EXPRESSION_TYPE (this_parm_var)));
      if (last_parms)
      if (last_parms)
        {
        {
          last_parms->tp.par.next = this_parms;
          last_parms->tp.par.next = this_parms;
          last_parms = this_parms;
          last_parms = this_parms;
        }
        }
      else
      else
        {
        {
          first_parms = this_parms;
          first_parms = this_parms;
          last_parms = this_parms;
          last_parms = this_parms;
        }
        }
      this_parms->tp.par.where_to_put_var_tree =
      this_parms->tp.par.where_to_put_var_tree =
        & (((struct prod_token_parm_item *)VARIABLE (this_parm))->tp.pro.code);
        & (((struct prod_token_parm_item *)VARIABLE (this_parm))->tp.pro.code);
    }
    }
  FIRST_PARMS (prod) = first_parms;
  FIRST_PARMS (prod) = first_parms;
  prod->tp.pro.code =
  prod->tp.pro.code =
    tree_code_create_function_prototype (tok->tp.tok.chars,
    tree_code_create_function_prototype (tok->tp.tok.chars,
                                         STORAGE_CLASS (prod),
                                         STORAGE_CLASS (prod),
                                         NUMERIC_TYPE (type),
                                         NUMERIC_TYPE (type),
                                         first_parms, tok->tp.tok.location);
                                         first_parms, tok->tp.tok.location);
#ifdef ENABLE_CHECKING
#ifdef ENABLE_CHECKING
  /* Check all the parameters have code.  */
  /* Check all the parameters have code.  */
  for (this_parm = PARAMETERS (prod);
  for (this_parm = PARAMETERS (prod);
       this_parm;
       this_parm;
       this_parm = this_parm->tp.pro.next)
       this_parm = this_parm->tp.pro.next)
    {
    {
      gcc_assert ((struct prod_token_parm_item *)VARIABLE (this_parm));
      gcc_assert ((struct prod_token_parm_item *)VARIABLE (this_parm));
      gcc_assert (((struct prod_token_parm_item *)
      gcc_assert (((struct prod_token_parm_item *)
                   VARIABLE (this_parm))->tp.pro.code);
                   VARIABLE (this_parm))->tp.pro.code);
    }
    }
#endif
#endif
}
}
;
;
function:
function:
NAME LEFT_BRACE {
NAME LEFT_BRACE {
  struct prod_token_parm_item *proto;
  struct prod_token_parm_item *proto;
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tok = $1;
  tok = $1;
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  search_prod.category = token_category;
  search_prod.category = token_category;
  current_function = proto = lookup_tree_name (&search_prod);
  current_function = proto = lookup_tree_name (&search_prod);
  if (!proto)
  if (!proto)
    {
    {
      error ("%Hno prototype found for %q.*s", &tok->tp.tok.location,
      error ("%Hno prototype found for %q.*s", &tok->tp.tok.location,
             tok->tp.tok.length, tok->tp.tok.chars);
             tok->tp.tok.length, tok->tp.tok.chars);
      YYERROR;
      YYERROR;
    }
    }
  gcc_assert (proto->tp.pro.code);
  gcc_assert (proto->tp.pro.code);
  tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
  tree_code_create_function_initial (proto->tp.pro.code, tok->tp.tok.location);
}
}
variable_defs_opt statements_opt RIGHT_BRACE {
variable_defs_opt statements_opt RIGHT_BRACE {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tok = $1;
  tok = $1;
  tree_code_create_function_wrapup (tok->tp.tok.location);
  tree_code_create_function_wrapup (tok->tp.tok.location);
  current_function = NULL;
  current_function = NULL;
}
}
;
;
variable_defs_opt:
variable_defs_opt:
/* Nil.  */ {
/* Nil.  */ {
  $$ = 0;
  $$ = 0;
}
}
|variable_defs {
|variable_defs {
  $$ = $1;
  $$ = $1;
}
}
;
;
statements_opt:
statements_opt:
/* Nil.  */ {
/* Nil.  */ {
  $$ = 0;
  $$ = 0;
}
}
|statements {
|statements {
  $$ = $1;
  $$ = $1;
}
}
;
;
variable_defs:
variable_defs:
variable_def {
variable_def {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|variable_defs variable_def {
|variable_defs variable_def {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
typename:
typename:
INT {
INT {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_TYPE_NAME, tok);
  prod = make_production (PROD_TYPE_NAME, tok);
  NUMERIC_TYPE (prod) = SIGNED_INT;
  NUMERIC_TYPE (prod) = SIGNED_INT;
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  $$ = prod;
  $$ = prod;
}
}
|UNSIGNED INT {
|UNSIGNED INT {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_TYPE_NAME, tok);
  prod = make_production (PROD_TYPE_NAME, tok);
  NUMERIC_TYPE (prod) = UNSIGNED_INT;
  NUMERIC_TYPE (prod) = UNSIGNED_INT;
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  $$ = prod;
  $$ = prod;
}
}
|CHAR {
|CHAR {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_TYPE_NAME, tok);
  prod = make_production (PROD_TYPE_NAME, tok);
  NUMERIC_TYPE (prod) = SIGNED_CHAR;
  NUMERIC_TYPE (prod) = SIGNED_CHAR;
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  $$ = prod;
  $$ = prod;
}
}
|UNSIGNED CHAR {
|UNSIGNED CHAR {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_TYPE_NAME, tok);
  prod = make_production (PROD_TYPE_NAME, tok);
  NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
  NUMERIC_TYPE (prod) = UNSIGNED_CHAR;
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  $$ = prod;
  $$ = prod;
}
}
|VOID {
|VOID {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_TYPE_NAME, tok);
  prod = make_production (PROD_TYPE_NAME, tok);
  NUMERIC_TYPE (prod) = VOID_TYPE;
  NUMERIC_TYPE (prod) = VOID_TYPE;
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_type (NUMERIC_TYPE (prod));
  $$ = prod;
  $$ = prod;
}
}
;
;
parameters_opt:
parameters_opt:
/* Nothing to do.  */ {
/* Nothing to do.  */ {
 $$ = 0;
 $$ = 0;
}
}
| parameters {
| parameters {
 $$ = $1;
 $$ = $1;
}
}
;
;
parameters:
parameters:
parameter {
parameter {
  /* Nothing to do.  */
  /* Nothing to do.  */
  $$ = $1;
  $$ = $1;
}
}
|parameters COMMA parameter {
|parameters COMMA parameter {
  struct prod_token_parm_item *prod1;
  struct prod_token_parm_item *prod1;
  prod1 = $3;
  prod1 = $3;
  prod1->tp.pro.next = $1; /* Insert in reverse order.  */
  prod1->tp.pro.next = $1; /* Insert in reverse order.  */
  $$ = prod1;
  $$ = prod1;
}
}
;
;
statements:
statements:
statement {
statement {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|statements statement {
|statements statement {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
statement:
statement:
expression SEMICOLON {
expression SEMICOLON {
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  exp = $1;
  exp = $1;
  tree_code_output_expression_statement (exp->tp.pro.code,
  tree_code_output_expression_statement (exp->tp.pro.code,
                                         exp->tp.pro.main_token->tp.tok.location);
                                         exp->tp.pro.main_token->tp.tok.location);
}
}
|return SEMICOLON {
|return SEMICOLON {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
|if_statement {
|if_statement {
  /* Nothing to do.  */
  /* Nothing to do.  */
}
}
;
;
if_statement:
if_statement:
IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
IF LEFT_PARENTHESIS expression RIGHT_PARENTHESIS {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  tok = $1;
  tok = $1;
  exp = $3;
  exp = $3;
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
  tree_code_if_start (exp->tp.pro.code, tok->tp.tok.location);
}
}
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
  /* Just let the statements flow.  */
  /* Just let the statements flow.  */
}
}
ELSE {
ELSE {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tok = $1;
  tok = $1;
  tree_code_if_else (tok->tp.tok.location);
  tree_code_if_else (tok->tp.tok.location);
}
}
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
LEFT_BRACE variable_defs_opt statements_opt RIGHT_BRACE {
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tok = $1;
  tok = $1;
  tree_code_if_end (tok->tp.tok.location);
  tree_code_if_end (tok->tp.tok.location);
}
}
;
;
return:
return:
tl_RETURN expression_opt {
tl_RETURN expression_opt {
  struct prod_token_parm_item *type_prod;
  struct prod_token_parm_item *type_prod;
  struct prod_token_parm_item *ret_tok = $1;
  struct prod_token_parm_item *ret_tok = $1;
  struct prod_token_parm_item *exp = $2;
  struct prod_token_parm_item *exp = $2;
  type_prod = EXPRESSION_TYPE (current_function);
  type_prod = EXPRESSION_TYPE (current_function);
  if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
  if (NUMERIC_TYPE (type_prod) == VOID_TYPE)
    if (exp == NULL)
    if (exp == NULL)
      tree_code_generate_return (type_prod->tp.pro.code, NULL);
      tree_code_generate_return (type_prod->tp.pro.code, NULL);
    else
    else
      {
      {
        warning (0, "%Hredundant expression in return",
        warning (0, "%Hredundant expression in return",
                 &ret_tok->tp.tok.location);
                 &ret_tok->tp.tok.location);
        tree_code_generate_return (type_prod->tp.pro.code, NULL);
        tree_code_generate_return (type_prod->tp.pro.code, NULL);
       }
       }
  else
  else
    if (exp == NULL)
    if (exp == NULL)
        error ("%Hexpression missing in return", &ret_tok->tp.tok.location);
        error ("%Hexpression missing in return", &ret_tok->tp.tok.location);
    else
    else
      {
      {
        /* Check same type.  */
        /* Check same type.  */
        if (check_type_match (NUMERIC_TYPE (type_prod), exp))
        if (check_type_match (NUMERIC_TYPE (type_prod), exp))
          {
          {
            gcc_assert (type_prod->tp.pro.code);
            gcc_assert (type_prod->tp.pro.code);
            gcc_assert (exp->tp.pro.code);
            gcc_assert (exp->tp.pro.code);
            /* Generate the code. */
            /* Generate the code. */
            tree_code_generate_return (type_prod->tp.pro.code,
            tree_code_generate_return (type_prod->tp.pro.code,
                                       exp->tp.pro.code);
                                       exp->tp.pro.code);
          }
          }
      }
      }
}
}
;
;
expression_opt:
expression_opt:
/* Nil.  */ {
/* Nil.  */ {
  $$ = 0;
  $$ = 0;
}
}
|expression {
|expression {
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  exp = $1;
  exp = $1;
  gcc_assert (exp->tp.pro.code);
  gcc_assert (exp->tp.pro.code);
  $$ = $1;
  $$ = $1;
}
}
;
;
expression:
expression:
INTEGER {
INTEGER {
  $$ = make_integer_constant ($1);
  $$ = make_integer_constant ($1);
}
}
|variable_ref {
|variable_ref {
  $$ = $1;
  $$ = $1;
}
}
|expression tl_PLUS expression {
|expression tl_PLUS expression {
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op2 = $3;
  struct prod_token_parm_item *op2 = $3;
  int type_code = get_common_type (op1, op2);
  int type_code = get_common_type (op1, op2);
  if (!type_code)
  if (!type_code)
    YYERROR;
    YYERROR;
  $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
  $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
}
}
|expression tl_MINUS expression %prec tl_PLUS {
|expression tl_MINUS expression %prec tl_PLUS {
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op2 = $3;
  struct prod_token_parm_item *op2 = $3;
  int type_code = get_common_type (op1, op2);
  int type_code = get_common_type (op1, op2);
  if (!type_code)
  if (!type_code)
    YYERROR;
    YYERROR;
  $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
  $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
}
}
|expression EQUALS expression {
|expression EQUALS expression {
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op2 = $3;
  struct prod_token_parm_item *op2 = $3;
  int type_code = NUMERIC_TYPE (op1);
  int type_code = NUMERIC_TYPE (op1);
  if (!type_code)
  if (!type_code)
    YYERROR;
    YYERROR;
  $$ = make_plus_expression
  $$ = make_plus_expression
     (tok, op1, op2, type_code, EXP_EQUALS);
     (tok, op1, op2, type_code, EXP_EQUALS);
}
}
|variable_ref ASSIGN expression {
|variable_ref ASSIGN expression {
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *tok = $2;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op1 = $1;
  struct prod_token_parm_item *op2 = $3;
  struct prod_token_parm_item *op2 = $3;
  int type_code = NUMERIC_TYPE (op1);
  int type_code = NUMERIC_TYPE (op1);
  if (!type_code)
  if (!type_code)
    YYERROR;
    YYERROR;
  $$ = make_plus_expression
  $$ = make_plus_expression
     (tok, op1, op2, type_code, EXP_ASSIGN);
     (tok, op1, op2, type_code, EXP_ASSIGN);
}
}
|function_invocation {
|function_invocation {
  $$ = $1;
  $$ = $1;
}
}
;
;
function_invocation:
function_invocation:
NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
NAME LEFT_PARENTHESIS expressions_with_commas_opt RIGHT_PARENTHESIS {
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item *proto;
  struct prod_token_parm_item *proto;
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp_proto;
  struct prod_token_parm_item *exp_proto;
  struct prod_token_parm_item *var;
  struct prod_token_parm_item *var;
  int exp_proto_count;
  int exp_proto_count;
  int exp_count;
  int exp_count;
  tree parms;
  tree parms;
  tree type;
  tree type;
  tok = $1;
  tok = $1;
  prod = make_production (PROD_FUNCTION_INVOCATION, tok);
  prod = make_production (PROD_FUNCTION_INVOCATION, tok);
  SYMBOL_TABLE_NAME (prod) = tok;
  SYMBOL_TABLE_NAME (prod) = tok;
  PARAMETERS (prod) = reverse_prod_list ($3);
  PARAMETERS (prod) = reverse_prod_list ($3);
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  search_prod.category = token_category;
  search_prod.category = token_category;
  proto = lookup_tree_name (&search_prod);
  proto = lookup_tree_name (&search_prod);
  if (!proto)
  if (!proto)
    {
    {
      error ("%Hfunction prototype not found for %q.*s",
      error ("%Hfunction prototype not found for %q.*s",
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
      YYERROR;
      YYERROR;
    }
    }
  EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
  EXPRESSION_TYPE (prod) = EXPRESSION_TYPE (proto);
  NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
  NUMERIC_TYPE (prod) = NUMERIC_TYPE (proto);
  /* Count the expressions and ensure they match the prototype.  */
  /* Count the expressions and ensure they match the prototype.  */
  for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
  for (exp_proto_count = 0, exp_proto = PARAMETERS (proto);
       exp_proto; exp_proto = exp_proto->tp.pro.next)
       exp_proto; exp_proto = exp_proto->tp.pro.next)
    exp_proto_count++;
    exp_proto_count++;
  for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
  for (exp_count = 0, exp = PARAMETERS (prod); exp; exp = exp->tp.pro.next)
    exp_count++;
    exp_count++;
  if (exp_count !=  exp_proto_count)
  if (exp_count !=  exp_proto_count)
    {
    {
      error ("%Hexpression count mismatch %q.*s with prototype",
      error ("%Hexpression count mismatch %q.*s with prototype",
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
      YYERROR;
      YYERROR;
    }
    }
  parms = tree_code_init_parameters ();
  parms = tree_code_init_parameters ();
  for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
  for (exp_proto = PARAMETERS (proto), exp = PARAMETERS (prod);
       exp_proto;
       exp_proto;
       exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
       exp = exp->tp.pro.next, exp_proto = exp_proto->tp.pro.next)
    {
    {
      gcc_assert (exp);
      gcc_assert (exp);
      gcc_assert (exp_proto);
      gcc_assert (exp_proto);
      gcc_assert (exp->tp.pro.code);
      gcc_assert (exp->tp.pro.code);
      var = VARIABLE (exp_proto);
      var = VARIABLE (exp_proto);
      gcc_assert (var);
      gcc_assert (var);
      gcc_assert (var->tp.pro.code);
      gcc_assert (var->tp.pro.code);
      parms = tree_code_add_parameter (parms, var->tp.pro.code,
      parms = tree_code_add_parameter (parms, var->tp.pro.code,
                                       exp->tp.pro.code);
                                       exp->tp.pro.code);
    }
    }
  type = tree_code_get_type (NUMERIC_TYPE (prod));
  type = tree_code_get_type (NUMERIC_TYPE (prod));
  prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
  prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
                                                proto->tp.pro.code,
                                                proto->tp.pro.code,
                                                nreverse (parms),
                                                nreverse (parms),
                                                NULL, tok->tp.tok.location);
                                                NULL, tok->tp.tok.location);
  $$ = prod;
  $$ = prod;
}
}
;
;
expressions_with_commas_opt:
expressions_with_commas_opt:
/* Nil.  */ {
/* Nil.  */ {
$$ = 0
$$ = 0
}
}
|expressions_with_commas { $$ = $1 }
|expressions_with_commas { $$ = $1 }
;
;
expressions_with_commas:
expressions_with_commas:
expression {
expression {
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  exp = $1;
  exp = $1;
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  $$ = $1;
  $$ = $1;
}
}
|expressions_with_commas COMMA expression {
|expressions_with_commas COMMA expression {
  struct prod_token_parm_item *exp;
  struct prod_token_parm_item *exp;
  exp = $3;
  exp = $3;
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (exp), exp->tp.pro.main_token);
  exp->tp.pro.next = $1; /* Reverse order.  */
  exp->tp.pro.next = $1; /* Reverse order.  */
  $$ = exp;
  $$ = exp;
}
}
;
;
variable_ref:
variable_ref:
NAME {
NAME {
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item search_prod;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *symbol_table_entry;
  struct prod_token_parm_item *symbol_table_entry;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tree type;
  tree type;
  tok = $1;
  tok = $1;
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  SYMBOL_TABLE_NAME ((&search_prod)) = tok;
  search_prod.category = token_category;
  search_prod.category = token_category;
  symbol_table_entry = lookup_tree_name (&search_prod);
  symbol_table_entry = lookup_tree_name (&search_prod);
  if (!symbol_table_entry)
  if (!symbol_table_entry)
    {
    {
      error ("%Hvariable %q.*s not defined",
      error ("%Hvariable %q.*s not defined",
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
             &tok->tp.tok.location, tok->tp.tok.length, tok->tp.tok.chars);
      YYERROR;
      YYERROR;
    }
    }
  prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
  prod = make_production (PROD_VARIABLE_REFERENCE_EXPRESSION, tok);
  NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
  NUMERIC_TYPE (prod) = NUMERIC_TYPE (symbol_table_entry);
  type = tree_code_get_type (NUMERIC_TYPE (prod));
  type = tree_code_get_type (NUMERIC_TYPE (prod));
  if (!NUMERIC_TYPE (prod))
  if (!NUMERIC_TYPE (prod))
    YYERROR;
    YYERROR;
  OP1 (prod) = $1;
  OP1 (prod) = $1;
  prod->tp.pro.code =
  prod->tp.pro.code =
    tree_code_get_expression (EXP_REFERENCE, type,
    tree_code_get_expression (EXP_REFERENCE, type,
                              symbol_table_entry->tp.pro.code, NULL, NULL,
                              symbol_table_entry->tp.pro.code, NULL, NULL,
                              tok->tp.tok.location);
                              tok->tp.tok.location);
  $$ = prod;
  $$ = prod;
}
}
;
;
init_opt:
init_opt:
/* Nil.  */ {
/* Nil.  */ {
  $$ = 0;
  $$ = 0;
}
}
|init {
|init {
  /* Pass the initialization value up.  */
  /* Pass the initialization value up.  */
  $$ = $1;
  $$ = $1;
};
};
init:
init:
ASSIGN init_element {
ASSIGN init_element {
  $$ = $2;
  $$ = $2;
}
}
;
;
init_element:
init_element:
INTEGER {
INTEGER {
  $$ = make_integer_constant ($1);
  $$ = make_integer_constant ($1);
}
}
;
;
%%
%%
/* Print a token VALUE to file FILE.  Ignore TYPE which is the token
/* Print a token VALUE to file FILE.  Ignore TYPE which is the token
   type. */
   type. */
void
void
print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
print_token (FILE *file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value)
{
{
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  unsigned int  ix;
  unsigned int  ix;
  tok  =  value;
  tok  =  value;
  fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
  fprintf (file, "%d \"", LOCATION_LINE (tok->tp.tok.location));
  for (ix  =  0; ix < tok->tp.tok.length; ix++)
  for (ix  =  0; ix < tok->tp.tok.length; ix++)
    fprintf (file, "%c", tok->tp.tok.chars[ix]);
    fprintf (file, "%c", tok->tp.tok.chars[ix]);
  fprintf (file, "\"");
  fprintf (file, "\"");
}
}
/* Output a message ERROR_MESSAGE from the parser.  */
/* Output a message ERROR_MESSAGE from the parser.  */
static void
static void
yyerror (const char *error_message)
yyerror (const char *error_message)
{
{
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  tok = yylval;
  tok = yylval;
  if (tok)
  if (tok)
    error ("%H%s", &tok->tp.tok.location, error_message);
    error ("%H%s", &tok->tp.tok.location, error_message);
  else
  else
    error ("%s", error_message);
    error ("%s", error_message);
}
}
/* Reverse the order of a token list, linked by parse_next, old first
/* Reverse the order of a token list, linked by parse_next, old first
   token is OLD_FIRST.  */
   token is OLD_FIRST.  */
static struct prod_token_parm_item*
static struct prod_token_parm_item*
reverse_prod_list (struct prod_token_parm_item *old_first)
reverse_prod_list (struct prod_token_parm_item *old_first)
{
{
  struct prod_token_parm_item *current;
  struct prod_token_parm_item *current;
  struct prod_token_parm_item *next;
  struct prod_token_parm_item *next;
  struct prod_token_parm_item *prev = NULL;
  struct prod_token_parm_item *prev = NULL;
  current = old_first;
  current = old_first;
  prev = NULL;
  prev = NULL;
  while (current)
  while (current)
    {
    {
      gcc_assert (current->category == production_category);
      gcc_assert (current->category == production_category);
      next = current->tp.pro.next;
      next = current->tp.pro.next;
      current->tp.pro.next = prev;
      current->tp.pro.next = prev;
      prev = current;
      prev = current;
      current = next;
      current = next;
    }
    }
  return prev;
  return prev;
}
}
/* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
/* Ensure TYPE is not VOID. Use NAME as the token for the error location.  */
static void
static void
ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
{
{
  if (type == VOID_TYPE)
  if (type == VOID_TYPE)
    error ("%Htype must not be void in this context",
    error ("%Htype must not be void in this context",
           &name->tp.tok.location);
           &name->tp.tok.location);
}
}
/* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
/* Check TYPE1 and TYPE2 which are integral types.  Return the lowest
   common type (min is signed int).  */
   common type (min is signed int).  */
static int
static int
get_common_type (struct prod_token_parm_item *type1,
get_common_type (struct prod_token_parm_item *type1,
                 struct prod_token_parm_item *type2)
                 struct prod_token_parm_item *type2)
{
{
  if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
  if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
    return UNSIGNED_INT;
    return UNSIGNED_INT;
  if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
  if (NUMERIC_TYPE (type2) == UNSIGNED_INT)
    return UNSIGNED_INT;
    return UNSIGNED_INT;
  return SIGNED_INT;
  return SIGNED_INT;
}
}
/* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
/* Check type (TYPE_NUM) and expression (EXP) match.  Return the 1 if
   OK else 0.  Must be exact match - same name unless it is an
   OK else 0.  Must be exact match - same name unless it is an
   integral type.  */
   integral type.  */
static int
static int
check_type_match (int type_num, struct prod_token_parm_item *exp)
check_type_match (int type_num, struct prod_token_parm_item *exp)
{
{
  switch (type_num)
  switch (type_num)
    {
    {
    case SIGNED_INT:
    case SIGNED_INT:
    case UNSIGNED_INT:
    case UNSIGNED_INT:
    case SIGNED_CHAR:
    case SIGNED_CHAR:
    case UNSIGNED_CHAR:
    case UNSIGNED_CHAR:
      switch (NUMERIC_TYPE (exp))
      switch (NUMERIC_TYPE (exp))
        {
        {
        case SIGNED_INT:
        case SIGNED_INT:
        case UNSIGNED_INT:
        case UNSIGNED_INT:
        case SIGNED_CHAR:
        case SIGNED_CHAR:
        case UNSIGNED_CHAR:
        case UNSIGNED_CHAR:
          return 1;
          return 1;
        case VOID_TYPE:
        case VOID_TYPE:
        default:
        default:
          gcc_unreachable ();
          gcc_unreachable ();
        }
        }
      break;
      break;
    case VOID_TYPE:
    case VOID_TYPE:
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}
}
/* Make a production for an integer constant VALUE.  */
/* Make a production for an integer constant VALUE.  */
static struct prod_token_parm_item *
static struct prod_token_parm_item *
make_integer_constant (struct prod_token_parm_item* value)
make_integer_constant (struct prod_token_parm_item* value)
{
{
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *tok;
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tok = value;
  tok = value;
  prod = make_production (PROD_INTEGER_CONSTANT, tok);
  prod = make_production (PROD_INTEGER_CONSTANT, tok);
  if ((tok->tp.tok.chars[0] == (unsigned char)'-')
  if ((tok->tp.tok.chars[0] == (unsigned char)'-')
      || (tok->tp.tok.chars[0] == (unsigned char)'+'))
      || (tok->tp.tok.chars[0] == (unsigned char)'+'))
    NUMERIC_TYPE (prod) = SIGNED_INT;
    NUMERIC_TYPE (prod) = SIGNED_INT;
  else
  else
    NUMERIC_TYPE (prod) = UNSIGNED_INT;
    NUMERIC_TYPE (prod) = UNSIGNED_INT;
  prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
  prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
                                                   tok->tp.tok.length);
                                                   tok->tp.tok.length);
  return prod;
  return prod;
}
}
/* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
/* Build a PROD_PLUS_EXPRESSION.  This is uses for PLUS, MINUS, ASSIGN
   and EQUALS expressions.  */
   and EQUALS expressions.  */
static struct prod_token_parm_item *
static struct prod_token_parm_item *
make_plus_expression (struct prod_token_parm_item *tok,
make_plus_expression (struct prod_token_parm_item *tok,
                      struct prod_token_parm_item *op1,
                      struct prod_token_parm_item *op1,
                      struct prod_token_parm_item *op2,
                      struct prod_token_parm_item *op2,
                      int type_code, int prod_code)
                      int type_code, int prod_code)
{
{
  struct prod_token_parm_item *prod;
  struct prod_token_parm_item *prod;
  tree type;
  tree type;
  ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (op1), op1->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
  ensure_not_void (NUMERIC_TYPE (op2), op2->tp.pro.main_token);
  prod = make_production (PROD_PLUS_EXPRESSION, tok);
  prod = make_production (PROD_PLUS_EXPRESSION, tok);
  NUMERIC_TYPE (prod) = type_code;
  NUMERIC_TYPE (prod) = type_code;
  type = tree_code_get_type (type_code);
  type = tree_code_get_type (type_code);
  gcc_assert (type);
  gcc_assert (type);
  OP1 (prod) = op1;
  OP1 (prod) = op1;
  OP2 (prod) = op2;
  OP2 (prod) = op2;
  prod->tp.pro.code = tree_code_get_expression (prod_code, type,
  prod->tp.pro.code = tree_code_get_expression (prod_code, type,
                                                op1->tp.pro.code,
                                                op1->tp.pro.code,
                                                op2->tp.pro.code, NULL,
                                                op2->tp.pro.code, NULL,
                                                tok->tp.tok.location);
                                                tok->tp.tok.location);
  return prod;
  return prod;
}
}
/* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
/* Set STORAGE_CLASS in PROD according to CLASS_TOKEN.  */
static void
static void
set_storage (struct prod_token_parm_item *prod)
set_storage (struct prod_token_parm_item *prod)
{
{
  struct prod_token_parm_item *stg_class;
  struct prod_token_parm_item *stg_class;
  stg_class = STORAGE_CLASS_TOKEN (prod);
  stg_class = STORAGE_CLASS_TOKEN (prod);
  switch (stg_class->type)
  switch (stg_class->type)
    {
    {
    case STATIC:
    case STATIC:
      STORAGE_CLASS (prod) = STATIC_STORAGE;
      STORAGE_CLASS (prod) = STATIC_STORAGE;
      break;
      break;
    case AUTOMATIC:
    case AUTOMATIC:
      STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
      STORAGE_CLASS (prod) = AUTOMATIC_STORAGE;
      break;
      break;
    case EXTERNAL_DEFINITION:
    case EXTERNAL_DEFINITION:
      STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
      STORAGE_CLASS (prod) = EXTERNAL_DEFINITION_STORAGE;
      break;
      break;
    case EXTERNAL_REFERENCE:
    case EXTERNAL_REFERENCE:
      STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
      STORAGE_CLASS (prod) = EXTERNAL_REFERENCE_STORAGE;
      break;
      break;
    default:
    default:
      gcc_unreachable ();
      gcc_unreachable ();
    }
    }
}
}
/* Set parse trace.  */
/* Set parse trace.  */
void
void
treelang_debug (void)
treelang_debug (void)
{
{
  if (option_parser_trace)
  if (option_parser_trace)
    yydebug = 1;
    yydebug = 1;
}
}
#ifdef __XGETTEXT__
#ifdef __XGETTEXT__
/* Depending on the version of Bison used to compile this grammar,
/* Depending on the version of Bison used to compile this grammar,
   it may issue generic diagnostics spelled "syntax error" or
   it may issue generic diagnostics spelled "syntax error" or
   "parse error".  To prevent this from changing the translation
   "parse error".  To prevent this from changing the translation
   template randomly, we list all the variants of this particular
   template randomly, we list all the variants of this particular
   diagnostic here.  Translators: there is no fine distinction
   diagnostic here.  Translators: there is no fine distinction
   between diagnostics with "syntax error" in them, and diagnostics
   between diagnostics with "syntax error" in them, and diagnostics
   with "parse error" in them.  It's okay to give them both the same
   with "parse error" in them.  It's okay to give them both the same
   translation.  */
   translation.  */
const char d1[] = N_("syntax error");
const char d1[] = N_("syntax error");
const char d2[] = N_("parse error");
const char d2[] = N_("parse error");
const char d3[] = N_("syntax error; also virtual memory exhausted");
const char d3[] = N_("syntax error; also virtual memory exhausted");
const char d4[] = N_("parse error; also virtual memory exhausted");
const char d4[] = N_("parse error; also virtual memory exhausted");
const char d5[] = N_("syntax error: cannot back up");
const char d5[] = N_("syntax error: cannot back up");
const char d6[] = N_("parse error: cannot back up");
const char d6[] = N_("parse error: cannot back up");
#endif
#endif
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.