00001
00002
00003
00004
00005
00006
00007
00008
00009 static char *rcsid="@(#)$Id$";
00010
00011 #include <ctype.h>
00012 #include <fcntl.h>
00013 #include <signal.h>
00014 #include "eus.h"
00015 #if !alpha
00016 #define FALSE (0)
00017 #define TRUE (1)
00018 #endif
00019
00020 #define MAXTOKENLENGTH 1024
00021 #define MAXSTRINGLENGTH 16384
00022 #define to_upper(c) (islower(c) ? ((c)-'a'+'A') : (c))
00023 #define to_lower(c) (isupper(c) ? ((c)-'A'+'a') : (c))
00024
00025 #define syntaxtype(ch) ((enum ch_type)(current_syntax[ch]))
00026
00027 extern pointer FEATURES,READBASE,QREADTABLE;
00028 extern pointer QNOT, QAND, QOR;
00029
00030 static pointer read1(context *, pointer);
00031 static pointer read2(context *, pointer, int, int, int, char*, int);
00032 extern pointer makelabref();
00033
00034 extern mul_int_big();
00035 extern pointer normalize_bignum();
00036
00037
00038
00039 byte *current_syntax;
00040 pointer oblabels;
00041
00042
00043
00044
00045
00046
00047 enum ch_type chartype[256]={
00048 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00049 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00050 ch_constituent, ch_white, ch_white, ch_illegal,
00051 ch_white, ch_white, ch_illegal, ch_illegal,
00052 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00053 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00054 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00055 ch_illegal, ch_illegal, ch_illegal, ch_illegal,
00056 ch_white, ch_constituent, ch_termmacro, ch_nontermacro,
00057 ch_constituent, ch_constituent, ch_constituent, ch_termmacro,
00058 ch_termmacro, ch_termmacro, ch_constituent, ch_constituent,
00059 ch_termmacro, ch_constituent, ch_constituent, ch_constituent,
00060 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00061 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00062 ch_constituent, ch_constituent, ch_constituent, ch_termmacro,
00063 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00064 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00065 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00066 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00067 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00068 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00069 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00070 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00071 ch_sglescape, ch_constituent, ch_constituent, ch_constituent,
00072 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00073 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00074 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00075 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00076 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00077 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00078 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00079 ch_multiescape, ch_constituent, ch_constituent, ch_constituent,
00080 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00081 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00082 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00083 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00084 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00085 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00086 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00087 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00088 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00089 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00090 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00091 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00092 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00093 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00094 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00095 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00096 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00097 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00098 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00099 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00100 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00101 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00102 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00103 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00104 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00105 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00106 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00107 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00108 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00109 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00110 ch_constituent, ch_constituent, ch_constituent, ch_constituent,
00111 ch_constituent, ch_constituent, ch_constituent, ch_constituent};
00112
00113 enum ch_attr charattr[256]={
00114 illegal, illegal, illegal, illegal,
00115 illegal, illegal, illegal, illegal,
00116 illegal, illegal, illegal, illegal,
00117 illegal, illegal, illegal, illegal,
00118 illegal, illegal, illegal, illegal,
00119 illegal, illegal, illegal, illegal,
00120 illegal, illegal, illegal, illegal,
00121 illegal, illegal, illegal, illegal,
00122 alphabetic, alphabetic, alphabetic, alphabetic,
00123 alphabetic, alphabetic, alphabetic, alphabetic,
00124 alphabetic, alphabetic, alphabetic, alphabetic,
00125 alphabetic, alphabetic, alphabetic, alphabetic,
00126 alphadigit, alphadigit, alphadigit, alphadigit,
00127 alphadigit, alphadigit, alphadigit, alphadigit,
00128 alphadigit, alphadigit, package_marker, alphabetic,
00129 alphabetic, alphabetic, alphabetic, alphabetic,
00130 alphabetic, alphabetic, alphabetic, alphabetic,
00131 alphabetic, alphabetic, alphabetic, alphabetic,
00132 alphabetic, alphabetic, alphabetic, alphabetic,
00133 alphabetic, alphabetic, alphabetic, alphabetic,
00134 alphabetic, alphabetic, alphabetic, alphabetic,
00135 alphabetic, alphabetic, alphabetic, alphabetic,
00136 alphabetic, alphabetic, alphabetic, alphabetic,
00137 alphabetic, alphabetic, alphabetic, alphabetic,
00138 alphabetic, alphabetic, alphabetic, alphabetic,
00139 alphabetic, alphabetic, alphabetic, alphabetic,
00140 alphabetic, alphabetic, alphabetic, alphabetic,
00141 alphabetic, alphabetic, alphabetic, alphabetic,
00142 alphabetic, alphabetic, alphabetic, alphabetic,
00143 alphabetic, alphabetic, alphabetic, alphabetic,
00144 alphabetic, alphabetic, alphabetic, alphabetic,
00145 alphabetic, alphabetic, alphabetic, alphabetic,
00146 alphabetic, alphabetic, alphabetic, alphabetic,
00147 alphabetic, alphabetic, alphabetic, alphabetic,
00148 alphabetic, alphabetic, alphabetic, alphabetic,
00149 alphabetic, alphabetic, alphabetic, alphabetic,
00150 alphabetic, alphabetic, alphabetic, alphabetic,
00151 alphabetic, alphabetic, alphabetic, alphabetic,
00152 alphabetic, alphabetic, alphabetic, alphabetic,
00153 alphabetic, alphabetic, alphabetic, alphabetic,
00154 alphabetic, alphabetic, alphabetic, alphabetic,
00155 alphabetic, alphabetic, alphabetic, alphabetic,
00156 alphabetic, alphabetic, alphabetic, alphabetic,
00157 alphabetic, alphabetic, alphabetic, alphabetic,
00158 alphabetic, alphabetic, alphabetic, alphabetic,
00159 alphabetic, alphabetic, alphabetic, alphabetic,
00160 alphabetic, alphabetic, alphabetic, alphabetic,
00161 alphabetic, alphabetic, alphabetic, alphabetic,
00162 alphabetic, alphabetic, alphabetic, alphabetic,
00163 alphabetic, alphabetic, alphabetic, alphabetic,
00164 alphabetic, alphabetic, alphabetic, alphabetic,
00165 alphabetic, alphabetic, alphabetic, alphabetic,
00166 alphabetic, alphabetic, alphabetic, alphabetic,
00167 alphabetic, alphabetic, alphabetic, alphabetic,
00168 alphabetic, alphabetic, alphabetic, alphabetic,
00169 alphabetic, alphabetic, alphabetic, alphabetic,
00170 alphabetic, alphabetic, alphabetic, alphabetic,
00171 alphabetic, alphabetic, alphabetic, alphabetic,
00172 alphabetic, alphabetic, alphabetic, alphabetic,
00173 alphabetic, alphabetic, alphabetic, alphabetic,
00174 alphabetic, alphabetic, alphabetic, alphabetic,
00175 alphabetic, alphabetic, alphabetic, alphabetic,
00176 alphabetic, alphabetic, alphabetic, alphabetic,
00177 alphabetic, alphabetic, alphabetic, alphabetic
00178 };
00179
00180
00181
00182
00183
00184
00185
00186 #if IRIX || Linux_ppc
00187 #define Char int
00188 #else
00189 #define Char char
00190 #endif
00191
00192 static Char skip(ctx, f, ch)
00193 context *ctx;
00194 register pointer f;
00195 Char ch;
00196 { skipblank:
00197 while (syntaxtype((char)ch)==ch_white) {
00198 ch=readch(f);
00199 if (ch==EOF) return(EOF);}
00200 if (ch == ';' && (Spevalof(QREADTABLE)->c.rdtab.macro->c.vec.v[ch]
00201 == charmacro[';'])) {
00202
00203 do {
00204 ch=readch(f);
00205 if (ch==EOF) return(EOF); }
00206 while(ch!='\n');
00207 goto skipblank;} return(ch); }
00208
00209 static int nextch(ctx, f)
00210 context *ctx;
00211 register pointer f;
00212 {
00213 Char ch;
00214 ch=readch(f); ch=skip(ctx, f,ch); return(ch);}
00215
00216
00217
00218
00219
00220
00221 static pointer findlabel(labx)
00222 int labx;
00223 { register pointer obj,labid;
00224 labid=makeint(labx);
00225 obj=oblabels->c.lab.next;
00226 while (obj!=NIL) {
00227 if (obj->c.lab.label==labid) return(obj);
00228 else obj=obj->c.lab.next; }
00229 return(NIL);}
00230
00231 static pointer readlabdef(ctx,f,labx)
00232 context *ctx;
00233 pointer f;
00234 int labx;
00235 { pointer unsol, *unsolp, result,newlab;
00236
00237 if (findlabel(labx)!=NIL) error(E_READLABEL,makeint(labx));
00238 newlab=(pointer)makelabref(makeint(labx),UNBOUND,oblabels->c.lab.next);
00239 oblabels->c.lab.next=newlab;
00240 result=read1(ctx,f);
00241
00242
00243 newlab->c.lab.value=result;
00244 unsol=newlab->c.lab.unsolved;
00245 while (unsol!=NIL) {
00246 #if sun3 || (!alpha && system5) || sanyo
00247 unsolp=(pointer *)unsol;
00248 #endif
00249 #if sun4 || vax || news || mips || alpha || i386
00250 unsolp=(pointer *)((eusinteger_t)unsol & ~3);
00251 #endif
00252 unsol= *unsolp;
00253 *unsolp=result; }
00254 return(result);}
00255
00256 static addunsolved(labp,addr)
00257 pointer labp;
00258 pointer *addr;
00259 { *addr=labp->c.lab.unsolved;
00260 #if sun3 ||( !alpha && system5 ) || sanyo
00261 labp->c.lab.unsolved=(pointer)addr;
00262 #endif
00263 #if sun4 || vax || news || mips || alpha || i386
00264 { int i;
00265 i=intval(addr);
00266 labp->c.lab.unsolved=makeint(i);}
00267 #endif
00268 }
00269
00270 static pointer readlabref(ctx,f,val,subchar)
00271 pointer f;
00272 { register pointer obj,element;
00273 obj=findlabel(val);
00274 if (obj==NIL) error(E_READLABEL,makeint(val));
00275 if ((element=obj->c.lab.value)==UNBOUND) return(obj);
00276 else return(element);}
00277
00278
00279
00280
00281
00282
00283 static pointer readvector(ctx,f,size)
00284 register context *ctx;
00285 register pointer f;
00286 register int size;
00287 { register pointer result,element;
00288 register int i=0;
00289 Char ch;
00290 ch=nextch(ctx,f);
00291 if (size>0) {
00292 result=makevector(C_VECTOR,size);
00293 vpush(result);
00294 while ((ch!=')') && (ch!=EOF) && (i<size)) {
00295 unreadch(f,ch);
00296 element=read1(ctx,f);
00297 if (islabref(element)) {
00298 addunsolved(element,&result->c.vec.v[i]); }
00299 else result->c.vec.v[i]=element;
00300 i++;
00301 ch=nextch(ctx,f);}
00302 if (ch==')')
00303 while (i<size) result->c.vec.v[i++]=element;
00304 else {
00305 while (ch!=')' && ch!=EOF) ch=nextch(ctx,f);
00306 error(E_READ); }
00307 return(result);}
00308 else {
00309 while ((ch!=')') && (ch!=EOF)) {
00310 unreadch(f,ch);
00311 element=read1(ctx,f);
00312 ckpush(element);
00313 i++;
00314 ch=nextch(ctx,f);}
00315 result=makevector(C_VECTOR,i);
00316 while (i>0) {
00317 i--;
00318 element=vpop();
00319 if (islabref(element)) addunsolved(element,&result->c.vec.v[i]);
00320 else result->c.vec.v[i]=element; }
00321 return(result); } }
00322
00323 static pointer readivector(ctx,s)
00324 register context *ctx;
00325 register pointer s;
00326 { register int i=0,x;
00327 register pointer rvec;
00328 Char ch;
00329 ch=nextch(ctx,s);
00330 if (ch!='(') error(E_READFVECTOR);
00331 ch=nextch(ctx,s);
00332 while (ch!=')' && ch!=EOF) {
00333 if (isdigit(ch)) {
00334 x=0;
00335 while (isdigit(ch)) { x=x*10+ch-'0'; ch=readch(s);}
00336 if (ch=='.') ch=readch(s);}
00337 else {
00338 unreadch(s,ch);
00339 x=intval(read1(ctx,s));
00340 ch=nextch(ctx,s);}
00341 ckpush(makeint(x>>16)); ckpush(makeint(x & 0xffff));
00342 i++;}
00343 rvec=makevector(C_INTVECTOR,i);
00344 while (i>0) {
00345 x=intval(vpop());
00346 x=(intval(vpop())<<16) + x;
00347 rvec->c.ivec.iv[--i]=x;}
00348 return(rvec);}
00349
00350 static pointer readfvector(ctx,s)
00351 register context *ctx;
00352 register pointer s;
00353 { register int i=0,x;
00354 register pointer elm;
00355 float f;
00356 Char ch;
00357 numunion nu;
00358
00359 ch=nextch(ctx,s);
00360 if (ch!='(') error(E_READFVECTOR);
00361 ch=nextch(ctx,s);
00362 while (ch!=')' && ch!=EOF) {
00363 unreadch(s,ch);
00364 elm=read1(ctx,s);
00365 if (!isnum(elm)) error(E_READFVECTOR);
00366 if (isint(elm)) { f=intval(elm); elm=makeflt(f);}
00367 ckpush(elm);
00368 i++;
00369 ch=nextch(ctx,s);}
00370 elm=makevector(C_FLTVECTOR,i);
00371 while (i>0) elm->c.fvec.fv[--i]=fltval(vpop());
00372 return(elm);}
00373
00374 static pointer readobject(ctx,s)
00375 register context *ctx;
00376 register pointer s;
00377 {
00378 register pointer name, klass, elem, result;
00379 register int i,sz;
00380 Char ch;
00381
00382 ch=nextch(ctx,s);
00383 if (ch!='(') error(E_READOBJECT);
00384 name=read1(ctx,s);
00385 if (!issymbol(name)) error(E_READOBJECT);
00386 klass=speval(name);
00387 if (klass==UNBOUND) error(E_NOCLASS,name);
00388 if (!isclass(klass)) error(E_READOBJECT);
00389 if (isvecclass(klass)) {
00390 elem=read1(ctx,s);
00391 if (!isint(elem)) error(E_READOBJECT);
00392 sz=intval(elem);
00393 result=makevector(klass,sz);
00394 i=1;}
00395 else if (isclass(klass)) {
00396 result=(pointer)makeobject(klass);
00397 i=0;}
00398 else error(E_NOCLASS,name);
00399 vpush(result);
00400 ch=nextch(ctx,s);
00401 while (ch!=')' && ch!=EOF) {
00402 unreadch(s,ch);
00403 elem=read1(ctx,s);
00404 if (islabref(elem)) {
00405 addunsolved(elem,&result->c.obj.iv[i++]); }
00406 else result->c.obj.iv[i++]=elem;
00407 ch=nextch(ctx,s);
00408 }
00409 vpop();
00410 return(result); }
00411
00412 static pointer readstructure(ctx,s)
00413 register context *ctx;
00414 register pointer s;
00415 { register pointer name, klass, slot, elem, result, varvec, *slotp;
00416 Char ch;
00417
00418 ch=nextch(ctx,s);
00419 if (ch!='(') error(E_READOBJECT);
00420 name=read1(ctx,s);
00421 if (!issymbol(name)) error(E_READOBJECT);
00422 klass=speval(name);
00423 if (klass==UNBOUND) error(E_NOCLASS,name);
00424 if (!isclass(klass)) error(E_READOBJECT);
00425 if (isvecclass(klass)) { error(E_NOCLASS,name);}
00426 else if (isclass(klass)) result=(pointer)makeobject(klass);
00427 else error(E_NOCLASS,name);
00428 vpush(result);
00429 ch=nextch(ctx,s);
00430 while (ch!=')' && ch!=EOF) {
00431 unreadch(s,ch);
00432 slot=read1(ctx,s);
00433 if (!issymbol(slot)) error(E_NOSYMBOL);
00434 elem=read1(ctx,s);
00435 slotp=(pointer *)getobjv(slot,klass->c.cls.vars,result);
00436 if (slotp!=NULL) {
00437 if (islabref(elem)) {
00438 addunsolved(elem,slotp); }
00439 else *slotp=elem; }
00440 ch=nextch(ctx,s);
00441 }
00442 vpop();
00443 return(result); }
00444
00445
00446
00447
00448 static pointer read_sharp_char(ctx,f,val,subchar)
00449 register context *ctx;
00450 register pointer f;
00451 int val,subchar;
00452 { char ch;
00453 ch=readch(f); return(makeint(ch));}
00454
00455 static pointer read_sharp_comment(ctx,f,val,subchar)
00456 register context *ctx;
00457 register pointer f;
00458 register int val,subchar;
00459 { Char ch;
00460 val=0;
00461 ch=readch(f);
00462 morecomments:
00463 while (ch!=subchar && ch!='#' && ch!=EOF) ch=readch(f);
00464 if (ch==EOF) return((pointer)EOF);
00465 if (ch==subchar) {
00466 ch=readch(f);
00467 if (ch=='#') { if (--val<0) return(UNBOUND);}
00468 goto morecomments;}
00469 ch=readch(f);
00470 if (ch==subchar) { ch=readch(f); val++;}
00471 goto morecomments;}
00472
00473 static pointer read_sharp_hex(ctx,f,val,subchar)
00474 register context *ctx;
00475 register pointer f;
00476 eusinteger_t val;
00477 int subchar;
00478 { register int i=0,j,x,c,p,q;
00479 pointer b;
00480 eusinteger_t *bv;
00481 char ch, buf[WORD_SIZE];
00482
00483 ch=readch(f);
00484 while (i<WORD_SIZE && isxdigit(ch)) { buf[i++] = ch; ch=readch(f);}
00485 unreadch(f,ch); buf[i]=0;
00486 if (i<sizeof(eusinteger_t)*2) { sscanf(buf,"%lx",&val); return(makeint(val));}
00487 else {
00488 b= (pointer)makebig((i*4+WORD_SIZE-1)/(WORD_SIZE-1));
00489 bv=bigvec(b);
00490 p=0;q=0;
00491 for (j=i-1; j>=0; j--) {
00492 c=toupper(buf[j]);
00493 x=(c<='9')?(c-'0'):(c-'A'+10);
00494 bv[p/(WORD_SIZE-1)] |= ((x << q) & MASK);
00495 if (q>=(WORD_SIZE-4)) bv[p/(WORD_SIZE-1) + 1] = x>>(WORD_SIZE-1-q);
00496 p +=4; q = (q+4) % (WORD_SIZE-1);
00497 }
00498 b=(pointer)normalize_bignum(b);
00499 return(b);}
00500 }
00501
00502 static pointer read_sharp_octal(ctx,f,val,subchar)
00503 register context *ctx;
00504 pointer f;
00505 eusinteger_t val;
00506 int subchar;
00507 { register int i=0;
00508 char buf[WORD_SIZE/2], ch;
00509 ch=readch(f); val=0;
00510 while (i<WORD_SIZE/2 && ch>='0' && ch<'8') { buf[i++] = ch; ch=readch(f);}
00511 unreadch(f,ch); buf[i]=0;
00512 sscanf(buf,"%lo",&val);
00513 return(makeint(val));}
00514
00515 static pointer read_sharp_function(ctx,f,val,subchar)
00516 register context *ctx;
00517 pointer f;
00518 int val,subchar;
00519 { return(cons(ctx,FUNCTION,cons(ctx,read1(ctx,f),NIL)));}
00520
00521 static pointer read_uninterned_symbol(ctx,f,val,subchar,token)
00522 context *ctx;
00523 pointer f;
00524 int val,subchar;
00525 char token[];
00526 { register int i=0;
00527 char ch;
00528 ch=readch(f);
00529 while (syntaxtype(ch)==ch_constituent) {
00530 token[i++]=to_upper(ch); ch=readch(f);}
00531 token[i]=0; unreadch(f,ch);
00532 return(makesymbol(ctx,(char *)token,i,NIL));}
00533
00534 static pointer read_sharp_eval(ctx,f)
00535 register context *ctx;
00536 pointer f;
00537 { pointer p;
00538 p=read1(ctx,f);
00539
00540 return(eval(ctx,p));}
00541
00542 static pointer eval_read_cond(ctx,expr)
00543 context *ctx;
00544 pointer expr;
00545 { pointer r;
00546 if (issymbol(expr)) return(memq(expr,speval(FEATURES)));
00547 if (iscons(expr)) {
00548 if (ccar(expr)==QNOT) {
00549 r=eval_read_cond(ctx,ccar(ccdr(expr)));
00550 return((r==NIL)?T:NIL);}
00551 else if (ccar(expr)==QAND) {
00552 expr=ccdr(expr);
00553 while (iscons(expr)) {
00554 r=eval_read_cond(ctx,ccar(expr));
00555 if (r==NIL) return(NIL);
00556 else expr=ccdr(expr);}
00557 return(T);}
00558 else if (ccar(expr)==QOR) {
00559 expr=ccdr(expr);
00560 while (iscons(expr)) {
00561 r=eval_read_cond(ctx,ccar(expr));
00562 if (r!=NIL) return(T);
00563 else expr=ccdr(expr);}
00564 return(NIL);}}
00565 error(E_USER,(pointer)"AND/OR/NOT expected in #+ or #-", expr);}
00566
00567 static pointer read_cond_plus(ctx,f)
00568 register context *ctx;
00569 register pointer f;
00570 { register pointer flag,result;
00571 flag=read1(ctx,f);
00572 vpush(flag);
00573 result=read1(ctx,f);
00574 if (eval_read_cond(ctx,flag)==NIL) result=(pointer)UNBOUND;
00575 vpop();
00576 return(result);}
00577
00578 static pointer read_cond_minus(ctx,f)
00579 register context *ctx;
00580 register pointer f;
00581 { register pointer flag,result;
00582 flag=read1(ctx,f);
00583 vpush(flag);
00584 result=read1(ctx,f);
00585 if (eval_read_cond(ctx,flag)!=NIL) result=(pointer)UNBOUND;
00586 vpop();
00587 return(result);}
00588
00589 static pointer read_sharp_object(ctx,f)
00590 register context *ctx;
00591 register pointer f;
00592 { register pointer element,result,obj;
00593 register int val;
00594 Char ch;
00595 element=read1(ctx,f);
00596 if (!issymbol(element)) error(E_NOSYMBOL);
00597 element=speval(element);
00598 if (element==UNBOUND || !isclass(element)) error(E_NOCLASS,element);
00599 obj=read1(ctx,f); val=ckintval(obj);
00600 result=makepointer(val);
00601 if (classof(result)!=element)
00602 error(E_TYPEMISMATCH, (pointer)"read #<> class mismatch");
00603 ch=readch(f);
00604 while (ch!='>' && ch!=EOF) ch=readch(f);
00605 return(result);}
00606
00607 static pointer readsharp(ctx,f,ch,token)
00608 register context *ctx;
00609 register pointer f;
00610 Char ch;
00611 char token[];
00612 { register int i=0,val=0,subchar;
00613 pointer macrofunc,result;
00614 pointer (*intmac)();
00615
00616 ch=readch(f);
00617 if (ch==EOF) return(UNBOUND);
00618 while (isdigit(ch)) {
00619 val=val*10+ch-'0'; ch=nextch(ctx,f);
00620 if (ch==EOF) return(UNBOUND);}
00621 subchar=to_upper(ch);
00622 macrofunc=Spevalof(QREADTABLE)->c.rdtab.dispatch->c.vec.v[subchar];
00623 if (macrofunc==NIL) error(E_USER,(pointer)"no # macro defined");
00624 if (isint(macrofunc)) {
00625 intmac=(pointer (*)())(intval(macrofunc));
00626 result=(*intmac)(ctx,f,val,subchar,token);}
00627 else {
00628 vpush(f); vpush(makeint(subchar)); vpush(makeint(val));
00629 result=ufuncall(ctx,macrofunc,macrofunc,(pointer)(ctx->vsp-3),NULL,3);
00630 ctx->vsp-=3;}
00631 return(result);}
00632
00633 static pointer readstring(ctx,f,terminator)
00634 register context *ctx;
00635 pointer f;
00636 int terminator;
00637 { int tleng = 0, lengmax=MAXSTRINGLENGTH;
00638 byte buf[MAXSTRINGLENGTH], *token, *newtoken;
00639 int ch, malloced=FALSE;
00640 pointer p;
00641
00642 ch=readch(f);
00643 token=buf;
00644 while ((ch!=terminator) && (ch!=EOF)) {
00645 if (syntaxtype(ch) == ch_sglescape) ch=readch(f);
00646 token[tleng++]=ch;
00647 if (tleng >= lengmax) {
00648
00649 newtoken=(byte *)malloc(lengmax*2);
00650 if (newtoken == NULL) {
00651 if (malloced==TRUE) cfree(token);
00652 error(E_LONGSTRING);}
00653 memcpy(newtoken,token,tleng);
00654 if (malloced==TRUE) cfree(token);
00655 malloced=TRUE;
00656 token=newtoken; lengmax=lengmax*2;
00657 }
00658 ch=readch(f);}
00659 token[tleng] = '\0';
00660 p=makestring((char *)token,tleng);
00661 if (malloced==TRUE) cfree(token);
00662 return(p);
00663 }
00664
00665 static pointer readsymbol(ctx,leng,colon, token)
00666 register context *ctx;
00667 register int leng,colon;
00668 char token[];
00669 { register pointer pkg;
00670 pointer pkgstr,sym;
00671 register int doublecolon=1;
00672 int hash;
00673 if (colon==0) pkg=keywordpkg;
00674 else if (colon>0) {
00675 if (charattr[token[colon-1]]==package_marker) {
00676 pkg=(pointer)searchpkg((byte *)token,colon-1);}
00677 else {
00678 doublecolon=0;
00679 pkg=(pointer)searchpkg((byte *)token,colon);}
00680 if (pkg==(pointer)NULL) {
00681 if (doublecolon) colon--;
00682 pkgstr=makestring(token,colon);
00683 vpush(pkgstr);
00684 error(E_NOPACKAGE,pkgstr);} }
00685 else pkg=Spevalof(PACKAGE);
00686 colon++;
00687 if (doublecolon) return(intern(ctx,&token[colon],leng-colon,pkg));
00688 else {
00689 sym=findsymbol((byte *)&token[colon],leng-colon, pkg->c.pkg.symvector, &hash);
00690
00691 if (sym) return(sym);
00692 else {
00693 pkgstr=makestring(token,leng);
00694 fprintf(stderr,"%s ",token);
00695 vpush(pkgstr);
00696 error(E_EXTSYMBOL,pkgstr);}
00697 } }
00698
00699
00700 #if news || sanyo
00701 int strtol(str,ptr,base)
00702 register char *str,**ptr;
00703 register int base;
00704 { long val=0,sign=1;
00705 char ch;
00706 while (isspace(*str)) str++;
00707 ch= *str;
00708 if (ch=='+') str++; else if (ch=='-') { str++; sign= -1;}
00709 if (base<=10) {
00710 while ('0'<= *str && *str<('0'+base)) val=val*base+(*str++)-'0';
00711 return(sign*val);}
00712 else {
00713 while (1) {
00714 if ('0'<= *str && *str<='9') val=val*base+(*str++ -'0');
00715 else if ('A'<= *str && *str<('A'+base-10)) val=val*base+(*str++ - 'A'+10);
00716 else if ('a'<= *str && *str<('a'+base-10)) val=val*base+(*str++ - 'a'+10);
00717 else break;
00718 continue;}
00719 return(sign*val);}}
00720 #endif
00721
00722 static pointer readint(ctx,token,len)
00723 context *ctx;
00724 char *token;
00725 int len;
00726 { int base=intval(Spevalof(READBASE));
00727 int head,i,sign=1, k;
00728 pointer b;
00729
00730 if (len<8) {
00731 i=strtol(token,NULL,base);
00732 return(makeint(i));}
00733 else {
00734 if (token[0]=='+') { head=1;}
00735 else if (token[0]=='-') {head=1; sign= -1;}
00736 else head=0;
00737 b=(pointer)makebig1(0);
00738 vpush(b);
00739 for (i=head; i<len; i++) {
00740 k= (int) token[i];
00741 if (k>='0' && k<='9') k= k-'0';
00742 else if (k>='A' && k<='Z') k=k-'A'+10;
00743 else if (k>='a' && k<='z') k=k-'a'+10;
00744 else if (k=='.') continue;
00745 else error(E_USER,(pointer)"illegal integer consituent char");
00746 mul_int_big(base,b);
00747 add_int_big(k,b); }
00748 if (sign<0) complement_big(b);
00749 b=(pointer)normalize_bignum(b);
00750 }
00751 ctx->lastalloc= vpop();
00752 return(b);}
00753
00754 is_digit(ch,base)
00755 register int ch,base;
00756 { if (ch<'0') return(FALSE);
00757 if (base<=10)
00758 if (ch<'0'+base) return(TRUE);
00759 else return(FALSE);
00760 else if (ch<='9') return(TRUE);
00761 else if ('A'<=ch && ch<'A'+base-10) return(TRUE);
00762 else return(FALSE);}
00763
00764 pointer read_delimited_list(ctx,f,delim_char,token)
00765 register context *ctx;
00766 pointer f;
00767 int delim_char;
00768 char token[];
00769 { pointer result=NIL;
00770 pointer temp,element;
00771 Char ch;
00772 ch=nextch(ctx,f);
00773 vpush(STOPPER);
00774 while (ch!=delim_char && ch!=EOF) {
00775 if (ch=='.') {
00776 ch=readch(f); unreadch(f,ch);
00777 if (syntaxtype(ch)==ch_constituent) {
00778 token[0]='.';
00779 element=read2(ctx,f,0,0,1,token, -1);}
00780 else if (syntaxtype(ch)==ch_white) {
00781 result=read1(ctx,f);
00782 ch=nextch(ctx,f);
00783 if (ch!=delim_char) error(E_READ);
00784 break;}
00785 else error(E_READ);}
00786 else { unreadch(f,ch); element=read1(ctx,f);}
00787 if (element!=UNBOUND && element!=(pointer)EOF) ckpush(element);
00788 ch=nextch(ctx,f);}
00789 while ((element=vpop())!=STOPPER) {
00790 temp=cons(ctx,element,result);
00791 if (islabref(element)) addunsolved(element,&temp->c.cons.car);
00792 if (islabref(result)) addunsolved(result,&temp->c.cons.cdr);
00793 result=temp;}
00794 return(result); }
00795
00796 static pointer readlist(ctx,f,ch,token)
00797 register context *ctx;
00798 pointer f;
00799 char ch, token[];
00800 { return(read_delimited_list(ctx,f,')',token));}
00801
00802 static pointer readquote(ctx,f)
00803 register context *ctx;
00804 pointer f;
00805 { pointer q;
00806 q=read1(ctx,f);
00807 if (q==(pointer)EOF) return((pointer)EOF);
00808 return(cons(ctx,QUOTE,cons(ctx,q,NIL)));}
00809
00810 static pointer readcomment(ctx,f)
00811 pointer f;
00812 { register Char ch;
00813 do { ch=readch(f);} while (ch!='\n' && ch!=EOF);
00814 return(UNBOUND);}
00815
00816 static pointer readrparen(ctx,f)
00817 { return(UNBOUND);}
00818
00819
00820
00821 int gcd(u,v)
00822 register int u,v;
00823 { register int t;
00824 if(u<0) u = -u;
00825 if(v<0) v = -v;
00826 if(u<v) {t=u; u=v; v=t;}
00827 while(v!=0){t=u % v; u=v; v=t;}
00828 return(u);}
00829
00830 static pointer readratio(ctx,token,slash)
00831 context *ctx;
00832 char *token;
00833 int slash;
00834 { int num, denom, g;
00835 extern pointer makeratio();
00836 num=strtol(token,NULL,intval(Spevalof(READBASE)));
00837 denom=strtol(&token[slash+1],NULL,intval(Spevalof(READBASE)));
00838 g=gcd(num, denom);
00839 if (g!=0) { num /= g; denom /= g;}
00840 else return(makeint(0));
00841 if (denom==1) return(makeint(num));
00842 return(makeratio(num, denom));}
00843
00844
00845 static pointer read2(ctx,ins,escaped,multiescaped,i,token,colon)
00846 register context *ctx;
00847 register pointer ins;
00848 int escaped,multiescaped,i;
00849 char token[];
00850 int colon;
00851 { register int j,c, base;
00852 int slash;
00853 enum ch_type ctype;
00854
00855 int ch;
00856 pointer readcase;
00857 numunion nu;
00858 extern double atof();
00859
00860 readcase=Spevalof(QREADTABLE)->c.rdtab.readcase;
00861
00862 if (multiescaped) goto step9;
00863 step8:
00864 if (i>=MAXTOKENLENGTH) error(E_LONGSTRING);
00865 ch=readch(ins);
00866 if (ch==EOF) goto step10;
00867 if (ch<0) ch &= 0xff;
00868 ctype=syntaxtype(ch);
00869 switch(ctype) {
00870 case ch_constituent: case ch_nontermacro:
00871 if (charattr[ch]==package_marker) colon=i;
00872 if (readcase==K_DOWNCASE) ch=to_lower(ch);
00873 else if (readcase==K_PRESERVE) ch=ch;
00874 else ch=to_upper(ch);
00875 token[i++]=ch; goto step8;
00876 case ch_sglescape:
00877 token[i++]=readch(ins); escaped=1; goto step8;
00878 case ch_multiescape:
00879 goto step9;
00880 case ch_illegal:
00881 error(E_ILLCH,makeint(ch)); break;
00882 case ch_termmacro:
00883 unreadch(ins,ch); goto step10;
00884 case ch_white:
00885 unreadch(ins,ch); goto step10;
00886 default: error(E_USER,(pointer)"unknown char type");}
00887 step9:
00888 escaped=1;
00889 if (i>=MAXTOKENLENGTH) error(E_LONGSTRING);
00890 ch=readch(ins);
00891 if (ch==EOF) error(E_EOF);
00892 ch &= 0xff;
00893 ctype=syntaxtype(ch);
00894 switch(ctype) {
00895 case ch_constituent: case ch_white:
00896 case ch_nontermacro: case ch_termmacro:
00897 token[i++]=ch; goto step9;
00898 case ch_sglescape:
00899 ch=readch(ins); token[i++]=ch; goto step9;
00900 case ch_multiescape:
00901 goto step8;
00902 default: error(E_ILLCH,makeint(ch));}
00903 step10:
00904
00905 token[i]=0;
00906 if (escaped) return(readsymbol(ctx,i,colon,token));
00907 base=intval(Spevalof(READBASE));
00908
00909 j=0;
00910 if ((token[j]=='+') || (token[j]=='-')) j++;
00911 else if (token[j]=='.' && token[j+1]=='\0')
00912 return(readsymbol(ctx,i,colon,token));
00913 if (is_digit(token[j],base) || token[j]=='.') {
00914 while (is_digit(token[j],base)) j++;
00915 if (token[j] == '.') {
00916 if (++j==i) return(readint(ctx,token,i));
00917
00918 while (is_digit(token[j],base)) j++;
00919 c=to_upper(token[j]);
00920 if (c=='E' || c=='D' || c=='F' || c=='L') {
00921 c=j; j++;
00922 if ((token[j]=='+') || (token[j]=='-')) j++;
00923 while (is_digit(token[j],base)) j++;
00924 if (j==i) { token[c]='E'; return(makeflt(atof(token)));}
00925 else return(readsymbol(ctx,i,colon,token));}
00926 else if (j==i) return(makeflt(atof(token)));
00927 else return(readsymbol(ctx,i,colon,token));}
00928 else if (token[j] == '/') {
00929 slash=j;
00930 if (++j==i) return(readsymbol(i,colon));
00931
00932 while (is_digit(token[j],base)) j++;
00933 if (j==i) return(readratio(ctx,token,slash));
00934 else return(readsymbol(i,colon));}
00935 else if (j==i) return(readint(ctx,token,i));
00936 else {
00937 c=to_upper(token[j]);
00938 if (c=='E' || c=='D' || c=='F' || c=='L') {
00939 c=j; j++;
00940 if ((token[j]=='+') || (token[j]=='-')) j++;
00941 while (is_digit(token[j],base)) j++;
00942 if (j==i) { token[c]='E'; return(makeflt(atof(token)));}
00943 else return(readsymbol(ctx,i,colon,token));}
00944 else if (j==i) return(makeflt(atof(token)));
00945 else return(readsymbol(ctx,i,colon,token));} }
00946 else return(readsymbol(ctx,i,colon,token));}
00947
00948 static pointer read1(ctx,ins)
00949 register context *ctx;
00950 register pointer ins;
00951 { register enum ch_type ctype;
00952 register int firstch;
00953 register pointer macrofunc,result;
00954 pointer (*intmac)();
00955 int colon;
00956
00957 int ch;
00958 char token[MAXTOKENLENGTH];
00959 pointer readcase;
00960
00961 colon= -1;
00962 step1:
00963 ch=readch(ins);
00964 if (ch==EOF) return((pointer)EOF);
00965 ch &= 0xff;
00966 firstch=ch;
00967 ctype=syntaxtype(ch);
00968 switch(ctype) {
00969 case ch_illegal: error(E_ILLCH,makeint(ch));
00970 case ch_white: goto step1;
00971 case ch_termmacro: case ch_nontermacro:
00972 macrofunc=Spevalof(QREADTABLE)->c.rdtab.macro->c.vec.v[ch];
00973 if (macrofunc==NIL) error(E_USER,(pointer)"no char macro defined");
00974 if (isint(macrofunc)) {
00975 intmac=(pointer (*)())(intval(macrofunc));
00976 result=(*intmac)(ctx,ins,ch,token);}
00977 else {
00978 vpush(ins); vpush(makeint(ch));
00979 result=ufuncall(ctx,macrofunc,macrofunc,(pointer)(ctx->vsp-2),NULL,2);
00980 ctx->vsp-=2;}
00981
00982
00983 return(result);
00984 case ch_sglescape: token[0]=readch(ins);
00985 return(read2(ctx,ins,1,0,1,token,colon));
00986 case ch_multiescape: return(read2(ctx,ins,1,1,0,token,colon));
00987 case ch_constituent:
00988 if (charattr[ch]==package_marker) colon=0;
00989 readcase=Spevalof(QREADTABLE)->c.rdtab.readcase;
00990 if (readcase==K_DOWNCASE) ch=to_lower(ch);
00991 else if (readcase==K_PRESERVE) ch=ch;
00992 else ch=to_upper(ch);
00993 token[0]= ch;
00994 return(read2(ctx,ins,0,0,1,token,colon));}}
00995
00996 pointer reader(ctx,f,recursivep)
00997 register context *ctx;
00998 register pointer f,recursivep;
00999 { register pointer val;
01000 Char ch;
01001 current_syntax=Spevalof(QREADTABLE)->c.rdtab.syntax->c.str.chars;
01002 ch=nextch(ctx,f);
01003 if (ch==EOF) return((pointer)EOF);
01004 while (ch==')') ch=nextch(ctx,f);
01005 unreadch(f,ch);
01006 if (recursivep==NIL) {
01007 oblabels->c.lab.next=NIL;
01008 val=read1(ctx,f);
01009 oblabels->c.lab.next=NIL;}
01010 else val=read1(ctx,f);
01011 if (val==UNBOUND) return(NIL);
01012 return(val);}
01013
01014 initreader(ctx)
01015 register context *ctx;
01016 { register pointer rdtable;
01017 register int i;
01018
01019 charmacro['(']=makeint(readlist);
01020 charmacro[')']=makeint(readrparen);
01021 charmacro['#']=makeint(readsharp);
01022 charmacro['\'']=makeint(readquote);
01023 charmacro['"']=makeint(readstring);
01024 charmacro[';']=makeint(readcomment);
01025
01026 sharpmacro['\\']=makeint(read_sharp_char);
01027 sharpmacro['\'']=makeint(read_sharp_function);
01028 sharpmacro[':']=makeint(read_uninterned_symbol);
01029 sharpmacro[',']=makeint(read_sharp_eval);
01030 sharpmacro['.']=makeint(read_sharp_eval);
01031 sharpmacro['|']=makeint(read_sharp_comment);
01032 sharpmacro['+']=makeint(read_cond_plus);
01033 sharpmacro['-']=makeint(read_cond_minus);
01034 sharpmacro['#']=makeint(readlabref);
01035 sharpmacro['=']=makeint(readlabdef);
01036 sharpmacro['(']=makeint(readvector);
01037 sharpmacro['<']=makeint(read_sharp_object);
01038 sharpmacro['X']=makeint(read_sharp_hex);
01039 sharpmacro['O']=makeint(read_sharp_octal);
01040 sharpmacro['S']=makeint(readstructure);
01041 sharpmacro['F']=makeint(readfvector);
01042 sharpmacro['I']=makeint(readivector);
01043 sharpmacro['J']=makeint(readobject);
01044 sharpmacro['V']=makeint(readobject);
01045
01046
01047 rdtable=(pointer)makereadtable(ctx);
01048 Spevalof(QREADTABLE)=rdtable;
01049 for (i=0; i<256; i++) {
01050 rdtable->c.rdtab.syntax->c.str.chars[i]=(int)chartype[i];
01051 rdtable->c.rdtab.macro->c.vec.v[i]=charmacro[i];
01052 rdtable->c.rdtab.dispatch->c.vec.v[i]=sharpmacro[i];
01053 rdtable->c.rdtab.readcase=K_UPCASE;
01054 }
01055 }