/*-------------------------------------------------------------------------* * CHECK_VARIABLE * * * *-------------------------------------------------------------------------*/ static Bool Check_Variable(WamWord *adr, WamWord var_word) { WamWord word, tag_mask; WamWord *adr1; PlLong *p; if (Tag_Of(var_word) == FDV) /* improve FDV */ return FALSE; for (p = pl_glob_dico_var; p < base_var_ptr; p++) /* check if already found until now */ if (*p == (PlLong) adr) /* test if already present (thus well dereferenced) */ return TRUE; if (base_var_ptr >= var_ptr) return FALSE; /* not found */ /* check if Specific has been modified (also deref which is important) */ DEREF(*base_var_ptr, word, tag_mask); if (Tag_Of(word) != REF) /* TODO: treat FD vars */ return FALSE; /* specific has been instantiated - no longer a var */ adr1 = UnTag_REF(word); /* save dereferenced adr */ if (adr1 != adr) /* check if it is the current variable */ return FALSE; /* not ok */ *base_var_ptr = (PlLong) adr1; /* replace adr by dereferenced adr */ base_var_ptr++; return TRUE; }
/*-------------------------------------------------------------------------* * PL_TREAT_VARS_OF_TERM * * * * Call fct for each variable found in a term. * *-------------------------------------------------------------------------*/ void Pl_Treat_Vars_Of_Term(WamWord start_word, Bool generic_var, void (*fct) ()) { WamWord word, tag_mask; WamWord *adr; int i; terminal_rec: DEREF(start_word, word, tag_mask); switch (Tag_Of(word)) { case REF: (*fct) (UnTag_REF(word), word); break; #ifndef NO_USE_FD_SOLVER case FDV: if (generic_var) (*fct) (UnTag_FDV(word), word); break; #endif case LST: adr = UnTag_LST(word); adr = &Car(adr); Pl_Treat_Vars_Of_Term(*adr++, generic_var, fct); start_word = *adr; goto terminal_rec; case STC: adr = UnTag_STC(word); i = Arity(adr); adr = &Arg(adr, 0); while (--i) Pl_Treat_Vars_Of_Term(*adr++, generic_var, fct); start_word = *adr; goto terminal_rec; } }
/*-------------------------------------------------------------------------* * PL_COPY_CONTIGUOUS_TERM * * * * Copy a contiguous term (dereferenced), the result is a contiguous term. * *-------------------------------------------------------------------------*/ void Pl_Copy_Contiguous_Term(WamWord *dst_adr, WamWord *src_adr) #define Old_Adr_To_New_Adr(adr) ((dst_adr)+((adr)-(src_adr))) { WamWord word, *adr; WamWord *q; int i; terminal_rec: word = *src_adr; switch (Tag_Of(word)) { case REF: adr = UnTag_REF(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_REF(q); if (adr > src_adr) /* only useful for Dont_Separate_Tag */ Pl_Copy_Contiguous_Term(q, adr); return; #ifndef NO_USE_FD_SOLVER case FDV: adr = UnTag_FDV(word); Fd_Copy_Variable(dst_adr, adr); return; #endif case FLT: adr = UnTag_FLT(word); q = Old_Adr_To_New_Adr(adr); q[0] = adr[0]; #if WORD_SIZE == 32 q[1] = adr[1]; #endif *dst_adr = Tag_FLT(q); return; case LST: adr = UnTag_LST(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_LST(q); q = &Car(q); adr = &Car(adr); Pl_Copy_Contiguous_Term(q++, adr++); dst_adr = q; src_adr = adr; goto terminal_rec; case STC: adr = UnTag_STC(word); q = Old_Adr_To_New_Adr(adr); *dst_adr = Tag_STC(q); Functor_And_Arity(q) = Functor_And_Arity(adr); i = Arity(adr); q = &Arg(q, 0); adr = &Arg(adr, 0); while (--i) Pl_Copy_Contiguous_Term(q++, adr++); dst_adr = q; src_adr = adr; goto terminal_rec; default: *dst_adr = word; return; } }