--- pari-2.7.0/src/language/eval.c-pre 2019-03-01 03:30:30.428655500 -0800 +++ pari-2.7.0/src/language/eval.c 2019-03-01 17:29:05.309988700 -0800 @@ -136,6 +136,9 @@ pop_val(entree *ep) void freeep(entree *ep) { + if (foreignFuncFree && ep->code && (*ep->code == 'x')) + (*foreignFuncFree)(ep); /* function created by foreign interpreter */ + if (EpSTATIC(ep)) return; /* gp function loaded at init time */ if (ep->help) {pari_free((void*)ep->help); ep->help=NULL;} if (ep->code) {pari_free((void*)ep->code); ep->code=NULL;} --- pari-2.7.0/src/language/init.c-pre 2019-03-01 03:44:51.207967500 -0800 +++ pari-2.7.0/src/language/init.c 2019-03-01 17:28:05.405883500 -0800 @@ -85,6 +85,12 @@ static pari_stack s_MODULES, s_OLDMODULE const long functions_tblsz = 135; /* size of functions_hash */ entree **functions_hash, **defaults_hash; +void *foreignHandler; /* Handler for foreign commands. */ +char foreignExprSwitch = 3; /* Just some unprobable char. */ +GEN (*foreignExprHandler)(char*); /* Handler for foreign expressions.*/ +entree* (*foreignAutoload)(const char*, long len); /* Autoloader */ +void (*foreignFuncFree)(entree *); /* How to free external entree. */ + void (*cb_pari_ask_confirm)(const char *); int (*cb_pari_handle_exception)(long); int (*cb_pari_whatnow)(PariOUT *out, const char *, int); @@ -2340,6 +2346,12 @@ pari_version(void) * * Syntax requirements: * = Separator '=' required. + * + * Origin: + * x Installed foreign function. Put the ep of the function as the + * first argument, fill the rest with PARI arguments, + * then call installedHandler with these arguments. + * Should be the first char in the code. **************************************************************************** */ #include "init.h" --- pari-2.7.0/src/language/anal.h-pre 2014-03-20 01:59:28.000000000 -0700 +++ pari-2.7.0/src/language/anal.h 2019-03-01 17:21:54.576632100 -0800 @@ -33,6 +33,12 @@ void pari_fill_hashtable(entree **tabl void compile_err(const char *msg, const char *str); void compile_varerr(const char *str); +extern void *foreignHandler; +extern GEN (*foreignExprHandler)(char*); +extern char foreignExprSwitch; +extern entree * (*foreignAutoload)(const char*, long len); +extern void (*foreignFuncFree)(entree *); + #ifdef STACK_CHECK extern THREAD void *PARI_stack_limit; #endif --- pari-2.7.0/src/language/anal.c-pre 2019-03-01 03:36:32.318091200 -0800 +++ pari-2.7.0/src/language/anal.c 2019-03-01 17:24:51.107542200 -0800 @@ -753,6 +753,8 @@ findentry(const char *name, long len, en entree *ep; for (ep = ep1; ep; ep = ep->next) if (!strncmp(ep->name, name, len) && !(ep->name)[len]) return ep; + if (foreignAutoload) /* Try to autoload. */ + return foreignAutoload(name,len); return NULL; /* not found */ }