Subversion Repositories Vertical

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  
  113. #include <stdio.h>
  114. #include <stdlib.h>
  115. #include <string.h>
  116.  
  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.  
  126. /* place reference to a 'C' variable at the end of the tree branch */
  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.   }
  138.  
  139.  
  140.  
  141. /* place an integer  constant at the end of the tree branch */
  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.   }
  153. /* place a boolean constant at the end of the tree branch */
  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.   }
  165.  
  166. /* this is where the user types some arbitrary string which is a numeric constant */
  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.   }
  178. /* this is where the user types some arbitrary string which is a boolean constant */
  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.   }
  190.  
  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.   }
  203.  
  204.  
  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.   }
  215.  
  216.  
  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.   }
  227.  
  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.   }
  239.  
  240.  
  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.   }
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  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);
  307.         }
  308.       else
  309.         fprintf(f,"((%s))",e->right.s);
  310.  
  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 */  
  407. /* if there is no expression return */
  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;
  426.  
  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);
  436.  
  437.       break;
  438.  
  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.   }
  456.  
  457.  
  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;
  463.  
  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)
  480.         {
  481.         gen = get_generic_ref(chip_generics,e->right.s);
  482.         }
  483.         /* search outwards */
  484.       if (!gen)
  485.         {
  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;
  498.  
  499.           newgen.valid     = 1;
  500.           newgen.expr      = compile_constant(0);
  501.           newgen.g_type    = IS_INTEGER;
  502.           newgen.g_class   = DEFINED;
  503.  
  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 */
  522.  
  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);
  528. #if defined DEBUG_EXPRESSION
  529.           printf("eval %s = %d\n",gen->name,r);
  530. #endif
  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.           }
  536.         }
  537.       else
  538.         {
  539.  
  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);
  554. #if defined DEBUG_EXPRESSION
  555.           printf("eval %s = %d\n",gen->name,r);
  556. #endif
  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.         }
  563.  
  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)
  600.         {
  601.         r= eval_expression(e->left.e,chip_generics)/rhs;
  602.         }
  603.       else
  604.         {
  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;
  617.         }
  618.       else
  619.         {
  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.   }
  687.  
  688.  
  689.  
  690. int eval_vhdl_expression(expression_t * expr,
  691.                          int * high,
  692.                          int * low ) {
  693.   int rc;
  694.  
  695.   generic_info_t ** chip_generics = NULL; /* no local search scope, order of declaration should ensure that
  696.                                            generics are defined before use */
  697.  
  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;
  702.  
  703.   if (!expr) return 0;
  704.  
  705.   switch (expr->opcode) {
  706.    
  707.  
  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.     }
  729. #if defined DEBUG_EXPRESSION
  730.   print_msg_expression(stdout,"eval vhdl ",expr);
  731.   printf("high %d low %d rc %d\n",
  732.       *high,*low,
  733.       rc );
  734. #endif
  735.   return rc;
  736.   }
  737.  
  738.  
  739. int eval_gen_expression(
  740.        generic_info_t * gen) {
  741. #if defined NEED_EVAL_GEN
  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;  
  767.         }
  768.       gen->g_class = DEFINED;
  769.       return gen->g_type;
  770.       }
  771.     }
  772.  
  773.   return NO_VALUE;
  774. #else
  775.   return gen->g_type;
  776. #endif
  777.   }
  778.  
  779. /* delete any expression pointed to */
  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.   }
  805. /* copy the expression, fixing up the references to local generic constants
  806.    at the same time . Need to */
  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.     }
  834.  
  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);
  844. #if defined DEBUG_EXPRESSION
  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);
  848. #endif
  849.   return new_vhdl;
  850.   }
  851.  
  852.  
  853.  
  854.  
  855.