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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
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);
|
||||
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;
|
||||
}
|
||||
for (i = 1; i <= 7; ++i)
|
||||
if (strcmp(type, optypes[i]) == 0)
|
||||
break;
|
||||
@ -223,8 +230,13 @@ 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->NextForME = (me = Yap_GetModuleEntry(m))->OpForME;
|
||||
me->OpForME = info;
|
||||
info->OpModule = m;
|
||||
info->OpName = a;
|
||||
// LOCK(OpListLock);
|
||||
@ -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;
|
||||
|
25
C/modules.c
25
C/modules.c
@ -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;
|
||||
@ -514,6 +538,7 @@ void Yap_InitModulesC(void) {
|
||||
SafePredFlag | SyncPredFlag);
|
||||
Yap_InitCPred("context_module", 1, context_module, 0);
|
||||
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);
|
||||
|
12
C/scanner.c
12
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 == '%')) {
|
||||
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,8 +1750,10 @@ 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;
|
||||
@ -1802,6 +1806,10 @@ 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 (ch == '%') {
|
||||
t->TokInfo = TermNewLine;
|
||||
return l;
|
||||
}
|
||||
if (chtype(ch) == EF) {
|
||||
mark_eof(inp_stream);
|
||||
t->TokInfo = TermEof;
|
||||
|
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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)
|
||||
|
@ -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),
|
||||
|
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);
|
||||
}
|
||||
|
||||
/* 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 *);
|
||||
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 DcrlpFlag 0x1000
|
||||
#define DcrrpFlag 0x2000
|
||||
|
Reference in New Issue
Block a user