Subversion Repositories Vertical

Rev

Blame | 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. #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. }
  892.