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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [jv-exp.y] - Blame information for rev 854

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

Line No. Rev Author Line
1 330 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 last_exp_size = length_of_subexp(expout, expout_ptr);
551
                  struct type *type;
552
                  int i;
553
                  int base = expout_ptr - last_exp_size - 3;
554
                  if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
555
                    error (_("Invalid cast expression"));
556
                  type = expout->elts[base+1].type;
557
                  /* Remove the 'Expression' and slide the
558
                     UnaryExpressionNotPlusMinus down to replace it. */
559
                  for (i = 0;  i < last_exp_size;  i++)
560
                    expout->elts[base + i] = expout->elts[base + i + 3];
561
                  expout_ptr -= 3;
562
                  if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
563
                    type = lookup_pointer_type (type);
564
                  write_exp_elt_opcode (UNOP_CAST);
565
                  write_exp_elt_type (type);
566
                  write_exp_elt_opcode (UNOP_CAST);
567
                }
568
|       '(' Name Dims ')' UnaryExpressionNotPlusMinus
569
                { write_exp_elt_opcode (UNOP_CAST);
570
                  write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
571
                  write_exp_elt_opcode (UNOP_CAST); }
572
;
573
 
574
 
575
MultiplicativeExpression:
576
        UnaryExpression
577
|       MultiplicativeExpression '*' UnaryExpression
578
                { write_exp_elt_opcode (BINOP_MUL); }
579
|       MultiplicativeExpression '/' UnaryExpression
580
                { write_exp_elt_opcode (BINOP_DIV); }
581
|       MultiplicativeExpression '%' UnaryExpression
582
                { write_exp_elt_opcode (BINOP_REM); }
583
;
584
 
585
AdditiveExpression:
586
        MultiplicativeExpression
587
|       AdditiveExpression '+' MultiplicativeExpression
588
                { write_exp_elt_opcode (BINOP_ADD); }
589
|       AdditiveExpression '-' MultiplicativeExpression
590
                { write_exp_elt_opcode (BINOP_SUB); }
591
;
592
 
593
ShiftExpression:
594
        AdditiveExpression
595
|       ShiftExpression LSH AdditiveExpression
596
                { write_exp_elt_opcode (BINOP_LSH); }
597
|       ShiftExpression RSH AdditiveExpression
598
                { write_exp_elt_opcode (BINOP_RSH); }
599
/* |    ShiftExpression >>> AdditiveExpression { FIXME } */
600
;
601
 
602
RelationalExpression:
603
        ShiftExpression
604
|       RelationalExpression '<' ShiftExpression
605
                { write_exp_elt_opcode (BINOP_LESS); }
606
|       RelationalExpression '>' ShiftExpression
607
                { write_exp_elt_opcode (BINOP_GTR); }
608
|       RelationalExpression LEQ ShiftExpression
609
                { write_exp_elt_opcode (BINOP_LEQ); }
610
|       RelationalExpression GEQ ShiftExpression
611
                { write_exp_elt_opcode (BINOP_GEQ); }
612
/* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
613
;
614
 
615
EqualityExpression:
616
        RelationalExpression
617
|       EqualityExpression EQUAL RelationalExpression
618
                { write_exp_elt_opcode (BINOP_EQUAL); }
619
|       EqualityExpression NOTEQUAL RelationalExpression
620
                { write_exp_elt_opcode (BINOP_NOTEQUAL); }
621
;
622
 
623
AndExpression:
624
        EqualityExpression
625
|       AndExpression '&' EqualityExpression
626
                { write_exp_elt_opcode (BINOP_BITWISE_AND); }
627
;
628
 
629
ExclusiveOrExpression:
630
        AndExpression
631
|       ExclusiveOrExpression '^' AndExpression
632
                { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
633
;
634
InclusiveOrExpression:
635
        ExclusiveOrExpression
636
|       InclusiveOrExpression '|' ExclusiveOrExpression
637
                { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
638
;
639
 
640
ConditionalAndExpression:
641
        InclusiveOrExpression
642
|       ConditionalAndExpression ANDAND InclusiveOrExpression
643
                { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
644
;
645
 
646
ConditionalOrExpression:
647
        ConditionalAndExpression
648
|       ConditionalOrExpression OROR ConditionalAndExpression
649
                { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
650
;
651
 
652
ConditionalExpression:
653
        ConditionalOrExpression
654
|       ConditionalOrExpression '?' Expression ':' ConditionalExpression
655
                { write_exp_elt_opcode (TERNOP_COND); }
656
;
657
 
658
AssignmentExpression:
659
        ConditionalExpression
660
|       Assignment
661
;
662
 
663
Assignment:
664
        LeftHandSide '=' ConditionalExpression
665
                { write_exp_elt_opcode (BINOP_ASSIGN); }
666
|       LeftHandSide ASSIGN_MODIFY ConditionalExpression
667
                { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
668
                  write_exp_elt_opcode ($2);
669
                  write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
670
;
671
 
672
LeftHandSide:
673
        ForcedName
674
                { push_expression_name ($1); }
675
|       VARIABLE
676
                /* Already written by write_dollar_variable. */
677
|       FieldAccess
678
|       ArrayAccess
679
;
680
 
681
 
682
Expression:
683
        AssignmentExpression
684
;
685
 
686
%%
687
/* Take care of parsing a number (anything that starts with a digit).
688
   Set yylval and return the token type; update lexptr.
689
   LEN is the number of characters in it.  */
690
 
691
/*** Needs some error checking for the float case ***/
692
 
693
static int
694
parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
695
{
696
  ULONGEST n = 0;
697
  ULONGEST limit, limit_div_base;
698
 
699
  int c;
700
  int base = input_radix;
701
 
702
  struct type *type;
703
 
704
  if (parsed_float)
705
    {
706
      /* It's a float since it contains a point or an exponent.  */
707
      char c;
708
      int num = 0;      /* number of tokens scanned by scanf */
709
      char saved_char = p[len];
710
 
711
      p[len] = 0;       /* null-terminate the token */
712
      num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
713
                    &putithere->typed_val_float.dval, &c);
714
      p[len] = saved_char;      /* restore the input stream */
715
      if (num != 1)             /* check scanf found ONLY a float ... */
716
        return ERROR;
717
      /* See if it has `f' or `d' suffix (float or double).  */
718
 
719
      c = tolower (p[len - 1]);
720
 
721
      if (c == 'f' || c == 'F')
722
        putithere->typed_val_float.type = parse_type->builtin_float;
723
      else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
724
        putithere->typed_val_float.type = parse_type->builtin_double;
725
      else
726
        return ERROR;
727
 
728
      return FLOATING_POINT_LITERAL;
729
    }
730
 
731
  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
732
  if (p[0] == '0')
733
    switch (p[1])
734
      {
735
      case 'x':
736
      case 'X':
737
        if (len >= 3)
738
          {
739
            p += 2;
740
            base = 16;
741
            len -= 2;
742
          }
743
        break;
744
 
745
      case 't':
746
      case 'T':
747
      case 'd':
748
      case 'D':
749
        if (len >= 3)
750
          {
751
            p += 2;
752
            base = 10;
753
            len -= 2;
754
          }
755
        break;
756
 
757
      default:
758
        base = 8;
759
        break;
760
      }
761
 
762
  c = p[len-1];
763
  /* A paranoid calculation of (1<<64)-1. */
764
  limit = (ULONGEST)0xffffffff;
765
  limit = ((limit << 16) << 16) | limit;
766
  if (c == 'l' || c == 'L')
767
    {
768
      type = parse_java_type->builtin_long;
769
      len--;
770
    }
771
  else
772
    {
773
      type = parse_java_type->builtin_int;
774
    }
775
  limit_div_base = limit / (ULONGEST) base;
776
 
777
  while (--len >= 0)
778
    {
779
      c = *p++;
780
      if (c >= '0' && c <= '9')
781
        c -= '0';
782
      else if (c >= 'A' && c <= 'Z')
783
        c -= 'A' - 10;
784
      else if (c >= 'a' && c <= 'z')
785
        c -= 'a' - 10;
786
      else
787
        return ERROR;   /* Char not a digit */
788
      if (c >= base)
789
        return ERROR;
790
      if (n > limit_div_base
791
          || (n *= base) > limit - c)
792
        error (_("Numeric constant too large"));
793
      n += c;
794
        }
795
 
796
  /* If the type is bigger than a 32-bit signed integer can be, implicitly
797
     promote to long.  Java does not do this, so mark it as
798
     parse_type->builtin_uint64 rather than parse_java_type->builtin_long.
799
     0x80000000 will become -0x80000000 instead of 0x80000000L, because we
800
     don't know the sign at this point.  */
801
  if (type == parse_java_type->builtin_int && n > (ULONGEST)0x80000000)
802
    type = parse_type->builtin_uint64;
803
 
804
  putithere->typed_val_int.val = n;
805
  putithere->typed_val_int.type = type;
806
 
807
  return INTEGER_LITERAL;
808
}
809
 
810
struct token
811
{
812
  char *operator;
813
  int token;
814
  enum exp_opcode opcode;
815
};
816
 
817
static const struct token tokentab3[] =
818
  {
819
    {">>=", ASSIGN_MODIFY, BINOP_RSH},
820
    {"<<=", ASSIGN_MODIFY, BINOP_LSH}
821
  };
822
 
823
static const struct token tokentab2[] =
824
  {
825
    {"+=", ASSIGN_MODIFY, BINOP_ADD},
826
    {"-=", ASSIGN_MODIFY, BINOP_SUB},
827
    {"*=", ASSIGN_MODIFY, BINOP_MUL},
828
    {"/=", ASSIGN_MODIFY, BINOP_DIV},
829
    {"%=", ASSIGN_MODIFY, BINOP_REM},
830
    {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
831
    {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
832
    {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
833
    {"++", INCREMENT, BINOP_END},
834
    {"--", DECREMENT, BINOP_END},
835
    {"&&", ANDAND, BINOP_END},
836
    {"||", OROR, BINOP_END},
837
    {"<<", LSH, BINOP_END},
838
    {">>", RSH, BINOP_END},
839
    {"==", EQUAL, BINOP_END},
840
    {"!=", NOTEQUAL, BINOP_END},
841
    {"<=", LEQ, BINOP_END},
842
    {">=", GEQ, BINOP_END}
843
  };
844
 
845
/* Read one token, getting characters through lexptr.  */
846
 
847
static int
848
yylex (void)
849
{
850
  int c;
851
  int namelen;
852
  unsigned int i;
853
  char *tokstart;
854
  char *tokptr;
855
  int tempbufindex;
856
  static char *tempbuf;
857
  static int tempbufsize;
858
 
859
 retry:
860
 
861
  prev_lexptr = lexptr;
862
 
863
  tokstart = lexptr;
864
  /* See if it is a special token of length 3.  */
865
  for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
866
    if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
867
      {
868
        lexptr += 3;
869
        yylval.opcode = tokentab3[i].opcode;
870
        return tokentab3[i].token;
871
      }
872
 
873
  /* See if it is a special token of length 2.  */
874
  for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
875
    if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
876
      {
877
        lexptr += 2;
878
        yylval.opcode = tokentab2[i].opcode;
879
        return tokentab2[i].token;
880
      }
881
 
882
  switch (c = *tokstart)
883
    {
884
    case 0:
885
      return 0;
886
 
887
    case ' ':
888
    case '\t':
889
    case '\n':
890
      lexptr++;
891
      goto retry;
892
 
893
    case '\'':
894
      /* We either have a character constant ('0' or '\177' for example)
895
         or we have a quoted symbol reference ('foo(int,int)' in C++
896
         for example). */
897
      lexptr++;
898
      c = *lexptr++;
899
      if (c == '\\')
900
        c = parse_escape (parse_gdbarch, &lexptr);
901
      else if (c == '\'')
902
        error (_("Empty character constant"));
903
 
904
      yylval.typed_val_int.val = c;
905
      yylval.typed_val_int.type = parse_java_type->builtin_char;
906
 
907
      c = *lexptr++;
908
      if (c != '\'')
909
        {
910
          namelen = skip_quoted (tokstart) - tokstart;
911
          if (namelen > 2)
912
            {
913
              lexptr = tokstart + namelen;
914
              if (lexptr[-1] != '\'')
915
                error (_("Unmatched single quote"));
916
              namelen -= 2;
917
              tokstart++;
918
              goto tryname;
919
            }
920
          error (_("Invalid character constant"));
921
        }
922
      return INTEGER_LITERAL;
923
 
924
    case '(':
925
      paren_depth++;
926
      lexptr++;
927
      return c;
928
 
929
    case ')':
930
      if (paren_depth == 0)
931
        return 0;
932
      paren_depth--;
933
      lexptr++;
934
      return c;
935
 
936
    case ',':
937
      if (comma_terminates && paren_depth == 0)
938
        return 0;
939
      lexptr++;
940
      return c;
941
 
942
    case '.':
943
      /* Might be a floating point number.  */
944
      if (lexptr[1] < '0' || lexptr[1] > '9')
945
        goto symbol;            /* Nope, must be a symbol. */
946
      /* FALL THRU into number case.  */
947
 
948
    case '0':
949
    case '1':
950
    case '2':
951
    case '3':
952
    case '4':
953
    case '5':
954
    case '6':
955
    case '7':
956
    case '8':
957
    case '9':
958
      {
959
        /* It's a number.  */
960
        int got_dot = 0, got_e = 0, toktype;
961
        char *p = tokstart;
962
        int hex = input_radix > 10;
963
 
964
        if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
965
          {
966
            p += 2;
967
            hex = 1;
968
          }
969
        else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
970
          {
971
            p += 2;
972
            hex = 0;
973
          }
974
 
975
        for (;; ++p)
976
          {
977
            /* This test includes !hex because 'e' is a valid hex digit
978
               and thus does not indicate a floating point number when
979
               the radix is hex.  */
980
            if (!hex && !got_e && (*p == 'e' || *p == 'E'))
981
              got_dot = got_e = 1;
982
            /* This test does not include !hex, because a '.' always indicates
983
               a decimal floating point number regardless of the radix.  */
984
            else if (!got_dot && *p == '.')
985
              got_dot = 1;
986
            else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
987
                     && (*p == '-' || *p == '+'))
988
              /* This is the sign of the exponent, not the end of the
989
                 number.  */
990
              continue;
991
            /* We will take any letters or digits.  parse_number will
992
               complain if past the radix, or if L or U are not final.  */
993
            else if ((*p < '0' || *p > '9')
994
                     && ((*p < 'a' || *p > 'z')
995
                                  && (*p < 'A' || *p > 'Z')))
996
              break;
997
          }
998
        toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
999
        if (toktype == ERROR)
1000
          {
1001
            char *err_copy = (char *) alloca (p - tokstart + 1);
1002
 
1003
            memcpy (err_copy, tokstart, p - tokstart);
1004
            err_copy[p - tokstart] = 0;
1005
            error (_("Invalid number \"%s\""), err_copy);
1006
          }
1007
        lexptr = p;
1008
        return toktype;
1009
      }
1010
 
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
    case '[':
1024
    case ']':
1025
    case '?':
1026
    case ':':
1027
    case '=':
1028
    case '{':
1029
    case '}':
1030
    symbol:
1031
      lexptr++;
1032
      return c;
1033
 
1034
    case '"':
1035
 
1036
      /* Build the gdb internal form of the input string in tempbuf,
1037
         translating any standard C escape forms seen.  Note that the
1038
         buffer is null byte terminated *only* for the convenience of
1039
         debugging gdb itself and printing the buffer contents when
1040
         the buffer contains no embedded nulls.  Gdb does not depend
1041
         upon the buffer being null byte terminated, it uses the length
1042
         string instead.  This allows gdb to handle C strings (as well
1043
         as strings in other languages) with embedded null bytes */
1044
 
1045
      tokptr = ++tokstart;
1046
      tempbufindex = 0;
1047
 
1048
      do {
1049
        /* Grow the static temp buffer if necessary, including allocating
1050
           the first one on demand. */
1051
        if (tempbufindex + 1 >= tempbufsize)
1052
          {
1053
            tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
1054
          }
1055
        switch (*tokptr)
1056
          {
1057
          case '\0':
1058
          case '"':
1059
            /* Do nothing, loop will terminate. */
1060
            break;
1061
          case '\\':
1062
            tokptr++;
1063
            c = parse_escape (parse_gdbarch, &tokptr);
1064
            if (c == -1)
1065
              {
1066
                continue;
1067
              }
1068
            tempbuf[tempbufindex++] = c;
1069
            break;
1070
          default:
1071
            tempbuf[tempbufindex++] = *tokptr++;
1072
            break;
1073
          }
1074
      } while ((*tokptr != '"') && (*tokptr != '\0'));
1075
      if (*tokptr++ != '"')
1076
        {
1077
          error (_("Unterminated string in expression"));
1078
        }
1079
      tempbuf[tempbufindex] = '\0';     /* See note above */
1080
      yylval.sval.ptr = tempbuf;
1081
      yylval.sval.length = tempbufindex;
1082
      lexptr = tokptr;
1083
      return (STRING_LITERAL);
1084
    }
1085
 
1086
  if (!(c == '_' || c == '$'
1087
        || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
1088
    /* We must have come across a bad character (e.g. ';').  */
1089
    error (_("Invalid character '%c' in expression"), c);
1090
 
1091
  /* It's a name.  See how long it is.  */
1092
  namelen = 0;
1093
  for (c = tokstart[namelen];
1094
       (c == '_'
1095
        || c == '$'
1096
        || (c >= '0' && c <= '9')
1097
        || (c >= 'a' && c <= 'z')
1098
        || (c >= 'A' && c <= 'Z')
1099
        || c == '<');
1100
       )
1101
    {
1102
      if (c == '<')
1103
        {
1104
          int i = namelen;
1105
          while (tokstart[++i] && tokstart[i] != '>');
1106
          if (tokstart[i] == '>')
1107
            namelen = i;
1108
        }
1109
       c = tokstart[++namelen];
1110
     }
1111
 
1112
  /* The token "if" terminates the expression and is NOT
1113
     removed from the input stream.  */
1114
  if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
1115
    {
1116
      return 0;
1117
    }
1118
 
1119
  lexptr += namelen;
1120
 
1121
  tryname:
1122
 
1123
  /* Catch specific keywords.  Should be done with a data structure.  */
1124
  switch (namelen)
1125
    {
1126
    case 7:
1127
      if (strncmp (tokstart, "boolean", 7) == 0)
1128
        return BOOLEAN;
1129
      break;
1130
    case 6:
1131
      if (strncmp (tokstart, "double", 6) == 0)
1132
        return DOUBLE;
1133
      break;
1134
    case 5:
1135
      if (strncmp (tokstart, "short", 5) == 0)
1136
        return SHORT;
1137
      if (strncmp (tokstart, "false", 5) == 0)
1138
        {
1139
          yylval.lval = 0;
1140
          return BOOLEAN_LITERAL;
1141
        }
1142
      if (strncmp (tokstart, "super", 5) == 0)
1143
        return SUPER;
1144
      if (strncmp (tokstart, "float", 5) == 0)
1145
        return FLOAT;
1146
      break;
1147
    case 4:
1148
      if (strncmp (tokstart, "long", 4) == 0)
1149
        return LONG;
1150
      if (strncmp (tokstart, "byte", 4) == 0)
1151
        return BYTE;
1152
      if (strncmp (tokstart, "char", 4) == 0)
1153
        return CHAR;
1154
      if (strncmp (tokstart, "true", 4) == 0)
1155
        {
1156
          yylval.lval = 1;
1157
          return BOOLEAN_LITERAL;
1158
        }
1159
      break;
1160
    case 3:
1161
      if (strncmp (tokstart, "int", 3) == 0)
1162
        return INT;
1163
      if (strncmp (tokstart, "new", 3) == 0)
1164
        return NEW;
1165
      break;
1166
    default:
1167
      break;
1168
    }
1169
 
1170
  yylval.sval.ptr = tokstart;
1171
  yylval.sval.length = namelen;
1172
 
1173
  if (*tokstart == '$')
1174
    {
1175
      write_dollar_variable (yylval.sval);
1176
      return VARIABLE;
1177
    }
1178
 
1179
  /* Input names that aren't symbols but ARE valid hex numbers,
1180
     when the input radix permits them, can be names or numbers
1181
     depending on the parse.  Note we support radixes > 16 here.  */
1182
  if (((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
1183
       (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
1184
    {
1185
      YYSTYPE newlval;  /* Its value is ignored.  */
1186
      int hextype = parse_number (tokstart, namelen, 0, &newlval);
1187
      if (hextype == INTEGER_LITERAL)
1188
        return NAME_OR_INT;
1189
    }
1190
  return IDENTIFIER;
1191
}
1192
 
1193
void
1194
yyerror (char *msg)
1195
{
1196
  if (prev_lexptr)
1197
    lexptr = prev_lexptr;
1198
 
1199
  if (msg)
1200
    error (_("%s: near `%s'"), msg, lexptr);
1201
  else
1202
    error (_("error in expression, near `%s'"), lexptr);
1203
}
1204
 
1205
static struct type *
1206
java_type_from_name (struct stoken name)
1207
{
1208
  char *tmp = copy_name (name);
1209
  struct type *typ = java_lookup_class (tmp);
1210
  if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
1211
    error (_("No class named `%s'"), tmp);
1212
  return typ;
1213
}
1214
 
1215
/* If NAME is a valid variable name in this scope, push it and return 1.
1216
   Otherwise, return 0. */
1217
 
1218
static int
1219
push_variable (struct stoken name)
1220
{
1221
  char *tmp = copy_name (name);
1222
  int is_a_field_of_this = 0;
1223
  struct symbol *sym;
1224
  sym = lookup_symbol (tmp, expression_context_block, VAR_DOMAIN,
1225
                       &is_a_field_of_this);
1226
  if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
1227
    {
1228
      if (symbol_read_needs_frame (sym))
1229
        {
1230
          if (innermost_block == 0 ||
1231
              contained_in (block_found, innermost_block))
1232
            innermost_block = block_found;
1233
        }
1234
 
1235
      write_exp_elt_opcode (OP_VAR_VALUE);
1236
      /* We want to use the selected frame, not another more inner frame
1237
         which happens to be in the same block.  */
1238
      write_exp_elt_block (NULL);
1239
      write_exp_elt_sym (sym);
1240
      write_exp_elt_opcode (OP_VAR_VALUE);
1241
      return 1;
1242
    }
1243
  if (is_a_field_of_this)
1244
    {
1245
      /* it hangs off of `this'.  Must not inadvertently convert from a
1246
         method call to data ref.  */
1247
      if (innermost_block == 0 ||
1248
          contained_in (block_found, innermost_block))
1249
        innermost_block = block_found;
1250
      write_exp_elt_opcode (OP_THIS);
1251
      write_exp_elt_opcode (OP_THIS);
1252
      write_exp_elt_opcode (STRUCTOP_PTR);
1253
      write_exp_string (name);
1254
      write_exp_elt_opcode (STRUCTOP_PTR);
1255
      return 1;
1256
    }
1257
  return 0;
1258
}
1259
 
1260
/* Assuming a reference expression has been pushed, emit the
1261
   STRUCTOP_PTR ops to access the field named NAME.  If NAME is a
1262
   qualified name (has '.'), generate a field access for each part. */
1263
 
1264
static void
1265
push_fieldnames (struct stoken name)
1266
{
1267
  int i;
1268
  struct stoken token;
1269
  token.ptr = name.ptr;
1270
  for (i = 0;  ;  i++)
1271
    {
1272
      if (i == name.length || name.ptr[i] == '.')
1273
        {
1274
          /* token.ptr is start of current field name. */
1275
          token.length = &name.ptr[i] - token.ptr;
1276
          write_exp_elt_opcode (STRUCTOP_PTR);
1277
          write_exp_string (token);
1278
          write_exp_elt_opcode (STRUCTOP_PTR);
1279
          token.ptr += token.length + 1;
1280
        }
1281
      if (i >= name.length)
1282
        break;
1283
    }
1284
}
1285
 
1286
/* Helper routine for push_expression_name.
1287
   Handle a qualified name, where DOT_INDEX is the index of the first '.' */
1288
 
1289
static void
1290
push_qualified_expression_name (struct stoken name, int dot_index)
1291
{
1292
  struct stoken token;
1293
  char *tmp;
1294
  struct type *typ;
1295
 
1296
  token.ptr = name.ptr;
1297
  token.length = dot_index;
1298
 
1299
  if (push_variable (token))
1300
    {
1301
      token.ptr = name.ptr + dot_index + 1;
1302
      token.length = name.length - dot_index - 1;
1303
      push_fieldnames (token);
1304
      return;
1305
    }
1306
 
1307
  token.ptr = name.ptr;
1308
  for (;;)
1309
    {
1310
      token.length = dot_index;
1311
      tmp = copy_name (token);
1312
      typ = java_lookup_class (tmp);
1313
      if (typ != NULL)
1314
        {
1315
          if (dot_index == name.length)
1316
            {
1317
              write_exp_elt_opcode(OP_TYPE);
1318
              write_exp_elt_type(typ);
1319
              write_exp_elt_opcode(OP_TYPE);
1320
              return;
1321
            }
1322
          dot_index++;  /* Skip '.' */
1323
          name.ptr += dot_index;
1324
          name.length -= dot_index;
1325
          dot_index = 0;
1326
          while (dot_index < name.length && name.ptr[dot_index] != '.')
1327
            dot_index++;
1328
          token.ptr = name.ptr;
1329
          token.length = dot_index;
1330
          write_exp_elt_opcode (OP_SCOPE);
1331
          write_exp_elt_type (typ);
1332
          write_exp_string (token);
1333
          write_exp_elt_opcode (OP_SCOPE);
1334
          if (dot_index < name.length)
1335
            {
1336
              dot_index++;
1337
              name.ptr += dot_index;
1338
              name.length -= dot_index;
1339
              push_fieldnames (name);
1340
            }
1341
          return;
1342
        }
1343
      else if (dot_index >= name.length)
1344
        break;
1345
      dot_index++;  /* Skip '.' */
1346
      while (dot_index < name.length && name.ptr[dot_index] != '.')
1347
        dot_index++;
1348
    }
1349
  error (_("unknown type `%.*s'"), name.length, name.ptr);
1350
}
1351
 
1352
/* Handle Name in an expression (or LHS).
1353
   Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
1354
 
1355
static void
1356
push_expression_name (struct stoken name)
1357
{
1358
  char *tmp;
1359
  struct type *typ;
1360
  int i;
1361
 
1362
  for (i = 0;  i < name.length;  i++)
1363
    {
1364
      if (name.ptr[i] == '.')
1365
        {
1366
          /* It's a Qualified Expression Name. */
1367
          push_qualified_expression_name (name, i);
1368
          return;
1369
        }
1370
    }
1371
 
1372
  /* It's a Simple Expression Name. */
1373
 
1374
  if (push_variable (name))
1375
    return;
1376
  tmp = copy_name (name);
1377
  typ = java_lookup_class (tmp);
1378
  if (typ != NULL)
1379
    {
1380
      write_exp_elt_opcode(OP_TYPE);
1381
      write_exp_elt_type(typ);
1382
      write_exp_elt_opcode(OP_TYPE);
1383
    }
1384
  else
1385
    {
1386
      struct minimal_symbol *msymbol;
1387
 
1388
      msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
1389
      if (msymbol != NULL)
1390
        write_exp_msymbol (msymbol);
1391
      else if (!have_full_symbols () && !have_partial_symbols ())
1392
        error (_("No symbol table is loaded.  Use the \"file\" command"));
1393
      else
1394
        error (_("No symbol \"%s\" in current context"), tmp);
1395
    }
1396
 
1397
}
1398
 
1399
 
1400
/* The following two routines, copy_exp and insert_exp, aren't specific to
1401
   Java, so they could go in parse.c, but their only purpose is to support
1402
   the parsing kludges we use in this file, so maybe it's best to isolate
1403
   them here.  */
1404
 
1405
/* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
1406
   into a freshly malloc'ed struct expression.  Its language_defn is set
1407
   to null.  */
1408
static struct expression *
1409
copy_exp (struct expression *expr, int endpos)
1410
{
1411
  int len = length_of_subexp (expr, endpos);
1412
  struct expression *new
1413
    = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
1414
  new->nelts = len;
1415
  memcpy (new->elts, expr->elts + endpos - len, EXP_ELEM_TO_BYTES (len));
1416
  new->language_defn = 0;
1417
 
1418
  return new;
1419
}
1420
 
1421
/* Insert the expression NEW into the current expression (expout) at POS.  */
1422
static void
1423
insert_exp (int pos, struct expression *new)
1424
{
1425
  int newlen = new->nelts;
1426
 
1427
  /* Grow expout if necessary.  In this function's only use at present,
1428
     this should never be necessary.  */
1429
  if (expout_ptr + newlen > expout_size)
1430
    {
1431
      expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
1432
      expout = (struct expression *)
1433
        realloc ((char *) expout, (sizeof (struct expression)
1434
                                    + EXP_ELEM_TO_BYTES (expout_size)));
1435
    }
1436
 
1437
  {
1438
    int i;
1439
 
1440
    for (i = expout_ptr - 1; i >= pos; i--)
1441
      expout->elts[i + newlen] = expout->elts[i];
1442
  }
1443
 
1444
  memcpy (expout->elts + pos, new->elts, EXP_ELEM_TO_BYTES (newlen));
1445
  expout_ptr += newlen;
1446
}

powered by: WebSVN 2.1.0

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