/* lisp.h by Michael Thorpe 2017-05-29 */ #ifndef LISP_H #define LISP_H #ifdef USE_FLOAT /* Define this if your machine can't handle floating-point division by 0 */ /* #define NO_FDIV_BY_0 */ #endif #ifdef USE_BIGINT #include #endif /* Only necessary for stream objects: */ #include typedef struct obj obj; typedef struct objtype objtype; struct objtype { char *name; obj *nameobj; obj *(*tostring)(obj *); void (*predropobj)(obj *); /* Called when object is put on the freelist */ void (*dropobj)(obj *); /* Called when object is to be discarded */ objtype *next; int (*init)(); /* Called when objtype is registered */ void (*exit)(); /* Called when objtype is to be unregistered */ }; union rawfuncptr { obj *(*ns0)(); obj *(*ns1)(obj *); obj *(*ns2)(obj *,obj *); obj *(*ns3)(obj *,obj *,obj *); }; struct wordextra { char *data; unsigned long len; struct wordextra *previnhash,*nextinhash; obj *obj; /* doesn't INCREF/DECREF */ }; struct obj { objtype *type; union { unsigned long refcount; obj *nextfree; } rcnf; union { #ifdef USE_BIGINT mpz_t bi; #endif struct c { obj *a; obj *d; } c; signed long i; #ifdef USE_FLOAT double f; #endif obj *o; struct rawfunc { unsigned int numargs:2; union rawfuncptr rawfuncptr; } rawfunc; struct bytefunc { obj *code; obj *objs; } bytefunc; struct s { char *data; unsigned long len; } s; struct stream { unsigned int readable:1; unsigned int writable:1; unsigned int closable:1; FILE *f; } stream; struct word { struct wordextra *extra; obj *value; } word; } value; #ifdef DEBUG obj *prev,*next; #endif }; extern objtype #ifdef USE_BIGINT bigint_objtype, #endif bytefunc_objtype, cons_objtype, #ifdef USE_FLOAT float_objtype, #endif integer_objtype, nil_objtype, quote_objtype, rawfunc_objtype, stream_objtype, string_objtype, word_objtype; #ifdef USE_BIGINT /* bigint.c */ obj *addb(obj *a,obj *b); obj *bitselectb(obj *a,obj *if0,obj *if1); obj *div2b(obj *a,obj *b); obj *mulb(obj *a,obj *b); obj *numcmpb(obj *a,obj *b,int desired); obj *string_to_bigint(obj *str); obj *subb(obj *a,obj *b); #ifdef USE_FLOAT obj *bigint_to_float(obj *bi); #endif #endif /* bytefunc.c */ /* cons.c */ #define CAR(o) ((o)->value.c.a) #define CDR(o) ((o)->value.c.d) obj *cons(obj *a,obj *d); #ifdef USE_FLOAT /* float.c */ obj *addf(obj *a,obj *b); obj *div2f(obj *a,obj *b); obj *mulf(obj *a,obj *b); obj *numcmpf(obj *a,obj *b,int desired); obj *string_to_float(obj *str); obj *subf(obj *a,obj *b); #endif /* integer.c */ extern obj *divideby0error; extern obj trueobj; obj *add(obj *a,obj *b); obj *bitselect(obj *a,obj *if0,obj *if1); obj *asr(obj *a,obj *b); obj *div2(obj *a,obj *b); /* stdlib.h sometimes has a div() function */ obj *mul(obj *a,obj *b); obj *numcmp(obj *a,obj *b,int desired); obj *sub(obj *a,obj *b); /* nil.c */ extern obj nilobj; /* preload.c */ int preload_init(); /* quote.c */ obj *quoteobj(obj *o); obj *unquote(obj *o); /* rawfunc.c */ obj *applyrawfunc(obj *func,obj *args); /* stream.c */ /* string.c */ obj *new_string(const char *data,unsigned long len); /* throw.c */ extern obj *exception, *exceptionvalue; obj *throw(obj *type,obj *value); obj *throwaccesserror(obj *value); obj *throwargumenterror(obj *value); obj *throwoom(); obj *throwrangecheck(obj *value); obj *throwtypeerror(obj *value); int throw_init(); void throw_exit(); /* util.c */ #ifdef DEBUG #define DECREF(o) real_decref((o),__FILE__,__LINE__) void real_decref(obj *o,const char *file,int line); #define INCREF(o) real_incref((o),__FILE__,__LINE__) obj *real_incref(obj *o,const char *file,int line); extern unsigned long total_objects; #else #define DECREF(o) do{if(!--(o)->rcnf.refcount)drop_object(o);}while(0) #define INCREF(o) ((o)->rcnf.refcount++,(o)) #endif void drop_object(obj *o); obj *new_object(objtype *type); int register_objtype(objtype *type); int clean_up(); /* vm.c */ int run_vm(); int vm_init(); void vm_exit(); /* word.c */ obj *lookup(obj *name); obj *define(obj *name,obj *value); obj *set(obj *name,obj *value); obj *undefine(obj *name); int store_builtin(unsigned int numargs,const char *name,obj *(*rawfunc)()); obj *new_word(const char *data,unsigned long len); int store_object(const char *name,obj *o); #define store_builtin_ns0(name,func) ((int (*)(unsigned int numargs,const char *,obj *(*)()))store_builtin)(0,name,func) #define store_builtin_ns1(name,func) ((int (*)(unsigned int numargs,const char *,obj *(*)(obj *)))store_builtin)(1,name,func) #define store_builtin_ns2(name,func) ((int (*)(unsigned int numargs,const char *,obj *(*)(obj *,obj *)))store_builtin)(2,name,func) #define store_builtin_ns3(name,func) ((int (*)(unsigned int numargs,const char *,obj *(*)(obj *,obj *,obj *)))store_builtin)(3,name,func) #endif