swipl-devel
swipl-devel copied to clipboard
Missing from SWI-Prolog.h: wchar_t equivalent of PL_put_atom_nchars()
I can do the following in C++
if ( !(ref_ = PL_new_term_ref()) ||
!PL_put_atom_nchars(ref_, text.size(), text.data()) )
throw PlResourceError();
but for wchar_t* or std:wstring, it seems that there's no PL_put_XXX() and instead I must do PL_unify_wchars() ... is this deliberate? (And,therefore, PL_put_atom_nchars() is deprecated and shouldn't be used?):
if ( !(ref_ = PL_new_term_ref()) ||
!PL_unify_wchars(ref_, PL_ATOM, text.size(), text.data()) )
throw PlResourceError();
Yes, the current way to handle text is using PL_get_*chars() and PL_unify_*chars(). The old stuff was from the days atoms where 0-terminated ASCII C strings and the *n* variations when they became char*/length pairs. The new functions can deal with many more scenarios. Best use with CVT_EXCEPTION and re-throw the exception prepared by Prolog. In that case you get the correct exception.
Eventually the wchars versions may possibly go as well and we can use REP_WCHAR instead.
Does this mean that the various PL_put_*() functions are obsolete/deprecated?
If a PL_get() with CVT_EXCEPTION fails, does this mean that PL_exception(0) should always be called? E.g.:
if ( !PL_get_wchars(t, &len, &s, CVT_ALL|CVT_EXCEPTION) )
{ if ( term_t ex = PL_exception()) )
PlException(ex).cppThrow();
return FALSE;
}
Does this mean that the various
PL_put_*()functions are obsolete/deprecated?
The ones dealing with text to create atoms/strings/code lists should be considered deprecated. Not sure we should actually deprecate them, they may have special use cases. Possibly we should add PL_put_chars() with functionality as PL_unify_chars(), but overruling the term_t. That avoids a PL_put_variable() and subsequent unification (and thus trailing).
PL_exception(0)should always be called?
It is surely better to let the Prolog primitives generate the exceptions as they are more precise and in any case virtually any of the primitives can generate a (resource) exception. As is, functions that may fail can return FALSE without or with an exception (e.g. PL_unify() may fail due to failing unification or stacks exhausting).
If I had to do the interface again I would have turned 0 in success, return error codes as negative values and a function to turn these into exceptions ...
On Thu, 4 Aug 2022 at 03:00, Jan Wielemaker @.***> wrote:
Does this mean that the various PL_put_*() functions are obsolete/deprecated?
The ones dealing with text to create atoms/strings/code lists should be considered deprecated. Not sure we should actually deprecate them, they may have special use cases. Possibly we should add PL_put_chars() with functionality as PL_unify_chars(), but overruling the term_t. That avoids a PL_put_variable() and subsequent unification (and thus trailing).
Shall I mark up foreign.doc and SWI-Prolog.h to reflect this?
I was wondering about the difference between PL_put_() and PL_unify_() and of course, it's the trailing. (It's been many many years since I've done WAM-machine like stuff ... I guess I'll look for my copy of Aït-Kaci's tutorial and refresh myself.
PL_exception(0) should always be called?
It is surely better to let the Prolog primitives generate the exceptions as they are more precise and in any case virtually any of the primitives can generate a (resource) exception. As is, functions that may fail can return FALSE without or with an exception (e.g. PL_unify() may fail due to failing unification or stacks exhausting).
What are the "Prolog primitives"?
If I had to do the interface again I would have turned 0 in success, return error codes as negative values and a function to turn these into exceptions ...
We can at least make a C++ interface that makes things easier -- "throw' definitely simplifies the code.
Back to splitting up SWI-cpp.h into multiple files ... this would lose some edit history - do you care? As things stand, I'd still want to verify that all the methods have implementations, and the only way I know of checking this is by a test file that calls everything, so there's not much advantage in splitting SWI-cpp.h into declarations and implementation. But some C++ toolchains might have trouble with "inline" - have no way of verifying with Microsoft's compiler, for example, although I presume it's OK. I don't know what other compilers are in common use.
- p
— Reply to this email directly, view it on GitHub https://github.com/SWI-Prolog/swipl-devel/issues/1019#issuecomment-1205034257, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIIGNNKATGU5W5UTZBMXRBDVXOIDNANCNFSM55QGC7XA . You are receiving this because you authored the thread.Message ID: @.***>
About trail with PL_unify_*() ... this only applies for variables that are older than the current choice point (more-or-less), so PL_new_term_ref; PL_unify_*() wouldn't create an entry on the trail, would it?
According to Trail() (pl-inline.h), local variables are always trailed. It would be a bit digging to find the rationale for that ...
I thought that local variables are never trailed; only sufficiently old global variables. But perhaps the meaning of "local variable" is different when inside a foreign function?
There's this comment in the code:
Mark() sets LD->mark_bar, indicating that any assignment above this
value need not be trailed.
Note that the local stack is always _above_ the global stack.
They are clearly trailed as it tests for > lBase. Whether that is (still) necessary I don't know. It is not my priority to figure this out. Possibly not because local variables are since some time always references to the global stack to simply last-call optimization.
The more important question (for me) is knowing which functions in SWI-Prolog.h are deprecated.
(Because I only want to use non-deprecated functions in SWI-cpp.h.
Anyway, it seems that (for now, anyway), I have no choice but to use PL_unify_wchars() because there's no PL_put_*() equilvaent
Just use the PL_unify* functions if there is no suitable put version and make sure to use the text exchange functions with the flags and accepting term_t. That should deal with almost all deprecations. I'll find the others :smile:
Added PL_put_wchars(), so we can do
PL_put_wchars(t, PL_ATOM, len, string);
See fe70225ba6dbb0408014bc3f4faf9f46c2c1b5e9