* java-*: Renamed to jv-*, to make fit within 14 characters.
[platform/upstream/binutils.git] / gdb / jv-exp.y
1 /* YACC parser for Java expressions, for GDB.
2    Copyright (C) 1997.
3    Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* Parse a C expression from text in a string,
22    and return the result as a  struct expression  pointer.
23    That structure contains arithmetic operations in reverse polish,
24    with constants represented by operations that are followed by special data.
25    See expression.h for the details of the format.
26    What is important here is that it can be built up sequentially
27    during the process of parsing; the lower levels of the tree always
28    come first in the result.
29
30    Note that malloc's and realloc's in this file are transformed to
31    xmalloc and xrealloc respectively by the same sed command in the
32    makefile that remaps any other malloc/realloc inserted by the parser
33    generator.  Doing this with #defines and trying to control the interaction
34    with include files (<malloc.h> and <stdlib.h> for example) just became
35    too messy, particularly when such includes can be inserted at random
36    times by the parser generator.  */
37   
38 %{
39
40 #include "defs.h"
41 #include "gdb_string.h"
42 #include <ctype.h>
43 #include "expression.h"
44 #include "value.h"
45 #include "parser-defs.h"
46 #include "language.h"
47 #include "jv-lang.h"
48 #include "bfd.h" /* Required by objfiles.h.  */
49 #include "symfile.h" /* Required by objfiles.h.  */
50 #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
51
52 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
53    as well as gratuitiously global symbol names, so we can have multiple
54    yacc generated parsers in gdb.  Note that these are only the variables
55    produced by yacc.  If other parser generators (bison, byacc, etc) produce
56    additional global names that conflict at link time, then those parser
57    generators need to be fixed instead of adding those names to this list. */
58
59 #define yymaxdepth java_maxdepth
60 #define yyparse java_parse
61 #define yylex   java_lex
62 #define yyerror java_error
63 #define yylval  java_lval
64 #define yychar  java_char
65 #define yydebug java_debug
66 #define yypact  java_pact       
67 #define yyr1    java_r1                 
68 #define yyr2    java_r2                 
69 #define yydef   java_def                
70 #define yychk   java_chk                
71 #define yypgo   java_pgo                
72 #define yyact   java_act                
73 #define yyexca  java_exca
74 #define yyerrflag java_errflag
75 #define yynerrs java_nerrs
76 #define yyps    java_ps
77 #define yypv    java_pv
78 #define yys     java_s
79 #define yy_yys  java_yys
80 #define yystate java_state
81 #define yytmp   java_tmp
82 #define yyv     java_v
83 #define yy_yyv  java_yyv
84 #define yyval   java_val
85 #define yylloc  java_lloc
86 #define yyreds  java_reds               /* With YYDEBUG defined */
87 #define yytoks  java_toks               /* With YYDEBUG defined */
88 #define yylhs   java_yylhs
89 #define yylen   java_yylen
90 #define yydefred java_yydefred
91 #define yydgoto java_yydgoto
92 #define yysindex java_yysindex
93 #define yyrindex java_yyrindex
94 #define yygindex java_yygindex
95 #define yytable  java_yytable
96 #define yycheck  java_yycheck
97
98 #ifndef YYDEBUG
99 #define YYDEBUG 0               /* Default to no yydebug support */
100 #endif
101
102 int
103 yyparse PARAMS ((void));
104
105 static int
106 yylex PARAMS ((void));
107
108 void
109 yyerror PARAMS ((char *));
110
111 static struct type * java_type_from_name PARAMS ((struct stoken));
112 static void push_variable PARAMS ((struct stoken));
113
114 %}
115
116 /* Although the yacc "value" of an expression is not used,
117    since the result is stored in the structure being created,
118    other node types do have values.  */
119
120 %union
121   {
122     LONGEST lval;
123     struct {
124       LONGEST val;
125       struct type *type;
126     } typed_val_int;
127     struct {
128       DOUBLEST dval;
129       struct type *type;
130     } typed_val_float;
131     struct symbol *sym;
132     struct type *tval;
133     struct stoken sval;
134     struct ttype tsym;
135     struct symtoken ssym;
136     struct block *bval;
137     enum exp_opcode opcode;
138     struct internalvar *ivar;
139     int *ivec;
140   }
141
142 %{
143 /* YYSTYPE gets defined by %union */
144 static int
145 parse_number PARAMS ((char *, int, int, YYSTYPE *));
146 %}
147
148 %type <lval> rcurly Dims Dims_opt
149 %type <tval> ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
150 %type <tval> IntegralType FloatingPointType NumericType PrimitiveType
151
152 %token <typed_val_int> INTEGER_LITERAL
153 %token <typed_val_float> FLOATING_POINT_LITERAL
154
155 %token <sval> IDENTIFIER
156 %token <sval> STRING_LITERAL
157 %token <lval> BOOLEAN_LITERAL
158 %token <tsym> TYPENAME
159 %type <sval> Name SimpleName QualifiedName ForcedName
160
161 /* A NAME_OR_INT is a symbol which is not known in the symbol table,
162    but which would parse as a valid number in the current input radix.
163    E.g. "c" when input_radix==16.  Depending on the parse, it will be
164    turned into a name or into a number.  */
165
166 %token <sval> NAME_OR_INT 
167
168 %token ERROR
169
170 /* Special type cases, put in to allow the parser to distinguish different
171    legal basetypes.  */
172 %token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
173
174 %token VARIABLE
175
176 %token <opcode> ASSIGN_MODIFY
177
178 %token THIS SUPER NEW
179
180 %left ','
181 %right '=' ASSIGN_MODIFY
182 %right '?'
183 %left OROR
184 %left ANDAND
185 %left '|'
186 %left '^'
187 %left '&'
188 %left EQUAL NOTEQUAL
189 %left '<' '>' LEQ GEQ
190 %left LSH RSH
191 %left '+' '-'
192 %left '*' '/' '%'
193 %right INCREMENT DECREMENT
194 %right '.' '[' '('
195
196 \f
197 %%
198
199 start   :       exp1
200 /*      |       type_exp FIXME */
201         ;
202
203 StringLiteral:
204         STRING_LITERAL
205                 {
206                   write_exp_elt_opcode (OP_STRING);
207                   write_exp_string ($1);
208                   write_exp_elt_opcode (OP_STRING);
209                 }
210 ;
211
212 Literal :
213         INTEGER_LITERAL
214                 { write_exp_elt_opcode (OP_LONG);
215                   write_exp_elt_type ($1.type);
216                   write_exp_elt_longcst ((LONGEST)($1.val));
217                   write_exp_elt_opcode (OP_LONG); }
218 |       NAME_OR_INT
219                 { YYSTYPE val;
220                   parse_number ($1.ptr, $1.length, 0, &val);
221                   write_exp_elt_opcode (OP_LONG);
222                   write_exp_elt_type (val.typed_val_int.type);
223                   write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
224                   write_exp_elt_opcode (OP_LONG);
225                 }
226 |       FLOATING_POINT_LITERAL
227                 { write_exp_elt_opcode (OP_DOUBLE);
228                   write_exp_elt_type ($1.type);
229                   write_exp_elt_dblcst ($1.dval);
230                   write_exp_elt_opcode (OP_DOUBLE); }
231 |       BOOLEAN_LITERAL
232                 { write_exp_elt_opcode (OP_LONG);
233                   write_exp_elt_type (java_boolean_type);
234                   write_exp_elt_longcst ((LONGEST)$1);
235                   write_exp_elt_opcode (OP_LONG); }
236 |       StringLiteral
237         ;
238
239 /* UNUSED:
240 Type:
241         PrimitiveType
242 |       ReferenceType
243 ;
244 */
245
246 PrimitiveType:
247         NumericType
248 |       BOOLEAN
249                 { $$ = java_boolean_type; }
250 ;
251
252 NumericType:
253         IntegralType
254 |       FloatingPointType
255 ;
256
257 IntegralType:
258         BYTE
259                 { $$ = java_byte_type; }
260 |       SHORT
261                 { $$ = java_short_type; }
262 |       INT
263                 { $$ = java_int_type; }
264 |       LONG
265                 { $$ = java_long_type; }
266 |       CHAR
267                 { $$ = java_char_type; }
268 ;
269
270 FloatingPointType:
271         FLOAT
272                 { $$ = java_float_type; }
273 |       DOUBLE
274                 { $$ = java_double_type; }
275 ;
276
277 /* UNUSED:
278 ReferenceType:
279         ClassOrInterfaceType
280 |       ArrayType
281 ;
282 */
283
284 ClassOrInterfaceType:
285         Name
286                 { $$ = java_type_from_name ($1); }
287 ;
288
289 ClassType:
290         ClassOrInterfaceType
291 ;
292
293 /* UNUSED:
294 ArrayType:
295         PrimitiveType Dims
296                 { $$ = java_array_type ($1, $2); }
297 |       Name Dims
298                 { $$ = java_array_type (java_type_from_name ($1), $2); }
299 ;
300 */
301
302 Name:
303         IDENTIFIER
304 |       QualifiedName
305 ;
306
307 ForcedName:
308         SimpleName
309 |       QualifiedName
310 ;
311
312 SimpleName:
313         IDENTIFIER
314 |       NAME_OR_INT
315 ;
316
317 QualifiedName:
318         Name '.' SimpleName
319                 { $$.length = $1.length + $3.length + 1;
320                   if ($1.ptr + $1.length + 1 == $3.ptr
321                       && $1.ptr[$1.length] == '.')
322                     $$.ptr = $1.ptr;  /* Optimization. */
323                   else
324                     {
325                       $$.ptr = (char *) malloc ($$.length + 1);
326                       make_cleanup (free, $$.ptr);
327                       sprintf ($$.ptr, "%.*s.%.*s",
328                                $1.length, $1.ptr, $3.length, $3.ptr);
329                 } }
330 ;
331
332 /*
333 type_exp:       type
334                         { write_exp_elt_opcode(OP_TYPE);
335                           write_exp_elt_type($1);
336                           write_exp_elt_opcode(OP_TYPE);}
337         ;
338         */
339
340 /* Expressions, including the comma operator.  */
341 exp1    :       Expression
342         |       exp1 ',' Expression
343                         { write_exp_elt_opcode (BINOP_COMMA); }
344         ;
345
346 Primary:
347         PrimaryNoNewArray
348 |       ArrayCreationExpression
349 ;
350
351 PrimaryNoNewArray:
352         Literal
353 |       THIS
354                 { write_exp_elt_opcode (OP_THIS);
355                   write_exp_elt_opcode (OP_THIS); }
356 |       '(' Expression ')'
357 |       ClassInstanceCreationExpression
358 |       FieldAccess
359 |       MethodInvocation
360 |       ArrayAccess
361 |       lcurly ArgumentList rcurly
362                 { write_exp_elt_opcode (OP_ARRAY);
363                   write_exp_elt_longcst ((LONGEST) 0);
364                   write_exp_elt_longcst ((LONGEST) $3);
365                   write_exp_elt_opcode (OP_ARRAY); }
366 ;
367
368 lcurly:
369         '{'
370                 { start_arglist (); }
371 ;
372
373 rcurly:
374         '}'
375                 { $$ = end_arglist () - 1; }
376 ;
377
378 ClassInstanceCreationExpression:
379         NEW ClassType '(' ArgumentList_opt ')'
380                 { error ("FIXME - ClassInstanceCreationExpression"); }
381 ;
382
383 ArgumentList:
384         Expression
385                 { arglist_len = 1; }
386 |       ArgumentList ',' Expression
387                 { arglist_len++; }
388 ;
389
390 ArgumentList_opt:
391         /* EMPTY */
392                 { arglist_len = 0; }
393 | ArgumentList
394 ;
395
396 ArrayCreationExpression:
397         NEW PrimitiveType DimExprs Dims_opt
398                 { error ("FIXME - ArrayCreatiionExpression"); }
399 |       NEW ClassOrInterfaceType DimExprs Dims_opt
400                 { error ("FIXME - ArrayCreatiionExpression"); }
401 ;
402
403 DimExprs:
404         DimExpr
405 |       DimExprs DimExpr
406 ;
407
408 DimExpr:
409         '[' Expression ']'
410 ;
411
412 Dims:
413         '[' ']'
414                 { $$ = 1; }
415 |       Dims '[' ']'
416         { $$ = $1 + 1; }
417 ;
418
419 Dims_opt:
420         Dims
421 |       /* EMPTY */
422                 { $$ = 0; }
423 ;
424
425 FieldAccess:
426         Primary '.' SimpleName
427                 { write_exp_elt_opcode (STRUCTOP_STRUCT);
428                   write_exp_string ($3);
429                   write_exp_elt_opcode (STRUCTOP_STRUCT); }
430 /*|     SUPER '.' SimpleName { FIXME } */
431 ;
432
433 MethodInvocation:
434         Name '(' ArgumentList_opt ')'
435                 { error ("method invocation not implemented"); }
436 |       Primary '.' SimpleName '(' ArgumentList_opt ')'
437                 { error ("method invocation not implemented"); }
438 |       SUPER '.' SimpleName '(' ArgumentList_opt ')'
439                 { error ("method invocation not implemented"); }
440 ;
441
442 ArrayAccess:
443         Name '[' Expression ']'
444                 { error ("ArrayAccess"); } /* FIXME - NASTY */
445 |       PrimaryNoNewArray '[' Expression ']'
446                 { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
447 ;
448
449 PostfixExpression:
450         Primary
451 |       Name
452                 { push_variable ($1); }
453 |       VARIABLE
454                 /* Already written by write_dollar_variable. */
455 |       PostIncrementExpression
456 |       PostDecrementExpression
457 ;
458
459 PostIncrementExpression:
460         PostfixExpression INCREMENT
461                 { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
462 ;
463
464 PostDecrementExpression:
465         PostfixExpression DECREMENT
466                 { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
467 ;
468
469 UnaryExpression:
470         PreIncrementExpression
471 |       PreDecrementExpression
472 |       '+' UnaryExpression
473 |       '-' UnaryExpression
474                 { write_exp_elt_opcode (UNOP_NEG); }
475 |       '*' UnaryExpression 
476                 { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java  */
477 |       UnaryExpressionNotPlusMinus
478 ;
479
480 PreIncrementExpression:
481         INCREMENT UnaryExpression
482                 { write_exp_elt_opcode (UNOP_PREINCREMENT); }
483 ;
484
485 PreDecrementExpression:
486         DECREMENT UnaryExpression
487                 { write_exp_elt_opcode (UNOP_PREDECREMENT); }
488 ;
489
490 UnaryExpressionNotPlusMinus:
491         PostfixExpression
492 |       '~' UnaryExpression
493                 { write_exp_elt_opcode (UNOP_COMPLEMENT); }
494 |       '!' UnaryExpression
495                 { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
496 |       CastExpression
497         ;
498
499 CastExpression:
500         '(' PrimitiveType Dims_opt ')' UnaryExpression
501                 { write_exp_elt_opcode (UNOP_CAST);
502                   write_exp_elt_type (java_array_type ($2, $3));
503                   write_exp_elt_opcode (UNOP_CAST); }
504 |       '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
505 |       '(' Name Dims ')' UnaryExpressionNotPlusMinus
506                 { write_exp_elt_opcode (UNOP_CAST);
507                   write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
508                   write_exp_elt_opcode (UNOP_CAST); }
509 ;
510
511
512 MultiplicativeExpression:
513         UnaryExpression
514 |       MultiplicativeExpression '*' UnaryExpression
515                 { write_exp_elt_opcode (BINOP_MUL); }
516 |       MultiplicativeExpression '/' UnaryExpression
517                 { write_exp_elt_opcode (BINOP_DIV); }
518 |       MultiplicativeExpression '%' UnaryExpression
519                 { write_exp_elt_opcode (BINOP_REM); }
520 ;
521
522 AdditiveExpression:
523         MultiplicativeExpression
524 |       AdditiveExpression '+' MultiplicativeExpression
525                 { write_exp_elt_opcode (BINOP_ADD); }
526 |       AdditiveExpression '-' MultiplicativeExpression
527                 { write_exp_elt_opcode (BINOP_SUB); }
528 ;
529
530 ShiftExpression:
531         AdditiveExpression
532 |       ShiftExpression LSH AdditiveExpression
533                 { write_exp_elt_opcode (BINOP_LSH); }
534 |       ShiftExpression RSH AdditiveExpression
535                 { write_exp_elt_opcode (BINOP_RSH); }
536 /* |    ShiftExpression >>> AdditiveExpression { FIXME } */
537 ;
538
539 RelationalExpression:
540         ShiftExpression
541 |       RelationalExpression '<' ShiftExpression
542                 { write_exp_elt_opcode (BINOP_LESS); }
543 |       RelationalExpression '>' ShiftExpression
544                 { write_exp_elt_opcode (BINOP_GTR); }
545 |       RelationalExpression LEQ ShiftExpression
546                 { write_exp_elt_opcode (BINOP_LEQ); }
547 |       RelationalExpression GEQ ShiftExpression
548                 { write_exp_elt_opcode (BINOP_GEQ); }
549 /* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
550 ;
551
552 EqualityExpression:
553         RelationalExpression
554 |       EqualityExpression EQUAL RelationalExpression
555                 { write_exp_elt_opcode (BINOP_EQUAL); }
556 |       EqualityExpression NOTEQUAL RelationalExpression
557                 { write_exp_elt_opcode (BINOP_NOTEQUAL); }
558 ;
559
560 AndExpression:
561         EqualityExpression
562 |       AndExpression '&' EqualityExpression
563                 { write_exp_elt_opcode (BINOP_BITWISE_AND); }
564 ;
565
566 ExclusiveOrExpression:
567         AndExpression
568 |       ExclusiveOrExpression '^' AndExpression
569                 { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
570 ;
571 InclusiveOrExpression:
572         ExclusiveOrExpression
573 |       InclusiveOrExpression '|' ExclusiveOrExpression
574                 { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
575 ;
576
577 ConditionalAndExpression:
578         InclusiveOrExpression
579 |       ConditionalAndExpression ANDAND InclusiveOrExpression
580                 { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
581 ;
582
583 ConditionalOrExpression:
584         ConditionalAndExpression
585 |       ConditionalOrExpression OROR ConditionalAndExpression
586                 { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
587 ;
588
589 ConditionalExpression:
590         ConditionalOrExpression
591 |       ConditionalOrExpression '?' Expression ':' ConditionalExpression
592                 { write_exp_elt_opcode (TERNOP_COND); }
593 ;
594
595 AssignmentExpression:
596         ConditionalExpression
597 |       Assignment
598 ;
599                           
600 Assignment:
601         LeftHandSide '=' ConditionalExpression
602                 { write_exp_elt_opcode (BINOP_ASSIGN); }
603 |       LeftHandSide ASSIGN_MODIFY ConditionalExpression
604                 { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
605                   write_exp_elt_opcode ($2);
606                   write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
607 ;
608
609 LeftHandSide:
610         ForcedName
611                 { push_variable ($1); }
612 |       VARIABLE
613                 /* Already written by write_dollar_variable. */
614 |       FieldAccess
615 |       ArrayAccess
616 ;
617
618
619 Expression:
620         AssignmentExpression
621 ;
622
623 %%
624 /* Take care of parsing a number (anything that starts with a digit).
625    Set yylval and return the token type; update lexptr.
626    LEN is the number of characters in it.  */
627
628 /*** Needs some error checking for the float case ***/
629
630 static int
631 parse_number (p, len, parsed_float, putithere)
632      register char *p;
633      register int len;
634      int parsed_float;
635      YYSTYPE *putithere;
636 {
637   register ULONGEST n = 0;
638   ULONGEST limit, limit_div_base;
639
640   register int c;
641   register int base = input_radix;
642
643   struct type *type;
644
645   if (parsed_float)
646     {
647       /* It's a float since it contains a point or an exponent.  */
648       char c;
649       int num = 0;      /* number of tokens scanned by scanf */
650       char saved_char = p[len];
651
652       p[len] = 0;       /* null-terminate the token */
653       if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
654         num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
655       else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
656         num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
657       else
658         {
659 #ifdef PRINTF_HAS_LONG_DOUBLE
660           num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
661 #else
662           /* Scan it into a double, then assign it to the long double.
663              This at least wins with values representable in the range
664              of doubles. */
665           double temp;
666           num = sscanf (p, "%lg%c", &temp, &c);
667           putithere->typed_val_float.dval = temp;
668 #endif
669         }
670       p[len] = saved_char;      /* restore the input stream */
671       if (num != 1)             /* check scanf found ONLY a float ... */
672         return ERROR;
673       /* See if it has `f' or `d' suffix (float or double).  */
674
675       c = tolower (p[len - 1]);
676
677       if (c == 'f' || c == 'F')
678         putithere->typed_val_float.type = builtin_type_float;
679       else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
680         putithere->typed_val_float.type = builtin_type_double;
681       else
682         return ERROR;
683
684       return FLOATING_POINT_LITERAL;
685 }
686
687   /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
688   if (p[0] == '0')
689     switch (p[1])
690       {
691       case 'x':
692       case 'X':
693         if (len >= 3)
694           {
695             p += 2;
696             base = 16;
697             len -= 2;
698           }
699         break;
700
701       case 't':
702       case 'T':
703       case 'd':
704       case 'D':
705         if (len >= 3)
706           {
707             p += 2;
708             base = 10;
709             len -= 2;
710           }
711         break;
712
713       default:
714         base = 8;
715         break;
716       }
717
718   c = p[len-1];
719   limit = (ULONGEST)0xffffffff;
720   if (c == 'l' || c == 'L')
721     {
722       type = java_long_type;
723       len--;
724       /* A paranoid calculation of (1<<64)-1. */
725       limit = ((limit << 16) << 16) | limit;
726     }
727   else
728     {
729       type = java_int_type;
730     }
731   limit_div_base = limit / (ULONGEST) base;
732
733   while (--len >= 0)
734     {
735       c = *p++;
736       if (c >= '0' && c <= '9')
737         c -= '0';
738       else
739         {
740           if (c >= 'A' && c <= 'Z')
741             c += 'a' - 'A';
742           if (c >= 'a' && c - 'a' + 10 < base)
743             c -= 'a' + 10;
744           else
745             return ERROR;       /* Char not a digit */
746         }
747       if (c >= base)
748         return ERROR;
749       if (n > limit_div_base
750           || (n *= base) > limit - c)
751         error ("Numeric constant too large.");
752       n += c;
753         }
754
755    putithere->typed_val_int.val = n;
756    putithere->typed_val_int.type = type;
757    return INTEGER_LITERAL;
758 }
759
760 struct token
761 {
762   char *operator;
763   int token;
764   enum exp_opcode opcode;
765 };
766
767 static const struct token tokentab3[] =
768   {
769     {">>=", ASSIGN_MODIFY, BINOP_RSH},
770     {"<<=", ASSIGN_MODIFY, BINOP_LSH}
771   };
772
773 static const struct token tokentab2[] =
774   {
775     {"+=", ASSIGN_MODIFY, BINOP_ADD},
776     {"-=", ASSIGN_MODIFY, BINOP_SUB},
777     {"*=", ASSIGN_MODIFY, BINOP_MUL},
778     {"/=", ASSIGN_MODIFY, BINOP_DIV},
779     {"%=", ASSIGN_MODIFY, BINOP_REM},
780     {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
781     {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
782     {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
783     {"++", INCREMENT, BINOP_END},
784     {"--", DECREMENT, BINOP_END},
785     {"&&", ANDAND, BINOP_END},
786     {"||", OROR, BINOP_END},
787     {"<<", LSH, BINOP_END},
788     {">>", RSH, BINOP_END},
789     {"==", EQUAL, BINOP_END},
790     {"!=", NOTEQUAL, BINOP_END},
791     {"<=", LEQ, BINOP_END},
792     {">=", GEQ, BINOP_END}
793   };
794
795 /* Read one token, getting characters through lexptr.  */
796
797 static int
798 yylex ()
799 {
800   int c;
801   int namelen;
802   unsigned int i;
803   char *tokstart;
804   char *tokptr;
805   int tempbufindex;
806   static char *tempbuf;
807   static int tempbufsize;
808   
809  retry:
810
811   tokstart = lexptr;
812   /* See if it is a special token of length 3.  */
813   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
814     if (STREQN (tokstart, tokentab3[i].operator, 3))
815       {
816         lexptr += 3;
817         yylval.opcode = tokentab3[i].opcode;
818         return tokentab3[i].token;
819       }
820
821   /* See if it is a special token of length 2.  */
822   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
823     if (STREQN (tokstart, tokentab2[i].operator, 2))
824       {
825         lexptr += 2;
826         yylval.opcode = tokentab2[i].opcode;
827         return tokentab2[i].token;
828       }
829
830   switch (c = *tokstart)
831     {
832     case 0:
833       return 0;
834
835     case ' ':
836     case '\t':
837     case '\n':
838       lexptr++;
839       goto retry;
840
841     case '\'':
842       /* We either have a character constant ('0' or '\177' for example)
843          or we have a quoted symbol reference ('foo(int,int)' in C++
844          for example). */
845       lexptr++;
846       c = *lexptr++;
847       if (c == '\\')
848         c = parse_escape (&lexptr);
849       else if (c == '\'')
850         error ("Empty character constant.");
851
852       yylval.typed_val_int.val = c;
853       yylval.typed_val_int.type = builtin_type_char;
854
855       c = *lexptr++;
856       if (c != '\'')
857         {
858           namelen = skip_quoted (tokstart) - tokstart;
859           if (namelen > 2)
860             {
861               lexptr = tokstart + namelen;
862               if (lexptr[-1] != '\'')
863                 error ("Unmatched single quote.");
864               namelen -= 2;
865               tokstart++;
866               goto tryname;
867             }
868           error ("Invalid character constant.");
869         }
870       return INTEGER_LITERAL;
871
872     case '(':
873       paren_depth++;
874       lexptr++;
875       return c;
876
877     case ')':
878       if (paren_depth == 0)
879         return 0;
880       paren_depth--;
881       lexptr++;
882       return c;
883
884     case ',':
885       if (comma_terminates && paren_depth == 0)
886         return 0;
887       lexptr++;
888       return c;
889
890     case '.':
891       /* Might be a floating point number.  */
892       if (lexptr[1] < '0' || lexptr[1] > '9')
893         goto symbol;            /* Nope, must be a symbol. */
894       /* FALL THRU into number case.  */
895
896     case '0':
897     case '1':
898     case '2':
899     case '3':
900     case '4':
901     case '5':
902     case '6':
903     case '7':
904     case '8':
905     case '9':
906       {
907         /* It's a number.  */
908         int got_dot = 0, got_e = 0, toktype;
909         register char *p = tokstart;
910         int hex = input_radix > 10;
911
912         if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
913           {
914             p += 2;
915             hex = 1;
916           }
917         else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
918           {
919             p += 2;
920             hex = 0;
921           }
922
923         for (;; ++p)
924           {
925             /* This test includes !hex because 'e' is a valid hex digit
926                and thus does not indicate a floating point number when
927                the radix is hex.  */
928             if (!hex && !got_e && (*p == 'e' || *p == 'E'))
929               got_dot = got_e = 1;
930             /* This test does not include !hex, because a '.' always indicates
931                a decimal floating point number regardless of the radix.  */
932             else if (!got_dot && *p == '.')
933               got_dot = 1;
934             else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
935                      && (*p == '-' || *p == '+'))
936               /* This is the sign of the exponent, not the end of the
937                  number.  */
938               continue;
939             /* We will take any letters or digits.  parse_number will
940                complain if past the radix, or if L or U are not final.  */
941             else if ((*p < '0' || *p > '9')
942                      && ((*p < 'a' || *p > 'z')
943                                   && (*p < 'A' || *p > 'Z')))
944               break;
945           }
946         toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
947         if (toktype == ERROR)
948           {
949             char *err_copy = (char *) alloca (p - tokstart + 1);
950
951             memcpy (err_copy, tokstart, p - tokstart);
952             err_copy[p - tokstart] = 0;
953             error ("Invalid number \"%s\".", err_copy);
954           }
955         lexptr = p;
956         return toktype;
957       }
958
959     case '+':
960     case '-':
961     case '*':
962     case '/':
963     case '%':
964     case '|':
965     case '&':
966     case '^':
967     case '~':
968     case '!':
969     case '<':
970     case '>':
971     case '[':
972     case ']':
973     case '?':
974     case ':':
975     case '=':
976     case '{':
977     case '}':
978     symbol:
979       lexptr++;
980       return c;
981
982     case '"':
983
984       /* Build the gdb internal form of the input string in tempbuf,
985          translating any standard C escape forms seen.  Note that the
986          buffer is null byte terminated *only* for the convenience of
987          debugging gdb itself and printing the buffer contents when
988          the buffer contains no embedded nulls.  Gdb does not depend
989          upon the buffer being null byte terminated, it uses the length
990          string instead.  This allows gdb to handle C strings (as well
991          as strings in other languages) with embedded null bytes */
992
993       tokptr = ++tokstart;
994       tempbufindex = 0;
995
996       do {
997         /* Grow the static temp buffer if necessary, including allocating
998            the first one on demand. */
999         if (tempbufindex + 1 >= tempbufsize)
1000           {
1001             tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
1002           }
1003         switch (*tokptr)
1004           {
1005           case '\0':
1006           case '"':
1007             /* Do nothing, loop will terminate. */
1008             break;
1009           case '\\':
1010             tokptr++;
1011             c = parse_escape (&tokptr);
1012             if (c == -1)
1013               {
1014                 continue;
1015               }
1016             tempbuf[tempbufindex++] = c;
1017             break;
1018           default:
1019             tempbuf[tempbufindex++] = *tokptr++;
1020             break;
1021           }
1022       } while ((*tokptr != '"') && (*tokptr != '\0'));
1023       if (*tokptr++ != '"')
1024         {
1025           error ("Unterminated string in expression.");
1026         }
1027       tempbuf[tempbufindex] = '\0';     /* See note above */
1028       yylval.sval.ptr = tempbuf;
1029       yylval.sval.length = tempbufindex;
1030       lexptr = tokptr;
1031       return (STRING_LITERAL);
1032     }
1033
1034   if (!(c == '_' || c == '$'
1035         || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
1036     /* We must have come across a bad character (e.g. ';').  */
1037     error ("Invalid character '%c' in expression.", c);
1038
1039   /* It's a name.  See how long it is.  */
1040   namelen = 0;
1041   for (c = tokstart[namelen];
1042        (c == '_' || c == '$' || (c >= '0' && c <= '9')
1043         || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
1044     {
1045        if (c == '<')
1046          {
1047            int i = namelen;
1048            while (tokstart[++i] && tokstart[i] != '>');
1049            if (tokstart[i] == '>')
1050              namelen = i;
1051           }
1052        c = tokstart[++namelen];
1053      }
1054
1055   /* The token "if" terminates the expression and is NOT 
1056      removed from the input stream.  */
1057   if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
1058     {
1059       return 0;
1060     }
1061
1062   lexptr += namelen;
1063
1064   tryname:
1065
1066   /* Catch specific keywords.  Should be done with a data structure.  */
1067   switch (namelen)
1068     {
1069     case 7:
1070       if (STREQN (tokstart, "boolean", 7))
1071         return BOOLEAN;
1072       break;
1073     case 6:
1074       if (STREQN (tokstart, "double", 6))      
1075         return DOUBLE;
1076       break;
1077     case 5:
1078       if (STREQN (tokstart, "short", 5))
1079         return SHORT;
1080       if (STREQN (tokstart, "false", 5))
1081         {
1082           yylval.lval = 0;
1083           return BOOLEAN_LITERAL;
1084         }
1085       if (STREQN (tokstart, "super", 5))
1086         return SUPER;
1087       if (STREQN (tokstart, "float", 5))
1088         return FLOAT;
1089       break;
1090     case 4:
1091       if (STREQN (tokstart, "long", 4))
1092         return LONG;
1093       if (STREQN (tokstart, "byte", 4))
1094         return BYTE;
1095       if (STREQN (tokstart, "char", 4))
1096         return CHAR;
1097       if (STREQN (tokstart, "true", 4))
1098         {
1099           yylval.lval = 1;
1100           return BOOLEAN_LITERAL;
1101         }
1102       if (current_language->la_language == language_cplus
1103           && STREQN (tokstart, "this", 4))
1104         {
1105           static const char this_name[] =
1106                                  { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
1107
1108           if (lookup_symbol (this_name, expression_context_block,
1109                              VAR_NAMESPACE, (int *) NULL,
1110                              (struct symtab **) NULL))
1111             return THIS;
1112         }
1113       break;
1114     case 3:
1115       if (STREQN (tokstart, "int", 3))
1116         return INT;
1117       if (STREQN (tokstart, "new", 3))
1118         return NEW;
1119       break;
1120     default:
1121       break;
1122     }
1123
1124   yylval.sval.ptr = tokstart;
1125   yylval.sval.length = namelen;
1126
1127   if (*tokstart == '$')
1128     {
1129       write_dollar_variable (yylval.sval);
1130       return VARIABLE;
1131     }
1132
1133   /* Input names that aren't symbols but ARE valid hex numbers,
1134      when the input radix permits them, can be names or numbers
1135      depending on the parse.  Note we support radixes > 16 here.  */
1136   if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1137        (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1138     {
1139       YYSTYPE newlval;  /* Its value is ignored.  */
1140       int hextype = parse_number (tokstart, namelen, 0, &newlval);
1141       if (hextype == INTEGER_LITERAL)
1142         return NAME_OR_INT;
1143     }
1144   return IDENTIFIER;
1145 }
1146
1147 void
1148 yyerror (msg)
1149      char *msg;
1150 {
1151   error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
1152 }
1153
1154 static struct type *
1155 java_type_from_name (name)
1156      struct stoken name;
1157  
1158 {
1159   char *tmp = copy_name (name);
1160   struct type *typ = java_lookup_class (tmp);
1161   if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1162     error ("No class named %s.", tmp);
1163   return typ;
1164 }
1165
1166 static void
1167 push_variable (name)
1168      struct stoken name;
1169  
1170 {
1171   char *tmp = copy_name (name);
1172   int is_a_field_of_this = 0;
1173   struct symbol *sym;
1174   struct type *typ;
1175   sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
1176                        &is_a_field_of_this, (struct symtab **) NULL);
1177   if (sym)
1178     {
1179       if (symbol_read_needs_frame (sym))
1180         {
1181           if (innermost_block == 0 ||
1182               contained_in (block_found, innermost_block))
1183             innermost_block = block_found;
1184         }
1185
1186       write_exp_elt_opcode (OP_VAR_VALUE);
1187       /* We want to use the selected frame, not another more inner frame
1188          which happens to be in the same block.  */
1189       write_exp_elt_block (NULL);
1190       write_exp_elt_sym (sym);
1191       write_exp_elt_opcode (OP_VAR_VALUE);
1192       return;
1193     }
1194   if (is_a_field_of_this)
1195     {
1196       /* it hangs off of `this'.  Must not inadvertently convert from a
1197          method call to data ref.  */
1198       if (innermost_block == 0 || 
1199           contained_in (block_found, innermost_block))
1200         innermost_block = block_found;
1201       write_exp_elt_opcode (OP_THIS);
1202       write_exp_elt_opcode (OP_THIS);
1203       write_exp_elt_opcode (STRUCTOP_PTR);
1204       write_exp_string (name);
1205       write_exp_elt_opcode (STRUCTOP_PTR);
1206       return;
1207     }
1208
1209   typ = java_lookup_class (tmp);
1210   if (typ != NULL)
1211     {
1212       write_exp_elt_opcode(OP_TYPE);
1213       write_exp_elt_type(typ);
1214       write_exp_elt_opcode(OP_TYPE);
1215     }
1216   else
1217     {
1218       struct minimal_symbol *msymbol;
1219
1220       msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1221       if (msymbol != NULL)
1222         {
1223           write_exp_msymbol (msymbol,
1224                              lookup_function_type (builtin_type_int),
1225                              builtin_type_int);
1226         }
1227       else if (!have_full_symbols () && !have_partial_symbols ())
1228         error ("No symbol table is loaded.  Use the \"file\" command.");
1229       else
1230         error ("No symbol \"%s\" in current context.", tmp);
1231     }
1232
1233 }