18static char SccsId[] =
"%W% %G%";
39#define HAS_CACHE_REGS 1
48#include "tab.macros.h"
59static Int name(USES_REGS1);
60static Int atom_chars(USES_REGS1);
61static Int atom_codes(USES_REGS1);
62static Int atom_length(USES_REGS1);
63static Int string_length(USES_REGS1);
64static Int atom_split(USES_REGS1);
65static Int number_chars(USES_REGS1);
66static Int number_codes(USES_REGS1);
67static Int current_atom(USES_REGS1);
68static Int cont_current_atom(USES_REGS1);
69static int AlreadyHidden(
unsigned char *);
70static Int hide_atom(USES_REGS1);
71static Int hidden_atom(USES_REGS1);
72static Int unhide_atom(USES_REGS1);
74static Int det_atom_concat3(USES_REGS1);
76static int AlreadyHidden(
unsigned char *name) {
79 READ_LOCK(INVISIBLECHAIN.AERWLock);
80 chain = RepAtom(INVISIBLECHAIN.Entry);
81 READ_UNLOCK(INVISIBLECHAIN.AERWLock);
82 while (!EndOfPAEntr(chain) &&
83 strcmp((
char *)chain->StrOfAE, (
char *)name) != 0)
84 chain = RepAtom(chain->NextOfAE);
85 if (EndOfPAEntr(chain))
98static Int hide_atom(USES_REGS1) {
100 Term t1 = Deref(ARG1);
102 if (!Yap_IsGroundTerm(t1)) {
103 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"hide_atom/1");
106 if (!IsAtomTerm(t1)) {
107 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"hide_atom/1");
110 atomToInclude = AtomOfTerm(t1);
111 if (AlreadyHidden(RepAtom(atomToInclude)->UStrOfAE)) {
112 Yap_ThrowError(SYSTEM_ERROR_INTERNAL, t1,
113 "an atom of name %s was already hidden",
114 RepAtom(atomToInclude)->StrOfAE);
118 Prop p = ae->PropsOfAE;
120 if (IsPredProperty(p->KindOfPE) || IsDBProperty(p->KindOfPE)) {
121 RepPredProp(p)->PredFlags |= HiddenPredFlag;
123 }
else if (p->KindOfPE == FunctorProperty) {
124 Prop q = RepFunctorProp(p)->PropsOfFE;
126 if (IsPredProperty(q->KindOfPE) || IsDBProperty(q->KindOfPE)) {
127 RepPredProp(q)->PredFlags |= HiddenPredFlag;
134 Yap_ReleaseAtom(atomToInclude);
135 WRITE_LOCK(INVISIBLECHAIN.AERWLock);
136 WRITE_LOCK(RepAtom(atomToInclude)->ARWLock);
137 RepAtom(atomToInclude)->NextOfAE = INVISIBLECHAIN.Entry;
138 WRITE_UNLOCK(RepAtom(atomToInclude)->ARWLock);
139 INVISIBLECHAIN.Entry = atomToInclude;
140 WRITE_UNLOCK(INVISIBLECHAIN.AERWLock);
148static Int hidden_atom(USES_REGS1) {
151 Term t1 = Deref(ARG1);
153 if (!Yap_IsGroundTerm(t1))
157 else if (IsApplTerm(t1))
158 at = NameOfFunctor(FunctorOfTerm(t1));
161 READ_LOCK(INVISIBLECHAIN.AERWLock);
162 chain = RepAtom(INVISIBLECHAIN.Entry);
163 while (!EndOfPAEntr(chain) && AbsAtom(chain) != at)
164 chain = RepAtom(chain->NextOfAE);
165 READ_UNLOCK(INVISIBLECHAIN.AERWLock);
166 if (EndOfPAEntr(chain))
178static Int unhide_atom(USES_REGS1) {
180 Term t1 = Deref(ARG1);
182 if (!Yap_IsGroundTerm(t1)) {
183 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"unhide_atom/1");
186 if (!IsAtomTerm(t1)) {
187 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"unhide_atom/1");
190 atom = RepAtom(AtomOfTerm(t1));
191 WRITE_LOCK(atom->ARWLock);
192 if (atom->PropsOfAE != NIL) {
193 Yap_ThrowError(SYSTEM_ERROR_INTERNAL, t1,
"cannot unhide_atom an atom in use");
196 WRITE_LOCK(INVISIBLECHAIN.AERWLock);
197 chain = RepAtom(INVISIBLECHAIN.Entry);
199 while (!EndOfPAEntr(chain) &&
200 strcmp((
char *)chain->StrOfAE, (
char *)atom->StrOfAE) != 0) {
202 chain = RepAtom(chain->NextOfAE);
204 if (EndOfPAEntr(chain))
206 atom->PropsOfAE = chain->PropsOfAE;
208 INVISIBLECHAIN.Entry = chain->NextOfAE;
210 old->NextOfAE = chain->NextOfAE;
211 WRITE_UNLOCK(INVISIBLECHAIN.AERWLock);
212 WRITE_UNLOCK(atom->ARWLock);
226static Int char_code(USES_REGS1) {
227 Int t0 = Deref(ARG1);
228 if (!Yap_IsGroundTerm(t0)) {
229 Term t1 = Deref(ARG2);
230 if (!Yap_IsGroundTerm(t1)) {
231 Yap_ThrowError(INSTANTIATION_ERROR, t0,
"char_code/2");
233 }
else if (!IsIntegerTerm(t1)) {
234 if (!IsBigIntTerm(t1)) {
235 Yap_ThrowError(REPRESENTATION_ERROR_INT, t1,
"char_code/2");
238 Yap_ThrowError(TYPE_ERROR_INTEGER, t1,
"char_code/2");
241 Int code = IntegerOfTerm(t1);
245 Yap_ThrowError(REPRESENTATION_ERROR_CHARACTER_CODE, t1,
"char_code/2");
248 if (code > MAX_ISO_LATIN1) {
249 unsigned char codes[10];
251 if (code > CHARCODE_MAX) {
252 Yap_ThrowError(REPRESENTATION_ERROR_INT, t1,
"char_code/2");
255 size_t n = put_utf8(codes, code);
257 tout = MkAtomTerm(Yap_ULookupAtom(codes));
263 tout = MkAtomTerm(Yap_LookupAtom(codes));
265 return Yap_unify(ARG1, tout);
267 }
else if (!IsAtomTerm(t0)) {
269 Yap_ThrowError(TYPE_ERROR_CHARACTER, t0,
"char_code/2");
272 Atom at = AtomOfTerm(t0);
274 unsigned char *c = RepAtom(at)->UStrOfAE;
275 int32_t v = IntegerOfTerm(ARG1);
281 return Yap_unify(ARG2, tf);
314static Int name(USES_REGS1) {
315 Term t2 = Deref(ARG2), NewT, t1 = Deref(ARG1);
316 LOCAL_MAX_SIZE = 1024;
317 int l = push_text_stack();
320 if (Yap_IsGroundTerm(t1)) {
321 if (!!Yap_IsGroundTerm(t2) && !IsPairTerm(t2) && t2 != TermNil) {
322 Yap_ThrowError(TYPE_ERROR_LIST, ARG2,
"name/2");
327 NewT = Yap_AtomicToListOfCodes(t1 PASS_REGS);
330 return Yap_unify(NewT, ARG2);
333 }
else if (!Yap_IsGroundTerm(t2)) {
334 Yap_ThrowError(INSTANTIATION_ERROR, t2,
"name/2");
338 Term at = Yap_ListToAtomic(t2 PASS_REGS);
341 return Yap_unify(at, ARG1);
344 if (LOCAL_Error_TYPE) {
345 Yap_ThrowError(LOCAL_Error_TYPE,ARG1,
"atom/2");
363static Int string_to_atomic(
367 int l = push_text_stack();
370 v1 = !Yap_IsGroundTerm(t1);
371 v2 = !Yap_IsGroundTerm(t2);
374 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_c");
379 if (!(t2 = Yap_AtomicToString(t2 PASS_REGS))) {
386 if (!IsStringTerm(t1)) {
392 bool rc = Yap_unify(t1,t2);
405static Int atomic_to_string(USES_REGS1) {
407 ARG1 = ARG2, ARG2 = t1;
408 return string_to_atomic(PASS_REGS1);
420static Int string_to_atom(USES_REGS1) {
424 int l = push_text_stack();
427 v1 = !Yap_IsGroundTerm(t1);
428 v2 = !Yap_IsGroundTerm(t2);
431 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
436 t2 = (Yap_AtomSWIToString(t2 PASS_REGS));
442 t1 = MkAtomTerm(Yap_StringSWIToAtom(t1 PASS_REGS));
449 t1 = MkAtomTerm(Yap_AtomicToAtom(t1 PASS_REGS));
450 t2= MkAtomTerm(Yap_AtomicToAtom(t2 PASS_REGS));
456 return Yap_unify(t1,t2);
465static Int atom_to_string(USES_REGS1) {
470 return string_to_atom(PASS_REGS1);
473static Int string_to_list(USES_REGS1) {
474 Term list = Deref(ARG2),
string = Deref(ARG1);
475 LOCAL_MAX_SIZE = 1024;
476 int l = push_text_stack();
479 if (IsVarTerm(
string)) {
480 Term t1 = Yap_ListToString(list PASS_REGS);
483 return Yap_unify(ARG1, t1);
485 }
else if (IsStringTerm(
string)) {
486 Term tf = Yap_StringToListOfCodes(
string PASS_REGS);
489 return Yap_unify(ARG2, tf);
492 LOCAL_Error_TYPE = TYPE_ERROR_STRING;
494 if (LOCAL_Error_TYPE && Yap_HandleError(
"string_to_list/2")) {
495 string = Deref(ARG1);
511static Int atom_string(USES_REGS1) {
514 int l = push_text_stack();
517 v1 = !Yap_IsGroundTerm(t1);
518 v2 = !Yap_IsGroundTerm(t2);
521 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
526 t2 = MkAtomTerm(Yap_StringSWIToAtom(t2 PASS_REGS));
532 t1 = Yap_AtomicToString(t1 PASS_REGS);
539 t1 = Yap_AtomicToString(t1 PASS_REGS);
540 t2= MkAtomTerm(Yap_StringSWIToAtom(t2 PASS_REGS));
546 return Yap_unify(t1,t2);
552static Int string_atom(USES_REGS1) {
557 return atom_string(PASS_REGS1);
570static Int atom_chars(USES_REGS1) {
572 LOCAL_MAX_SIZE = 1024;
573 int l = push_text_stack();
577 if (IsAtomTerm(t1)) {
578 Term tf = Yap_AtomSWIToListOfAtoms(t1 PASS_REGS);
581 return Yap_unify(ARG2, tf);
583 }
else if (!Yap_IsGroundTerm(t1)) {
585 Term t = Deref(ARG2);
586 Atom af = Yap_ListOfAtomsToAtom(t PASS_REGS);
589 return Yap_unify(ARG1, MkAtomTerm(af));
593 LOCAL_Error_TYPE = TYPE_ERROR_ATOM;
595 if (LOCAL_Error_TYPE && Yap_HandleError(
"atom_chars/2")) {
628static Int atom_codes(USES_REGS1) {
631 int l = push_text_stack();
634 v1 = !Yap_IsGroundTerm(t1);
635 v2 = !Yap_IsGroundTerm(t2);
638 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
643 rc = Yap_unify(t1,MkAtomTerm(Yap_ListToAtom(t2 PASS_REGS)));
645 if (!(t1=Yap_AtomSWIToListOfCodes(t1 PASS_REGS)))
647 rc = Yap_unify(t1,t2);
651 if (!(a1=Yap_AtomicToAtom(t1 PASS_REGS)))
653 rc = a1 == Yap_ListToAtom(t2 PASS_REGS);
660static Int string_codes(USES_REGS1) {
663 int l = push_text_stack();
666 v1 = !Yap_IsGroundTerm(t1);
667 v2 = !Yap_IsGroundTerm(t2);
670 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
675 t2 = Yap_ListSWIToString(t2 PASS_REGS);
681 t1 = Yap_StringSWIToListOfCodes(t1 PASS_REGS);
688 t1 = Yap_AtomicToString(t1 PASS_REGS);
689 t2= Yap_ListSWIToString(t2 PASS_REGS);
695 rc = Yap_unify(t1,t2);
699static Int string_chars(USES_REGS1) {
702 int l = push_text_stack();
705 v1 = !Yap_IsGroundTerm(t1);
706 v2 = !Yap_IsGroundTerm(t2);
709 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
714 t2 = Yap_ListSWIToString(t2 PASS_REGS);
720 t1 = Yap_StringSWIToListOfAtoms(t1 PASS_REGS);
727 t1 = Yap_AtomicToString(t1 PASS_REGS);
728 t2= Yap_ListSWIToString(t2 PASS_REGS);
736 return Yap_unify(t1,t2);
748static Int number_chars(USES_REGS1) {
751 int l = push_text_stack();
754 v1 = !Yap_IsGroundTerm(t1);
755 v2 = !Yap_IsGroundTerm(t2);
758 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
763 t2 = Yap_ListToNumber(t2 PASS_REGS);
766 Yap_ThrowError(SYNTAX_ERROR, t2,
"atom_codes");
770 t1 = Yap_NumberToListOfAtoms(t1 PASS_REGS);
777 t2= Yap_ListToNumber(t2 PASS_REGS);
783 return Yap_unify(t1,t2);
797static Int number_codes(USES_REGS1) {
800 int l = push_text_stack();
803 v1 = !Yap_IsGroundTerm(t1);
804 v2 = !Yap_IsGroundTerm(t2);
807 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
812 t2 = Yap_ListToNumber(t2 PASS_REGS);
818 t1 = Yap_NumberToListOfCodes(t1 PASS_REGS);
825 t2= Yap_ListToNumber(t2 PASS_REGS);
831 return Yap_unify(t1,t2);
848static Int number_atom(USES_REGS1) {
851 int l = push_text_stack();
854 v1 = !Yap_IsGroundTerm(t1);
855 v2 = !Yap_IsGroundTerm(t2);
858 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
864 t2 = Yap_AtomToNumber(t2 PASS_REGS);
870 t1 = Yap_NumberToString(t1 PASS_REGS);
877 t2= Yap_AtomToNumber(t2 PASS_REGS);
883 return Yap_unify(t1,t2);
897static Int number_string(USES_REGS1) {
900 int l = push_text_stack();
903 v1 = !Yap_IsGroundTerm(t1);
904 v2 = !Yap_IsGroundTerm(t2);
907 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"atom_codes");
912 t2 =( Yap_AtomToNumber(t2 PASS_REGS) );
918 t1 = MkAtomTerm(Yap_NumberToAtom(t1 PASS_REGS));
926 ( Yap_AtomToNumber(t2 PASS_REGS) );
932 return Yap_unify(t1,t2);
936static Int cont_atom_concat3(USES_REGS1) {
942 i = IntOfTerm(EXTRA_CBACK_ARG(3, 1));
943 max = IntOfTerm(EXTRA_CBACK_ARG(3, 2));
944 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(i + 1);
946 int l = push_text_stack();
947 bool rc = Yap_SpliceAtom(t3, ats, i, max PASS_REGS);
949 if (LOCAL_Error_TYPE == YAP_NO_ERROR) {
952 return (Yap_unify(ARG1, MkAtomTerm(ats[0])) &&
953 Yap_unify(ARG2, MkAtomTerm(ats[1])));
955 return do_cut(Yap_unify(ARG1, MkAtomTerm(ats[0])) &&
956 Yap_unify(ARG2, MkAtomTerm(ats[1])));
962 if (LOCAL_Error_TYPE) {
963 if (Yap_HandleError(
"atom_concat/3")) {
971static Int det_atom_concat3(USES_REGS1) {
979 g1 = IsAtomTerm(t1) ? 1: 0;
982 t1 = MkAtomTerm(Yap_NumberToAtom(t1));
986 g2 = IsAtomTerm(t2) ? 1: 0;
989 t2 = MkAtomTerm(Yap_NumberToAtom(t2));
993 g3 = IsAtomTerm(t3) ? 1: 0;
994 int l = push_text_stack();
996 if ((at=Yap_ConcatAtoms(t1, t2 PASS_REGS))) {
997 o = Yap_unify(t3,MkAtomTerm(at));
1002 }
else if (g1 && g3) {
1003 if ((at=Yap_SubtractHeadAtom(t3, t1 PASS_REGS))) {
1004 o = Yap_unify(t2,MkAtomTerm(at));
1008 }
else if (g2 && g3) {
1009 if ((at=Yap_SubtractTailAtom(t3, t2 PASS_REGS))) {
1010 o = Yap_unify(t1,MkAtomTerm(at));
1019 (o ==
true ? Yap_unify(ARG4,TermTrue) : Yap_unify(ARG4,TermFalse) );
1023static Int non_det_atom_concat3(USES_REGS1) {
1033 g1 = IsAtomTerm(t1) ? 1: 0;
1035 if (IsNumTerm(t1)) {
1036 t1 = MkAtomTerm(Yap_NumberToAtom(t1));
1040 g2 = IsAtomTerm(t2) ? 1: 0;
1042 if (IsNumTerm(t2)) {
1043 t2 = MkAtomTerm(Yap_NumberToAtom(t2));
1047 g3 = IsAtomTerm(t3) ? 1: 0;
1049 if (IsNumTerm(t3)) {
1050 t3 = MkAtomTerm(Yap_NumberToAtom(t3));
1054 v1 = !Yap_IsGroundTerm(t1) ? 1: 0;
1055 v2 = !Yap_IsGroundTerm(t2) ? 1: 0;
1056 v3 = !Yap_IsGroundTerm(t3) ? 1: 0;
1058 Int len = Yap_AtomToUnicodeLength(t3 PASS_REGS);
1062 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1063 EXTRA_CBACK_ARG(3, 2) = MkIntTerm(len);
1064 {
return cont_atom_concat3(PASS_REGS1); }
1067 if (g1+g2+g3+v1+v2+v3 == 3)
1068 Yap_ThrowError(INSTANTIATION_ERROR, v1 ? t1 : t2,
"atom_concat");
1070 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"atom_concat");
1072 Yap_ThrowError(TYPE_ERROR_ATOM, t2,
"atom_concat");
1076 bool rc = at && Yap_unify(ot, MkAtomTerm(at));
1080#define CastToNumeric(x) CastToNumeric__(x PASS_REGS)
1082static Term CastToNumeric__(
Atom at USES_REGS) {
1084 if ((t = Yap_AtomToNumber(MkAtomTerm(at) PASS_REGS))) {
1087 return MkAtomTerm(at);
1091static Int cont_atomic_concat3(USES_REGS1) {
1097 i = IntOfTerm(EXTRA_CBACK_ARG(3, 1));
1098 max = IntOfTerm(EXTRA_CBACK_ARG(3, 2));
1099 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(i + 1);
1100 int l = push_text_stack();
1101 bool rc = Yap_SpliceAtom(t3, ats, i, max PASS_REGS);
1106 Term t1 = CastToNumeric(ats[0]);
1107 Term t2 = CastToNumeric(ats[1]);
1109 return Yap_unify(ARG1, t1) && Yap_unify(ARG2, t2);
1111 if (Yap_unify(ARG1, t1) && Yap_unify(ARG2, t2))
1116 if (LOCAL_Error_TYPE) {
1117 if (Yap_HandleError(
"string_concat/3")) {
1126static Int atomic_concat3(USES_REGS1) {
1135 g1 = Yap_IsGroundTerm(t1);
1136 g2 = Yap_IsGroundTerm(t2);
1137 g3 = Yap_IsGroundTerm(t3);
1139 int l = push_text_stack();
1140 at = Yap_ConcatAtomics(t1, t2 PASS_REGS);
1143 }
else if (g1 && g3) {
1144 int l = push_text_stack();
1145 at = Yap_SubtractHeadAtom(t3, t1 PASS_REGS);
1148 }
else if (g2 && g3) {
1149 int l = push_text_stack();
1150 at = Yap_SubtractTailAtom(t3, t2 PASS_REGS);
1154 Int len = Yap_AtomicToUnicodeLength(t3 PASS_REGS);
1158 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1159 EXTRA_CBACK_ARG(3, 2) = MkIntTerm(len);
1160 return cont_atomic_concat3(PASS_REGS1);
1162 LOCAL_Error_TYPE = INSTANTIATION_ERROR;
1166 if (Yap_unify(ot, MkAtomTerm(at))) {
1173 if (LOCAL_Error_TYPE) {
1174 if (Yap_HandleError(
"atomic_concat/3")) {
1183static Int cont_string_concat3(USES_REGS1) {
1189 i = IntOfTerm(EXTRA_CBACK_ARG(3, 1));
1190 max = IntOfTerm(EXTRA_CBACK_ARG(3, 2));
1191 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(i + 1);
1193 l = push_text_stack();
1194 bool rc = Yap_SpliceString(t3, ts, i, max PASS_REGS);
1200 return Yap_unify(ARG1, ts[0]) && Yap_unify(ARG2, ts[1]);
1202 return do_cut(Yap_unify(ARG1, ts[0]) && Yap_unify(ARG2, ts[1]));
1206 if (LOCAL_Error_TYPE) {
1207 if (Yap_HandleError(
"string_concat/3")) {
1216static Int string_concat3(USES_REGS1) {
1226 g1 = IsStringTerm(t1) ? 1: 0;
1227 g2 = IsStringTerm(t2) ? 1: 0;
1228 g3 = IsStringTerm(t3) ? 1: 0;
1229 v1 = !Yap_IsGroundTerm(t1) ? 1: 0;
1230 v2 = !Yap_IsGroundTerm(t2) ? 1: 0;
1231 v3 = !Yap_IsGroundTerm(t3) ? 1: 0;
1233 int l = push_text_stack();
1234 s = Yap_ConcatStrings(t1, t2 PASS_REGS);
1237 }
else if (g1 && g3) {
1238 int l = push_text_stack();
1239 s = Yap_SubtractHeadString(t3, t1 PASS_REGS);
1242 }
else if (g2 && g3) {
1243 int l = push_text_stack();
1244 s = Yap_SubtractTailString(t3, t2 PASS_REGS);
1248 Int len = Yap_StringToUnicodeLength(t3 PASS_REGS);
1252 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1253 EXTRA_CBACK_ARG(3, 2) = MkIntTerm(len);
1254 {
return cont_string_concat3(PASS_REGS1); }
1257 if (g1+g2+g3+v1+v2+v3 == 3)
1258 Yap_ThrowError(INSTANTIATION_ERROR, v1 ? t1 : t2,
"string_concat");
1260 Yap_ThrowError(TYPE_ERROR_STRING, t1,
"string_concat");
1262 Yap_ThrowError(TYPE_ERROR_STRING, t2,
"string_concat");
1263 Yap_ThrowError(TYPE_ERROR_STRING, t3,
"string_concat");
1267 return do_cut(Yap_unify(ot, s) );
1272static Int cont_string_code3(USES_REGS1) {
1275 utf8proc_int32_t chr;
1276 const unsigned char *s;
1277 const unsigned char *s0;
1279 l = push_text_stack();
1282 s0 = UStringOfTerm(t2);
1284 EXTRA_CBACK_ARG(3, 1));
1285 j = IntOfTerm(EXTRA_CBACK_ARG(3, 2));
1288 s = (s0 + i) + get_utf8((
unsigned char *)s0 + i, -1, &chr);
1290 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(s - s0);
1291 EXTRA_CBACK_ARG(3, 2) = MkIntTerm(j + 1);
1292 return (Yap_unify(MkIntegerTerm(chr), ARG3) &&
1293 Yap_unify(MkIntegerTerm(j + 1), ARG1));
1295 return do_cut(Yap_unify(MkIntegerTerm(chr), ARG3) &&
1296 Yap_unify(MkIntegerTerm(j), ARG1));
1298 if (LOCAL_Error_TYPE) {
1299 if (Yap_HandleError(
"string_code/3")) {
1311static Int string_code3(USES_REGS1) {
1314 const unsigned char *s;
1315 int l = push_text_stack();
1319 if (!Yap_IsGroundTerm(t2)) {
1320 LOCAL_Error_TYPE = INSTANTIATION_ERROR;
1321 }
else if (!IsStringTerm(t2)) {
1322 LOCAL_Error_TYPE = TYPE_ERROR_STRING;
1324 s = UStringOfTerm(t2);
1326 if (!Yap_IsGroundTerm(t1)) {
1327 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1328 EXTRA_CBACK_ARG(3, 2) = MkIntTerm(0);
1331 return cont_string_code3(PASS_REGS1);
1333 }
else if (!IsIntegerTerm(t1)) {
1334 LOCAL_Error_TYPE = TYPE_ERROR_INTEGER;
1336 const unsigned char *ns = s;
1337 utf8proc_int32_t chr;
1338 Int indx = IntegerOfTerm(t1);
1341 LOCAL_Error_TYPE = DOMAIN_ERROR_NOT_LESS_THAN_ZERO;
1345 ns = skip_utf8(s, indx);
1349 get_utf8(ns, -1, &chr);
1352 if (Yap_unify(ARG3, MkIntegerTerm(chr)))
1358 if (LOCAL_Error_TYPE) {
1359 if (Yap_HandleError(
"string_code/3")) {
1371static Int get_string_code3(USES_REGS1) {
1374 const unsigned char *s;
1378 if (!Yap_IsGroundTerm(t2)) {
1379 LOCAL_Error_TYPE = INSTANTIATION_ERROR;
1380 }
else if (!IsStringTerm(t2)) {
1381 LOCAL_Error_TYPE = TYPE_ERROR_STRING;
1383 s = UStringOfTerm(t2);
1385 if (!Yap_IsGroundTerm(t1)) {
1386 LOCAL_Error_TYPE = INSTANTIATION_ERROR;
1388 }
else if (!IsIntegerTerm(t1)) {
1389 LOCAL_Error_TYPE = TYPE_ERROR_INTEGER;
1391 const unsigned char *ns = s;
1392 Int indx = IntegerOfTerm(t1);
1396 LOCAL_Error_TYPE = DOMAIN_ERROR_NOT_LESS_THAN_ZERO;
1402 ns = skip_utf8(ns, indx);
1407 utf8proc_int32_t chr;
1408 get_utf8(ns, -1, &chr);
1410 return Yap_unify(ARG3, MkIntegerTerm(chr));
1416 if (LOCAL_Error_TYPE) {
1417 if (Yap_HandleError(
"string_code/3")) {
1426static Int atom_concat2(USES_REGS1) {
1430 int l = push_text_stack();
1433 n = Yap_SkipList(&t1, &tailp);
1434 if (*tailp != TermNil) {
1435 LOCAL_Error_TYPE = TYPE_ERROR_LIST;
1442 LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
1446 while (t1 != TermNil) {
1447 inpv[i].type = YAP_STRING_ATOM|YAP_STRING_INT|YAP_STRING_FLOAT|YAP_STRING_BIG;
1448 inpv[i].val.t = HeadOfTerm(t1);
1450 t1 = TailOfTerm(t1);
1452 out.type = YAP_STRING_ATOM;
1453 if (!Yap_Concat_Text(n, inpv, &out PASS_REGS)) {
1459 return Yap_unify(ARG2, MkAtomTerm(at));
1464 if (LOCAL_Error_TYPE) {
1465 if (Yap_HandleError(
"atom_concat/2")) {
1476static Int string_concat2(USES_REGS1) {
1480 int l = push_text_stack();
1483 Yap_SkipList(&t1, &tailp);
1484 if (*tailp != TermNil) {
1486 Yap_ThrowError(TYPE_ERROR_LIST,*tailp,
"string_code/3");
1490 while (t1 != TermNil) {
1491 Term head = HeadOfTerm(t1);
1492 if (IsAtomTerm(head)) {
1493 nsz += strlen(RepAtom(AtomOfTerm(head))->StrOfAE);
1494 }
else if (!IsStringTerm(head)) {
1496 Yap_ThrowError(TYPE_ERROR_STRING,head,
"string_concat/2");
1499 nsz += strlen(StringOfTerm(head) );
1501 t1 = TailOfTerm(t1);
1506 while (t1 != TermNil) {
1507 Term head = HeadOfTerm(t1);
1508 if (IsAtomTerm(head)) {
1509 strcat(buf,RepAtom(AtomOfTerm(head))->StrOfAE);
1510 }
else { strcat(buf,StringOfTerm(head));
1512 t1 = TailOfTerm(t1);
1514 Term t = MkStringTerm(buf);
1516 return Yap_unify(ARG2, t);
1520static Int atomic_concat2(USES_REGS1) {
1524 int l = push_text_stack();
1527 n = Yap_SkipList(&t1, &tailp);
1528 if (*tailp != TermNil) {
1529 LOCAL_Error_TYPE = TYPE_ERROR_LIST;
1537 return Yap_unify(ARG2, HeadOfTerm(t1));
1540 LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
1544 while (t1 != TermNil) {
1545 Term th = HeadOfTerm(t1);
1546 if (IsAtomTerm(th)) {
1547 inpv[i].type = YAP_STRING_ATOM|YAP_STRING_TERM;
1548 }
else if (IsStringTerm(th)) {
1549 inpv[i].type = YAP_STRING_STRING|YAP_STRING_TERM;
1550 }
else if (IsIntegerTerm(th)) {
1551 inpv[i].type = YAP_STRING_INT|YAP_STRING_TERM;
1552 }
else if (IsFloatTerm(th)) {
1553 inpv[i].type = YAP_STRING_FLOAT|YAP_STRING_TERM;
1554 }
else if (IsBigIntTerm(th)) {
1555 inpv[i].type = YAP_STRING_BIG|YAP_STRING_TERM;
1557 inpv[i].type = YAP_STRING_CHARS |
1558 YAP_STRING_CODES|YAP_STRING_TERM;
1562 t1 = TailOfTerm(t1);
1564 out.type = YAP_STRING_ATOM;
1565 if (!Yap_Concat_Text(n, inpv, &out PASS_REGS)) {
1573 return Yap_unify(ARG2, MkAtomTerm(at));
1578 if (LOCAL_Error_TYPE && Yap_HandleError(
"atom_concat/3")) {
1587static Int atomics_to_string2(USES_REGS1) {
1591 int l = push_text_stack();
1594 n = Yap_SkipList(&t1, &tailp);
1595 if (*tailp != TermNil) {
1596 LOCAL_Error_TYPE = TYPE_ERROR_LIST;
1603 LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
1608 while (t1 != TermNil) {
1609 inpv[i].type = YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT |
1610 YAP_STRING_FLOAT | YAP_STRING_BIG | YAP_STRING_TERM;
1611 inpv[i].val.t = HeadOfTerm(t1);
1613 t1 = TailOfTerm(t1);
1615 out.type = YAP_STRING_STRING;
1616 if (!Yap_Concat_Text(n, inpv, &out PASS_REGS)) {
1624 return Yap_unify(ARG2, MkAtomTerm(at));
1629 if (LOCAL_Error_TYPE && Yap_HandleError(
"atomics_to_string/2")) {
1638static Int atomics_to_string3(USES_REGS1) {
1642 int l = push_text_stack();
1646 n = Yap_SkipList(&t1, &tailp);
1647 if (*tailp != TermNil) {
1648 LOCAL_Error_TYPE = TYPE_ERROR_LIST;
1655 LOCAL_Error_TYPE = RESOURCE_ERROR_HEAP;
1660 while (t1 != TermNil) {
1661 inpv[i].type = YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT |
1662 YAP_STRING_FLOAT | YAP_STRING_BIG | YAP_STRING_TERM;
1663 inpv[i].val.t = HeadOfTerm(t1);
1665 inpv[i].type = YAP_STRING_STRING | YAP_STRING_ATOM | YAP_STRING_INT |
1666 YAP_STRING_FLOAT | YAP_STRING_BIG | YAP_STRING_TERM;
1669 t1 = TailOfTerm(t1);
1671 out.type = YAP_STRING_STRING;
1672 if (!Yap_Concat_Text(2 * n - 1, inpv, &out PASS_REGS)) {
1680 return Yap_unify(ARG3, MkAtomTerm(at));
1685 if (LOCAL_Error_TYPE && Yap_HandleError(
"atomics_to_string/3")) {
1701static Int atom_length(USES_REGS1) {
1702 Term t1 = Deref(ARG1);
1703 Term t2 = Deref(ARG2);
1706 int l = push_text_stack();
1707 if (!Yap_IsGroundTerm(t1)) {
1708 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1710 }
else if (!IsAtomTerm(t1)) {
1711 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"at first argument");
1715 if (Yap_IsGroundTerm(t2)) {
1717 if (!IsIntegerTerm(t2)) {
1718 Yap_ThrowError(TYPE_ERROR_INTEGER, t2,
"atom_length/2");
1723 }
else if ((Int)(len = IntegerOfTerm(t2)) < 0) {
1724 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
"atom_length/2");
1732 len = Yap_AtomToUnicodeLength(t1 PASS_REGS);
1733 if (len != (
size_t)-1) {
1735 return Yap_unify(ARG2, MkIntegerTerm(len));
1738 if (LOCAL_Error_TYPE && Yap_HandleError(
"atom_length/2")) {
1756static Int atomic_length(USES_REGS1) {
1757 Term t1 = Deref(ARG1);
1758 Term t2 = Deref(ARG2);
1761 int l = push_text_stack();
1762 if (!Yap_IsGroundTerm(t1)) {
1763 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1770 if (IsNonVarTerm(t2)) {
1772 if (!IsIntegerTerm(t2)) {
1773 Yap_ThrowError(TYPE_ERROR_INTEGER, t2,
"atom_length/2");
1778 }
else if ((Int)(len = IntegerOfTerm(t2)) < 0) {
1779 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
"atom_length/2");
1787 len = Yap_AtomicToUnicodeLength(t1 PASS_REGS);
1788 if (len != (
size_t)-1) {
1790 return Yap_unify(ARG2, MkIntegerTerm(len));
1793 if (LOCAL_Error_TYPE && Yap_HandleError(
"atomic_length/2")) {
1802static Int string_length(USES_REGS1) {
1804 Term t2 = Deref(ARG2);
1807 int l = push_text_stack();
1808 if (Yap_IsGroundTerm(t2)) {
1810 if (!IsIntegerTerm(t2)) {
1811 Yap_ThrowError(TYPE_ERROR_INTEGER, t2,
"string_length/2");
1817 if (FALSE && (Int)(len = IntegerOfTerm(t2)) < 0) {
1818 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
"string_length/2");
1827 len = Yap_StringToUnicodeLength(t1 PASS_REGS);
1828 if (len != (
size_t)-1) {
1830 return Yap_unify(ARG2, MkIntegerTerm(len));
1833 if (LOCAL_Error_TYPE && Yap_HandleError(
"string_length/2")) {
1849static Int downcase_text_to_atom(USES_REGS1) {
1850 Term t1 = Deref(ARG1);
1851 Term t2 = Deref(ARG2);
1853 int l = push_text_stack();
1854 if (!Yap_IsGroundTerm(t1)) {
1855 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1862 if (IsNonVarTerm(t2)) {
1863 if (!IsAtomTerm(t2)) {
1864 Yap_ThrowError(TYPE_ERROR_ATOM, t2,
"at second argument");
1872 Atom at = Yap_AtomicToLowAtom(t1);
1874 if (LOCAL_Error_TYPE && Yap_HandleError(
"downcase_text_to_atom/2"))
1882 return Yap_unify(MkAtomTerm(at), t2);
1895static Int upcase_text_to_atom(USES_REGS1) {
1896 Term t1 = Deref(ARG1);
1897 Term t2 = Deref(ARG2);
1899 int l = push_text_stack();
1900 if (!Yap_IsGroundTerm(t1)) {
1901 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1908 if (IsNonVarTerm(t2)) {
1909 if (!IsAtomTerm(t2)) {
1910 Yap_ThrowError(TYPE_ERROR_ATOM, t2,
"at second argument");
1918 Atom at = Yap_AtomicToUpAtom(t1);
1920 if (LOCAL_Error_TYPE && Yap_HandleError(
"upcase_text_to_atom/2"))
1928 return Yap_unify(MkAtomTerm(at), t2);
1943static Int downcase_text_to_string(USES_REGS1) {
1944 Term t1 = Deref(ARG1);
1945 Term t2 = Deref(ARG2);
1947 if (!Yap_IsGroundTerm(t1)) {
1948 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1952 if (IsNonVarTerm(t2)) {
1953 if (!IsStringTerm(t2)) {
1954 Yap_ThrowError(TYPE_ERROR_STRING, t2,
"at second argument");
1958 Term t = Yap_AtomicToLowString(t1);
1959 if (t == TermZERO) {
1960 if (LOCAL_Error_TYPE && Yap_HandleError(
"downcase_text_to_string/2"))
1965 return Yap_unify(t, t2);
1978static Int upcase_text_to_string(USES_REGS1) {
1979 Term t1 = Deref(ARG1);
1980 Term t2 = Deref(ARG2);
1982 if (!Yap_IsGroundTerm(t1)) {
1983 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
1987 if (IsNonVarTerm(t2)) {
1988 if (!IsStringTerm(t2)) {
1989 Yap_ThrowError(TYPE_ERROR_STRING, t2,
"at second argument");
1993 int l = push_text_stack();
1995 Term t = Yap_AtomicToUpString(t1);
1997 if (t == TermZERO) {
1998 if (LOCAL_Error_TYPE && Yap_HandleError(
"upcase_text_to_string/2"))
2006 return Yap_unify(t, t2);
2019static Int downcase_text_to_codes(USES_REGS1) {
2020 Term t1 = Deref(ARG1);
2021 Term t2 = Deref(ARG2);
2023 if (!Yap_IsGroundTerm(t1)) {
2024 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
2028 if (IsNonVarTerm(t2)) {
2029 if (!Yap_IsListTerm(t2)) {
2030 Yap_ThrowError(TYPE_ERROR_LIST, t2,
"at second argument");
2034 int l = push_text_stack();
2036 Term t = Yap_AtomicToLowListOfCodes(t1);
2037 if (t == TermZERO) {
2038 if (LOCAL_Error_TYPE && Yap_HandleError(
"downcase_text_to_codes/2"))
2044 return Yap_unify(t, t2);
2057static Int upcase_text_to_codes(USES_REGS1) {
2058 Term t1 = Deref(ARG1);
2059 Term t2 = Deref(ARG2);
2061 if (!Yap_IsGroundTerm(t1)) {
2062 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
2066 if (IsNonVarTerm(t2)) {
2067 if (!Yap_IsListTerm(t2)) {
2068 Yap_ThrowError(TYPE_ERROR_LIST, t2,
"at second argument");
2072 int l = push_text_stack();
2074 Term t = Yap_AtomicToUpListOfCodes(t1);
2075 if (t == TermZERO) {
2076 if (LOCAL_Error_TYPE && Yap_HandleError(
"upcase_text_to_codes/2"))
2082 return Yap_unify(t, t2);
2095static Int downcase_text_to_chars(USES_REGS1) {
2096 Term t1 = Deref(ARG1);
2097 Term t2 = Deref(ARG2);
2099 if (!Yap_IsGroundTerm(t1)) {
2100 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
2104 if (IsNonVarTerm(t2)) {
2105 if (!Yap_IsListTerm(t2)) {
2106 Yap_ThrowError(TYPE_ERROR_LIST, t2,
"at second argument");
2110 int l = push_text_stack();
2112 Term t = Yap_AtomicToLowListOfAtoms(t1);
2114 if (t == TermZERO) {
2115 if (LOCAL_Error_TYPE && Yap_HandleError(
"downcase_text_to_to_chars/2"))
2121 return Yap_unify(t, t2);
2134static Int upcase_text_to_chars(USES_REGS1) {
2135 Term t1 = Deref(ARG1);
2136 Term t2 = Deref(ARG2);
2138 if (!Yap_IsGroundTerm(t1)) {
2139 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"at first argument");
2143 if (IsNonVarTerm(t2)) {
2144 if (!Yap_IsListTerm(t2)) {
2145 Yap_ThrowError(TYPE_ERROR_LIST, t2,
"at second argument");
2149 int l = push_text_stack();
2151 Term t = Yap_AtomicToUpListOfAtoms(t1);
2152 if (t == TermZERO) {
2153 if (LOCAL_Error_TYPE && Yap_HandleError(
"upcase_text_to_chars/2"))
2159 return Yap_unify(t, t2);
2166static Int atom_split(USES_REGS1) {
2167 Term t1 = Deref(ARG1);
2168 Term t2 = Deref(ARG2);
2173 if (!Yap_IsGroundTerm(t1)) {
2174 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"$atom_split/4");
2177 if (!IsAtomTerm(t1)) {
2178 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"$atom_split/4");
2181 if (!Yap_IsGroundTerm(t2)) {
2182 Yap_ThrowError(INSTANTIATION_ERROR, t2,
"$atom_split/4");
2185 if (!IsIntTerm(t2)) {
2186 Yap_ThrowError(TYPE_ERROR_INTEGER, t2,
"$atom_split/4");
2189 if ((Int)(u_mid = IntOfTerm(t2)) < 0) {
2190 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
"atom_split/4");
2193 at = AtomOfTerm(t1);
2194 const char *s = RepAtom(at)->StrOfAE;
2195 const unsigned char *s0 = RepAtom(at)->UStrOfAE;
2196 unsigned char *s1, *s10;
2197 size_t u_len = strlen_utf8(s0);
2198 if (u_mid > u_len) {
2201 size_t b_mid = skip_utf8(s0, u_mid) - s0;
2202 s1 = s10 =
Malloc(b_mid + 1);
2203 memcpy(s1, s, b_mid);
2205 to1 = MkAtomTerm(Yap_ULookupAtom(s10));
2206 to2 = MkAtomTerm(Yap_ULookupAtom(s0 + b_mid));
2207 return Yap_unify_constant(ARG3, to1) && Yap_unify_constant(ARG4, to2);
2221static Int atom_number(USES_REGS1) {
2223 int l = push_text_stack();
2226 if (Yap_IsGroundTerm(t1)) {
2227 Term tf = Yap_AtomToNumber(t1 PASS_REGS);
2230 return Yap_unify(ARG2, tf);
2234 Term t = Deref(ARG2);
2235 Atom af = Yap_NumberToAtom(t PASS_REGS);
2238 return Yap_unify(ARG1, MkAtomTerm(af));
2242 if (LOCAL_Error_TYPE && Yap_HandleError(
"atom_number/2")) {
2261static Int string_number(USES_REGS1) {
2263 int l = push_text_stack();
2266 if (Yap_IsGroundTerm(t1)) {
2267 Term tf = Yap_StringToNumber(t1 PASS_REGS);
2271 return Yap_unify(ARG2, tf);
2275 Term t = Deref(ARG2);
2276 Term tf = Yap_NumberToString(t PASS_REGS);
2279 return Yap_unify(ARG1, tf);
2284 if (LOCAL_Error_TYPE && Yap_HandleError(
"string_number/2")) {
2292#define SUB_ATOM_HAS_MIN 1
2293#define SUB_ATOM_HAS_SIZE 2
2294#define SUB_ATOM_HAS_AFTER 4
2295#define SUB_ATOM_HAS_VAL 8
2296#define SUB_ATOM_HAS_ATOM 16
2297#define SUB_ATOM_HAS_UTF8 32
2299static Term build_new_atomic(
int mask,
const unsigned char *p,
size_t minv,
2300 size_t len USES_REGS) {
2306 cuts[1] = minv + len;
2311 cuts[0] = minv + len;
2315 inp.type = YAP_STRING_CHARS;
2316 inp.enc = ENC_ISO_UTF8;
2318 outv[n + 1].type = 0;
2319 if (mask & SUB_ATOM_HAS_ATOM) {
2320 outv[n].type = YAP_STRING_ATOM;
2322 outv[n].type = YAP_STRING_STRING;
2324 bool rc = Yap_Splice_Text(2 + n, cuts, &inp, outv PASS_REGS);
2328 if (mask & SUB_ATOM_HAS_ATOM) {
2329 return (MkAtomTerm(outv[n].val.a));
2331 return (outv[n].val.t);
2334static bool check_sub_string_at(
int minv,
const unsigned char *p1,
2335 const unsigned char *p2,
size_t len) {
2336 p1 = skip_utf8((
unsigned char *)p1, minv);
2337 if (p1 == NULL || p2 == NULL)
2339 return cmpn_utf8(p1, p2, len) == 0;
2342static bool check_sub_string_bef(
int max,
const unsigned char *p1,
2343 const unsigned char *p2) {
2344 size_t len = strlen_utf8(p2);
2345 int minv = max - len;
2348 if ((Int)(minv) < 0)
2351 p1 = skip_utf8(p1, minv);
2352 if (p1 == NULL || p2 == NULL)
2354 while ((c2 = *p2++) == *p1++ && c2)
2359static Int cont_sub_atomic(USES_REGS1) {
2360 Term tat1 = Deref(ARG1);
2361 Term tat5 = Deref(ARG5);
2363 size_t minv, len, after, sz;
2364 const unsigned char *p = NULL, *p5 = NULL;
2366 mask = IntegerOfTerm(EXTRA_CBACK_ARG(5, 1));
2367 minv = IntegerOfTerm(EXTRA_CBACK_ARG(5, 2));
2368 len = IntegerOfTerm(EXTRA_CBACK_ARG(5, 3));
2369 after = IntegerOfTerm(EXTRA_CBACK_ARG(5, 4));
2370 sz = IntegerOfTerm(EXTRA_CBACK_ARG(5, 5));
2372 if (Yap_IsGroundTerm(tat1)) {
2373 if (IsAtomTerm(tat1)) {
2374 p = AtomOfTerm(tat1)->UStrOfAE;
2375 }
else if (IsNumTerm(tat1)) {
2376 p = RepAtom(Yap_NumberToAtom(tat1 PASS_REGS))->UStrOfAE;
2378 p = UStringOfTerm(tat1);
2381 if (Yap_IsGroundTerm(tat5)) {
2382 if (IsAtomTerm(tat5)) {
2383 p5 = AtomOfTerm(tat5)->UStrOfAE;
2384 }
else if (IsNumTerm(tat5)) {
2385 p5 = RepAtom(Yap_NumberToAtom(tat5 PASS_REGS))->UStrOfAE;
2387 p5 = UStringOfTerm(tat5);
2391 if (mask & SUB_ATOM_HAS_VAL) {
2394 const unsigned char *p1 = p;
2396 while (!found && minv < sz-len) {
2398 p = skip_utf8(p1, minv);
2401 if (cmpn_utf8(p, p5, len) == 0) {
2402 Yap_unify(ARG2, MkIntegerTerm(minv));
2403 Yap_unify(ARG3, MkIntegerTerm(len));
2404 Yap_unify(ARG4, MkIntegerTerm(after));
2407 while (minv <= sz - len) {
2409 p += get_utf8((
unsigned char *)p, -1, &chr);
2412 if (cmpn_utf8(p, p5, len) == 0)
2416 if (minv == sz - len)
2424 if (minv > sz - len)
2430 }
else if (mask & SUB_ATOM_HAS_SIZE) {
2431 Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2432 Yap_unify(ARG2, MkIntegerTerm(minv));
2433 Yap_unify(ARG4, MkIntegerTerm(after));
2434 Yap_unify(ARG5, nat);
2439 }
else if (mask & SUB_ATOM_HAS_MIN) {
2440 after = sz - (minv + len);
2441 Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2442 Yap_unify(ARG3, MkIntegerTerm(len));
2443 Yap_unify(ARG4, MkIntegerTerm(after));
2444 Yap_unify(ARG5, nat);
2449 }
else if (mask & SUB_ATOM_HAS_AFTER) {
2450 len = sz - (minv + after);
2451 Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2452 Yap_unify(ARG2, MkIntegerTerm(minv));
2453 Yap_unify(ARG3, MkIntegerTerm(len));
2454 Yap_unify(ARG5, nat);
2460 Term nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2461 Yap_unify(ARG2, MkIntegerTerm(minv));
2462 Yap_unify(ARG3, MkIntegerTerm(len));
2463 Yap_unify(ARG4, MkIntegerTerm(after));
2464 Yap_unify(ARG5, nat);
2475 EXTRA_CBACK_ARG(5, 1) = MkIntegerTerm(mask);
2476 EXTRA_CBACK_ARG(5, 2) = MkIntegerTerm(minv);
2477 EXTRA_CBACK_ARG(5, 3) = MkIntegerTerm(len);
2478 EXTRA_CBACK_ARG(5, 4) = MkIntegerTerm(after);
2479 EXTRA_CBACK_ARG(5, 5) = MkIntegerTerm(sz);
2484static Int sub_atomic(
bool sub_atom,
bool sub_string USES_REGS) {
2485 Term tat1, tbef, tsize, tafter, tout;
2486 int mask = SUB_ATOM_HAS_UTF8;
2487 size_t minv, len, after, sz;
2488 const unsigned char *p = NULL;
2493 mask |= SUB_ATOM_HAS_ATOM;
2497 if (!!Yap_IsGroundTerm(tat1)) {
2499 if (IsAtomTerm(tat1)) {
2500 p = AtomOfTerm(tat1)->UStrOfAE;
2501 sz = strlen_utf8(p);
2502 }
else if (IsNumTerm(tat1)) {
2503 p = RepAtom(Yap_NumberToAtom(tat1 PASS_REGS))->UStrOfAE;
2504 sz = strlen_utf8(p);
2506 Yap_ThrowError(TYPE_ERROR_ATOM, tat1,
"sub_atom/5");
2509 }
else if (sub_string) {
2510 if (IsStringTerm(tat1)) {
2511 p = UStringOfTerm(tat1);
2512 sz = strlen_utf8(p);
2513 }
else if (IsNumTerm(tat1)) {
2514 p = RepAtom(Yap_NumberToAtom(tat1 PASS_REGS))->UStrOfAE;
2515 sz = strlen_utf8(p);
2517 Yap_ThrowError(TYPE_ERROR_STRING, tat1,
"sub_string/5");
2521 int l = push_text_stack();
2522 if ((p = Yap_TextToUTF8Buffer(tat1 PASS_REGS))) {
2524 sz = strlen_utf8(p);
2532 Yap_ThrowError(INSTANTIATION_ERROR, tat1,
"sub_atom/5: first variable\n");
2535 EXTRA_CBACK_ARG(5, 3) = MkIntegerTerm(0);
2537 if (!Yap_IsGroundTerm(tbef)) {
2539 }
else if (!IsIntegerTerm(tbef)) {
2540 Yap_ThrowError(TYPE_ERROR_INTEGER, tbef,
"sub_string/5");
2543 minv = IntegerOfTerm(tbef);
2544 if ((Int)minv < 0) {
2545 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, tbef,
"sub_string/5");
2548 mask |= SUB_ATOM_HAS_MIN;
2551 if (!Yap_IsGroundTerm(tsize = Deref(ARG3))) {
2553 }
else if (!IsIntegerTerm(tsize)) {
2554 Yap_ThrowError(TYPE_ERROR_INTEGER, tsize,
"sub_string/5");
2557 len = IntegerOfTerm(tsize);
2559 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, tsize,
"sub_string/5");
2562 mask |= SUB_ATOM_HAS_SIZE;
2565 if (!Yap_IsGroundTerm(tafter = Deref(ARG4))) {
2567 }
else if (!IsIntegerTerm(tafter)) {
2568 Yap_ThrowError(TYPE_ERROR_INTEGER, tafter,
"sub_string/5");
2571 after = IntegerOfTerm(tafter);
2572 if ((Int)after < 0) {
2573 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, tafter,
"sub_string/5");
2576 mask |= SUB_ATOM_HAS_AFTER;
2579 if (!!Yap_IsGroundTerm(tout = Deref(ARG5))) {
2581 if (!IsAtomTerm(tout)) {
2582 Yap_ThrowError(TYPE_ERROR_ATOM, tout,
"sub_atom/5");
2586 mask |= SUB_ATOM_HAS_VAL | SUB_ATOM_HAS_SIZE;
2587 oat = AtomOfTerm(tout);
2588 len = strlen_utf8(RepAtom(oat)->UStrOfAE);
2591 if (!IsStringTerm(tout)) {
2592 Yap_ThrowError(TYPE_ERROR_STRING, tout,
"sub_string/5");
2595 mask |= SUB_ATOM_HAS_VAL | SUB_ATOM_HAS_SIZE;
2596 len = strlen_utf8(UStringOfTerm(tout));
2599 if (!Yap_unify(ARG3, MkIntegerTerm(len))) {
2608 if ((mask & (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_VAL | SUB_ATOM_HAS_AFTER)) ==
2609 (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_VAL | SUB_ATOM_HAS_AFTER)) {
2610 const unsigned char *sm;
2612 sm = RepAtom(AtomOfTerm(tout))->UStrOfAE;
2614 sm = UStringOfTerm(tout);
2615 if (mask & SUB_ATOM_HAS_SIZE) {
2616 if (len != strlen_utf8(sm) ) {
2619 len = strlen_utf8(sm);
2622 if (sz != minv+len+after) {
2625 return do_cut(check_sub_string_at(
2627 }
else if ((mask & (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_VAL)) ==
2628 (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_VAL)) {
2629 if (! Yap_unify(ARG4,MkIntegerTerm(sz-minv-len)) )
2632 return do_cut(check_sub_string_at(
2633 minv, p, RepAtom(AtomOfTerm(tout))->UStrOfAE, len));
2635 return do_cut(check_sub_string_at(minv, p, UStringOfTerm(tout), len));
2636 }
else if ((mask & (SUB_ATOM_HAS_AFTER | SUB_ATOM_HAS_VAL)) ==
2637 (SUB_ATOM_HAS_AFTER | SUB_ATOM_HAS_VAL)) {
2638 if (! Yap_unify(ARG2,MkIntegerTerm(sz-after-len)) )
2641 return do_cut(check_sub_string_bef(
2642 sz - after, p, RepAtom(AtomOfTerm(tout))->UStrOfAE));
2644 return do_cut(check_sub_string_bef(sz - after, p, UStringOfTerm(tout)));}
2645 }
else if ((mask & (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_SIZE)) ==
2646 (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_SIZE)) {
2647 if (minv + len + after > sz) {
2650 if ((Int)(after = (sz - (minv + len))) < 0) {
2653 nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2657 return do_cut(Yap_unify(ARG4, MkIntegerTerm(after)) &&
2658 Yap_unify(ARG5, nat));
2659 }
else if ((mask & (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_AFTER)) ==
2660 (SUB_ATOM_HAS_MIN | SUB_ATOM_HAS_AFTER)) {
2661 if (sz < minv + after) {
2664 len = sz - (minv + after);
2665 int l = push_text_stack();
2666 nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2671 return do_cut(Yap_unify(ARG3, MkIntegerTerm(len)) &&
2672 Yap_unify(ARG5, nat));
2673 }
else if ((mask & (SUB_ATOM_HAS_SIZE | SUB_ATOM_HAS_AFTER)) ==
2674 (SUB_ATOM_HAS_SIZE | SUB_ATOM_HAS_AFTER)) {
2675 if (len + after > sz) {
2678 minv = sz - (len + after);
2679 int l = push_text_stack();
2680 nat = build_new_atomic(mask, p, minv, len PASS_REGS);
2685 return do_cut(Yap_unify(ARG2, MkIntegerTerm(minv)) &&
2686 Yap_unify(ARG5, nat));
2687 }
else if ((mask & (SUB_ATOM_HAS_SIZE | SUB_ATOM_HAS_VAL)) ==
2688 (SUB_ATOM_HAS_SIZE | SUB_ATOM_HAS_VAL)) {
2690 out = (strlen_utf8(UStringOfTerm(tout)) == len);
2695 out = (strlen(RepAtom(AtomOfTerm(tout))->StrOfAE) == len);
2700 out = out && Yap_unify(ARG1, ARG5) &&
2701 Yap_unify(ARG2, MkIntegerTerm(0)) &&
2702 Yap_unify(ARG4, MkIntegerTerm(0));
2703 }
else if (len > sz) {
2706 mask |= SUB_ATOM_HAS_SIZE;
2718 if (!(mask & SUB_ATOM_HAS_MIN))
2720 if (!(mask & SUB_ATOM_HAS_SIZE))
2722 if (!(mask & SUB_ATOM_HAS_AFTER))
2723 after = sz - (len + minv);
2726 EXTRA_CBACK_ARG(5, 1) = MkIntegerTerm(mask);
2727 EXTRA_CBACK_ARG(5, 2) = MkIntegerTerm(minv);
2728 EXTRA_CBACK_ARG(5, 3) = MkIntegerTerm(len);
2729 EXTRA_CBACK_ARG(5, 4) = MkIntegerTerm(after);
2730 EXTRA_CBACK_ARG(5, 5) = MkIntegerTerm(sz);
2731 return cont_sub_atomic(PASS_REGS1);
2749static Int sub_atom(USES_REGS1) {
return (sub_atomic(
true,
false PASS_REGS)); }
2766static Int sub_string(USES_REGS1) {
return sub_atomic(
false,
true PASS_REGS); }
2772static Int sub_text(USES_REGS1) {
return sub_atomic(
false,
false PASS_REGS); }
2775static Int cont_current_atom(USES_REGS1) {
2777 Int i = IntOfTerm(EXTRA_CBACK_ARG(1, 2));
2781 if (IsAtomTerm(EXTRA_CBACK_ARG(1, 1)))
2782 catom = AtomOfTerm(EXTRA_CBACK_ARG(1, 1));
2788 while (i < AtomHashTableSize) {
2789 READ_LOCK(HashChain[i].AERWLock);
2790 catom = HashChain[i].Entry;
2791 READ_UNLOCK(HashChain[i].AERWLock);
2797 if (i == AtomHashTableSize) {
2801 ap = RepAtom(catom);
2802 if (Yap_unify_constant(ARG1, MkAtomTerm(catom))) {
2803 READ_LOCK(ap->ARWLock);
2804 if (ap->NextOfAE == NIL) {
2805 READ_UNLOCK(ap->ARWLock);
2807 while (i < AtomHashTableSize) {
2808 READ_LOCK(HashChain[i].AERWLock);
2809 catom = HashChain[i].Entry;
2810 READ_UNLOCK(HashChain[i].AERWLock);
2816 if (i == AtomHashTableSize) {
2819 EXTRA_CBACK_ARG(1, 1) = MkAtomTerm(catom);
2822 EXTRA_CBACK_ARG(1, 1) = MkAtomTerm(ap->NextOfAE);
2823 READ_UNLOCK(ap->ARWLock);
2825 EXTRA_CBACK_ARG(1, 2) = MkIntTerm(i);
2832static Int current_atom(USES_REGS1) {
2834 Term t1 = Deref(ARG1);
2835 if (!!Yap_IsGroundTerm(t1)) {
2836 if (IsAtomTerm(t1)) {
2841 READ_LOCK(HashChain[0].AERWLock);
2842 if (HashChain[0].Entry != NIL) {
2843 EXTRA_CBACK_ARG(1, 1) = MkAtomTerm(HashChain[0].Entry);
2845 EXTRA_CBACK_ARG(1, 1) = MkIntTerm(0);
2847 READ_UNLOCK(HashChain[0].AERWLock);
2848 EXTRA_CBACK_ARG(1, 2) = MkIntTerm(0);
2849 return (cont_current_atom(PASS_REGS1));
2852void Yap_InitBackAtoms(
void) {
2853 Yap_InitCPredBack(
"$current_atom", 1, 2, current_atom, cont_current_atom,
2854 SafePredFlag | SyncPredFlag);
2855 Yap_InitCPredBack(
"non_det_atom_concat", 3, 2, non_det_atom_concat3, cont_atom_concat3, 0);
2856 Yap_InitCPredBack(
"atomic_concat", 3, 2, atomic_concat3, cont_atomic_concat3,
2858 Yap_InitCPredBack(
"string_concat", 3, 2, string_concat3, cont_string_concat3,
2860 Yap_InitCPredBack(
"sub_atom", 5, 5, sub_atom, cont_sub_atomic, 0);
2861 Yap_InitCPredBack(
"sub_string", 5, 5, sub_string, cont_sub_atomic, 0);
2862 Yap_InitCPredBack(
"sub_text", 5, 5, sub_text, cont_sub_atomic, 0);
2863 Yap_InitCPredBack(
"string_code", 3, 1, string_code3, cont_string_code3, 0);
2866void Yap_InitAtomPreds(
void) {
2867 Yap_InitCPred(
"name", 2, name, 0);
2868 Yap_InitCPred(
"det_atom_concat", 4, det_atom_concat3, SafePredFlag);
2869 Yap_InitCPred(
"string_to_atom", 2, string_to_atom, 0);
2870 Yap_InitCPred(
"atom_to_string", 2, atom_to_string, 0);
2871 Yap_InitCPred(
"string_to_atomic", 2, string_to_atomic, 0);
2872 Yap_InitCPred(
"atomic_to_string", 2, atomic_to_string, 0);
2873 Yap_InitCPred(
"string_to_list", 2, string_to_list, 0);
2874 Yap_InitCPred(
"char_code", 2, char_code, SafePredFlag);
2875 Yap_InitCPred(
"atom_chars", 2, atom_chars, 0);
2876 Yap_InitCPred(
"atom_codes", 2, atom_codes, 0);
2877 Yap_InitCPred(
"atom_string", 2, atom_string, 0);
2878 Yap_InitCPred(
"string_atom", 2, string_atom, 0);
2879 Yap_InitCPred(
"string_codes", 2, string_codes, 0);
2880 Yap_InitCPred(
"string_chars", 2, string_chars, 0);
2881 Yap_InitCPred(
"atom_length", 2, atom_length, SafePredFlag);
2882 Yap_InitCPred(
"atomic_length", 2, atomic_length, SafePredFlag);
2883 Yap_InitCPred(
"string_length", 2, string_length, SafePredFlag);
2884 Yap_InitCPred(
"$atom_split", 4, atom_split, SafePredFlag);
2885 Yap_InitCPred(
"number_chars", 2, number_chars, 0);
2886 Yap_InitCPred(
"number_atom", 2, number_atom, 0);
2887 Yap_InitCPred(
"number_string", 2, number_string, 0);
2888 Yap_InitCPred(
"number_codes", 2, number_codes, 0);
2889 Yap_InitCPred(
"atom_number", 2, atom_number, 0);
2890 Yap_InitCPred(
"string_number", 2, string_number, 0);
2891 Yap_InitCPred(
"$atom_concat", 2, atom_concat2, 0);
2892 Yap_InitCPred(
"$string_concat", 2, string_concat2, 0);
2893 Yap_InitCPred(
"atomic_concat", 2, atomic_concat2, 0);
2894 Yap_InitCPred(
"atomics_to_string", 2, atomics_to_string2, 0);
2895 Yap_InitCPred(
"atomics_to_string", 3, atomics_to_string3, 0);
2896 Yap_InitCPred(
"get_string_code", 3, get_string_code3, 0);
2898 Yap_InitCPred(
"downcase_text_to_atom", 2, downcase_text_to_atom, 0);
2899 Yap_InitCPred(
"downcase_atom", 2, downcase_text_to_atom, 0);
2900 Yap_InitCPred(
"upcase_text_to_atom", 2, upcase_text_to_atom, 0);
2901 Yap_InitCPred(
"upcase_atom", 2, upcase_text_to_atom, 0);
2902 Yap_InitCPred(
"downcase_text_to_string", 2, downcase_text_to_string, 0);
2903 Yap_InitCPred(
"upcase_text_to_string", 2, upcase_text_to_string, 0);
2904 Yap_InitCPred(
"downcase_text_to_codes", 2, downcase_text_to_codes, 0);
2905 Yap_InitCPred(
"upcase_text_to_codes", 2, upcase_text_to_codes, 0);
2906 Yap_InitCPred(
"downcase_text_to_chars", 2, downcase_text_to_chars, 0);
2907 Yap_InitCPred(
"upcase_text_to_chars", 2, upcase_text_to_chars, 0);
2910 Yap_InitCPred(
"hide_atom", 1, hide_atom, SafePredFlag | SyncPredFlag);
2911 Yap_InitCPred(
"hide", 1, hide_atom, SafePredFlag | SyncPredFlag);
2912 Yap_InitCPred(
"unhide_atom", 1, unhide_atom, SafePredFlag | SyncPredFlag);
2913 Yap_InitCPred(
"$hidden_atom", 1, hidden_atom,
2914 HiddenPredFlag | SafePredFlag | SyncPredFlag);
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block