Subversion Repositories Vertical

Rev

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