OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [jv-exp.y] - Blame information for rev 277

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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