Files
SAPFOR/dvm/fdvm/trunk/parser/low_hpf.c

1007 lines
24 KiB
C
Raw Normal View History

2024-10-04 15:26:19 +03:00
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h> /* ANSI variable argument header */
#include "compatible.h" /* Make different system compatible... (PHB) */
#ifdef SYS5
#include <string.h>
#else
#include <strings.h>
#endif
#include "vpc.h"
#include "macro.h"
#include "ext_lib.h"
#define HPF_STRING 2
/*int debug =NO; used in db.c*/
/*static int number_of_bif_node = 0;*/
/*int number_of_ll_node = 0; this counters are useless anymore */
/*static int number_of_symb_node = 0;
static int number_of_type_node = 0;*/
/* FORWARD DECLARATIONS (phb) */
void Message();
char * filter();
int *evaluateExpression();
extern int write_nodes();
extern char* Tool_Unparse2_LLnode();
extern void Init_HPFUnparser();
extern char* Tool_Unparse_Bif ();
extern char* Tool_Unparse_Type();
#define MAXFIELDSYMB 10
#define MAXFIELDTYPE 10
#ifdef __SPF
extern void removeFromCollection(void *pointer);
#endif
#ifdef __SPF_BUILT_IN_PARSER
static int Warning_count = 0;
//static PTR_FILE pointer_on_file_proj;
//static char* default_filename;
/* records propoerties and type of node */
//static char node_code_type[LAST_CODE];
/* Number of argument-words in each kind of tree-node. */
//static int node_code_length[LAST_CODE];
//static enum typenode node_code_kind[LAST_CODE];
/* special table for infos on type and symbol */
static char info_type[LAST_CODE][MAXFIELDTYPE];
static char info_symb[LAST_CODE][MAXFIELDSYMB];
static char general_info[LAST_CODE][MAXFIELDSYMB];
#else
PTR_FILE pointer_on_file_proj;
char* default_filename;
int Warning_count = 0;
/* records propoerties and type of node */
char node_code_type[LAST_CODE];
/* Number of argument-words in each kind of tree-node. */
int node_code_length[LAST_CODE];
enum typenode node_code_kind[LAST_CODE];
/* special table for infos on type and symbol */
char info_type[LAST_CODE][MAXFIELDTYPE];
char info_symb[LAST_CODE][MAXFIELDSYMB];
char general_info[LAST_CODE][MAXFIELDSYMB];
#endif
/*static struct bif_stack_level *stack_level = NULL;
static struct bif_stack_level *current_level = NULL;*/
PTR_BFND getFunctionHeader();
#ifdef __SPF_BUILT_IN_PARSER
#define xmalloc xmalloc_temp
#define make_a_malloc_stack make_a_malloc_stack_temp
#define mymalloc mymalloc_temp
#define isATypeNode isATypeNode_temp
#define isASymbNode isASymbNode_temp
#define isABifNode isABifNode_temp
#define isALoNode isALoNode_temp
#define hasTypeBaseType hasTypeBaseType_temp
#define isStructType isStructType_temp
#define isPointerType isPointerType_temp
#define isUnionType isUnionType_temp
#define isEnumType isEnumType_temp
#define hasTypeSymbol hasTypeSymbol_temp
#define isAtomicType isAtomicType_temp
#define hasNodeASymb hasNodeASymb_temp
#define isNodeAConst isNodeAConst_temp
#define isAStructDeclBif isAStructDeclBif_temp
#define isAUnionDeclBif isAUnionDeclBif_temp
#define isAEnumDeclBif isAEnumDeclBif_temp
#define isADeclBif isADeclBif_temp
#define isAControlEnd isAControlEnd_temp
#define Message Message_temp
#define Check_Lang_Fortran Check_Lang_Fortran_temp
#define filter filter_temp
#define allocateValueEvaluate allocateValueEvaluate_temp
#define addElementEvaluate addElementEvaluate_temp
#define getElementEvaluate getElementEvaluate_temp
#define resetPresetEvaluate resetPresetEvaluate_temp
#define evaluateExpression evaluateExpression_temp
#define patternMatchExpression patternMatchExpression_temp
#define Follow_Llnd Follow_Llnd_temp
#endif
/*****************************************************************************
* *
* Procedure of general use *
* *
*****************************************************************************/
/***************************************************************************/
void Message(s, l)
char *s;
int l;
{
if (l != 0)
fprintf(stderr,"Warning : %s line %d\n",s, l);
else
fprintf(stderr,"Warning : %s\n",s);
Warning_count++;
}
/* Modified to return a pointer (64bit clean) (phb) */
/***************************************************************************/
char* xmalloc(size)
int size;
{
char *val;
val = (char *) malloc (size);
if (val == 0)
Message("Virtual memory exhausted (malloc failed)",0);
return val;
}
/* list of allocated data */
static ptstack_chaining Current_Allocated_Data = NULL;
static ptstack_chaining First_STACK= NULL;
/***************************************************************************/
void make_a_malloc_stack()
{
ptstack_chaining pt;
pt = (ptstack_chaining) malloc(sizeof(struct stack_chaining));
if (!pt)
{
Message("sorry : out of memory\n",0);
exit(1);
}
if (Current_Allocated_Data)
Current_Allocated_Data->next = pt;
pt->first = NULL;
pt->last = NULL;
pt->prev = Current_Allocated_Data;
if (Current_Allocated_Data)
pt->level = Current_Allocated_Data->level +1;
else
pt->level = 0;
/* printf("make_a_malloc_stack %d \n",pt->level);*/
Current_Allocated_Data = pt;
if (First_STACK == NULL)
First_STACK = pt;
}
/***************************************************************************/
char* mymalloc(size)
int size;
{
char *pt1;
ptchaining pt2;
if (!Current_Allocated_Data)
{
Message("Allocated Stack not defined\n",0);
exit(1);
}
/* if (Current_Allocated_Data->level > 0)
printf("mymalloc %d \n", Current_Allocated_Data->level); */
pt1 = (char *) malloc(size);
if (!pt1)
{
Message("sorry : out of memory\n",0);
exit(1);
}
pt2 = (ptchaining) malloc(sizeof(struct chaining));
if (!pt2 )
{
Message("sorry : out of memory\n",0);
exit(1);
}
pt2->zone = pt1;
pt2->list = NULL;
if (Current_Allocated_Data->first == NULL)
Current_Allocated_Data->first = pt2;
if (Current_Allocated_Data->last == NULL)
Current_Allocated_Data->last = pt2;
else
{
Current_Allocated_Data->last->list = pt2;
Current_Allocated_Data->last = pt2;
}
return pt1;
}
/***************** Provides infos on nodes ********************************
* *
* based on the table info in include dir *.def *
* *
**************************************************************************/
/***************************************************************************/
int isATypeNode(variant)
int variant;
{
return (TYPENODE == (int) node_code_kind[variant]);
}
/***************************************************************************/
int isASymbNode(variant)
int variant;
{
return (SYMBNODE == (int) node_code_kind[variant]);
}
/***************************************************************************/
int isABifNode(variant)
int variant;
{
return (BIFNODE == (int) node_code_kind[variant]);
}
/***************************************************************************/
int isALoNode(variant)
int variant;
{
return (LLNODE == (int) node_code_kind[variant]);
}
/***************************************************************************/
int hasTypeBaseType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("hasTypeBaseType not applied to a type node",0);
return 0;
}
if (info_type[variant][2] == 'b')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isStructType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("isStructType not applied to a type node",0);
return 0;
}
if (info_type[variant][0] == 's')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isPointerType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("isPointerType not applied to a type node",0);
return 0;
}
if (info_type[variant][0] == 'p')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isUnionType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("isUnionType not applied to a type node",0);
return 0;
}
if (info_type[variant][0] == 'u')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isEnumType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("EnumType not applied to a type node",0);
return 0;
}
if (info_type[variant][0] == 'e')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int hasTypeSymbol(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("hasTypeSymbol not applied to a type node",0);
return 0;
}
if (info_type[variant][1] == 's')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isAtomicType(variant)
int variant;
{
if (!isATypeNode(variant))
{
Message("isAtomicType not applied to a type node",0);
return 0;
}
if (info_type[variant][0] == 'a')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int hasNodeASymb(variant)
int variant;
{
if ((!isABifNode(variant)) && (!isALoNode(variant)))
{
Message("hasNodeASymb not applied to a bif or low level node",0);
return 0;
}
if (general_info[variant][2] == 's')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isNodeAConst(variant)
int variant;
{
if ((!isABifNode(variant)) && (!isALoNode(variant)))
{
Message("isNodeAConst not applied to a bif or low level node",0);
return 0;
}
if (general_info[variant][1] == 'c')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isAStructDeclBif(variant)
int variant;
{
if (!isABifNode(variant))
{
Message("isAStructDeclBif not applied to a bif",0);
return 0;
}
if (general_info[variant][1] == 's')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isAUnionDeclBif(variant)
int variant;
{
if (!isABifNode(variant))
{
Message("isAUnionDeclBif not applied to a bif",0);
return 0;
}
if (general_info[variant][1] == 'u')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isAEnumDeclBif(variant)
int variant;
{
if (!isABifNode(variant))
{
Message("isAEnumDeclBif not applied to a bif",0);
return 0;
}
if (general_info[variant][1] == 'e')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isADeclBif(variant)
int variant;
{
if (!isABifNode(variant))
{
Message("isADeclBif not applied to a bif",0);
return 0;
}
if (general_info[variant][0] == 'd')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int isAControlEnd(variant)
int variant;
{
if (!isABifNode(variant))
{
Message("isAControlEnd not applied to a bif",0);
return 0;
}
if (general_info[variant][0] == 'c')
return TRUE;
else
return FALSE;
}
/***************************************************************************/
int Check_Lang_Fortran(proj)
PTR_PROJ proj;
{
PTR_FILE ptf;
PTR_BLOB ptb;
/* Change FALSE to TRUE */
if (!proj)
return TRUE;
for (ptb = PROJ_FILE_CHAIN (proj); ptb ; ptb = BLOB_NEXT (ptb))
{
ptf = (PTR_FILE) BLOB_VALUE (ptb);
/* if (debug)
fprintf(stderr,"%s\n",FILE_FILENAME (ptf)); */
if (FILE_LANGUAGE(ptf) != ForSrc)
return(FALSE);
}
return(TRUE);
}
/***************************************************************************/
char* filter(s)
char *s;
{
char c;
int i = 1;
char temp[1024];
int temp_i = 0;
int buf_i = 0;
int commentline = 0;
char *resul, *init;
if (!s) return NULL;
if (strlen(s)==0) return s;
/* allocate very simple, but to redo later, allocate two times the size */
make_a_malloc_stack();
resul = (char *) mymalloc((int)(2*strlen(s)));
memset(resul, 0, 2*strlen(s));
init = resul;
/* find the separator */
c = s[0];
if ((c != ' ')
&&(c != '\n')
&& (c != '0')
&& (c != '1')
&& (c != '2')
&& (c != '3')
&& (c != '4')
&& (c != '5')
&& (c != '6')
&& (c != '7')
&& (c != '8')
&& (c != '9'))
if ( c=='!') commentline = HPF_STRING;
else commentline = 1;
else
commentline = 0;
temp_i = 0;
i = 0;
buf_i =0;
while (c!='\0')
{
c = s[i];
temp[ buf_i] = c;
if (c == '\n')
{
temp[ buf_i+1] = '\0';
sprintf(resul,"%s",temp);
resul = resul + strlen(temp);
temp_i = -1;
buf_i = -1;
if ((s[i+1] != ' ')
&&(s[i+1] != '\n')
&& (s[i+1] != '0')
&& (s[i+1] != '1')
&& (s[i+1] != '2')
&& (s[i+1] != '3')
&& (s[i+1] != '4')
&& (s[i+1] != '5')
&& (s[i+1] != '6')
&& (s[i+1] != '7')
&& (s[i+1] != '8')
&& (s[i+1] != '9'))
if (s[i+1] == '!') commentline = HPF_STRING;
else commentline = 1;
else
commentline = 0;
} else
{
if ((temp_i == 71) && !commentline)
{
/* insert where necessary */
temp[ buf_i+1] = '\0';
sprintf(resul,"%s\n",temp);
resul = resul + strlen(temp)+1;
sprintf(resul," +");
resul = resul + strlen(" +");
commentline = 0;
memset(temp, 0, 1024);
temp_i = strlen(" +")-1;
buf_i = -1;
}
if ((temp_i == 71) && (commentline==HPF_STRING))
{
/* insert where necessary */
int count=0;
for(;s[i]!='$';i--,count++)
{
if (strncmp(&(s[i]),"ONTO", strlen("ONTO"))== 0)
break;
if (strncmp(&(s[i]),"BEGIN", strlen("BEGIN"))== 0)
break;
if (strncmp(&(s[i]),"ON", strlen("ON"))== 0)
{
i+=3;count-=3;
break;
}
if (strncmp(&(s[i]),"WITH", strlen("WITH"))== 0)
break;
if (strncmp(&(s[i]),"NEW", strlen("NEW"))== 0)
break;
if (strncmp(&(s[i]),"REDUCTION", strlen("REDUCTION"))== 0)
break;
if (strncmp(&(s[i]),"TEMPLATE", strlen("TEMPLATE"))== 0)
break;
if (strncmp(&(s[i]),"SHADOW", strlen("SHADOW"))== 0)
break;
if (strncmp(&(s[i]),"INHERIT", strlen("INHERIT"))== 0)
break;
if (strncmp(&(s[i]),"DYNAMIC", strlen("DYNAMIC"))== 0)
break;
if (strncmp(&(s[i]),"DIMENSION", strlen("DIMENSION"))== 0)
break;
if (strncmp(&(s[i]),"PROCESSORS", strlen("PROCESSORS"))== 0)
break;
if (strncmp(&(s[i]),"DISTRIBUTE", strlen("DISTRIBUTE"))== 0)
break;
if (strncmp(&(s[i]),"ALIGN", strlen("ALIGN"))== 0)
break;
if (strncmp(&(s[i]),"::", strlen("::"))== 0)
{
/*i+=3;count-=3;*/
break;
}
}
i--;count++;
if (count<36)
temp[ buf_i+1-count] = '\0';
else
{
i+=count;
temp[ buf_i+1] = '\0';
}
sprintf(resul,"%s\n",temp);
resul = resul + strlen(temp)+1;
sprintf(resul,"!HPF$*");
resul = resul + strlen("!HPF$*");
/*8commentline = 0;*/
memset(temp, 0, 1024);
temp_i = strlen("!HPF$*")-1;
buf_i = -1;
}
}
i++;
temp_i++;
buf_i++;
}
return init;
}
/* preset some values of symbols for evaluateExpression*/
#define ALLOCATECHUNKVALUE 100
static PTR_SYMB *ValuesSymb = NULL;
static int *ValuesInt = NULL;
static int NbValues = 0;
static int NbElement = 0;
/***************************************************************************/
void allocateValueEvaluate()
{
int i;
PTR_SYMB *pt1;
int *pt2;
pt1 = (PTR_SYMB *) xmalloc((int)( sizeof(PTR_SYMB *) *
(NbValues + ALLOCATECHUNKVALUE)));
pt2 = (int *) xmalloc((int)( sizeof(int *) * (NbValues + ALLOCATECHUNKVALUE)));
for (i=0; i<NbValues + ALLOCATECHUNKVALUE; i++) {
pt1[i] = NULL;
pt2[i] = 0;
}
for (i=0 ; i < NbValues; i++) {
pt1[i] = ValuesSymb[i];
pt2[i] = ValuesInt[i];
}
if (NbValues) {
#ifdef __SPF
removeFromCollection(ValuesSymb);
removeFromCollection(ValuesInt);
#endif
free(ValuesSymb);
free(ValuesInt);
}
ValuesSymb = pt1;
ValuesInt = pt2;
NbValues = NbValues + ALLOCATECHUNKVALUE;
}
/***************************************************************************/
void addElementEvaluate(symb, val)
PTR_SYMB symb;
int val;
{
if (!symb)
return;
while (NbValues <= ( NbElement+1))
{
allocateValueEvaluate();
}
ValuesSymb[NbElement] = symb;
ValuesInt[NbElement] = val;
NbElement++;
}
/***************************************************************************/
int getElementEvaluate(symb)
PTR_SYMB symb;
{
int i;
if (!symb)
return -1;
for (i=0 ; i < NbElement; i++)
{
if (ValuesSymb[i] == symb)
return i;
}
return -1;
}
/***************************************************************************/
void resetPresetEvaluate()
{
NbValues = 0;
NbElement = 0;
if (ValuesSymb)
{
#ifdef __SPF
removeFromCollection(ValuesSymb);
#endif
free(ValuesSymb);
}
if (ValuesInt)
{
#ifdef __SPF
removeFromCollection(ValuesInt);
#endif
free(ValuesInt);
}
ValuesSymb = NULL;
ValuesInt = NULL;
}
/***************************************************************************/
int* evaluateExpression(expr)
PTR_LLND expr;
{
int *res, *op1, *op2;
res = (int *) xmalloc((int)(2 * sizeof(int)));
memset((char *) res, 0, 2 * sizeof (int));
op1 = (int *) xmalloc((int)(2 * sizeof(int)));
memset((char *)op1, 0, 2 * sizeof (int));
op2 = (int *) xmalloc((int)(2 * sizeof(int)));
memset((char *) op2, 0, 2 * sizeof (int));
if (! expr)
{
res [0] = -1;
return res;
}
switch (BIF_CODE (expr))
{
case INT_VAL:
res [1] = NODE_INT_CST_LOW (expr);
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case ADD_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] + op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case MULT_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] * op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case SUBT_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] - op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case DIV_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] / op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case MOD_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] % op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case EXP_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
op2 = evaluateExpression (NODE_OPERAND1 (expr));
if ((op1 [0] == -1) || (op2 [0] == -1))
res [0] = -1;
else
res [1] = op1 [1] ^ op2 [1];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
case MINUS_OP :
op1 = evaluateExpression (NODE_OPERAND0 (expr));
if (op1 [0] == -1)
res [0] = -1;
else
res [1] = - op1 [1];
#ifdef __SPF
removeFromCollection(op1);
#endif
free(op1);
return res;
case VAR_REF: /* assume here that some value for Symbole are given*/
{
int ind;
if ((ind = getElementEvaluate(NODE_SYMB(expr))) != -1)
{
res [1] = ValuesInt[ind];
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
} else
{
res [0] = -1;
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
}
break;
}
default :
res [0] = -1;
#ifdef __SPF
removeFromCollection(op1);
removeFromCollection(op2);
#endif
free(op1); free(op2);
return res;
}
return res;
}
/***************************************************************************/
int patternMatchExpression(ll1,ll2)
PTR_LLND ll1,ll2;
{
int *res1, *res2;
if (ll1 == ll2)
return TRUE;
if (!ll1 || !ll2)
return FALSE;
if (NODE_CODE(ll1) != NODE_CODE(ll2))
return FALSE;
/* first test if constant equations identical */
res1 = evaluateExpression(ll1);
res2 = evaluateExpression(ll2);
if ((res1[0] != -1) &&
(res2[0] != -1) &&
(res1[1] == res2[1]))
{
#ifdef __SPF
removeFromCollection(res1);
removeFromCollection(res2);
#endif
free(res1);
free(res2);
return TRUE;
}
if ((res1[0] != -1) && (res2[0] == -1))
{
#ifdef __SPF
removeFromCollection(res1);
removeFromCollection(res2);
#endif
free(res1);
free(res2);
return FALSE;
}
if ((res1[0] == -1) && (res2[0] != -1))
{
#ifdef __SPF
removeFromCollection(res1);
removeFromCollection(res2);
#endif
free(res1);
free(res2);
return FALSE;
}
#ifdef __SPF
removeFromCollection(res1);
removeFromCollection(res2);
#endif
free(res1);
free(res2);
/* for each kind of node do the pattern match */
switch (NODE_CODE(ll1))
{
case VAR_REF:
if (NODE_SYMB(ll1) == NODE_SYMB(ll2))
return TRUE;
break;
/* commutatif operator */
case EQ_OP:
if ((NODE_SYMB(ll1) == NODE_SYMB(ll2)) &&
patternMatchExpression(NODE_OPERAND0(ll1),
NODE_OPERAND1(ll2)) &&
patternMatchExpression(NODE_OPERAND0(ll1),
NODE_OPERAND1(ll2)))
return TRUE;
default :
if ((NODE_SYMB(ll1) == NODE_SYMB(ll2)) &&
patternMatchExpression(NODE_OPERAND0(ll1),
NODE_OPERAND0(ll2)) &&
patternMatchExpression(NODE_OPERAND1(ll1),
NODE_OPERAND1(ll2)))
return TRUE;
}
return FALSE;
}
PTR_LLND Follow_Llnd(ll,c)
PTR_LLND ll;
int c;
{
PTR_LLND pt;
if(c == 2)
{
pt = ll;
while(pt)
{
if (NODE_OPERAND1(pt) == NULL)
return pt;
pt = NODE_OPERAND1(pt);
}
} else
{
pt = ll;
while(pt)
{
if (NODE_OPERAND1(pt) == NULL)
return NODE_OPERAND0(pt);
pt = NODE_OPERAND1(pt);
}
}
return NULL;
}