Subversion Repositories Vertical

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 1
/* expression.h */
2
/* contains the type declarations for expression handling information  */
3
/*
4
 * $Id: expression.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $
5
 *
6
 * $Log: expression.c,v $
7
 * Revision 1.1.1.1  2003/11/04 23:34:57  mjames
8
 * Imported into local repositrory
9
 *
10
 * Revision 1.11  2002/09/30 13:22:38  MJAMES
11
 * Altered the use and creation of partition
12
 * generics (at evaluation time of expressions within the partition )
13
 * This still needs checking, as evaluation of the expression may well be
14
 * delayed until after when the partition generics need to be defined.
15
 *
16
 * Revision 1.10  2002/09/09 15:15:37  mjames
17
 * Altered expression to copy properly
18
 *
19
 * Revision 1.8  2001/11/30 22:19:27  mjames
20
 * Corrected some missing conversion of LBRK to '('.
21
 * Initialised a variable to satisfy GCC.
22
 * Enhanced an error message to give some context.
23
 *
24
 * Revision 1.7  2001/10/31 22:20:04  mjames
25
 * Tidying up problematical comments caused by CVS
26
 * 'intelligent' comment guessing
27
 *
28
 * Revision 1.6  2001/06/06 12:10:23  mjames
29
 * Move from HPUX
30
 *
31
 * Revision 1.5  2001/04/09 14:58:29  mjames
32
 * Added capability to delete generics from specific sockets.
33
 *
34
 * Revision 1.4  2001/04/06 22:47:02  mjames
35
 * Added doc2, the creator of documentation to Vertical scripts uses PERL
36
 *
37
 *
38
 * Also correcting generic behaviour and the printing of Verilog.
39
 *
40
 * Revision 1.3  2000/12/04 13:14:02  mjames
41
 * Imported all of the PCB syntax readers.
42
 *
43
 * Converted "a/b" to mean "a" divided by "b" insted of a single string
44
 * "a/b" in Verilog
45
 *
46
 * Revision 1.2  2000/11/29 21:51:18  mjames
47
 * Fine tuning of software
48
 *
49
 * Revision 1.1.1.1  2000/10/19 21:58:37  mjames
50
 * Mike put it here
51
 *
52
 *
53
 * Revision 1.20  2000/10/12  15:32:18  15:32:18  mjames (Mike James)
54
 * Removed <cr>
55
 *
56
 * Revision 1.19  2000/10/04  10:37:04  10:37:04  mjames (Mike James)
57
 * Modified for Vertical2 : support COMPONENTS and SIGNALS
58
 *
59
 * Revision 1.19  2000/10/04  10:37:04  10:37:04  mjames (Mike James)
60
 * Part of Release PSAVAT01
61
 *
62
 * Revision 1.18  2000/10/02  11:04:12  11:04:12  mjames (Mike James)
63
 * new_vhdl
64
 *
65
 * Revision 1.17  2000/09/27  14:42:12  14:42:12  mjames (Mike James)
66
 * Part of Release Sep_27_ST_2000
67
 *
68
 * Revision 1.16  2000/09/21  10:15:42  10:15:42  mjames (Mike James)
69
 * Part of Release Sep21Alpha
70
 *
71
 * Revision 1.15  2000/08/25  09:57:10  09:57:10  mjames (Mike James)
72
 * Part of Release Aug25_alpha
73
 *
74
 * Revision 1.14  2000/08/16  08:57:27  08:57:27  mjames (Mike James)
75
 * Part of Release CD01_Aug2000
76
 *
77
 * Revision 1.13  2000/08/14  14:45:08  14:45:08  mjames (Mike James)
78
 * Part of Release Aug_14_2000
79
 *
80
 * Revision 1.12  2000/08/11  08:30:28  08:30:28  mjames (Mike James)
81
 * Part of Release Aug_11_2000
82
 *
83
 * Revision 1.11  2000/08/09  10:31:42  10:31:42  mjames (Mike James)
84
 * Part of Release Aug__9_2000
85
 *
86
 * Revision 1.10  2000/05/31  11:42:50  11:42:50  mjames (Mike James)
87
 * Part of Release May_31_2000
88
 *
89
 * Revision 1.9  2000/05/08  17:01:34  17:01:34  mjames (Mike James)
90
 * Part of Release May__8_2000
91
 *
92
 * Revision 1.8  2000/05/08  16:59:27  16:59:27  mjames (Mike James)
93
 * Part of Release May__8_2000
94
 *
95
 * Revision 1.7  2000/05/08  16:57:03  16:57:03  mjames (Mike James)
96
 * Part of Release May__8_2000
97
 *
98
 * Revision 1.6  2000/03/08  16:18:56  16:18:56  mjames (Mike James)
99
 * New version including PC
100
 *
101
 * Revision 1.3  2000/01/20  15:58:42  15:58:42  mjames (Mike James)
102
 * Part of Release R22
103
 *
104
 * Revision 1.2  99/12/22  11:15:23  11:15:23  mjames (Mike James)
105
 * Part of Release Dec_22_1999
106
 *
107
 * Revision 1.1  99/06/25  14:34:45  14:34:45  mjames (Mike James)
108
 * Initial revision
109
 *
110
 *  */
111
 
112
#include "expression.h"
113
 
114
#include "acf_yacc.h"
115
#include "cmdlog.h"
116
#include "cmdparse.h"
117
#include "database.h"
118
#include "generic.h"
119
#include "vertcl_main.h"
120
 
121
#include <stdio.h>
122
#include <stdlib.h>
123
#include <string.h>
124
 
125
/* place reference to a 'C' variable at the end of the tree branch */
126
expression_t *compile_variable_reference (int *v, char *s)
127
{
128
        expression_t *p;
129
        p = calloc (1, sizeof (expression_t));
130
 
131
        if (p)
132
        {
133
                p->opcode = EXP_VAR_REF;
134
                p->left.ip = v;
135
                p->right.s = s;
136
        }
137
        return p;
138
}
139
 
140
/* place an integer  constant at the end of the tree branch */
141
expression_t *compile_constant (int k)
142
{
143
        expression_t *p;
144
        p = calloc (1, sizeof (expression_t));
145
 
146
        if (p)
147
        {
148
                p->opcode = EXP_CONSTANT;
149
                p->left.i = k;
150
                p->right.s = NULL;
151
        }
152
        return p;
153
}
154
/* place a boolean constant at the end of the tree branch */
155
expression_t *compile_boolean_constant (int k)
156
{
157
        expression_t *p;
158
        p = calloc (1, sizeof (expression_t));
159
 
160
        if (p)
161
        {
162
                p->opcode = EXP_BOOLEAN;
163
                p->left.i = k;
164
                p->right.s = NULL;
165
        }
166
        return p;
167
}
168
 
169
/* this is where the user types some arbitrary string which is a numeric constant */
170
expression_t *compile_constant_string (int k, char *s)
171
{
172
        expression_t *p;
173
        p = calloc (1, sizeof (expression_t));
174
 
175
        if (p)
176
        {
177
                p->opcode = EXP_CONSTANT;
178
                p->left.i = k;
179
                p->right.s = ISNULLSTR (s) ? NULL : strdup (s);
180
        }
181
        return p;
182
}
183
/* this is where the user types some arbitrary string which is a boolean constant */
184
expression_t *compile_boolean_constant_string (int k, char *s)
185
{
186
        expression_t *p;
187
        p = calloc (1, sizeof (expression_t));
188
 
189
        if (p)
190
        {
191
                p->opcode = EXP_BOOLEAN;
192
                p->left.i = k;
193
                p->right.s = ISNULLSTR (s) ? NULL : strdup (s);
194
        }
195
        return p;
196
}
197
 
198
/* this compiles a reference to the variable */
199
expression_t *compile_variable (generic_info_t *generic, char *valname)
200
{
201
        expression_t *p;
202
        p = calloc (1, sizeof (expression_t));
203
 
204
        if (p)
205
        {
206
                p->opcode = EXP_VARIABLE;
207
                p->left.g = generic;
208
                p->right.s = valname;
209
        }
210
        return p;
211
}
212
 
213
expression_t *compile_string (char *s)
214
{
215
        expression_t *p;
216
        p = (expression_t *) calloc (1, sizeof (expression_t));
217
 
218
        if (p)
219
        {
220
                p->opcode = EXP_STRING;
221
                p->left.s = ISNULLSTR (s) ? NULL : strdup (s);
222
        }
223
        return p;
224
}
225
 
226
expression_t *compile_char (char c)
227
{
228
        expression_t *p;
229
        p = (expression_t *) calloc (1, sizeof (expression_t));
230
 
231
        if (p)
232
        {
233
                p->opcode = EXP_CHAR;
234
                p->left.i = c;
235
        }
236
        return p;
237
}
238
 
239
expression_t *compile_reference (char *s)
240
{
241
        expression_t *p;
242
        p = (expression_t *) calloc (1, sizeof (expression_t));
243
 
244
        if (p)
245
        {
246
                p->opcode = EXP_UNDEF_VAR;
247
                p->right.s = ISNULLSTR (s) ? NULL : strdup (s);
248
        }
249
        return p;
250
}
251
 
252
expression_t *compile_expression (int opcode, expression_t *l, expression_t *r)
253
{
254
        expression_t *p;
255
        p = (expression_t *) calloc (1, sizeof (expression_t));
256
        if (p)
257
        {
258
                p->opcode = opcode;
259
                p->left.e = l;
260
                p->right.e = r;
261
        }
262
        return p;
263
}
264
 
265
void print_expression (FILE *f, expression_t *e, generic_print_style recurse_generics)
266
{
267
        if (!e)
268
        {
269
                fprintf (f, "(NULL)");
270
                return;
271
        }
272
        switch (e->opcode)
273
        {
274
        case EXP_UNDEF_VAR:
275
                if (e->right.s)
276
                        fprintf (f, "%s", e->right.s);
277
                break;
278
        case EXP_STRING:
279
                if (e->left.s)
280
                        fprintf (f, "\"%s\"", e->left.s);
281
                break;
282
        case EXP_CHAR:
283
                fprintf (f, "\'%c\'", e->left.i);
284
                break;
285
        case EXP_CONSTANT:
286
                if (e->right.s)
287
                        fprintf (f, "%s", e->right.s);
288
                else
289
                        fprintf (f, "%d", e->left.i);
290
                break;
291
        case EXP_VAR_REF:
292
                /*      if (e->right.s)
293
                        fprintf(f,"%s",e->right.s);
294
                      else */
295
                fprintf (f, "%d", *(e->left.ip));
296
                break;
297
        case EXP_BOOLEAN:
298
                if (e->right.s)
299
                        fprintf (f, "%s", e->right.s);
300
                else
301
                        fprintf (f, "%s", e->left.i ? "true" : "false");
302
                break;
303
        case EXP_VARIABLE:
304
                if (e->left.g)
305
                {
306
                        if (recurse_generics != NO_RECURSE && e->left.g->expr &&
307
                            (recurse_generics == RECURSE_NUMBER ||
308
                             e->left.g->expr->opcode != EXP_CONSTANT))
309
                        {
310
                                fprintf (f, "(");
311
                                print_expression (f, e->left.g->expr, recurse_generics);
312
                                fprintf (f, ")");
313
                        }
314
                        else
315
                                fprintf (f, "%s", e->right.s);
316
                }
317
                else
318
                        fprintf (f, "((%s))", e->right.s);
319
 
320
                break;
321
        case UMINUS:
322
                fprintf (f, "(-");
323
                if (e->left.e->opcode != EXP_CONSTANT)
324
                        fprintf (f, "(");
325
                print_expression (f, e->left.e, recurse_generics);
326
                if (e->left.e->opcode != EXP_CONSTANT)
327
                        fprintf (f, ")");
328
                fprintf (f, ")");
329
                break;
330
        case '~':
331
                fprintf (f, "(~");
332
                if (e->left.e->opcode != EXP_CONSTANT)
333
                        fprintf (f, "(");
334
                print_expression (f, e->left.e, recurse_generics);
335
                if (e->left.e->opcode != EXP_CONSTANT)
336
                        fprintf (f, ")");
337
                fprintf (f, ")");
338
                break;
339
        case '!':
340
                fprintf (f, "(!");
341
                if (e->left.e->opcode != EXP_CONSTANT)
342
                        fprintf (f, "(");
343
                print_expression (f, e->left.e, recurse_generics);
344
                if (e->left.e->opcode != EXP_CONSTANT)
345
                        fprintf (f, ")");
346
                fprintf (f, ")");
347
                break;
348
        case '(':
349
                fprintf (f, "(");
350
                print_expression (f, e->left.e, recurse_generics);
351
                fprintf (f, ")");
352
                break;
353
        case '+':
354
        case '-':
355
        case '*':
356
        case '/':
357
        case '%':
358
        case '^':
359
        case '?':
360
        case ':':
361
        case '>':
362
        case '<':
363
        case '&':
364
        case '|':
365
 
366
                print_expression (f, e->left.e, recurse_generics);
367
                fprintf (f, "%c", e->opcode);
368
                print_expression (f, e->right.e, recurse_generics);
369
 
370
                break;
371
        case SHL:
372
                print_expression (f, e->left.e, recurse_generics);
373
                fprintf (f, "<<");
374
                print_expression (f, e->right.e, recurse_generics);
375
                break;
376
        case SHR:
377
                print_expression (f, e->left.e, recurse_generics);
378
                fprintf (f, ">>");
379
                print_expression (f, e->right.e, recurse_generics);
380
                break;
381
        case EQ_EQ:
382
                print_expression (f, e->left.e, recurse_generics);
383
                fprintf (f, "==");
384
                print_expression (f, e->right.e, recurse_generics);
385
                break;
386
        case N_EQ:
387
                print_expression (f, e->left.e, recurse_generics);
388
                fprintf (f, "!=");
389
                print_expression (f, e->right.e, recurse_generics);
390
                break;
391
        case LOG_AND:
392
                print_expression (f, e->left.e, recurse_generics);
393
                fprintf (f, "&&");
394
                print_expression (f, e->right.e, recurse_generics);
395
                break;
396
        case LOG_OR:
397
                print_expression (f, e->left.e, recurse_generics);
398
                fprintf (f, "||");
399
                print_expression (f, e->right.e, recurse_generics);
400
                break;
401
        case TO_POW:
402
                print_expression (f, e->left.e, recurse_generics);
403
                fprintf (f, "**");
404
                print_expression (f, e->right.e, recurse_generics);
405
                break;
406
        default:
407
                fprintf (f, "(?? expression ERROR : OPCODE 0x%X)", e->opcode);
408
        }
409
}
410
 
411
/* a range is permitted at the top level of an expression */
412
/* if there is no expression return */
413
void print_range_expression (FILE *f, expression_t *e, generic_print_style recurse_generics)
414
{
415
        if (!e)
416
                return;
417
        switch (e->opcode)
418
        {
419
        case TO:
420
                fprintf (f, "(");
421
                print_expression (f, e->left.e, recurse_generics);
422
                fprintf (f, " TO ");
423
                print_expression (f, e->right.e, recurse_generics);
424
                fprintf (f, ")");
425
                break;
426
 
427
        case DOWNTO:
428
                fprintf (f, "(");
429
                print_expression (f, e->left.e, recurse_generics);
430
                fprintf (f, " DOWNTO ");
431
                print_expression (f, e->right.e, recurse_generics);
432
                fprintf (f, ")");
433
                break;
434
 
435
        case EXP_VARIABLE:
436
                if (e->left.g)
437
                {
438
                        if (recurse_generics != NO_RECURSE)
439
                                print_range_expression (f, e->left.g->expr, recurse_generics);
440
                        else
441
                                fprintf (f, "(%s)", e->right.s);
442
                }
443
                else
444
                        fprintf (f, "((??%s))", e->right.s);
445
 
446
                break;
447
 
448
        default:
449
                /* handle the expressions down each level of the hierarchy */
450
                /*      fprintf(f,"("); */
451
                print_expression (f, e, recurse_generics);
452
                /*      fprintf(f,")"); */
453
        }
454
}
455
 
456
void print_msg_expression (FILE *f, char *s, expression_t *e)
457
{
458
        fprintf (f, "%s '", s);
459
        print_range_expression (f, e, NO_RECURSE);
460
        fprintf (f, "'\n");
461
}
462
 
463
/* evaluate an integer expression : checking local generics if they are available  */
464
int eval_expression (expression_t *e, generic_info_t **chip_generics)
465
{
466
        int r = 0;
467
        if (!e)
468
                return 0;
469
 
470
        switch (e->opcode)
471
        {
472
        case EXP_CONSTANT:
473
        case EXP_BOOLEAN:
474
                r = e->left.i;
475
                break;
476
        case EXP_VAR_REF:
477
                r = *(e->left.ip);
478
                break;
479
        /* when evaluating expression, if a generic in scope is found then the
480
           generic will be updated : ends up creating and cross-linking a
481
           partition generic */
482
        case EXP_UNDEF_VAR:
483
        {
484
                generic_info_t *gen;
485
                gen = NULL;
486
                if (chip_generics)
487
                {
488
                        gen = get_generic_ref (chip_generics, e->right.s);
489
                }
490
                /* search outwards */
491
                if (!gen)
492
                {
493
                        gen = get_generic_ref (&global_generics, e->right.s);
494
                }
495
                if (!gen)
496
                { /* scope is external not local */
497
                        expr_ref_t *link;
498
                        gen = get_generic_ref (&partition_generics, e->right.s);
499
                        /* if no partition generic appears, make one */
500
                        if (!gen)
501
                        {
502
                                generic_info_t newgen;
503
                                newgen.typename = "integer";
504
                                newgen.name = e->right.s;
505
 
506
                                newgen.valid = 1;
507
                                newgen.expr = compile_constant (0);
508
                                newgen.g_type = IS_INTEGER;
509
                                newgen.g_class = DEFINED;
510
 
511
                                gen = set_generic_value (&partition_generics, &newgen);
512
                        }
513
                        if (gen)
514
                        {
515
                                link = calloc (1, sizeof (expr_ref_t));
516
                        }
517
                        if (gen && link)
518
                        {
519
                                link->expr_ref = gen->expr_ref;
520
                                gen->expr_ref = link;
521
                                link->expr = e;
522
                        }
523
                }
524
                if (gen)
525
                {
526
                        e->opcode = EXP_VARIABLE;
527
                        e->left.g = gen;
528
                        /* having located a valid generic then try to link it up */
529
 
530
                        /* duplicate code borrowed from below. Avoiding 'goto' !! */
531
                        eval_gen_expression (gen);
532
                        if (gen->g_type == IS_ATTRIBUTE || gen->g_type == IS_INTEGER)
533
                        {
534
                                r = eval_expression (gen->expr, chip_generics);
535
#if defined DEBUG_EXPRESSION
536
                                printf ("eval %s = %d\n", gen->name, r);
537
#endif
538
                        }
539
                        else
540
                        {
541
                                Log (
542
                                    LOG_ERROR,
543
                                    "#Error : generic %s has non integer type (code %d)\n",
544
                                    gen->name,
545
                                    gen->g_type);
546
                                r = 0;
547
                        }
548
                }
549
                else
550
                {
551
                        Log (LOG_ERROR, "# symbol '%s' is not defined\n", e->right.s);
552
                }
553
        }
554
        break;
555
        case EXP_VARIABLE:
556
        {
557
                generic_info_t *gen;
558
                gen = e->left.g;
559
 
560
                if (gen)
561
                {
562
                        eval_gen_expression (gen);
563
                        if (gen->g_type == IS_ATTRIBUTE || gen->g_type == IS_INTEGER)
564
                        {
565
                                r = eval_expression (gen->expr, chip_generics);
566
#if defined DEBUG_EXPRESSION
567
                                printf ("eval %s = %d\n", gen->name, r);
568
#endif
569
                        }
570
                        else
571
                        {
572
                                Log (
573
                                    LOG_ERROR,
574
                                    "#Error : generic %s has non integer type (code %d)\n",
575
                                    gen->name,
576
                                    gen->g_type);
577
                                r = 0;
578
                        }
579
                }
580
 
581
                else
582
                        Log (LOG_ERROR, "#Error : generic '%s' not found\n", e->right.s);
583
        }
584
        break;
585
        case EXP_CHAR:
586
                r = e->left.i;
587
                break;
588
        case EXP_STRING:
589
                r = 0;
590
                break;
591
        case '(':
592
                r = eval_expression (e->left.e, chip_generics);
593
                break;
594
        case UMINUS:
595
                r = 0 - eval_expression (e->left.e, chip_generics);
596
                break;
597
        case '~':
598
                r = ~eval_expression (e->left.e, chip_generics);
599
                break;
600
        case '!':
601
                r = !eval_expression (e->left.e, chip_generics);
602
                break;
603
        case '+':
604
                r = eval_expression (e->left.e, chip_generics) +
605
                    eval_expression (e->right.e, chip_generics);
606
                break;
607
        case '-':
608
                r = eval_expression (e->left.e, chip_generics) -
609
                    eval_expression (e->right.e, chip_generics);
610
                break;
611
        case '*':
612
                r = eval_expression (e->left.e, chip_generics) *
613
                    eval_expression (e->right.e, chip_generics);
614
                break;
615
        case '/':
616
        {
617
                int rhs;
618
                rhs = eval_expression (e->right.e, chip_generics);
619
                if (rhs)
620
                {
621
                        r = eval_expression (e->left.e, chip_generics) / rhs;
622
                }
623
                else
624
                {
625
                        Log (LOG_ERROR, "# ERROR: Division by 0\n");
626
                        r = 0;
627
                };
628
        }
629
        break;
630
        case '%':
631
        {
632
                int rhs;
633
                rhs = eval_expression (e->right.e, chip_generics);
634
                if (rhs)
635
                {
636
                        r = eval_expression (e->left.e, chip_generics) % rhs;
637
                }
638
                else
639
                {
640
                        Log (LOG_ERROR, "# ERROR: Modulus by 0\n");
641
                        r = 0;
642
                };
643
        }
644
        break;
645
        case '^':
646
                r = eval_expression (e->left.e, chip_generics) ^
647
                    eval_expression (e->right.e, chip_generics);
648
                break;
649
        case '|':
650
                r = eval_expression (e->left.e, chip_generics) |
651
                    eval_expression (e->right.e, chip_generics);
652
                break;
653
        case '&':
654
                r = eval_expression (e->left.e, chip_generics) &
655
                    eval_expression (e->right.e, chip_generics);
656
                break;
657
        case '>':
658
                r = eval_expression (e->left.e, chip_generics) >
659
                    eval_expression (e->right.e, chip_generics);
660
                break;
661
        case '<':
662
                r = eval_expression (e->left.e, chip_generics) <
663
                    eval_expression (e->right.e, chip_generics);
664
                break;
665
        case EQ_EQ:
666
                r = eval_expression (e->left.e, chip_generics) ==
667
                    eval_expression (e->right.e, chip_generics);
668
                break;
669
        case N_EQ:
670
                r = eval_expression (e->left.e, chip_generics) !=
671
                    eval_expression (e->right.e, chip_generics);
672
                break;
673
        case LOG_OR:
674
                r = eval_expression (e->left.e, chip_generics) ||
675
                    eval_expression (e->right.e, chip_generics);
676
                break;
677
        case LOG_AND:
678
                r = eval_expression (e->left.e, chip_generics) &&
679
                    eval_expression (e->right.e, chip_generics);
680
                break;
681
        case SHL:
682
                r = eval_expression (e->left.e, chip_generics)
683
                    << eval_expression (e->right.e, chip_generics);
684
                break;
685
        case SHR:
686
                r = eval_expression (e->left.e, chip_generics) >>
687
                    eval_expression (e->right.e, chip_generics);
688
                break;
689
        case '?':
690
                r = eval_expression (e->left.e, chip_generics)
691
                        ? eval_expression (e->right.e->left.e, chip_generics)
692
                        : eval_expression (e->right.e->right.e, chip_generics);
693
                break;
694
        case TO_POW:
695
        {
696
                int i, y, x;
697
                x = eval_expression (e->left.e, chip_generics);
698
                y = eval_expression (e->right.e, chip_generics);
699
                if (y == 0) /* x**0 = 1 */
700
                        r = 1;
701
                else if (y < 0) /* negative powers */
702
                        r = 0;
703
                else
704
                {
705
                        i = y; /* limit power */
706
                        if (i > 32)
707
                        {
708
                                Log (
709
                                    LOG_ERROR,
710
                                    "arithmetic power of: %d ** %d : %d > 32: limited to 32\n",
711
                                    x,
712
                                    y,
713
                                    y);
714
                                i = 32;
715
                        }
716
                        r = x;
717
                        while (--i)
718
                                r *= x;
719
                }
720
        }
721
        break;
722
        default:
723
                Log (LOG_ERROR, "#Error : expression : illegal operator (%d)\n", e->opcode);
724
        }
725
        /*  printf("(%d)",r); */
726
        return r;
727
}
728
 
729
int eval_vhdl_expression (expression_t *expr, int *high, int *low)
730
{
731
        int rc;
732
 
733
        generic_info_t **chip_generics =
734
            NULL; /* no local search scope, order of declaration should ensure that
735
                   generics are defined before use */
736
 
737
        if (!expr)
738
                return 0;
739
        /* my be range at top level in variable */
740
        if (expr->opcode == EXP_VARIABLE)
741
                expr = expr->left.g->expr;
742
 
743
        if (!expr)
744
                return 0;
745
 
746
        switch (expr->opcode)
747
        {
748
        case TO:
749
                *high = eval_expression (expr->left.e, chip_generics);
750
                *low = eval_expression (expr->right.e, chip_generics);
751
                rc = TO;
752
                break;
753
 
754
        case DOWNTO:
755
                *high = eval_expression (expr->left.e, chip_generics);
756
                *low = eval_expression (expr->right.e, chip_generics);
757
                rc = DOWNTO;
758
                break;
759
 
760
        default:
761
                /* handle the expressions down each level of the hierarchy */
762
                *high = eval_expression (expr, chip_generics);
763
                *low = *high;
764
                rc = IS_INTEGER;
765
                break;
766
        }
767
#if defined DEBUG_EXPRESSION
768
        print_msg_expression (stdout, "eval vhdl ", expr);
769
        printf ("high %d low %d rc %d\n", *high, *low, rc);
770
#endif
771
        return rc;
772
}
773
 
774
int eval_gen_expression (generic_info_t *gen)
775
{
776
#if defined NEED_EVAL_GEN
777
        expression_t *exp;
778
        if (gen)
779
        {
780
                exp = gen->expr;
781
                /*    printf("Ptr %p: ",exp); */
782
                if (exp)
783
                {
784
                        switch (exp->opcode)
785
                        {
786
                        case EXP_STRING:
787
                                gen->valuename = exp->left.s;
788
                                gen->g_type = IS_STRING;
789
                                gen->valid = 1;
790
                                break;
791
                        case TO:
792
                                gen->valid = 1;
793
                                gen->g_type = TO;
794
 
795
                                break;
796
 
797
                        case DOWNTO:
798
                                gen->valid = 1;
799
                                gen->g_type = DOWNTO;
800
                                break;
801
                        default:
802
                                /* handle the expressions down each level of the hierarchy */
803
                                gen->valid = 1;
804
                                gen->g_type = IS_INTEGER;
805
                        }
806
                        gen->g_class = DEFINED;
807
                        return gen->g_type;
808
                }
809
        }
810
 
811
        return NO_VALUE;
812
#else
813
        return gen->g_type;
814
#endif
815
}
816
 
817
/* delete any expression pointed to */
818
void free_expression (expression_t *ptr)
819
{
820
        if (!ptr)
821
                return;
822
        switch (ptr->opcode)
823
        {
824
        case EXP_STRING:
825
                if (ptr->left.s)
826
                        free (ptr->left.s);
827
        case EXP_CONSTANT:
828
        case EXP_BOOLEAN:
829
        case EXP_VARIABLE:
830
        case EXP_VAR_REF:
831
                if (ptr->right.s)
832
                        free (ptr->right.s); /* remove string */
833
                break;
834
        default:
835
                if (ptr->left.e)
836
                        free_expression (ptr->left.e);
837
                if (ptr->right.e)
838
                        free_expression (ptr->right.e);
839
                break;
840
        }
841
        free (ptr);
842
}
843
/* copy the expression, fixing up the references to local generic constants
844
   at the same time . Need to */
845
expression_t *copy_expression (expression_t *ptr, socket_t *skt)
846
{
847
        expression_t *copy;
848
        if (!ptr)
849
                return NULL;
850
        switch (ptr->opcode)
851
        {
852
        case EXP_CONSTANT:
853
        case EXP_BOOLEAN:
854
        case EXP_STRING:
855
        case EXP_VAR_REF:
856
        case EXP_VARIABLE:
857
        case EXP_CHAR:
858
                return ptr; /* no copy needed as this is a terminal node that cannot change */
859
                break;
860
                /* duplicate undefined references so each induvidual expression is fixed up */
861
        case EXP_UNDEF_VAR:
862
                copy = calloc (1, sizeof (expression_t));
863
                *copy = *ptr;
864
                return copy;
865
                break;
866
        default:
867
                return compile_expression (
868
                    ptr->opcode,
869
                    copy_expression (ptr->left.e, skt),
870
                    copy_expression (ptr->right.e, skt));
871
                break;
872
        }
873
        return NULL;
874
}
875
 
876
struct vhdl *copy_vhdl (vhdl_t *vhdl, socket_t *skt)
877
{
878
        vhdl_t *new_vhdl;
879
        if (!vhdl)
880
                return NULL;
881
        new_vhdl = calloc (1, sizeof (vhdl_t));
882
        *new_vhdl = *vhdl;
883
        new_vhdl->expr = copy_expression (vhdl->expr, skt);
884
        new_vhdl->default_expr = copy_expression (vhdl->default_expr, skt);
885
#if defined DEBUG_EXPRESSION
886
        printf ("Type = %s\n", vhdl->basetype);
887
        print_msg_expression (stdout, "Copied expr", new_vhdl->expr);
888
        print_msg_expression (stdout, "Copied default", new_vhdl->default_expr);
889
#endif
890
        return new_vhdl;
891
}