don't loop on cyclic terms.
This commit is contained in:
parent
8e1c8d723e
commit
328e2f5c22
4
C/init.c
4
C/init.c
@ -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);
|
||||||
|
80
C/write.c
80
C/write.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user