/* * COPYRIGHT (c) 1988-1996 BY * * PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS. * * See the source file SLIB.C for more information. * Array-hacking code moved to another source file. */ #include #include #include #include #include #include #include #include "siod.h" #include "siodp.h" static void init_sliba_version(void) {setvar(cintern("*sliba-version*"), cintern("$Id: sliba.c,v 1.1.1.1 2000/12/09 01:57:11 thhsieh Exp $"), NIL);} static LISP sym_plists = NIL; static LISP bashnum = NIL; static LISP sym_e = NIL; static LISP sym_f = NIL; void init_storage_a1(long type) {long j; struct user_type_hooks *p; set_gc_hooks(type, array_gc_relocate, array_gc_mark, array_gc_scan, array_gc_free, &j); set_print_hooks(type,array_prin1); p = get_user_type_hooks(type); p->fast_print = array_fast_print; p->fast_read = array_fast_read; p->equal = array_equal; p->c_sxhash = array_sxhash;} void init_storage_a(void) {gc_protect(&bashnum); bashnum = newcell(tc_flonum); init_storage_a1(tc_string); init_storage_a1(tc_double_array); init_storage_a1(tc_long_array); init_storage_a1(tc_lisp_array); init_storage_a1(tc_byte_array);} LISP array_gc_relocate(LISP ptr) {LISP nw; if ((nw = heap) >= heap_end) gc_fatal_error(); heap = nw+1; memcpy(nw,ptr,sizeof(struct obj)); return(nw);} void array_gc_scan(LISP ptr) {long j; if TYPEP(ptr,tc_lisp_array) for(j=0;j < ptr->storage_as.lisp_array.dim; ++j) ptr->storage_as.lisp_array.data[j] = gc_relocate(ptr->storage_as.lisp_array.data[j]);} LISP array_gc_mark(LISP ptr) {long j; if TYPEP(ptr,tc_lisp_array) for(j=0;j < ptr->storage_as.lisp_array.dim; ++j) gc_mark(ptr->storage_as.lisp_array.data[j]); return(NIL);} void array_gc_free(LISP ptr) {switch (ptr->type) {case tc_string: case tc_byte_array: free(ptr->storage_as.string.data); break; case tc_double_array: free(ptr->storage_as.double_array.data); break; case tc_long_array: free(ptr->storage_as.long_array.data); break; case tc_lisp_array: free(ptr->storage_as.lisp_array.data); break;}} void array_prin1(LISP ptr,struct gen_printio *f) {int j; switch (ptr->type) {case tc_string: gput_st(f,"\""); if (strcspn(ptr->storage_as.string.data,"\"\\\n\r\t") == strlen(ptr->storage_as.string.data)) gput_st(f,ptr->storage_as.string.data); else {int n,c; char cbuff[3]; n = strlen(ptr->storage_as.string.data); for(j=0;jstorage_as.string.data[j]) {case '\\': case '"': cbuff[0] = '\\'; cbuff[1] = c; cbuff[2] = 0; gput_st(f,cbuff); break; case '\n': gput_st(f,"\\n"); break; case '\r': gput_st(f,"\\r"); break; case '\t': gput_st(f,"\\t"); break; default: cbuff[0] = c; cbuff[1] = 0; gput_st(f,cbuff); break;}} gput_st(f,"\""); break; case tc_double_array: gput_st(f,"#("); for(j=0; j < ptr->storage_as.double_array.dim; ++j) {sprintf(tkbuffer,"%g",ptr->storage_as.double_array.data[j]); gput_st(f,tkbuffer); if ((j + 1) < ptr->storage_as.double_array.dim) gput_st(f," ");} gput_st(f,")"); break; case tc_long_array: gput_st(f,"#("); for(j=0; j < ptr->storage_as.long_array.dim; ++j) {sprintf(tkbuffer,"%ld",ptr->storage_as.long_array.data[j]); gput_st(f,tkbuffer); if ((j + 1) < ptr->storage_as.long_array.dim) gput_st(f," ");} gput_st(f,")"); case tc_byte_array: sprintf(tkbuffer,"#%ld\"",ptr->storage_as.string.dim); gput_st(f,tkbuffer); for(j=0; j < ptr->storage_as.string.dim; ++j) {sprintf(tkbuffer,"%02x",ptr->storage_as.string.data[j] & 0xFF); gput_st(f,tkbuffer);} gput_st(f,"\""); break; case tc_lisp_array: gput_st(f,"#("); for(j=0; j < ptr->storage_as.lisp_array.dim; ++j) {lprin1g(ptr->storage_as.lisp_array.data[j],f); if ((j + 1) < ptr->storage_as.lisp_array.dim) gput_st(f," ");} gput_st(f,")"); break;}} LISP strcons(long length,const char *data) {long flag; LISP s; flag = no_interrupt(1); s = cons(NIL,NIL); s->type = tc_string; if (length == -1) length = strlen(data); s->storage_as.string.data = must_malloc(length+1); s->storage_as.string.dim = length; if (data) memcpy(s->storage_as.string.data,data,length); s->storage_as.string.data[length] = 0; no_interrupt(flag); return(s);} int rfs_getc(unsigned char **p) {int i; i = **p; if (!i) return(EOF); *p = *p + 1; return(i);} void rfs_ungetc(unsigned char c,unsigned char **p) {*p = *p - 1;} LISP read_from_string(LISP x) {char *p; struct gen_readio s; p = get_c_string(x); s.getc_fcn = (int (*)(void *))rfs_getc; s.ungetc_fcn = (void (*)(int,void *))rfs_ungetc; s.cb_argument = (char *) &p; return(readtl(&s));} int pts_puts(char *from,void *cb) {LISP into; size_t fromlen,intolen,intosize,fitsize; into = (LISP) cb; fromlen = strlen(from); intolen = strlen(into->storage_as.string.data); intosize = into->storage_as.string.dim - intolen; fitsize = (fromlen < intosize) ? fromlen : intosize; memcpy(&into->storage_as.string.data[intolen],from,fitsize); into->storage_as.string.data[intolen+fitsize] = 0; if (fitsize < fromlen) err("print to string overflow",NIL); return(1);} LISP err_wta_str(LISP exp) {return(err("not a string",exp));} LISP print_to_string(LISP exp,LISP str,LISP nostart) {struct gen_printio s; if NTYPEP(str,tc_string) err_wta_str(str); s.putc_fcn = NULL; s.puts_fcn = pts_puts; s.cb_argument = str; if NULLP(nostart) str->storage_as.string.data[0] = 0; lprin1g(exp,&s); return(str);} LISP aref1(LISP a,LISP i) {long k; if NFLONUMP(i) err("bad index to aref",i); k = (long) FLONM(i); if (k < 0) err("negative index to aref",i); switch TYPE(a) {case tc_string: if (k >= a->storage_as.string.dim) err("index too large",i); return(flocons((double) a->storage_as.u_string.data[k])); case tc_byte_array: if (k >= a->storage_as.string.dim) err("index too large",i); return(flocons((double) a->storage_as.string.data[k])); case tc_double_array: if (k >= a->storage_as.double_array.dim) err("index too large",i); return(flocons(a->storage_as.double_array.data[k])); case tc_long_array: if (k >= a->storage_as.long_array.dim) err("index too large",i); return(flocons(a->storage_as.long_array.data[k])); case tc_lisp_array: if (k >= a->storage_as.lisp_array.dim) err("index too large",i); return(a->storage_as.lisp_array.data[k]); default: return(err("invalid argument to aref",a));}} void err1_aset1(LISP i) {err("index to aset too large",i);} void err2_aset1(LISP v) {err("bad value to store in array",v);} LISP aset1(LISP a,LISP i,LISP v) {long k; if NFLONUMP(i) err("bad index to aset",i); k = (long) FLONM(i); if (k < 0) err("negative index to aset",i); switch TYPE(a) {case tc_string: case tc_byte_array: if NFLONUMP(v) err2_aset1(v); if (k >= a->storage_as.string.dim) err1_aset1(i); a->storage_as.string.data[k] = (char) FLONM(v); return(v); case tc_double_array: if NFLONUMP(v) err2_aset1(v); if (k >= a->storage_as.double_array.dim) err1_aset1(i); a->storage_as.double_array.data[k] = FLONM(v); return(v); case tc_long_array: if NFLONUMP(v) err2_aset1(v); if (k >= a->storage_as.long_array.dim) err1_aset1(i); a->storage_as.long_array.data[k] = (long) FLONM(v); return(v); case tc_lisp_array: if (k >= a->storage_as.lisp_array.dim) err1_aset1(i); a->storage_as.lisp_array.data[k] = v; return(v); default: return(err("invalid argument to aset",a));}} LISP arcons(long typecode,long n,long initp) {LISP a; long flag,j; flag = no_interrupt(1); a = cons(NIL,NIL); switch(typecode) {case tc_double_array: a->storage_as.double_array.dim = n; a->storage_as.double_array.data = (double *) must_malloc(n * sizeof(double)); if (initp) for(j=0;jstorage_as.double_array.data[j] = 0.0; break; case tc_long_array: a->storage_as.long_array.dim = n; a->storage_as.long_array.data = (long *) must_malloc(n * sizeof(long)); if (initp) for(j=0;jstorage_as.long_array.data[j] = 0; break; case tc_string: a->storage_as.string.dim = n; a->storage_as.string.data = (char *) must_malloc(n+1); a->storage_as.string.data[n] = 0; if (initp) for(j=0;jstorage_as.string.data[j] = ' '; case tc_byte_array: a->storage_as.string.dim = n; a->storage_as.string.data = (char *) must_malloc(n); if (initp) for(j=0;jstorage_as.string.data[j] = 0; break; case tc_lisp_array: a->storage_as.lisp_array.dim = n; a->storage_as.lisp_array.data = (LISP *) must_malloc(n * sizeof(LISP)); for(j=0;jstorage_as.lisp_array.data[j] = NIL; break; default: errswitch();} a->type = (short) typecode; no_interrupt(flag); return(a);} LISP mallocl(void *place,long size) {long n,r; LISP retval; n = size / sizeof(long); r = size % sizeof(long); if (r) ++n; retval = arcons(tc_long_array,n,0); *(long **)place = retval->storage_as.long_array.data; return(retval);} LISP cons_array(LISP dim,LISP kind) {LISP a; long flag,n,j; if (NFLONUMP(dim) || (FLONM(dim) < 0)) return(err("bad dimension to cons-array",dim)); else n = (long) FLONM(dim); flag = no_interrupt(1); a = cons(NIL,NIL); if EQ(cintern("double"),kind) {a->type = tc_double_array; a->storage_as.double_array.dim = n; a->storage_as.double_array.data = (double *) must_malloc(n * sizeof(double)); for(j=0;jstorage_as.double_array.data[j] = 0.0;} else if EQ(cintern("long"),kind) {a->type = tc_long_array; a->storage_as.long_array.dim = n; a->storage_as.long_array.data = (long *) must_malloc(n * sizeof(long)); for(j=0;jstorage_as.long_array.data[j] = 0;} else if EQ(cintern("string"),kind) {a->type = tc_string; a->storage_as.string.dim = n; a->storage_as.string.data = (char *) must_malloc(n+1); a->storage_as.string.data[n] = 0; for(j=0;jstorage_as.string.data[j] = ' ';} else if EQ(cintern("byte"),kind) {a->type = tc_byte_array; a->storage_as.string.dim = n; a->storage_as.string.data = (char *) must_malloc(n); for(j=0;jstorage_as.string.data[j] = 0;} else if (EQ(cintern("lisp"),kind) || NULLP(kind)) {a->type = tc_lisp_array; a->storage_as.lisp_array.dim = n; a->storage_as.lisp_array.data = (LISP *) must_malloc(n * sizeof(LISP)); for(j=0;jstorage_as.lisp_array.data[j] = NIL;} else err("bad type of array",kind); no_interrupt(flag); return(a);} LISP string_append(LISP args) {long size; LISP l,s; char *data; size = 0; for(l=args;NNULLP(l);l=cdr(l)) size += strlen(get_c_string(car(l))); s = strcons(size,NULL); data = s->storage_as.string.data; data[0] = 0; for(l=args;NNULLP(l);l=cdr(l)) strcat(data,get_c_string(car(l))); return(s);} LISP bytes_append(LISP args) {long size,n,j; LISP l,s; char *data,*ptr; size = 0; for(l=args;NNULLP(l);l=cdr(l)) {get_c_string_dim(car(l),&n); size += n;} s = arcons(tc_byte_array,size,0); data = s->storage_as.string.data; for(j=0,l=args;NNULLP(l);l=cdr(l)) {ptr = get_c_string_dim(car(l),&n); memcpy(&data[j],ptr,n); j += n;} return(s);} LISP substring(LISP str,LISP start,LISP end) {long s,e,n; char *data; data = get_c_string_dim(str,&n); s = get_c_long(start); if NULLP(end) e = n; else e = get_c_long(end); if ((s < 0) || (s > e)) err("bad start index",start); if ((e < 0) || (e > n)) err("bad end index",end); return(strcons(e-s,&data[s]));} LISP string_search(LISP token,LISP str) {char *s1,*s2,*ptr; s1 = get_c_string(str); s2 = get_c_string(token); ptr = strstr(s1,s2); if (ptr) return(flocons(ptr - s1)); else return(NIL);} #define IS_TRIM_SPACE(_x) (strchr(" \t\r\n",(_x))) LISP string_trim(LISP str) {char *start,*end; start = get_c_string(str); while(*start && IS_TRIM_SPACE(*start)) ++start; end = &start[strlen(start)]; while((end > start) && IS_TRIM_SPACE(*(end-1))) --end; return(strcons(end-start,start));} LISP string_trim_left(LISP str) {char *start,*end; start = get_c_string(str); while(*start && IS_TRIM_SPACE(*start)) ++start; end = &start[strlen(start)]; return(strcons(end-start,start));} LISP string_trim_right(LISP str) {char *start,*end; start = get_c_string(str); end = &start[strlen(start)]; while((end > start) && IS_TRIM_SPACE(*(end-1))) --end; return(strcons(end-start,start));} LISP string_upcase(LISP str) {LISP result; char *s1,*s2; long j,n; s1 = get_c_string(str); n = strlen(s1); result = strcons(n,s1); s2 = get_c_string(result); for(j=0;j= TKBUFFERN) err("read string overflow",NIL); ++j; *p++ = c;} *p = 0; return(strcons(j,tkbuffer));} LISP lreadsharp(struct gen_readio *f) {LISP obj,l,result; long j,n; int c; c = GETC_FCN(f); switch(c) {case '(': UNGETC_FCN(c,f); obj = lreadr(f); n = nlength(obj); result = arcons(tc_lisp_array,n,1); for(l=obj,j=0;jstorage_as.lisp_array.data[j] = car(l); return(result); case '.': obj = lreadr(f); return(leval(obj,NIL)); case 'f': return(NIL); case 't': return(flocons(1)); default: return(err("readsharp syntax not handled",NIL));}} #define HASH_COMBINE(_h1,_h2,_mod) ((((_h1) * 17 + 1) ^ (_h2)) % (_mod)) long c_sxhash(LISP obj,long n) {long hash; unsigned char *s; LISP tmp; struct user_type_hooks *p; STACK_CHECK(&obj); INTERRUPT_CHECK(); switch TYPE(obj) {case tc_nil: return(0); case tc_cons: hash = c_sxhash(CAR(obj),n); for(tmp=CDR(obj);CONSP(tmp);tmp=CDR(tmp)) hash = HASH_COMBINE(hash,c_sxhash(CAR(tmp),n),n); hash = HASH_COMBINE(hash,c_sxhash(tmp,n),n); return(hash); case tc_symbol: for(hash=0,s=(unsigned char *)PNAME(obj);*s;++s) hash = HASH_COMBINE(hash,*s,n); return(hash); case tc_subr_0: case tc_subr_1: case tc_subr_2: case tc_subr_3: case tc_subr_4: case tc_subr_5: case tc_lsubr: case tc_fsubr: case tc_msubr: for(hash=0,s=(unsigned char *) obj->storage_as.subr.name;*s;++s) hash = HASH_COMBINE(hash,*s,n); return(hash); case tc_flonum: return(((unsigned long)FLONM(obj)) % n); default: p = get_user_type_hooks(TYPE(obj)); if (p->c_sxhash) return((*p->c_sxhash)(obj,n)); else return(0);}} LISP sxhash(LISP obj,LISP n) {return(flocons(c_sxhash(obj,FLONUMP(n) ? (long) FLONM(n) : 10000)));} LISP equal(LISP a,LISP b) {struct user_type_hooks *p; long atype; STACK_CHECK(&a); loop: INTERRUPT_CHECK(); if EQ(a,b) return(sym_t); atype = TYPE(a); if (atype != TYPE(b)) return(NIL); switch(atype) {case tc_cons: if NULLP(equal(car(a),car(b))) return(NIL); a = cdr(a); b = cdr(b); goto loop; case tc_flonum: return((FLONM(a) == FLONM(b)) ? sym_t : NIL); case tc_symbol: return(NIL); default: p = get_user_type_hooks(atype); if (p->equal) return((*p->equal)(a,b)); else return(NIL);}} LISP array_equal(LISP a,LISP b) {long j,len; switch(TYPE(a)) {case tc_string: case tc_byte_array: len = a->storage_as.string.dim; if (len != b->storage_as.string.dim) return(NIL); if (memcmp(a->storage_as.string.data,b->storage_as.string.data,len) == 0) return(sym_t); else return(NIL); case tc_long_array: len = a->storage_as.long_array.dim; if (len != b->storage_as.long_array.dim) return(NIL); if (memcmp(a->storage_as.long_array.data, b->storage_as.long_array.data, len * sizeof(long)) == 0) return(sym_t); else return(NIL); case tc_double_array: len = a->storage_as.double_array.dim; if (len != b->storage_as.double_array.dim) return(NIL); for(j=0;jstorage_as.double_array.data[j] != b->storage_as.double_array.data[j]) return(NIL); return(sym_t); case tc_lisp_array: len = a->storage_as.lisp_array.dim; if (len != b->storage_as.lisp_array.dim) return(NIL); for(j=0;jstorage_as.lisp_array.data[j], b->storage_as.lisp_array.data[j])) return(NIL); return(sym_t); default: return(errswitch());}} long array_sxhash(LISP a,long n) {long j,len,hash; unsigned char *char_data; unsigned long *long_data; double *double_data; switch(TYPE(a)) {case tc_string: case tc_byte_array: len = a->storage_as.string.dim; for(j=0,hash=0,char_data=(unsigned char *)a->storage_as.string.data; j < len; ++j,++char_data) hash = HASH_COMBINE(hash,*char_data,n); return(hash); case tc_long_array: len = a->storage_as.long_array.dim; for(j=0,hash=0,long_data=(unsigned long *)a->storage_as.long_array.data; j < len; ++j,++long_data) hash = HASH_COMBINE(hash,*long_data % n,n); return(hash); case tc_double_array: len = a->storage_as.double_array.dim; for(j=0,hash=0,double_data=a->storage_as.double_array.data; j < len; ++j,++double_data) hash = HASH_COMBINE(hash,(unsigned long)*double_data % n,n); return(hash); case tc_lisp_array: len = a->storage_as.lisp_array.dim; for(j=0,hash=0; j < len; ++j) hash = HASH_COMBINE(hash, c_sxhash(a->storage_as.lisp_array.data[j],n), n); return(hash); default: errswitch(); return(0);}} long href_index(LISP table,LISP key) {long index; if NTYPEP(table,tc_lisp_array) err("not a hash table",table); index = c_sxhash(key,table->storage_as.lisp_array.dim); if ((index < 0) || (index >= table->storage_as.lisp_array.dim)) {err("sxhash inconsistency",table); return(0);} else return(index);} LISP href(LISP table,LISP key) {return(cdr(assoc(key, table->storage_as.lisp_array.data[href_index(table,key)])));} LISP hset(LISP table,LISP key,LISP value) {long index; LISP cell,l; index = href_index(table,key); l = table->storage_as.lisp_array.data[index]; if NNULLP(cell = assoc(key,l)) return(setcdr(cell,value)); cell = cons(key,value); table->storage_as.lisp_array.data[index] = cons(cell,l); return(value);} LISP assoc(LISP x,LISP alist) {LISP l,tmp; for(l=alist;CONSP(l);l=CDR(l)) {tmp = CAR(l); if (CONSP(tmp) && equal(CAR(tmp),x)) return(tmp); INTERRUPT_CHECK();} if EQ(l,NIL) return(NIL); return(err("improper list to assoc",alist));} LISP assv(LISP x,LISP alist) {LISP l,tmp; for(l=alist;CONSP(l);l=CDR(l)) {tmp = CAR(l); if (CONSP(tmp) && NNULLP(eql(CAR(tmp),x))) return(tmp); INTERRUPT_CHECK();} if EQ(l,NIL) return(NIL); return(err("improper list to assv",alist));} void put_long(long i,FILE *f) {fwrite(&i,sizeof(long),1,f);} long get_long(FILE *f) {long i; fread(&i,sizeof(long),1,f); return(i);} long fast_print_table(LISP obj,LISP table) {FILE *f; LISP ht,index; f = get_c_file(car(table),(FILE *) NULL); if NULLP(ht = car(cdr(table))) return(1); index = href(ht,obj); if NNULLP(index) {putc(FO_fetch,f); put_long(get_c_long(index),f); return(0);} if NULLP(index = car(cdr(cdr(table)))) return(1); hset(ht,obj,index); FLONM(bashnum) = 1.0; setcar(cdr(cdr(table)),plus(index,bashnum)); putc(FO_store,f); put_long(get_c_long(index),f); return(1);} LISP fast_print(LISP obj,LISP table) {FILE *f; long len; LISP tmp; struct user_type_hooks *p; STACK_CHECK(&obj); f = get_c_file(car(table),(FILE *) NULL); switch(TYPE(obj)) {case tc_nil: putc(tc_nil,f); return(NIL); case tc_cons: for(len=0,tmp=obj;CONSP(tmp);tmp=CDR(tmp)) {INTERRUPT_CHECK();++len;} if (len == 1) {putc(tc_cons,f); fast_print(car(obj),table); fast_print(cdr(obj),table);} else if NULLP(tmp) {putc(FO_list,f); put_long(len,f); for(tmp=obj;CONSP(tmp);tmp=CDR(tmp)) fast_print(CAR(tmp),table);} else {putc(FO_listd,f); put_long(len,f); for(tmp=obj;CONSP(tmp);tmp=CDR(tmp)) fast_print(CAR(tmp),table); fast_print(tmp,table);} return(NIL); case tc_flonum: putc(tc_flonum,f); fwrite(&obj->storage_as.flonum.data, sizeof(obj->storage_as.flonum.data), 1, f); return(NIL); case tc_symbol: if (fast_print_table(obj,table)) {putc(tc_symbol,f); len = strlen(PNAME(obj)); if (len >= TKBUFFERN) err("symbol name too long",obj); put_long(len,f); fwrite(PNAME(obj),len,1,f); return(sym_t);} else return(NIL); default: p = get_user_type_hooks(TYPE(obj)); if (p->fast_print) return((*p->fast_print)(obj,table)); else return(err("cannot fast-print",obj));}} LISP fast_read(LISP table) {FILE *f; LISP tmp,l; struct user_type_hooks *p; int c; long len; f = get_c_file(car(table),(FILE *) NULL); c = getc(f); if (c == EOF) return(table); switch(c) {case FO_comment: while((c = getc(f))) switch(c) {case EOF: return(table); case '\n': return(fast_read(table));} case FO_fetch: len = get_long(f); FLONM(bashnum) = len; return(href(car(cdr(table)),bashnum)); case FO_store: len = get_long(f); tmp = fast_read(table); hset(car(cdr(table)),flocons(len),tmp); return(tmp); case tc_nil: return(NIL); case tc_cons: tmp = fast_read(table); return(cons(tmp,fast_read(table))); case FO_list: case FO_listd: len = get_long(f); FLONM(bashnum) = len; l = make_list(bashnum,NIL); tmp = l; while(len > 1) {CAR(tmp) = fast_read(table); tmp = CDR(tmp); --len;} CAR(tmp) = fast_read(table); if (c == FO_listd) CDR(tmp) = fast_read(table); return(l); case tc_flonum: tmp = newcell(tc_flonum); fread(&tmp->storage_as.flonum.data, sizeof(tmp->storage_as.flonum.data), 1, f); return(tmp); case tc_symbol: len = get_long(f); if (len >= TKBUFFERN) err("symbol name too long",NIL); fread(tkbuffer,len,1,f); tkbuffer[len] = 0; return(rintern(tkbuffer)); default: p = get_user_type_hooks(c); if (p->fast_read) return(*p->fast_read)(c,table); else return(err("unknown fast-read opcode",flocons(c)));}} LISP array_fast_print(LISP ptr,LISP table) {int j,len; FILE *f; f = get_c_file(car(table),(FILE *) NULL); switch (ptr->type) {case tc_string: case tc_byte_array: putc(ptr->type,f); len = ptr->storage_as.string.dim; put_long(len,f); fwrite(ptr->storage_as.string.data,len,1,f); return(NIL); case tc_double_array: putc(tc_double_array,f); len = ptr->storage_as.double_array.dim * sizeof(double); put_long(len,f); fwrite(ptr->storage_as.double_array.data,len,1,f); return(NIL); case tc_long_array: putc(tc_long_array,f); len = ptr->storage_as.long_array.dim * sizeof(long); put_long(len,f); fwrite(ptr->storage_as.long_array.data,len,1,f); return(NIL); case tc_lisp_array: putc(tc_lisp_array,f); len = ptr->storage_as.lisp_array.dim; put_long(len,f); for(j=0; j < len; ++j) fast_print(ptr->storage_as.lisp_array.data[j],table); return(NIL); default: return(errswitch());}} LISP array_fast_read(int code,LISP table) {long j,len,iflag; FILE *f; LISP ptr; f = get_c_file(car(table),(FILE *) NULL); switch (code) {case tc_string: len = get_long(f); ptr = strcons(len,NULL); fread(ptr->storage_as.string.data,len,1,f); ptr->storage_as.string.data[len] = 0; return(ptr); case tc_byte_array: len = get_long(f); iflag = no_interrupt(1); ptr = newcell(tc_byte_array); ptr->storage_as.string.dim = len; ptr->storage_as.string.data = (char *) must_malloc(len); fread(ptr->storage_as.string.data,len,1,f); no_interrupt(iflag); return(ptr); case tc_double_array: len = get_long(f); iflag = no_interrupt(1); ptr = newcell(tc_double_array); ptr->storage_as.double_array.dim = len; ptr->storage_as.double_array.data = (double *) must_malloc(len * sizeof(double)); fread(ptr->storage_as.double_array.data,sizeof(double),len,f); no_interrupt(iflag); return(ptr); case tc_long_array: len = get_long(f); iflag = no_interrupt(1); ptr = newcell(tc_long_array); ptr->storage_as.long_array.dim = len; ptr->storage_as.long_array.data = (long *) must_malloc(len * sizeof(long)); fread(ptr->storage_as.long_array.data,sizeof(long),len,f); no_interrupt(iflag); return(ptr); case tc_lisp_array: len = get_long(f); FLONM(bashnum) = len; ptr = cons_array(bashnum,NIL); for(j=0; j < len; ++j) ptr->storage_as.lisp_array.data[j] = fast_read(table); return(ptr); default: return(errswitch());}} long get_c_long(LISP x) {if NFLONUMP(x) err("not a number",x); return((long)FLONM(x));} double get_c_double(LISP x) {if NFLONUMP(x) err("not a number",x); return(FLONM(x));} LISP make_list(LISP x,LISP v) {long n; LISP l; n = get_c_long(x); l = NIL; while(n > 0) {l = cons(v,l); --n;} return(l);} LISP lfread(LISP size,LISP file) {long flag,n,ret,m; char *buffer; LISP s; FILE *f; f = get_c_file(file,stdin); flag = no_interrupt(1); switch(TYPE(size)) {case tc_string: case tc_byte_array: s = size; buffer = s->storage_as.string.data; n = s->storage_as.string.dim; m = 0; break; default: n = get_c_long(size); buffer = (char *) must_malloc(n+1); buffer[n] = 0; m = 1;} ret = fread(buffer,1,n,f); if (ret == 0) {if (m) free(buffer); no_interrupt(flag); return(NIL);} if (m) {if (ret == n) {s = cons(NIL,NIL); s->type = tc_string; s->storage_as.string.data = buffer; s->storage_as.string.dim = n;} else {s = strcons(ret,NULL); memcpy(s->storage_as.string.data,buffer,ret); free(buffer);} no_interrupt(flag); return(s);} no_interrupt(flag); return(flocons((double)ret));} LISP lfwrite(LISP string,LISP file) {FILE *f; long flag; char *data; long dim,len; f = get_c_file(file,stdout); data = get_c_string_dim(CONSP(string) ? car(string) : string,&dim); len = CONSP(string) ? get_c_long(cadr(string)) : dim; if (len <= 0) return(NIL); if (len > dim) err("write length too long",string); flag = no_interrupt(1); fwrite(data,1,len,f); no_interrupt(flag); return(NIL);} LISP lfflush(LISP file) {FILE *f; long flag; f = get_c_file(file,stdout); flag = no_interrupt(1); fflush(f); no_interrupt(flag); return(NIL);} LISP string_length(LISP string) {if NTYPEP(string,tc_string) err_wta_str(string); return(flocons(strlen(string->storage_as.string.data)));} LISP string_dim(LISP string) {if NTYPEP(string,tc_string) err_wta_str(string); return(flocons((double)string->storage_as.string.dim));} long nlength(LISP obj) {LISP l; long n; switch TYPE(obj) {case tc_string: return(strlen(obj->storage_as.string.data)); case tc_byte_array: return(obj->storage_as.string.dim); case tc_double_array: return(obj->storage_as.double_array.dim); case tc_long_array: return(obj->storage_as.long_array.dim); case tc_lisp_array: return(obj->storage_as.lisp_array.dim); case tc_nil: return(0); case tc_cons: for(l=obj,n=0;CONSP(l);l=CDR(l),++n) INTERRUPT_CHECK(); if NNULLP(l) err("improper list to length",obj); return(n); default: err("wta to length",obj); return(0);}} LISP llength(LISP obj) {return(flocons(nlength(obj)));} LISP number2string(LISP x,LISP b,LISP w,LISP p) {char buffer[1000]; double y; long base,width,prec; if NFLONUMP(x) err("wta",x); y = FLONM(x); width = NNULLP(w) ? get_c_long(w) : -1; if (width > 100) err("width too long",w); prec = NNULLP(p) ? get_c_long(p) : -1; if (prec > 100) err("precision too large",p); if (NULLP(b) || EQ(sym_e,b) || EQ(sym_f,b)) {if ((width >= 0) && (prec >= 0)) sprintf(buffer, NULLP(b) ? "% *.*g" : EQ(sym_e,b) ? "% *.*e" : "% *.*f", width, prec, y); else if (width >= 0) sprintf(buffer, NULLP(b) ? "% *g" : EQ(sym_e,b) ? "% *e" : "% *f", width, y); else if (prec >= 0) sprintf(buffer, NULLP(b) ? "%.*g" : EQ(sym_e,b) ? "%.*e" : "%.*f", prec, y); else sprintf(buffer, NULLP(b) ? "%g" : EQ(sym_e,b) ? "%e" : "%f", y);} else if (((base = get_c_long(b)) == 10) || (base == 8) || (base == 16)) {if (width >= 0) sprintf(buffer, (base == 10) ? "%0*ld" : (base == 8) ? "%0*lo" : "%0*lX", width, (long) y); else sprintf(buffer, (base == 10) ? "%ld" : (base == 8) ? "%lo" : "%lX", (long) y);} else err("number base not handled",b); return(strcons(strlen(buffer),buffer));} LISP string2number(LISP x,LISP b) {char *str; long base,value = 0; double result; str = get_c_string(x); if NULLP(b) result = atof(str); else if ((base = get_c_long(b)) == 10) {sscanf(str,"%ld",&value); result = (double) value;} else if (base == 8) {sscanf(str,"%lo",&value); result = (double) value;} else if (base == 16) {sscanf(str,"%lx",&value); result = (double) value;} else if ((base >= 1) && (base <= 16)) {for(result = 0.0;*str;++str) if (isdigit((int)(*str))) result = result * base + *str - '0'; else if (isxdigit((int)(*str))) result = result * base + toupper(*str) - 'A' + 10;} else return(err("number base not handled",b)); return(flocons(result));} LISP lstrcmp(LISP s1,LISP s2) {return(flocons(strcmp(get_c_string(s1),get_c_string(s2))));} void chk_string(LISP s,char **data,long *dim) {if TYPEP(s,tc_string) {*data = s->storage_as.string.data; *dim = s->storage_as.string.dim;} else err_wta_str(s);} LISP lstrcpy(LISP dest,LISP src) {long ddim,slen; char *d,*s; chk_string(dest,&d,&ddim); s = get_c_string(src); slen = strlen(s); if (slen > ddim) err("string too long",src); memcpy(d,s,slen); d[slen] = 0; return(NIL);} LISP lstrcat(LISP dest,LISP src) {long ddim,dlen,slen; char *d,*s; chk_string(dest,&d,&ddim); s = get_c_string(src); slen = strlen(s); dlen = strlen(d); if ((slen + dlen) > ddim) err("string too long",src); memcpy(&d[dlen],s,slen); d[dlen+slen] = 0; return(NIL);} LISP lstrbreakup(LISP str,LISP lmarker) {char *start,*end,*marker; size_t k; LISP result = NIL; start = get_c_string(str); marker = get_c_string(lmarker); k = strlen(marker); while(*start) {if (!(end = strstr(start,marker))) end = &start[strlen(start)]; result = cons(strcons(end-start,start),result); start = (*end) ? end+k : end;} return(nreverse(result));} LISP lstrunbreakup(LISP elems,LISP lmarker) {LISP result,l; for(l=elems,result=NIL;NNULLP(l);l=cdr(l)) if EQ(l,elems) result = cons(car(l),result); else result = cons(car(l),cons(lmarker,result)); return(string_append(nreverse(result)));} LISP stringp(LISP x) {return(TYPEP(x,tc_string) ? sym_t : NIL);} static char *base64_encode_table = "\ ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz\ 0123456789+/="; static char *base64_decode_table = NULL; static void init_base64_table(void) {int j; base64_decode_table = (char *) malloc(256); memset(base64_decode_table,-1,256); for(j=0;j<65;++j) base64_decode_table[(int)base64_encode_table[j]] = (char)j;} #define BITMSK(N) ((1 << (N)) - 1) #define ITEM1(X) (X >> 2) & BITMSK(6) #define ITEM2(X,Y) ((X & BITMSK(2)) << 4) | ((Y >> 4) & BITMSK(4)) #define ITEM3(X,Y) ((X & BITMSK(4)) << 2) | ((Y >> 6) & BITMSK(2)) #define ITEM4(X) X & BITMSK(6) LISP base64encode(LISP in) {char *s,*t = base64_encode_table; unsigned char *p1,*p2; LISP out; long j,m,n,chunks,leftover; s = get_c_string_dim(in,&n); chunks = n / 3; leftover = n % 3; m = (chunks + ((leftover) ? 1 : 0)) * 4; out = strcons(m,NULL); p2 = (unsigned char *) get_c_string(out); for(j=0,p1=(unsigned char *)s;j> 4)); *p2++ = (unsigned char) ((item2 << 4) | (item3 >> 2)); *p2++ = (unsigned char) ((item3 << 6) | item4);} switch(leftover) {case 0: break; case 1: if ((item1 = t[p1[0]]) & ~BITMSK(6)) return(NIL); if ((item2 = t[p1[1]]) & ~BITMSK(6)) return(NIL); *p2++ = (unsigned char) ((item1 << 2) | (item2 >> 4)); break; case 2: if ((item1 = t[p1[0]]) & ~BITMSK(6)) return(NIL); if ((item2 = t[p1[1]]) & ~BITMSK(6)) return(NIL); if ((item3 = t[p1[2]]) & ~BITMSK(6)) return(NIL); *p2++ = (unsigned char) ((item1 << 2) | (item2 >> 4)); *p2++ = (unsigned char) ((item2 << 4) | (item3 >> 2)); break; default: errswitch();} return(out);} LISP memq(LISP x,LISP il) {LISP l,tmp; for(l=il;CONSP(l);l=CDR(l)) {tmp = CAR(l); if EQ(x,tmp) return(l); INTERRUPT_CHECK();} if EQ(l,NIL) return(NIL); return(err("improper list to memq",il));} LISP member(LISP x,LISP il) {LISP l,tmp; for(l=il;CONSP(l);l=CDR(l)) {tmp = CAR(l); if NNULLP(equal(x,tmp)) return(l); INTERRUPT_CHECK();} if EQ(l,NIL) return(NIL); return(err("improper list to member",il));} LISP memv(LISP x,LISP il) {LISP l,tmp; for(l=il;CONSP(l);l=CDR(l)) {tmp = CAR(l); if NNULLP(eql(x,tmp)) return(l); INTERRUPT_CHECK();} if EQ(l,NIL) return(NIL); return(err("improper list to memv",il));} LISP nth(LISP x,LISP li) {LISP l; long j,n = get_c_long(x); for(j = 0, l = li; (j < n) && CONSP(l); ++j) l = CDR(l); if CONSP(l) return(CAR(l)); else return(err("bad arg to nth",x));} /* these lxxx_default functions are convenient for manipulating command-line argument lists */ LISP lref_default(LISP li,LISP x,LISP fcn) {LISP l; long j,n = get_c_long(x); for(j = 0, l = li; (j < n) && CONSP(l); ++j) l = CDR(l); if CONSP(l) return(CAR(l)); else if NNULLP(fcn) return(lapply(fcn,NIL)); else return(NIL);} LISP larg_default(LISP li,LISP x,LISP dval) {LISP l = li,elem; long j=0,n = get_c_long(x); while NNULLP(l) {elem = car(l); if (TYPEP(elem,tc_string) && strchr("-:",*get_c_string(elem))) l = cdr(l); else if (j == n) return(elem); else {l = cdr(l); ++j;}} return(dval);} LISP lkey_default(LISP li,LISP key,LISP dval) {LISP l = li,elem; char *ckey,*celem; long n; ckey = get_c_string(key); n = strlen(ckey); while NNULLP(l) {elem = car(l); if (TYPEP(elem,tc_string) && (*(celem = get_c_string(elem)) == ':') && (strncmp(&celem[1],ckey,n) == 0) && (celem[n+1] == '=')) return(strcons(strlen(&celem[n+2]),&celem[n+2])); l = cdr(l);} return(dval);} LISP llist(LISP l) {return(l);} LISP writes1(FILE *f,LISP l) {LISP v; STACK_CHECK(&v); INTERRUPT_CHECK(); for(v=l;CONSP(v);v=CDR(v)) writes1(f,CAR(v)); switch TYPE(v) {case tc_nil: break; case tc_symbol: case tc_string: fput_st(f,get_c_string(v)); break; default: lprin1f(v,f); break;} return(NIL);} LISP writes(LISP args) {return(writes1(get_c_file(car(args),stdout),cdr(args)));} LISP last(LISP l) {LISP v1,v2; v1 = l; v2 = CONSP(v1) ? CDR(v1) : err("bad arg to last",l); while(CONSP(v2)) {INTERRUPT_CHECK(); v1 = v2; v2 = CDR(v2);} return(v1);} LISP butlast(LISP l) {INTERRUPT_CHECK(); STACK_CHECK(&l); if NULLP(l) err("list is empty",l); if CONSP(l) { if NULLP(CDR(l)) return(NIL); else return(cons(CAR(l),butlast(CDR(l)))); } return(err("not a list",l));} LISP nconc(LISP a,LISP b) {if NULLP(a) return(b); setcdr(last(a),b); return(a);} LISP funcall1(LISP fcn,LISP a1) {switch TYPE(fcn) {case tc_subr_1: STACK_CHECK(&fcn); INTERRUPT_CHECK(); return(SUBR1(fcn)(a1)); case tc_closure: if TYPEP(fcn->storage_as.closure.code,tc_subr_2) {STACK_CHECK(&fcn); INTERRUPT_CHECK(); return(SUBR2(fcn->storage_as.closure.code) (fcn->storage_as.closure.env,a1));} default: return(lapply(fcn,cons(a1,NIL)));}} LISP funcall2(LISP fcn,LISP a1,LISP a2) {switch TYPE(fcn) {case tc_subr_2: case tc_subr_2n: STACK_CHECK(&fcn); INTERRUPT_CHECK(); return(SUBR2(fcn)(a1,a2)); default: return(lapply(fcn,cons(a1,cons(a2,NIL))));}} LISP lqsort(LISP l,LISP f,LISP g) /* this is a stupid recursive qsort */ {int j,n; LISP v,mark,less,notless; for(v=l,n=0;CONSP(v);v=CDR(v),++n) INTERRUPT_CHECK(); if NNULLP(v) err("bad list to qsort",l); if (n == 0) return(NIL); j = rand() % n; for(v=l,n=0;n 0) {result = cons(NIL,result); --n;} for(p1=result,p2=l1;NNULLP(p2);p1=cdr(p1),p2=cdr(p2)) setcar(p1,car(p2)); for(p2=l2;NNULLP(p2);p1=cdr(p1),p2=cdr(p2)) setcar(p1,car(p2)); return(result);} LISP append(LISP l) {STACK_CHECK(&l); INTERRUPT_CHECK(); if NULLP(l) return(NIL); else if NULLP(cdr(l)) return(car(l)); else if NULLP(cddr(l)) return(append2(car(l),cadr(l))); else return(append2(car(l),append(cdr(l))));} LISP listn(long n, ...) {LISP result,ptr; long j; va_list args; for(j=0,result=NIL;j= 3) {put_st("fast loading "); put_st(fname); put_st("\n");} stream = listn(3, fopen_c(fname,"rb"), cons_array(flocons(100),NIL), flocons(0)); while(NEQ(stream,form = fast_read(stream))) {if (siod_verbose_level >= 5) lprint(form,NIL); if NULLP(noeval) leval(form,NIL); else result = cons(form,result);} fclose_l(car(stream)); if (siod_verbose_level >= 3) put_st("done.\n"); return(nreverse(result));} static void shexstr(char *outstr,void *buff,size_t len) {unsigned char *data = buff; size_t j; for(j=0;j= 3) {put_st("fast saving forms to "); put_st(cname); put_st("\n");} stream = listn(3, fopen_c(cname,NNULLP(fmode) ? get_c_string(fmode) : "wb"), NNULLP(nohash) ? NIL : cons_array(flocons(100),NIL), flocons(0)); f = get_c_file(car(stream),NULL); if NNULLP(comment) fput_st(f,get_c_string(comment)); sprintf(msgbuff,"# Siod Binary Object Save File\n"); fput_st(f,msgbuff); sprintf(msgbuff,"# sizeof(long) = %d\n# sizeof(double) = %d\n", sizeof(long),sizeof(double)); fput_st(f,msgbuff); shexstr(databuff,&l_one,sizeof(l_one)); sprintf(msgbuff,"# 1 = %s\n",databuff); fput_st(f,msgbuff); shexstr(databuff,&d_one,sizeof(d_one)); sprintf(msgbuff,"# 1.0 = %s\n",databuff); fput_st(f,msgbuff); for(l=forms;NNULLP(l);l=cdr(l)) fast_print(car(l),stream); fclose_l(car(stream)); if (siod_verbose_level >= 3) put_st("done.\n"); return(NIL);} void swrite1(LISP stream,LISP data) {FILE *f = get_c_file(stream,stdout); switch TYPE(data) {case tc_symbol: case tc_string: fput_st(f,get_c_string(data)); break; default: lprin1f(data,f); break;}} static LISP swrite2(LISP name,LISP table) {LISP value,key; if (SYMBOLP(name) && (PNAME(name)[0] == '.')) key = rintern(&PNAME(name)[1]); else key = name; value = href(table,key); if (CONSP(value)) {if (CONSP(CDR(value)) && EQ(name,key)) hset(table,key,CDR(value)); return(CAR(value));} else if (NULLP(value)) return(name); else return(value);} LISP swrite(LISP stream,LISP table,LISP data) {long j,k,m,n; switch(TYPE(data)) {case tc_symbol: swrite1(stream,swrite2(data,table)); break; case tc_lisp_array: n = data->storage_as.lisp_array.dim; if (n < 1) err("no object repeat count",data); m = get_c_long(swrite2(data->storage_as.lisp_array.data[0], table)); for(k=0;kstorage_as.lisp_array.data[j]); break; case tc_cons: /* this should be handled similar to the array case */ break; default: swrite1(stream,data);} return(NIL);} LISP lpow(LISP x,LISP y) {if NFLONUMP(x) err("wta(1st) to pow",x); if NFLONUMP(y) err("wta(2nd) to pow",y); return(flocons(pow(FLONM(x),FLONM(y))));} LISP lexp(LISP x) {return(flocons(exp(get_c_double(x))));} LISP llog(LISP x) {return(flocons(log(get_c_double(x))));} LISP lsin(LISP x) {return(flocons(sin(get_c_double(x))));} LISP lcos(LISP x) {return(flocons(cos(get_c_double(x))));} LISP ltan(LISP x) {return(flocons(tan(get_c_double(x))));} LISP lasin(LISP x) {return(flocons(asin(get_c_double(x))));} LISP lacos(LISP x) {return(flocons(acos(get_c_double(x))));} LISP latan(LISP x) {return(flocons(atan(get_c_double(x))));} LISP latan2(LISP x,LISP y) {return(flocons(atan2(get_c_double(x),get_c_double(y))));} LISP hexstr(LISP a) {unsigned char *in; char *out; LISP result; long j,dim; in = (unsigned char *) get_c_string_dim(a,&dim); result = strcons(dim*2,NULL); for(out=get_c_string(result),j=0;jstorage_as.string.data; for(j=0;j 0) m = m << k; else m = m >> (-k); return(flocons(m));} LISP bitand(LISP a,LISP b) {return(flocons(get_c_long(a) & get_c_long(b)));} LISP bitor(LISP a,LISP b) {return(flocons(get_c_long(a) | get_c_long(b)));} LISP bitxor(LISP a,LISP b) {return(flocons(get_c_long(a) ^ get_c_long(b)));} LISP bitnot(LISP a) {return(flocons(~get_c_long(a)));} LISP leval_prog1(LISP args,LISP env) {LISP retval,l; retval = leval(car(args),env); for(l=cdr(args);NNULLP(l);l=cdr(l)) leval(car(l),env); return(retval);} LISP leval_cond(LISP *pform,LISP *penv) {LISP args,env,clause,value,next; args = cdr(*pform); env = *penv; if NULLP(args) {*pform = NIL; return(NIL);} next = cdr(args); while NNULLP(next) {clause = car(args); value = leval(car(clause),env); if NNULLP(value) {clause = cdr(clause); if NULLP(clause) {*pform = value; return(NIL);} else {next = cdr(clause); while(NNULLP(next)) {leval(car(clause),env); clause=next; next=cdr(next);} *pform = car(clause); return(sym_t);}} args = next; next = cdr(next);} clause = car(args); next = cdr(clause); if NULLP(next) {*pform = car(clause); return(sym_t);} value = leval(car(clause),env); if NULLP(value) {*pform = NIL; return(NIL);} clause = next; next = cdr(next); while(NNULLP(next)) {leval(car(clause),env); clause=next; next=cdr(next);} *pform = car(clause); return(sym_t);} LISP lstrspn(LISP str1,LISP str2) {return(flocons(strspn(get_c_string(str1),get_c_string(str2))));} LISP lstrcspn(LISP str1,LISP str2) {return(flocons(strcspn(get_c_string(str1),get_c_string(str2))));} LISP substring_equal(LISP str1,LISP str2,LISP start,LISP end) {char *cstr1,*cstr2; long len1,n,s,e; cstr1 = get_c_string_dim(str1,&len1); cstr2 = get_c_string_dim(str2,&n); s = NULLP(start) ? 0 : get_c_long(start); e = NULLP(end) ? len1 : get_c_long(end); if ((s < 0) || (s > e) || (e < 0) || (e > n) || ((e - s) != len1)) return(NIL); return((memcmp(cstr1,&cstr2[s],e-s) == 0) ? a_true_value() : NIL);} #ifdef vms int strncasecmp(const char *s1, const char *s2, int n) {int j,c1,c2; for(j=0;j c1) return(1);} return(0);} #endif LISP substring_equalcase(LISP str1,LISP str2,LISP start,LISP end) {char *cstr1,*cstr2; long len1,n,s,e; cstr1 = get_c_string_dim(str1,&len1); cstr2 = get_c_string_dim(str2,&n); s = NULLP(start) ? 0 : get_c_long(start); e = NULLP(end) ? len1 : get_c_long(end); if ((s < 0) || (s > e) || (e < 0) || (e > n) || ((e - s) != len1)) return(NIL); return((strncasecmp(cstr1,&cstr2[s],e-s) == 0) ? a_true_value() : NIL);} LISP set_eval_history(LISP len,LISP circ) {LISP data; data = NULLP(len) ? len : make_list(len,NIL); if NNULLP(circ) data = nconc(data,data); setvar(cintern("*eval-history-ptr*"),data,NIL); setvar(cintern("*eval-history*"),data,NIL); return(len);} static LISP parser_fasl(LISP ignore) {return(closure(listn(3, NIL, cons_array(flocons(100),NIL), flocons(0)), leval(cintern("parser_fasl_hook"),NIL)));} static LISP parser_fasl_hook(LISP env,LISP f) {LISP result; setcar(env,f); result = fast_read(env); if EQ(result,env) return(get_eof_val()); else return(result);} void init_subrs_a(void) {init_subr_2("aref",aref1); init_subr_3("aset",aset1); init_lsubr("string-append",string_append); init_lsubr("bytes-append",bytes_append); init_subr_1("string-length",string_length); init_subr_1("string-dimension",string_dim); init_subr_1("read-from-string",read_from_string); init_subr_3("print-to-string",print_to_string); init_subr_2("cons-array",cons_array); init_subr_2("sxhash",sxhash); init_subr_2("equal?",equal); init_subr_2("href",href); init_subr_3("hset",hset); init_subr_2("assoc",assoc); init_subr_2("assv",assv); init_subr_1("fast-read",fast_read); init_subr_2("fast-print",fast_print); init_subr_2("make-list",make_list); init_subr_2("fread",lfread); init_subr_2("fwrite",lfwrite); init_subr_1("fflush",lfflush); init_subr_1("length",llength); init_subr_4("number->string",number2string); init_subr_2("string->number",string2number); init_subr_3("substring",substring); init_subr_2("string-search",string_search); init_subr_1("string-trim",string_trim); init_subr_1("string-trim-left",string_trim_left); init_subr_1("string-trim-right",string_trim_right); init_subr_1("string-upcase",string_upcase); init_subr_1("string-downcase",string_downcase); init_subr_2("strcmp",lstrcmp); init_subr_2("strcat",lstrcat); init_subr_2("strcpy",lstrcpy); init_subr_2("strbreakup",lstrbreakup); init_subr_2("unbreakupstr",lstrunbreakup); init_subr_1("string?",stringp); gc_protect_sym(&sym_e,"e"); gc_protect_sym(&sym_f,"f"); gc_protect_sym(&sym_plists,"*plists*"); setvar(sym_plists,arcons(tc_lisp_array,100,1),NIL); init_subr_3("lref-default",lref_default); init_subr_3("larg-default",larg_default); init_subr_3("lkey-default",lkey_default); init_lsubr("list",llist); init_lsubr("writes",writes); init_subr_3("qsort",lqsort); init_subr_2("string-lessp",string_lessp); init_lsubr("mapcar",mapcar); init_subr_3("mapcar2",mapcar2); init_subr_2("mapcar1",mapcar1); init_subr_3("benchmark-funcall1",benchmark_funcall1); init_lsubr("benchmark-funcall2",benchmark_funcall2); init_subr_3("benchmark-eval",benchmark_eval); init_subr_2("fmod",lfmod); init_subr_2("subset",lsubset); init_subr_1("base64encode",base64encode); init_subr_1("base64decode",base64decode); init_subr_3("ass",ass); init_subr_2("append2",append2); init_lsubr("append",append); init_subr_5("fast-save",fast_save); init_subr_2("fast-load",fast_load); init_subr_3("swrite",swrite); init_subr_2("pow",lpow); init_subr_1("exp",lexp); init_subr_1("log",llog); init_subr_1("sin",lsin); init_subr_1("cos",lcos); init_subr_1("tan",ltan); init_subr_1("asin",lasin); init_subr_1("acos",lacos); init_subr_1("atan",latan); init_subr_2("atan2",latan2); init_subr_1("typeof",ltypeof); init_subr_1("caaar",caaar); init_subr_1("caadr",caadr); init_subr_1("cadar",cadar); init_subr_1("caddr",caddr); init_subr_1("cdaar",cdaar); init_subr_1("cdadr",cdadr); init_subr_1("cddar",cddar); init_subr_1("cdddr",cdddr); setvar(cintern("*pi*"),flocons(atan(1.0)*4),NIL); init_base64_table(); init_subr_1("array->hexstr",hexstr); init_subr_1("hexstr->bytes",hexstr2bytes); init_subr_3("ass",ass); init_subr_2("bit-and",bitand); init_subr_2("bit-or",bitor); init_subr_2("bit-xor",bitxor); init_subr_1("bit-not",bitnot); init_msubr("cond",leval_cond); init_fsubr("prog1",leval_prog1); init_subr_2("strspn",lstrspn); init_subr_2("strcspn",lstrcspn); init_subr_4("substring-equal?",substring_equal); init_subr_4("substring-equalcase?",substring_equalcase); init_subr_1("butlast",butlast); init_subr_2("ash",ash); init_subr_2("get",getprop); init_subr_3("setprop",setprop); init_subr_3("putprop",putprop); init_subr_1("last",last); init_subr_2("memq",memq); init_subr_2("memv",memv); init_subr_2("member",member); init_subr_2("nth",nth); init_subr_2("nconc",nconc); init_subr_2("set-eval-history",set_eval_history); init_subr_1("parser_fasl",parser_fasl); setvar(cintern("*parser_fasl.scm-loaded*"),a_true_value(),NIL); init_subr_2("parser_fasl_hook",parser_fasl_hook); init_sliba_version();}