A function to extend XLisp's table of function bindings dynamically

This commit is contained in:
Paul Licameli 2018-02-21 15:46:18 -05:00
parent e57afb3729
commit a1dc8305f0
7 changed files with 38 additions and 7 deletions

View File

@ -12,6 +12,7 @@ HISTORY
*/
#include <string.h> /* for memcpy */
#include "switches.h"
#include "xlisp.h"
#ifndef NO_PROTOTYPES_IN_XLISP_H
@ -114,7 +115,7 @@ LVAL xstoprecordio(void);
#endif
/* the function table */
FUNDEF funtab[] = {
FUNDEF init_funtab[] = {
/* read macro functions */
{ NULL, S, rmhash }, /* 0 */
@ -498,7 +499,32 @@ FUNDEF funtab[] = {
{0,0,0} /* end of table marker */
};
};
FUNDEF *funtab = init_funtab;
static size_t szfuntab = sizeof(init_funtab) / sizeof(*init_funtab);
int xlbindfunctions(FUNDEF *functions, size_t nfunctions)
{
/* This is written very generally, imposing no fixed upper limit on the
growth of the table. But perhaps a lightweight alternative with such a
limit could be conditionally compiled.
*/
/* malloc, not realloc, to leave old table unchanged in case of failure */
FUNDEF *newfuntab = malloc((szfuntab + nfunctions) * sizeof(FUNDEF));
if (!newfuntab)
return FALSE;
memcpy(newfuntab, funtab, (szfuntab - 1) * sizeof(FUNDEF));
memcpy(newfuntab + szfuntab - 1, functions, nfunctions * sizeof(FUNDEF));
FUNDEF sentinel = { 0, 0, 0 };
newfuntab[szfuntab - 1] = sentinel;
funtab = newfuntab;
szfuntab += nfunctions;
return TRUE;
/* To do: deallocate funtab when XLisp runtime shuts down */
}
/* xnotimp does not return anything on purpose, so disable
* "no return value" warning

View File

@ -134,7 +134,7 @@ int xlisave(const char *fname)
/* xlirestore - restore a saved memory image */
int xlirestore(const char *fname)
{
extern FUNDEF funtab[];
extern FUNDEF *funtab;
char fullname[STRMAX+1];
unsigned char *cp;
int n,i,max,type;

View File

@ -41,7 +41,7 @@ extern LVAL a_fixnum,a_flonum,a_string,a_stream,a_object;
extern LVAL a_vector,a_closure,a_char,a_ustream,a_extern;
extern LVAL s_gcflag,s_gchook;
extern LVAL s_search_path;
extern FUNDEF funtab[];
extern FUNDEF *funtab;
/* forward declarations */
FORWARD LOCAL void initwks();

View File

@ -671,6 +671,11 @@ void xlinit(void);
void xlsymbols(void);
/* xlftab.c */
/* returns true on success,
false if table limits would be exceeded and the table remains unchanged */
int xlbindfunctions(FUNDEF *functions, size_t nfunctions);
/* xlio.c */
int xlgetc(LVAL fptr);

View File

@ -88,7 +88,7 @@ void xladdivar(LVAL cls, const char *var)
/* xladdmsg - add a message to a class */
void xladdmsg(LVAL cls, const char *msg, int offset)
{
extern FUNDEF funtab[];
extern FUNDEF *funtab;
LVAL mptr;
/* enter the message selector */

View File

@ -21,7 +21,7 @@
/* external variables */
extern LVAL s_printcase,k_downcase,k_const,k_nmacro;
extern LVAL s_ifmt,s_ffmt;
extern FUNDEF funtab[];
extern FUNDEF *funtab;
extern char buf[];
LOCAL void putsymbol(LVAL fptr, char *str, int escflag);

View File

@ -925,7 +925,7 @@ int xlisnumber(char *str, LVAL *pval)
/* defmacro - define a read macro */
void defmacro(int ch, LVAL type, int offset)
{
extern FUNDEF funtab[];
extern FUNDEF *funtab;
LVAL subr;
subr = cvsubr(funtab[offset].fd_subr,funtab[offset].fd_type,offset);
setelement(getvalue(s_rtable),ch,cons(type,subr));