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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [jv-exp.y] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* YACC parser for Java expressions, for GDB.
2
   Copyright 1997, 1998, 1999, 2000
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 Java 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.  Well, almost always; see ArrayAccess.
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 ( and  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 
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 yyparse (void);
103
 
104
static int yylex (void);
105
 
106
void yyerror (char *);
107
 
108
static struct type *java_type_from_name (struct stoken);
109
static void push_expression_name (struct stoken);
110
static void push_fieldnames (struct stoken);
111
 
112
static struct expression *copy_exp (struct expression *, int);
113
static void insert_exp (int, struct expression *);
114
 
115
%}
116
 
117
/* Although the yacc "value" of an expression is not used,
118
   since the result is stored in the structure being created,
119
   other node types do have values.  */
120
 
121
%union
122
  {
123
    LONGEST lval;
124
    struct {
125
      LONGEST val;
126
      struct type *type;
127
    } typed_val_int;
128
    struct {
129
      DOUBLEST dval;
130
      struct type *type;
131
    } typed_val_float;
132
    struct symbol *sym;
133
    struct type *tval;
134
    struct stoken sval;
135
    struct ttype tsym;
136
    struct symtoken ssym;
137
    struct block *bval;
138
    enum exp_opcode opcode;
139
    struct internalvar *ivar;
140
    int *ivec;
141
  }
142
 
143
%{
144
/* YYSTYPE gets defined by %union */
145
static int parse_number (char *, int, int, YYSTYPE *);
146
%}
147
 
148
%type  rcurly Dims Dims_opt
149
%type  ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
150
%type  IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
151
 
152
%token  INTEGER_LITERAL
153
%token  FLOATING_POINT_LITERAL
154
 
155
%token  IDENTIFIER
156
%token  STRING_LITERAL
157
%token  BOOLEAN_LITERAL
158
%token  TYPENAME
159
%type  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  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  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
 
197
%%
198
 
199
start   :       exp1
200
        |       type_exp
201
        ;
202
 
203
type_exp:       PrimitiveOrArrayType
204
                {
205
                  write_exp_elt_opcode(OP_TYPE);
206
                  write_exp_elt_type($1);
207
                  write_exp_elt_opcode(OP_TYPE);
208
                }
209
        ;
210
 
211
PrimitiveOrArrayType:
212
                PrimitiveType
213
        |       ArrayType
214
        ;
215
 
216
StringLiteral:
217
        STRING_LITERAL
218
                {
219
                  write_exp_elt_opcode (OP_STRING);
220
                  write_exp_string ($1);
221
                  write_exp_elt_opcode (OP_STRING);
222
                }
223
;
224
 
225
Literal:
226
        INTEGER_LITERAL
227
                { write_exp_elt_opcode (OP_LONG);
228
                  write_exp_elt_type ($1.type);
229
                  write_exp_elt_longcst ((LONGEST)($1.val));
230
                  write_exp_elt_opcode (OP_LONG); }
231
|       NAME_OR_INT
232
                { YYSTYPE val;
233
                  parse_number ($1.ptr, $1.length, 0, &val);
234
                  write_exp_elt_opcode (OP_LONG);
235
                  write_exp_elt_type (val.typed_val_int.type);
236
                  write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
237
                  write_exp_elt_opcode (OP_LONG);
238
                }
239
|       FLOATING_POINT_LITERAL
240
                { write_exp_elt_opcode (OP_DOUBLE);
241
                  write_exp_elt_type ($1.type);
242
                  write_exp_elt_dblcst ($1.dval);
243
                  write_exp_elt_opcode (OP_DOUBLE); }
244
|       BOOLEAN_LITERAL
245
                { write_exp_elt_opcode (OP_LONG);
246
                  write_exp_elt_type (java_boolean_type);
247
                  write_exp_elt_longcst ((LONGEST)$1);
248
                  write_exp_elt_opcode (OP_LONG); }
249
|       StringLiteral
250
        ;
251
 
252
/* UNUSED:
253
Type:
254
        PrimitiveType
255
|       ReferenceType
256
;
257
*/
258
 
259
PrimitiveType:
260
        NumericType
261
|       BOOLEAN
262
                { $$ = java_boolean_type; }
263
;
264
 
265
NumericType:
266
        IntegralType
267
|       FloatingPointType
268
;
269
 
270
IntegralType:
271
        BYTE
272
                { $$ = java_byte_type; }
273
|       SHORT
274
                { $$ = java_short_type; }
275
|       INT
276
                { $$ = java_int_type; }
277
|       LONG
278
                { $$ = java_long_type; }
279
|       CHAR
280
                { $$ = java_char_type; }
281
;
282
 
283
FloatingPointType:
284
        FLOAT
285
                { $$ = java_float_type; }
286
|       DOUBLE
287
                { $$ = java_double_type; }
288
;
289
 
290
/* UNUSED:
291
ReferenceType:
292
        ClassOrInterfaceType
293
|       ArrayType
294
;
295
*/
296
 
297
ClassOrInterfaceType:
298
        Name
299
                { $$ = java_type_from_name ($1); }
300
;
301
 
302
ClassType:
303
        ClassOrInterfaceType
304
;
305
 
306
ArrayType:
307
        PrimitiveType Dims
308
                { $$ = java_array_type ($1, $2); }
309
|       Name Dims
310
                { $$ = java_array_type (java_type_from_name ($1), $2); }
311
;
312
 
313
Name:
314
        IDENTIFIER
315
|       QualifiedName
316
;
317
 
318
ForcedName:
319
        SimpleName
320
|       QualifiedName
321
;
322
 
323
SimpleName:
324
        IDENTIFIER
325
|       NAME_OR_INT
326
;
327
 
328
QualifiedName:
329
        Name '.' SimpleName
330
                { $$.length = $1.length + $3.length + 1;
331
                  if ($1.ptr + $1.length + 1 == $3.ptr
332
                      && $1.ptr[$1.length] == '.')
333
                    $$.ptr = $1.ptr;  /* Optimization. */
334
                  else
335
                    {
336
                      $$.ptr = (char *) malloc ($$.length + 1);
337
                      make_cleanup (free, $$.ptr);
338
                      sprintf ($$.ptr, "%.*s.%.*s",
339
                               $1.length, $1.ptr, $3.length, $3.ptr);
340
                } }
341
;
342
 
343
/*
344
type_exp:       type
345
                        { write_exp_elt_opcode(OP_TYPE);
346
                          write_exp_elt_type($1);
347
                          write_exp_elt_opcode(OP_TYPE);}
348
        ;
349
        */
350
 
351
/* Expressions, including the comma operator.  */
352
exp1    :       Expression
353
        |       exp1 ',' Expression
354
                        { write_exp_elt_opcode (BINOP_COMMA); }
355
        ;
356
 
357
Primary:
358
        PrimaryNoNewArray
359
|       ArrayCreationExpression
360
;
361
 
362
PrimaryNoNewArray:
363
        Literal
364
|       THIS
365
                { write_exp_elt_opcode (OP_THIS);
366
                  write_exp_elt_opcode (OP_THIS); }
367
|       '(' Expression ')'
368
|       ClassInstanceCreationExpression
369
|       FieldAccess
370
|       MethodInvocation
371
|       ArrayAccess
372
|       lcurly ArgumentList rcurly
373
                { write_exp_elt_opcode (OP_ARRAY);
374
                  write_exp_elt_longcst ((LONGEST) 0);
375
                  write_exp_elt_longcst ((LONGEST) $3);
376
                  write_exp_elt_opcode (OP_ARRAY); }
377
;
378
 
379
lcurly:
380
        '{'
381
                { start_arglist (); }
382
;
383
 
384
rcurly:
385
        '}'
386
                { $$ = end_arglist () - 1; }
387
;
388
 
389
ClassInstanceCreationExpression:
390
        NEW ClassType '(' ArgumentList_opt ')'
391
                { error ("FIXME - ClassInstanceCreationExpression"); }
392
;
393
 
394
ArgumentList:
395
        Expression
396
                { arglist_len = 1; }
397
|       ArgumentList ',' Expression
398
                { arglist_len++; }
399
;
400
 
401
ArgumentList_opt:
402
        /* EMPTY */
403
                { arglist_len = 0; }
404
| ArgumentList
405
;
406
 
407
ArrayCreationExpression:
408
        NEW PrimitiveType DimExprs Dims_opt
409
                { error ("FIXME - ArrayCreatiionExpression"); }
410
|       NEW ClassOrInterfaceType DimExprs Dims_opt
411
                { error ("FIXME - ArrayCreatiionExpression"); }
412
;
413
 
414
DimExprs:
415
        DimExpr
416
|       DimExprs DimExpr
417
;
418
 
419
DimExpr:
420
        '[' Expression ']'
421
;
422
 
423
Dims:
424
        '[' ']'
425
                { $$ = 1; }
426
|       Dims '[' ']'
427
        { $$ = $1 + 1; }
428
;
429
 
430
Dims_opt:
431
        Dims
432
|       /* EMPTY */
433
                { $$ = 0; }
434
;
435
 
436
FieldAccess:
437
        Primary '.' SimpleName
438
                { push_fieldnames ($3); }
439
|       VARIABLE '.' SimpleName
440
                { push_fieldnames ($3); }
441
/*|     SUPER '.' SimpleName { FIXME } */
442
;
443
 
444
MethodInvocation:
445
        Name '(' ArgumentList_opt ')'
446
                { error ("method invocation not implemented"); }
447
|       Primary '.' SimpleName '(' ArgumentList_opt ')'
448
                { error ("method invocation not implemented"); }
449
|       SUPER '.' SimpleName '(' ArgumentList_opt ')'
450
                { error ("method invocation not implemented"); }
451
;
452
 
453
ArrayAccess:
454
        Name '[' Expression ']'
455
                {
456
                  /* Emit code for the Name now, then exchange it in the
457
                     expout array with the Expression's code.  We could
458
                     introduce a OP_SWAP code or a reversed version of
459
                     BINOP_SUBSCRIPT, but that makes the rest of GDB pay
460
                     for our parsing kludges.  */
461
                  struct expression *name_expr;
462
 
463
                  push_expression_name ($1);
464
                  name_expr = copy_exp (expout, expout_ptr);
465
                  expout_ptr -= name_expr->nelts;
466
                  insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
467
                              name_expr);
468
                  free (name_expr);
469
                  write_exp_elt_opcode (BINOP_SUBSCRIPT);
470
                }
471
|       VARIABLE '[' Expression ']'
472
                { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
473
|       PrimaryNoNewArray '[' Expression ']'
474
                { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
475
;
476
 
477
PostfixExpression:
478
        Primary
479
|       Name
480
                { push_expression_name ($1); }
481
|       VARIABLE
482
                /* Already written by write_dollar_variable. */
483
|       PostIncrementExpression
484
|       PostDecrementExpression
485
;
486
 
487
PostIncrementExpression:
488
        PostfixExpression INCREMENT
489
                { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
490
;
491
 
492
PostDecrementExpression:
493
        PostfixExpression DECREMENT
494
                { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
495
;
496
 
497
UnaryExpression:
498
        PreIncrementExpression
499
|       PreDecrementExpression
500
|       '+' UnaryExpression
501
|       '-' UnaryExpression
502
                { write_exp_elt_opcode (UNOP_NEG); }
503
|       '*' UnaryExpression
504
                { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java  */
505
|       UnaryExpressionNotPlusMinus
506
;
507
 
508
PreIncrementExpression:
509
        INCREMENT UnaryExpression
510
                { write_exp_elt_opcode (UNOP_PREINCREMENT); }
511
;
512
 
513
PreDecrementExpression:
514
        DECREMENT UnaryExpression
515
                { write_exp_elt_opcode (UNOP_PREDECREMENT); }
516
;
517
 
518
UnaryExpressionNotPlusMinus:
519
        PostfixExpression
520
|       '~' UnaryExpression
521
                { write_exp_elt_opcode (UNOP_COMPLEMENT); }
522
|       '!' UnaryExpression
523
                { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
524
|       CastExpression
525
        ;
526
 
527
CastExpression:
528
        '(' PrimitiveType Dims_opt ')' UnaryExpression
529
                { write_exp_elt_opcode (UNOP_CAST);
530
                  write_exp_elt_type (java_array_type ($2, $3));
531
                  write_exp_elt_opcode (UNOP_CAST); }
532
|       '(' Expression ')' UnaryExpressionNotPlusMinus
533
                {
534
                  int exp_size = expout_ptr;
535
                  int last_exp_size = length_of_subexp(expout, expout_ptr);
536
                  struct type *type;
537
                  int i;
538
                  int base = expout_ptr - last_exp_size - 3;
539
                  if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
540
                    error ("invalid cast expression");
541
                  type = expout->elts[base+1].type;
542
                  /* Remove the 'Expression' and slide the
543
                     UnaryExpressionNotPlusMinus down to replace it. */
544
                  for (i = 0;  i < last_exp_size;  i++)
545
                    expout->elts[base + i] = expout->elts[base + i + 3];
546
                  expout_ptr -= 3;
547
                  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
548
                    type = lookup_pointer_type (type);
549
                  write_exp_elt_opcode (UNOP_CAST);
550
                  write_exp_elt_type (type);
551
                  write_exp_elt_opcode (UNOP_CAST);
552
                }
553
|       '(' Name Dims ')' UnaryExpressionNotPlusMinus
554
                { write_exp_elt_opcode (UNOP_CAST);
555
                  write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
556
                  write_exp_elt_opcode (UNOP_CAST); }
557
;
558
 
559
 
560
MultiplicativeExpression:
561
        UnaryExpression
562
|       MultiplicativeExpression '*' UnaryExpression
563
                { write_exp_elt_opcode (BINOP_MUL); }
564
|       MultiplicativeExpression '/' UnaryExpression
565
                { write_exp_elt_opcode (BINOP_DIV); }
566
|       MultiplicativeExpression '%' UnaryExpression
567
                { write_exp_elt_opcode (BINOP_REM); }
568
;
569
 
570
AdditiveExpression:
571
        MultiplicativeExpression
572
|       AdditiveExpression '+' MultiplicativeExpression
573
                { write_exp_elt_opcode (BINOP_ADD); }
574
|       AdditiveExpression '-' MultiplicativeExpression
575
                { write_exp_elt_opcode (BINOP_SUB); }
576
;
577
 
578
ShiftExpression:
579
        AdditiveExpression
580
|       ShiftExpression LSH AdditiveExpression
581
                { write_exp_elt_opcode (BINOP_LSH); }
582
|       ShiftExpression RSH AdditiveExpression
583
                { write_exp_elt_opcode (BINOP_RSH); }
584
/* |    ShiftExpression >>> AdditiveExpression { FIXME } */
585
;
586
 
587
RelationalExpression:
588
        ShiftExpression
589
|       RelationalExpression '<' ShiftExpression
590
                { write_exp_elt_opcode (BINOP_LESS); }
591
|       RelationalExpression '>' ShiftExpression
592
                { write_exp_elt_opcode (BINOP_GTR); }
593
|       RelationalExpression LEQ ShiftExpression
594
                { write_exp_elt_opcode (BINOP_LEQ); }
595
|       RelationalExpression GEQ ShiftExpression
596
                { write_exp_elt_opcode (BINOP_GEQ); }
597
/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
598
;
599
 
600
EqualityExpression:
601
        RelationalExpression
602
|       EqualityExpression EQUAL RelationalExpression
603
                { write_exp_elt_opcode (BINOP_EQUAL); }
604
|       EqualityExpression NOTEQUAL RelationalExpression
605
                { write_exp_elt_opcode (BINOP_NOTEQUAL); }
606
;
607
 
608
AndExpression:
609
        EqualityExpression
610
|       AndExpression '&' EqualityExpression
611
                { write_exp_elt_opcode (BINOP_BITWISE_AND); }
612
;
613
 
614
ExclusiveOrExpression:
615
        AndExpression
616
|       ExclusiveOrExpression '^' AndExpression
617
                { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
618
;
619
InclusiveOrExpression:
620
        ExclusiveOrExpression
621
|       InclusiveOrExpression '|' ExclusiveOrExpression
622
                { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
623
;
624
 
625
ConditionalAndExpression:
626
        InclusiveOrExpression
627
|       ConditionalAndExpression ANDAND InclusiveOrExpression
628
                { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
629
;
630
 
631
ConditionalOrExpression:
632
        ConditionalAndExpression
633
|       ConditionalOrExpression OROR ConditionalAndExpression
634
                { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
635
;
636
 
637
ConditionalExpression:
638
        ConditionalOrExpression
639
|       ConditionalOrExpression '?' Expression ':' ConditionalExpression
640
                { write_exp_elt_opcode (TERNOP_COND); }
641
;
642
 
643
AssignmentExpression:
644
        ConditionalExpression
645
|       Assignment
646
;
647
 
648
Assignment:
649
        LeftHandSide '=' ConditionalExpression
650
                { write_exp_elt_opcode (BINOP_ASSIGN); }
651
|       LeftHandSide ASSIGN_MODIFY ConditionalExpression
652
                { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
653
                  write_exp_elt_opcode ($2);
654
                  write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
655
;
656
 
657
LeftHandSide:
658
        ForcedName
659
                { push_expression_name ($1); }
660
|       VARIABLE
661
                /* Already written by write_dollar_variable. */
662
|       FieldAccess
663
|       ArrayAccess
664
;
665
 
666
 
667
Expression:
668
        AssignmentExpression
669
;
670
 
671
%%
672
/* Take care of parsing a number (anything that starts with a digit).
673
   Set yylval and return the token type; update lexptr.
674
   LEN is the number of characters in it.  */
675
 
676
/*** Needs some error checking for the float case ***/
677
 
678
static int
679
parse_number (p, len, parsed_float, putithere)
680
     register char *p;
681
     register int len;
682
     int parsed_float;
683
     YYSTYPE *putithere;
684
{
685
  register ULONGEST n = 0;
686
  ULONGEST limit, limit_div_base;
687
 
688
  register int c;
689
  register int base = input_radix;
690
 
691
  struct type *type;
692
 
693
  if (parsed_float)
694
    {
695
      /* It's a float since it contains a point or an exponent.  */
696
      char c;
697
      int num = 0;      /* number of tokens scanned by scanf */
698
      char saved_char = p[len];
699
 
700
      p[len] = 0;       /* null-terminate the token */
701
      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
702
        num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval, &c);
703
      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
704
        num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval, &c);
705
      else
706
        {
707
#ifdef SCANF_HAS_LONG_DOUBLE
708
          num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval, &c);
709
#else
710
          /* Scan it into a double, then assign it to the long double.
711
             This at least wins with values representable in the range
712
             of doubles. */
713
          double temp;
714
          num = sscanf (p, "%lg%c", &temp, &c);
715
          putithere->typed_val_float.dval = temp;
716
#endif
717
        }
718
      p[len] = saved_char;      /* restore the input stream */
719
      if (num != 1)             /* check scanf found ONLY a float ... */
720
        return ERROR;
721
      /* See if it has `f' or `d' suffix (float or double).  */
722
 
723
      c = tolower (p[len - 1]);
724
 
725
      if (c == 'f' || c == 'F')
726
        putithere->typed_val_float.type = builtin_type_float;
727
      else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
728
        putithere->typed_val_float.type = builtin_type_double;
729
      else
730
        return ERROR;
731
 
732
      return FLOATING_POINT_LITERAL;
733
    }
734
 
735
  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
736
  if (p[0] == '0')
737
    switch (p[1])
738
      {
739
      case 'x':
740
      case 'X':
741
        if (len >= 3)
742
          {
743
            p += 2;
744
            base = 16;
745
            len -= 2;
746
          }
747
        break;
748
 
749
      case 't':
750
      case 'T':
751
      case 'd':
752
      case 'D':
753
        if (len >= 3)
754
          {
755
            p += 2;
756
            base = 10;
757
            len -= 2;
758
          }
759
        break;
760
 
761
      default:
762
        base = 8;
763
        break;
764
      }
765
 
766
  c = p[len-1];
767
  limit = (ULONGEST)0xffffffff;
768
  if (c == 'l' || c == 'L')
769
    {
770
      type = java_long_type;
771
      len--;
772
      /* A paranoid calculation of (1<<64)-1. */
773
      limit = ((limit << 16) << 16) | limit;
774
    }
775
  else
776
    {
777
      type = java_int_type;
778
    }
779
  limit_div_base = limit / (ULONGEST) base;
780
 
781
  while (--len >= 0)
782
    {
783
      c = *p++;
784
      if (c >= '0' && c <= '9')
785
        c -= '0';
786
      else if (c >= 'A' && c <= 'Z')
787
        c -= 'A' - 10;
788
      else if (c >= 'a' && c <= 'z')
789
        c -= 'a' - 10;
790
      else
791
        return ERROR;   /* Char not a digit */
792
      if (c >= base)
793
        return ERROR;
794
      if (n > limit_div_base
795
          || (n *= base) > limit - c)
796
        error ("Numeric constant too large.");
797
      n += c;
798
        }
799
 
800
   putithere->typed_val_int.val = n;
801
   putithere->typed_val_int.type = type;
802
   return INTEGER_LITERAL;
803
}
804
 
805
struct token
806
{
807
  char *operator;
808
  int token;
809
  enum exp_opcode opcode;
810
};
811
 
812
static const struct token tokentab3[] =
813
  {
814
    {">>=", ASSIGN_MODIFY, BINOP_RSH},
815
    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
816
  };
817
 
818
static const struct token tokentab2[] =
819
  {
820
    {"+=", ASSIGN_MODIFY, BINOP_ADD},
821
    {"-=", ASSIGN_MODIFY, BINOP_SUB},
822
    {"*=", ASSIGN_MODIFY, BINOP_MUL},
823
    {"/=", ASSIGN_MODIFY, BINOP_DIV},
824
    {"%=", ASSIGN_MODIFY, BINOP_REM},
825
    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
826
    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
827
    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
828
    {"++", INCREMENT, BINOP_END},
829
    {"--", DECREMENT, BINOP_END},
830
    {"&&", ANDAND, BINOP_END},
831
    {"||", OROR, BINOP_END},
832
    {"<<", LSH, BINOP_END},
833
    {">>", RSH, BINOP_END},
834
    {"==", EQUAL, BINOP_END},
835
    {"!=", NOTEQUAL, BINOP_END},
836
    {"<=", LEQ, BINOP_END},
837
    {">=", GEQ, BINOP_END}
838
  };
839
 
840
/* Read one token, getting characters through lexptr.  */
841
 
842
static int
843
yylex ()
844
{
845
  int c;
846
  int namelen;
847
  unsigned int i;
848
  char *tokstart;
849
  char *tokptr;
850
  int tempbufindex;
851
  static char *tempbuf;
852
  static int tempbufsize;
853
 
854
 retry:
855
 
856
  tokstart = lexptr;
857
  /* See if it is a special token of length 3.  */
858
  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
859
    if (STREQN (tokstart, tokentab3[i].operator, 3))
860
      {
861
        lexptr += 3;
862
        yylval.opcode = tokentab3[i].opcode;
863
        return tokentab3[i].token;
864
      }
865
 
866
  /* See if it is a special token of length 2.  */
867
  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
868
    if (STREQN (tokstart, tokentab2[i].operator, 2))
869
      {
870
        lexptr += 2;
871
        yylval.opcode = tokentab2[i].opcode;
872
        return tokentab2[i].token;
873
      }
874
 
875
  switch (c = *tokstart)
876
    {
877
    case 0:
878
      return 0;
879
 
880
    case ' ':
881
    case '\t':
882
    case '\n':
883
      lexptr++;
884
      goto retry;
885
 
886
    case '\'':
887
      /* We either have a character constant ('0' or '\177' for example)
888
         or we have a quoted symbol reference ('foo(int,int)' in C++
889
         for example). */
890
      lexptr++;
891
      c = *lexptr++;
892
      if (c == '\\')
893
        c = parse_escape (&lexptr);
894
      else if (c == '\'')
895
        error ("Empty character constant.");
896
 
897
      yylval.typed_val_int.val = c;
898
      yylval.typed_val_int.type = java_char_type;
899
 
900
      c = *lexptr++;
901
      if (c != '\'')
902
        {
903
          namelen = skip_quoted (tokstart) - tokstart;
904
          if (namelen > 2)
905
            {
906
              lexptr = tokstart + namelen;
907
              if (lexptr[-1] != '\'')
908
                error ("Unmatched single quote.");
909
              namelen -= 2;
910
              tokstart++;
911
              goto tryname;
912
            }
913
          error ("Invalid character constant.");
914
        }
915
      return INTEGER_LITERAL;
916
 
917
    case '(':
918
      paren_depth++;
919
      lexptr++;
920
      return c;
921
 
922
    case ')':
923
      if (paren_depth == 0)
924
        return 0;
925
      paren_depth--;
926
      lexptr++;
927
      return c;
928
 
929
    case ',':
930
      if (comma_terminates && paren_depth == 0)
931
        return 0;
932
      lexptr++;
933
      return c;
934
 
935
    case '.':
936
      /* Might be a floating point number.  */
937
      if (lexptr[1] < '0' || lexptr[1] > '9')
938
        goto symbol;            /* Nope, must be a symbol. */
939
      /* FALL THRU into number case.  */
940
 
941
    case '0':
942
    case '1':
943
    case '2':
944
    case '3':
945
    case '4':
946
    case '5':
947
    case '6':
948
    case '7':
949
    case '8':
950
    case '9':
951
      {
952
        /* It's a number.  */
953
        int got_dot = 0, got_e = 0, toktype;
954
        register char *p = tokstart;
955
        int hex = input_radix > 10;
956
 
957
        if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
958
          {
959
            p += 2;
960
            hex = 1;
961
          }
962
        else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
963
          {
964
            p += 2;
965
            hex = 0;
966
          }
967
 
968
        for (;; ++p)
969
          {
970
            /* This test includes !hex because 'e' is a valid hex digit
971
               and thus does not indicate a floating point number when
972
               the radix is hex.  */
973
            if (!hex && !got_e && (*p == 'e' || *p == 'E'))
974
              got_dot = got_e = 1;
975
            /* This test does not include !hex, because a '.' always indicates
976
               a decimal floating point number regardless of the radix.  */
977
            else if (!got_dot && *p == '.')
978
              got_dot = 1;
979
            else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
980
                     && (*p == '-' || *p == '+'))
981
              /* This is the sign of the exponent, not the end of the
982
                 number.  */
983
              continue;
984
            /* We will take any letters or digits.  parse_number will
985
               complain if past the radix, or if L or U are not final.  */
986
            else if ((*p < '0' || *p > '9')
987
                     && ((*p < 'a' || *p > 'z')
988
                                  && (*p < 'A' || *p > 'Z')))
989
              break;
990
          }
991
        toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
992
        if (toktype == ERROR)
993
          {
994
            char *err_copy = (char *) alloca (p - tokstart + 1);
995
 
996
            memcpy (err_copy, tokstart, p - tokstart);
997
            err_copy[p - tokstart] = 0;
998
            error ("Invalid number \"%s\".", err_copy);
999
          }
1000
        lexptr = p;
1001
        return toktype;
1002
      }
1003
 
1004
    case '+':
1005
    case '-':
1006
    case '*':
1007
    case '/':
1008
    case '%':
1009
    case '|':
1010
    case '&':
1011
    case '^':
1012
    case '~':
1013
    case '!':
1014
    case '<':
1015
    case '>':
1016
    case '[':
1017
    case ']':
1018
    case '?':
1019
    case ':':
1020
    case '=':
1021
    case '{':
1022
    case '}':
1023
    symbol:
1024
      lexptr++;
1025
      return c;
1026
 
1027
    case '"':
1028
 
1029
      /* Build the gdb internal form of the input string in tempbuf,
1030
         translating any standard C escape forms seen.  Note that the
1031
         buffer is null byte terminated *only* for the convenience of
1032
         debugging gdb itself and printing the buffer contents when
1033
         the buffer contains no embedded nulls.  Gdb does not depend
1034
         upon the buffer being null byte terminated, it uses the length
1035
         string instead.  This allows gdb to handle C strings (as well
1036
         as strings in other languages) with embedded null bytes */
1037
 
1038
      tokptr = ++tokstart;
1039
      tempbufindex = 0;
1040
 
1041
      do {
1042
        /* Grow the static temp buffer if necessary, including allocating
1043
           the first one on demand. */
1044
        if (tempbufindex + 1 >= tempbufsize)
1045
          {
1046
            tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
1047
          }
1048
        switch (*tokptr)
1049
          {
1050
          case '\0':
1051
          case '"':
1052
            /* Do nothing, loop will terminate. */
1053
            break;
1054
          case '\\':
1055
            tokptr++;
1056
            c = parse_escape (&tokptr);
1057
            if (c == -1)
1058
              {
1059
                continue;
1060
              }
1061
            tempbuf[tempbufindex++] = c;
1062
            break;
1063
          default:
1064
            tempbuf[tempbufindex++] = *tokptr++;
1065
            break;
1066
          }
1067
      } while ((*tokptr != '"') && (*tokptr != '\0'));
1068
      if (*tokptr++ != '"')
1069
        {
1070
          error ("Unterminated string in expression.");
1071
        }
1072
      tempbuf[tempbufindex] = '\0';     /* See note above */
1073
      yylval.sval.ptr = tempbuf;
1074
      yylval.sval.length = tempbufindex;
1075
      lexptr = tokptr;
1076
      return (STRING_LITERAL);
1077
    }
1078
 
1079
  if (!(c == '_' || c == '$'
1080
        || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
1081
    /* We must have come across a bad character (e.g. ';').  */
1082
    error ("Invalid character '%c' in expression.", c);
1083
 
1084
  /* It's a name.  See how long it is.  */
1085
  namelen = 0;
1086
  for (c = tokstart[namelen];
1087
       (c == '_'
1088
        || c == '$'
1089
        || (c >= '0' && c <= '9')
1090
        || (c >= 'a' && c <= 'z')
1091
        || (c >= 'A' && c <= 'Z')
1092
        || c == '<');
1093
       )
1094
    {
1095
      if (c == '<')
1096
        {
1097
          int i = namelen;
1098
          while (tokstart[++i] && tokstart[i] != '>');
1099
          if (tokstart[i] == '>')
1100
            namelen = i;
1101
        }
1102
       c = tokstart[++namelen];
1103
     }
1104
 
1105
  /* The token "if" terminates the expression and is NOT
1106
     removed from the input stream.  */
1107
  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
1108
    {
1109
      return 0;
1110
    }
1111
 
1112
  lexptr += namelen;
1113
 
1114
  tryname:
1115
 
1116
  /* Catch specific keywords.  Should be done with a data structure.  */
1117
  switch (namelen)
1118
    {
1119
    case 7:
1120
      if (STREQN (tokstart, "boolean", 7))
1121
        return BOOLEAN;
1122
      break;
1123
    case 6:
1124
      if (STREQN (tokstart, "double", 6))
1125
        return DOUBLE;
1126
      break;
1127
    case 5:
1128
      if (STREQN (tokstart, "short", 5))
1129
        return SHORT;
1130
      if (STREQN (tokstart, "false", 5))
1131
        {
1132
          yylval.lval = 0;
1133
          return BOOLEAN_LITERAL;
1134
        }
1135
      if (STREQN (tokstart, "super", 5))
1136
        return SUPER;
1137
      if (STREQN (tokstart, "float", 5))
1138
        return FLOAT;
1139
      break;
1140
    case 4:
1141
      if (STREQN (tokstart, "long", 4))
1142
        return LONG;
1143
      if (STREQN (tokstart, "byte", 4))
1144
        return BYTE;
1145
      if (STREQN (tokstart, "char", 4))
1146
        return CHAR;
1147
      if (STREQN (tokstart, "true", 4))
1148
        {
1149
          yylval.lval = 1;
1150
          return BOOLEAN_LITERAL;
1151
        }
1152
      if (current_language->la_language == language_cplus
1153
          && STREQN (tokstart, "this", 4))
1154
        {
1155
          static const char this_name[] =
1156
                                 { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
1157
 
1158
          if (lookup_symbol (this_name, expression_context_block,
1159
                             VAR_NAMESPACE, (int *) NULL,
1160
                             (struct symtab **) NULL))
1161
            return THIS;
1162
        }
1163
      break;
1164
    case 3:
1165
      if (STREQN (tokstart, "int", 3))
1166
        return INT;
1167
      if (STREQN (tokstart, "new", 3))
1168
        return NEW;
1169
      break;
1170
    default:
1171
      break;
1172
    }
1173
 
1174
  yylval.sval.ptr = tokstart;
1175
  yylval.sval.length = namelen;
1176
 
1177
  if (*tokstart == '$')
1178
    {
1179
      write_dollar_variable (yylval.sval);
1180
      return VARIABLE;
1181
    }
1182
 
1183
  /* Input names that aren't symbols but ARE valid hex numbers,
1184
     when the input radix permits them, can be names or numbers
1185
     depending on the parse.  Note we support radixes > 16 here.  */
1186
  if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1187
       (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1188
    {
1189
      YYSTYPE newlval;  /* Its value is ignored.  */
1190
      int hextype = parse_number (tokstart, namelen, 0, &newlval);
1191
      if (hextype == INTEGER_LITERAL)
1192
        return NAME_OR_INT;
1193
    }
1194
  return IDENTIFIER;
1195
}
1196
 
1197
void
1198
yyerror (msg)
1199
     char *msg;
1200
{
1201
  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
1202
}
1203
 
1204
static struct type *
1205
java_type_from_name (name)
1206
     struct stoken name;
1207
 
1208
{
1209
  char *tmp = copy_name (name);
1210
  struct type *typ = java_lookup_class (tmp);
1211
  if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1212
    error ("No class named %s.", tmp);
1213
  return typ;
1214
}
1215
 
1216
/* If NAME is a valid variable name in this scope, push it and return 1.
1217
   Otherwise, return 0. */
1218
 
1219
static int
1220
push_variable (name)
1221
     struct stoken name;
1222
 
1223
{
1224
  char *tmp = copy_name (name);
1225
  int is_a_field_of_this = 0;
1226
  struct symbol *sym;
1227
  sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
1228
                       &is_a_field_of_this, (struct symtab **) NULL);
1229
  if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
1230
    {
1231
      if (symbol_read_needs_frame (sym))
1232
        {
1233
          if (innermost_block == 0 ||
1234
              contained_in (block_found, innermost_block))
1235
            innermost_block = block_found;
1236
        }
1237
 
1238
      write_exp_elt_opcode (OP_VAR_VALUE);
1239
      /* We want to use the selected frame, not another more inner frame
1240
         which happens to be in the same block.  */
1241
      write_exp_elt_block (NULL);
1242
      write_exp_elt_sym (sym);
1243
      write_exp_elt_opcode (OP_VAR_VALUE);
1244
      return 1;
1245
    }
1246
  if (is_a_field_of_this)
1247
    {
1248
      /* it hangs off of `this'.  Must not inadvertently convert from a
1249
         method call to data ref.  */
1250
      if (innermost_block == 0 ||
1251
          contained_in (block_found, innermost_block))
1252
        innermost_block = block_found;
1253
      write_exp_elt_opcode (OP_THIS);
1254
      write_exp_elt_opcode (OP_THIS);
1255
      write_exp_elt_opcode (STRUCTOP_PTR);
1256
      write_exp_string (name);
1257
      write_exp_elt_opcode (STRUCTOP_PTR);
1258
      return 1;
1259
    }
1260
  return 0;
1261
}
1262
 
1263
/* Assuming a reference expression has been pushed, emit the
1264
   STRUCTOP_STRUCT ops to access the field named NAME.  If NAME is a
1265
   qualified name (has '.'), generate a field access for each part. */
1266
 
1267
static void
1268
push_fieldnames (name)
1269
     struct stoken name;
1270
{
1271
  int i;
1272
  struct stoken token;
1273
  token.ptr = name.ptr;
1274
  for (i = 0;  ;  i++)
1275
    {
1276
      if (i == name.length || name.ptr[i] == '.')
1277
        {
1278
          /* token.ptr is start of current field name. */
1279
          token.length = &name.ptr[i] - token.ptr;
1280
          write_exp_elt_opcode (STRUCTOP_STRUCT);
1281
          write_exp_string (token);
1282
          write_exp_elt_opcode (STRUCTOP_STRUCT);
1283
          token.ptr += token.length + 1;
1284
        }
1285
      if (i >= name.length)
1286
        break;
1287
    }
1288
}
1289
 
1290
/* Helper routine for push_expression_name.
1291
   Handle a qualified name, where DOT_INDEX is the index of the first '.' */
1292
 
1293
static void
1294
push_qualified_expression_name (name, dot_index)
1295
     struct stoken name;
1296
     int dot_index;
1297
{
1298
  struct stoken token;
1299
  char *tmp;
1300
  struct type *typ;
1301
 
1302
  token.ptr = name.ptr;
1303
  token.length = dot_index;
1304
 
1305
  if (push_variable (token))
1306
    {
1307
      token.ptr = name.ptr + dot_index + 1;
1308
      token.length = name.length - dot_index - 1;
1309
      push_fieldnames (token);
1310
      return;
1311
    }
1312
 
1313
  token.ptr = name.ptr;
1314
  for (;;)
1315
    {
1316
      token.length = dot_index;
1317
      tmp = copy_name (token);
1318
      typ = java_lookup_class (tmp);
1319
      if (typ != NULL)
1320
        {
1321
          if (dot_index == name.length)
1322
            {
1323
              write_exp_elt_opcode(OP_TYPE);
1324
              write_exp_elt_type(typ);
1325
              write_exp_elt_opcode(OP_TYPE);
1326
              return;
1327
            }
1328
          dot_index++;  /* Skip '.' */
1329
          name.ptr += dot_index;
1330
          name.length -= dot_index;
1331
          dot_index = 0;
1332
          while (dot_index < name.length && name.ptr[dot_index] != '.')
1333
            dot_index++;
1334
          token.ptr = name.ptr;
1335
          token.length = dot_index;
1336
          write_exp_elt_opcode (OP_SCOPE);
1337
          write_exp_elt_type (typ);
1338
          write_exp_string (token);
1339
          write_exp_elt_opcode (OP_SCOPE);
1340
          if (dot_index < name.length)
1341
            {
1342
              dot_index++;
1343
              name.ptr += dot_index;
1344
              name.length -= dot_index;
1345
              push_fieldnames (name);
1346
            }
1347
          return;
1348
        }
1349
      else if (dot_index >= name.length)
1350
        break;
1351
      dot_index++;  /* Skip '.' */
1352
      while (dot_index < name.length && name.ptr[dot_index] != '.')
1353
        dot_index++;
1354
    }
1355
  error ("unknown type `%.*s'", name.length, name.ptr);
1356
}
1357
 
1358
/* Handle Name in an expression (or LHS).
1359
   Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
1360
 
1361
static void
1362
push_expression_name (name)
1363
     struct stoken name;
1364
{
1365
  char *tmp;
1366
  struct type *typ;
1367
  char *ptr;
1368
  int i;
1369
 
1370
  for (i = 0;  i < name.length;  i++)
1371
    {
1372
      if (name.ptr[i] == '.')
1373
        {
1374
          /* It's a Qualified Expression Name. */
1375
          push_qualified_expression_name (name, i);
1376
          return;
1377
        }
1378
    }
1379
 
1380
  /* It's a Simple Expression Name. */
1381
 
1382
  if (push_variable (name))
1383
    return;
1384
  tmp = copy_name (name);
1385
  typ = java_lookup_class (tmp);
1386
  if (typ != NULL)
1387
    {
1388
      write_exp_elt_opcode(OP_TYPE);
1389
      write_exp_elt_type(typ);
1390
      write_exp_elt_opcode(OP_TYPE);
1391
    }
1392
  else
1393
    {
1394
      struct minimal_symbol *msymbol;
1395
 
1396
      msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1397
      if (msymbol != NULL)
1398
        {
1399
          write_exp_msymbol (msymbol,
1400
                             lookup_function_type (builtin_type_int),
1401
                             builtin_type_int);
1402
        }
1403
      else if (!have_full_symbols () && !have_partial_symbols ())
1404
        error ("No symbol table is loaded.  Use the \"file\" command.");
1405
      else
1406
        error ("No symbol \"%s\" in current context.", tmp);
1407
    }
1408
 
1409
}
1410
 
1411
 
1412
/* The following two routines, copy_exp and insert_exp, aren't specific to
1413
   Java, so they could go in parse.c, but their only purpose is to support
1414
   the parsing kludges we use in this file, so maybe it's best to isolate
1415
   them here.  */
1416
 
1417
/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
1418
   into a freshly malloc'ed struct expression.  Its language_defn is set
1419
   to null.  */
1420
static struct expression *
1421
copy_exp (expr, endpos)
1422
     struct expression *expr;
1423
     int endpos;
1424
{
1425
  int len = length_of_subexp (expr, endpos);
1426
  struct expression *new
1427
    = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
1428
  new->nelts = len;
1429
  memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
1430
  new->language_defn = 0;
1431
 
1432
  return new;
1433
}
1434
 
1435
/* Insert the expression NEW into the current expression (expout) at POS.  */
1436
static void
1437
insert_exp (pos, new)
1438
     int pos;
1439
     struct expression *new;
1440
{
1441
  int newlen = new->nelts;
1442
 
1443
  /* Grow expout if necessary.  In this function's only use at present,
1444
     this should never be necessary.  */
1445
  if (expout_ptr + newlen > expout_size)
1446
    {
1447
      expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
1448
      expout = (struct expression *)
1449
        realloc ((char *) expout, (sizeof (struct expression)
1450
                                    + EXP_ELEM_TO_BYTES (expout_size)));
1451
    }
1452
 
1453
  {
1454
    int i;
1455
 
1456
    for (i = expout_ptr - 1; i >= pos; i--)
1457
      expout->elts[i + newlen] = expout->elts[i];
1458
  }
1459
 
1460
  memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
1461
  expout_ptr += newlen;
1462
}

powered by: WebSVN 2.1.0

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