From 74d7ad2704011d724b41e5dcee7f7c05e90412cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Wed, 14 Mar 2012 11:08:28 +0000 Subject: [PATCH] extend interface to copy fast lists of integers or floats. --- C/c_interface.c | 104 +++++++++++++++++++++++++++++++++++++---- docs/yap.tex | 16 ++++++- include/YapInterface.h | 4 ++ 3 files changed, 113 insertions(+), 11 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index 610dc9c00..d9d773f88 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -442,6 +442,9 @@ X_API void STD_PROTO(YAP_FreeSpaceFromYap,(void *)); X_API int STD_PROTO(YAP_StringToBuffer, (Term, char *, unsigned int)); X_API Term STD_PROTO(YAP_ReadBuffer, (char *,Term *)); X_API Term STD_PROTO(YAP_FloatsToList, (double *, size_t)); +X_API Int STD_PROTO(YAP_ListToFloats, (Term, double *, size_t)); +X_API Term STD_PROTO(YAP_IntsToList, (Int *, size_t)); +X_API Int STD_PROTO(YAP_ListToInts, (Term, Int *, size_t)); X_API Term STD_PROTO(YAP_BufferToString, (char *)); X_API Term STD_PROTO(YAP_NBufferToString, (char *, size_t)); X_API Term STD_PROTO(YAP_WideBufferToString, (wchar_t *)); @@ -3594,6 +3597,89 @@ YAP_FloatsToList(double *dblp, size_t sz) return t; } +X_API Int +YAP_ListToFloats(Term t, double *dblp, size_t sz) +{ + size_t i = 0; + + t = Deref(t); + do { + Term hd; + if (IsVarTerm(t)) + return -1; + if (t == TermNil) + return i; + if (!IsPairTerm(t)) + return -1; + hd = HeadOfTerm(t); + if (!IsFloatTerm(hd)) + return -1; + dblp[i++] = FloatOfTerm(hd); + if (i == sz) + return sz; + t = TailOfTerm(t); + } while (TRUE); +} + +X_API Term +YAP_IntsToList(Int *dblp, size_t sz) +{ + CACHE_REGS + Term t; + CELL *oldH; + BACKUP_H(); + + if (!sz) + return TermNil; + while (ASP-1024 < H + sz*3) { + if ((CELL *)dblp > H0 && (CELL *)dblp < H) { + /* we are in trouble */ + LOCAL_OpenArray = (CELL *)dblp; + } + if (!dogc( 0, NULL PASS_REGS )) { + RECOVER_H(); + return 0L; + } + dblp = (Int *)LOCAL_OpenArray; + LOCAL_OpenArray = NULL; + } + t = AbsPair(H); + while (sz) { + oldH = H; + H +=2; + oldH[0] = MkIntegerTerm(*dblp++); + oldH[1] = AbsPair(H); + sz--; + } + oldH[1] = TermNil; + RECOVER_H(); + return t; +} + +X_API Int +YAP_ListToInts(Term t, Int *dblp, size_t sz) +{ + size_t i = 0; + + t = Deref(t); + do { + Term hd; + if (IsVarTerm(t)) + return -1; + if (t == TermNil) + return i; + if (!IsPairTerm(t)) + return -1; + hd = HeadOfTerm(t); + if (!IsIntTerm(hd)) + return -1; + dblp[i++] = IntOfTerm(hd); + if (i == sz) + return sz; + t = TailOfTerm(t); + } while (TRUE); +} + X_API Term YAP_OpenList(int n) { @@ -3975,16 +4061,14 @@ Term YAP_BPROLOG_curr_toam_status; Int YAP_ListLength(Term t) { - Int l = 0; - while (TRUE) { - if (IsVarTerm(t)) return -1; - if (t == TermNil) - return l; - if (!IsPairTerm(t)) - return -1; - l++; - t = TailOfTerm(t); - } + Term *aux; + + Int n = Yap_SkipList(&t, &aux); + if (IsVarTerm(*aux)) + return -1; + if (*aux == TermNil) + return n; + return -1; } Int diff --git a/docs/yap.tex b/docs/yap.tex index 2d3730475..5709a446c 100644 --- a/docs/yap.tex +++ b/docs/yap.tex @@ -16536,13 +16536,27 @@ The user-provided string must include a terminating null character. Syntax errors will cause returning @code{FALSE} and binding @var{error} to a Prolog term. +@findex YAP_IntsToList (C-Interface function) @findex YAP_FloatsToList (C-Interface function) These C-interface functions are useful when converting chunks of data to Prolog: @example YAP_Term YAP_FloatsToList(double *@var{buf},size_t @var{sz}) + YAP_Term YAP_IntsToList(YAP_Int *@var{buf},size_t @var{sz}) @end example @noindent -Notice that they are unsafe, and may call the garbage collector. +Notice that they are unsafe, and may call the garbage collector. They +return 0 on error. + +@findex YAP_ListToInts (C-Interface function) +@findex YAP_ToListFloats (C-Interface function) +These C-interface functions are useful when converting Prolog lists to arrays: +@example + YAP_Int YAP_IntsToList(YAP_Term t, YAP_Int *@var{buf},size_t @var{sz}) + YAP_Int YAP_FloatsToList(YAP_Term t, double *@var{buf},size_t @var{sz}) +@end example +@noindent +They return the number of integers scanned, up to a maximum of @t{sz}, +and @t{-1} on error. @node Memory Allocation, Controlling Streams, Manipulating Strings, C-Interface @section Memory Allocation diff --git a/include/YapInterface.h b/include/YapInterface.h index 371863aba..f58bfd159 100644 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -357,6 +357,10 @@ extern X_API void PROTO(YAP_PutValue,(YAP_Atom, YAP_Term)); extern X_API YAP_Term PROTO(YAP_GetValue,(YAP_Atom)); extern X_API YAP_Term PROTO(YAP_FloatsToList,(YAP_Float *, size_t)); +extern X_API YAP_Int PROTO(YAP_ListToFloats,(YAP_Term, YAP_Float *, size_t)); + +extern X_API YAP_Term PROTO(YAP_IntsToList,(YAP_Int *, size_t)); +extern X_API YAP_Int PROTO(YAP_ListToInts,(YAP_Term, YAP_Int *, size_t)); /* int StringToBuffer(YAP_Term,char *,unsigned int) */ extern X_API int PROTO(YAP_StringToBuffer,(YAP_Term,char *,unsigned int));