* monitor.c (monitor_load_srec monitor_make_srec): Move all
[deliverable/binutils-gdb.git] / gdb / ch-exp.y
index 35fb2feff6592e9a506771068310e47ecee33107..70823ef2cdd50bd2ada049ca42a6c7745080b9bd 100644 (file)
@@ -1,5 +1,5 @@
 /* YACC grammar for Chill expressions, for GDB.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -15,7 +15,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Parse a Chill expression from text in a string,
    and return the result as a  struct expression  pointer.
@@ -54,11 +54,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 %{
 
 #include "defs.h"
+#include <string.h>
+#include <ctype.h>
 #include "expression.h"
 #include "language.h"
 #include "value.h"
 #include "parser-defs.h"
 #include "ch-lang.h"
+#include "bfd.h" /* Required by objfiles.h.  */
+#include "symfile.h" /* Required by objfiles.h.  */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
@@ -82,8 +87,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yypgo   chill_pgo
 #define        yyact   chill_act
 #define        yyexca  chill_exca
-#define yyerrflag chill_errflag
-#define yynerrs        chill_nerrs
+#define        yyerrflag chill_errflag
+#define        yynerrs chill_nerrs
 #define        yyps    chill_ps
 #define        yypv    chill_pv
 #define        yys     chill_s
@@ -94,13 +99,25 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yy_yyv  chill_yyv
 #define        yyval   chill_val
 #define        yylloc  chill_lloc
-#define yyreds chill_reds              /* With YYDEBUG defined */
-#define yytoks chill_toks              /* With YYDEBUG defined */
+#define        yyreds  chill_reds              /* With YYDEBUG defined */
+#define        yytoks  chill_toks              /* With YYDEBUG defined */
+#define yylhs  chill_yylhs
+#define yylen  chill_yylen
+#define yydefred chill_yydefred
+#define yydgoto        chill_yydgoto
+#define yysindex chill_yysindex
+#define yyrindex chill_yyrindex
+#define yygindex chill_yygindex
+#define yytable         chill_yytable
+#define yycheck         chill_yycheck
 
 #ifndef YYDEBUG
 #define        YYDEBUG 0               /* Default to no yydebug support */
 #endif
 
+static void
+write_lower_upper_value PARAMS ((enum exp_opcode, struct type *type));
+
 int
 yyparse PARAMS ((void));
 
@@ -139,21 +156,18 @@ yyerror PARAMS ((char *));
     int *ivec;
   }
 
-%token <voidval> FIXME
-
 %token <typed_val>     INTEGER_LITERAL
 %token <ulval>         BOOLEAN_LITERAL
 %token <typed_val>     CHARACTER_LITERAL
 %token <dval>          FLOAT_LITERAL
 %token <ssym>          GENERAL_PROCEDURE_NAME
 %token <ssym>          LOCATION_NAME
-%token <voidval>       SET_LITERAL
 %token <voidval>       EMPTINESS_LITERAL
 %token <sval>          CHARACTER_STRING_LITERAL
 %token <sval>          BIT_STRING_LITERAL
+%token <tsym>          TYPENAME
+%token <sval>          FIELD_NAME
 
-%token <voidval>       STRING
-%token <voidval>       CONSTANT
 %token <voidval>       '.'
 %token <voidval>       ';'
 %token <voidval>       ':'
@@ -182,7 +196,6 @@ yyerror PARAMS ((char *));
 %token <voidval>       NOT
 %token <voidval>       POINTER
 %token <voidval>       RECEIVE
-%token <voidval>       SC
 %token <voidval>       '['
 %token <voidval>       ']'
 %token <voidval>       '('
@@ -199,49 +212,36 @@ yyerror PARAMS ((char *));
 %token <voidval>       SUCC
 %token <voidval>       ABS
 %token <voidval>       CARD
-%token <voidval>       MAX
-%token <voidval>       MIN
+%token <voidval>       MAX_TOKEN
+%token <voidval>       MIN_TOKEN
+%token <voidval>       ADDR_TOKEN
 %token <voidval>       SIZE
 %token <voidval>       UPPER
 %token <voidval>       LOWER
 %token <voidval>       LENGTH
+%token <voidval>       ARRAY
 
 /* Tokens which are not Chill tokens used in expressions, but rather GDB
    specific things that we recognize in the same context as Chill tokens
    (register names for example). */
 
-%token <lval>          GDB_REGNAME     /* Machine register name */
-%token <lval>          GDB_LAST        /* Value history */
-%token <ivar>          GDB_VARIABLE    /* Convenience variable */
+%token <voidval>       GDB_VARIABLE    /* Convenience variable */
 %token <voidval>       GDB_ASSIGNMENT  /* Assign value to somewhere */
 
-%type <voidval>                location
 %type <voidval>                access_name
 %type <voidval>                primitive_value
-%type <voidval>                location_contents
 %type <voidval>                value_name
 %type <voidval>                literal
 %type <voidval>                tuple
-%type <voidval>                value_string_element
-%type <voidval>                value_string_slice
-%type <voidval>                value_array_element
-%type <voidval>                value_array_slice
-%type <voidval>                value_structure_field
+%type <voidval>                slice
 %type <voidval>                expression_conversion
-%type <voidval>                value_procedure_call
 %type <voidval>                value_built_in_routine_call
-%type <voidval>                chill_value_built_in_routine_call
-%type <voidval>                start_expression
-%type <voidval>                zero_adic_operator
 %type <voidval>                parenthesised_expression
 %type <voidval>                value
-%type <voidval>                undefined_value
 %type <voidval>                expression
 %type <voidval>                conditional_expression
 %type <voidval>                then_alternative
 %type <voidval>                else_alternative
-%type <voidval>                sub_expression
-%type <voidval>                value_case_alternative
 %type <voidval>                operand_0
 %type <voidval>                operand_1
 %type <voidval>                operand_2
@@ -249,68 +249,35 @@ yyerror PARAMS ((char *));
 %type <voidval>                operand_4
 %type <voidval>                operand_5
 %type <voidval>                operand_6
-%type <voidval>                integer_literal_expression
-%type <voidval>                synonym_name
-%type <voidval>                value_enumeration_name
-%type <voidval>                value_do_with_name
-%type <voidval>                value_receive_name
-%type <voidval>                string_primitive_value
-%type <voidval>                start_element
-%type <voidval>                left_element
-%type <voidval>                right_element
-%type <voidval>                slice_size
-%type <voidval>                array_primitive_value
 %type <voidval>                expression_list
-%type <voidval>                lower_element
-%type <voidval>                upper_element
-%type <voidval>                first_element
-%type <voidval>                structure_primitive_value
-%type <voidval>                field_name
-%type <voidval>                mode_argument
-%type <voidval>                upper_lower_argument
-%type <voidval>                length_argument
-%type <voidval>                mode_name
+%type <tval>           mode_argument
+%type <voidval>                single_assignment_action
+%type <tsym>           mode_name
+%type <lval>           rparen
+
+/* Not implemented:
+%type <voidval>                undefined_value
 %type <voidval>                array_mode_name
 %type <voidval>                string_mode_name
 %type <voidval>                variant_structure_mode_name
-%type <voidval>                boolean_expression
-%type <voidval>                case_selector_list
-%type <voidval>                subexpression
-%type <voidval>                case_label_specification
-%type <voidval>                buffer_location
-
-%type <voidval>                single_assignment_action
+*/
 
 %%
 
 /* Z.200, 5.3.1 */
 
+start  :       value { }
+       |       mode_name
+                       { write_exp_elt_opcode(OP_TYPE);
+                         write_exp_elt_type($1.type);
+                         write_exp_elt_opcode(OP_TYPE);}
+       ;
+
 value          :       expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+/*
                |       undefined_value
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-undefined_value        :       FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-/* Z.200, 4.2.1 */
-
-location       :       access_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
+*/
                ;
 
 /* Z.200, 4.2.2 */
@@ -318,31 +285,11 @@ location  :       access_name
 access_name    :       LOCATION_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
-               |       GDB_LAST                /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_LAST);
-                         write_exp_elt_longcst ($1);
-                         write_exp_elt_opcode (OP_LAST); 
-                       }
-               |       GDB_REGNAME             /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_REGISTER);
-                         write_exp_elt_longcst ($1);
-                         write_exp_elt_opcode (OP_REGISTER); 
-                       }
                |       GDB_VARIABLE    /* gdb specific */
-                       {
-                         write_exp_elt_opcode (OP_INTERNALVAR);
-                         write_exp_elt_intern ($1);
-                         write_exp_elt_opcode (OP_INTERNALVAR); 
-                       }
-               |       FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 /* Z.200, 4.2.8 */
@@ -355,100 +302,73 @@ expression_list  :       expression
                        {
                          arglist_len++;
                        }
+               ;
 
-/* Z.200, 5.2.1 */
-
-primitive_value        :       location_contents
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-                |      value_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-                |      literal
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-                |      tuple
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-                |      value_string_element
+maybe_expression_list: /* EMPTY */
                        {
-                         $$ = 0;       /* FIXME */
+                         arglist_len = 0;
                        }
-                |      value_string_slice
+               |       expression_list
+               ;
+
+
+/* Z.200, 5.2.1 */
+
+primitive_value_lparen: primitive_value '('
+                               /* This is to save the value of arglist_len
+                                  being accumulated for each dimension. */
+                               { start_arglist (); }
+               ;
+
+rparen         :       ')'
+                               { $$ = end_arglist (); }
+               ;
+
+primitive_value        :
+                       access_name
+               |       primitive_value_lparen maybe_expression_list rparen
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
+                         write_exp_elt_longcst ($3);
+                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
                        }
-                |      value_array_element
-                       {
-                         $$ = 0;       /* FIXME */
+               |       primitive_value FIELD_NAME
+                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         write_exp_string ($2);
+                         write_exp_elt_opcode (STRUCTOP_STRUCT);
                        }
-                |      value_array_slice
+               |       primitive_value POINTER
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_IND);
                        }
-                |      value_structure_field
+               |       primitive_value POINTER mode_name
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type (lookup_pointer_type ($3.type));
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_opcode (UNOP_IND);
                        }
+                |      value_name
+                |      literal
+                |      tuple
+                |      slice
                 |      expression_conversion
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-                |      value_procedure_call
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                 |      value_built_in_routine_call
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+/*
                 |      start_expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
                 |      zero_adic_operator
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
+*/
                 |      parenthesised_expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-/* Z.200, 5.2.2 */
-
-location_contents:     location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 /* Z.200, 5.2.3 */
 
-value_name     :       synonym_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       value_enumeration_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       value_do_with_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       value_receive_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       GENERAL_PROCEDURE_NAME
+value_name     :       GENERAL_PROCEDURE_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
@@ -483,13 +403,14 @@ literal           :       INTEGER_LITERAL
                          write_exp_elt_dblcst ($1);
                          write_exp_elt_opcode (OP_DOUBLE);
                        }
-               |       SET_LITERAL
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       EMPTINESS_LITERAL
                        {
-                         $$ = 0;       /* FIXME */
+                         struct type *void_ptr_type
+                           = lookup_pointer_type (builtin_type_void);
+                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (void_ptr_type);
+                         write_exp_elt_longcst (0);
+                         write_exp_elt_opcode (OP_LONG);
                        }
                |       CHARACTER_STRING_LITERAL
                        {
@@ -507,211 +428,162 @@ literal         :       INTEGER_LITERAL
 
 /* Z.200, 5.2.5 */
 
-tuple          :       FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+tuple_element  :       expression
+               |       named_record_element
                ;
 
-
-/* Z.200, 5.2.6 */
-
-value_string_element:  string_primitive_value '(' start_element ')'
-                       {
-                         $$ = 0;       /* FIXME */
+named_record_element:  FIELD_NAME ',' named_record_element
+                       { write_exp_elt_opcode (OP_LABELED);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_LABELED);
+                       }
+               |       FIELD_NAME ':' expression       
+                       { write_exp_elt_opcode (OP_LABELED);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_LABELED);
                        }
                ;
 
-/* Z.200, 5.2.7 */
-
-value_string_slice:    string_primitive_value '(' left_element ':' right_element ')'
+tuple_elements :       tuple_element
                        {
-                         $$ = 0;       /* FIXME */
+                         arglist_len = 1;
                        }
-               |       string_primitive_value '(' start_element UP slice_size ')'
+               |       tuple_elements ',' tuple_element
                        {
-                         $$ = 0;       /* FIXME */
+                         arglist_len++;
                        }
                ;
 
-/* Z.200, 5.2.8 */
-
-value_array_element:   array_primitive_value '('
-                               /* This is to save the value of arglist_len
-                                  being accumulated for each dimension. */
-                               { start_arglist (); }
-                       expression_list ')'
-                       {
-                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
-                         write_exp_elt_longcst ((LONGEST) end_arglist ());
-                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
-                       }
+maybe_tuple_elements : tuple_elements
+               | /* EMPTY */
                ;
 
-/* Z.200, 5.2.9 */
-
-value_array_slice:     array_primitive_value '(' lower_element ':' upper_element ')'
+tuple  :       '['
+                       { start_arglist (); }
+               maybe_tuple_elements ']'
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (OP_ARRAY);
+                         write_exp_elt_longcst ((LONGEST) 0);
+                         write_exp_elt_longcst ((LONGEST) end_arglist () - 1);
+                         write_exp_elt_opcode (OP_ARRAY);
                        }
-               |       array_primitive_value '(' first_element UP slice_size ')'
+               |
+               mode_name '['
+                       { start_arglist (); }
+               maybe_tuple_elements ']'
                        {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-/* Z.200, 5.2.10 */
+                         write_exp_elt_opcode (OP_ARRAY);
+                         write_exp_elt_longcst ((LONGEST) 0);
+                         write_exp_elt_longcst ((LONGEST) end_arglist () - 1);
+                         write_exp_elt_opcode (OP_ARRAY);
 
-value_structure_field: structure_primitive_value '.' field_name
-                       {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_opcode (UNOP_CAST);
                        }
                ;
 
-/* Z.200, 5.2.11 */
 
-expression_conversion: mode_name '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
+/* Z.200, 5.2.6 */
 
-/* Z.200, 5.2.12 */
 
-value_procedure_call:  FIXME
+slice: primitive_value_lparen expression ':' expression rparen
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (TERNOP_SLICE);
                        }
-               ;
-
-/* Z.200, 5.2.13 */
-
-value_built_in_routine_call:   chill_value_built_in_routine_call
+               |       primitive_value_lparen expression UP expression rparen
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (TERNOP_SLICE_COUNT);
                        }
                ;
 
-/* Z.200, 5.2.14 */
-
-start_expression:      FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }       /* Not in GNU-Chill */
-               ;
-
-/* Z.200, 5.2.15 */
+/* Z.200, 5.2.11 */
 
-zero_adic_operator:    FIXME
+expression_conversion: mode_name parenthesised_expression
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_opcode (UNOP_CAST);
+                       }
+               |       ARRAY '(' ')' mode_name parenthesised_expression
+                       /* This is pseudo-Chill, similar to C's '(TYPE[])EXPR'
+                          which casts to an artificial array. */
+                       {
+                         struct type *range_type
+                           = create_range_type ((struct type *) NULL,
+                                                builtin_type_int, 0, 0);
+                         struct type *array_type
+                           = create_array_type ((struct type *) NULL,
+                                                $4.type, range_type);
+                         TYPE_ARRAY_UPPER_BOUND_TYPE(array_type)
+                           = BOUND_CANNOT_BE_DETERMINED;
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type (array_type);
+                         write_exp_elt_opcode (UNOP_CAST);
                        }
                ;
 
 /* Z.200, 5.2.16 */
 
 parenthesised_expression:      '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 /* Z.200, 5.3.2 */
 
 expression     :       operand_0
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+               |       single_assignment_action
                |       conditional_expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
-conditional_expression : IF boolean_expression then_alternative else_alternative FI
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       CASE case_selector_list OF value_case_alternative '[' ELSE sub_expression ']' ESAC
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+conditional_expression : IF expression then_alternative else_alternative FI
+                       { write_exp_elt_opcode (TERNOP_COND); }
+/*
+               |       CASE case_selector_list OF value_case_alternative ELSE expression ESAC
+                       { error ("not implemented:  CASE expression" }
+*/
                ;
 
-then_alternative:      THEN subexpression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+then_alternative:      THEN expression
                ;
 
-else_alternative:      ELSE subexpression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       ELSIF boolean_expression then_alternative else_alternative
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-sub_expression :       expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-value_case_alternative:        case_label_specification ':' sub_expression ';'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+else_alternative:      ELSE expression
+               |       ELSIF expression then_alternative else_alternative
+                       { write_exp_elt_opcode (TERNOP_COND); }
                ;
 
 /* Z.200, 5.3.3 */
 
 operand_0      :       operand_1
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       operand_0 LOGIOR operand_1
                        {
                          write_exp_elt_opcode (BINOP_BITWISE_IOR);
                        }
                |       operand_0 ORIF operand_1
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_LOGICAL_OR);
                        }
                |       operand_0 LOGXOR operand_1
                        {
                          write_exp_elt_opcode (BINOP_BITWISE_XOR);
                        }
-               |       single_assignment_action
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 /* Z.200, 5.3.4 */
 
 operand_1      :       operand_2
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       operand_1 LOGAND operand_2
                        {
                          write_exp_elt_opcode (BINOP_BITWISE_AND);
                        }
                |       operand_1 ANDIF operand_2
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_LOGICAL_AND);
                        }
                ;
 
 /* Z.200, 5.3.5 */
 
 operand_2      :       operand_3
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       operand_2 '=' operand_3
                        {
                          write_exp_elt_opcode (BINOP_EQUAL);
@@ -738,7 +610,7 @@ operand_2   :       operand_3
                        }
                |       operand_2 IN operand_3
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_IN);
                        }
                ;
 
@@ -746,9 +618,6 @@ operand_2   :       operand_3
 /* Z.200, 5.3.6 */
 
 operand_3      :       operand_4
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       operand_3 '+' operand_4
                        {
                          write_exp_elt_opcode (BINOP_ADD);
@@ -759,16 +628,13 @@ operand_3 :       operand_4
                        }
                |       operand_3 SLASH_SLASH operand_4
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_CONCAT);
                        }
                ;
 
 /* Z.200, 5.3.7 */
 
 operand_4      :       operand_5
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       operand_4 '*' operand_5
                        {
                          write_exp_elt_opcode (BINOP_MUL);
@@ -790,9 +656,6 @@ operand_4   :       operand_5
 /* Z.200, 5.3.8 */
 
 operand_5      :       operand_6
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                |       '-' operand_6
                        {
                          write_exp_elt_opcode (UNOP_NEG);
@@ -801,33 +664,30 @@ operand_5 :       operand_6
                        {
                          write_exp_elt_opcode (UNOP_LOGICAL_NOT);
                        }
-               |       '(' integer_literal_expression ')' operand_6
+               |       parenthesised_expression literal
+/* We require the string operand to be a literal, to avoid some
+   nasty parsing ambiguities. */
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_CONCAT);
                        }
                ;
 
 /* Z.200, 5.3.9 */
 
-operand_6      :       POINTER location
+operand_6      :       POINTER primitive_value
                        {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       RECEIVE buffer_location
-                       {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
                        }
+               |       RECEIVE expression
+                       { error ("not implemented:  RECEIVE expression"); }
                |       primitive_value
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 
 /* Z.200, 6.2 */
 
 single_assignment_action :
-                       location GDB_ASSIGNMENT value
+                       primitive_value GDB_ASSIGNMENT value
                        {
                          write_exp_elt_opcode (BINOP_ASSIGN);
                        }
@@ -835,144 +695,63 @@ single_assignment_action :
 
 /* Z.200, 6.20.3 */
 
-chill_value_built_in_routine_call :
+value_built_in_routine_call :
                        NUM '(' expression ')'
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_opcode (UNOP_CAST);
                        }
                |       PRED '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { error ("not implemented:  PRED builtin function"); }
                |       SUCC '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { error ("not implemented:  SUCC builtin function"); }
+               |       ADDR_TOKEN '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_ADDR); }
                |       ABS '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { error ("not implemented:  ABS builtin function"); }
                |       CARD '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       MAX '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       MIN '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       SIZE '(' location ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { error ("not implemented:  CARD builtin function"); }
+               |       MAX_TOKEN '(' expression ')'
+                       { error ("not implemented:  MAX builtin function"); }
+               |       MIN_TOKEN '(' expression ')'
+                       { error ("not implemented:  MIN builtin function"); }
+               |       SIZE '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_SIZEOF); }
                |       SIZE '(' mode_argument ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       UPPER '(' upper_lower_argument ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       LOWER '(' upper_lower_argument ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       LENGTH '(' length_argument ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+                         write_exp_elt_opcode (OP_LONG); }
+               |       LOWER '(' mode_argument ')'
+                       { write_lower_upper_value (UNOP_LOWER, $3); }
+               |       UPPER '(' mode_argument ')'
+                       { write_lower_upper_value (UNOP_UPPER, $3); }
+               |       LOWER '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_LOWER); }
+               |       UPPER '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_UPPER); }
+               |       LENGTH '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_LENGTH); }
                ;
 
 mode_argument :                mode_name
                        {
-                         $$ = 0;       /* FIXME */
+                         $$ = $1.type;
                        }
+/*
                |       array_mode_name '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
                |       string_mode_name '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
                |       variant_structure_mode_name '(' expression_list ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-upper_lower_argument : location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       mode_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { ??? }
+*/
                ;
 
-length_argument :      location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       expression
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+mode_name :            TYPENAME
                ;
 
-/* Z.200, 12.4.3 */
-/* FIXME:  For now we just accept only a single integer literal. */
-
-integer_literal_expression:
-                       INTEGER_LITERAL
-                       {
-                         $$ = 0;
-                       }
-               ;
-
-/* Z.200, 12.4.3 */
-
-array_primitive_value :        primitive_value
-                       {
-                         $$ = 0;
-                       }
-               ;
-
-
-/* Things which still need productions... */
-
-array_mode_name                :       FIXME { $$ = 0; }
-string_mode_name       :       FIXME { $$ = 0; }
-variant_structure_mode_name:   FIXME { $$ = 0; }
-synonym_name           :       FIXME { $$ = 0; }
-value_enumeration_name         :       FIXME { $$ = 0; }
-value_do_with_name     :       FIXME { $$ = 0; }
-value_receive_name     :       FIXME { $$ = 0; }
-string_primitive_value         :       FIXME { $$ = 0; }
-start_element          :       FIXME { $$ = 0; }
-left_element           :       FIXME { $$ = 0; }
-right_element          :       FIXME { $$ = 0; }
-slice_size             :       FIXME { $$ = 0; }
-lower_element          :       FIXME { $$ = 0; }
-upper_element          :       FIXME { $$ = 0; }
-first_element          :       FIXME { $$ = 0; }
-structure_primitive_value:     FIXME { $$ = 0; }
-field_name             :       FIXME { $$ = 0; }
-mode_name              :       FIXME { $$ = 0; }
-boolean_expression     :       FIXME { $$ = 0; }
-case_selector_list     :       FIXME { $$ = 0; }
-subexpression          :       FIXME { $$ = 0; }
-case_label_specification:      FIXME { $$ = 0; }
-buffer_location        :       FIXME { $$ = 0; }
-
 %%
 
 /* Implementation of a dynamically expandable buffer for processing input
@@ -1023,15 +802,17 @@ match_simple_name_string ()
 {
   char *tokptr = lexptr;
 
-  if (isalpha (*tokptr))
+  if (isalpha (*tokptr) || *tokptr == '_')
     {
+      char *result;
       do {
        tokptr++;
-      } while (isalpha (*tokptr) || isdigit (*tokptr) || (*tokptr == '_'));
+      } while (isalnum (*tokptr) || (*tokptr == '_'));
       yylval.sval.ptr = lexptr;
       yylval.sval.length = tokptr - lexptr;
       lexptr = tokptr;
-      return (copy_name (yylval.sval));
+      result = copy_name (yylval.sval);
+      return result;
     }
   return (NULL);
 }
@@ -1054,7 +835,9 @@ decode_integer_value (base, tokptrptr, ivalptr)
 
   while (*tokptr != '\0')
     {
-      temp = tolower (*tokptr);
+      temp = *tokptr;
+      if (isupper (temp))
+        temp = tolower (temp);
       tokptr++;
       switch (temp)
        {
@@ -1192,7 +975,6 @@ match_float_literal ()
   char *tokptr = lexptr;
   char *buf;
   char *copy;
-  char ch;
   double dval;
   extern double strtod ();
   
@@ -1311,7 +1093,7 @@ match_float_literal ()
   return (0);
 }
 
-/* Recognize a string literal.  A string literal is a nonzero sequence
+/* Recognize a string literal.  A string literal is a sequence
    of characters enclosed in matching single or double quotes, except that
    a single character inside single quotes is a character literal, which
    we reject as a string literal.  To embed the terminator character inside
@@ -1339,7 +1121,6 @@ match_string_literal ()
       tempbuf[tempbufindex++] = *tokptr;
     }
   if (*tokptr == '\0'                                  /* no terminator */
-      || tempbufindex == 0                             /* no string */
       || (tempbufindex == 1 && *tokptr == '\''))       /* char literal */
     {
       return (0);
@@ -1382,7 +1163,7 @@ match_character_literal ()
   char *tokptr = lexptr;
   int ival = 0;
   
-  if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\''))
+  if ((*tokptr == 'c' || *tokptr == 'C') && (*(tokptr + 1) == '\''))
     {
       /* We have a GNU chill extension form, so skip the leading "C'",
         decode the hex value, and then ensure that we have a trailing
@@ -1403,7 +1184,7 @@ match_character_literal ()
       
       if ((*tokptr == '^') && (*(tokptr + 1) == '('))
        {
-         return (0);  /* Disable, see note above. */
+#if 0     /* Disable, see note above. -fnf */
          /* Match and decode a control sequence.  Return zero if we don't
             find a valid integer literal, or if the next unconsumed character
             after the integer literal is not the trailing ')'.
@@ -1414,6 +1195,9 @@ match_character_literal ()
            {
              return (0);
            }
+#else
+         return (0);
+#endif
        }
       else
        {
@@ -1471,14 +1255,15 @@ match_integer_literal ()
 static int
 match_bitstring_literal ()
 {
-  char *tokptr = lexptr;
-  int mask;
+  register char *tokptr = lexptr;
   int bitoffset = 0;
   int bitcount = 0;
-  int base;
+  int bits_per_char;
   int digit;
   
   tempbufindex = 0;
+  CHECKBUF (1);
+  tempbuf[0] = 0;
 
   /* Look for the required explicit base specifier. */
   
@@ -1486,21 +1271,21 @@ match_bitstring_literal ()
     {
     case 'b':
     case 'B':
-      base = 2;
+      bits_per_char = 1;
       break;
     case 'o':
     case 'O':
-      base = 8;
+      bits_per_char = 3;
       break;
     case 'h':
     case 'H':
-      base = 16;
+      bits_per_char = 4;
       break;
     default:
       return (0);
       break;
     }
-  
+
   /* Ensure that the character after the explicit base is a single quote. */
   
   if (*tokptr++ != '\'')
@@ -1510,7 +1295,9 @@ match_bitstring_literal ()
   
   while (*tokptr != '\0' && *tokptr != '\'')
     {
-      digit = tolower (*tokptr);
+      digit = *tokptr;
+      if (isupper (digit))
+        digit = tolower (digit);
       tokptr++;
       switch (digit)
        {
@@ -1528,29 +1315,33 @@ match_bitstring_literal ()
            return (0);
            break;
        }
-      if (digit >= base)
+      if (digit >= 1 << bits_per_char)
        {
          /* Found something not in domain for current base. */
          return (0);
        }
       else
        {
-         /* Extract bits from digit, starting with the msbit appropriate for
-            the current base, and packing them into the bitstring byte,
-            starting at the lsbit. */
-         for (mask = (base >> 1); mask > 0; mask >>= 1)
+         /* Extract bits from digit, packing them into the bitstring byte. */
+         int k = TARGET_BYTE_ORDER == BIG_ENDIAN ? bits_per_char - 1 : 0;
+         for (; TARGET_BYTE_ORDER == BIG_ENDIAN ? k >= 0 : k < bits_per_char;
+              TARGET_BYTE_ORDER == BIG_ENDIAN ? k-- : k++)
            {
              bitcount++;
-             CHECKBUF (1);
-             if (digit & mask)
+             if (digit & (1 << k))
                {
-                 tempbuf[tempbufindex] |= (1 << bitoffset);
+                 tempbuf[tempbufindex] |=
+                   (TARGET_BYTE_ORDER == BIG_ENDIAN)
+                     ? (1 << (HOST_CHAR_BIT - 1 - bitoffset))
+                       : (1 << bitoffset);
                }
              bitoffset++;
              if (bitoffset == HOST_CHAR_BIT)
                {
                  bitoffset = 0;
                  tempbufindex++;
+                 CHECKBUF(1);
+                 tempbuf[tempbufindex] = 0;
                }
            }
        }
@@ -1572,180 +1363,48 @@ match_bitstring_literal ()
     }
 }
 
-/* Recognize tokens that start with '$'.  These include:
-
-       $regname        A native register name or a "standard
-                       register name".
-                       Return token GDB_REGNAME.
-
-       $variable       A convenience variable with a name chosen
-                       by the user.
-                       Return token GDB_VARIABLE.
-
-       $digits         Value history with index <digits>, starting
-                       from the first value which has index 1.
-                       Return GDB_LAST.
-
-       $$digits        Value history with index <digits> relative
-                       to the last value.  I.E. $$0 is the last
-                       value, $$1 is the one previous to that, $$2
-                       is the one previous to $$1, etc.
-                       Return token GDB_LAST.
-
-       $ | $0 | $$0    The last value in the value history.
-                       Return token GDB_LAST.
-
-       $$              An abbreviation for the second to the last
-                       value in the value history, I.E. $$1
-                       Return token GDB_LAST.
-
-    Note that we currently assume that register names and convenience
-    variables follow the convention of starting with a letter or '_'.
-
-   */
-
-static int
-match_dollar_tokens ()
-{
-  char *tokptr;
-  int regno;
-  int namelength;
-  int negate;
-  int ival;
-
-  /* We will always have a successful match, even if it is just for
-     a single '$', the abbreviation for $$0.  So advance lexptr. */
-
-  tokptr = ++lexptr;
-
-  if (*tokptr == '_' || isalpha (*tokptr))
-    {
-      /* Look for a match with a native register name, usually something
-        like "r0" for example. */
-
-      for (regno = 0; regno < NUM_REGS; regno++)
-       {
-         namelength = strlen (reg_names[regno]);
-         if (STREQN (tokptr, reg_names[regno], namelength)
-             && !isalnum (tokptr[namelength]))
-           {
-             yylval.lval = regno;
-             lexptr += namelength + 1;
-             return (GDB_REGNAME);
-           }
-       }
-
-      /* Look for a match with a standard register name, usually something
-        like "pc", which gdb always recognizes as the program counter
-        regardless of what the native register name is. */
-
-      for (regno = 0; regno < num_std_regs; regno++)
-       {
-         namelength = strlen (std_regs[regno].name);
-         if (STREQN (tokptr, std_regs[regno].name, namelength)
-             && !isalnum (tokptr[namelength]))
-           {
-             yylval.lval = std_regs[regno].regnum;
-             lexptr += namelength;
-             return (GDB_REGNAME);
-           }
-       }
-
-      /* Attempt to match against a convenience variable.  Note that
-        this will always succeed, because if no variable of that name
-        already exists, the lookup_internalvar will create one for us.
-        Also note that both lexptr and tokptr currently point to the
-        start of the input string we are trying to match, and that we
-        have already tested the first character for non-numeric, so we
-        don't have to treat it specially. */
-
-      while (*tokptr == '_' || isalnum (*tokptr))
-       {
-         tokptr++;
-       }
-      yylval.sval.ptr = lexptr;
-      yylval.sval.length = tokptr - lexptr;
-      yylval.ivar = lookup_internalvar (copy_name (yylval.sval));
-      lexptr = tokptr;
-      return (GDB_VARIABLE);
-    }
-
-  /* Since we didn't match against a register name or convenience
-     variable, our only choice left is a history value. */
-
-  if (*tokptr == '$')
-    {
-      negate = 1;
-      ival = 1;
-      tokptr++;
-    }
-  else
-    {
-      negate = 0;
-      ival = 0;
-    }
-
-  /* Attempt to decode more characters as an integer value giving
-     the index in the history list.  If successful, the value will
-     overwrite ival (currently 0 or 1), and if not, ival will be
-     left alone, which is good since it is currently correct for
-     the '$' or '$$' case. */
-
-  decode_integer_literal (&ival, &tokptr);
-  yylval.lval = negate ? -ival : ival;
-  lexptr = tokptr;
-  return (GDB_LAST);
-}
-
 struct token
 {
   char *operator;
   int token;
 };
 
-static const struct token tokentab6[] =
-{
-    { "LENGTH", LENGTH }
-};
-
-static const struct token tokentab5[] =
-{
-    { "LOWER", LOWER },
-    { "UPPER", UPPER },
-    { "ANDIF", ANDIF }
-};
-
-static const struct token tokentab4[] =
-{
-    { "PRED", PRED },
-    { "SUCC", SUCC },
-    { "CARD", CARD },
-    { "SIZE", SIZE },
-    { "ORIF", ORIF }
-};
-
-static const struct token tokentab3[] =
+static const struct token idtokentab[] =
 {
-    { "NUM", NUM },
-    { "ABS", ABS },
-    { "MAX", MAX },
-    { "MIN", MIN },
-    { "MOD", MOD },
-    { "REM", REM },
-    { "NOT", NOT },
-    { "XOR", LOGXOR },
-    { "AND", LOGAND }
+    { "array", ARRAY },
+    { "length", LENGTH },
+    { "lower", LOWER },
+    { "upper", UPPER },
+    { "andif", ANDIF },
+    { "pred", PRED },
+    { "succ", SUCC },
+    { "card", CARD },
+    { "size", SIZE },
+    { "orif", ORIF },
+    { "num", NUM },
+    { "abs", ABS },
+    { "max", MAX_TOKEN },
+    { "min", MIN_TOKEN },
+    { "mod", MOD },
+    { "rem", REM },
+    { "not", NOT },
+    { "xor", LOGXOR },
+    { "and", LOGAND },
+    { "in", IN },
+    { "or", LOGIOR },
+    { "up", UP },
+    { "addr", ADDR_TOKEN },
+    { "null", EMPTINESS_LITERAL }
 };
 
 static const struct token tokentab2[] =
 {
     { ":=", GDB_ASSIGNMENT },
     { "//", SLASH_SLASH },
+    { "->", POINTER },
     { "/=", NOTEQUAL },
     { "<=", LEQ },
-    { ">=", GTR },
-    { "IN", IN },
-    { "OR", LOGIOR }
+    { ">=", GTR }
 };
 
 /* Read one token, getting characters through lexptr.  */
@@ -1757,7 +1416,7 @@ yylex ()
 {
     unsigned int i;
     int token;
-    char *simplename;
+    char *inputname;
     struct symbol *sym;
 
     /* Skip over any leading whitespace. */
@@ -1776,9 +1435,7 @@ yylex ()
            case ';':
            case '!':
            case '+':
-           case '-':
            case '*':
-           case '/':
            case '(':
            case ')':
            case '[':
@@ -1792,7 +1449,7 @@ yylex ()
       {
        case '\'':
        case '\"':
-         /* First try to match a string literal, which is any nonzero
+         /* First try to match a string literal, which is any
             sequence of characters enclosed in matching single or double
             quotes, except that a single character inside single quotes
             is a character literal, so we have to catch that case also. */
@@ -1819,49 +1476,15 @@ yylex ()
            }
          break;
        case '$':
-         token = match_dollar_tokens ();
-         if (token != 0)
-           {
-             return (token);
-           }
+         yylval.sval.ptr = lexptr;
+         do {
+           lexptr++;
+         } while (isalnum (*lexptr) || *lexptr == '_' || *lexptr == '$');
+         yylval.sval.length = lexptr - yylval.sval.ptr;
+         write_dollar_variable (yylval.sval);
+         return GDB_VARIABLE;
          break;
       }
-    /* See if it is a special token of length 6.  */
-    for (i = 0; i < sizeof (tokentab6) / sizeof (tokentab6[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab6[i].operator, 6))
-               {
-                   lexptr += 6;
-                   return (tokentab6[i].token);
-               }
-       }
-    /* See if it is a special token of length 5.  */
-    for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab5[i].operator, 5))
-               {
-                   lexptr += 5;
-                   return (tokentab5[i].token);
-               }
-       }
-    /* See if it is a special token of length 4.  */
-    for (i = 0; i < sizeof (tokentab4) / sizeof (tokentab4[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab4[i].operator, 4))
-               {
-                   lexptr += 4;
-                   return (tokentab4[i].token);
-               }
-       }
-    /* See if it is a special token of length 3.  */
-    for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab3[i].operator, 3))
-               {
-                   lexptr += 3;
-                   return (tokentab3[i].token);
-               }
-       }
     /* See if it is a special token of length 2.  */
     for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
        {
@@ -1876,25 +1499,13 @@ yylex ()
        would already have found it. */
     switch (*lexptr)
        {
+           case '-':
            case ':':
            case '/':
            case '<':
            case '>':
                return (*lexptr++);
        }
-    /* Look for other special tokens. */
-    if (STREQN (lexptr, "TRUE", 4)) /* FIXME:  What about lowercase? */
-       {
-           yylval.ulval = 1;
-           lexptr += 4;
-           return (BOOLEAN_LITERAL);
-       }
-    if (STREQN (lexptr, "FALSE", 5)) /* FIXME:  What about lowercase? */
-       {
-           yylval.ulval = 0;
-           lexptr += 5;
-           return (BOOLEAN_LITERAL);
-       }
     /* Look for a float literal before looking for an integer literal, so
        we match as much of the input stream as possible. */
     token = match_float_literal ();
@@ -1919,12 +1530,47 @@ yylex ()
        the token from lexptr, so we can't back out if we later find that
        we can't classify what sort of name it is. */
 
-    simplename = match_simple_name_string ();
-    if (simplename != NULL)
+    inputname = match_simple_name_string ();
+
+    if (inputname != NULL)
       {
-       sym = lookup_symbol (simplename, expression_context_block,
+       char *simplename = (char*) alloca (strlen (inputname) + 1);
+
+       char *dptr = simplename, *sptr = inputname;
+       for (; *sptr; sptr++)
+         *dptr++ = isupper (*sptr) ? tolower(*sptr) : *sptr;
+       *dptr = '\0';
+
+       /* See if it is a reserved identifier. */
+       for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++)
+           {
+               if (STREQ (simplename, idtokentab[i].operator))
+                   {
+                       return (idtokentab[i].token);
+                   }
+           }
+
+       /* Look for other special tokens. */
+       if (STREQ (simplename, "true"))
+           {
+               yylval.ulval = 1;
+               return (BOOLEAN_LITERAL);
+           }
+       if (STREQ (simplename, "false"))
+           {
+               yylval.ulval = 0;
+               return (BOOLEAN_LITERAL);
+           }
+
+       sym = lookup_symbol (inputname, expression_context_block,
                             VAR_NAMESPACE, (int *) NULL,
                             (struct symtab **) NULL);
+       if (sym == NULL && strcmp (inputname, simplename) != 0)
+         {
+           sym = lookup_symbol (simplename, expression_context_block,
+                                VAR_NAMESPACE, (int *) NULL,
+                                (struct symtab **) NULL);
+         }
        if (sym != NULL)
          {
            yylval.ssym.stoken.ptr = NULL;
@@ -1943,8 +1589,11 @@ yylex ()
              case LOC_ARG:
              case LOC_REF_ARG:
              case LOC_REGPARM:
+             case LOC_REGPARM_ADDR:
              case LOC_LOCAL:
              case LOC_LOCAL_ARG:
+             case LOC_BASEREG:
+             case LOC_BASEREG_ARG:
                if (innermost_block == NULL
                    || contained_in (block_found, innermost_block))
                  {
@@ -1956,10 +1605,13 @@ yylex ()
              case LOC_LABEL:
                return (LOCATION_NAME);
                break;
-             case LOC_UNDEF:
              case LOC_TYPEDEF:
+               yylval.tsym.type = SYMBOL_TYPE (sym);
+               return TYPENAME;
+             case LOC_UNDEF:
              case LOC_CONST_BYTES:
-               error ("Symbol \"%s\" names no location.", simplename);
+             case LOC_OPTIMIZED_OUT:
+               error ("Symbol \"%s\" names no location.", inputname);
                break;
              }
          }
@@ -1969,7 +1621,7 @@ yylex ()
          }
        else
          {
-           error ("No symbol \"%s\" in current context.", simplename);
+           error ("No symbol \"%s\" in current context.", inputname);
          }
       }
 
@@ -1979,23 +1631,34 @@ yylex ()
     switch (*lexptr)
       {
        case '.':                       /* Not float for example. */
-         return (*lexptr++);
+         lexptr++;
+         while (isspace (*lexptr)) lexptr++;
+         inputname = match_simple_name_string ();
+         if (!inputname)
+           return '.';
+         return FIELD_NAME;
       }
 
     return (ILLEGAL_TOKEN);
 }
 
+static void
+write_lower_upper_value (opcode, type)
+     enum exp_opcode opcode;  /* Either UNOP_LOWER or UNOP_UPPER */
+     struct type *type;
+{
+  extern LONGEST type_lower_upper ();
+  struct type *result_type;
+  LONGEST val = type_lower_upper (opcode, type, &result_type);
+  write_exp_elt_opcode (OP_LONG);
+  write_exp_elt_type (result_type);
+  write_exp_elt_longcst (val);
+  write_exp_elt_opcode (OP_LONG);
+}
+
 void
 yyerror (msg)
-     char *msg;        /* unused */
+     char *msg;
 {
-  printf ("Parsing:  %s\n", lexptr);
-  if (yychar < 256)
-    {
-      error ("Invalid syntax in expression near character '%c'.", yychar);
-    }
-  else
-    {
-      error ("Invalid syntax in expression");
-    }
+  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
 }
This page took 0.041613 seconds and 4 git commands to generate.