make modules remember which operators they ever defined.

Make modules import operators from other modules
This commit is contained in:
Vitor Santos Costa 2016-04-28 15:01:16 +01:00
parent 61ba15fa3a
commit 70061308ff
8 changed files with 126 additions and 32 deletions

View File

@ -1638,6 +1638,8 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
tf = ArgOfTerm(1, t);
else
tf = t;
tf = Yap_YapStripModule(tf, &mod);
if (IsAtomTerm(tf)) {
at = AtomOfTerm(tf);
p = RepPredProp(PredPropByAtom(at, mod));
@ -1796,11 +1798,6 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
} else {
tf = Yap_MkStaticRefTerm(ClauseCodeToStaticClause(cp), p);
}
if (t4ref && *t4ref != TermNil) {
if (!Yap_unify(*t4ref, tf)) {
return false;
}
}
if (mod == PROLOG_MODULE)
mod = TermProlog;
if (pflags & MultiFileFlag) {
@ -1814,6 +1811,11 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
tn = Yap_MkApplTerm(FunctorMultiFileClause, 5, t);
Yap_Recordz(AtomMultiFile, tn);
}
if (t4ref && *t4ref != TermNil) {
if (!Yap_unify(*t4ref, tf)) {
return false;
}
}
return true;
}

View File

@ -202,10 +202,17 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
AtomEntry *ae = RepAtom(a);
OpEntry *info;
#if defined(MODULE_INDEPENDENT_OPERATORS_FLAG)
if (booleanFlag(MODULE_INDEPENDENT_OPERATORS_FLAG)) {
m = PROLOG_MODULE;
} else
#endif
{
if (m == TermProlog)
m = PROLOG_MODULE;
else if (m == USER_MODULE)
m = PROLOG_MODULE;
m = PROLOG_MODULE;
}
for (i = 1; i <= 7; ++i)
if (strcmp(type, optypes[i]) == 0)
break;
@ -223,9 +230,14 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
WRITE_LOCK(ae->ARWLock);
info = Yap_GetOpPropForAModuleHavingALock(ae, m);
if (EndOfPAEntr(info)) {
ModEntry *me;
info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry));
if (!info)
return false;
info->KindOfPE = Ord(OpProperty);
info->OpModule = m;
info->NextForME = (me = Yap_GetModuleEntry(m))->OpForME;
me->OpForME = info;
info->OpModule = m;
info->OpName = a;
// LOCK(OpListLock);
info->OpNext = OpList;
@ -246,7 +258,7 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
/* ISO dictates */
WRITE_UNLOCK(info->OpRWLock);
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
return FALSE;
return false;
}
info->Infix = p;
} else if (i <= 5) {
@ -256,14 +268,14 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
/* ISO dictates */
WRITE_UNLOCK(info->OpRWLock);
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
return FALSE;
return false;
}
info->Posfix = p;
} else {
info->Prefix = p;
}
WRITE_UNLOCK(info->OpRWLock);
return (TRUE);
return true;
}
int Yap_OpDec(int p, char *type, Atom a, Term m) {
@ -278,6 +290,22 @@ static void SetOp(int p, int type, char *at, Term m) {
OpDec(p, optypes[type], Yap_LookupAtom(at), m);
}
bool Yap_dup_op(OpEntry *op, ModEntry *she)
{
AtomEntry *ae = RepAtom(op->OpName);
OpEntry *info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry));
if (!info)
return false;
memcpy(info, op, sizeof(OpEntry));
info->NextForME =she->OpForME;
she->OpForME = info;
info->OpModule = MkAtomTerm(she->AtomOfME);
AddPropToAtom(ae, AbsOpProp(info));
INIT_RWLOCK(info->OpRWLock);
return true;
}
/* Gets the info about an operator in a prop */
Atom Yap_GetOp(OpEntry *pp, int *prio, int fix) {
int n;

View File

@ -462,6 +462,30 @@ static Int source_module(USES_REGS1) {
return Yap_unify(ARG1, LOCAL_SourceModule);
}
/**
* @pred $copy_operators(+ModSource, +ModTarget)
*
* Copy all operators in ModSource to ModTarget
*
* : _Mod_ is the current read-in or source module.
*/
static Int copy_operators(USES_REGS1) {
ModEntry * me = LookupModule( Deref(ARG1) );
if (!me)
return true;
ModEntry *she = LookupModule( Deref(ARG2) );
if (!she)
return true;
OpEntry *op = me->OpForME;
while (op) {
if (!Yap_dup_op(op, she)) {
return false;
}
op = op->NextForME;
}
return true;
}
Term Yap_StripModule(Term t, Term *modp) {
CACHE_REGS
Term tmod;
@ -513,7 +537,8 @@ void Yap_InitModulesC(void) {
Yap_InitCPred("$yap_strip_module", 3, yap_strip_module,
SafePredFlag | SyncPredFlag);
Yap_InitCPred("context_module", 1, context_module, 0);
Yap_InitCPred("$is_system_module", 1, is_system_module, SafePredFlag);
Yap_InitCPred("$is_system_module", 1, is_system_module, SafePredFlag);
Yap_InitCPred("$copy_operators", 2, copy_operators, 0);
Yap_InitCPred("new_system_module", 1, new_system_module, SafePredFlag);
Yap_InitCPredBack("$all_current_modules", 1, 1, init_current_module,
cont_current_module, SafePredFlag | SyncPredFlag);

View File

@ -1730,8 +1730,10 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
(chtype(pch) == BS || chtype(pch) == EF || pch == '%')) {
t->Tok = Ord(kind = eot_tok);
// consume...
if (ch == '%')
if (pch == '%') {
t->TokInfo = TermNewLine;
return l;
}
ch = getchr(inp_stream);
if (chtype(ch) == EF) {
mark_eof(inp_stream);
@ -1748,12 +1750,14 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
if (och == '.') {
if (chtype(ch) == BS || chtype(ch) == EF || ch == '%') {
t->Tok = Ord(kind = eot_tok);
if (ch == '%')
if (ch == '%') {
t->TokInfo = TermNewLine;
return l;
}
if (chtype(ch) == EF) {
mark_eof(inp_stream);
t->TokInfo = TermEof;
} else {
t->TokInfo = TermEof;
} else {
t->TokInfo = TermNewLine;
}
return l;
@ -1802,7 +1806,11 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
enter_symbol:
if (och == '.' && (chtype(ch) == BS || chtype(ch) == EF || ch == '%')) {
t->Tok = Ord(kind = eot_tok);
if (chtype(ch) == EF) {
if (ch == '%') {
t->TokInfo = TermNewLine;
return l;
}
if (chtype(ch) == EF) {
mark_eof(inp_stream);
t->TokInfo = TermEof;
} else {

View File

@ -1060,6 +1060,25 @@ static Int init_current_atom_op(
return cont_current_atom_op(PASS_REGS1);
}
static Int copy_local_ops (USES_REGS1) { /* current_op(-Precedence,-Type,-Atom) */
Term tmodin = Deref(ARG1);
Term t = Deref(ARG1);
AtomEntry *ae;
OpEntry *ope;
if (IsVarTerm(t) || !IsAtomTerm(t)) {
Yap_Error(TYPE_ERROR_ATOM, t, "current_op/3");
cut_fail();
}
ae = RepAtom(AtomOfTerm(t));
if (EndOfPAEntr((ope = NextOp(RepOpProp(ae->PropsOfAE) PASS_REGS)))) {
cut_fail();
}
EXTRA_CBACK_ARG(5, 1) = (CELL)MkIntegerTerm((Int)ope);
B->cp_h = HR;
return cont_current_atom_op(PASS_REGS1);
}
void Yap_show_statistics(void) {
CACHE_REGS
unsigned long int heap_space_taken;

View File

@ -128,7 +128,6 @@ else()
set(YAP_STARTUP startup.yss)
endif()
set(WITH_CUDD YES CACHE FILEPATH "Try to use Cudd (currently Cudd 3)")
if (WITH_CUDD)
#detect cudd setup, as it is shared between different installations.
@ -148,13 +147,13 @@ check_include_files( "stdio.h;cudd/cudd.h;cudd/cuddInt.h" HAVE_CUDD_CUDDINT_H )
endif(WITH_CUDD)
set(WITH_JAVA YES CACHE FILEPATH "Try to use Java (currently Java 6,7,8)")
option(WITH_JAVA "Try to use Java (currently Java 6,7,8)" ON)
if (WITH_JAVA)
include(java)
endif(WITH_JAVA)
set(WITH_PYTHON YES CACHE FILEPATH "Try to use Python (currently Python 3)")
option(WITH_PYTHON "Try to use Python (currently Python 3)" ON)
if (WITH_PYTHON)
include(python)

View File

@ -304,6 +304,13 @@ If true, `open_shared_object/2` and friends are implemented,
providing access to shared libraries (`.so` files) or to dynamic link
libraries (`.DLL` files).
*/
//YAP_FLAG(MODULE_INDEPENDENT_OPERATORS_FLAG, "module_independent_operators", true, booleanFlag,
// "false", NULL),
/**< `module_independent_operators `
If `true` an operator declaration will be valid for every module in the program. This is for compatibility with old software that
might expect module-independent operators.
*/
YAP_FLAG(OPTIMISE_FLAG, "optimise", true, booleanFlag, "false", NULL),
YAP_FLAG(OS_ARGV_FLAG, "os_argv", false, os_argv, "?-", NULL),
YAP_FLAG(PID_FLAG, "pid", false, ro, "0", NULL),

View File

@ -250,18 +250,22 @@ INLINE_ONLY inline EXTERN bool IsWideAtom(Atom at) {
IsWideAtomProperty(RepWideAtomProp(RepAtom(at)->PropsOfAE)->KindOfPE);
}
/* Module property */
/** Module property: low-level data used to manage modes.
Includes lists of pedicates, operators and other well-defIned properties.
*/
typedef struct mod_entry {
Prop NextOfPE; /** chain of atom properties */
PropFlags KindOfPE; /* kind of property */
struct pred_entry *PredForME; /* index in module table */
Atom AtomOfME; /* module's name */
Atom OwnerFile; /* module's owner file */
PropFlags KindOfPE; /** kind of property */
struct pred_entry *PredForME; /** index in module table */
struct operator_entry *OpForME; /** index in operator table */
Atom AtomOfME; /** module's name */
Atom OwnerFile; /** module's owner file */
#if defined(YAPOR) || defined(THREADS)
rwlock_t ModRWLock; /* a read-write lock to protect the entry */
rwlock_t ModRWLock; /** a read-write lock to protect the entry */
#endif
unsigned int flags; /* Module local flags (from SWI compat) */
struct mod_entry *NextME; /* next module */
unsigned int flags; /** Module local flags (from SWI compat) */
struct mod_entry *NextME; /** next module */
} ModEntry;
#if USE_OFFSETS_IN_PROPS
@ -327,7 +331,7 @@ INLINE_ONLY inline EXTERN bool IsModProperty(int flags) {
(UNKNOWN_ERROR | UNKNOWN_WARNING | UNKNOWN_FAIL | UNKNOWN_FAST_FAIL | \
UNKNOWN_ABORT | UNKNOWN_HALT)
Term Yap_getUnknownModule(ModEntry *m);
Term Yap_getUnknownModule(ModEntry *m);
void Yap_setModuleFlags(ModEntry *n, ModEntry *o);
/* operator property entry structure */
@ -340,7 +344,8 @@ typedef struct operator_entry {
Atom OpName; /* atom name */
Term OpModule; /* module of predicate */
struct operator_entry *OpNext; /* next in list of operators */
BITS16 Prefix, Infix, Posfix; /* precedences */
struct operator_entry *NextForME; /* next in list of module operators */
BITS16 Prefix, Infix, Posfix; /**o precedences */
} OpEntry;
#if USE_OFFSETS_IN_PROPS
@ -382,9 +387,10 @@ OpEntry *Yap_GetOpProp(Atom, op_type, Term CACHE_TYPE);
int Yap_IsPrefixOp(Atom, int *, int *);
int Yap_IsOp(Atom);
int Yap_IsInfixOp(Atom, int *, int *, int *);
int Yap_IsPosfixOp(Atom, int *, int *);
/* defines related to operator specifications */
int Yap_IsPosfixOp(Atom, int *, int *);
bool Yap_dup_op(OpEntry *op, ModEntry *she);
/* defines related to operator specifications */
#define MaskPrio 0x0fff
#define DcrlpFlag 0x1000
#define DcrrpFlag 0x2000