ftp.nice.ch/pub/next/unix/audio/Cmix.N.s.tar.gz#/cmix/Minc/trees.c

This is trees.c in view mode; [Download] [Up]

/*
*   intermediate representation
*/


#include "defs.h"	
#include <stdio.h>

double   *disp_args;
int	 arg_count;
double *arg_list_stack[MAXSTACK];
int    arg_count_stack[MAXSTACK];
int    stack_ptr;
double  parse_dispatch();

char	buf[500];
extern Tree tp1,tp2,tp3;
extern int i1,i2,i3;
extern double f1,f2,f3;
/*
*   floating point comparisons:
*   f1 < f2  ==> -1
*   f1 = f2  ==> 0
*   f1 > f2  ==> 1 
*/
/*  useless funtion */
foo(){};
foo2(){};


cmp (f1,f2)
double f1,f2;
{
foo();
	if (fabs(f1-f2)< EPS){// printf("cmp=%g %g %g \n",f1,f2,fabs(f1-f2));
			return (0);
			}
	if ((f1-f2)   > EPS) { //printf("cmp > %g %g %g \n",f1,f2,fabs(f1-f2)); 
			return (1);
			}
	if ((f2-f1)   > EPS) {// printf("cmp <%g %g %g \n",f1,f2,fabs(f1-f2)); 
			return (-1);
			}
}





Tree  node(op,kind)
int	op;
int	kind;
{
Tree	tp1;	

	tp1 = (Tree) emalloc(sizeof(struct tree));
	tp1->op = op;
	tp1->kind = kind;
	tp1->u.child[0] = NULL;
	tp1->u.child[1] = NULL;
	tp1->u.child[2] = NULL;
	tp1->u.child[3] = NULL;
	return tp1;
}


/*
Tree   tproc(){};
*/

Tree   tnoop()
{
Tree	tp1;
foo();
	tp1=node(FREE,TNOOP);
return (tp1);
}


Tree   tseq(e1,e2)
Tree	e1,e2;
{
Tree	tp1;
foo();
	tp1=node(FREE,SEQ);

	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;
	
}

Tree	top(op,e1,e2)
Tree	e1,e2;
int	op;
{

Tree	tp1;
foo();

	tp1 =node (op,OP);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;
}

Tree	tunop(op,e1)
Tree	e1;
int	op;
{
Tree	tp1;
foo();

	tp1 = node(op,UNOP);
	tp1->u.child[0] = e1;
	return tp1;
}

Tree	tconvert(op,e1)
int	op;
Tree	e1;
{

Tree	tp1;
foo();

	tp1=node (op,CONVERT);
	tp1->u.child[0] = e1;
	return tp1;
}

/*
Tree 	tfetch(){};
*/

Tree	tstore(e1,e2)
Tree	e1,e2;
{

Tree	tp1;
foo();


	tp1 = node(FREE,STORE);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;

}

	
/* 
Tree tmove(){};
*/

/*   not used ********************* 
Tree	teseq(stm,e1)
Tree	stm,e1;
{
Tree	tp1;
foo();
	tp1 = node(FREE,ESEQ);
	tp1->u.child[0] = stm;
	tp1->u.child[1] = e1;
	return tp1;
}
*/

/*
Tree	tbool(){}
*/

/*
*  converts symbol table entry into tree
*  or initialize tree node to a symbol entry
*/

Tree	tname(sym)	
SYMBOL  *sym;

{

Tree	tp1;
foo();

	tp1 = node(FREE,NAME);
	tp1->u.sym = sym;	
	return tp1;
}

Tree	tconst(ival)
int	ival;
{
Tree	tp1;
foo();
	tp1 = node(FREE,CONST);
	tp1->u.ival = ival;
	return tp1;
}

Tree	tconstf(fval)
double	fval;
{
Tree	tp1;
foo();
	tp1 = node(FREE,CONSTF);
	tp1->u.fval = fval;
	return tp1;
}

/*
Tree falloc(){}
Tree ttemp(){}
*/


Tree  tcall(e1,str)
Tree	e1;   /*arguments*/
char	*str;	/* name of function to call */
{

Tree	tp1;
foo();
	tp1 = node(FREE,CALL);
	tp1->x.fctname = str;
	tp1->u.child[0] = e1;
	return tp1;
}


Tree	tcand(test1,test2)
Tree	test1,test2;
{

Tree	tp1;
foo();
	tp1 = node(FREE,CAND);
	tp1->u.child[0] = test1;
	tp1->u.child[1] = test2;
	return tp1;
}

Tree	tcor(test1,test2)
Tree	test1,test2;
{

Tree	tp1;
foo();
	tp1 = node(FREE,COR);
	tp1->u.child[0] = test1;
	tp1->u.child[1] = test2;
	return tp1;
}
	

	

Tree	tnot(test1)
Tree	test1;
{

Tree	tp1;
foo();
	tp1 = node(FREE,NOT);
	tp1->u.child[0] = test1;
	return tp1;
}

Tree    trel(op,e1,e2)
int	op;
Tree	e1,e2;
{

Tree	tp1;
foo();
	tp1 = node (op,REL);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;

}

Tree targ(e1,args)
Tree e1,args;
{

Tree	tp1;
foo();
	tp1 = node(FREE,ARG);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = args;
	return tp1;
}

Tree tnoargs()
{
Tree	tp1;
foo();
	tp1 = node(FREE,NOARGS);
	return tp1;
}


Tree tif(e1,e2)
Tree	e1,e2;
{

Tree	tp1;
foo();
	tp1 = node (FREE,TIF);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;
}


Tree tifelse(e1,e2,e3)
Tree	e1,e2,e3;
{

Tree	tp1;
foo();
	tp1 = node (FREE,TIFELSE);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	tp1->u.child[2] = e3;
	return tp1;
}


Tree tfor(e1,e2,e3,e4)
Tree	e1,e2,e3,e4;
{

Tree	tp1;
foo();
	tp1 = node (FREE,TFOR);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	tp1->u.child[2] = e3;
	tp1->u.child[3] = e4;
	return tp1;
}

Tree twhile(e1,e2)
Tree	e1,e2;
{

Tree	tp1;
foo();
	tp1 = node (FREE,TWHILE);
	tp1->u.child[0] = e1;
	tp1->u.child[1] = e2;
	return tp1;
}

/*
*
*
*   This recursive function interprets the intermediate code 
*
*/


Tree exct(tp)
Tree   tp;

{
int i;


if (tp == NULL) return (NULL);

switch (tp->kind)  {

   case	SEQ: {
		exct(tp->u.child[0]);			
		exct(tp->u.child[1]);			
		break;
	}
	/*  puts value and type into symbol pted to by child[0]u.sym */
   case	STORE: {
		/* TBD: include handlng of different types */
		tp->u.child[0]->u.sym->v.fval = exct(tp->u.child[1])->v.fval;
		tp->u.child[0]->u.sym->type = tp->u.child[1]->type;
		tp->v.fval = tp->u.child[0]->u.sym->v.fval;
		tp->type = tp->u.child[1]->type;
		break;
	}
	
 	/*  assign what's in the symobol into tree's value field */ 
   case	NAME:  {
		tp->type = tp->u.sym->type;
		tp->v.fval = tp->u.sym->v.fval;
		break;
	}
   case	CONST: {
		tp->type = T_INT;
		tp->v.ival = tp->u.ival;
		break;
	}
   case	CONSTF: {
		tp->type = T_FLOAT;
		tp->v.fval = tp->u.fval;
		break;
	}
   case ARG:    {
		exct(tp->u.child[0]);
		if (arg_count ==MAXDISPARGS) 
			i_error("exeeded maximum number of arguments for a function call"); 
		disp_args[arg_count++] = exct(tp->u.child[1])->v.fval;
		break;
		}
   case NOARGS:  {  /* do nothing */
		break;
		}
	
   case	CALL:   {
	 	/* TBD:  distinguish between internal or dispatcher function */	

		push_args ();	
		exct(tp->u.child[0]);

		for (i=arg_count;i<MAXDISPARGS;i++) disp_args[i]=0;
		tp->v.fval = parse_dispatch (tp->x.fctname,
							disp_args,arg_count);
		pop_args ();
		tp->type =  T_FLOAT;
		
		break;
	}
	
   case	NOT: {
		tp->type = T_FLOAT;
		if(cmp(0.0,exct(tp->u.child[0])->v.fval)==0)
			tp->v.fval = 1.0;
		else    tp->v.fval = 0.0;
		break;
	}
   case	CAND: {
		tp->type = T_FLOAT;
		tp->v.fval = 0.0;
		if(cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
		   if(cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0)
			{ tp->type = T_FLOAT;
			  tp->v.fval = 1.0;
			}
		break;
	}
   case	REL:  {
		tp->type = T_FLOAT;
		
	    switch((int)tp->op)  {
		
       case EQ: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)== 0)
		tp->v.fval = 1.0;
	     else 
		tp->v.fval = 0.0;
	     break;		
	    }
       case NEQ: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)== 0)
		tp->v.fval = 0.0;
	     else 
		tp->v.fval = 1.0;
	     break;		
	    }
	case LT: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)== -1)
		tp->v.fval = 1.0;
	     else 
		tp->v.fval = 0.0;
	     break;		
	    }
	case    GT: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)== 1)
		tp->v.fval = 1.0;
	     else 
		tp->v.fval = 0.0;
	     break;		
	    }
	case    LEQ: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)<= 0)
		tp->v.fval = 1.0;
	     else 
		tp->v.fval = 0.0;
	     break;		
	    }
	case    GEQ: {
	     if(cmp(exct(tp->u.child[0])->v.fval,
			exct(tp->u.child[1])->v.fval)>= 0)
		tp->v.fval = 1.0;
	     else 
		tp->v.fval = 0.0;
	     break;		
	    }
	default: {
			foo2();
			sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f;   type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
			msg(buf);
			i_warning("tried to execute illegal REL in exct");
		}
	  }
	  break;  /* switch REL */
	} 
  case	OP:{
		tp->type = T_FLOAT;
	   switch ((int)tp->op){
		
	  case	PLUS: {
		   	tp->v.fval=exct(tp->u.child[0])->v.fval +	
		   	          	 exct(tp->u.child[1])->v.fval; 	
			break;
		}
	  case	MINUS: {
		   	tp->v.fval=exct(tp->u.child[0])->v.fval -	
		   	          	 exct(tp->u.child[1])->v.fval; 	
			break;
		}
	  case	MUL: {
		   	tp->v.fval=exct(tp->u.child[0])->v.fval *	
		   	          	 exct(tp->u.child[1])->v.fval; 	
			break;
		}
	  case	DIV: {
		   	tp->v.fval=exct(tp->u.child[0])->v.fval /	
		   	          	 exct(tp->u.child[1])->v.fval; 	
			break;
		}
	  case	POW: {
		   	tp->v.fval=pow(exct(tp->u.child[0])->v.fval ,	
		   	          	 exct(tp->u.child[1])->v.fval);
		 	break; 
		}
	default: {
			foo2();
			sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f;   type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
			msg(buf);
			i_warning("tried to execute illegal OP in exct");
		}
	   }
	   break; /*  switch  OP */
	   				 
	   } 
  case	   CONVERT: {
		tp->type = T_FLOAT;
		switch (tp->op) {
/******  TBD: THE CONVERSION FUNCTIONS NEED TO BE COMPLETED  ******/
		  case	CVTOC: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
		  case	CVTOL: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
		  case	CVTLO: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
		  case	CVTLC: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
		  case	CVTCL: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
		  case	CVTCO: { tp->v.fval=exct(tp->u.child[0])->v.fval;
				break;
			      } 
	default: {
			foo2();
			sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f;   type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
			msg(buf);
			i_warning("tried to execute illegal CVT in exct");
		}
	   	} 
		break; /* switch CONVERT */	
	 }
  case	UNOP: {
		tp->type = T_FLOAT;
		if (tp->op == NEG) 
		     tp->v.fval= - exct(tp->u.child[0])->v.fval;
		break;
	}
  case	COR: {
		tp->type = T_FLOAT;
		tp->v.fval = 0;
		if((cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0) ||
		     (cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0))
			{ tp->v.fval = 1;
			}
		break;
	}
  case	TIF: {
		if (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
			exct(tp->u.child[1]);
		break;
	}
  case	TIFELSE: {
		if (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
			exct(tp->u.child[1]);
		else
			exct(tp->u.child[2]);
		break;
	}
  case	TWHILE: {
		while (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
			exct(tp->u.child[1]);
		break;
	}
  case  TNOOP:  {break;}
  case	TFOR: {
/*
		for (exct(tp->u.child[0]);cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0;
				exct(tp->u.child[2]))
*/
		exct(tp->u.child[0]);
		while (cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0) {
			exct(tp->u.child[3]);
			exct(tp->u.child[2]);
		}
		break;
	}
	default: {
			foo2();
			sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f;   type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
			msg(buf);
			i_warning("tried to execute illegal node in exct");
		}

   }   /*  switch  kind */
return (tp);
}
		


	    
/* keeps a stack of dispatch argument lists */
push_args ()
{
	char *malloc();
	    
if (stack_ptr >= MAXSTACK) 
	i_error ("stack overflow: too many nested function calls");
arg_list_stack[stack_ptr] = disp_args;
arg_count_stack[stack_ptr++] = arg_count;
disp_args = (double *) malloc (sizeof(double) * MAXDISPARGS);
arg_count = 0;
}
		
pop_args ()
{
free (disp_args);
if (stack_ptr == 0 ) 
	i_error ("stack underflow");
disp_args = arg_list_stack[--stack_ptr];
arg_count = arg_count_stack[stack_ptr];
		
}
		
		
/*
*
*
*   This recursive function frees space.
*
*/


free_tree(tp)
Tree   tp;
{


if (tp == NULL) return (NULL);

switch (tp->kind)  {

   case	SEQ: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
   case	STORE: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
   case	NAME:  {
		break;
	}
   case	CONST: {
		break;
	}
   case	CONSTF: {
		break;
	}
   case ARG:    {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
		}
   case NOARGS:  { 
		break;
		}
   case	CALL:   {
		free_tree(tp->u.child[0]);
		break;
	}
   case	NOT: {
		free_tree(tp->u.child[0]);
		break;
	}
   case	CAND: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
   case	REL:  {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	} 
  case	OP:{
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	   } 
  case	   CONVERT: {
		free_tree(tp->u.child[0]);
		break;
	 }
  case	UNOP: {
		free_tree(tp->u.child[0]);
		break;
	}
  case	COR: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
  case	TIF: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
  case	TIFELSE: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		free_tree(tp->u.child[2]);
		break;
	}
  case	TWHILE: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		break;
	}
  case  TNOOP:  {
		break;
	}
  case	TFOR: {
		free_tree(tp->u.child[0]);
		free_tree(tp->u.child[1]);
		free_tree(tp->u.child[2]);
		free_tree(tp->u.child[3]);
		break;
	}

   }   /*  switch  kind */

free(tp);  /* actually free space */

}
		

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.