From f2e8f2ac2e41e796df3135bf74ac1a881716a3fc Mon Sep 17 00:00:00 2001 From: ubu32 Date: Sun, 27 Feb 2011 03:40:27 -0800 Subject: [PATCH] more fixes for bignum support in PLStream. --- library/dialect/swi/fli/swi.c | 62 ++++++++++++++++++++++++++++++++++- packages/PLStream/pl-write.c | 3 ++ packages/PLStream/pl-yap.c | 7 +++- packages/PLStream/pl-yap.h | 2 ++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index 9e5a44358..d8e6a6af5 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -535,6 +535,9 @@ X_API int PL_get_name_arity(term_t ts, atom_t *name, int *arity) } if (YAP_IsApplTerm(t)) { Functor f = FunctorOfTerm(t); + if (IsExtensionFunctor(f)) { + return 0; + } *name = AtomToSWIAtom(NameOfFunctor(f)); *arity = ArityOfFunctor(f); return 1; @@ -1697,7 +1700,18 @@ X_API int PL_is_float(term_t ts) X_API int PL_is_integer(term_t ts) { YAP_Term t = Yap_GetFromSlot(ts); - return YAP_IsIntTerm(t) || YAP_IsBigNumTerm(t); + if (IsVarTerm(t)) return FALSE; + if (IsIntTerm(t)) return TRUE; + if (IsApplTerm(t)) { + Functor f = FunctorOfTerm(t); + if (f == FunctorLongInt) + return TRUE; + if (f == FunctorBigInt) { + CELL mask = RepAppl(t)[1]; + return ( mask == BIG_INT ); + } + } + return FALSE; } X_API int PL_is_list(term_t ts) @@ -2841,6 +2855,52 @@ FILE *Yap_FileDescriptorFromStream(Term t) return NULL; } +extern term_t Yap_CvtTerm(term_t ts); + +term_t Yap_CvtTerm(term_t ts) +{ + Term t = Yap_GetFromSlot(ts); + if (IsVarTerm(t)) return ts; + if (IsPairTerm(t)) return ts; + if (IsAtomTerm(t)) return ts; + if (IsIntTerm(t)) return ts; + if (IsApplTerm(t)) { + Functor f = FunctorOfTerm(t); + if (IsExtensionFunctor(f)) { + if (f == FunctorBigInt) { + big_blob_type flag = RepAppl(t)[1]; + switch (flag) { + case BIG_INT: + return ts; + case BIG_RATIONAL: +#if USE_GMP + { + MP_RAT *b = Yap_BigRatOfTerm(t); + Term ta[2]; + ta[0] = Yap_MkBigIntTerm(mpq_numref(b)); + if (ta[0] == TermNil) + return ts; + ta[1] = Yap_MkBigIntTerm(mpq_denref(b)); + if (ta[1] == TermNil) + return ts; + return Yap_InitSlot(Yap_MkApplTerm(FunctorRDiv, 2, ta)); + } +#endif + case EMPTY_ARENA: + case ARRAY_INT: + case ARRAY_FLOAT: + case CLAUSE_LIST: + case EXTERNAL_BLOB: + return Yap_InitSlot(MkIntTerm(0)); + default: + return ts; + } + } + } + } + return ts; +} + #ifdef _WIN32 #include diff --git a/packages/PLStream/pl-write.c b/packages/PLStream/pl-write.c index 61b641dde..3680d1cff 100644 --- a/packages/PLStream/pl-write.c +++ b/packages/PLStream/pl-write.c @@ -1065,6 +1065,9 @@ writeTerm2(term_t t, int prec, write_options *options, bool arg) } } +#if __YAP_PROLOG__ + t = Yap_CvtTerm(t); +#endif if ( PL_get_atom(t, &a) ) { if ( !arg && prec < 1200 && priorityOperator((Module)NULL, a) > 0 ) { if ( PutOpenBrace(out) && diff --git a/packages/PLStream/pl-yap.c b/packages/PLStream/pl-yap.c index 432578433..2e1568d37 100755 --- a/packages/PLStream/pl-yap.c +++ b/packages/PLStream/pl-yap.c @@ -381,9 +381,14 @@ PL_get_number(term_t l, number *n) { n->type = V_INTEGER; n->value.i = YAP_IntOfTerm(t); #ifdef O_GMP - } else { + } else if (YAP_IsBigNumTerm(t)) { n->type = V_MPZ; + mpz_init(&n->value.mpq); YAP_BigNumOfTerm(t, &n->value.mpz); + } else { + n->type = V_MPQ; + mpq_init(&n->value.mpq); + YAP_RationalOfTerm(t, &n->value.mpq); #endif } } diff --git a/packages/PLStream/pl-yap.h b/packages/PLStream/pl-yap.h index f23a8d456..da9c46a95 100644 --- a/packages/PLStream/pl-yap.h +++ b/packages/PLStream/pl-yap.h @@ -149,6 +149,8 @@ void PL_license(const char *license, const char *module); #define isTaggedInt(A) YAP_IsIntTerm(A) #define valInt(A) YAP_IntOfTerm(A) +extern term_t Yap_CvtTerm(term_t ts); + #define clearNumber(n) inline static int