don't loop on cyclic terms.

This commit is contained in:
Vitor Santos Costa 2009-05-22 12:24:30 -05:00
parent 8e1c8d723e
commit 328e2f5c22
2 changed files with 63 additions and 21 deletions

View File

@ -1410,14 +1410,14 @@ Yap_InitWorkspace(UInt Heap, UInt Stack, UInt Trail, UInt Atts, UInt max_table_s
NOfWideAtoms = 0; NOfWideAtoms = 0;
PredsInHashTable = 0; PredsInHashTable = 0;
#if THREADS #if THREADS
SF_STORE->AtFoundVar = Yap_LookupAtom("."); SF_STORE->AtFoundVar = Yap_LookupAtom("**");
Yap_ReleaseAtom(AtomFoundVar); Yap_ReleaseAtom(AtomFoundVar);
SF_STORE->AtFreeTerm = Yap_LookupAtom("?"); SF_STORE->AtFreeTerm = Yap_LookupAtom("?");
Yap_ReleaseAtom(AtomFreeTerm); Yap_ReleaseAtom(AtomFreeTerm);
SF_STORE->AtNil = Yap_LookupAtom("[]"); SF_STORE->AtNil = Yap_LookupAtom("[]");
SF_STORE->AtDot = Yap_LookupAtom("."); SF_STORE->AtDot = Yap_LookupAtom(".");
#else #else
Yap_LookupAtomWithAddress(".",&(SF_STORE->AtFoundVar)); Yap_LookupAtomWithAddress("**",&(SF_STORE->AtFoundVar));
Yap_ReleaseAtom(AtomFoundVar); Yap_ReleaseAtom(AtomFoundVar);
Yap_LookupAtomWithAddress("?",&(SF_STORE->AtFreeTerm)); Yap_LookupAtomWithAddress("?",&(SF_STORE->AtFreeTerm));
Yap_ReleaseAtom(AtomFreeTerm); Yap_ReleaseAtom(AtomFreeTerm);

View File

@ -18,6 +18,7 @@
static char SccsId[] = "%W% %G%"; static char SccsId[] = "%W% %G%";
#endif #endif
#include <stdlib.h>
#include "Yap.h" #include "Yap.h"
#include "Yatom.h" #include "Yatom.h"
#include "Heap.h" #include "Heap.h"
@ -44,10 +45,17 @@ static wtype lastw;
typedef int (*wrf) (int, wchar_t); typedef int (*wrf) (int, wchar_t);
typedef struct rewind_term {
struct rewind_term *parent;
Term old;
CELL *ptr;
} rwts;
typedef struct write_globs { typedef struct write_globs {
wrf writewch; wrf writewch;
int Quote_illegal, Ignore_ops, Handle_vars, Use_portray; int Quote_illegal, Ignore_ops, Handle_vars, Use_portray;
int keep_terms; int keep_terms;
int Write_Loops;
UInt MaxDepth, MaxList, MaxArgs; UInt MaxDepth, MaxList, MaxArgs;
} wglbs; } wglbs;
@ -60,7 +68,7 @@ STATIC_PROTO(int LeftOpToProtect, (Atom, int));
STATIC_PROTO(int RightOpToProtect, (Atom, int)); STATIC_PROTO(int RightOpToProtect, (Atom, int));
STATIC_PROTO(wtype AtomIsSymbols, (unsigned char *)); STATIC_PROTO(wtype AtomIsSymbols, (unsigned char *));
STATIC_PROTO(void putAtom, (Atom, int, wrf)); STATIC_PROTO(void putAtom, (Atom, int, wrf));
STATIC_PROTO(void writeTerm, (Term, int, int, int, struct write_globs *)); STATIC_PROTO(void writeTerm, (Term, int, int, int, struct write_globs *, struct rewind_term *));
#define wrputc(X,WF) ((*WF)(Yap_c_output_stream,X)) /* writes a character */ #define wrputc(X,WF) ((*WF)(Yap_c_output_stream,X)) /* writes a character */
@ -383,7 +391,7 @@ putUnquotedString(Term string, wrf writewch) /* writes a string */
static void static void
write_var(CELL *t, struct write_globs *wglb) write_var(CELL *t, struct write_globs *wglb, struct rewind_term *rwt)
{ {
if (lastw == alphanum) { if (lastw == alphanum) {
wrputc(' ', wglb->writewch); wrputc(' ', wglb->writewch);
@ -405,15 +413,15 @@ write_var(CELL *t, struct write_globs *wglb)
Term l = attv->Atts; Term l = attv->Atts;
wrputs("$AT(",wglb->writewch); wrputs("$AT(",wglb->writewch);
write_var(t, wglb); write_var(t, wglb, rwt);
wrputc(',', wglb->writewch); wrputc(',', wglb->writewch);
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot((CELL)attv); sl = Yap_InitSlot((CELL)attv);
} }
writeTerm((Term)&(attv->Value), 999, 1, FALSE, wglb); writeTerm((Term)&(attv->Value), 999, 1, FALSE, wglb, rwt);
wrputc(',', wglb->writewch); wrputc(',', wglb->writewch);
writeTerm(l, 999, 1, FALSE, wglb); writeTerm(l, 999, 1, FALSE, wglb, rwt);
if (wglb->keep_terms) { if (wglb->keep_terms) {
attv = (attvar_record *)Yap_GetFromSlot(sl); attv = (attvar_record *)Yap_GetFromSlot(sl);
Yap_RecoverSlots(1); Yap_RecoverSlots(1);
@ -432,12 +440,31 @@ write_var(CELL *t, struct write_globs *wglb)
} }
} }
static Term
from_pointer(CELL *ptr, struct rewind_term *rwt)
{
Term t;
while (IsVarTerm(*ptr) && *ptr)
ptr = (CELL *)*ptr;
t = *ptr;
rwt->old = t;
rwt->ptr = ptr;
*ptr = TermFoundVar;
return t;
}
static void static void
writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb) writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb, struct rewind_term *rwt)
/* term to write */ /* term to write */
/* context priority */ /* context priority */
{ {
struct rewind_term nrwt;
nrwt.parent = rwt;
nrwt.ptr = NULL;
if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) { if (wglb->MaxDepth != 0 && depth > wglb->MaxDepth) {
putAtom(Atom3Dots, wglb->Quote_illegal, wglb->writewch); putAtom(Atom3Dots, wglb->Quote_illegal, wglb->writewch);
return; return;
@ -446,7 +473,7 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
return; return;
t = Deref(t); t = Deref(t);
if (IsVarTerm(t)) { if (IsVarTerm(t)) {
write_var((CELL *)t, wglb); write_var((CELL *)t, wglb, &nrwt);
} else if (IsIntTerm(t)) { } else if (IsIntTerm(t)) {
wrputn((Int) IntOfTerm(t),wglb->writewch); wrputn((Int) IntOfTerm(t),wglb->writewch);
} else if (IsAtomTerm(t)) { } else if (IsAtomTerm(t)) {
@ -492,7 +519,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(HeadOfTermCell(t), 999, new_depth, FALSE, wglb); writeTerm(from_pointer(RepPair(t), &nrwt), 999, new_depth, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
Yap_RecoverSlots(1); Yap_RecoverSlots(1);
@ -509,7 +537,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
if (ti != MkAtomTerm(AtomNil)) { if (ti != MkAtomTerm(AtomNil)) {
wrputc('|', wglb->writewch); wrputc('|', wglb->writewch);
lastw = separator; lastw = separator;
writeTerm(TailOfTermCell(t), 999, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepPair(t)+1, &nrwt), 999, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
} }
wrputc(']', wglb->writewch); wrputc(']', wglb->writewch);
lastw = separator; lastw = separator;
@ -617,7 +646,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot((CELL)p); sl = Yap_InitSlot((CELL)p);
} }
writeTerm(Deref(p++), 999, depth + 1, FALSE, wglb); writeTerm(from_pointer(p++, &nrwt), 999, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
p = (CELL *)Yap_GetFromSlot(sl); p = (CELL *)Yap_GetFromSlot(sl);
@ -676,7 +706,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
wrputc('(', wglb->writewch); wrputc('(', wglb->writewch);
lastw = separator; lastw = separator;
} }
writeTerm(ArgOfTermCell(1,t), rp, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepAppl(t)+1, &nrwt), rp, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (bracket_right) { if (bracket_right) {
wrputc(')', wglb->writewch); wrputc(')', wglb->writewch);
lastw = separator; lastw = separator;
@ -707,7 +738,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(ArgOfTermCell(1,t), lp, depth + 1, rinfixarg, wglb); writeTerm(from_pointer(RepAppl(t)+1, &nrwt), lp, depth + 1, rinfixarg, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
@ -750,7 +782,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(ArgOfTermCell(1, t), lp, depth + 1, rinfixarg, wglb); writeTerm(from_pointer(RepAppl(t)+1, &nrwt), lp, depth + 1, rinfixarg, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
@ -771,7 +804,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
wrputc('(', wglb->writewch); wrputc('(', wglb->writewch);
lastw = separator; lastw = separator;
} }
writeTerm(ArgOfTermCell(2, t), rp, depth + 1, TRUE, wglb); writeTerm(from_pointer(RepAppl(t)+2, &nrwt), rp, depth + 1, TRUE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (bracket_right) { if (bracket_right) {
wrputc(')', wglb->writewch); wrputc(')', wglb->writewch);
lastw = separator; lastw = separator;
@ -813,7 +847,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(ArgOfTermCell(1,t), 999, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepAppl(t)+1, &nrwt), 999, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
@ -825,7 +860,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
} else if (!wglb->Ignore_ops && functor == FunctorBraces) { } else if (!wglb->Ignore_ops && functor == FunctorBraces) {
wrputc('{', wglb->writewch); wrputc('{', wglb->writewch);
lastw = separator; lastw = separator;
writeTerm(ArgOfTermCell(1, t), 1200, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepAppl(t)+1, &nrwt), 1200, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
wrputc('}', wglb->writewch); wrputc('}', wglb->writewch);
lastw = separator; lastw = separator;
} else if (atom == AtomArray) { } else if (atom == AtomArray) {
@ -844,7 +880,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(ArgOfTermCell(op, t), 999, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepAppl(t)+op, &nrwt), 999, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
@ -874,7 +911,8 @@ writeTerm(Term t, int p, int depth, int rinfixarg, struct write_globs *wglb)
/* garbage collection may be called */ /* garbage collection may be called */
sl = Yap_InitSlot(t); sl = Yap_InitSlot(t);
} }
writeTerm(ArgOfTermCell(op, t), 999, depth + 1, FALSE, wglb); writeTerm(from_pointer(RepAppl(t)+op, &nrwt), 999, depth + 1, FALSE, wglb, &nrwt);
*nrwt.ptr = nrwt.old; nrwt.ptr = NULL;
if (wglb->keep_terms) { if (wglb->keep_terms) {
/* garbage collection may be called */ /* garbage collection may be called */
t = Yap_GetFromSlot(sl); t = Yap_GetFromSlot(sl);
@ -898,6 +936,9 @@ Yap_plwrite(Term t, int (*mywrite) (int, wchar_t), int flags)
/* write options */ /* write options */
{ {
struct write_globs wglb; struct write_globs wglb;
struct rewind_term rwt;
rwt.parent = NULL;
rwt.ptr = NULL;
wglb.writewch = mywrite; wglb.writewch = mywrite;
lastw = separator; lastw = separator;
@ -912,6 +953,7 @@ Yap_plwrite(Term t, int (*mywrite) (int, wchar_t), int flags)
wglb.keep_terms = (flags & (Use_portray_f|To_heap_f)); wglb.keep_terms = (flags & (Use_portray_f|To_heap_f));
wglb.Ignore_ops = flags & Ignore_ops_f; wglb.Ignore_ops = flags & Ignore_ops_f;
/* protect slots for portray */ /* protect slots for portray */
writeTerm(t, 1200, 1, FALSE, &wglb); writeTerm(from_pointer(&t, &rwt), 1200, 1, FALSE, &wglb, &rwt);
*rwt.ptr = rwt.old; rwt.ptr = NULL;
} }