diff --git a/C/absmi.c b/C/absmi.c index 783c15ce7..0d9a357dd 100755 --- a/C/absmi.c +++ b/C/absmi.c @@ -1679,18 +1679,18 @@ Yap_absmi(int inp) *****************************************************************/ /* ensure_space */ - BOp(ensure_space, Osbpi); + BOp(ensure_space, Osbpa); { - Int sz = PREG->u.Osbpi.i; - UInt arity = PREG->u.Osbpi.p->ArityOfPE; + Int sz = PREG->u.Osbpa.i; + UInt arity = PREG->u.Osbpa.p->ArityOfPE; if (Unsigned(H) + sz > Unsigned(YREG)-CreepFlag) { YENV[E_CP] = (CELL) CPREG; YENV[E_E] = (CELL) ENV; #ifdef DEPTH_LIMIT YENV[E_DEPTH] = DEPTH; #endif /* DEPTH_LIMIT */ - SET_ASP(YREG, PREG->u.Osbpi.s); - PREG = NEXTOP(PREG,Osbpi); + SET_ASP(YREG, PREG->u.Osbpa.s); + PREG = NEXTOP(PREG,Osbpa); saveregs(); if (!Yap_gcl(sz, arity, YENV, PREG)) { Yap_Error(OUT_OF_STACK_ERROR,TermNil,LOCAL_ErrorMessage); @@ -1700,7 +1700,7 @@ Yap_absmi(int inp) setregs(); } } else { - PREG = NEXTOP(PREG,Osbpi); + PREG = NEXTOP(PREG,Osbpa); } } JMPNext(); diff --git a/C/amasm.c b/C/amasm.c index 04753e537..72c54d7d1 100755 --- a/C/amasm.c +++ b/C/amasm.c @@ -1104,12 +1104,12 @@ a_ensure_space(op_numbers opcode, yamop *code_p, int pass_no, struct intermediat if (cip->cpc->rnd1 > 4096) { if (pass_no) { code_p->opc = emit_op(opcode); - code_p->u.Osbpi.i = sizeof(CELL) * cip->cpc->rnd1; - code_p->u.Osbpi.p = clinfo->CurrentPred; - code_p->u.Osbpi.bmap = NULL; - code_p->u.Osbpi.s = emit_count(-Signed(RealEnvSize)); + code_p->u.Osbpa.i = sizeof(CELL) * cip->cpc->rnd1; + code_p->u.Osbpa.p = clinfo->CurrentPred; + code_p->u.Osbpa.bmap = NULL; + code_p->u.Osbpa.s = emit_count(-Signed(RealEnvSize)); } - GONEXT(Osbpi); + GONEXT(Osbpa); } return code_p; } diff --git a/C/init.c b/C/init.c index 17d8e2358..95336e9d6 100755 --- a/C/init.c +++ b/C/init.c @@ -391,8 +391,6 @@ update_flags_from_prolog(UInt flags, PredEntry *pe) flags |= SourcePredFlag; if (pe->PredFlags & SequentialPredFlag) flags |= SequentialPredFlag; - if (pe->PredFlags & MyddasPredFlag) - flags |= MyddasPredFlag; if (pe->PredFlags & UDIPredFlag) flags |= UDIPredFlag; if (pe->PredFlags & ModuleTransparentPredFlag) diff --git a/C/qly.c b/C/qly.c new file mode 100644 index 000000000..929c2a6c8 --- /dev/null +++ b/C/qly.c @@ -0,0 +1,334 @@ +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- * +* * +************************************************************************** +* * +* File: stdpreds.c * +* comments: quick saver/loader * +* * +* Last rev: $Date: 2011-08-29$,$Author: vsc $ * +* $Log: not supported by cvs2svn $ * +* * +*************************************************************************/ + +#include "config.h" +#if HAVE_STRING_H +#include +#endif +#include +#include +#include +#include + +#define NEXTOP(V,TYPE) ((yamop *)(&((V)->u.TYPE.next))) + +typedef enum { + QLF_START_CLAUSE, + QLF_END_CLAUSES, + QLF_CONSTANT_INT, + QLF_CONSTANT_ATOM, + QLF_ATOM, + QLF_WIDE_ATOM +} qlf_tag_t; + +#define CHECK(F) { size_t r = (F); if (!r) return r; } + +static size_t save_bytes(IOSTREAM *stream, void *ptr, size_t sz) +{ + return Sfwrite(ptr, sz, 1, stream); +} + +static size_t save_term(IOSTREAM *stream, Term t) +{ + size_t len = Yap_ExportTerm(t, (char *)H, sizeof(CELL)*(ASP-H)); + if (len <= 0) return 0; + return save_bytes(stream, (char *)H, len); +} + +static size_t save_tag(IOSTREAM *stream, qlf_tag_t tag) +{ + return save_bytes(stream, &tag, sizeof(qlf_tag_t)); +} + +static size_t save_pointer(IOSTREAM *stream, void *ptr) +{ + void *p = ptr; + return save_bytes(stream, &p, sizeof(void *)); +} + +static size_t save_uint(IOSTREAM *stream, UInt val) +{ + UInt v = val; + return save_bytes(stream, &v, sizeof(UInt)); +} + +static size_t save_int(IOSTREAM *stream, Int val) +{ + Int v = val; + return save_bytes(stream, &v, sizeof(Int)); +} + +static size_t save_atom(IOSTREAM *stream, Atom at) +{ + if (IsWideAtom(at)) { + size_t sz = wcslen(RepAtom(at)->WStrOfAE); + CHECK(save_tag(stream, QLF_WIDE_ATOM)); + CHECK(save_uint(stream, sz)); + return save_bytes(stream, RepAtom(at)->WStrOfAE, (sz+1)*sizeof(wchar_t)); + } else { + size_t sz = strlen(RepAtom(at)->StrOfAE); + CHECK(save_tag(stream, QLF_ATOM)); + return save_bytes(stream, RepAtom(at)->StrOfAE, (sz+1)*sizeof(char)); + } +} + +static size_t save_Arity(IOSTREAM *stream, Int a) +{ + return save_uint(stream, a); +} + +static size_t save_CellPtoHeap(IOSTREAM *stream, CELL *ptr) +{ + return save_pointer(stream, ptr); +} + +static size_t save_ConstantTerm(IOSTREAM *stream, Term t) +{ + if (IsIntTerm(t)) { + CHECK(save_tag(stream, QLF_CONSTANT_INT)); + return save_int(stream, IntOfTerm(t)); + } + CHECK(save_tag(stream, QLF_CONSTANT_ATOM)); + return save_atom(stream, AtomOfTerm(t)); +} + +static size_t save_DoubleInCode(IOSTREAM *stream, CELL *t) +{ + return save_bytes(stream, (void *)(t+1), sizeof(double)); +} + +static size_t save_Constant(IOSTREAM *stream, COUNT c) +{ + return save_bytes(stream, (void *)&c, sizeof(COUNT)); +} + +static size_t save_DBGroundTerm(IOSTREAM *stream, Term t) +{ + return save_term(stream, t); +} + +static size_t save_Func(IOSTREAM *stream, Functor f) +{ + CHECK(save_atom(stream, NameOfFunctor(f))); + return save_Arity(stream, ArityOfFunctor(f)); +} + +static size_t save_ExternalFunction(IOSTREAM *stream, CPredicate f) +{ + Yap_Error(INTERNAL_ERROR, TermNil, "trying to save an ExternalFunction"); + return 0; +} + +static size_t save_IntegerInCode(IOSTREAM *stream, CELL *t) +{ + return save_int(stream, t[1]); +} + +static size_t save_Integer(IOSTREAM *stream, Int i) +{ + return save_int(stream, i); +} + +static size_t save_PtoLUIndex(IOSTREAM *stream, struct logic_upd_index *p) +{ + Yap_Error(INTERNAL_ERROR, TermNil, "trying to save PtoLUIndex"); + return 0; +} + +static size_t save_PtoOp(IOSTREAM *stream, yamop *l) +{ + return save_pointer(stream, (void *)l); +} + +static size_t save_PtoLUClause(IOSTREAM *stream, struct logic_upd_clause *t) +{ + Yap_Error(INTERNAL_ERROR, TermNil, "trying to save PtoLUIndex"); + return 0; +} + +static size_t save_BlobTermInCode(IOSTREAM *stream, Term t) +{ + return save_pointer(stream, (void *)RepAppl(t)); +} + +static size_t save_Opcode(IOSTREAM *stream, OPCODE op) +{ + return save_int(stream, Yap_op_from_opcode(op)); +} + +#ifdef YAPOR +static size_t save_OrArg(IOSTREAM *stream, unsigned int i) +{ + return save_uint(stream, i); +} +#endif /* YAPOR */ + +static size_t save_PtoPred(IOSTREAM *stream, struct pred_entry *ap) +{ + if (ap->ModuleOfPred) { + CHECK(save_atom(stream, AtomOfTerm(ap->ModuleOfPred))); + } else { + CHECK(save_atom(stream, AtomProlog)); + } + if (ap->ArityOfPE) { + CHECK(save_int(stream, ap->ArityOfPE)); + return save_atom(stream, NameOfFunctor(ap->FunctorOfPred)); + } else { + CHECK(save_int(stream, 0)); + return save_atom(stream, (Atom)(ap->FunctorOfPred)); + } +} + +static size_t save_Module(IOSTREAM *stream, Term tmod) +{ + if (tmod == 0) { + return save_atom(stream, AtomProlog); + } else { + return save_atom(stream, AtomOfTerm(tmod)); + } +} + +#ifdef TABLING +static size_t save_TabEntry(IOSTREAM *stream, struct table_entry *ap) +{ + return save_pointer(stream, NULL); +} +#endif + +#if PRECOMPUTE_REGADDRESS +#define arg_from_x(I) (((CELL *)(I))-XREGS) +#else +#define arg_from_x(I) (I) +#endif /* PRECOMPUTE_REGADDRESS */ + +static size_t save_X(IOSTREAM *stream, wamreg reg) +{ + return save_int(stream, arg_from_x(reg)); +} + +static size_t save_Y(IOSTREAM *stream, yslot reg) +{ + return save_int(stream, reg); +} + +static size_t +save_code(IOSTREAM *stream, yamop *pc, yamop *max) { +#include "saveclause.h" + if (max && max > pc) { + return save_bytes(stream, pc, (char *)max-(char *)pc); + } + return 1; +} + +static size_t +save_lu_clause(IOSTREAM *stream, LogUpdClause *cl) { + CHECK(save_tag(stream, QLF_START_CLAUSE)); + CHECK(save_term(stream, cl->ClSource->Entry)); + return save_code(stream, cl->ClCode, (yamop *)cl->ClSource); +} + +static size_t +save_dynamic_clause(IOSTREAM *stream, DynamicClause *cl) { + CHECK(save_tag(stream, QLF_START_CLAUSE)); + return save_code(stream, cl->ClCode, NULL); +} + +static size_t +save_static_clause(IOSTREAM *stream, StaticClause *cl) { + CHECK(save_tag(stream, QLF_START_CLAUSE)); + if (!(cl->ClFlags & FactMask)) { + CHECK(save_term(stream, cl->usc.ClSource->Entry)); + return save_code(stream, cl->ClCode, (yamop *)(cl->usc.ClSource)); + } else { + return save_code(stream, cl->ClCode, NULL); + } +} + +static size_t +save_mega_clause(IOSTREAM *stream, MegaClause *cl) { + UInt i; + yamop *ptr; + UInt ncls = cl->ClPred->cs.p_code.NOfClauses; + + for (i = 0, ptr = cl->ClCode; i < ncls; i++) { + yamop *nextptr = (yamop *)((char *)ptr + cl->ClItemSize); + CHECK(save_tag(stream, QLF_START_CLAUSE)); + CHECK(save_code(stream, ptr, nextptr)); + ptr = nextptr; + } + return 1; +} + +static size_t +save_clauses(IOSTREAM *stream, PredEntry *pp) { + yamop *FirstC, *LastC; + + FirstC = pp->cs.p_code.FirstClause; + LastC = pp->cs.p_code.LastClause; + if (FirstC == NULL && LastC == NULL) { + return save_tag(stream, QLF_END_CLAUSES); + } + if (pp->PredFlags & LogUpdatePredFlag) { + LogUpdClause *cl = ClauseCodeToLogUpdClause(FirstC); + + while (cl != NULL) { + CHECK(save_lu_clause(stream, cl)); + cl = cl->ClNext; + } + } else if (pp->PredFlags & MegaClausePredFlag) { + MegaClause *cl = ClauseCodeToMegaClause(FirstC); + + CHECK(save_mega_clause(stream, cl)); + } else if (pp->PredFlags & DynamicPredFlag) { + yamop *cl = FirstC; + + do { + CHECK(save_dynamic_clause(stream, ClauseCodeToDynamicClause(cl))); + if (cl == LastC) return 1; + cl = NextDynamicClause(cl); + } while (TRUE); + } else { + StaticClause *cl = ClauseCodeToStaticClause(FirstC); + + do { + CHECK(save_static_clause(stream, cl)); + if (cl->ClCode == LastC) return 1; + cl = cl->ClNext; + } while (TRUE); + } + return save_tag(stream, QLF_END_CLAUSES); +} + +static size_t +save_pred(IOSTREAM *stream, PredEntry *ap) { + CHECK(save_Func(stream, ap->FunctorOfPred)); + CHECK(save_uint(stream, ap->ArityOfPE)); + CHECK(save_uint(stream, ap->PredFlags)); + CHECK(save_uint(stream, ap->cs.p_code.NOfClauses)); + return save_clauses(stream, ap); +} + +size_t +save_module(IOSTREAM *stream, Term mod) { + PredEntry *ap = Yap_ModulePred(mod); + while (ap) { + CHECK(save_pred(stream, ap)); + ap = ap->NextPredOfModule; + } +} + diff --git a/H/YapOpcodes.h b/H/YapOpcodes.h index 2515b3bba..0710fd7cf 100644 --- a/H/YapOpcodes.h +++ b/H/YapOpcodes.h @@ -24,7 +24,7 @@ OPCODE(alloc_for_logical_pred ,L), OPCODE(copy_idb_term ,e), OPCODE(unify_idb_term ,e), - OPCODE(ensure_space ,Osbpi), + OPCODE(ensure_space ,Osbpa), OPCODE(spy_or_trymark ,Otapl), OPCODE(try_and_mark ,Otapl), OPCODE(count_retry_and_mark ,Otapl), diff --git a/H/Yatom.h b/H/Yatom.h index 4add68733..f79e1bb78 100755 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -674,7 +674,7 @@ typedef enum TabledPredFlag = 0x00000040L, /* is tabled */ SequentialPredFlag = 0x00000020L, /* may not create parallel choice points! */ ProfiledPredFlag = 0x00000010L, /* pred is being profiled */ - MyddasPredFlag = 0x00000008L, /* Myddas Imported pred */ + /* MyddasPredFlag = 0x00000008L, Myddas Imported pred */ ModuleTransparentPredFlag = 0x00000004L, /* ModuleTransparent pred */ SWIEnvPredFlag = 0x00000002L, /* new SWI interface */ UDIPredFlag = 0x00000001L /* User Defined Indexing */ @@ -708,7 +708,7 @@ typedef struct pred_entry struct yami *CodeOfPred; OPCODE OpcodeOfPred; /* undefcode, indexcode, spycode, .... */ CELL PredFlags; - unsigned int ArityOfPE; /* arity of property */ + UInt ArityOfPE; /* arity of property */ union { struct diff --git a/H/amidefs.h b/H/amidefs.h index 6a99d1621..cf424bc22 100644 --- a/H/amidefs.h +++ b/H/amidefs.h @@ -693,7 +693,7 @@ typedef struct yami { struct pred_entry *p; Int i; CELL next; - } Osbpi; + } Osbpa; struct { #ifdef YAPOR unsigned int or_arg; diff --git a/H/findclause.h b/H/findclause.h index bcc965c75..4a5c4199a 100644 --- a/H/findclause.h +++ b/H/findclause.h @@ -16,7 +16,7 @@ cl = NEXTOP(cl,N); break; case _ensure_space: - cl = NEXTOP(cl,Osbpi); + cl = NEXTOP(cl,Osbpa); break; case _native_me: cl = NEXTOP(cl,aFlp); diff --git a/H/rclause.h b/H/rclause.h index a701f1dc4..9541aa78b 100644 --- a/H/rclause.h +++ b/H/rclause.h @@ -60,14 +60,14 @@ restore_opcodes(yamop *pc, yamop *max USES_REGS) pc->u.Osbmp.p0 = PtoPredAdjust(pc->u.Osbmp.p0); pc = NEXTOP(pc,Osbmp); break; - /* instructions type Osbpi */ + /* instructions type Osbpa */ case _ensure_space: - OrArgAdjust(pc->u.Osbpi.or_arg); - pc->u.Osbpi.s = ConstantAdjust(pc->u.Osbpi.s); - pc->u.Osbpi.bmap = CellPtoHeapAdjust(pc->u.Osbpi.bmap); - pc->u.Osbpi.p = PtoPredAdjust(pc->u.Osbpi.p); - IntegerInCodeAdjust(pc->u.Osbpi.i); - pc = NEXTOP(pc,Osbpi); + OrArgAdjust(pc->u.Osbpa.or_arg); + pc->u.Osbpa.s = ConstantAdjust(pc->u.Osbpa.s); + pc->u.Osbpa.bmap = CellPtoHeapAdjust(pc->u.Osbpa.bmap); + pc->u.Osbpa.p = PtoPredAdjust(pc->u.Osbpa.p); + pc->u.Osbpa.i = ArityAdjust(pc->u.Osbpa.i); + pc = NEXTOP(pc,Osbpa); break; /* instructions type Osbpp */ case _call: diff --git a/H/walkclause.h b/H/walkclause.h index ad08e3806..286a67e00 100644 --- a/H/walkclause.h +++ b/H/walkclause.h @@ -34,9 +34,9 @@ case _p_execute: pc = NEXTOP(pc,Osbmp); break; - /* instructions type Osbpi */ + /* instructions type Osbpa */ case _ensure_space: - pc = NEXTOP(pc,Osbpi); + pc = NEXTOP(pc,Osbpa); break; /* instructions type Osbpp */ case _call_cpred: diff --git a/Makefile.in b/Makefile.in index 306c886f8..9b812480f 100755 --- a/Makefile.in +++ b/Makefile.in @@ -248,6 +248,7 @@ C_SOURCES= \ $(srcdir)/C/load_shl.c $(srcdir)/C/load_dyld.c \ $(srcdir)/C/mavar.c $(srcdir)/C/modules.c $(srcdir)/C/other.c \ $(srcdir)/C/parser.c \ + $(srcdir)/C/qly.c \ $(srcdir)/C/save.c $(srcdir)/C/scanner.c \ $(srcdir)/C/sort.c $(srcdir)/C/stdpreds.c $(srcdir)/C/sysbits.c \ $(srcdir)/C/threads.c \ @@ -356,7 +357,7 @@ ENGINE_OBJECTS = \ myddas_mysql.o myddas_odbc.o myddas_shared.o myddas_initialization.o \ myddas_util.o myddas_statistics.o myddas_top_level.o \ myddas_wkb2prolog.o modules.o other.o \ - parser.o save.o scanner.o sort.o stdpreds.o \ + parser.o qly.o save.o scanner.o sort.o stdpreds.o \ sysbits.o threads.o tracer.o \ udi.o rtree.o rtree_udi.o\ unify.o userpreds.o utilpreds.o \ @@ -442,6 +443,9 @@ init.o: $(srcdir)/C/init.c config.h load_foreign.o: $(srcdir)/C/load_foreign.c config.h $(CC) -c $(CFLAGS) $(srcdir)/C/load_foreign.c -o $@ +qly.o: $(srcdir)/C/qly.c config.h + $(CC) -c $(CFLAGS) $(srcdir)/C/qly.c -o $@ + save.o: $(srcdir)/C/save.c config.h $(CC) -c $(CFLAGS) $(srcdir)/C/save.c -o $@ diff --git a/misc/buildops b/misc/buildops index 50a24ee44..41343394b 100644 --- a/misc/buildops +++ b/misc/buildops @@ -31,44 +31,51 @@ main :- open('H/walkclause.h',write,L), open('H/findclause.h',write,F), open('H/headclause.h',write,H), + open('H/saveclause.h',write,S), header(W), header_rclause(C), header_walk_clause(L), header_find_clause(F), header_find_clause(H), - file('C/absmi.c', W, C, L, F, H), - start_ifdef("YAPOR", W, C, L, F, H), - file('OPTYap/or.insts.i',W, C, L, F, H), - end_ifdef(W, C, L, F, H), - start_ifdef("TABLING", W, C, L, F, H), - file('OPTYap/tab.insts.i',W,C,L, F, H), + header_save_clause(S), + file('C/absmi.c', W, C, L, F, H, S), + start_ifdef("YAPOR", W, C, L, F, H, S), + file('OPTYap/or.insts.i',W, C, L, F, H, S), + end_ifdef(W, C, L, F, H, S), + start_ifdef("TABLING", W, C, L, F, H, S), + file('OPTYap/tab.insts.i',W,C,L, F, H, S), retractall(op(_,_)), - file('OPTYap/tab.tries.insts.i', W, C, L, F, H), - end_ifdef(W, C, L, F, H), + file('OPTYap/tab.tries.insts.i', W, C, L, F, H, S), + end_ifdef(W, C, L, F, H, S), footer(W), footer_rclause(C), footer_walk_clause(L), footer_find_clause(F), footer_find_clause(H), + footer_save_clause(S), close(F), close(L), close(W), - close(C). + close(C), + close(H), + close(S). -start_ifdef(D, W, C, L, F, H) :- +start_ifdef(D, W, C, L, F, H, S) :- retractall(op(_,_)), format(W, '#ifdef ~s~n',[D]), format(C, '#ifdef ~s~n',[D]), format(L, '#ifdef ~s~n',[D]), format(F, '#ifdef ~s~n',[D]), - format(H, '#ifdef ~s~n',[D]). + format(H, '#ifdef ~s~n',[D]), + format(S, '#ifdef ~s~n',[D]). -end_ifdef(W,C,L,F,H) :- +end_ifdef(W,C,L,F,H, S) :- format(W, '#endif~n',[]), format(C, '#endif~n',[]), format(L, '#endif~n',[]), format(F, '#endif~n',[]), - format(H, '#endif~n',[]). + format(H, '#endif~n',[]), + format(S, '#endif~n',[]). header(W) :- format(W,'~n /* This file was generated automatically by \"yap -L misc/buildops\"~n please do not update */~n~n',[]). @@ -101,6 +108,17 @@ header_walk_clause(W) :- switch (op) { ',[]). +header_save_clause(W) :- + format(W,'~n /* This file was generated automatically by \"yap -L misc/buildops\"~n please do not update */~n~n + while (TRUE) { + op_numbers op; + if (max && pc >= max) return 1; + op = Yap_op_from_opcode(pc->opc); + save_Opcode(stream, op); + + /* C-code, maybe indexing */ + switch (op) { +',[]). header_find_clause(W) :- format(W,'~n /* This file was generated automatically by \"yap -L misc/buildops\"~n please do not update */~n~n @@ -110,14 +128,15 @@ header_find_clause(W) :- ',[]). -file(I,W,C,L,F,H) :- +file(I,W,C,L,F,H, S) :- open(I,read,R), process(R,grep_opcode(W)), close(R), output_rclause(C), output_walk_clause(L), output_find_clause(F), - output_head_clause(H). + output_head_clause(H), + output_save_clause(S). grep_opcode(W, Line) :- split(Line," ,();",[OP,Name,Type]), @@ -728,6 +747,12 @@ footer_find_clause(W) :- } }~n',[]). +footer_save_clause(S) :- + format(S,'default: + return -1; + } + }~n',[]). + get_field_names(F) :- open(F, read, A), loop_for_fields(A), @@ -1098,3 +1123,43 @@ opinfo("alloc_for_logical_pred",[body]). opinfo("deallocate",[body]). opinfo("table_try_single",[]). opinfo("native_me",[]). + +output_save_clause(S) :- + setof(T,O^op(T,O),Types), + member(T, Types), + output_save_type(S, T), + fail. +output_save_clause(_). + +output_save_type(S, T) :- + format(S,' /* instructions type ~s */~n',[T]), + setof(Op,op(T,Op),Ops), + dump_ops(S,Ops), + % then the code for every instruction with this header. + tinfo(T, Desc), + output_save(S, T, Desc, T), + format(S,' pc = NEXTOP(pc,~s);~n',[T]), + format(S,' break;~n',[]). + +output_save(S, "e", [], _) :- + format(S, " if (op == _Nstop || op == _copy_idb_term || op == _unify_idb_term) return 1;~n", []). +output_save(_, [], [], _). +output_save(S, [Name|Names], [Type|Types], Desc) :- + output_save_type(S, Name, Type, Desc), + output_save(S, Names, Types, Desc). + +output_save_type(S, OpT, T-"none", Desc) :- !, + get_op(OpT, Name), + format(S, " CHECK(save_~s(stream, pc->u.~s.~s));~n", [Name, Desc, T]). +output_save_type(S, OpT, T-Def, Desc) :- + get_op(OpT, Name), + format(S, "#ifdef ~s~n CHECK(save_~s(stream, pc->u.~s.~s));~n#endif~n", [Def,Name, Desc, T]). + + + + + + + + +