/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : synthetiseur logique                                        */
/*    Fichier : nonbal.c                                                    */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : L. Burgun                             le : 31/01/1992     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include MUT_H
#include LOG_H
#include BEH_H
#include "balance.h"


void displayCarac1(expr,caracTH)
chain_list *expr;
pTH caracTH;
{
if (ATOM(expr))
   printf(" %d",searchTH(caracTH,expr));
else
   {
   printf(" (%s%d",operToChar(OPER(expr)),lengthExpr(expr));
   while (expr = CDR(expr))
         printf(" %d",searchTH(caracTH,CAR(expr)));
   printf(")");
   }
}

void displayCarac(expr,caracTH)
chain_list *expr;
pTH caracTH;
{
if (ATOM(expr))
   printf(" %d",searchTH(caracTH,expr));
else
   {
   printf(" (%s",operToChar(OPER(expr)));
   while (expr = CDR(expr))
         displayCarac(CAR(expr),caracTH);
   printf(")");
   }
}

/*-------------------------------------------------------------------------
nonBalanceExpr: renvoie l'expression non balancee correspondant a une
             expression a decomposer. 
---------------------------------------------------------------------------
retour		: une expression
---------------------------------------------------------------------------*/
chain_list *nonBalanceExpr(beh,delaisTH,expr,echantil,grain)
befig_list *beh;
pTH delaisTH;
chain_list *expr;
int echantil, grain;
{
printf("nonBal : grain = %d, echantil = %d\n ***",grain,echantil);
displayExpr(expr);
displayCarac1(expr,delaisTH); printf("\n");

if (lengthExpr(expr) <= grain)
   {
   chain_list *ret = copyExpr(expr);

   calculDelaisExpr(beh,delaisTH,ret,0);
   return ret;
   }
else
   {
   int oper = OPER(expr);
   chain_list *exprAdd = createExpr(oper);
   chain_list *exprRet, *aux;
   chain_list *oldExpr = expr;
   int borne = echantil + searchTH(delaisTH,CADR(expr));

	/* creation d'une ss-expr avec le premier echantillon */
   while ((expr = CDR(expr)) && (searchTH(delaisTH,CAR(expr)) < borne))
         addQExpr(exprAdd,copyExpr(CAR(expr)));

	/* cas ou un seul argument passe dans l'echantillon */
   if (lengthExpr(exprAdd) == 1)
      {
      printf("nonBal : un seul arg\n");
      freeExpr(exprAdd);
      return nonBalanceExpr(beh,delaisTH,oldExpr,2*echantil,grain);
      }

   printf("nonBal : expr echantillonnee\n"); 
   displayExpr(exprAdd);

   if (lengthExpr(exprAdd) > grain)
      {
		/* si la ss-expr ne respecte pas le grain : decomp balancee */

      aux = balanceExpr(exprAdd,1,grain);
      }
    else
      aux = copyExpr(exprAdd);
    freeExpr(exprAdd);

   if (expr)
      {

	/* si tous les arguments de expr ne sont pas dans la ss-expr */

      exprRet = createExpr(oper);
      addQExpr(exprRet,aux);
      while(expr)
           {
           addQExpr(exprRet,copyExpr(CAR(expr)));
           expr = CDR(expr);
           }
      }
    else
      {
      exprRet = aux;
      }

   calculDelaisExpr(beh,delaisTH,exprRet,0);
   printf("nonBal : apres calculDelais\n");
   displayExpr(exprRet);
   displayCarac1(exprRet,delaisTH); printf("\n");
   return nonBalanceExpr(beh,delaisTH,exprRet,2*echantil,grain);
   }
}
