make modules remember which operators they ever defined.
Make modules import operators from other modules
This commit is contained in:
parent
61ba15fa3a
commit
70061308ff
12
C/cdmgr.c
12
C/cdmgr.c
@ -1638,6 +1638,8 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
|
|||||||
tf = ArgOfTerm(1, t);
|
tf = ArgOfTerm(1, t);
|
||||||
else
|
else
|
||||||
tf = t;
|
tf = t;
|
||||||
|
tf = Yap_YapStripModule(tf, &mod);
|
||||||
|
|
||||||
if (IsAtomTerm(tf)) {
|
if (IsAtomTerm(tf)) {
|
||||||
at = AtomOfTerm(tf);
|
at = AtomOfTerm(tf);
|
||||||
p = RepPredProp(PredPropByAtom(at, mod));
|
p = RepPredProp(PredPropByAtom(at, mod));
|
||||||
@ -1796,11 +1798,6 @@ bool Yap_addclause(Term t, yamop *cp, Term tmode, Term mod, Term *t4ref)
|
|||||||
} else {
|
} else {
|
||||||
tf = Yap_MkStaticRefTerm(ClauseCodeToStaticClause(cp), p);
|
tf = Yap_MkStaticRefTerm(ClauseCodeToStaticClause(cp), p);
|
||||||
}
|
}
|
||||||
if (t4ref && *t4ref != TermNil) {
|
|
||||||
if (!Yap_unify(*t4ref, tf)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mod == PROLOG_MODULE)
|
if (mod == PROLOG_MODULE)
|
||||||
mod = TermProlog;
|
mod = TermProlog;
|
||||||
if (pflags & MultiFileFlag) {
|
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);
|
tn = Yap_MkApplTerm(FunctorMultiFileClause, 5, t);
|
||||||
Yap_Recordz(AtomMultiFile, tn);
|
Yap_Recordz(AtomMultiFile, tn);
|
||||||
}
|
}
|
||||||
|
if (t4ref && *t4ref != TermNil) {
|
||||||
|
if (!Yap_unify(*t4ref, tf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
C/init.c
34
C/init.c
@ -202,10 +202,17 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
|
|||||||
AtomEntry *ae = RepAtom(a);
|
AtomEntry *ae = RepAtom(a);
|
||||||
OpEntry *info;
|
OpEntry *info;
|
||||||
|
|
||||||
|
#if defined(MODULE_INDEPENDENT_OPERATORS_FLAG)
|
||||||
|
if (booleanFlag(MODULE_INDEPENDENT_OPERATORS_FLAG)) {
|
||||||
|
m = PROLOG_MODULE;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
if (m == TermProlog)
|
if (m == TermProlog)
|
||||||
m = PROLOG_MODULE;
|
m = PROLOG_MODULE;
|
||||||
else if (m == USER_MODULE)
|
else if (m == USER_MODULE)
|
||||||
m = PROLOG_MODULE;
|
m = PROLOG_MODULE;
|
||||||
|
}
|
||||||
for (i = 1; i <= 7; ++i)
|
for (i = 1; i <= 7; ++i)
|
||||||
if (strcmp(type, optypes[i]) == 0)
|
if (strcmp(type, optypes[i]) == 0)
|
||||||
break;
|
break;
|
||||||
@ -223,8 +230,13 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
|
|||||||
WRITE_LOCK(ae->ARWLock);
|
WRITE_LOCK(ae->ARWLock);
|
||||||
info = Yap_GetOpPropForAModuleHavingALock(ae, m);
|
info = Yap_GetOpPropForAModuleHavingALock(ae, m);
|
||||||
if (EndOfPAEntr(info)) {
|
if (EndOfPAEntr(info)) {
|
||||||
|
ModEntry *me;
|
||||||
info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry));
|
info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry));
|
||||||
|
if (!info)
|
||||||
|
return false;
|
||||||
info->KindOfPE = Ord(OpProperty);
|
info->KindOfPE = Ord(OpProperty);
|
||||||
|
info->NextForME = (me = Yap_GetModuleEntry(m))->OpForME;
|
||||||
|
me->OpForME = info;
|
||||||
info->OpModule = m;
|
info->OpModule = m;
|
||||||
info->OpName = a;
|
info->OpName = a;
|
||||||
// LOCK(OpListLock);
|
// LOCK(OpListLock);
|
||||||
@ -246,7 +258,7 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
|
|||||||
/* ISO dictates */
|
/* ISO dictates */
|
||||||
WRITE_UNLOCK(info->OpRWLock);
|
WRITE_UNLOCK(info->OpRWLock);
|
||||||
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
|
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
info->Infix = p;
|
info->Infix = p;
|
||||||
} else if (i <= 5) {
|
} else if (i <= 5) {
|
||||||
@ -256,14 +268,14 @@ static int OpDec(int p, const char *type, Atom a, Term m) {
|
|||||||
/* ISO dictates */
|
/* ISO dictates */
|
||||||
WRITE_UNLOCK(info->OpRWLock);
|
WRITE_UNLOCK(info->OpRWLock);
|
||||||
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
|
Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR, MkAtomTerm(a), "op/3");
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
info->Posfix = p;
|
info->Posfix = p;
|
||||||
} else {
|
} else {
|
||||||
info->Prefix = p;
|
info->Prefix = p;
|
||||||
}
|
}
|
||||||
WRITE_UNLOCK(info->OpRWLock);
|
WRITE_UNLOCK(info->OpRWLock);
|
||||||
return (TRUE);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Yap_OpDec(int p, char *type, Atom a, Term m) {
|
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);
|
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 */
|
/* Gets the info about an operator in a prop */
|
||||||
Atom Yap_GetOp(OpEntry *pp, int *prio, int fix) {
|
Atom Yap_GetOp(OpEntry *pp, int *prio, int fix) {
|
||||||
int n;
|
int n;
|
||||||
|
25
C/modules.c
25
C/modules.c
@ -462,6 +462,30 @@ static Int source_module(USES_REGS1) {
|
|||||||
return Yap_unify(ARG1, LOCAL_SourceModule);
|
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) {
|
Term Yap_StripModule(Term t, Term *modp) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
Term tmod;
|
Term tmod;
|
||||||
@ -514,6 +538,7 @@ void Yap_InitModulesC(void) {
|
|||||||
SafePredFlag | SyncPredFlag);
|
SafePredFlag | SyncPredFlag);
|
||||||
Yap_InitCPred("context_module", 1, context_module, 0);
|
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_InitCPred("new_system_module", 1, new_system_module, SafePredFlag);
|
||||||
Yap_InitCPredBack("$all_current_modules", 1, 1, init_current_module,
|
Yap_InitCPredBack("$all_current_modules", 1, 1, init_current_module,
|
||||||
cont_current_module, SafePredFlag | SyncPredFlag);
|
cont_current_module, SafePredFlag | SyncPredFlag);
|
||||||
|
18
C/scanner.c
18
C/scanner.c
@ -1730,8 +1730,10 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
|
|||||||
(chtype(pch) == BS || chtype(pch) == EF || pch == '%')) {
|
(chtype(pch) == BS || chtype(pch) == EF || pch == '%')) {
|
||||||
t->Tok = Ord(kind = eot_tok);
|
t->Tok = Ord(kind = eot_tok);
|
||||||
// consume...
|
// consume...
|
||||||
if (ch == '%')
|
if (pch == '%') {
|
||||||
|
t->TokInfo = TermNewLine;
|
||||||
return l;
|
return l;
|
||||||
|
}
|
||||||
ch = getchr(inp_stream);
|
ch = getchr(inp_stream);
|
||||||
if (chtype(ch) == EF) {
|
if (chtype(ch) == EF) {
|
||||||
mark_eof(inp_stream);
|
mark_eof(inp_stream);
|
||||||
@ -1748,12 +1750,14 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
|
|||||||
if (och == '.') {
|
if (och == '.') {
|
||||||
if (chtype(ch) == BS || chtype(ch) == EF || ch == '%') {
|
if (chtype(ch) == BS || chtype(ch) == EF || ch == '%') {
|
||||||
t->Tok = Ord(kind = eot_tok);
|
t->Tok = Ord(kind = eot_tok);
|
||||||
if (ch == '%')
|
if (ch == '%') {
|
||||||
|
t->TokInfo = TermNewLine;
|
||||||
return l;
|
return l;
|
||||||
|
}
|
||||||
if (chtype(ch) == EF) {
|
if (chtype(ch) == EF) {
|
||||||
mark_eof(inp_stream);
|
mark_eof(inp_stream);
|
||||||
t->TokInfo = TermEof;
|
t->TokInfo = TermEof;
|
||||||
} else {
|
} else {
|
||||||
t->TokInfo = TermNewLine;
|
t->TokInfo = TermNewLine;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
@ -1802,7 +1806,11 @@ TokEntry *Yap_tokenizer(struct stream_desc *inp_stream, bool store_comments,
|
|||||||
enter_symbol:
|
enter_symbol:
|
||||||
if (och == '.' && (chtype(ch) == BS || chtype(ch) == EF || ch == '%')) {
|
if (och == '.' && (chtype(ch) == BS || chtype(ch) == EF || ch == '%')) {
|
||||||
t->Tok = Ord(kind = eot_tok);
|
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);
|
mark_eof(inp_stream);
|
||||||
t->TokInfo = TermEof;
|
t->TokInfo = TermEof;
|
||||||
} else {
|
} else {
|
||||||
|
19
C/stdpreds.c
19
C/stdpreds.c
@ -1060,6 +1060,25 @@ static Int init_current_atom_op(
|
|||||||
return cont_current_atom_op(PASS_REGS1);
|
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) {
|
void Yap_show_statistics(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
unsigned long int heap_space_taken;
|
unsigned long int heap_space_taken;
|
||||||
|
@ -128,7 +128,6 @@ else()
|
|||||||
set(YAP_STARTUP startup.yss)
|
set(YAP_STARTUP startup.yss)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WITH_CUDD YES CACHE FILEPATH "Try to use Cudd (currently Cudd 3)")
|
|
||||||
|
|
||||||
if (WITH_CUDD)
|
if (WITH_CUDD)
|
||||||
#detect cudd setup, as it is shared between different installations.
|
#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)
|
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)
|
if (WITH_JAVA)
|
||||||
include(java)
|
include(java)
|
||||||
endif(WITH_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)
|
if (WITH_PYTHON)
|
||||||
include(python)
|
include(python)
|
||||||
|
@ -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
|
providing access to shared libraries (`.so` files) or to dynamic link
|
||||||
libraries (`.DLL` files).
|
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(OPTIMISE_FLAG, "optimise", true, booleanFlag, "false", NULL),
|
||||||
YAP_FLAG(OS_ARGV_FLAG, "os_argv", false, os_argv, "?-", NULL),
|
YAP_FLAG(OS_ARGV_FLAG, "os_argv", false, os_argv, "?-", NULL),
|
||||||
YAP_FLAG(PID_FLAG, "pid", false, ro, "0", NULL),
|
YAP_FLAG(PID_FLAG, "pid", false, ro, "0", NULL),
|
||||||
|
30
H/Yatom.h
30
H/Yatom.h
@ -250,18 +250,22 @@ INLINE_ONLY inline EXTERN bool IsWideAtom(Atom at) {
|
|||||||
IsWideAtomProperty(RepWideAtomProp(RepAtom(at)->PropsOfAE)->KindOfPE);
|
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 {
|
typedef struct mod_entry {
|
||||||
Prop NextOfPE; /** chain of atom properties */
|
Prop NextOfPE; /** chain of atom properties */
|
||||||
PropFlags KindOfPE; /* kind of property */
|
PropFlags KindOfPE; /** kind of property */
|
||||||
struct pred_entry *PredForME; /* index in module table */
|
struct pred_entry *PredForME; /** index in module table */
|
||||||
Atom AtomOfME; /* module's name */
|
struct operator_entry *OpForME; /** index in operator table */
|
||||||
Atom OwnerFile; /* module's owner file */
|
Atom AtomOfME; /** module's name */
|
||||||
|
Atom OwnerFile; /** module's owner file */
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#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
|
#endif
|
||||||
unsigned int flags; /* Module local flags (from SWI compat) */
|
unsigned int flags; /** Module local flags (from SWI compat) */
|
||||||
struct mod_entry *NextME; /* next module */
|
struct mod_entry *NextME; /** next module */
|
||||||
} ModEntry;
|
} ModEntry;
|
||||||
|
|
||||||
#if USE_OFFSETS_IN_PROPS
|
#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_ERROR | UNKNOWN_WARNING | UNKNOWN_FAIL | UNKNOWN_FAST_FAIL | \
|
||||||
UNKNOWN_ABORT | UNKNOWN_HALT)
|
UNKNOWN_ABORT | UNKNOWN_HALT)
|
||||||
|
|
||||||
Term Yap_getUnknownModule(ModEntry *m);
|
Term Yap_getUnknownModule(ModEntry *m);
|
||||||
void Yap_setModuleFlags(ModEntry *n, ModEntry *o);
|
void Yap_setModuleFlags(ModEntry *n, ModEntry *o);
|
||||||
|
|
||||||
/* operator property entry structure */
|
/* operator property entry structure */
|
||||||
@ -340,7 +344,8 @@ typedef struct operator_entry {
|
|||||||
Atom OpName; /* atom name */
|
Atom OpName; /* atom name */
|
||||||
Term OpModule; /* module of predicate */
|
Term OpModule; /* module of predicate */
|
||||||
struct operator_entry *OpNext; /* next in list of operators */
|
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;
|
} OpEntry;
|
||||||
#if USE_OFFSETS_IN_PROPS
|
#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_IsPrefixOp(Atom, int *, int *);
|
||||||
int Yap_IsOp(Atom);
|
int Yap_IsOp(Atom);
|
||||||
int Yap_IsInfixOp(Atom, int *, int *, int *);
|
int Yap_IsInfixOp(Atom, int *, int *, int *);
|
||||||
int Yap_IsPosfixOp(Atom, int *, int *);
|
int Yap_IsPosfixOp(Atom, int *, int *);
|
||||||
|
bool Yap_dup_op(OpEntry *op, ModEntry *she);
|
||||||
|
|
||||||
/* defines related to operator specifications */
|
/* defines related to operator specifications */
|
||||||
#define MaskPrio 0x0fff
|
#define MaskPrio 0x0fff
|
||||||
#define DcrlpFlag 0x1000
|
#define DcrlpFlag 0x1000
|
||||||
#define DcrrpFlag 0x2000
|
#define DcrrpFlag 0x2000
|
||||||
|
Reference in New Issue
Block a user