This commit is contained in:
Vitor Santos Costa 2019-01-25 08:57:13 +00:00
parent bfe5fc2f49
commit 650653cc64
3 changed files with 100 additions and 65 deletions

View File

@ -60,6 +60,7 @@ typedef struct non_single_struct_t {
pt0 = ptd0; \ pt0 = ptd0; \
*ptd0 = TermFreeTerm; \ *ptd0 = TermFreeTerm; \
pt0_end = pt0 + 1; \ pt0_end = pt0 + 1; \
if (pt0 <= pt0_end) \
goto list_loop; \ goto list_loop; \
} else if (IsApplTerm(d0)) { \ } else if (IsApplTerm(d0)) { \
register Functor f; \ register Functor f; \
@ -293,7 +294,6 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
if (HR > ASP - MIN_ARENA_SIZE) { if (HR > ASP - MIN_ARENA_SIZE) {
goto overflow; goto overflow;
} }
ptd0 = pt0;
goto deref; goto deref;
} else if (IsApplTerm(d0)) { } else if (IsApplTerm(d0)) {
Functor f; Functor f;
@ -337,7 +337,6 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
} }
*ptf = AbsAppl(HR); *ptf = AbsAppl(HR);
ptf++; ptf++;
ptf = HR;
if (IsExtensionFunctor(f)) { if (IsExtensionFunctor(f)) {
switch ((CELL)f) { switch ((CELL)f) {
@ -415,15 +414,16 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
TrailedMaBind(ptf,AbsAppl(HR)); TrailedMaBind(ptf,AbsAppl(HR));
} }
ptf = HR; ptf = HR;
ptf[-1] = (CELL)f; ptf[0] = (CELL)f;
ground = true; ground = true;
arity_t a = ArityOfFunctor(f); arity_t a = ArityOfFunctor(f);
HR = ptf+a; if (HR > ASP - MIN_ARENA_SIZE) {
if (HR > ASP - MIN_ARENA_SIZE) {
goto overflow; goto overflow;
} }
pt0 = headp; ptf++;
pt0_end = headp+a; HR = ptf+a;
pt0_end = headp+(a);
pt0 = headp;
ground = (f != FunctorMutable); ground = (f != FunctorMutable);
} else { } else {
/* just copy atoms or integers */ /* just copy atoms or integers */
@ -436,10 +436,10 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
ground = false; ground = false;
/* don't need to copy variables if we want to share the global term */ /* don't need to copy variables if we want to share the global term */
if (//(share && ptd0 < HB && ptd0 > H0) || if (//(share && ptd0 < HB && ptd0 > H0) ||
(ptd0 >= HLow && ptd0 < HR)) { (ptd0 >= HB && ptd0 < HR)) {
/* we have already found this cell */ /* we have already found this cell */
*ptf++ = (CELL)ptd0; *ptf++ = (CELL)ptd0;
} else { } else
if (copy_att_vars && GlobalIsAttachedTerm((CELL)ptd0)) { if (copy_att_vars && GlobalIsAttachedTerm((CELL)ptd0)) {
/* if unbound, call the standard copy term routine */ /* if unbound, call the standard copy term routine */
struct cp_frame *bp; struct cp_frame *bp;
@ -463,12 +463,12 @@ int Yap_copy_complex_term(register CELL *pt0, register CELL *pt0_end,
} else { } else {
/* first time we met this term */ /* first time we met this term */
RESET_VARIABLE(ptf); RESET_VARIABLE(ptf);
if ((ADDR)TR > LOCAL_TrailTop - MIN_ARENA_SIZE) if ((ADDR)TR > LOCAL_TrailTop - 16)
goto trail_overflow; goto trail_overflow;
DO_TRAIL(ptd0, (CELL)ptf); DO_TRAIL(ptd0, (CELL)ptf);
*ptd0 = (CELL)ptf; *ptd0 = (CELL)ptf;
ptf++; ptf++;
} continue;
} }
} }
@ -2069,7 +2069,7 @@ p_term_attvars( USES_REGS1 ) /* variables in term t */
Term t = Deref(ARG1); Term t = Deref(ARG1);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
out = attvars_in_complex_term(VarOfTerm(t)-1, out = attvars_in_complex_term(VarOfTerm(t)-1,
VarOfTerm(t)+1, TermNil PASS_REGS); VarOfTerm(t), TermNil PASS_REGS);
} else if (IsPrimitiveTerm(t)) { } else if (IsPrimitiveTerm(t)) {
return Yap_unify(TermNil, ARG2); return Yap_unify(TermNil, ARG2);
} else if (IsPairTerm(t)) { } else if (IsPairTerm(t)) {
@ -2080,9 +2080,11 @@ p_term_attvars( USES_REGS1 ) /* variables in term t */
Functor f = FunctorOfTerm(t); Functor f = FunctorOfTerm(t);
if (IsExtensionFunctor(f)) if (IsExtensionFunctor(f))
return Yap_unify(TermNil, ARG2); return Yap_unify(TermNil, ARG2);
RepAppl(t)[0] = TermNil;
out = attvars_in_complex_term(RepAppl(t), out = attvars_in_complex_term(RepAppl(t),
RepAppl(t)+ RepAppl(t)+
ArityOfFunctor(f), TermNil PASS_REGS); ArityOfFunctor(f), TermNil PASS_REGS);
RepAppl(t)[0] = (CELL)f;
} }
if (out == 0L) { if (out == 0L) {
if (!expand_vts( 3 PASS_REGS )) if (!expand_vts( 3 PASS_REGS ))

119
C/write.c
View File

@ -77,7 +77,8 @@ typedef struct write_globs {
int last_atom_minus; int last_atom_minus;
UInt MaxDepth, MaxArgs; UInt MaxDepth, MaxArgs;
wtype lw; wtype lw;
int sl0; yhandle_t sl0, sl;
bool protectedEntry;
} wglbs; } wglbs;
#define lastw wglb->lw #define lastw wglb->lw
@ -101,22 +102,9 @@ static bool callPortray(Term t, int sno USES_REGS) {
return false; return false;
} }
#define PROTECT(t, F) \ #define PROTECT(t, F) \
{ \ { \
yhandle_t yt = Yap_InitHandle(t); \ F; \
if (wglb->Write_Loops) { \
yhandle_t i; \
for (i = yt - 1; i >= wglb->sl0; i--) { \
if (Yap_GetFromHandle(i) == t) { \
char buf[63]; \
snprintf(buf, 63, " @{ ^^%ld } ", yt - i); \
wrputs(buf, wglb->stream); \
return; \
} \
} \
} \
F; \
t = Yap_PopHandle(yt); \
} }
static void wrputn(Int, struct write_globs *); static void wrputn(Int, struct write_globs *);
static void wrputf(Float, struct write_globs *); static void wrputf(Float, struct write_globs *);
@ -129,6 +117,9 @@ static void putAtom(Atom, int, struct write_globs *);
static void writeTerm(Term, int, int, int, struct write_globs *, static void writeTerm(Term, int, int, int, struct write_globs *,
struct rewind_term *); struct rewind_term *);
static void write_list(Term t, int direction, int depth,
struct write_globs *wglb, struct rewind_term *rwt);
#define wrputc(WF, X) \ #define wrputc(WF, X) \
(X)->stream_wputc(X - GLOBAL_Stream, WF) /* writes a character */ (X)->stream_wputc(X - GLOBAL_Stream, WF) /* writes a character */
@ -279,7 +270,7 @@ static void writebig(Term t, int p, int depth, int rinfixarg,
return; return;
} else if (big_tag == BIG_RATIONAL) { } else if (big_tag == BIG_RATIONAL) {
Term trat = Yap_RatTermToApplTerm(t); Term trat = Yap_RatTermToApplTerm(t);
PROTECT(t,writeTerm(trat, p, depth, rinfixarg, wglb, rwt)); writeTerm(trat, p, depth, rinfixarg, wglb, rwt);
return; return;
#endif #endif
} else if (big_tag >= USER_BLOB_START && big_tag < USER_BLOB_END) { } else if (big_tag >= USER_BLOB_START && big_tag < USER_BLOB_END) {
@ -393,8 +384,7 @@ int Yap_FormatFloat(Float f, char **s, size_t sz) {
struct write_globs wglb; struct write_globs wglb;
int sno; int sno;
sno = Yap_open_buf_write_stream(GLOBAL_Stream[LOCAL_c_output_stream].encoding, sno = Yap_open_buf_write_stream(GLOBAL_Stream[LOCAL_c_output_stream].encoding, 0);
0);
if (sno < 0) if (sno < 0)
return false; return false;
wglb.lw = separator; wglb.lw = separator;
@ -713,11 +703,11 @@ static void write_var(CELL *t, struct write_globs *wglb,
wrputs("$AT(", wglb->stream); wrputs("$AT(", wglb->stream);
write_var(t, wglb, rwt); write_var(t, wglb, rwt);
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
PROTECT(*l, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt)); PROTECT(*t, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt));
attv = RepAttVar(t); attv = RepAttVar(t);
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
l++; l++;
PROTECT(*l, writeTerm(*l, 999, 1, FALSE, wglb, &nrwt)); writeTerm(*l, 999, 1, FALSE, wglb, &nrwt);
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
wglb->Portray_delays = TRUE; wglb->Portray_delays = TRUE;
@ -730,13 +720,32 @@ static void write_var(CELL *t, struct write_globs *wglb,
} }
} }
static void write_list(Term t, int direction, int depth, static bool check_for_loops(Term t, struct write_globs *wglb)
{
yhandle_t i, sl = wglb->sl;
if ((wglb->Write_Loops)) {
return false;
}
for (i=sl-1; i>wglb->sl0;i--) {
if (Yap_GetFromHandle(i) == t) {
char buf[64];
snprintf(buf,63," @{ ^^%ld } " ,sl-i);
wrputs(buf, wglb->stream);
return true;
}
}
return false;
}
static void write_list__(Term t, yhandle_t sl, int direction, int depth,
struct write_globs *wglb, struct rewind_term *rwt) { struct write_globs *wglb, struct rewind_term *rwt) {
Term ti; Term ti;
struct rewind_term nrwt; struct rewind_term nrwt;
nrwt.parent = rwt; nrwt.parent = rwt;
nrwt.u_sd.s.ptr = 0; nrwt.u_sd.s.ptr = 0;
while (1) { while (1) {
int ndirection; int ndirection;
int do_jump; int do_jump;
@ -751,12 +760,12 @@ static void write_list(Term t, int direction, int depth,
/* make sure we're not trapped in loops */ /* make sure we're not trapped in loops */
if (ndirection > 0) { if (ndirection > 0) {
do_jump = (direction <= 0); do_jump = (direction <= 0);
} else if (ndirection == 0) { } /*else if (ndirection == 0) {
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
putAtom(AtomFoundVar, wglb->Quote_illegal, wglb); putAtom(AtomFoundVar, wglb->Quote_illegal, wglb);
lastw = separator; lastw = separator;
return; return;
} else { } */ else {
do_jump = (direction >= 0); do_jump = (direction >= 0);
} }
if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) { if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) {
@ -779,27 +788,34 @@ static void write_list(Term t, int direction, int depth,
/* we found an infinite loop */ /* we found an infinite loop */
/* keep going on the list */ /* keep going on the list */
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
PROTECT(t,write_list(ti, direction, depth, wglb, &nrwt)); write_list(ti, direction, depth, wglb, &nrwt);
} else if (ti != MkAtomTerm(AtomNil)) { } else if (ti != MkAtomTerm(AtomNil)) {
if (lastw == symbol || lastw == separator) { if (lastw == symbol || lastw == separator) {
wrputc(' ', wglb->stream); wrputc(' ', wglb->stream);
} }
wrputc('|', wglb->stream); wrputc('|', wglb->stream);
lastw = separator; lastw = separator;
PROTECT(ti,writeTerm(ti, 999, depth, FALSE, wglb, &nrwt)); writeTerm(ti, 999, depth, FALSE, wglb, &nrwt);
} }
} }
static void writeTerm(Term t, int p, int depth, int rinfixarg, static void write_list(Term t, int direction, int depth,
struct write_globs *wglb, struct rewind_term *rwt) {
if (check_for_loops(t,wglb)) return;
yhandle_t sl = wglb->sl = Yap_InitHandle(t);
write_list__(t, sl, direction, depth,
wglb, rwt);
Yap_PopHandle(sl);
}
static void writeTerm__(Term t, yhandle_t sl, int p, int depth, int rinfixarg,
struct write_globs *wglb, struct rewind_term *rwt) struct write_globs *wglb, struct rewind_term *rwt)
/* term to write */ /* term to write */
/* context priority */ /* context priority */
{ {
CACHE_REGS CACHE_REGS
struct rewind_term nrwt; struct rewind_term nrwt;
nrwt.parent = rwt;
nrwt.u_sd.s.ptr = 0;
if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) { if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) {
putAtom(Atom3Dots, wglb->Quote_illegal, wglb); putAtom(Atom3Dots, wglb->Quote_illegal, wglb);
return; return;
@ -819,7 +835,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
PROTECT(t, writeTerm(HeadOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt)); PROTECT(t, writeTerm(HeadOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt));
wrputs(",", wglb->stream); wrputs(",", wglb->stream);
PROTECT(t, writeTerm(TailOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(TailOfTerm(t), 999, depth + 1, FALSE, wglb, &nrwt);
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
return; return;
} }
@ -885,7 +901,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
*p++; *p++;
lastw = separator; lastw = separator;
/* cannot use the term directly with the SBA */ /* cannot use the term directly with the SBA */
PROTECT(t, writeTerm(*p, 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(*p, 999, depth + 1, FALSE, wglb, &nrwt);
if (*p) if (*p)
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
argno++; argno++;
@ -913,7 +929,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
} else if (atom == AtomMinus) { } else if (atom == AtomMinus) {
last_minus = TRUE; last_minus = TRUE;
} }
PROTECT(t,writeTerm(tright, rp, depth + 1, TRUE, wglb, &nrwt)); writeTerm(tright, rp, depth + 1, TRUE, wglb, &nrwt);
if (bracket_right) { if (bracket_right) {
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
@ -946,7 +962,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
if (bracket_left) { if (bracket_left) {
wropen_bracket(wglb, TRUE); wropen_bracket(wglb, TRUE);
} }
PROTECT(t,writeTerm(ArgOfTerm(offset, t), lp, depth + 1, rinfixarg, wglb, &nrwt)); writeTerm(ArgOfTerm(offset, t), lp, depth + 1, rinfixarg, wglb, &nrwt);
if (bracket_left) { if (bracket_left) {
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
@ -1011,7 +1027,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
if (bracket_right) { if (bracket_right) {
wropen_bracket(wglb, TRUE); wropen_bracket(wglb, TRUE);
} }
PROTECT(t,writeTerm(ArgOfTerm(2, t), rp, depth + 1, TRUE, wglb, &nrwt)); writeTerm(ArgOfTerm(2, t), rp, depth + 1, TRUE, wglb, &nrwt);
if (bracket_right) { if (bracket_right) {
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
@ -1051,14 +1067,14 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
} else { } else {
wrputs("'$VAR'(", wglb->stream); wrputs("'$VAR'(", wglb->stream);
lastw = separator; lastw = separator;
PROTECT(t,writeTerm(ArgOfTerm(1, t), 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(ArgOfTerm(1, t), 999, depth + 1, FALSE, wglb, &nrwt);
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
} else if (!wglb->Ignore_ops && functor == FunctorBraces) { } else if (!wglb->Ignore_ops && functor == FunctorBraces) {
wrputc('{', wglb->stream); wrputc('{', wglb->stream);
lastw = separator; lastw = separator;
PROTECT(t,writeTerm(ArgOfTerm(1, t), GLOBAL_MaxPriority, depth + 1, FALSE, wglb, writeTerm(ArgOfTerm(1, t), GLOBAL_MaxPriority, depth + 1, FALSE, wglb,
&nrwt)); &nrwt);
wrputc('}', wglb->stream); wrputc('}', wglb->stream);
lastw = separator; lastw = separator;
} else if (atom == AtomArray) { } else if (atom == AtomArray) {
@ -1069,7 +1085,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
wrputs("...", wglb->stream); wrputs("...", wglb->stream);
break; break;
} }
PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt);
if (op != Arity) { if (op != Arity) {
PROTECT(t, writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, PROTECT(t, writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb,
&nrwt)); &nrwt));
@ -1077,7 +1093,7 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
lastw = separator; lastw = separator;
} }
} }
PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt);
wrputc('}', wglb->stream); wrputc('}', wglb->stream);
lastw = separator; lastw = separator;
} else { } else {
@ -1096,12 +1112,22 @@ static void writeTerm(Term t, int p, int depth, int rinfixarg,
wrputc(',', wglb->stream); wrputc(',', wglb->stream);
lastw = separator; lastw = separator;
} }
PROTECT(t,writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt)); writeTerm(ArgOfTerm(op, t), 999, depth + 1, FALSE, wglb, &nrwt);
wrclose_bracket(wglb, TRUE); wrclose_bracket(wglb, TRUE);
} }
} }
} }
static void writeTerm(Term t, int p, int depth, int rinfixarg,
struct write_globs *wglb, struct rewind_term *rwt)
{
if (check_for_loops(t,wglb)) return;
yhandle_t sl = wglb->sl = Yap_InitHandle(t);
writeTerm__(t, sl, p, depth, rinfixarg,
wglb, rwt);
Yap_PopHandle(sl);
}
void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags, void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
int priority) int priority)
/* term to be written */ /* term to be written */
@ -1114,7 +1140,6 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
yhandle_t sls = Yap_CurrentSlot(); yhandle_t sls = Yap_CurrentSlot();
int lvl = push_text_stack(); int lvl = push_text_stack();
wglb.sl0 = sls;
if (t == 0) if (t == 0)
return; return;
if (!mywrite) { if (!mywrite) {
@ -1137,7 +1162,7 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
rwt.parent = NULL; rwt.parent = NULL;
wglb.Ignore_ops = flags & Ignore_ops_f; wglb.Ignore_ops = flags & Ignore_ops_f;
wglb.Write_strings = flags & BackQuote_String_f; wglb.Write_strings = flags & BackQuote_String_f;
wglb.Write_Loops = !(flags &Ignore_cyclics_f); wglb.Write_Loops = flags & YAP_WRITE_HANDLE_CYCLES;
if (!(flags & Ignore_cyclics_f) && false) { if (!(flags & Ignore_cyclics_f) && false) {
Term ts[2]; Term ts[2];
ts[0] = Yap_BreakRational(t, 0, ts + 1, TermNil PASS_REGS); ts[0] = Yap_BreakRational(t, 0, ts + 1, TermNil PASS_REGS);
@ -1149,7 +1174,11 @@ void Yap_plwrite(Term t, StreamDesc *mywrite, int max_depth, int flags,
} }
} }
/* protect slots for portray */ /* protect slots for portray */
yhandle_t sl;
wglb.sl0 = (sl = wglb.sl = Yap_InitHandle(t)) -1;
wglb.protectedEntry = false; \
writeTerm(t, priority, 1, FALSE, &wglb, &rwt); writeTerm(t, priority, 1, FALSE, &wglb, &rwt);
t = Yap_PopHandle(sl); \
if (flags & New_Line_f) { if (flags & New_Line_f) {
if (flags & Fullstop_f) { if (flags & Fullstop_f) {
wrputc('.', wglb.stream); wrputc('.', wglb.stream);

View File

@ -1,7 +1,11 @@
:- X = [X], copy_term(X,Y), writeln(X), writeln(Y), fail. :- X = [], copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X = [_|X], copy_term(X,Y), writeln(X), writeln(Y), fail. :- X = [_A], copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X), copy_term(X,Y), writeln(X), writeln(Y), fail. :- X = [a,A], copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X,X), copy_term(X,Y), writeln(X), writeln(Y), fail. :- X = [X], copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(_,X), copy_term(X,Y), writeln(X), writeln(Y), fail. :- X = [_|X], copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X,[X,X]), copy_term(X,Y), writeln(X), writeln(Y), fail. :- X= f(X), copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X,[X,g(X)]), copy_term(X,Y), writeln(X), writeln(Y), fail. :- X= f(X,X), copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(_,X), copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X,[X,X]), copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X= f(X,[X,g(X)]), copy_term(X,Y), writeln('....'), writeln(X), writeln(Y).
:- X=f(_,X/[X]),copy_term(X,Y), writeln('....'),writeln(X),writeln(Y).