From 562e9e5af3e3cd3e1642ea324fb1ea81db258f2a Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Sat, 21 Jul 2018 01:56:48 +0100 Subject: [PATCH] jupyter --- C/adtdefs.c | 3 +- C/flags.c | 67 +- C/load_foreign.c | 1 + C/text.c | 512 ++++--- C/text.c.new | 1238 +++++++++-------- C/write.c | 1 - CXX/yapdb.hh | 1 + CXX/yapi.cpp | 8 +- H/ATOMS | 2 +- H/YapFlags.h | 9 + H/YapHeap.h | 14 +- H/generated/iatoms.h | 2 +- library/dialect/swi/fli/swi.c | 30 +- library/expand_macros.yap | 1 + library/maputils.yap | 11 +- os/fmem.c | 5 - packages/python/CMakeLists.txt | 2 +- packages/python/pl2py.c | 27 +- packages/python/py2pl.c | 281 ++-- packages/python/pypreds.c | 6 + packages/python/python.pl | 1 + packages/python/swig/prolog/yapi.yap | 23 +- packages/python/swig/yap4py/yapi.py | 32 +- .../yap_ipython/prolog/complete.yap | 6 +- .../yap_kernel/yap_ipython/prolog/jupyter.yap | 27 +- .../yap_kernel/yap_ipython/prolog/verify.yap | 75 +- .../python/yap_kernel/yap_ipython/yapi.py | 442 +----- pl/consult.yap | 6 +- 28 files changed, 1266 insertions(+), 1567 deletions(-) diff --git a/C/adtdefs.c b/C/adtdefs.c index e6ead9022..87ea9c6b4 100755 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -251,9 +251,8 @@ Atom Yap_LookupAtomWithLength(const char *atom, return NIL; memmove(ptr, atom, len0); ptr[len0] = '\0'; - if (atom[0] '\0') { at = LookupAtom(ptr); - Yap_FreeCodeSpace(ptr); + Yap_FreeCodeSpace(ptr); return at; } diff --git a/C/flags.c b/C/flags.c index eb1bd9ffe..61f29f6e5 100644 --- a/C/flags.c +++ b/C/flags.c @@ -109,6 +109,9 @@ static Int set_prolog_flag(USES_REGS1); #include "YapLFlagInfo.h" static Term indexer(Term inp) { + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (inp == TermOff || inp == TermSingle || inp == TermCompact || inp == TermMulti || inp == TermOn || inp == TermMax) return inp; @@ -124,6 +127,9 @@ static Term indexer(Term inp) { static bool dqf1(ModEntry *new, Term t2 USES_REGS) { new->flags &= ~(DBLQ_CHARS | DBLQ_CODES | DBLQ_ATOM | DBLQ_STRING); + if (IsStringTerm(t2)) { + t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE); + } if (IsAtomTerm(t2)) { if (t2 == TermString) { new->flags |= DBLQ_STRING; @@ -162,6 +168,9 @@ static bool dqs(Term t2) { static bool bqf1(ModEntry *new, Term t2 USES_REGS) { new->flags &= ~(BCKQ_CHARS | BCKQ_CODES | BCKQ_ATOM | BCKQ_STRING); + if (IsStringTerm(t2)) { + t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE); + } if (IsAtomTerm(t2)) { if (t2 == TermString) { new->flags |= BCKQ_STRING; @@ -197,6 +206,9 @@ static bool bqs(Term t2) { static bool sqf1(ModEntry *new, Term t2 USES_REGS) { new->flags &= ~(SNGQ_CHARS | SNGQ_CODES | SNGQ_ATOM | SNGQ_STRING); + if (IsStringTerm(t2)) { + t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE); + } if (IsAtomTerm(t2)) { if (t2 == TermString) { new->flags |= SNGQ_STRING; @@ -234,6 +246,9 @@ static Term isaccess(Term inp) { if (inp == TermReadWrite || inp == TermReadOnly) return inp; + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (IsAtomTerm(inp)) { Yap_Error(DOMAIN_ERROR_OUT_OF_RANGE, inp, "set_prolog_flag access in {read_write,read_only}"); @@ -281,6 +296,9 @@ static Term flagscope(Term inp) { if (inp == TermGlobal || inp == TermThread || inp == TermModule) return inp; + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (IsAtomTerm(inp)) { Yap_Error(DOMAIN_ERROR_OUT_OF_RANGE, inp, "set_prolog_flag access in {global,module,thread}"); @@ -295,8 +313,11 @@ static bool mkprompt(Term inp) { CACHE_REGS if (IsVarTerm(inp)) { return Yap_unify(inp, MkAtomTerm(Yap_LookupAtom(LOCAL_Prompt))); + } + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); } - if (!IsAtomTerm(inp)) { + if (!IsAtomTerm(inp)) { Yap_Error(TYPE_ERROR_ATOM, inp, "set_prolog_flag"); return false; } @@ -307,6 +328,9 @@ static bool mkprompt(Term inp) { static bool getenc(Term inp) { CACHE_REGS + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (!IsVarTerm(inp) && !IsAtomTerm(inp)) { Yap_Error(TYPE_ERROR_ATOM, inp, "get_encoding"); return false; @@ -338,6 +362,9 @@ static bool typein(Term inp) { tin = TermProlog; return Yap_unify(inp, tin); } + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (!IsAtomTerm(inp)) { Yap_Error(TYPE_ERROR_ATOM, inp, "set_prolog_flag"); return false; @@ -448,6 +475,9 @@ static bool typein(Term inp) { if (IsAtomTerm(hd)) { do { Term hd = HeadOfTerm(inp); + if (IsStringTerm(hd)) { + hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE); + } if (!IsAtomTerm(hd)) { Yap_Error(TYPE_ERROR_TEXT, inp0, "set_prolog_flag in \"...\""); return false; @@ -486,6 +516,10 @@ x static bool list_atom( Term inp ) { if (IsPairTerm(inp)) { Term hd = HeadOfTerm(inp); do { + if (IsStringTerm(hd)) { + hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE); + } + if (!IsAtomTerm(hd)) { Yap_Error(TYPE_ERROR_ATOM, inp0, "set_prolog_flag in \"...\""); return false; @@ -510,6 +544,9 @@ static Term list_option(Term inp) { do { Term hd = HeadOfTerm(inp); inp = TailOfTerm(inp); + if (IsStringTerm(hd)) { + hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE); + } if (IsAtomTerm(hd)) { continue; } @@ -530,6 +567,9 @@ static Term list_option(Term inp) { Yap_Error(TYPE_ERROR_LIST, inp0, "set_prolog_flag in [...]"); return TermZERO; } else /* lone option */ { + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (IsAtomTerm(inp)) { return inp; } else if (IsApplTerm(inp)) { @@ -1035,6 +1075,9 @@ static Int current_prolog_flag2(USES_REGS1) { return cont_yap_flag(PASS_REGS1); } do_cut(0); + if (IsStringTerm(tflag)) { + tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE); + } if (!IsAtomTerm(tflag)) { Yap_Error(TYPE_ERROR_ATOM, tflag, "current_prolog_flag/3"); return (FALSE); @@ -1084,6 +1127,10 @@ bool setYapFlag(Term tflag, Term t2) { Yap_Error(INSTANTIATION_ERROR, tflag, "yap_flag/2"); return (FALSE); } + if (IsStringTerm(tflag)) { + tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE); + } + if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) { Term modt; tflag = Yap_StripModule(tflag, &modt); @@ -1165,11 +1212,20 @@ Term getYapFlag(Term tflag) { Yap_Error(INSTANTIATION_ERROR, tflag, "yap_flag/2"); return (FALSE); } + if (IsStringTerm(tflag)) { + tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE); + } if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) { Term modt; tflag = Yap_StripModule(tflag, &modt); + if (IsStringTerm(tflag)) { + tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE); + } if (!isatom(tflag)) return false; + if (IsStringTerm(modt)) { + modt = MkStringTerm(RepAtom(AtomOfTerm(modt))->StrOfAE); + } if (!isatom(modt)) return false; return getYapFlagInModule(tflag, modt); @@ -1405,6 +1461,9 @@ static bool setInitialValue(bool bootstrap, flag_func f, const char *s, GLOBAL_MaxPriority); if (!t0) return false; + if (IsStringTerm(t0)) { + t0 = MkStringTerm(RepAtom(AtomOfTerm(t0))->StrOfAE); + } if (IsAtomTerm(t0) || IsIntTerm(t0)) { // do yourself flags if (t0 == MkAtomTerm(AtomQuery)) { @@ -1456,6 +1515,9 @@ do_prolog_flag_property(Term tflag, Yap_Error(LOCAL_Error_TYPE, opts, NULL); return false; } + if (IsStringTerm(tflag)) { + tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE); + } if (!IsAtomTerm(tflag)) { if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) { Term modt = CurrentModule; @@ -1572,6 +1634,9 @@ static Int prolog_flag_property(USES_REGS1) { /* Init current_prolog_flag */ Term t1 = Deref(ARG1); /* make valgrind happy by always filling in memory */ EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0); + if (IsStringTerm(t1)) { + t1 = MkStringTerm(RepAtom(AtomOfTerm(t1))->StrOfAE); + } if (IsVarTerm(t1)) { return (cont_prolog_flag_property(PASS_REGS1)); } else { diff --git a/C/load_foreign.c b/C/load_foreign.c index bc764a289..ed18c3a4a 100644 --- a/C/load_foreign.c +++ b/C/load_foreign.c @@ -286,4 +286,5 @@ void Yap_ReOpenLoadForeign(void) { X_API bool load_none(void) { + return true; } diff --git a/C/text.c b/C/text.c index 077eb937d..b1b78aeb9 100644 --- a/C/text.c +++ b/C/text.c @@ -91,11 +91,11 @@ void *pop_output_text_stack__(int i, const void *export) { while (p) { struct mblock *np = p->next; if (p + 1 == export) { - size_t sz = p->sz - sizeof(struct mblock); - memmove(p, p + 1, sz); - export = p; + size_t sz = p->sz - sizeof(struct mblock); + memmove(p, p + 1, sz); + export = p; } else { - free(p); + free(p); } p = np; } @@ -229,9 +229,9 @@ static Term Globalize(Term v USES_REGS) { } static void *codes2buf(Term t0, void *b0, bool get_codes, - bool fixed USES_REGS) { + bool fixed USES_REGS) { unsigned char *st0, *st, ar[16]; - Term t = Deref(t0); + Term t = t0; size_t length = 0; if (t == TermNil) { @@ -247,7 +247,7 @@ static void *codes2buf(Term t0, void *b0, bool get_codes, if (get_codes != codes && fixed) { if (codes) { Yap_ThrowError(TYPE_ERROR_INTEGER, HeadOfTerm(t), - "scanning list of codes"); + "scanning list of codes"); } else { Yap_ThrowError(TYPE_ERROR_ATOM, HeadOfTerm(t), "scanning list of atoms"); } @@ -256,55 +256,55 @@ static void *codes2buf(Term t0, void *b0, bool get_codes, while (IsPairTerm(t)) { Term hd = HeadOfTerm(t); if (IsVarTerm(hd)) { - Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); - return NULL; + Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); + return NULL; } if (!IsIntegerTerm(hd)) { - Yap_ThrowError(TYPE_ERROR_CHARACTER_CODE, hd, "scanning list of codes"); - return NULL; + Yap_ThrowError(TYPE_ERROR_CHARACTER_CODE, hd, "scanning list of codes"); + return NULL; } Int code = IntegerOfTerm(hd); if (code < 0) { - Yap_ThrowError(REPRESENTATION_ERROR_CHARACTER_CODE, hd, - "scanning list of character codes, found %d", code); - return NULL; + Yap_ThrowError(REPRESENTATION_ERROR_CHARACTER_CODE, hd, + "scanning list of character codes, found %d", code); + return NULL; } length += put_utf8(ar, code); t = TailOfTerm(t); if (IsVarTerm(t)) { - Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); - return NULL; + Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); + return NULL; } if (!IsPairTerm(t) && t != TermNil) { - Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); - return NULL; + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; } } } else { while (IsPairTerm(t)) { Term hd = HeadOfTerm(t); if (IsVarTerm(hd)) { - Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); - return NULL; + Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); + return NULL; } if (!IsAtomTerm(hd)) { - Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of texts"); - return NULL; + Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of texts"); + return NULL; } const char *code = RepAtom(AtomOfTerm(hd))->StrOfAE; if (code < 0) { - Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of atoms"); - return NULL; + Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of atoms"); + return NULL; } length += strlen(code); t = TailOfTerm(t); if (IsVarTerm(t)) { - Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); - return NULL; + Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); + return NULL; } if (!IsPairTerm(t) && t != TermNil) { - Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); - return NULL; + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; } } } @@ -374,33 +374,33 @@ static unsigned char *wchar2utf8(seq_tv_t *inp) { static void *slice(size_t min, size_t max, const unsigned char *buf USES_REGS); static unsigned char *Yap_ListOfCodesToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp USES_REGS) { + seq_tv_t *inp USES_REGS) { bool codes = true, fixed = true; unsigned char *nbuf = codes2buf(t, buf, codes, fixed PASS_REGS); return nbuf; } static unsigned char *Yap_ListOfAtomsToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp USES_REGS) { + seq_tv_t *inp USES_REGS) { bool codes = false; unsigned char *nbuf = codes2buf(t, buf, codes, true PASS_REGS); return nbuf; } static unsigned char *Yap_ListToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp USES_REGS) { + seq_tv_t *inp USES_REGS) { return codes2buf(t, buf, NULL, false PASS_REGS); } #if USE_GEN_TYPE_ERROR static yap_error_number gen_type_error(int flags) { if ((flags & (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | - YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) == + YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) == (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) return TYPE_ERROR_TEXT; if ((flags & (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | - YAP_STRING_FLOAT | YAP_STRING_BIG)) == + YAP_STRING_FLOAT | YAP_STRING_BIG)) == (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) return TYPE_ERROR_ATOMIC; @@ -417,183 +417,149 @@ static yap_error_number gen_type_error(int flags) { } #endif -static yap_error_number type_error(seq_tv_t *inp) { - if ((inp->type & YAP_STRING_ATOMS_CODES) == YAP_STRING_ATOMS_CODES) - { - return TYPE_ERROR_IN_CHARACTER; - } - if ((inp->type & YAP_STRING_ATOMS) == YAP_STRING_ATOMS) { - return TYPE_ERROR_CHARACTER; - } - if ((inp->type & YAP_STRING_CODES) == YAP_STRING_CODES) { - return TYPE_ERROR_CHARACTER_CODE; - } - if ((inp->type & YAP_STRING_STRING) == YAP_STRING_STRING) { - return TYPE_ERROR_IN_CHARACTER; - } - if ((inp->type & YAP_STRING_CODES) == YAP_STRING_CODES) { - return TYPE_ERROR_IN_CHARACTER; - } - if ((inp->type & (YAP_STRING_ATOM|YAP_STRING_STRING)) == (YAP_STRING_ATOM|YAP_STRING_STRING)) { - return TYPE_ERROR_ATOMIC; - } - if ((inp->type & YAP_STRING_ATOM) == YAP_STRING_ATOM) { - return TYPE_ERROR_IN_CHARACTER; - } - return SYSTEM_ERROR_INTERNAL; -} +// static int cnt; -/// @brief translate anything to bufffer UTF-8 -/// -/// @arg input descriptor unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) { #define POPRET(x) return pop_output_text_stack(lvl, x) int lvl = push_text_stack(); char *out = NULL; + yap_error_number err0 = LOCAL_Error_TYPE; /* we know what the term is */ - if ((inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) { - //> buffer processing - //> must convert: - if (inp->type & YAP_STRING_CHARS) { - //> - ASCII to UTF-8 - if (inp->enc == ENC_ISO_ASCII) { - pop_text_stack(lvl); - return inp->val.uc; - } - //> - ISO-LATIN-1 to UTF-8 - if (inp->enc == ENC_ISO_LATIN1) { - POPRET( (char*)latin2utf8(inp)); - } - - //> - assume UTF-8 - if (inp->enc == ENC_ISO_UTF8) { - pop_text_stack(lvl); - return inp->val.uc; + if (!(inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) { + if (!(inp->type & YAP_STRING_TERM)) { + if (IsVarTerm(inp->val.t)) { + LOCAL_Error_TYPE = INSTANTIATION_ERROR; + } else if (!IsAtomTerm(inp->val.t) && inp->type == YAP_STRING_ATOM) { + LOCAL_Error_TYPE = TYPE_ERROR_ATOM; + } else if (!IsStringTerm(inp->val.t) && inp->type == YAP_STRING_STRING) { + LOCAL_Error_TYPE = TYPE_ERROR_STRING; + } else if (!IsPairOrNilTerm(inp->val.t) && !IsStringTerm(inp->val.t) && + inp->type == (YAP_STRING_ATOMS_CODES | YAP_STRING_STRING)) { + LOCAL_ActiveError->errorRawTerm = inp->val.t; + } else if (!IsPairOrNilTerm(inp->val.t) && !IsStringTerm(inp->val.t) && + !IsAtomTerm(inp->val.t) && !(inp->type & YAP_STRING_DATUM)) { + LOCAL_Error_TYPE = TYPE_ERROR_TEXT; } } - if (inp->type & YAP_STRING_WCHARS) { - // printf("%S\n",inp->val.w); - //> wide includes everything else - POPRET( (char *)wchar2utf8(inp) ); + if (err0 != LOCAL_Error_TYPE) { + Yap_ThrowError(LOCAL_Error_TYPE, inp->val.t, "while reading text in"); } - } else { - if (inp->type & YAP_STRING_TERM) { - //> term: anything goes - pop_text_stack(lvl); - return (unsigned char *)Yap_TermToBuffer(inp->val.t, 0); - } - if (IsVarTerm(inp->val.t)) { - Yap_ThrowError(INSTANTIATION_ERROR, inp->val.t, NULL); - } - if (IsPairOrNilTerm(inp->val.t)) { - if (((inp->type & (YAP_STRING_CODES | YAP_STRING_ATOMS)) == - (YAP_STRING_CODES | YAP_STRING_ATOMS))) { - // Yap_DebugPlWriteln(inp->val.t); - out = (char *)Yap_ListToBuffer(NULL, inp->val.t, inp PASS_REGS); - POPRET( out ); - // this is a term, extract to a sfer, and representation is wide - } - if (inp->type & YAP_STRING_CODES) { - // Yap_DebugPlWriteln(inp->val.t); - out = (char *)Yap_ListOfCodesToBuffer(NULL, inp->val.t, inp PASS_REGS); - // this is a term, extract to a sfer, and representation is wide - POPRET( out ); - } - - if (inp->type & YAP_STRING_ATOMS) { - // Yap_DebugPlWriteln(inp->val.t); - out = (char *)Yap_ListOfAtomsToBuffer(NULL, inp->val.t, inp PASS_REGS); - // this is a term, extract to a buffer, and representation is wide - POPRET( out ); - } - } - if (IsStringTerm(inp->val.t)) { - if(!(inp->type & (YAP_STRING_STRING))) { - Yap_ThrowError(type_error(inp), inp->val.t, NULL); - } - // this is a term, extract to a buffer, and representation is wide - // Yap_DebugPlWriteln(inp->val.t); - const char *s = StringOfTerm(inp->val.t); - if (s[0] == 0) { - out = Malloc(4); - memset(out, 0, 4); - POPRET( out ); - } - if (inp->type & YAP_STRING_WITH_BUFFER) { - pop_text_stack(lvl); - return (unsigned char *)UStringOfTerm(inp->val.t); - } - { - inp->type |= YAP_STRING_IN_TMP; - size_t sz = strlen(s); - out = Malloc(sz + 1); - strcpy(out, s); - POPRET( out ); - } - } - if (IsAtomTerm(inp->val.t)) { - if(!(inp->type & (YAP_STRING_ATOM))) { - Yap_ThrowError(type_error(inp), inp->val.t, NULL); - } - // this is a term, extract to a buffer, and representation is wide - // Yap_DebugPlWriteln(inp->val.t); - Atom at = AtomOfTerm(inp->val.t); - if (RepAtom(at)->UStrOfAE[0] == '\0') { - out = Malloc(4); - memset(out, 0, 4); - POPRET( out ); - } - if (inp->type & YAP_STRING_WITH_BUFFER) { - pop_text_stack(lvl); - return at->UStrOfAE; - } else - { - size_t sz = strlen(at->StrOfAE); - out = Malloc(sz + 1); - strcpy(out, at->StrOfAE); - POPRET( out ); - } - } - if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) { - if(!(inp->type & (YAP_STRING_INT))) { - Yap_ThrowError(type_error(inp), inp->val.t, NULL); - } // ASCII, so both LATIN1 and UTF-8 - // Yap_DebugPlWriteln(inp->val.t); - out = Malloc(2 * MaxTmp(PASS_REGS1)); - if (snprintf(out, MaxTmp(PASS_REGS1) - 1, Int_FORMAT, - IntegerOfTerm(inp->val.t)) < 0) { - AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), out, char); - } + } + if (IsAtomTerm(inp->val.t) && inp->type & YAP_STRING_ATOM) { + // this is a term, extract to a buffer, and representation is wide + // Yap_DebugPlWriteln(inp->val.t); + Atom at = AtomOfTerm(inp->val.t); + if (RepAtom(at)->UStrOfAE[0] == 0) { + out = Malloc(4); + memset(out, 0, 4); POPRET( out ); } - if (inp->type & YAP_STRING_FLOAT && IsFloatTerm(inp->val.t)) { - if(!(inp->type & (YAP_STRING_FLOAT))) { - Yap_ThrowError(type_error(inp), inp->val.t, NULL); - } // ASCII, so both LATIN1 and UTF-8 - out = Malloc(2 * MaxTmp(PASS_REGS1)); - if (!Yap_FormatFloat(FloatOfTerm(inp->val.t), &out, 1024)) { - pop_text_stack(lvl); - return NULL; - } - POPRET(out); + if (inp->type & YAP_STRING_WITH_BUFFER) { + pop_text_stack(lvl); + return at->UStrOfAE; } -#if USE_GMP - if ( IsBigIntTerm(inp->val.t)) { - if(!(inp->type & (YAP_STRING_BIG))) { - Yap_ThrowError(type_error(inp), inp->val.t, NULL); - } // ASCII, so both LATIN1 and UTF-8 + { + size_t sz = strlen(at->StrOfAE); + out = Malloc(sz + 1); + strcpy(out, at->StrOfAE); + POPRET( out ); + } + } + if (IsStringTerm(inp->val.t) && inp->type & YAP_STRING_STRING) { + // this is a term, extract to a buffer, and representation is wide + // Yap_DebugPlWriteln(inp->val.t); + const char *s = StringOfTerm(inp->val.t); + if (s[0] == 0) { + out = Malloc(4); + memset(out, 0, 4); + POPRET( out ); + } + if (inp->type & YAP_STRING_WITH_BUFFER) { + pop_text_stack(lvl); + return (unsigned char *)UStringOfTerm(inp->val.t); + } + { + inp->type |= YAP_STRING_IN_TMP; + size_t sz = strlen(s); + out = Malloc(sz + 1); + strcpy(out, s); + POPRET( out ); + } + } else if (IsPairOrNilTerm(inp->val.t)) { + if (((inp->type & (YAP_STRING_CODES | YAP_STRING_ATOMS)) == + (YAP_STRING_CODES | YAP_STRING_ATOMS))) { // Yap_DebugPlWriteln(inp->val.t); - out = Malloc(MaxTmp()); - if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), out, MaxTmp() - 1, - 10)) { - AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), out, char); - } - POPRET(out); + out = (char *)Yap_ListToBuffer(NULL, inp->val.t, inp PASS_REGS); + POPRET( out ); + // this is a term, extract to a sfer, and representation is wide } + if (inp->type & YAP_STRING_CODES) { + // Yap_DebugPlWriteln(inp->val.t); + out = (char *)Yap_ListOfCodesToBuffer(NULL, inp->val.t, inp PASS_REGS); + // this is a term, extract to a sfer, and representation is wide + POPRET( out ); + } + if (inp->type & YAP_STRING_ATOMS) { + // Yap_DebugPlWriteln(inp->val.t); + out = (char *)Yap_ListOfAtomsToBuffer(NULL, inp->val.t, inp PASS_REGS); + // this is a term, extract to a buffer, and representation is wide + POPRET( out ); + } + } + if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) { + // ASCII, so both LATIN1 and UTF-8 + // Yap_DebugPlWriteln(inp->val.t); + out = Malloc(2 * MaxTmp(PASS_REGS1)); + if (snprintf(out, MaxTmp(PASS_REGS1) - 1, Int_FORMAT, + IntegerOfTerm(inp->val.t)) < 0) { + AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), out, char); + } + POPRET( out ); + } + if (inp->type & YAP_STRING_FLOAT && IsFloatTerm(inp->val.t)) { + out = Malloc(2 * MaxTmp(PASS_REGS1)); + if (!Yap_FormatFloat(FloatOfTerm(inp->val.t), &out, 1024)) { + pop_text_stack(lvl); + return NULL; + } + POPRET(out); + } +#if USE_GMP + if (inp->type & YAP_STRING_BIG && IsBigIntTerm(inp->val.t)) { + // Yap_DebugPlWriteln(inp->val.t); + out = Malloc(MaxTmp()); + if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), out, MaxTmp() - 1, + 10)) { + AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), out, char); + } + POPRET(out); + } #endif + if (inp->type & YAP_STRING_TERM) { + pop_text_stack(lvl); + return Yap_TermToBuffer(inp->val.t, 0); + } + + if (inp->type & YAP_STRING_CHARS) { + if (inp->enc == ENC_ISO_ASCII) { + pop_text_stack(lvl); + return inp->val.uc; + } + + if (inp->enc == ENC_ISO_LATIN1) { + POPRET( (char*)latin2utf8(inp)); + } + + if (inp->enc == ENC_ISO_UTF8) { + pop_text_stack(lvl); + return inp->val.c; + } + } + if (inp->type & YAP_STRING_WCHARS) { + // printf("%S\n",inp->val.w); + POPRET( (char *)wchar2utf8(inp) ); } pop_text_stack(lvl); - Yap_ThrowError(type_error(inp), inp->val.t, NULL); return NULL; } @@ -761,11 +727,11 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { utf8proc_int32_t chr; int off = get_utf8(cp, -1, &chr); if (off <= 0 || chr > 255) { - pop_text_stack(l); - return NULL; + pop_text_stack(l); + return NULL; } if (off == max) - break; + break; cp += off; *buf++ = chr; } @@ -773,10 +739,10 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { *buf++ = '\0'; else while (max < min) { - utf8proc_int32_t chr; - max++; - cp += get_utf8(cp, -1, &chr); - *buf++ = chr; + utf8proc_int32_t chr; + max++; + cp += get_utf8(cp, -1, &chr); + *buf++ = chr; } } else if (out->enc == ENC_WCHAR) { unsigned char *s = s0, *lim = s + (max = strnlen((char *)s0, max)); @@ -797,10 +763,10 @@ void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { *buf++ = '\0'; else while (max < min) { - utf8proc_int32_t chr; - max++; - cp += get_utf8(cp, -1, &chr); - *buf++ = chr; + utf8proc_int32_t chr; + max++; + cp += get_utf8(cp, -1, &chr); + *buf++ = chr; } *buf = '\0'; } else { @@ -817,7 +783,7 @@ static size_t write_length(const unsigned char *s0, seq_tv_t *out USES_REGS) { } static Term write_number(unsigned char *s, seq_tv_t *out, - bool error_on USES_REGS) { + bool error_on USES_REGS) { Term t; LOCAL_delay = !error_on; t = Yap_StringToNumberTerm((char *)s, &out->enc, error_on); @@ -846,7 +812,7 @@ bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) { if (out->type & (YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) { if ((out->val.t = write_number( - inp, out, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) { + inp, out, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) { // Yap_DebugPlWriteln(out->val.t); return true; @@ -859,7 +825,7 @@ bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) { if ((out->val.a = write_atom(inp, out PASS_REGS)) != NIL) { Atom at = out->val.a; if (at && (out->type & YAP_STRING_OUTPUT_TERM)) - out->val.t = MkAtomTerm(at); + out->val.t = MkAtomTerm(at); // Yap_DebugPlWriteln(out->val.t); return at != NIL; } @@ -959,12 +925,12 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) { size_t leng = strlen_utf8(buf); if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { if (out->max < leng) { - const unsigned char *ptr = skip_utf8(buf, out->max); - size_t diff = (ptr - buf); - char *nbuf = Malloc(diff + 1); - memmove(nbuf, buf, diff); - nbuf[diff] = '\0'; - leng = diff; + const unsigned char *ptr = skip_utf8(buf, out->max); + size_t diff = (ptr - buf); + char *nbuf = Malloc(diff + 1); + memmove(nbuf, buf, diff); + nbuf[diff] = '\0'; + leng = diff; } // else if (out->type & YAP_STRING_NCHARS && // const unsigned char *ptr = skip_utf8(buf) @@ -972,32 +938,32 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) { if (out->type & (YAP_STRING_UPCASE | YAP_STRING_DOWNCASE)) { if (out->type & YAP_STRING_UPCASE) { - if (!upcase(buf, out)) { - pop_text_stack(l); - return false; - } + if (!upcase(buf, out)) { + pop_text_stack(l); + return false; + } } if (out->type & YAP_STRING_DOWNCASE) { - if (!downcase(buf, out)) { - pop_text_stack(l); - return false; - } + if (!downcase(buf, out)) { + pop_text_stack(l); + return false; + } } } } rc = write_Text(buf, out PASS_REGS); /* fprintf(stderr, " -> "); - if (!rc) fprintf(stderr, "NULL"); - else if (out->type & - (YAP_STRING_TERM|YAP_STRING_ATOMS_CODES - |YAP_STRING_STRING)) //Yap_DebugPlWrite(out->val.t); - else if (out->type & - YAP_STRING_ATOM) //Yap_DebugPlWriteln(MkAtomTerm(out->val.a)); - else if (out->type & YAP_STRING_WCHARS) fprintf(stderr, "%S", - out->val.w); - else - fprintf(stderr, "%s", out->val.c); - fprintf(stderr, "\n]\n"); */ + if (!rc) fprintf(stderr, "NULL"); + else if (out->type & + (YAP_STRING_TERM|YAP_STRING_ATOMS_CODES + |YAP_STRING_STRING)) //Yap_DebugPlWrite(out->val.t); + else if (out->type & + YAP_STRING_ATOM) //Yap_DebugPlWriteln(MkAtomTerm(out->val.a)); + else if (out->type & YAP_STRING_WCHARS) fprintf(stderr, "%S", + out->val.w); + else + fprintf(stderr, "%s", out->val.c); + fprintf(stderr, "\n]\n"); */ pop_text_stack(l); return rc; } @@ -1083,7 +1049,7 @@ bool Yap_Concat_Text(int tot, seq_tv_t inp[], seq_tv_t *out USES_REGS) { // bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, - seq_tv_t outv[] USES_REGS) { + seq_tv_t outv[] USES_REGS) { int lvl = push_text_stack(); const unsigned char *buf; size_t b_l, u_l; @@ -1106,46 +1072,46 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, unsigned char *buf0, *buf1; if (outv[0].val.t) { - buf0 = Yap_readText(outv PASS_REGS); - if (!buf0) { - return false; - } - b_l0 = strlen((const char *)buf0); - if (memcmp(buf, buf0, b_l0) != 0) { - pop_text_stack(lvl); - return false; - } - u_l0 = strlen_utf8(buf0); - u_l1 = u_l - u_l0; + buf0 = Yap_readText(outv PASS_REGS); + if (!buf0) { + return false; + } + b_l0 = strlen((const char *)buf0); + if (memcmp(buf, buf0, b_l0) != 0) { + pop_text_stack(lvl); + return false; + } + u_l0 = strlen_utf8(buf0); + u_l1 = u_l - u_l0; - b_l1 = b_l - b_l0; - buf1 = slice(u_l0, u_l, buf PASS_REGS); - b_l1 = strlen((const char *)buf1); - bool rc = write_Text(buf1, outv + 1 PASS_REGS); - pop_text_stack(lvl); - if (!rc) { - return false; - } - return rc; + b_l1 = b_l - b_l0; + buf1 = slice(u_l0, u_l, buf PASS_REGS); + b_l1 = strlen((const char *)buf1); + bool rc = write_Text(buf1, outv + 1 PASS_REGS); + pop_text_stack(lvl); + if (!rc) { + return false; + } + return rc; } else /* if (outv[1].val.t) */ { - buf1 = Yap_readText(outv + 1 PASS_REGS); - if (!buf1) { - pop_text_stack(lvl); - return false; - } - b_l1 = strlen((char *)buf1); - u_l1 = strlen_utf8(buf1); - b_l0 = b_l - b_l1; - u_l0 = u_l - u_l1; - if (memcmp(skip_utf8((const unsigned char *)buf, b_l0), buf1, b_l1) != - 0) { - pop_text_stack(lvl); - return false; - } - buf0 = slice(0, u_l0, buf PASS_REGS); - buf0 = pop_output_text_stack(lvl, buf0); - bool rc = write_Text(buf0, outv PASS_REGS); - return rc; + buf1 = Yap_readText(outv + 1 PASS_REGS); + if (!buf1) { + pop_text_stack(lvl); + return false; + } + b_l1 = strlen((char *)buf1); + u_l1 = strlen_utf8(buf1); + b_l0 = b_l - b_l1; + u_l0 = u_l - u_l1; + if (memcmp(skip_utf8((const unsigned char *)buf, b_l0), buf1, b_l1) != + 0) { + pop_text_stack(lvl); + return false; + } + buf0 = slice(0, u_l0, buf PASS_REGS); + buf0 = pop_output_text_stack(lvl, buf0); + bool rc = write_Text(buf0, outv PASS_REGS); + return rc; } } } @@ -1181,7 +1147,7 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, */ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { CACHE_REGS - Atom at; + Atom at; arity_t arity = 0; Functor f; char *s, *smax, *s0; @@ -1213,7 +1179,7 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { } else if (ap->PredFlags & AtomDBPredFlag) { at = (Atom)(ap->FunctorOfPred); if (!stpcpy(s, Yap_AtomToUTF8Text(at))) - return NULL; + return NULL; } else { f = ap->FunctorOfPred; at = NameOfFunctor(f); diff --git a/C/text.c.new b/C/text.c.new index e4326e3d9..3db58d085 100644 --- a/C/text.c.new +++ b/C/text.c.new @@ -1,19 +1,19 @@ /************************************************************************* -* * -* YAP Prolog * -* * -* Yap Prolog was developed at NCCUP - Universidade do Porto * -* * -* Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- * -* * -************************************************************************** -* * -* File: strings.c * -* comments: General-conversion of character sequences. * -* * -* Last rev: $Date: 2008-07-24 16:02:00 $,$Author: vsc $ * -* * -*************************************************************************/ + * * + * YAP Prolog * + * * + * Yap Prolog was developed at NCCUP - Universidade do Porto * + * * + * Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- * + * * + ************************************************************************** + * * + * File: strings.c * + * comments: General-conversion of character sequences. * + * * + * Last rev: $Date: 2008-07-24 16:02:00 $,$Author: vsc $ * + * * + *************************************************************************/ #include "Yap.h" #include "YapEval.h" @@ -31,6 +31,13 @@ inline static size_t min_size(size_t i, size_t j) { return (i < j ? i : j); } #define wcsnlen(S, N) min_size(N, wcslen(S)) #endif +#if !defined(HAVE_STPCPY) && !defined(__APPLE__) +inline static void *__stpcpy(void *i, const void *j) { + return strcpy(i, j) + strlen(j); +} +#define stpcpy __stpcpy +#endif + #ifndef NAN #define NAN (0.0 / 0.0) #endif @@ -51,11 +58,16 @@ typedef struct TextBuffer_manager { int lvl; } text_buffer_t; -int push_text_stack(USES_REGS1) { +int AllocLevel(void) { return LOCAL_TextBuffer->lvl; } +int push_text_stack__(USES_REGS1) { + int i = LOCAL_TextBuffer->lvl; + i++; + LOCAL_TextBuffer->lvl = i; - return LOCAL_TextBuffer->lvl++; } + return i; +} -int pop_text_stack(int i) { +int pop_text_stack__(int i) { int lvl = LOCAL_TextBuffer->lvl; while (lvl >= i) { struct mblock *p = LOCAL_TextBuffer->first[lvl]; @@ -68,26 +80,22 @@ int pop_text_stack(int i) { LOCAL_TextBuffer->last[lvl] = NULL; lvl--; } - LOCAL_TextBuffer->lvl = i; + LOCAL_TextBuffer->lvl = lvl; return lvl; } -void *protected_pop_text_stack(int i, void *protected, bool tmp, - size_t sz USES_REGS) { - void *out = protected; +void *pop_output_text_stack__(int i, const void *export) { int lvl = LOCAL_TextBuffer->lvl; - while (lvl > i) { + while (lvl >= i) { struct mblock *p = LOCAL_TextBuffer->first[lvl]; while (p) { struct mblock *np = p->next; - if (p + 1 == protected) { - if (tmp) - out = LOCAL_FileNameBuf; - else - out = p; - memmove(out, protected, sz); + if (p + 1 == export) { + size_t sz = p->sz - sizeof(struct mblock); + memmove(p, p + 1, sz); + export = p; } else { - free(p); + free(p); } p = np; } @@ -96,19 +104,12 @@ void *protected_pop_text_stack(int i, void *protected, bool tmp, lvl--; } LOCAL_TextBuffer->lvl = lvl; - return out; + return (void *)export; } // void pop_text_stack(int i) { LOCAL_TextBuffer->lvl = i; } - -void *Malloc(size_t sz USES_REGS) { - int lvl = LOCAL_TextBuffer->lvl; - if (sz == 0) - sz = 1024; - sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL); - struct mblock *o = malloc(sz); - if (!o) - return NULL; +void insert_block(struct mblock *o) { + int lvl = o->lvl; o->prev = LOCAL_TextBuffer->last[lvl]; if (o->prev) { o->prev->next = o; @@ -119,38 +120,9 @@ void *Malloc(size_t sz USES_REGS) { LOCAL_TextBuffer->first[lvl] = LOCAL_TextBuffer->last[lvl] = o; } o->next = NULL; - o->sz = sz; - o->lvl = lvl; - return o + 1; } -void *Realloc(void *pt, size_t sz USES_REGS) { - sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL); - struct mblock *old = pt, *o; - old--; - int lvl = old->lvl; - o = realloc(old, sz); - if (o->prev) - o->prev->next = o; - if (o->next) - o->next->prev = o; - if (LOCAL_TextBuffer->first[lvl] == old) { - LOCAL_TextBuffer->first[lvl] = o; - } - if (LOCAL_TextBuffer->last[lvl] == old) { - LOCAL_TextBuffer->last[lvl] = o; - } - - return o + 1; -} - -void Free(void *pt USES_REGS) { - struct mblock *o = pt; - o--; - if (o->prev) - o->prev->next = o->next; - if (o->next) - o->next->prev = o->prev; +void release_block(struct mblock *o) { int lvl = o->lvl; if (LOCAL_TextBuffer->first[lvl] == o) { if (LOCAL_TextBuffer->last[lvl] == o) { @@ -160,6 +132,81 @@ void Free(void *pt USES_REGS) { } else if (LOCAL_TextBuffer->last[lvl] == o) { LOCAL_TextBuffer->last[lvl] = o->prev; } + if (o->prev) + o->prev->next = o->next; + if (o->next) + o->next->prev = o->prev; +} + +void *Malloc(size_t sz USES_REGS) { + int lvl = LOCAL_TextBuffer->lvl; + if (sz == 0) + sz = 1024; + sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL); + struct mblock *o = malloc(sz); + if (!o) + return NULL; + o->sz = sz; + o->lvl = lvl; + o->prev = o->next = 0; + insert_block(o); + return o + 1; +} + +void *MallocAtLevel(size_t sz, int atL USES_REGS) { + int lvl = LOCAL_TextBuffer->lvl; + if (atL > 0 && atL <= lvl) { + lvl = atL; + } else if (atL < 0 && lvl - atL >= 0) { + lvl += atL; + } else { + return NULL; + } + if (sz == 0) + sz = 1024; + sz = ALIGN_BY_TYPE(sz + sizeof(struct mblock), CELL); + struct mblock *o = malloc(sz); + if (!o) + return NULL; + o->sz = sz; + o->lvl = lvl; + o->prev = o->next = 0; + insert_block(o); + return o + 1; +} + +void *Realloc(void *pt, size_t sz USES_REGS) { + sz += sizeof(struct mblock); + struct mblock *old = pt, *o; + old--; + release_block(old); + o = realloc(old, sz); + o->sz = sz; + insert_block(o); + + return o + 1; +} + +/** + * Export a local memory object as a RO object to the outside world, that is, + * recovering as much storage as one can. + * @param pt pointer to object + * @return new object + */ +const void *MallocExportAsRO(const void *pt USES_REGS) { + struct mblock *old = (void *)pt, *o = old - 1; + if (old == NULL) + return NULL; + size_t sz = o->sz; + release_block(o); + memmove((void *)o, pt, sz); + return realloc((void *)o, sz); +} + +void Free(void *pt USES_REGS) { + struct mblock *o = pt; + o--; + release_block(o); free(o); } @@ -168,11 +215,7 @@ void *Yap_InitTextAllocator(void) { return new; } -static size_t MaxTmp(USES_REGS1) { - - return ((char *)LOCAL_TextBuffer->buf + LOCAL_TextBuffer->sz) - - (char *)LOCAL_TextBuffer->ptr; -} +static size_t MaxTmp(USES_REGS1) { return 1025; } static Term Globalize(Term v USES_REGS) { if (!IsVarTerm(v = Deref(v))) { @@ -185,129 +228,138 @@ static Term Globalize(Term v USES_REGS) { return v; } -static Int SkipListCodes(unsigned char **bufp, Term *l, Term **tailp, - Int *atoms, bool *wide, seq_tv_t *inp USES_REGS) { - Int length = 0; - Term *s; /* slow */ - Term v; /* temporary */ - *wide = false; - unsigned char *st0 = *bufp, *st; +static void *codes2buf(Term t0, void *b0, bool get_codes, + bool fixed USES_REGS) { + unsigned char *st0, *st, ar[16]; + Term t = Deref(t0); + size_t length = 0; - if (!st0) { - st0 = Malloc(0); + if (t == TermNil) { + st0 = Malloc(4); + st0[0] = 0; + return st0; } - - do_derefa(v, l, derefa_unk, derefa_nonvar); - *tailp = l; - s = l; - - *bufp = st = st0; - - if (*l == TermNil) { - st[0] = '\0'; - return 0; + if (!IsPairTerm(t)) { + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; } - if (IsPairTerm(*l)) { - Term hd0 = HeadOfTerm(*l); - if (IsVarTerm(hd0)) { - return -INSTANTIATION_ERROR; + bool codes = IsIntegerTerm(HeadOfTerm(t)); + if (get_codes != codes && fixed) { + if (codes) { + Yap_ThrowError(TYPE_ERROR_INTEGER, HeadOfTerm(t), + "scanning list of codes"); + } else { + Yap_ThrowError(TYPE_ERROR_ATOM, HeadOfTerm(t), "scanning list of atoms"); } - // are we looking for atoms/codes? - // whatever the case, we should be consistent throughout, - // so we should be consistent with the first arg. - if (*atoms == 1) { - if (!IsIntegerTerm(hd0)) { - return -INSTANTIATION_ERROR; + } + if (codes) { + while (IsPairTerm(t)) { + Term hd = HeadOfTerm(t); + if (IsVarTerm(hd)) { + Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); + return NULL; } - } else if (*atoms == 2) { - if (!IsAtomTerm(hd0)) { - return -TYPE_ERROR_ATOM; + if (!IsIntegerTerm(hd)) { + Yap_ThrowError(TYPE_ERROR_CHARACTER_CODE, hd, "scanning list of codes"); + return NULL; + } + Int code = IntegerOfTerm(hd); + if (code < 0) { + Yap_ThrowError(REPRESENTATION_ERROR_CHARACTER_CODE, hd, + "scanning list of character codes, found %d", code); + return NULL; + } + length += put_utf8(ar, code); + t = TailOfTerm(t); + if (IsVarTerm(t)) { + Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); + return NULL; + } + if (!IsPairTerm(t) && t != TermNil) { + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; } } + } else { + while (IsPairTerm(t)) { + Term hd = HeadOfTerm(t); + if (IsVarTerm(hd)) { + Yap_ThrowError(INSTANTIATION_ERROR, hd, "scanning list of codes"); + return NULL; + } + if (!IsAtomTerm(hd)) { + Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of texts"); + return NULL; + } + const char *code = RepAtom(AtomOfTerm(hd))->StrOfAE; + if (code < 0) { + Yap_ThrowError(TYPE_ERROR_CHARACTER, hd, "scanning list of atoms"); + return NULL; + } + length += strlen(code); + t = TailOfTerm(t); + if (IsVarTerm(t)) { + Yap_ThrowError(INSTANTIATION_ERROR, t, "scanning list of codes"); + return NULL; + } + if (!IsPairTerm(t) && t != TermNil) { + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; + } + } + } - do { - int ch; - length++; - { - Term hd = Deref(RepPair(*l)[0]); - if (IsVarTerm(hd)) { - return -INSTANTIATION_ERROR; - } else if (IsAtomTerm(hd)) { - (*atoms)++; - if (*atoms < length) { - *tailp = l; - return -REPRESENTATION_ERROR_CHARACTER_CODE; - } else { - AtomEntry *ae = RepAtom(AtomOfTerm(hd)); - if ((ae->StrOfAE)[1] != '\0') { - length = -REPRESENTATION_ERROR_CHARACTER; - } else { - ch = RepAtom(AtomOfTerm(hd))->StrOfAE[0]; - *wide |= ch > 0x80; - } - } - } else if (IsIntegerTerm(hd)) { - ch = IntegerOfTerm(hd); - if (*atoms) - length = -REPRESENTATION_ERROR_CHARACTER; - else if (ch < 0) { - *tailp = l; - length = -REPRESENTATION_ERROR_CHARACTER_CODE; - } else { - *wide |= ch > 0x80; - } - } else { - length = -TYPE_ERROR_INTEGER; - } - if (length < 0) { - *tailp = l; - return length; - } - } - // now copy char to buffer - int chsz = put_utf8(st, ch); - if (chsz > 0) { - st += chsz; - } - l = RepPair(*l) + 1; - do_derefa(v, l, derefa2_unk, derefa2_nonvar); - } while (*l != *s && IsPairTerm(*l)); + if (!IsVarTerm(t)) { + if (t != TermNil) { + Yap_ThrowError(TYPE_ERROR_LIST, t, "scanning list of codes"); + return NULL; + } } - if (IsVarTerm(*l)) { - return -INSTANTIATION_ERROR; - } - if (*l != TermNil) { - return -TYPE_ERROR_LIST; + + st0 = st = Malloc(length + 1); + t = t0; + if (codes) { + while (IsPairTerm(t)) { + Term hd = HeadOfTerm(t); + Int code = IntegerOfTerm(hd); + + st = st + put_utf8(st, code); + t = TailOfTerm(t); + } + } else { + while (IsPairTerm(t)) { + Term hd = HeadOfTerm(t); + const char *code = RepAtom(AtomOfTerm(hd))->StrOfAE; + st = (unsigned char *)stpcpy((char *)st, code); + t = TailOfTerm(t); + } } st[0] = '\0'; - Malloc((st - st0) + 1); - *tailp = l; - return length; + return st0; } -static unsigned char *latin2utf8(seq_tv_t *inp, size_t *lengp) { +static unsigned char *latin2utf8(seq_tv_t *inp) { unsigned char *b0 = inp->val.uc; - size_t sz = *lengp = strlen(inp->val.c); + size_t sz = strlen(inp->val.c); sz *= 2; int ch; unsigned char *buf = Malloc(sz + 1), *pt = buf; - *lengp = strlen(inp->val.c); if (!buf) return NULL; while ((ch = *b0++)) { int off = put_utf8(pt, ch); - if (off < 0) + if (off < 0) { continue; + } pt += off; } *pt++ = '\0'; return buf; } -static unsigned char *wchar2utf8(seq_tv_t *inp, size_t *lengp) { - *lengp = wcslen(inp->val.w); - size_t sz = *lengp * 4; +static unsigned char *wchar2utf8(seq_tv_t *inp) { + size_t sz = wcslen(inp->val.w) * 4; wchar_t *b0 = inp->val.w; unsigned char *buf = Malloc(sz + 1), *pt = buf; int ch; @@ -319,57 +371,36 @@ static unsigned char *wchar2utf8(seq_tv_t *inp, size_t *lengp) { return buf; } -static void *slice(size_t min, size_t max, unsigned char *buf USES_REGS); - -static unsigned char *to_buffer(unsigned char *buf, Term t, seq_tv_t *inp, - bool *widep, Int *atoms, - size_t *lenp USES_REGS) { - CELL *r = NULL; - Int n; - - if (!buf) { - inp->max = *lenp; - } - unsigned char *bufc = buf; - n = SkipListCodes(&bufc, &t, &r, atoms, widep, inp PASS_REGS); - if (n < 0) { - LOCAL_Error_TYPE = -n; - return NULL; - } - *lenp = n; - return bufc; -} +static void *slice(size_t min, size_t max, const unsigned char *buf USES_REGS); static unsigned char *Yap_ListOfCodesToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp, bool *widep, - size_t *lenp USES_REGS) { - Int atoms = 1; // we only want lists of atoms - return to_buffer(buf, t, inp, widep, &atoms, lenp PASS_REGS); + seq_tv_t *inp USES_REGS) { + bool codes = true, fixed = true; + unsigned char *nbuf = codes2buf(t, buf, codes, fixed PASS_REGS); + return nbuf; } static unsigned char *Yap_ListOfAtomsToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp, bool *widep, - size_t *lenp USES_REGS) { - Int atoms = 2; // we only want lists of integer codes - return to_buffer(buf, t, inp, widep, &atoms, lenp PASS_REGS); + seq_tv_t *inp USES_REGS) { + bool codes = false; + unsigned char *nbuf = codes2buf(t, buf, codes, true PASS_REGS); + return nbuf; } static unsigned char *Yap_ListToBuffer(unsigned char *buf, Term t, - seq_tv_t *inp, bool *widep, - size_t *lenp USES_REGS) { - Int atoms = 0; // we accept both types of lists. - return to_buffer(buf, t, inp, widep, &atoms, lenp PASS_REGS); + seq_tv_t *inp USES_REGS) { + return codes2buf(t, buf, NULL, false PASS_REGS); } #if USE_GEN_TYPE_ERROR static yap_error_number gen_type_error(int flags) { if ((flags & (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | - YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) == + YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) == (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_ATOMS_CODES | YAP_STRING_BIG)) return TYPE_ERROR_TEXT; if ((flags & (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | - YAP_STRING_FLOAT | YAP_STRING_BIG)) == + YAP_STRING_FLOAT | YAP_STRING_BIG)) == (YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) return TYPE_ERROR_ATOMIC; @@ -386,147 +417,188 @@ static yap_error_number gen_type_error(int flags) { } #endif -// static int cnt; - -unsigned char *Yap_readText(seq_tv_t *inp, size_t *lengp) { - unsigned char *s0 = NULL; - bool wide; - - if (LOCAL_Error_TYPE != YAP_NO_ERROR) { - fprintf(stderr, "Sourious error %u\n", LOCAL_Error_TYPE); - LOCAL_Error_TYPE = YAP_NO_ERROR; +static yap_error_number type_error(seq_tv_t *inp) { + if ((inp->type & YAP_STRING_ATOMS_CODES) == YAP_STRING_ATOMS_CODES) + { + return TYPE_ERROR_IN_CHARACTER; + } + if ((inp->type & YAP_STRING_ATOMS) == YAP_STRING_ATOMS) { + return TYPE_ERROR_CHARACTER; } + if ((inp->type & YAP_STRING_CODES) == YAP_STRING_CODES) { + return TYPE_ERROR_CHARACTER_CODE; + } + if ((inp->type & YAP_STRING_STRING) == YAP_STRING_STRING) { + return TYPE_ERROR_IN_CHARACTER; + } + if ((inp->type & YAP_STRING_CODES) == YAP_STRING_CODES) { + return TYPE_ERROR_IN_CHARACTER; + } + if ((inp->type & (YAP_STRING_ATOM|YAP_STRING_STRING)) == (YAP_STRING_ATOM|YAP_STRING_STRING)) { + return TYPE_ERROR_ATOMIC; + } + if ((inp->type & YAP_STRING_ATOM) == YAP_STRING_ATOM) { + return TYPE_ERROR_IN_CHARACTER; + } + return SYSTEM_ERROR_INTERNAL; +} + +/// @brief translate anything to bufffer UTF-8 +/// +/// @arg input descriptor +unsigned char *Yap_readText(seq_tv_t *inp USES_REGS) { +#define POPRET(x) return pop_output_text_stack(lvl, x) + int lvl = push_text_stack(); + char *out = NULL; /* we know what the term is */ - if (!(inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) { - if (!(inp->type & YAP_STRING_TERM)) { - if (IsVarTerm(inp->val.t)) { - LOCAL_Error_TYPE = INSTANTIATION_ERROR; - } else if (!IsAtomTerm(inp->val.t) && inp->type == YAP_STRING_ATOM) { - LOCAL_Error_TYPE = TYPE_ERROR_ATOM; - } else if (!IsStringTerm(inp->val.t) && inp->type == YAP_STRING_STRING) { - LOCAL_Error_TYPE = TYPE_ERROR_STRING; - } else if (!IsPairOrNilTerm(inp->val.t) && !IsStringTerm(inp->val.t) && - inp->type == (YAP_STRING_ATOMS_CODES | YAP_STRING_STRING)) { - LOCAL_Error_TYPE = TYPE_ERROR_LIST; - } else if (!IsNumTerm(inp->val.t) && - (inp->type & (YAP_STRING_INT | YAP_STRING_FLOAT | - YAP_STRING_BIG)) == inp->type) { - LOCAL_Error_TYPE = TYPE_ERROR_NUMBER; + if ((inp->type & (YAP_STRING_CHARS | YAP_STRING_WCHARS))) { + //> buffer processing + //> must convert: + if (inp->type & YAP_STRING_CHARS) { + //> - ASCII to UTF-8 + if (inp->enc == ENC_ISO_ASCII) { + pop_text_stack(lvl); + return inp->val.uc; + } + //> - ISO-LATIN-1 to UTF-8 + if (inp->enc == ENC_ISO_LATIN1) { + POPRET( (char*)latin2utf8(inp)); + } + + //> - assume UTF-8 + if (inp->enc == ENC_ISO_UTF8) { + pop_text_stack(lvl); + return inp->val.uc; } } - } - if (LOCAL_Error_TYPE != YAP_NO_ERROR) - return NULL; + if (inp->type & YAP_STRING_WCHARS) { + // printf("%S\n",inp->val.w); + //> wide includes everything else + POPRET( (char *)wchar2utf8(inp) ); + } + } else { + if (inp->type & YAP_STRING_TERM) { + //> term: anything goes + pop_text_stack(lvl); + return (unsigned char *)Yap_TermToBuffer(inp->val.t, 0); + } + if (IsVarTerm(inp->val.t)) { + Yap_ThrowError(INSTANTIATION_ERROR, inp->val.t, NULL); + } + if (IsPairOrNilTerm(inp->val.t)) { + if (((inp->type & (YAP_STRING_CODES | YAP_STRING_ATOMS)) == + (YAP_STRING_CODES | YAP_STRING_ATOMS))) { + // Yap_DebugPlWriteln(inp->val.t); + out = (char *)Yap_ListToBuffer(NULL, inp->val.t, inp PASS_REGS); + POPRET( out ); + // this is a term, extract to a sfer, and representation is wide + } + if (inp->type & YAP_STRING_CODES) { + // Yap_DebugPlWriteln(inp->val.t); + out = (char *)Yap_ListOfCodesToBuffer(NULL, inp->val.t, inp PASS_REGS); + // this is a term, extract to a sfer, and representation is wide + POPRET( out ); + } - if (IsAtomTerm(inp->val.t) && inp->type & YAP_STRING_ATOM) { - // this is a term, extract to a buffer, and representation is wide - // Yap_DebugPlWriteln(inp->val.t); - Atom at = AtomOfTerm(inp->val.t); - size_t sz = strlen(at->StrOfAE); - if (lengp) - *lengp = sz; - if (inp->type & YAP_STRING_WITH_BUFFER) - return at->UStrOfAE; - inp->type |= YAP_STRING_IN_TMP; - char *o = Malloc(sz+1); - strcpy(o, at->StrOfAE); - return (unsigned char *)o; - } - if (IsStringTerm(inp->val.t) && inp->type & YAP_STRING_STRING) { - // this is a term, extract to a buffer, and representation is wide - // Yap_DebugPlWriteln(inp->val.t); - const char *s = StringOfTerm(inp->val.t); - size_t sz = strlen( s ); - if (lengp) - *lengp = sz; - if (inp->type & YAP_STRING_WITH_BUFFER) - return (unsigned char *)UStringOfTerm(inp->val.t); - inp->type |= YAP_STRING_IN_TMP; - char *o = Malloc(sz+1); - strcpy(o, s); - return (unsigned char *)o; - } - if (((inp->type & (YAP_STRING_CODES | YAP_STRING_ATOMS)) == - (YAP_STRING_CODES | YAP_STRING_ATOMS)) && - IsPairOrNilTerm(inp->val.t)) { - // Yap_DebugPlWriteln(inp->val.t); - return Yap_ListToBuffer(s0, inp->val.t, inp, &wide, lengp PASS_REGS); - // this is a term, extract to a sfer, and representation is wide - } - if (inp->type & YAP_STRING_CODES && IsPairOrNilTerm(inp->val.t)) { - // Yap_DebugPlWriteln(inp->val.t); - return Yap_ListOfCodesToBuffer(s0, inp->val.t, inp, &wide, lengp PASS_REGS); - // this is a term, extract to a sfer, and representation is wide - } - if (inp->type & YAP_STRING_ATOMS && IsPairOrNilTerm(inp->val.t)) { - // Yap_DebugPlWriteln(inp->val.t); - return Yap_ListOfAtomsToBuffer(s0, inp->val.t, inp, &wide, lengp PASS_REGS); - // this is a term, extract to a buffer, and representation is wide - } - if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) { - // ASCII, so both LATIN1 and UTF-8 - // Yap_DebugPlWriteln(inp->val.t); - char *s; - s = Malloc(0); - if (snprintf(s, MaxTmp(PASS_REGS1) - 1, Int_FORMAT, - IntegerOfTerm(inp->val.t)) < 0) { - AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), s, char); + if (inp->type & YAP_STRING_ATOMS) { + // Yap_DebugPlWriteln(inp->val.t); + out = (char *)Yap_ListOfAtomsToBuffer(NULL, inp->val.t, inp PASS_REGS); + // this is a term, extract to a buffer, and representation is wide + POPRET( out ); + } } - if (lengp) - *lengp = strlen(s); - return (unsigned char *)s; - } - if (inp->type & YAP_STRING_FLOAT && IsFloatTerm(inp->val.t)) { - char *s; - // Yap_DebugPlWriteln(inp->val.t); - if (!Yap_FormatFloat(FloatOfTerm(inp->val.t), &s, 1024)) { - return NULL; + if (IsStringTerm(inp->val.t)) { + if(!(inp->type & (YAP_STRING_STRING))) { + Yap_ThrowError(type_error(inp), inp->val.t, NULL); + } + // this is a term, extract to a buffer, and representation is wide + // Yap_DebugPlWriteln(inp->val.t); + const char *s = StringOfTerm(inp->val.t); + if (s[0] == 0) { + out = Malloc(4); + memset(out, 0, 4); + POPRET( out ); + } + if (inp->type & YAP_STRING_WITH_BUFFER) { + pop_text_stack(lvl); + return (unsigned char *)UStringOfTerm(inp->val.t); + } + { + inp->type |= YAP_STRING_IN_TMP; + size_t sz = strlen(s); + out = Malloc(sz + 1); + strcpy(out, s); + POPRET( out ); + } + } + if (IsAtomTerm(inp->val.t)) { + if(!(inp->type & (YAP_STRING_ATOM))) { + Yap_ThrowError(type_error(inp), inp->val.t, NULL); + } + // this is a term, extract to a buffer, and representation is wide + // Yap_DebugPlWriteln(inp->val.t); + Atom at = AtomOfTerm(inp->val.t); + if (RepAtom(at)->UStrOfAE[0] == '\0') { + out = Malloc(4); + memset(out, 0, 4); + POPRET( out ); + } + if (inp->type & YAP_STRING_WITH_BUFFER) { + pop_text_stack(lvl); + return at->UStrOfAE; + } else + { + size_t sz = strlen(at->StrOfAE); + out = Malloc(sz + 1); + strcpy(out, at->StrOfAE); + POPRET( out ); + } + } + if (inp->type & YAP_STRING_INT && IsIntegerTerm(inp->val.t)) { + if(!(inp->type & (YAP_STRING_INT))) { + Yap_ThrowError(type_error(inp), inp->val.t, NULL); + } // ASCII, so both LATIN1 and UTF-8 + // Yap_DebugPlWriteln(inp->val.t); + out = Malloc(2 * MaxTmp(PASS_REGS1)); + if (snprintf(out, MaxTmp(PASS_REGS1) - 1, Int_FORMAT, + IntegerOfTerm(inp->val.t)) < 0) { + AUX_ERROR(inp->val.t, 2 * MaxTmp(PASS_REGS1), out, char); + } + POPRET( out ); + } + if (inp->type & YAP_STRING_FLOAT && IsFloatTerm(inp->val.t)) { + if(!(inp->type & (YAP_STRING_FLOAT))) { + Yap_ThrowError(type_error(inp), inp->val.t, NULL); + } // ASCII, so both LATIN1 and UTF-8 + out = Malloc(2 * MaxTmp(PASS_REGS1)); + if (!Yap_FormatFloat(FloatOfTerm(inp->val.t), &out, 1024)) { + pop_text_stack(lvl); + return NULL; + } + POPRET(out); } - if (lengp) - *lengp = strlen(s); - return (unsigned char *)s; - } #if USE_GMP - if (inp->type & YAP_STRING_BIG && IsBigIntTerm(inp->val.t)) { - // Yap_DebugPlWriteln(inp->val.t); - char *s; - s = Malloc(0); - if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), s, MaxTmp() - 1, 10)) { - AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), s, char); + if ( IsBigIntTerm(inp->val.t)) { + if(!(inp->type & (YAP_STRING_BIG))) { + Yap_ThrowError(type_error(inp), inp->val.t, NULL); + } // ASCII, so both LATIN1 and UTF-8 + // Yap_DebugPlWriteln(inp->val.t); + out = Malloc(MaxTmp()); + if (!Yap_mpz_to_string(Yap_BigIntOfTerm(inp->val.t), out, MaxTmp() - 1, + 10)) { + AUX_ERROR(inp->val.t, MaxTmp(PASS_REGS1), out, char); + } + POPRET(out); } - if (lengp) - *lengp = strlen(s); - return inp->val.uc = (unsigned char *)s; - } #endif - if (inp->type & YAP_STRING_TERM) { - // Yap_DebugPlWriteln(inp->val.t); - char *s = (char *) Yap_TermToBuffer(inp->val.t, lengp, ENC_ISO_UTF8, 0); - return inp->val.uc = (unsigned char *)s; - } - if (inp->type & YAP_STRING_CHARS) { - if (inp->enc == ENC_ISO_LATIN1) { - return latin2utf8(inp, lengp); - } else if (inp->enc == ENC_ISO_ASCII) { - if (lengp) - *lengp = strlen(inp->val.c); - return inp->val.uc; - }else { //if (inp->enc == ENC_ISO_UTF8) { - if (lengp) - *lengp = strlen(inp->val.c); - return inp->val.uc; - } - } - if (inp->type & YAP_STRING_WCHARS) { - // printf("%S\n",inp->val.w); - return wchar2utf8(inp, lengp); } + pop_text_stack(lvl); + Yap_ThrowError(type_error(inp), inp->val.t, NULL); return NULL; } -static Term write_strings(unsigned char *s0, seq_tv_t *out, - size_t leng USES_REGS) { - size_t min = 0, max = leng; +static Term write_strings(unsigned char *s0, seq_tv_t *out USES_REGS) { + size_t min = 0, max = strlen((char *)s0); if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { if (out->type & YAP_STRING_NCHARS) @@ -541,14 +613,16 @@ static Term write_strings(unsigned char *s0, seq_tv_t *out, Term t = init_tstring(PASS_REGS1); LOCAL_TERM_ERROR(t, 2 * max); unsigned char *buf = buf_from_tstring(HR); - strcpy( (char *)buf, s ) - ; - if (max+1 < min) { - LOCAL_TERM_ERROR(t, 2 * min); - memset(buf+min, '\0', max); + if (max == 0) + buf[0] = '\0'; + else + strcpy((char *)buf, s); + if (max + 1 < min) { + LOCAL_TERM_ERROR(t, 2 * min); + memset(buf + min, '\0', max); buf += min; } else { - buf += max+1; + buf += max + 1; } close_tstring(buf PASS_REGS); out->val.t = t; @@ -556,12 +630,13 @@ static Term write_strings(unsigned char *s0, seq_tv_t *out, return out->val.t; } -static Term write_atoms(void *s0, seq_tv_t *out, size_t leng USES_REGS) { +static Term write_atoms(void *s0, seq_tv_t *out USES_REGS) { Term t = AbsPair(HR); + char *s1 = (char *)s0; size_t sz = 0; - size_t max = leng; - if (leng == 0) { - out->val.t = t; + size_t max = strlen(s1); + if (s1[0] == '\0') { + out->val.t = TermNil; return TermNil; } if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { @@ -571,17 +646,19 @@ static Term write_atoms(void *s0, seq_tv_t *out, size_t leng USES_REGS) { unsigned char *s = s0, *lim = s + strnlen((char *)s, max); unsigned char *cp = s; - unsigned char w[10], *wp = w; + unsigned char w[10]; + int wp = 0; LOCAL_TERM_ERROR(t, 2 * (lim - s)); while (cp < lim && *cp) { utf8proc_int32_t chr; CELL *cl; - s += get_utf8(s, 1, &chr); + s += get_utf8(s, -1, &chr); if (chr == '\0') { - wp[0] = '\0'; + w[0] = '\0'; break; } - wp += put_utf8(w, chr); + wp = put_utf8(w, chr); + w[wp] = '\0'; cl = HR; HR += 2; cl[0] = MkAtomTerm(Yap_ULookupAtom(w)); @@ -605,23 +682,23 @@ static Term write_atoms(void *s0, seq_tv_t *out, size_t leng USES_REGS) { return (t); } -static Term write_codes(void *s0, seq_tv_t *out, size_t leng USES_REGS) { - Term t = AbsPair(HR); - size_t sz = 0; - size_t max = leng; - if (leng == 0) { - out->val.t = t; - return TermNil; +static Term write_codes(void *s0, seq_tv_t *out USES_REGS) { + Term t; + size_t sz = strlen(s0); + if (sz == 0) { + if (out->type & YAP_STRING_DIFF) { + out->val.t = Globalize(out->dif PASS_REGS); + } else { + out->val.t = TermNil; + } + return out->val.t; } - if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { - if (out->type & YAP_STRING_TRUNC && out->max < max) - max = out->max; - } - - unsigned char *s = s0, *lim = s + strlen((char *)s); + unsigned char *s = s0, *lim = s + sz; unsigned char *cp = s; + t = AbsPair(HR); LOCAL_TERM_ERROR(t, 2 * (lim - s)); + t = AbsPair(HR); while (*cp) { utf8proc_int32_t chr; CELL *cl; @@ -632,65 +709,63 @@ static Term write_codes(void *s0, seq_tv_t *out, size_t leng USES_REGS) { HR += 2; cl[0] = MkIntegerTerm(chr); cl[1] = AbsPair(HR); - sz++; - if (sz == max) - break; } - if (out->type & YAP_STRING_DIFF) { - if (sz == 0) - t = out->dif; - else - HR[-1] = Globalize(out->dif PASS_REGS); + if (sz == 0) { + HR[-1] = Globalize(out->dif PASS_REGS); } else { - if (sz == 0) - t = TermNil; - else - HR[-1] = TermNil; + HR[-1] = TermNil; } out->val.t = t; return (t); } -static Atom write_atom(void *s0, seq_tv_t *out, size_t leng USES_REGS) { +static Atom write_atom(void *s0, seq_tv_t *out USES_REGS) { unsigned char *s = s0; int32_t ch; - if (leng == 0) { + if (s[0] == '\0') { return Yap_LookupAtom(""); } + size_t leng = strlen(s0); if (strlen_utf8(s0) <= leng) { return Yap_LookupAtom(s0); } else { - unsigned char *buf = Malloc(leng + 1); - memmove(buf, s0, leng); - buf[leng] = \0; + size_t n = get_utf8(s, -1, &ch); + unsigned char *buf = Malloc(n + 1); + memmove(buf, s0, n + 1); return Yap_ULookupAtom(buf); } } -size_t write_buffer(unsigned char *s0, seq_tv_t *out, size_t leng USES_REGS) { - size_t min = 0, max = leng, room_end; +void *write_buffer(unsigned char *s0, seq_tv_t *out USES_REGS) { + int l = push_text_stack(); + size_t leng = strlen((char *)s0); + size_t min = 0, max = leng; if (out->enc == ENC_ISO_UTF8) { - room_end = strlen((char *)s0) + 1; if (out->val.uc == NULL) { // this should always be the case - out->val.uc = malloc(room_end < 16 ? 16 : room_end); - } - if (out->val.uc != s0) { + out->val.uc = Malloc(leng + 1); + strcpy(out->val.c, (char *)s0); + } else if (out->val.uc != s0) { + out->val.c = Malloc(leng + 1); strcpy(out->val.c, (char *)s0); } } else if (out->enc == ENC_ISO_LATIN1) { - room_end = strlen((char *)s0) + 1; + unsigned char *s = s0; unsigned char *cp = s; unsigned char *buf = out->val.uc; - if (!buf) - return -1; + if (!buf) { + pop_text_stack(l); + return NULL; + } while (*cp) { utf8proc_int32_t chr; int off = get_utf8(cp, -1, &chr); - if (off <= 0 || chr > 255) - return -1; + if (off <= 0 || chr > 255) { + pop_text_stack(l); + return NULL; + } if (off == max) - break; + break; cp += off; *buf++ = chr; } @@ -698,20 +773,21 @@ size_t write_buffer(unsigned char *s0, seq_tv_t *out, size_t leng USES_REGS) { *buf++ = '\0'; else while (max < min) { - utf8proc_int32_t chr; - max++; - cp += get_utf8(cp, -1, &chr); - *buf++ = chr; + utf8proc_int32_t chr; + max++; + cp += get_utf8(cp, -1, &chr); + *buf++ = chr; } - room_end = buf - out->val.uc; } else if (out->enc == ENC_WCHAR) { unsigned char *s = s0, *lim = s + (max = strnlen((char *)s0, max)); unsigned char *cp = s; wchar_t *buf0, *buf; buf = buf0 = out->val.w; - if (!buf) - return -1; + if (!buf) { + pop_text_stack(l); + return NULL; + } while (*cp && cp < lim) { utf8proc_int32_t chr; cp += get_utf8(cp, -1, &chr); @@ -721,53 +797,56 @@ size_t write_buffer(unsigned char *s0, seq_tv_t *out, size_t leng USES_REGS) { *buf++ = '\0'; else while (max < min) { - utf8proc_int32_t chr; - max++; - cp += get_utf8(cp, -1, &chr); - *buf++ = chr; + utf8proc_int32_t chr; + max++; + cp += get_utf8(cp, -1, &chr); + *buf++ = chr; } *buf = '\0'; - room_end = (buf - buf0) + 1; } else { // no other encodings are supported. - room_end = -1; + pop_text_stack(l); + return NULL; } - return room_end; + out->val.c = pop_output_text_stack(l, out->val.c); + return out->val.c; } -static size_t write_length(const unsigned char *s0, seq_tv_t *out, - size_t leng USES_REGS) { - return leng; +static size_t write_length(const unsigned char *s0, seq_tv_t *out USES_REGS) { + return strlen_utf8(s0); } -static Term write_number(unsigned char *s, seq_tv_t *out, int size, - bool error_on USES_REGS) { +static Term write_number(unsigned char *s, seq_tv_t *out, + bool error_on USES_REGS) { Term t; - int i = push_text_stack(); + LOCAL_delay = !error_on; t = Yap_StringToNumberTerm((char *)s, &out->enc, error_on); - pop_text_stack(i); + LOCAL_delay = false; return t; } -static Term string_to_term(void *s, seq_tv_t *out, size_t leng USES_REGS) { +static Term string_to_term(void *s, seq_tv_t *out USES_REGS) { Term o; - o = out->val.t = Yap_BufferToTerm(s, strlen(s) + 1, TermNil); + yap_error_descriptor_t *new_error = malloc(sizeof(yap_error_descriptor_t)); + bool mdnew = Yap_pushErrorContext(true, new_error); + o = out->val.t = Yap_BufferToTerm(s, TermNil); + Yap_popErrorContext(mdnew, true); + return o; } -bool write_Text(unsigned char *inp, seq_tv_t *out, size_t leng USES_REGS) { +bool write_Text(unsigned char *inp, seq_tv_t *out USES_REGS) { /* we know what the term is */ if (out->type == 0) { return true; } - - if (out->type & YAP_STRING_TERM) { - if ((out->val.t = string_to_term(inp, out, leng PASS_REGS)) != 0L) - return out->val.t != 0; + if (LOCAL_Error_TYPE) { + return false; } + if (out->type & (YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG)) { if ((out->val.t = write_number( - inp, out, leng, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) { + inp, out, !(out->type & YAP_STRING_ATOM) PASS_REGS)) != 0L) { // Yap_DebugPlWriteln(out->val.t); return true; @@ -777,48 +856,52 @@ bool write_Text(unsigned char *inp, seq_tv_t *out, size_t leng USES_REGS) { return false; } if (out->type & (YAP_STRING_ATOM)) { - if ((out->val.a = write_atom(inp, out, leng PASS_REGS)) != NIL) { + if ((out->val.a = write_atom(inp, out PASS_REGS)) != NIL) { Atom at = out->val.a; if (at && (out->type & YAP_STRING_OUTPUT_TERM)) - out->val.t = MkAtomTerm(at); + out->val.t = MkAtomTerm(at); // Yap_DebugPlWriteln(out->val.t); return at != NIL; } } + if (out->type & YAP_STRING_DATUM) { + if ((out->val.t = string_to_term(inp, out PASS_REGS)) != 0L) + return out->val.t != 0; + } switch (out->type & YAP_TYPE_MASK) { case YAP_STRING_CHARS: { - size_t room = write_buffer(inp, out, leng PASS_REGS); + void *room = write_buffer(inp, out PASS_REGS); // printf("%s\n", out->val.c); - return ((Int)room > 0); + return room != NULL; } case YAP_STRING_WCHARS: { - size_t room = write_buffer(inp, out, leng PASS_REGS); + void *room = write_buffer(inp, out PASS_REGS); // printf("%S\n", out->val.w); - return ((Int)room > 0); + return room != NULL; } case YAP_STRING_STRING: - out->val.t = write_strings(inp, out, leng PASS_REGS); + out->val.t = write_strings(inp, out PASS_REGS); // Yap_DebugPlWriteln(out->val.t); return out->val.t != 0; case YAP_STRING_ATOMS: - out->val.t = write_atoms(inp, out, leng PASS_REGS); + out->val.t = write_atoms(inp, out PASS_REGS); // Yap_DebugPlWriteln(out->val.t); return out->val.t != 0; case YAP_STRING_CODES: - out->val.t = write_codes(inp, out, leng PASS_REGS); + out->val.t = write_codes(inp, out PASS_REGS); // Yap_DebugPlWriteln(out->val.t); return out->val.t != 0; case YAP_STRING_LENGTH: - out->val.l = write_length(inp, out, leng PASS_REGS); + out->val.l = write_length(inp, out PASS_REGS); // printf("s\n",out->val.l); return out->val.l != (size_t)(-1); case YAP_STRING_ATOM: - out->val.a = write_atom(inp, out, leng PASS_REGS); + out->val.a = write_atom(inp, out PASS_REGS); // Yap_DebugPlWriteln(out->val.t); return out->val.a != NULL; case YAP_STRING_INT | YAP_STRING_FLOAT | YAP_STRING_BIG: - out->val.t = write_number(inp, out, leng, true PASS_REGS); + out->val.t = write_number(inp, out, true PASS_REGS); // Yap_DebugPlWriteln(out->val.t); return out->val.t != 0; default: { return true; } @@ -856,76 +939,69 @@ bool Yap_CVT_Text(seq_tv_t *inp, seq_tv_t *out USES_REGS) { unsigned char *buf; bool rc; - size_t leng_s; /* - f//printfmark(stderr, "[ %d ", n++) ; + //printf(stderr, "[ %d ", n++) ; if (inp->type & (YAP_STRING_TERM|YAP_STRING_ATOM|YAP_STRING_ATOMS_CODES - |YAP_STRING_STRING)) - //Yap_DebugPlWriteln(inp->val.t); + |YAP_STRING_STRING)) + //Yap_DebugPlWriteln(inp->val.t); else if (inp->type & YAP_STRING_WCHARS) fprintf(stderr,"S %S\n", inp->val - .w); + .w); else fprintf(stderr,"s %s\n", inp->val.c); -*/ + */ // cnt++; - buf = Yap_readText(inp, &leng_s PASS_REGS); - if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { - size_t max_s = skip_utf8( buf, out-> max )-buf; - if (max_s < leng_s) { - char *nbuf = Malloc(max_s + 1); - memmove(nbuf, buf, max_s); - nbuf[max_s] = '\0'; - leng_s = out->max; - } - // else if (out->type & YAP_STRING_NCHARS && - // const unsigned char *ptr = skip_utf8(buf, leng) - } + int l = push_text_stack(); + buf = Yap_readText(inp PASS_REGS); if (!buf) { + pop_text_stack(l); return 0L; } - - if (out->type & (YAP_STRING_UPCASE | YAP_STRING_DOWNCASE)) { - if (out->type & YAP_STRING_UPCASE) { - if (!upcase(buf, out)) { - return false; + if (buf[0]) { + size_t leng = strlen_utf8(buf); + if (out->type & (YAP_STRING_NCHARS | YAP_STRING_TRUNC)) { + if (out->max < leng) { + const unsigned char *ptr = skip_utf8(buf, out->max); + size_t diff = (ptr - buf); + char *nbuf = Malloc(diff + 1); + memmove(nbuf, buf, diff); + nbuf[diff] = '\0'; + leng = diff; } + // else if (out->type & YAP_STRING_NCHARS && + // const unsigned char *ptr = skip_utf8(buf) } - if (out->type & YAP_STRING_DOWNCASE) { - if (!downcase(buf, out)) { - return false; + + if (out->type & (YAP_STRING_UPCASE | YAP_STRING_DOWNCASE)) { + if (out->type & YAP_STRING_UPCASE) { + if (!upcase(buf, out)) { + pop_text_stack(l); + return false; + } + } + if (out->type & YAP_STRING_DOWNCASE) { + if (!downcase(buf, out)) { + pop_text_stack(l); + return false; + } } } } - - rc = write_Text(buf, out, leng_s PASS_REGS); + rc = write_Text(buf, out PASS_REGS); /* fprintf(stderr, " -> "); - if (!rc) fprintf(stderr, "NULL"); - else if (out->type & - (YAP_STRING_TERM|YAP_STRING_ATOMS_CODES - |YAP_STRING_STRING)) //Yap_DebugPlWrite(out->val.t); - else if (out->type & - YAP_STRING_ATOM) //Yap_DebugPlWriteln(MkAtomTerm(out->val.a)); - else if (out->type & YAP_STRING_WCHARS) fprintf(stderr, "%S", - out->val.w); - else - fprintf(stderr, "%s", out->val.c); - fprintf(stderr, "\n]\n"); */ + if (!rc) fprintf(stderr, "NULL"); + else if (out->type & + (YAP_STRING_TERM|YAP_STRING_ATOMS_CODES + |YAP_STRING_STRING)) //Yap_DebugPlWrite(out->val.t); + else if (out->type & + YAP_STRING_ATOM) //Yap_DebugPlWriteln(MkAtomTerm(out->val.a)); + else if (out->type & YAP_STRING_WCHARS) fprintf(stderr, "%S", + out->val.w); + else + fprintf(stderr, "%s", out->val.c); + fprintf(stderr, "\n]\n"); */ + pop_text_stack(l); return rc; } -static int cmp_Text(const unsigned char *s1, const unsigned char *s2, int l) { - const unsigned char *w1 = s1; - utf8proc_int32_t chr1, chr2; - const unsigned char *w2 = s2; - int i; - for (i = 0; i < l; i++) { - w2 += get_utf8(w2, -1, &chr2); - w1 += get_utf8(w1, -1, &chr1); - if (chr1 - chr2) - return chr1 - chr2; - } - return 0; -} - static unsigned char *concat(int n, void *sv[] USES_REGS) { void *buf; unsigned char *buf0; @@ -933,23 +1009,28 @@ static unsigned char *concat(int n, void *sv[] USES_REGS) { int i; for (i = 0; i < n; i++) { - room += strlen((char *)sv[i]); + char *s = sv[i]; + if (s[0]) + room += strlen(s); } buf = Malloc(room + 1); buf0 = buf; for (i = 0; i < n; i++) { + char *s = sv[i]; + if (!s[0]) + continue; #if _WIN32 || defined(__ANDROID__) - strcpy(buf, sv[i]); + strcpy(buf, s); buf = (char *)buf + strlen(buf); #else - buf = stpcpy(buf, sv[i]); + buf = stpcpy(buf, s); #endif } return buf0; } -static void *slice(size_t min, size_t max, unsigned char *buf USES_REGS) { - unsigned char *nbuf = Malloc((max - min) * 4 + 1); +static void *slice(size_t min, size_t max, const unsigned char *buf USES_REGS) { + unsigned char *nbuf = BaseMalloc((max - min) * 4 + 1); const unsigned char *ptr = skip_utf8(buf, min); unsigned char *nptr = nbuf; utf8proc_int32_t chr; @@ -967,74 +1048,104 @@ static void *slice(size_t min, size_t max, unsigned char *buf USES_REGS) { bool Yap_Concat_Text(int tot, seq_tv_t inp[], seq_tv_t *out USES_REGS) { void **bufv; unsigned char *buf; - int i; - size_t leng; - - + int i, j; + // int lvl = push_text_stack(); bufv = Malloc(tot * sizeof(unsigned char *)); if (!bufv) { + // pop_text_stack(lvl); return NULL; } - for (i = 0; i < tot; i++) { - inp[i].type |= YAP_STRING_WITH_BUFFER; - unsigned char *nbuf = Yap_readText(inp + i, &leng PASS_REGS); + for (i = 0, j = 0; i < tot; i++) { + // inp[j].type |= YAP_STRING_WITH_BUFFER; + unsigned char *nbuf = Yap_readText(inp + i PASS_REGS); if (!nbuf) { + // pop_text_stack(lvl); return NULL; } - bufv[i] = nbuf; + // if (!nbuf[0]) + // continue; + bufv[j++] = nbuf; } - buf = concat(tot, bufv PASS_REGS); - bool rc = write_Text(buf, out, strlen_utf8(buf) PASS_REGS); + if (j == 0) { + buf = Malloc(8); + memset(buf, 0, 4); + } else if (j == 1) { + buf = bufv[0]; + } else { + buf = concat(tot, bufv PASS_REGS); + } + bool rc = write_Text(buf, out PASS_REGS); + // pop_text_stack( lvl ); return rc; } // bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, - seq_tv_t outv[] USES_REGS) { - unsigned char *buf; - size_t l; + seq_tv_t outv[] USES_REGS) { + int lvl = push_text_stack(); + const unsigned char *buf; + size_t b_l, u_l; inp->type |= YAP_STRING_IN_TMP; - buf = Yap_readText(inp, &l PASS_REGS); + buf = Yap_readText(inp PASS_REGS); if (!buf) { + pop_text_stack(lvl); return false; } + b_l = strlen((char *)buf); + if (b_l == 0) { + pop_text_stack(lvl); + return false; + } + u_l = strlen_utf8(buf); if (!cuts) { if (n == 2) { - size_t l0, l1; + size_t b_l0, b_l1, u_l0, u_l1; unsigned char *buf0, *buf1; if (outv[0].val.t) { - buf0 = Yap_readText(outv, &l0 PASS_REGS); - if (!buf0) { - return false; - } - if (cmp_Text(buf, buf0, l0) != 0) { - return false; - } - l1 = l - l0; + buf0 = Yap_readText(outv PASS_REGS); + if (!buf0) { + return false; + } + b_l0 = strlen((const char *)buf0); + if (memcmp(buf, buf0, b_l0) != 0) { + pop_text_stack(lvl); + return false; + } + u_l0 = strlen_utf8(buf0); + u_l1 = u_l - u_l0; - buf1 = slice(l0, l, buf PASS_REGS); - bool rc = write_Text(buf1, outv + 1, l1 PASS_REGS); - if (!rc) { - return false; - } - return rc; + b_l1 = b_l - b_l0; + buf1 = slice(u_l0, u_l, buf PASS_REGS); + b_l1 = strlen((const char *)buf1); + bool rc = write_Text(buf1, outv + 1 PASS_REGS); + pop_text_stack(lvl); + if (!rc) { + return false; + } + return rc; } else /* if (outv[1].val.t) */ { - buf1 = Yap_readText(outv + 1, &l1 PASS_REGS); - if (!buf1) { - return false; - } - l0 = l - l1; - if (cmp_Text(skip_utf8((const unsigned char *)buf, l0), buf1, l1) != - 0) { - return false; - } - buf0 = slice(0, l0, buf PASS_REGS); - bool rc = write_Text(buf0, outv, l0 PASS_REGS); - return rc; + buf1 = Yap_readText(outv + 1 PASS_REGS); + if (!buf1) { + pop_text_stack(lvl); + return false; + } + b_l1 = strlen((char *)buf1); + u_l1 = strlen_utf8(buf1); + b_l0 = b_l - b_l1; + u_l0 = u_l - u_l1; + if (memcmp(skip_utf8((const unsigned char *)buf, b_l0), buf1, b_l1) != + 0) { + pop_text_stack(lvl); + return false; + } + buf0 = slice(0, u_l0, buf PASS_REGS); + buf0 = pop_output_text_stack(lvl, buf0); + bool rc = write_Text(buf0, outv PASS_REGS); + return rc; } } } @@ -1047,53 +1158,16 @@ bool Yap_Splice_Text(int n, size_t cuts[], seq_tv_t *inp, if (i > 0 && cuts[i] == 0) break; void *bufi = slice(next, cuts[i], buf PASS_REGS); - if (!write_Text(bufi, outv + i, cuts[i] - next PASS_REGS)) { + bufi = pop_output_text_stack(lvl, bufi); + if (!write_Text(bufi, outv + i PASS_REGS)) { return false; } } + pop_text_stack(lvl); return true; } -/** - * Function to convert a generic text term (string, atom, list of codes, list -of< -atoms) into a buff -er. - * - * @param t the term - * @param buf the buffer, if NULL a buffer is malloced, and the user should -reclai it - * @param len buffer size - * @param enc encoding (UTF-8 is strongly recommended) - * - * @return the buffer, or NULL in case of failure. If so, Yap_Error may be -called. - */ -const char *Yap_TextTermToText(Term t, char *buf, size_t len, encoding_t enc) { - CACHE_REGS - seq_tv_t inp, out; - inp.val.t = t; - if (IsAtomTerm(t) && t != TermNil) { - inp.type = YAP_STRING_ATOM; - inp.enc = ENC_ISO_UTF8; - } else if (IsStringTerm(t)) { - inp.type = YAP_STRING_STRING; - inp.enc = ENC_ISO_UTF8; - } else if (IsPairOrNilTerm(t)) { - inp.type = (YAP_STRING_CODES | YAP_STRING_ATOMS); - } else { - Yap_Error(TYPE_ERROR_TEXT, t, NULL); - return false; - } - out.enc = enc; - out.type = YAP_STRING_CHARS; - out.val.c = buf; - if (!Yap_CVT_Text(&inp, &out PASS_REGS)) - return NULL; - return out.val.c; -} - /** * Convert from a predicate structure to an UTF-8 string of the form * @@ -1107,7 +1181,7 @@ const char *Yap_TextTermToText(Term t, char *buf, size_t len, encoding_t enc) { */ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { CACHE_REGS - Atom at; + Atom at; arity_t arity = 0; Functor f; char *s, *smax, *s0; @@ -1115,8 +1189,8 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { smax = s + 1024; Term tmod = ap->ModuleOfPred; if (tmod) { - Yap_AtomToUTF8Text(AtomOfTerm(tmod), s); - s += strlen(s); + char *sn = Yap_AtomToUTF8Text(AtomOfTerm(tmod)); + stpcpy(s, sn); if (smax - s > 1) { strcat(s, ":"); } else { @@ -1138,8 +1212,8 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { return LOCAL_FileNameBuf; } else if (ap->PredFlags & AtomDBPredFlag) { at = (Atom)(ap->FunctorOfPred); - if (!Yap_AtomToUTF8Text(at, s)) - return NULL; + if (!stpcpy(s, Yap_AtomToUTF8Text(at))) + return NULL; } else { f = ap->FunctorOfPred; at = NameOfFunctor(f); @@ -1153,7 +1227,7 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { at = (Atom)(ap->FunctorOfPred); } } - if (!Yap_AtomToUTF8Text(at, s)) { + if (!stpcpy(s, Yap_AtomToUTF8Text(at))) { return NULL; } s += strlen(s); @@ -1166,18 +1240,18 @@ const char *Yap_PredIndicatorToUTF8String(PredEntry *ap) { * _Tguide_ * ≈* @param s the buffer -≈ * @param tguide the guide + ≈ * @param tguide the guide * -≈ * @return the term - */ -Term Yap_MkTextTerm(const char *s, encoding_t enc, Term tguide) { - CACHE_REGS - if (IsAtomTerm(tguide)) + ≈ * @return the term +*/ +Term Yap_MkTextTerm(const char *s, int guide USES_REGS) { + if (guide == YAP_STRING_ATOM) { return MkAtomTerm(Yap_LookupAtom(s)); - if (IsStringTerm(tguide)) + } else if (guide == YAP_STRING_STRING) { return MkStringTerm(s); - if (IsPairTerm(tguide) && IsAtomTerm(HeadOfTerm(tguide))) { - return Yap_CharsToListOfAtoms(s, enc PASS_REGS); + } else if (guide == YAP_STRING_ATOMS) { + return Yap_CharsToListOfAtoms(s, ENC_ISO_UTF8 PASS_REGS); + } else { + return Yap_CharsToListOfCodes(s, ENC_ISO_UTF8 PASS_REGS); } - return Yap_CharsToListOfCodes(s, enc PASS_REGS); } diff --git a/C/write.c b/C/write.c index 9abc1af3f..b7e33dcb1 100644 --- a/C/write.c +++ b/C/write.c @@ -375,7 +375,6 @@ int Yap_FormatFloat(Float f, char **s, size_t sz) { CACHE_REGS struct write_globs wglb; int sno; - char *so; sno = Yap_open_buf_write_stream(GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0); diff --git a/CXX/yapdb.hh b/CXX/yapdb.hh index e29340df7..d376c7ff8 100644 --- a/CXX/yapdb.hh +++ b/CXX/yapdb.hh @@ -53,6 +53,7 @@ public: YAPModule(YAP_Term t) : YAPAtomTerm(t){}; YAPModule() : YAPAtomTerm(curModule()){}; YAPModule(YAPAtom t) : YAPAtomTerm(t){}; + YAPModule(YAPStringTerm t) : YAPAtomTerm(t.getString()){}; Term term() { return gt(); }; }; diff --git a/CXX/yapi.cpp b/CXX/yapi.cpp index 65bbf7cf6..e8ffa6272 100644 --- a/CXX/yapi.cpp +++ b/CXX/yapi.cpp @@ -517,6 +517,7 @@ bool YAPEngine::call(YAPPredicate ap, YAPTerm ts[]) { bool YAPEngine::mgoal(Term t, Term tmod, bool release) { #if YAP_PYTHON + // std::cerr << "mgoal(in) " << YAPTerm(tmod).text() << ":" << YAPTerm(t).text() << "\n"; // PyThreadState *_save; // std::cerr << "mgoal " << YAPTerm(t).text() << "\n"; @@ -529,8 +530,6 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) { q.p = P; q.cp = CP; PredEntry *ap = nullptr; - std::cerr << "mgoal " << YAPTerm(t).text() << "\n"; - std::cerr << "mgoal " << YAPTerm(tmod).text() << "\n"; if (IsStringTerm(tmod)) tmod = MkAtomTerm(Yap_LookupAtom(StringOfTerm(tmod))); YAPPredicate *p = new YAPPredicate(t, tmod, ts, "C++"); @@ -554,9 +553,8 @@ bool YAPEngine::mgoal(Term t, Term tmod, bool release) { // don't forget, on success these guys may create slots //__android_log_print(ANDROID_LOG_INFO, "YAPDroid", "exec "); - result = (bool)YAP_EnterGoal(ap, nullptr, &q); - std::cerr << "mgoal " << YAPTerm(t).text() << "\n"; - std::cerr << "mgoal " << YAPTerm(tmod).text() << "\n"; + result = (bool)YAP_EnterGoal(ap, nullptr, &q); + // std::cerr << "mgoal " << YAPTerm(tmod).text() << ":" << YAPTerm(t).text() << "\n"; YAP_LeaveGoal(result && !release, &q); // PyEval_RestoreThread(_save); diff --git a/H/ATOMS b/H/ATOMS index 9c5c63b02..b22adcf6e 100644 --- a/H/ATOMS +++ b/H/ATOMS @@ -269,7 +269,7 @@ A NotLessThanZero N "not_less_than_zero" A NotNewline N "not_newline" A NotZero N "not_zero" A Number N "number" -A Obj N "o__bj__" +A Obj N "__obj__" A Off N "off" A Offline N "offline" A On N "on" diff --git a/H/YapFlags.h b/H/YapFlags.h index ffadb6d5b..d6239561a 100644 --- a/H/YapFlags.h +++ b/H/YapFlags.h @@ -119,6 +119,9 @@ INLINE_ONLY Term aro(Term inp) { // INLINE_ONLY Term booleanFlag( Term inp ); static inline Term booleanFlag(Term inp) { + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (inp == TermTrue || inp == TermOn) return TermTrue; if (inp == TermFalse || inp == TermOff) @@ -139,6 +142,9 @@ static inline Term booleanFlag(Term inp) { } static Term synerr(Term inp) { + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (inp == TermDec10 || inp == TermFail || inp == TermError || inp == TermQuiet) return inp; @@ -172,6 +178,9 @@ static inline Term isatom(Term inp) { "value must be bound"); return TermZERO; } + if (IsStringTerm(inp)) { + inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE); + } if (IsAtomTerm(inp)) return inp; Yap_Error(TYPE_ERROR_ATOM, inp, "set_prolog_flag"); diff --git a/H/YapHeap.h b/H/YapHeap.h index 4ab90268c..5e8551775 100755 --- a/H/YapHeap.h +++ b/H/YapHeap.h @@ -156,10 +156,10 @@ typedef struct various_codes { } all_heap_codes; -#include "hglobals.h" +#include "generated/hglobals.h" -#include "dhstruct.h" -#include "dglobals.h" +#include "generated/dhstruct.h" +#include "generated/dglobals.h" #else typedef struct various_codes { /* memory allocation and management */ @@ -169,15 +169,15 @@ typedef struct various_codes { } all_heap_codes; -#include "tatoms.h" +#include "generated/tatoms.h" -#include "h0struct.h" +#include "generated/h0struct.h" -#include "h0globals.h" +#include "generated/h0globals.h" #endif -#include "hlocals.h" +#include "generated/hlocals.h" #include "dlocals.h" diff --git a/H/generated/iatoms.h b/H/generated/iatoms.h index 976b58afe..0a9574170 100644 --- a/H/generated/iatoms.h +++ b/H/generated/iatoms.h @@ -264,7 +264,7 @@ AtomNotNewline = Yap_LookupAtom("not_newline"); TermNotNewline = MkAtomTerm(AtomNotNewline); AtomNotZero = Yap_LookupAtom("not_zero"); TermNotZero = MkAtomTerm(AtomNotZero); AtomNumber = Yap_LookupAtom("number"); TermNumber = MkAtomTerm(AtomNumber); - AtomObj = Yap_LookupAtom("o__bj__"); TermObj = MkAtomTerm(AtomObj); + AtomObj = Yap_LookupAtom("__obj__"); TermObj = MkAtomTerm(AtomObj); AtomOff = Yap_LookupAtom("off"); TermOff = MkAtomTerm(AtomOff); AtomOffline = Yap_LookupAtom("offline"); TermOffline = MkAtomTerm(AtomOffline); AtomOn = Yap_LookupAtom("on"); TermOn = MkAtomTerm(AtomOn); diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index 568ecf6a2..1cdfef195 100755 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -1326,7 +1326,7 @@ YAP long int unify(YAP_Term* a, Term* b) */ X_API int PL_unify_atom_chars(term_t t, const char *s) { CACHE_REGS Atom at; - while ((at = Yap_CharsToAtom(s, ENC_ISO_LATIN1 PASS_REGS)) == 0L) { + while ((at = Yap_LookupAtom(s)) == 0L) { if (LOCAL_Error_TYPE && !Yap_SWIHandleError("PL_unify_atom_nchars")) return true; } @@ -1451,16 +1451,28 @@ X_API int PL_unify_list(term_t tt, term_t h, term_t tail) { } t = Deref(Yap_GetFromSlot(tt)); if (IsVarTerm(t)) { - Term pairterm = Yap_MkNewPairTerm(); - Yap_unify(t, pairterm); - /* avoid calling deref */ - t = pairterm; + Term ttail =Yap_GetFromSlot(tail), + pairterm = MkPairTerm(Yap_GetFromSlot(h) + , ttail); + if (tt == tail) { + Yap_PutInSlot(tt, pairterm); + return true; + } else { + return Yap_unify(t, pairterm); + } } else if (!IsPairTerm(t)) { return FALSE; } - Yap_PutInSlot(h, HeadOfTerm(t)); - Yap_PutInSlot(tail, TailOfTerm(t)); - return TRUE; + bool rc = Yap_unify(h, HeadOfTerm(t)); + if (rc) { + if (tt == tail) { + Yap_PutInSlot(tail, TailOfTerm(t)); + return true; + } else { + return Yap_unify(Yap_GetFromSlot(tail), TailOfTerm(t)); + } + } + return false; } /* int PL_unify_list(term_t ?t, term_t +h, term_t -t) @@ -1548,7 +1560,7 @@ YAP long int unify(YAP_Term* a, Term* b) */ X_API int PL_unify_string_chars(term_t t, const char *chars) { CACHE_REGS Term chterm; - while ((chterm = Yap_CharsToString(chars, ENC_ISO_LATIN1 PASS_REGS)) == 0L) { + while ((chterm = MkStringTerm(chars)) == 0L) { if (LOCAL_Error_TYPE && !Yap_SWIHandleError("PL_unify_list_ncodes")) return FALSE; } diff --git a/library/expand_macros.yap b/library/expand_macros.yap index e41137724..d1c927e78 100644 --- a/library/expand_macros.yap +++ b/library/expand_macros.yap @@ -86,6 +86,7 @@ aux_args([Arg|Args], [Arg|MVars], [PVar|PArgs], [PVar|PVars], ['_'|ProtoArgs]) : pred_name(Macro, Arity, _ , Name) :- transformation_id(Id), + atomic_concat(['$$$__Auxiliary_predicate__ for',Macro,'/',Arity,' ',Id], Name). transformation_id(Id) :- diff --git a/library/maputils.yap b/library/maputils.yap index ba5cb6bc4..a0106808f 100644 --- a/library/maputils.yap +++ b/library/maputils.yap @@ -85,13 +85,16 @@ pred_name(Macro, Arity, _ , Name) :- transformation_id(Id), atomic_concat(['$$$ for ',Macro,'/',Arity,', line ',Line,' in ',File,' ',Id], Name). pred_name(Macro, Arity, _ , Name) :- - transformation_id(Id), + transformation_id(Id), + stop_low_level_trace, atomic_concat(['$$$__expansion__ for ',Macro,'/',Arity,' ',Id], Name). transformation_id(Id) :- - retract(number_of_expansions(Id)), - Id1 is Id+1, - assert(number_of_expansions(Id1)). + retract(number_of_expansions(Id)), + !, + Id1 is Id+1, + assert(number_of_expansions(Id1)). +transformation_id(0). %% goal_expansion_allowed is semidet. % diff --git a/os/fmem.c b/os/fmem.c index b36970851..e2e586f67 100644 --- a/os/fmem.c +++ b/os/fmem.c @@ -213,18 +213,13 @@ int Yap_open_buf_write_stream(encoding_t enc, memBufSource src) { st->vfs = NULL; st->buf.on = true; st->nbuf = NULL; - st->nsize = 0; st->status |= Seekable_Stream_f; #if HAVE_OPEN_MEMSTREAM st->file = open_memstream(&st->nbuf, &st->nsize); // setbuf(st->file, NULL); - if (!st->nbuf) { - return -1; - } #else st->file = fmemopen((void *)st->nbuf, st->nsize, "w+"); #endif - st->vfs = NULL; Yap_DefaultStreamOps(st); UNLOCK(st->streamlock); return sno; diff --git a/packages/python/CMakeLists.txt b/packages/python/CMakeLists.txt index 1314dca1e..550dc5e78 100644 --- a/packages/python/CMakeLists.txt +++ b/packages/python/CMakeLists.txt @@ -6,7 +6,7 @@ set (PYTHON_HEADERS py4yap.h) set (CMAKE_POSITION_INDEPENDENT_CODE TRUE) include_directories( BEFORE ${PYTHON_INCLUDE_DIRS} ${CMAKE_BINARY_DIR} -${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/os ) +${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/os ${CMAKE_SOURCE_DIR}/H ${CMAKE_SOURCE_DIR}/OPTYap ) #talk to python.pl add_lib(YAPPython pyload.c ${PYTHON_HEADERS} ) diff --git a/packages/python/pl2py.c b/packages/python/pl2py.c index 167df5679..a7a331375 100644 --- a/packages/python/pl2py.c +++ b/packages/python/pl2py.c @@ -1,4 +1,5 @@ +#include "Yap.h" #include "py4yap.h" @@ -109,7 +110,7 @@ static bool copy_to_dictionary(PyObject *dict, term_t targ, term_t taux, PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { // o≈ YAP_Term yt = YAP_GetFromSlot(t); - // Yap_DebugPlWriteln(yt); + Yap_DebugPlWriteln(yt); switch (PL_term_type(t)) { case PL_VARIABLE: { if (yt == 0) { @@ -186,31 +187,24 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { } default: if (PL_is_pair(t)) { - term_t tail = PL_new_term_ref(); - term_t arg = PL_new_term_ref(); - size_t len, i; - if (PL_skip_list(t, tail, &len) && PL_get_nil(tail)) { + Term t0 = Yap_GetFromHandle(t); + Term *tail; + size_t len,i; + if ((len = Yap_SkipList(&t0, &tail))>=0 && *tail == TermNil) { PyObject *out, *a; out = PyList_New(len); - if (!out) { - PL_reset_term_refs(tail); - YAPPy_ThrowError(SYSTEM_ERROR_INTERNAL, t, "list->python"); - } for (i = 0; i < len; i++) { - if (!PL_get_list(t, arg, t)) { - PL_reset_term_refs(tail); - YAPPy_ThrowError(SYSTEM_ERROR_INTERNAL, t, "list->python"); - } - a = term_to_python(arg, eval, o, cvt); + Term ai = HeadOfTerm(t0); + a = term_to_python(Yap_InitHandle(ai), eval, o, cvt); if (a) { if (PyList_SetItem(out, i, a) < 0) { YAPPy_ThrowError(SYSTEM_ERROR_INTERNAL, t, "list->python"); } } + t0 = TailOfTerm(t0); } - PL_reset_term_refs(tail); return out; } else { PyObject *no = find_obj(o, t, false); @@ -343,7 +337,7 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { AOK(PL_get_arg(1, t, t), NULL); if (!(dict = PyDict_New())) return NULL; - Py_INCREF(dict); + Py_INCREF(dict); DebugPrintf("Dict %p\n", dict); while (PL_is_functor(t, FUNCTOR_comma2)) { @@ -360,6 +354,7 @@ PyObject *term_to_python(term_t t, bool eval, PyObject *o, bool cvt) { return dict; } AOK(PL_get_name_arity(t, &name, &arity), NULL); + if (name == ATOM_t) { int i; rc = PyTuple_New(arity); diff --git a/packages/python/py2pl.c b/packages/python/py2pl.c index d6606001f..919a5f35a 100644 --- a/packages/python/py2pl.c +++ b/packages/python/py2pl.c @@ -1,5 +1,9 @@ + +#include "Yap.h" + #include "py4yap.h" + #include void YAPPy_ThrowError__(const char *file, const char *function, int lineno, @@ -28,12 +32,9 @@ void YAPPy_ThrowError__(const char *file, const char *function, int lineno, } } -static foreign_t repr_term(PyObject *pVal, term_t t) { - term_t to = PL_new_term_ref(), t1 = PL_new_term_ref(); - PL_put_pointer(t1, pVal); - PL_cons_functor(to, FUNCTOR_pointer1, t1); - Py_INCREF(pVal); - return PL_unify(t, to); +static Term repr_term(PyObject *pVal) { + Term t = MkAddressTerm(pVal); + return Yap_MkApplTerm(FunctorObj, 1, &t); } foreign_t assign_to_symbol(term_t t, PyObject *e); @@ -50,185 +51,157 @@ foreign_t assign_to_symbol(term_t t, PyObject *e) { return PyObject_SetAttrString(dic, s, e) == 0; } -foreign_t python_to_term(PyObject *pVal, term_t t) -{ - bool rc = true; - term_t to = PL_new_term_ref(); - // fputs(" <<*** ",stderr); PyObject_Print(pVal,stderr,0); - // fputs("<<***\n",stderr); +static Term python_to_term__(PyObject *pVal) { if (pVal == Py_None) { // fputs("<<*** ",stderr);Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" // >>***\n",stderr); - rc = true; + return YAP_MkVarTerm(); // fputs("<<*** ",stderr);Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" // >>***\n",stderr); } else if (PyBool_Check(pVal)) { - rc = rc && PL_unify_bool(t, PyObject_IsTrue(pVal)); + if(PyObject_IsTrue(pVal)) return TermTrue; + return TermFalse; } else if (PyLong_Check(pVal)) { - rc = rc && PL_unify_int64(t, PyLong_AsLong(pVal)); + return MkIntegerTerm(PyLong_AsLong(pVal)); #if PY_MAJOR_VERSION < 3 } else if (PyInt_Check(pVal)) { - rc = rc && PL_unify_int64(t, PyInt_AsLong(pVal)); + return MkIntegerTerm(PyInt_AsLong(pVal)); #endif } else if (PyFloat_Check(pVal)) { - rc = rc && PL_unify_float(t, PyFloat_AsDouble(pVal)); + return MkFloatTerm(PyFloat_AsDouble(pVal)); } else if (PyComplex_Check(pVal)) { - term_t t1 = PL_new_term_ref(), t2 = PL_new_term_ref(); - if (!PL_put_float(t1, PyComplex_RealAsDouble(pVal)) || - !PL_put_float(t2, PyComplex_ImagAsDouble(pVal)) || - !PL_cons_functor(to, FUNCTOR_complex2, t1, t2)) { - rc = false; - } else { - rc = rc && PL_unify(t, to); - } - } else if (PyUnicode_Check(pVal)) { + Term t[2]; + t[0] = MkFloatTerm(PyComplex_RealAsDouble(pVal)); + t[1] = MkFloatTerm(PyComplex_ImagAsDouble(pVal)); + return Yap_MkApplTerm(FunctorI, 2, t); + +} +else if (PyUnicode_Check(pVal)) { #if PY_MAJOR_VERSION < 3 - size_t sz = PyUnicode_GetSize(pVal) + 1; - wchar_t *s = malloc(sizeof(wchar_t) * sz); - sz = PyUnicode_AsWideChar((PyUnicodeObject *)pVal, a, sz - 1); - free(ptr); + size_t sz = PyUnicode_GetSize(pVal) + 1; + wchar_t *s = malloc(sizeof(wchar_t) * sz); + sz = PyUnicode_AsWideChar((PyUnicodeObject *)pVal, a, sz - 1); + free(ptr); #else - const char *s = PyUnicode_AsUTF8(pVal); + const char *s = PyUnicode_AsUTF8(pVal); #endif - if (Yap_AtomInUse(s)) +#if 0 + if (false && Yap_AtomInUse(s)) rc = rc && PL_unify_atom_chars(t, s); else - rc = rc && PL_unify_string_chars(t, s); - } else if (PyByteArray_Check(pVal)) { - rc = rc && PL_unify_string_chars(t, PyByteArray_AsString(pVal)); -#if PY_MAJOR_VERSION < 3 - } else if (PyString_Check(pVal)) { - rc = rc && PL_unify_string_chars(t, PyString_AsString(pVal)); #endif - } else if (PyTuple_Check(pVal)) { - Py_ssize_t i, sz = PyTuple_Size(pVal); - functor_t f; - const char *s; - if (sz == 0) { - rc = rc && PL_unify_atom(t, ATOM_brackets); - } else { - if ((s = (Py_TYPE(pVal)->tp_name))) { - if (!strcmp(s, "v")) { - pVal = PyTuple_GetItem(pVal, 0); - if (pVal == NULL) { - pVal = Py_None; - PyErr_Clear(); - } - term_t v = YAP_InitSlot(PyLong_AsLong(pVal)); - return PL_unify(v, t); - } - if (s[0] == '$') { - char *ns = malloc(strlen(s) + 5); - strcpy(ns, "__"); - strcat(ns, s + 1); - strcat(ns, "__"); - f = PL_new_functor(PL_new_atom(ns), sz); - } else { - f = PL_new_functor(PL_new_atom(s), sz); - } - } else { - f = PL_new_functor(ATOM_t, sz); - } - if (PL_unify_functor(t, f)) { - for (i = 0; i < sz; i++) { - term_t to = PL_new_term_ref(); - if (!PL_get_arg(i + 1, t, to)) - rc = false; - PyObject *p = PyTuple_GetItem(pVal, i); - if (p == NULL) { - PyErr_Clear(); - p = Py_None; - } else { - rc = rc && python_to_term(p, to); - } - PL_reset_term_refs(to); - } - } else { - rc = false; - } - // fputs(" ||*** ",stderr); Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" - // ||***\n",stderr); + return MkStringTerm(s); +} +else if (PyByteArray_Check(pVal)) { + return MkStringTerm(PyByteArray_AsString(pVal)); +#if PY_MAJOR_VERSION < 3 +} +else if (PyString_Check(pVal)) { + return MkStringTerm(PyString_AsString(pVal)); +#endif +} +else if (PyTuple_Check(pVal)) { + Py_ssize_t sz = PyTuple_Size(pVal); + const char *s; + s = Py_TYPE(pVal)->tp_name; + if (s == NULL) + s = "t"; + if (sz == 0) { + return MkAtomTerm(YAP_LookupAtom(Py_TYPE(pVal)->tp_name)); +} +else { + Functor f = Yap_MkFunctor(Yap_LookupAtom(s), sz); + Term t = Yap_MkNewApplTerm(f, sz); + long i; + CELL *ptr = RepAppl(t) + 1; + for (i = 0; i < sz; i++) { + PyObject *p = PyTuple_GetItem(pVal, i); + if (p == NULL) { + PyErr_Clear(); + return false; } - } else if (PyList_Check(pVal)) { - Py_ssize_t i, sz = PyList_GET_SIZE(pVal); - - for (i = 0; i < sz; i++) { - PyObject *obj; - term_t to = PL_new_term_ref(); - rc = rc && PL_unify_list(t, to, t); - if ((obj = PyList_GetItem(pVal, i)) == NULL) { - obj = Py_None; - } - rc = rc && python_to_term(obj, to); - PL_reset_term_refs(to); - if (!rc) - return false; - } - return rc && PL_unify_nil(t); - // fputs("[***] ", stderr); - // Yap_DebugPlWrite(yt); fputs("[***]\n", stderr); - } else if (PyDict_Check(pVal)) { - Py_ssize_t pos = 0; - int left = PyDict_Size(pVal); - PyObject *key, *value; - - if (left == 0) { - rc = rc && PL_unify_atom(t, ATOM_curly_brackets); - } else { - while (PyDict_Next(pVal, &pos, &key, &value)) { - term_t tkey = PL_new_term_ref(), tval = PL_new_term_ref(), tint, - tnew = PL_new_term_ref(); - term_t to = PL_new_term_ref(); - /* do something interesting with the values... */ - if (!python_to_term(key, tkey)) { - continue; - } - if (!python_to_term(value, tval)) { - continue; - } - /* reuse */ - tint = tkey; - if (!PL_cons_functor(tint, FUNCTOR_colon2, tkey, tval)) { - rc = false; - continue; - } - if (--left) { - if (!PL_cons_functor(tint, FUNCTOR_comma2, tint, tnew)) - PL_reset_term_refs(tkey); - rc = false; - } - if (!PL_unify(to, tint)) { - rc = false; - } - } - rc = rc && PL_unify(t, to); - } - } else { - rc = rc && repr_term(pVal, t); + *ptr++ = python_to_term__(p); } + return t; +} +// PL_reset_term_refs(to); +// fputs(" ||*** ",stderr); Yap_DebugPlWrite(YAP_GetFromSlot(t)); fputs(" +// ||***\n",stderr); +} +else if (PyList_Check(pVal)) { + Py_ssize_t i, sz = PyList_GET_SIZE(pVal); + if (sz == 0) + return TermNil; + Term t = TermNil; + for (i = sz; i > 0; --i) { + PyObject *p = PyTuple_GetItem(pVal, i); + if (p == NULL) { + PyErr_Clear(); + return false; + } + if (!python_to_term__(p)) + return false; + t = MkPairTerm(python_to_term__(p), t); + } + return t; +} +else if (PyDict_Check(pVal)) { + Py_ssize_t pos = 0; + int left = PyDict_Size(pVal); + PyObject *key, *value; + Term f, *opt = &f, t; + if (left == 0) { + return ATOM_curly_brackets; + } else { + while (PyDict_Next(pVal, &pos, &key, &value)) { + Term t0[2], to; + t0[0] = python_to_term__(key); + t0[1] = python_to_term__(value); + to = Yap_MkApplTerm(FunctorEq, 2, t0); + if (left--) { + t = Yap_MkNewApplTerm(FunctorOr, 2); + *opt = t; + CELL *pt = RepAppl(t) + 1; + pt[0] = to; + opt = pt + 1; + } else { + *opt = t = to; + } + } + return Yap_MkApplTerm(FunctorBraces, 1, &t); + } + }else { + return repr_term(pVal); + } +} + +foreign_t python_to_term(PyObject *pVal, term_t t) { + term_t t0 = PL_new_term_ref(); + bool rc = python_to_term__(pVal); + PL_reset_term_refs(t0); return rc; } - - +// extern bool Yap_do_low_level_trace; X_API YAP_Term pythonToYAP(PyObject *pVal) { - - term_t t = PL_new_term_ref(); - if (pVal == NULL || !python_to_term(pVal, t)) { - PL_reset_term_refs(t); - return 0; - } - YAP_Term tt = YAP_GetFromSlot(t); - PL_reset_term_refs(t); + // Yap_do_low_level_trace=1; + /* fputs(" *** ", stderr); */ + /* PyObject_Print(pVal, stderr, 0); */ + /* fputs("***>>\n", stderr); */ + if (pVal == NULL) + Yap_ThrowError(SYSTEM_ERROR_INTERNAL, 0, NULL); + Term t = python_to_term__(pVal); + /* fputs("<< *** ", stderr); */ + /* Yap_DebugPlWrite(t); */ + /* fputs(" ***\n", stderr); */ // Py_DECREF(pVal); - return tt; + return t; } PyObject *py_Local, *py_Global; - /** * assigns the Python RHS to a Prolog term LHS, ie LHS = RHS * diff --git a/packages/python/pypreds.c b/packages/python/pypreds.c index 835835f64..758458796 100644 --- a/packages/python/pypreds.c +++ b/packages/python/pypreds.c @@ -23,6 +23,11 @@ static foreign_t python_len(term_t tobj, term_t tf) { len = PyObject_Length(o); pyErrorAndReturn(PL_unify_int64(tf, len)); } +static foreign_t python_clear_errors(void) { + PyErr_Clear(); + return true; +} + static foreign_t python_dir(term_t tobj, term_t tf) { PyObject *dir; @@ -701,6 +706,7 @@ install_t install_pypreds(void) { PL_register_foreign("python_import", 2, python_import, 0); PL_register_foreign("python_access", 3, python_access, 0); PL_register_foreign("python_threaded", 0, p_python_threaded, 0); + PL_register_foreign("python_clear_errors", 0, python_clear_errors, 0); init_python_vfs(); } diff --git a/packages/python/python.pl b/packages/python/python.pl index 7b7107369..79663a7c6 100644 --- a/packages/python/python.pl +++ b/packages/python/python.pl @@ -32,6 +32,7 @@ release_GIL/0, python_threaded/0, prolog_list_to_python_list/3, + python_clear_errors/0, op(100,fy,$), op(950,fy,:=), op(950,yfx,:=), diff --git a/packages/python/swig/prolog/yapi.yap b/packages/python/swig/prolog/yapi.yap index c54ddba49..e5e0322ef 100644 --- a/packages/python/swig/prolog/yapi.yap +++ b/packages/python/swig/prolog/yapi.yap @@ -3,20 +3,20 @@ %% @brief support yap shell %% %:- start_low_level_trace. - :- module(yapi, [ - python_ouput/0, - show_answer/2, - show_answer/3, - yap_query/4, - python_query/2, - python_query/3, - python_import/1, - yapi_query/2 - ]). + %% :- module(yapi, [ + %% python_ouput/0, + %% show_answer/2, + %% show_answer/3, + %% yap_query/4, + %% python_query/2, + %% python_query/3, + %% python_import/1, + %% yapi_query/2 + %% ]). :- yap_flag(verbose, silent). -:- use_module(library(python)). + :- use_module(library(python)). :- use_module( library(lists) ). :- use_module( library(maplist) ). @@ -88,3 +88,4 @@ in_dict(Dict, nonvar([V0|Vs],G)) :- !, in_dict( Dict, nonvar(Vs, G) ). in_dict(_Dict, nonvar([],_G)) :- !. in_dict(_, _) + diff --git a/packages/python/swig/yap4py/yapi.py b/packages/python/swig/yap4py/yapi.py index f10d491fc..b54db5390 100644 --- a/packages/python/swig/yap4py/yapi.py +++ b/packages/python/swig/yap4py/yapi.py @@ -6,16 +6,17 @@ import sys yap_lib_path = dirname(__file__) -compile = namedtuple('compile', 'file') bindvars = namedtuple('bindvars', 'list') -library = namedtuple('library', 'list') +compile = namedtuple('compile', 'file') +jupyter_query = namedtuple('jupyter_query', 'vars dict') +library = namedtuple('library', 'listfiles') +prolog_library = namedtuple('prolog_library', 'listfiles') +python_query = namedtuple('python_query', 'vars dict') +set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') +show_answer = namedtuple('show_answer', 'vars dict') v0 = namedtuple('v', 'slot') yap_query = namedtuple('yap_query', 'query owner') -jupyter_query = namedtuple('jupyter_query', 'vars dict') -python_query = namedtuple('python_query', 'vars dict') yapi_query = namedtuple('yapi_query', 'vars dict') -show_answer = namedtuple('show_answer', 'vars dict') -set_prolog_flag = namedtuple('set_prolog_flag', 'flag new_value') class Engine( YAPEngine ): @@ -30,17 +31,18 @@ class Engine( YAPEngine ): args.setYapPLDIR(yap_lib_path) args.setSavedState(join(yap_lib_path, "startup.yss")) YAPEngine.__init__(self, args) - self.goal(set_prolog_flag('verbose', 'silent'),True) - self.goal(compile(library('yapi')), True) - self.goal(set_prolog_flag('verbose', 'normal'), True) + self.run(compile(library('yapi')),m="user",release=True) def run(self, g, m=None, release=False): if m: self.mgoal(g, m, release) else: - self.goal(release) - + self.goal(g, release) + def prolog_library(self, file): + g = prolog_library(file) + self.run(g) + class JupyterEngine( Engine ): def __init__(self, args=None,self_contained=False,**kwargs): @@ -50,11 +52,9 @@ class JupyterEngine( Engine ): args.jupyter = True Engine.__init__(self, args) self.errors = None - self.goal(set_prolog_flag('verbose', 'silent'),True) - self.goal(compile(library('verify')), True) - self.goal(compile(library('complete')), True) - self.goal(compile(library('jupyter')), True) - self.goal(set_prolog_flag('verbose', 'normal'), True) + self.run(compile(library('jupyter')),"user") + self.run(compile(library('complete')),"user") + self.run(compile(library('verify')),"user") class EngineArgs( YAPEngineArgs ): """ Interface to Engine Options class""" diff --git a/packages/python/yap_kernel/yap_ipython/prolog/complete.yap b/packages/python/yap_kernel/yap_ipython/prolog/complete.yap index c17a1201e..4de1ea40c 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/complete.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/complete.yap @@ -4,12 +4,12 @@ * @brief Prolog completer. */ -:- module( completer, - [completions/2 ]). +%% %% :- module( completer, +%% %% [completions/2 ]). :- use_module(library(lists)). :- use_module(library(maplist)). -:- use_module(library(python)). + :- use_module(library(python)). %% completions( +Text, +PythonCell ) % diff --git a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap index 02e428134..4bcca17f4 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/jupyter.yap @@ -6,36 +6,38 @@ */ :- yap_flag(gc_trace,verbose). - +/* :- module( jupyter, [jupyter_query/3, - blank/1 + blank/1, + streams/1 ] ). +*/ :- use_module(library(hacks)). :- use_module(library(lists)). :- use_module(library(maplist)). -:- reexport(library(python)). -:- reexport(library(yapi)). -:- reexport(library(complete)). -:- reexport(library(verify)). +%% :- reexport(library(python)). +%% :- reexport(library(yapi)). +%% :- reexport(library(complete)). +%% :- reexport(library(verify)). + :- python_import(sys). jupyter_query(Caller, Cell, Line ) :- - jupyter_cell(Caller, Cell, Line). + jupyter_cell(Caller, Cell, Line). jupyter_cell(_Caller, Cell, _Line) :- jupyter_consult(Cell), %stack_dump, fail. -jupyter_cell( _Caller, _, '' ) :- !. +jupyter_cell( _Caller, _, `` ) :- !. jupyter_cell( _Caller, _, Line ) :- blank( Line ), !. -jupyter_cell( Caller, _, Line ) :- - Self := Caller.query, +jupyter_cell(Self, _, Line ) :- catch( python_query(Self,Line), E=error(A,B), @@ -83,7 +85,8 @@ blank(Text) :- string_codes(Text, L), maplist( code_type(space), L). -streams(false) :- + + streams(false) :- close(user_input), close(user_output), close(user_error). @@ -109,4 +112,4 @@ plot_inline :- :- endif. -%:- ( start_low_level_trace ). +%y:- ( start_low_level_trace ). diff --git a/packages/python/yap_kernel/yap_ipython/prolog/verify.yap b/packages/python/yap_kernel/yap_ipython/prolog/verify.yap index 04a9b641c..44e806174 100644 --- a/packages/python/yap_kernel/yap_ipython/prolog/verify.yap +++ b/packages/python/yap_kernel/yap_ipython/prolog/verify.yap @@ -5,19 +5,22 @@ */ - :- module( verify, - [errors/2,q - ready/2] - ). + %% :- module( verify, +%% [errors/2, +%% ready/2] +%% ). :- use_module(library(hacks)). -:- use_module(library(jupyter)). +%% :- use_module(library(jupyter)). + :- use_module(library(lists)). :- use_module(library(maplist)). -:- use_module(library(python)). -:- use_module(library(yapi)). + :- use_module(library(python)). +%% :- use_module(library(yapi)). +:- dynamic jupyter/1. +jupyter( []). ready( Engine, Query) :- errors( Engine , Cell ), @@ -27,10 +30,10 @@ ready( Engine, Query) :- errors( _Engine , Text ) :- - blank(Text). + blank(Text), !. errors( Engine , Text ) :- - jupyter..shell := Engine, +%start_low_level_trace, setup_call_cleanup( open_esh( Engine , Text, Stream, Name ), esh(Engine , Name, Stream), @@ -40,50 +43,55 @@ errors( Engine , Text ) :- errors( _Engine , _Text ). open_esh(Engine , Text, Stream, Name) :- - Engine.errors := [], + Engine.errors := [], + retractall(jupyter(_)), + assertz(jupyter(Engine)), b_setval( jupyter, Engine), Name := Engine.stream_name, open_mem_read_stream( Text, Stream ). esh(Engine , Name, Stream) :- -b_setval(code,python), repeat, catch( - ( read_clause(Stream, Cl, [ syntax_errors(fail)]), - writeln(cl:Cl), + read_clause(Stream, Cl, [ syntax_errors(dec10)]), error(C,E), - p_message(C,E) - + p3_message(C,Engine,E) + ), Cl == end_of_file, !. -user:print_message() :- p_message + +:- multifile user:portray_message/2. + +user:portray_message(S,E) :- +jupyter(En), + En \= [], + python_clear_errors, + p3_message(S,En,E). close_esh( _Engine , Stream ) :- - b_delete + retractall(jupyter(_)), + assertz(jupyter([])), close(Stream). - p_message(Severity, Error) :- - writeln((Severity->Error)), - p_message(Severity, Engine, Error). -p_message( _Severity, Engine, error(syntax_error(Cause),info(between(_,LN,_), _FileName, CharPos, Details))) :- - %% nb_getval(jupyter_cell, on), - %% assert( syntax_error(Cause,LN,CharPos,Details) ). - %% user:portray_message(_Severity, error(style_check(_),_) ) :- - %% nb_getval(jupyter_cell, on). - Engine.errors := [t(Cause,LN,CharPos,Details)] + Engine.errors, - !. - p_message(error, Engine, E) :- - writeln(E), - !. - p_message(warning, Engine, E) :- +p3_message( _Severity, Engine, error(syntax_error(Cause),info(between(_,LN,_), _FileName, CharPos, Details))) :- + python_clear_errors, + !, writeln(E), + NE := [t(Cause,LN,CharPos,Details)]+Engine.errors, + writeln(E), + writeln(NE), + Engine.errors := NE. +p3_message(error, Engine, E) :- + python_clear_errors, + !. + p3_message(warning, Engine, E) :- !. - p_message(error, Engine, E) :- + p3_message(error, Engine, E) :- Engine.errors := [E] + Engine.errors. - p_message(warning, Engine, E) :- + p3_message(warning, Engine, E) :- Engine.errors := [E] + Engine.errors. %% ready(_Self, Line ) :- %% blank( Line ), @@ -173,3 +181,4 @@ p_message( _Severity, Engine, error(syntax_error(Cause),info(between(_,LN,_), _ %% Self.errors := [t(C,L,N,A)] + Self.errors, %% fail. %% close_events( _ ). + diff --git a/packages/python/yap_kernel/yap_ipython/yapi.py b/packages/python/yap_kernel/yap_ipython/yapi.py index 64db56aa5..562f2bd34 100644 --- a/packages/python/yap_kernel/yap_ipython/yapi.py +++ b/packages/python/yap_kernel/yap_ipython/yapi.py @@ -113,424 +113,9 @@ class YAPInputSplitter(InputSplitter): return True if not line: line = text.rstrip() - engine.errors = [] - engine.goal(errors(engine, text),True) - print(engine.errors) - return engine.errors != [] - - - def reset(self): - """Reset the input buffer and associated state.""" - #super(YAPInputSplitter, self).reset() - self._buffer_raw[:] = [] - self.source_raw = '' - self.transformer_accumulating = False - - for t in self.transforms: - try: - t.reset() - except SyntaxError: - # Nothing that calls reset() expects to handle transformer - # errors - pass - - def flush_transformers(self): - def _flush(transform, outs): - """yield transformed lines - - always strings, never None - - transform: the current transform - outs: an iterable of previously transformed inputs. - Each may be multiline, which will be passed - one line at a time to transform. - """ - for out in outs: - for line in out.splitlines(): - # push one line at a time - tmp = transform.push(line) - if tmp is not None: - yield tmp - - # reset the transform - tmp = transform.reset() - if tmp is not None: - yield tmp - - out = [] - - for t in self.transforms: - out = _flush(t, out) - - out = list(out) - if out: - self._store('\n'.join(out)) - - def raw_reset(self): - """Return raw input only and perform a full reset. - """ - out = self.source_raw - self.reset() - return out - - def source_reset(self): - try: - self.flush_transformers() - return self.source - finally: - self.reset() - - def push_accepts_more(self): - if self.transformer_accumulating: - return True - else: - return self.validQuery(self.source, engine, self.shell) - - def transform_cell(self, cell): - """Process and translate a cell of input. - """ - self.reset() - try: - self.push(cell) - self.flush_transformers() - return self.source - finally: - self.reset() - - def push(self, lines): - """Push one or more lines of yap_ipython input. - - This stores the given lines and returns a status code indicating - whether the code forms a complete Python block or not, after processing - all input lines for special yap_ipython syntax. - - Any exceptions generated in compilation are swallowed, but if an - exception was produced, the method returns True. - - Parameters - ---------- - lines : string - One or more lines of Python input. - - Returns - ------- - is_complete : boolean - True if the current input source (the result of the current input - plus prior inputs) forms a complete Python execution block. Note that - this value is also stored as a private attribute (_is_complete), so it - can be queried at any time. - """ - - # We must ensure all input is pure unicode - lines = cast_unicode(lines, self.encoding) - # ''.splitlines() --> [], but we need to push the empty line to transformers - lines_list = lines.splitlines() - if not lines_list: - lines_list = [''] - - # Store raw source before applying any transformations to it. Note - # that this must be done *after* the reset() call that would otherwise - # flush the buffer. - self._store(lines, self._buffer_raw, 'source_raw') - - transformed_lines_list = [] - for line in lines_list: - transformed = self._transform_line(line) - if transformed is not None: - transformed_lines_list.append(transformed) - if transformed_lines_list: - transformed_lines = '\n'.join(transformed_lines_list) - else: - # Got nothing back from transformers - they must be waiting for - # more input. - return False - - def _transform_line(self, line): - """Push a line of input code through the various transformers. - - Returns any output from the transformers, or None if a transformer - is accumulating lines. - - Sets self.transformer_accumulating as a side effect. - """ - def _accumulating(dbg): - #print(dbg) - self.transformer_accumulating = True - return None - - for transformer in self.physical_line_transforms: - line = transformer.push(line) - if line is None: - return _accumulating(transformer) - - for transformer in self.logical_line_transforms: - line = transformer.push(line) - if line is None: - return _accumulating(transformer) - - - #print("transformers clear") #debug - self.transformer_accumulating = False - return line - - -class YAPCompleter(Completer): - - greedy = Bool(False, - help="""Activate greedy completion - PENDING DEPRECTION. this is now mostly taken care of with Jedi. - - This will enable completion on elements of lists, self.results of function calls, etc., - but can be unsafe because the code is actually evaluated on TAB. - """ - ).tag(config=True) - - debug = Bool(default_value=False, - help='Enable debug for the Completer. Mostly print extra ' - 'information for experimental jedi integration.') \ - .tag(config=True) - - backslash_combining_completions = Bool(True, - help="Enable unicode completions, e.g. \\alpha . " - "Includes completion of latex commands, unicode names, and expanding " - "unicode characters back to latex commands.").tag(config=True) - - - - def __init__(self, namespace=None, global_namespace=None, shell=None, **kwargs): - """Create a new completer for the command line. - - Completer(namespace=ns, global_namespace=ns2) -> completer instance. - - """ - - self.shell = shell - self.magic_escape = ESC_MAGIC - super(Completer, self).__init__(**kwargs) - - def complete(self, text, line=None, cursor_pos=None): - """Return the completed text and a list of completions. - - Parameters - ---------- - - text : string - A string of text to be completed on. It can be given as empty and - instead a line/position pair are given. In this case, the - completer itself will split the line like readline does. - - This is called successively with state == 0, 1, 2, ... until it - returns None. The completion should begin with 'text'. - - line : string, optional - The complete line that text is part of. - - cursor_pos : int, optional - The position of the cursor on the input line. - - Returns - ------- - text : string - The actual text that was completed. - - matches : list - A sorted list with all possible completions. - - The optional arguments allow the completion to take more context into - account, and are part of the low-level completion API. - - This is a wrapper around the completion mechanism, similar to what - readline does at the command line when the TAB key is hit. By - exposing it as a method, it can be used by other non-readline - environments (such as GUIs) for text completion. - - Simple usage example: - - In [1]: x = 'hello' - - In [2]: _ip.complete('x.l') - Out[2]: ('x.l', ['x.ljust', 'x.lower', 'x.lstrip']) - """ - if not text: - text = line[:cursor_pos] - return self.completions(text, cursor_pos) - - - def magic_matches(self, text): - """Match magics""" - # Get all shell magics now rather than statically, so magics loaded at - # runtime show up too. - lsm = self.shell.magics_manager.lsmagic() - line_magics = lsm['line'] - cell_magics = lsm['cell'] - pre = self.magic_escape - pre2 = pre+pre - - explicit_magic = text.startswith(pre) - - # Completion logic: - # - user gives %%: only do cell magics - # - user gives %: do both line and cell magics - # - no prefix: do both - # In other words, line magics are skipped if the user gives %% explicitly - # - # We also exclude magics that match any currently visible names: - # https://github.com/ipython/ipython/issues/4877, unless the user has - # typed a %: - # https://github.com/ipython/ipython/issues/10754 - bare_text = text.lstrip(pre) - global_matches = [] - if not explicit_magic: - def matches(magic): - """ - Filter magics, in particular remove magics that match - a name present in global namespace. - """ - return ( magic.startswith(bare_text) and - magic not in global_matches ) - else: - def matches(magic): - return magic.startswith(bare_text) - - comp = [ pre2+m for m in cell_magics if matches(m)] - if not text.startswith(pre2): - comp += [ pre+m for m in line_magics if matches(m)] - - return comp - - def magic_config_matches(self, text): #:str) -> List[str]: - """ Match class names and attributes for %config magic """ - texts = text.strip().split() - - if len(texts) > 0 and (texts[0] == 'config' or texts[0] == '%config'): - # get all configuration classes - classes = sorted(set([ c for c in self.shell.configurables - if c.__class__.class_traits(config=True) - ]), key=lambda x: x.__class__.__name__) - classnames = [ c.__class__.__name__ for c in classes ] - - # return all classnames if config or %config is given - if len(texts) == 1: - return classnames - - # match classname - classname_texts = texts[1].split('.') - classname = classname_texts[0] - classname_matches = [ c for c in classnames - if c.startswith(classname) ] - - # return matched classes or the matched class with attributes - if texts[1].find('.') < 0: - return classname_matches - elif len(classname_matches) == 1 and \ - classname_matches[0] == classname: - cls = classes[classnames.index(classname)].__class__ - help = cls.class_get_help() - # strip leading '--' from cl-args: - help = re.sub(re.compile(r'^--', re.MULTILINE), '', help) - return [ attr.split('=')[0] - for attr in help.strip().splitlines() - if attr.startswith(texts[1]) ] - return [] - - - def magic_color_matches(self, text): #:str) -> List[str] : - """ Match color schemes for %colors magic""" - texts = text.split() - if text.endswith(' '): - # .split() strips off the trailing whitespace. Add '' back - # so that: '%colors ' -> ['%colors', ''] - texts.append('') - - if len(texts) == 2 and (texts[0] == 'colors' or texts[0] == '%colors'): - prefix = texts[1] - return [ color for color in InspectColors.keys() - if color.startswith(prefix) ] - return [] - - - - - def completions(self, text, offset): - """ - Returns an iterator over the possible completions - - .. warning:: Unstable - - This function is unstable, API may change without warning. - It will also raise unless use in proper context manager. - - Parameters - ---------- - - text:str - Full text of the current input, multi line string. - offset:int - Integer representing the position of the cursor in ``text``. Offset - is 0-based indexed. - - Yields - ------ - :any:`Completion` object - - - The cursor on a text can either be seen as being "in between" - characters or "On" a character depending on the interface visible to - the user. For consistency the cursor being on "in between" characters X - and Y is equivalent to the cursor being "on" character Y, that is to say - the character the cursor is on is considered as being after the cursor. - - Combining characters may span more that one position in the - text. - - - .. note:: - - If ``IPCompleter.debug`` is :any:`True` will yield a ``--jedi/ipython--`` - fake Completion token to distinguish completion returned by Jedi - and usual yap_ipython completion. - - .. note:: - - Completions are not completely deduplicated yet. If identical - completions are coming from different sources this function does not - ensure that each completion object will only be present once. - """ - self.matches = [] - prolog_res = self.shell.yapeng.goal(completions(text, self),True) - if self.matches: - return text, self.matches - magic_res = self.magic_matches(text) - return text, magic_res - - - - -class YAPRun: - """An enhanced, interactive shell for YAP.""" - - def __init__(self, shell): - self.shell = shell - self.yapeng = JupyterEngine() - global engine - engine = self.yapeng - self.query = None - self.os = None - self.it = None - self.shell.yapeng = self.yapeng - self._get_exc_info = shell._get_exc_info - - def syntaxErrors(self, text): - """Return whether a legal query - """ - if not text: - return [] - if text == self.os: - return self.yapeng.errors - (text,_,_,_) = self.clean_end(text) - self.yapeng.goal(errors(self.yapeng,text),True) - print( self.yapeng.errors ) - return self.yapeng.errors != [] + self.errors = [] + engine.mgoal(errors(self, line),"user",True) + return self.errors != [] def reset(self): @@ -911,7 +496,7 @@ class YAPCompleter(Completer): ensure that each completion object will only be present once. """ self.matches = [] - prolog_res = self.shell.yapeng.goal(completions(text, self),True) + prolog_res = self.shell.yapeng.mgoal(completions(text, self), "user",True) if self.matches: return text, self.matches magic_res = self.magic_matches(text) @@ -940,11 +525,11 @@ class YAPRun: if not text: return [] if text == self.os: - return self.yapeng.errors + return self.errors + self.errors=[] (text,_,_,_) = self.clean_end(text) - self.yapeng.goal(errors(self.yapeng,text),True) - print( self.yapeng.errors ) - return self.yapeng.errors + self.yapeng.mgoal(errors(self,text),"user",True) + return self.errors def jupyter_query(self, s): # @@ -1027,6 +612,7 @@ class YAPRun: # you can print it out, the left-side is the variable name, # the right side wraps a handle to a variable #import pdb; pdb.set_trace() + # #pdb.set_trace() # atom match either symbols, or if no symbol exists, strings, In this case # variable names should match strings # ask = True @@ -1067,9 +653,7 @@ class YAPRun: # except SyntaxError: # preprocessing_exc_tuple = self.shell.syntax_error() # sys.exc_info() cell = raw_cell # cell has to exist so it can be stored/logged - self.yapeng.goal(streams(True), True) - errors = self.syntaxErrors(raw_cell) - for i in errors: + for i in self.syntaxErrors(raw_cell): try: (what,lin,_,text) = i e = SyntaxError(what, ("", lin, 1, text)) @@ -1095,7 +679,6 @@ class YAPRun: # compiler # compiler = self.shell.compile if shell_futures else CachingCompiler() cell_name = str( self.shell.execution_count) - engine.stream_name = cell_name if cell[0] == '%': if cell[1] == '%': linec = False @@ -1124,6 +707,7 @@ class YAPRun: self.shell.displayhook.exec_result = self.result has_raised = False try: + self.yapeng.mgoal(streams(True),"user", True) self.bindings = dicts = [] if cell.strip('\n \t'): #create a Trace object, telling it what to ignore, and whether to @@ -1148,9 +732,9 @@ class YAPRun: except Exception as e: has_raised = True self.result.result = False - self.yapeng.goal(streams(False), True) + self.yapeng.mgoal(streams(False),"user", True) - self.yapeng.goal(ODstreams(False), True) + self.yapeng.mgoal(streams(False),"user", True) self.shell.last_execution_succeeded = not has_raised # Reset this so later displayed values do not modify the diff --git a/pl/consult.yap b/pl/consult.yap index ce366ed89..9de156521 100644 --- a/pl/consult.yap +++ b/pl/consult.yap @@ -308,7 +308,6 @@ load_files(Files0,Opts) :- '$load_files__'(Files, M, Opts, Call) :- '$lf_option'(last_opt, LastOpt), '$show_consult_level'(LC), - writeln(user_error,innbbbbbb), ( LC > 0 -> '__NB_getval__'('$lf_status', OldTOpts, fail), @@ -1672,6 +1671,11 @@ End of conditional compilation. consult_depth(LV) :- '$show_consult_level'(LV). +prolog_library(File) :- + yap_flag(verbose,Old,silent), + ensure_loaded(library(File)), + yap_flag(verbose,_,Old). + :- '$add_multifile'(dot_qualified_goal,2,user). /**