/******************************************************************
 *  (C) Copyright 1994; dit/upm
 *  Distributed under the conditions stated in the
 *  TOPO General Public License (see file LICENSE)
 ******************************************************************
 *  $Log$
 ******************************************************************/

#ifndef lint
static char rcsid[]= "$Id$";
#endif

/******************************************************************
 *
 *  Santiago Pavon Gomez
 *  David Larrabeiti Lopez
 *
 *  17 Jan 1990
 *
 *  Management of expression ( or variable ) lists.
 *
 *  COMPILATION FLAGS:
 *
 *  LOG:
 *     25/06/92. santiago.
 *     New function to calculate the intersection of two expression
 *     lists.
 *
 ******************************************************************/

/* LINTLIBRARY */

/* KJT 12/02/12: Added */
#include <stdlib.h>
#include "baattr.h"
#include "babeh.h"
#include "badefca.h"
#include "limisc.h"
#include "batables.h"
#include "listdh.h"
#include "listrbk.h"

/*----------------------------------------------------------------*/

/* StatisticEL
 * Statistics of the expression list el.
 * Returns the number of variable and operation cells, and list nodes used.
 * nv,vv and ov are virtual values of number of list nodes, variable and
 * operation cell, i.e. without paying attention to the sharing feature.
 * nr,vr and or are the real values, i.e. nodes and cells already counted in
 * other expressions are not counted again here.
 * nl is the number of list nodes used to build the expression list.
 */
void StatisticEL( el,nv,vv,ov,nr,vr,or,nl )
     ExprListTyp el;
     int         *nv,*vv,*ov,*nr,*vr,*or,*nl;
{
  int op,var,list,op2,var2,list2;

  *nv = *vv = *ov = *nr = *vr = *or = *nl = 0;
  while (el != NULL) {
    (*nl)++;
    StatisticE( (ExprTyp)LookInfo_list(el), &list,&var,&op,&list2,&var2,&op2);
    *or += op2;
    *vr += var2;
    *nr += list2;
    *ov += op;
    *vv += var;
    *nv += list;
    el = Next_list(el);
  }
}

/*----------------------------------------------------------------*/

/* CreateEL
 * Create an expression list or a variable list . ( return an empty one )
 */
ExprListTyp CreateEL()
{
  return Create_list();
}

/*----------------------------------------------------------------*/

static void FreeEL2( e )
     ExprTyp e;
{
  LASSERT(OwnersE(e)!=0);
  e = UnshareE(e);
  FreeE( e );
}

/* FreeEL
 * Free an expression list el.
 */
void FreeEL( el )
     ExprListTyp el;
{
  Free_list( el, FreeEL2 );
}

/*----------------------------------------------------------------*/

static ExprTyp CopyEL2( e )
     ExprTyp e;
{
  LASSERT(OwnersE(e)!=0);
  return ShareE(CopyE(e));
}

/* CopyEL
 * Copy the expression list el.
 */
ExprListTyp CopyEL( el )
     ExprListTyp el;
{
  return Copy_list(el,(DataListTyp(*)()) CopyEL2);
}

/*----------------------------------------------------------------*/

static ExprTyp UnshareELaux( e )
     ExprTyp e;
{
  return ShareE(GetE(UnshareE(e)));
}

/* UnshareEL
 * Unshare the expression list el.
 */
ExprListTyp UnshareEL( el )
     ExprListTyp el;
{
  Apply_Func_list(el,(DataListTyp(*)())UnshareELaux);
  return el;
}

/*----------------------------------------------------------------*/

/* DrawEL
 * Draw an expression list el.
 * pstr is the function used to print strings.
 */
void DrawEL( el, pstr )
     ExprListTyp  el;
     void         (*pstr)();
{
  while (el!=NULL) {
    DrawE( (ExprTyp)LookInfo_list(el), pstr );
    el = Next_list(el);
    if ( el!=NULL)
      pstr(", ");
  }
}

/*----------------------------------------------------------------*/

/* PrintVL
 * Print the variable list vl.
 * pstr is the function used to print strings.
 */
void PrintVL( vl, pstr )
     ExprListTyp   vl;
     void         (*pstr)();
{
  char * str;

  str = SPrintVL(vl);
  pstr(str);
  free(str);
}

/*----------------------------------------------------------------*/

/* SPrintVL
 * return a char string block with a variable list vl.
 */
char * SPrintVL( vl )
     ExprListTyp vl;
{
  char    * str;
  StrBckTyp strBck;

  strBck = CreateStrBck();
  while ( vl!=NULL ){
    str = SPrintV( LookNameE((ExprTyp)LookInfo_list(vl)), TRUE );
    strBck  = ConcatStrBck( strBck, str );
    free(str);
    vl = Next_list(vl);
    if ( vl!=NULL )
      strBck = ConcatStrBck( strBck, ", " );
  }
  str = GetStrStrBck( strBck) ;
  FreeStrBck( strBck );

  return str;
}

/*----------------------------------------------------------------*/

/* PrintEL
 * Prints the expression list el.
 * pstr is the function used to print strings.
 */
void PrintEL( el, pstr )
     ExprListTyp  el;
     void         (*pstr)();
{
  char * str;

  str = SPrintEL(el);
  pstr(str);
  free(str);
}

/*----------------------------------------------------------------*/

/* SPrintEL
 * return a char string block with an expression list el.
 */
char * SPrintEL( el )
     ExprListTyp   el;
{
  return SPrint_list( el, ExprToStringE );
}

/*----------------------------------------------------------------*/

/* InEL
 * If an expression e is in expression list el then return TRUE else FALSE.
 */
extern boolean InEL( e, el )
     ExprTyp     e;
     ExprListTyp el;
{
  return In_list( (DataListTyp)e, el, EqualE ) ;
}

/*----------------------------------------------------------------*/

/* InsertEL
 * Insert expression e in an expression list. (At the header).
 */
ExprListTyp InsertEL( e, el )
     ExprTyp e;
     ExprListTyp el;
{
  return Insert_list( (DataListTyp)ShareE(e), el );
}

/*----------------------------------------------------------------*/

static ExprListTyp jvl;

static void IntersELAux( l1, l2 )
     ExprListTyp l1,l2;
{
  while (l1!=NULL) {
    if ( InEL((ExprTyp)LookInfo_list(l1),l2) )
      /*mse*/ jvl = InsertEL(CopyE((ExprTyp)LookInfo_list(l1)),jvl);
    l1 = Next_list(l1);
  }
}


/* IntersEL
 * Return the intersection of two expression lists,
 * i.e. a list with the expressions both in el1 and in el2.
 * The lists el1 and el2 are disposed.
 */
ExprListTyp IntersEL( el1,el2 )
     ExprListTyp el1,el2;
{
  jvl = CreateEL();
  IntersELAux(el1,el2);
  FreeEL(el1);
  FreeEL(el2);
  return jvl;
}

/*----------------------------------------------------------------*/

/* JoinEL
 * Return the concatenation el1,el2
 */
ExprListTyp JoinEL( el1, el2 )
     ExprListTyp el1, el2;
{
  return  Join_list( el1, el2 );
}

/*----------------------------------------------------------------*/

/* AddEL
 * Append expression e to the tail of expression list el.
 */
ExprListTyp AddEL( e, el )
     ExprTyp e;
     ExprListTyp el;
{
  return Add_list( (DataListTyp) ShareE(e), el);
}

/*----------------------------------------------------------------*/

static ListTyp vl;

static void Vars_Of_Expr( e )
     ExprTyp e;
{
  int i;

  if ( IsVariableE(e) )
    vl = Add_IfNotIn_list( (DataListTyp)LookNameE(e), vl, EqInt );
  else
    for ( i = NumArgE(e); i > 0; i-- )
      Vars_Of_Expr(LookArgE(e,i));
}

/* VarsOfEL
 * Return a list of variable names used in an expression list el
 */
ListTyp VarsOfEL( el )
     ExprListTyp el;
{
  vl = Create_list();
  while ( el!=NULL ) {
    Vars_Of_Expr((ExprTyp)LookInfo_list(el));
    el=Next_list(el);
  }
  return vl;
}

/*----------------------------------------------------------------*/

/* EqualEL
 * return el1 equal to el2
 */
boolean EqualEL( el1, el2 )
     ExprListTyp el1,el2;
{
  return Equal_list( el1, el2, EqualE );
}

/*----------------------------------------------------------------*/

static ListTyp vvl;

static void VarInExprAux( e )
     ExprTyp e;
{
  int n,i;
  ExprTyp a;

  if ( IsVariableE(e) ) {
    vvl = InsertEL(e,vvl);
  }
  else {
    n=NumArgE(e);
    for (i=1 ; i<=n ; i++) {
      a = LookArgE(e,i);
      VarInExprAux(a);
    }
  }
}

/* LookVarsInExpr
 * Return a list of pointers to the variables in the expression e.
 */
ListTyp LookVarsInExpr( e )
     ExprTyp e;
{
  vvl = CreateEL();
  VarInExprAux( e );
  return vvl;
}

/*----------------------------------------------------------------*/






