home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 11162 < prev    next >
Internet Message Format  |  1994-08-23  |  29KB

  1. Path: wupost!uhog.mit.edu!news.kei.com!travelers.mail.cornell.edu!newstand.syr.edu!galileo.cc.rochester.edu!ceas.rochester.edu!ceas.rochester.edu!not-for-mail
  2. From: weisberg@kirchoff.ee.rochester.edu (Jeff Weisberg)
  3. Newsgroups: alt.sources
  4. Subject: jlisp interpreter part07 / 10
  5. Followup-To: alt.sources.d
  6. Date: 23 Aug 1994 11:08:00 -0400
  7. Organization: University of Rochester School of Engineering and Applied Science
  8. Lines: 1390
  9. Message-ID: <Jlisp94Aug23part07@ee.rochester.edu>
  10. References: <Jlisp94Aug23Notice@ee.rochester.edu>
  11. NNTP-Posting-Host: kirchoff.ee.rochester.edu
  12.  
  13.  
  14. Archive-name: jlisp-1.03
  15. Submitted-by: weisberg@ee.rochester.edu
  16.  
  17. #! /bin/sh
  18. # 0. this is shell archive
  19. # 1. Remove everything above the #! /bin/sh line
  20. # 2. Save the resulting text in a file
  21. # 3. Execute the file with /bin/sh (not csh)
  22. # 4. Or use your favorite variant of unshar
  23. # 5. To overwrite existing files use "sh -c"
  24. #
  25. # Created by: weisberg@ankara on Tue Aug 23 10:51:39 EDT 1994
  26. #
  27. # This is part 07
  28.  
  29. if test -f jlisp-1.03/src/port.c -a "$1" != "-c" ; then
  30.     echo "will not overwrite jlisp-1.03/src/port.c"
  31. else
  32.     echo "    x - jlisp-1.03/src/port.c (7514 bytes)"
  33.     sed 's/^X//' > jlisp-1.03/src/port.c << \CEST_TOUT
  34. X
  35. X/*
  36. X    Copyright (c) 1994 Jeff Weisberg
  37. X
  38. X    see the file "License"
  39. X*/
  40. X
  41. X#ifdef RCSID
  42. Xstatic const char *const rcsid
  43. X= "@(#)$Id: port.c,v 1.26 94/08/23 07:20:10 weisberg Exp Locker: weisberg $";
  44. X#endif
  45. X
  46. X
  47. X/* I/O ports */
  48. X
  49. X#include <jlisp.h>
  50. X#include <stdio.h>
  51. X#include <setjmp.h>
  52. X#include <unistd.h>
  53. X#include <fcntl.h>
  54. X
  55. Xtypedef struct {
  56. X    void (*mark)(Obj);
  57. X    int (*free)(Obj);
  58. X    int (*print)(Obj,Obj,int);
  59. X    Obj (*equal)(Obj, Obj);
  60. X    int (*getc)(Obj);
  61. X    void (*ungetc)(Obj,int);
  62. X    void (*flush)(Obj);
  63. X    void (*putc)(Obj,int);
  64. X    void (*seek)(Obj, int);
  65. X    Obj (*tell)(Obj);
  66. X} PortDesc;
  67. X
  68. Xextern Obj sym_eof;
  69. X
  70. Xextern void mark0(), markcdr();
  71. Xextern int free0();
  72. Xextern Obj eqcdr();
  73. X
  74. Xvoid funreadc();
  75. Xint  freadc(), freefile(), freepipe();
  76. Xint strreadc();
  77. Xvoid strunreadc();
  78. Xvoid flflush(), flputc(), strputc();
  79. Xvoid flseek(), strseek();
  80. XObj fltell(), strtell();
  81. X
  82. XObj Fclose(Obj);
  83. X
  84. XPortDesc pdesc[] = {
  85. X    {mark0, freefile, 0, eqcdr, freadc, funreadc, flflush, flputc, flseek, fltell },    /* std file */
  86. X    {mark0, freepipe, 0, eqcdr, freadc, funreadc, flflush, flputc, flseek, fltell },    /* pipe */
  87. X    {markcdr, free0,  0, eqcdr, strreadc, strunreadc, 0, strputc, strseek, strtell },    /* string input */
  88. X    {0,0,0,0,0,0,0,0}
  89. X};
  90. X
  91. X
  92. X/* entries to vtbl table in jlisp.c */
  93. Xvoid markport(Obj p){
  94. X    void (*fnc)(Obj);
  95. X    int t = CAR(p) >> 14;
  96. X
  97. X    fnc = pdesc[t].mark;
  98. X
  99. X    if(fnc) fnc(p);
  100. X    else mark0(p);
  101. X}
  102. X
  103. Xint freeport(Obj p){
  104. X    int (*fnc)(Obj);
  105. X    int t = CAR(p) >> 14;
  106. X
  107. X    fnc = pdesc[t].free;
  108. X
  109. X    if(fnc) return fnc(p);
  110. X    else return free0(p);
  111. X}
  112. X
  113. Xint prnport(Obj p, Obj s, int h){
  114. X    int (*fnc)(Obj,Obj,int);
  115. X    int t = CAR(p) >> 14;
  116. X
  117. X    fnc = pdesc[t].print;
  118. X
  119. X    if(fnc) return fnc(p, s, h);
  120. X    else return 0;
  121. X}
  122. X
  123. XObj eqport(Obj a, Obj b){
  124. X    Obj (*fnc)(Obj,Obj);
  125. X    int t = CAR(a) >> 14;
  126. X
  127. X    fnc = pdesc[t].equal;
  128. X
  129. X    if(fnc) return fnc(a, b);
  130. X    else return eqcdr(a, b);
  131. X}
  132. X
  133. X
  134. X/* entries for port desc table (top of this file) */
  135. Xint freefile(Obj a){
  136. X
  137. X    fclose( CFILEPTR( a ));
  138. X    return 1;
  139. X}
  140. X
  141. Xint freepipe(Obj a){
  142. X
  143. X    pclose( CFILEPTR( a ));
  144. X    return 1;
  145. X}
  146. X
  147. Xint freadc(Obj p){
  148. X    return fgetc( CFILEPTR(p) );
  149. X}
  150. X
  151. Xvoid funreadc(Obj p, int c){
  152. X    ungetc(c, CFILEPTR(p));
  153. X}
  154. X
  155. Xvoid flflush(Obj p){
  156. X    fflush( CFILEPTR(p));
  157. X}
  158. X
  159. Xvoid flputc(Obj p, int c){
  160. X    fputc(c, CFILEPTR(p));
  161. X}
  162. X
  163. Xvoid flseek(Obj p, int i){
  164. X    fseek(CFILEPTR(p), i, SEEK_SET);
  165. X}
  166. X
  167. XObj fltell(Obj p){
  168. X    return MAKINT( ftell(CFILEPTR(p)));
  169. X}
  170. X
  171. X/* string port code is now in string.c */
  172. X
  173. XObj openport(Obj a, char *mode, int m, char*fnc){
  174. X    FILE*fp;
  175. X    int p=0;
  176. X
  177. X    if(! STRINGP(a))
  178. X        return jlerror(fnc, a, "WTA: filename expected");
  179. X
  180. X    if( CCHARS(a)[0] == '|'){
  181. X        p = 1;
  182. X        fp = popen( CCHARS(a)+1, mode);
  183. X    }else
  184. X        fp = fopen( CCHARS(a), mode);
  185. X
  186. X    if( !fp)
  187. X        return IC_NIL;
  188. X    return makport( fp, m + 4*p);    /* 4*p => subtype==pipe */
  189. X}
  190. X
  191. X
  192. XDEFUN("open:read", Fopenread,Sopenread, 1,1,1,0,
  193. X      "(open:read filename) Open a file for reading",
  194. X      (Obj a))
  195. X{
  196. X    return openport(a, "r", READABLE, Sopenread.name);
  197. X}
  198. X
  199. XDEFUN("open:write",Fopenwrite,Sopenwrite,1,1,1,0,
  200. X      "(open:write filename) Open a file for writing",
  201. X      (Obj a))
  202. X{
  203. X    return openport(a, "w", WRITABLE, Sopenwrite.name);
  204. X}
  205. X
  206. XDEFUN("open:read/write", Fopenrw, Sopenrw, 1,1,1,0,
  207. X      "(open:read/write filename) Open a file for reading and writing",
  208. X      (Obj a))
  209. X{
  210. X    return openport(a, "r+", READABLE|WRITABLE, Sopenrw.name);
  211. X}
  212. X
  213. XDEFUN("open:append",Fopenappend,Sopenappend,1,1,1,0,
  214. X      "(open:append filename) Open a file for appending",
  215. X      (Obj a))
  216. X{
  217. X    return openport(a, "a", WRITABLE, Sopenappend.name);
  218. X}
  219. X
  220. XDEFUN("open:string", Fopen_str, Sopen_str, 1,1,1,0,
  221. X      "(open:string string) Open a string as an io port",
  222. X      (Obj str))
  223. X{
  224. X    Obj p = newcell(), foo;
  225. X    int sigs;
  226. X
  227. X    if(! STRINGP(str))
  228. X        return jlerror(Sopen_str.name, str, "WTA: stringp");
  229. X
  230. X    foo = Fcons( MAKINT(0), str);
  231. X    DISABLE( sigs );
  232. X    CAR(p) = MAKETYPE( TPV_IOPORT ) | ((8+READABLE+WRITABLE) <<12);
  233. X    CDR(p) = foo;
  234. X    RENABLE( sigs );
  235. X    
  236. X    return p;
  237. X}
  238. X
  239. XDEFUN("load", Fload, Sload, 1,1,1,0,
  240. X      "(load filename) load a lisp file",
  241. X      (Obj file))
  242. X{
  243. X    /* this is used only for the initial init file
  244. X    which then redefines load to a much more useful
  245. X    function (with more jlerror handling...) */
  246. X    FILE *fp;
  247. X    Obj foo;
  248. X    
  249. X    if( STRINGP(file)){
  250. X        Fdefine(maksym_c("*current-file*"), file, IC_UNSPEC);
  251. X        file = Fopenread(file);
  252. X    }
  253. X    if( NULLP( file )) return IC_FALSE;
  254. X
  255. X    if( ! RPORTP(file))
  256. X        return IC_FALSE;
  257. X        /* return jlerror("load",file,"WTA: filename or input port p");  */
  258. X
  259. X    fp = CFILEPTR( file );
  260. X
  261. X    while( !feof( fp )){
  262. X        foo = Fread(file);
  263. X        /* Fdisplay( foo, IC_UNSPEC ); */
  264. X        Feval( foo );
  265. X    }
  266. X    Fclose( file );
  267. X    return IC_TRUE;
  268. X}
  269. X
  270. X
  271. Xint readchar(Obj port){
  272. X    int (*fnc)(Obj);
  273. X    int t = CAR(port) >> 14;
  274. X
  275. X    fnc = pdesc[t].getc;
  276. X
  277. X    if(fnc) return fnc(port);
  278. X    else return EOF;
  279. X}
  280. X
  281. Xvoid unreadchar(Obj port, int c){
  282. X    void (*fnc)(Obj,int);
  283. X    int t = CAR(port) >> 14;
  284. X
  285. X    fnc = pdesc[t].ungetc;
  286. X
  287. X    if(fnc) fnc(port, c);
  288. X
  289. X}
  290. X
  291. Xvoid writechar(Obj port, int c){
  292. X    void (*fnc)(Obj,int);
  293. X    int t = CAR(port) >> 14;
  294. X
  295. X    fnc = pdesc[t].putc;
  296. X
  297. X    if(fnc) fnc(port, c);
  298. X}
  299. X
  300. Xvoid writestr(Obj port, char* s){
  301. X    void (*fnc)(Obj,int);
  302. X    int t = CAR(port) >> 14;
  303. X
  304. X    if(! (fnc=pdesc[t].putc))
  305. X        return;
  306. X    while( *s)
  307. X        fnc(port, *s++);
  308. X}
  309. X
  310. XDEFUN("getc", Fgetc, Sgetc, 0,1,1,0,
  311. X      "(getc port) Read a character from the specified port",
  312. X      (Obj p))
  313. X{
  314. X    int c;
  315. X    
  316. X    if( NBOUNDP(p)) p = stdin_port;
  317. X    if( NULLP(p)){
  318. X        Fthrow(sym_eof, IC_TRUE);
  319. X        return IC_EOF;
  320. X    }
  321. X    if(! RPORTP(p))
  322. X        return jlerror("getc",p, "WTA: input port p");
  323. X    c = readchar(p);
  324. X    if(c==EOF){
  325. X        Fthrow(sym_eof, IC_TRUE);
  326. X        return IC_EOF;
  327. X    }
  328. X    return MAKCHAR( c );
  329. X}
  330. X
  331. XDEFUN("ungetc", Fungetc, Sungetc, 1,2,1,0,
  332. X      "(ungetc char [port]) un-get a character from the specified port",
  333. X      (Obj c, Obj p))
  334. X{
  335. X
  336. X    if( NBOUNDP(p)) p = stdin_port;
  337. X    if(! RPORTP(p))
  338. X        return jlerror("ungetc",p, "WTA: input port p");
  339. X    if(! ICHARP(c)) c = MAKCHAR(0);
  340. X    unreadchar(p, CCHAR( c ));
  341. X    return c;
  342. X}
  343. X
  344. XDEFUN("putc", Fputc, Sputc, 1,2,1,0,
  345. X      "(putc char [port]) Write a character to the specified port",
  346. X      (Obj c, Obj p))
  347. X{
  348. X    if( NBOUNDP(p)) p = stdout_port;
  349. X    if(! WPORTP(p))
  350. X        return jlerror("putc",p, "WTA: output port p");
  351. X
  352. X    if(! ICHARP(c))
  353. X        return jlerror(Sputc.name, c, "WTA: charp");
  354. X    
  355. X    writechar(p, CCHAR(c));
  356. X    return IC_UNSPEC;
  357. X}
  358. X
  359. X
  360. XDEFUN("flush", Fflush, Sflush, 0,1,1,0,
  361. X      "(flush port) flush the buffer associated with port",
  362. X      (Obj port))
  363. X{
  364. X    void (*fnc)(Obj);
  365. X    int t;
  366. X
  367. X    if( NBOUNDP(port)) port = stdin_port;
  368. X    if(! IOPORTP(port))
  369. X        return jlerror("flush", port, "WTA: ioportp");
  370. X
  371. X    t = CAR(port) >> 14;
  372. X    fnc = pdesc[t].flush;
  373. X    if(fnc) fnc(port);
  374. X    return IC_UNSPEC;
  375. X}
  376. X
  377. X/* this ought use bignum offset */
  378. XDEFUN("seek", Fseek, Sseek, 2,2,1,0,
  379. X      "(seek port offset) move file postion",
  380. X      (Obj p, Obj  o))
  381. X{
  382. X    void (*fnc)(Obj, int);
  383. X    int t;
  384. X    
  385. X    if(! IOPORTP(p))
  386. X        return jlerror("seek", p, "WTA: ioportp");
  387. X
  388. X    if(! INUMP(o))
  389. X        return jlerror("seek", o, "WTA: integerp");
  390. X    
  391. X    t = CAR(p) >> 14;
  392. X    fnc = pdesc[t].seek;
  393. X    if(fnc) fnc(p, CINT(o));
  394. X
  395. X    return IC_UNSPEC;
  396. X}
  397. X
  398. XDEFUN("tell", Ftell, Stell, 1,1,1,0,
  399. X      "(tell port) return the current file postion",
  400. X      (Obj p))
  401. X{
  402. X    Obj (*fnc)(Obj);
  403. X    int t;
  404. X
  405. X    if(! IOPORTP(p))
  406. X        return jlerror("seek", p, "WTA: ioportp");
  407. X
  408. X    t = CAR(p) >> 14;
  409. X    fnc = pdesc[t].tell;
  410. X    if(fnc) return fnc(p);
  411. X
  412. X    return IC_UNSPEC;
  413. X}
  414. X
  415. XDEFUN("close", Fclose, Sclose, 1,1,1,0,
  416. X      "(close port) closes the port",
  417. X      (Obj p))
  418. X{
  419. X    int (*fnc)(Obj);
  420. X    int t;
  421. X
  422. X    if(! IOPORTP(p))
  423. X        return jlerror("seek", p, "WTA: ioportp");
  424. X
  425. X    t = CAR(p) >> 14;
  426. X    fnc = pdesc[t].free;
  427. X    if(fnc){
  428. X        fnc(p);
  429. X        /* make sure it is no longer used */
  430. X        CAR(p) = CDR(p) = IC_NIL;
  431. X    }
  432. X    return IC_UNSPEC;
  433. X}
  434. CEST_TOUT
  435.     if test `wc -c < jlisp-1.03/src/port.c` -ne 7514 ; then
  436.         echo "file jlisp-1.03/src/port.c has been corrupted (should be 7514 bytes)"
  437.     fi
  438. fi
  439. if test -f jlisp-1.03/src/pred.c -a "$1" != "-c" ; then
  440.     echo "will not overwrite jlisp-1.03/src/pred.c"
  441. else
  442.     echo "    x - jlisp-1.03/src/pred.c (3154 bytes)"
  443.     sed 's/^X//' > jlisp-1.03/src/pred.c << \CEST_TOUT
  444. X
  445. X/*
  446. X    Copyright (c) 1994 Jeff Weisberg
  447. X
  448. X    see the file "License"
  449. X*/
  450. X
  451. X#ifdef RCSID
  452. Xstatic const char *const rcsid
  453. X= "@(#)$Id: pred.c,v 1.9 94/08/07 13:47:29 weisberg Exp Locker: weisberg $";
  454. X#endif
  455. X
  456. X/* $Id: pred.c,v 1.9 94/08/07 13:47:29 weisberg Exp Locker: weisberg $ */
  457. X
  458. X
  459. X#include <jlisp.h>
  460. X
  461. XDEFUN("consp", Fconsp, Sconsp, 1, 1, 1,0,  "Is this a cons cell",
  462. X      (Obj a))
  463. X{
  464. X
  465. X    return CONSP( a ) ? IC_TRUE : IC_FALSE;
  466. X}
  467. X
  468. XDEFUN("intp", Fintp, Sintp, 1,1, 1,0, "An integer?",
  469. X      (Obj a))
  470. X{
  471. X    return INUMP(a) ? IC_TRUE : IC_FALSE;
  472. X}
  473. X
  474. XDEFUN("charp", Fcharp, Scharp, 1,1,1,0, "A charcacter?",
  475. X      (Obj a))
  476. X{
  477. X    return ICHARP(a) ? IC_TRUE : IC_FALSE;
  478. X}
  479. X
  480. XDEFUN("floatp", Ffloatp, Sfloatp, 1,1,1,0, "A float?",
  481. X      (Obj a))
  482. X{
  483. X    return FLOATP(a) ? IC_TRUE : IC_FALSE;
  484. X}
  485. X
  486. XDEFUN("doublep", Fdoublep, Sdoublep, 1,1,1,0, "A double?",
  487. X      (Obj a))
  488. X{
  489. X    return DOUBLEP(a) ? IC_TRUE : IC_FALSE;
  490. X}
  491. X
  492. XDEFUN("bignump", Fbignp, Sbignp, 1,1,1,0, "A bignum?",
  493. X      (Obj a))
  494. X{
  495. X    return BIGNUMP(a) ? IC_TRUE : IC_FALSE;
  496. X}
  497. X
  498. XDEFUN("stringp", Fstringp, Sstringp, 1,1,1,0, "A string?",
  499. X      (Obj a))
  500. X{
  501. X    return STRINGP(a) ? IC_TRUE : IC_FALSE;
  502. X}
  503. X
  504. XDEFUN("vectorp", Fvectorp, Svectorp, 1,1,1,0, "A vector?",
  505. X      (Obj a))
  506. X{
  507. X    return VECTORP(a) ? IC_TRUE : IC_FALSE;
  508. X}
  509. X
  510. XDEFUN("atomp", Fatomp, Satomp, 1,1,1,0, "An atom?",
  511. X      (Obj a))
  512. X{
  513. X    return NCONSP(a) ? IC_TRUE : IC_FALSE;
  514. X}
  515. X
  516. XDEFUN("nullp", Fnullp, Snullp, 1,1,1,0, "()?",
  517. X      (Obj a))
  518. X{
  519. X    return NULLP(a) ? IC_TRUE : IC_FALSE;
  520. X}
  521. X
  522. XDEFUN("falsep", Ffalsep, Sfalsep, 1,1,1,0, "false?",
  523. X      (Obj a))
  524. X{
  525. X    return FALSEP(a) ? IC_TRUE : IC_FALSE;
  526. X}
  527. X
  528. XDEFUN("symbolp", Fsymbolp, Ssymbolp, 1,1,1,0, "A symbol?",
  529. X      (Obj a))
  530. X{
  531. X    return SYMBOLP(a)||SYMBOXP(a) ? IC_TRUE : IC_FALSE;
  532. X}
  533. X
  534. XDEFUN("boundp", Fboundp, Sboundp, 1,1,1,0, "a bound symbol?",
  535. X      (Obj a))
  536. X{
  537. X
  538. X    if( SYMBOLP(a) )
  539. X        a = Fenvlookup(a, IC_UNSPEC);
  540. X    if( SYMBOXP(a) && BOUNDP( a ))
  541. X        return IC_TRUE;
  542. X    return a==IC_UNSPEC ? IC_FALSE : IC_TRUE;
  543. X}
  544. X
  545. XDEFUN("definedp", Fdefinedp,Sdefinedp, 1,1,1,0, "defined?",
  546. X      (Obj a))
  547. X{
  548. X
  549. X    if( SYMBOLP(a) )
  550. X        a = Fenvlookup(a, IC_UNSPEC);
  551. X    if( SYMBOXP(a) && DEFINEDP( a ))
  552. X        return IC_TRUE;
  553. X    return a==IC_UNDEF ? IC_FALSE : IC_TRUE;
  554. X}
  555. X
  556. XDEFUN("zerop", Fzerop, Szerop, 1,1,1,0, "zero?",
  557. X      (Obj a))
  558. X{
  559. X
  560. X    if( INUMP(a)) return CINT(a)==0 ? IC_TRUE : IC_FALSE;
  561. X    if( FLOATP(a))return *(float*)&CDR(a)==0.0 ? IC_TRUE : IC_FALSE;
  562. X
  563. X    return IC_FALSE;
  564. X}
  565. X
  566. XDEFUN("inputportp",Finputportp, Sinputportp, 1,1,1,0, "A readable ioport?",
  567. X      (Obj a))
  568. X{
  569. X    return RPORTP(a) ? IC_TRUE : IC_FALSE;
  570. X}
  571. X
  572. XDEFUN("outputportp",Foutputportp,Soutputportp,1,1,1,0, "A writable ioport?",
  573. X      (Obj a))
  574. X{
  575. X    return WPORTP(a) ? IC_TRUE : IC_FALSE;
  576. X}
  577. X
  578. XDEFUN("procedurep", Fprocp, Sprocp, 1,1,1,0, "A procedure?",
  579. X      (Obj a))
  580. X{
  581. X
  582. X    return (CCODEP(a) || FUNCTIONP(a) || MACROP(a)) ? IC_TRUE : IC_FALSE;
  583. X}
  584. X
  585. XDEFUN("ccodep", Fccodep, Sccodep, 1,1,1,0, "Builtin C code?",
  586. X      (Obj a))
  587. X{
  588. X    return CCODEP(a) ? IC_TRUE : IC_FALSE;
  589. X}
  590. X
  591. XDEFUN("functionp", Fcosp, Sclosp, 1,1,1,0, "A function?",
  592. X      (Obj a))
  593. X{
  594. X
  595. X    return FUNCTIONP(a) ? IC_TRUE : IC_FALSE;
  596. X}
  597. XDEFUN("macrop", Fmacrop, Smacrop, 1,1,1,0, "A macro?",
  598. X      (Obj a))
  599. X{
  600. X
  601. X    return MACROP(a) ? IC_TRUE : IC_FALSE;
  602. X}
  603. CEST_TOUT
  604.     if test `wc -c < jlisp-1.03/src/pred.c` -ne 3154 ; then
  605.         echo "file jlisp-1.03/src/pred.c has been corrupted (should be 3154 bytes)"
  606.     fi
  607. fi
  608. if test -f jlisp-1.03/src/print.c -a "$1" != "-c" ; then
  609.     echo "will not overwrite jlisp-1.03/src/print.c"
  610. else
  611.     echo "    x - jlisp-1.03/src/print.c (6894 bytes)"
  612.     sed 's/^X//' > jlisp-1.03/src/print.c << \CEST_TOUT
  613. X
  614. X/*
  615. X    Copyright (c) 1994 Jeff Weisberg
  616. X
  617. X    see the file "License"
  618. X*/
  619. X
  620. X#ifdef RCSID
  621. Xstatic const char *const rcsid
  622. X= "@(#)$Id: print.c,v 1.18 94/08/18 16:14:02 weisberg Exp Locker: weisberg $";
  623. X#endif
  624. X
  625. X/* $Id: print.c,v 1.18 94/08/18 16:14:02 weisberg Exp Locker: weisberg $ */
  626. X
  627. X
  628. X#include <jlisp.h>
  629. X#include <stdio.h>
  630. X#include <math.h>
  631. X
  632. Xextern Obj_Vtbl jlisp_vtbl[];
  633. Xvoid writestr(Obj port, char* s);
  634. Xvoid writechar(Obj port, int c);
  635. Xvoid printnum(Obj port, int val, int bacse, int len, int zc);
  636. X
  637. Xextern Obj sym_oradix, sym_stdout;
  638. X
  639. X
  640. X/* how:
  641. X       0    std. print form (no quotes)
  642. X       1    in a form that can be read back
  643. X*/
  644. X
  645. X
  646. Xvoid prnobj(Obj a, Obj stream, int how){
  647. X    int typ = TYPEOFX(a);
  648. X    int (*printfnc)();
  649. X    int i;
  650. X    char *foo;
  651. X    Obj radix;
  652. X    int base;
  653. X    double val;
  654. X    
  655. X    switch( typ ){
  656. X      case TPVF_IMMED:
  657. X        if( INUMP( a )){
  658. X            /* int */
  659. X            radix = getvalue( sym_oradix);
  660. X            if(DEFINEDP(radix)&& INUMP(radix))
  661. X                base = CINT(radix);
  662. X            else
  663. X                base = 10;
  664. X            printnum(stream, CINT(a), base, 0,0);
  665. X        } else if( ICHARP( a )){
  666. X            /* char */
  667. X            foo = 0;
  668. X            if(how){
  669. X                writechar(stream, '?');
  670. X                switch( CCHAR(a)){
  671. X                  case '\n': foo = "\\n"; break;
  672. X                  case '\r': foo = "\\r"; break;
  673. X                  case '\b': foo = "\\b"; break;
  674. X                  case ' ' : foo = "\\s"; break;
  675. X                  case '\t': foo = "\\t"; break;    
  676. X                  case '\f': foo = "\\f"; break;
  677. X                  case 0x1B: foo = "\\e"; break;
  678. X                  default: foo = 0;
  679. X                }
  680. X            }
  681. X            if( foo)
  682. X                writestr(stream, foo);
  683. X            else
  684. X                writechar(stream, CCHAR(a));
  685. X        } else if( ICONSTP( a )){
  686. X            /* const sym */
  687. X            switch( a ){
  688. X
  689. X              case IC_NIL:
  690. X                writestr(stream, "()");
  691. X                break;
  692. X
  693. X              case IC_TRUE:
  694. X                writestr(stream, "#t");
  695. X                break;
  696. X
  697. X              case IC_FALSE:
  698. X                writestr(stream, "#f");
  699. X                break;
  700. X
  701. X              case IC_UNDEF:
  702. X                writestr(stream, "#<undefined>");
  703. X                break;
  704. X
  705. X              case IC_UNSPEC:
  706. X                writestr(stream, "#<unspecified>");
  707. X                break;
  708. X
  709. X              case IC_EOF:
  710. X                writestr(stream, "#<EOF>");
  711. X                break;
  712. X
  713. X              default:
  714. X                writestr(stream, "#<IC_0x");
  715. X                printnum(stream, a, 16,0,0);
  716. X                writestr(stream, "?>");
  717. X                break;
  718. X            }
  719. X        } else {
  720. X            writestr(stream, "#<IMM_0x");
  721. X            printnum(stream, a, 16,0,0);
  722. X            writestr(stream, "?>");
  723. X        }
  724. X        break;
  725. X
  726. X      case TPV_SYMBOL:
  727. X        writestr(stream, CCHARS(a));
  728. X        break;
  729. X
  730. X      case TPV_SYM_BOX:
  731. X        writestr(stream, CSYM_BOX(a)->name);
  732. X        break;
  733. X
  734. X      default:
  735. X        printfnc = jlisp_vtbl[ typ ].print;
  736. X
  737. X        if( !printfnc || ! printfnc(a, stream, how) ){
  738. X            writestr(stream, "#<_");
  739. X            printnum(stream, typ, 10,0,0);
  740. X            writestr(stream, "_0x");
  741. X            printnum(stream, a, 16, 0,0);
  742. X            writestr(stream, ">");
  743. X        }
  744. X        break;
  745. X    }
  746. X}
  747. X
  748. Xint prn_func_macr(Obj a, Obj stream, char* which){
  749. X    
  750. X    writestr(stream, "(");
  751. X    writestr(stream, which);
  752. X    writestr(stream, " ");
  753. X    prnobj( CADR(a), stream, 1);    /* the args */
  754. X    writestr(stream, " ");
  755. X    
  756. X    a = CDDR(a);
  757. X    while( NNULLP( a )){
  758. X        if( NCONSP( a )){
  759. X            writestr(stream, " . ");
  760. X            prnobj(a, stream, 1);
  761. X            break;
  762. X        }
  763. X        writestr(stream, " ");
  764. X        prnobj( CAR(a), stream, 1);
  765. X        a = CDR( a );
  766. X    }    
  767. X    writestr(stream, ")");
  768. X    return 1;
  769. X}
  770. X
  771. Xint prnfunc(Obj a, Obj stream, int how){
  772. X
  773. X    if( how) return prn_func_macr(a, stream, "lambda");
  774. X    else writestr(stream, "#<function>");
  775. X    return 1;
  776. X}
  777. Xint prnmacr(Obj a, Obj stream, int how){
  778. X
  779. X    if( how) return prn_func_macr(a, stream, "macro");
  780. X    else writestr(stream, "#<macro>");
  781. X    return 1;
  782. X}
  783. X
  784. Xint prnccode(Obj a, Obj stream, int how){
  785. X
  786. X    writestr(stream, "#<builtin-function:");
  787. X    writestr(stream, CCDECL(a)->name);
  788. X    writestr(stream, ">");
  789. X    return 1;
  790. X}
  791. X
  792. Xint prnstr(Obj a, Obj stream, int how){
  793. X    int i;
  794. X    
  795. X    if(how) writestr(stream, "\"");
  796. X    for(i=0; i< CLENGTH(a); i++)
  797. X        writechar(stream, CCHARS(a)[i]);
  798. X    if(how) writestr(stream, "\"");
  799. X    return 1;
  800. X}
  801. X
  802. Xint prnvect(Obj a, Obj stream, int how){
  803. X    int i;
  804. X    
  805. X    writestr(stream, "#(");
  806. X    if( CLENGTH(a)) prnobj( CVECTOR(a)[0], stream, how);
  807. X    for(i=1; i< CLENGTH(a); i++){
  808. X        writestr(stream, " ");
  809. X        prnobj( CVECTOR(a)[i], stream, how);
  810. X    }
  811. X    writestr(stream, ")");
  812. X        
  813. X    return 1;
  814. X}
  815. Xint prnbign(Obj a, Obj stream, int how){
  816. X    return 0;
  817. X}
  818. X
  819. Xint prncmplx(Obj a, Obj stream, int how){
  820. X    return 0;
  821. X}
  822. X    
  823. Xint prncons(Obj a, Obj stream, int how){
  824. X    FILE *fp = CFILEPTR( stream );
  825. X    
  826. X    writestr(stream, "(");
  827. X    prnobj(CAR(a), stream, how);
  828. X    a = CDR(a);
  829. X    while( NNULLP( a )){
  830. X        if( NCONSP( a )){
  831. X            writestr(stream, " . ");
  832. X            prnobj(a, stream, how);
  833. X            break;
  834. X        }
  835. X        writestr(stream, " ");
  836. X        prnobj( CAR(a), stream, how );
  837. X        a = CDR( a );
  838. X    }
  839. X    writestr(stream, ")");
  840. X    return 1;
  841. X}
  842. X
  843. XDEFUN("display", Fdisplay, Sdisplay, 1, 2, 1,0,
  844. X      "(display obj [port]) Display the object",
  845. X      (Obj a, Obj stream))
  846. X{
  847. X
  848. X    if( NBOUNDP( stream )) stream = getvalue(sym_stdout);
  849. X
  850. X    if( NULLP(stream)) return IC_UNSPEC;
  851. X    
  852. X    if( ! WPORTP( stream )){
  853. X        return jlerror("display", stream, "WTA: outputportp");
  854. X    }
  855. X
  856. X    prnobj(a, stream, 0);
  857. X    return IC_UNSPEC;
  858. X}
  859. X
  860. XDEFUN("write", Fwrite, Swrite, 1, 2, 1,0,
  861. X      "(write obj [port]) Display the object in read form",
  862. X      (Obj a, Obj stream))
  863. X{
  864. X
  865. X    if( NBOUNDP( stream )) stream = getvalue(sym_stdout);
  866. X
  867. X    if( NULLP(stream)) return IC_UNSPEC;
  868. X
  869. X    if( ! WPORTP( stream )){
  870. X        return jlerror("write", stream, "WTA: outputportp");
  871. X    }
  872. X
  873. X    prnobj(a, stream, 1);
  874. X    return IC_UNSPEC;
  875. X}
  876. X
  877. X
  878. Xvoid printnum(Obj port, int val, int base, int len, int zc){
  879. X    int c;
  880. X    int vv=1;
  881. X    int foo;
  882. X    if(!zc) zc = '0';
  883. X    
  884. X    if(val<0){
  885. X        val = -val;
  886. X        writechar(port, '-');
  887. X    }
  888. X    if(!val && !len){
  889. X        writechar(port, '0');
  890. X        return;
  891. X    }
  892. X    if(len) vv = pow(base, len);
  893. X    else{
  894. X        foo = val;
  895. X        while (foo >= base){
  896. X            foo /= base;
  897. X            vv *= base;
  898. X        }
  899. X    }
  900. X    
  901. X    while(vv){
  902. X
  903. X        c = val / vv;
  904. X        if(!c)
  905. X            writechar(port, zc);
  906. X        else{
  907. X            if(c>=0 && c<=9) c+= '0';
  908. X            else c += 'A' - 0xA;
  909. X            writechar(port, c);
  910. X            zc = '0';
  911. X        }
  912. X        val %= vv;
  913. X        vv /= base;
  914. X    }
  915. X}
  916. X
  917. X
  918. Xvoid prnfldbl(double val, int len, Obj stream, int how){
  919. X    float vv, vl;
  920. X    int vvl;
  921. X    int ip, fp;
  922. X    Obj radix;
  923. X    int base;
  924. X
  925. X    if(isinf(val)){
  926. X        writestr(stream, "Infinity");
  927. X        return;
  928. X    }
  929. X    if(isnan(val)){
  930. X        writestr(stream, "**NaN**");
  931. X        return;
  932. X    }
  933. X    if(val==0.0){
  934. X        writestr(stream, "0.0");
  935. X        return;
  936. X    }
  937. X    if(val<0){
  938. X        val = -val;
  939. X        writechar(stream, '-');
  940. X    }
  941. X    radix = getvalue( sym_oradix);
  942. X    if(DEFINEDP(radix)&& INUMP(radix))
  943. X        base = CINT(radix);
  944. X    else
  945. X        base = 10;
  946. X    
  947. X    if(!how){
  948. X        vv = floor(log(val)/log(base));
  949. X        if( vv>=-3 && vv<=4 )
  950. X            vv = 1;
  951. X        else{
  952. X            vvl = vv;
  953. X            vv = pow(base, vv);
  954. X        }
  955. X    }else{
  956. X        vv = 1;
  957. X    }
  958. X
  959. X    /* into: ip.fp */
  960. X
  961. X    vl = pow(base, len);
  962. X    val /= vv;
  963. X    val *= vl;
  964. X    val = rint(val);
  965. X
  966. X    fp = (int)val % (int)vl;
  967. X    ip = (val - fp) / vl;
  968. X
  969. X    
  970. X    printnum(stream, ip, base, 0, 0);
  971. X    writechar(stream, '.');
  972. X    printnum(stream, fp, base, len-1, 0);
  973. X
  974. X    if(vv!=1){
  975. X        writechar(stream, '$');
  976. X        printnum(stream, vvl, base, 0,0);
  977. X    }
  978. X}
  979. X    
  980. Xint prnflt(Obj a, Obj stream, int how){
  981. X    prnfldbl( CFLOAT(a), 4, stream, how);
  982. X    return 1;
  983. X}
  984. X
  985. Xint prndbl(Obj a, Obj stream, int how){
  986. X    prnfldbl( CDOUBLE(a), 8, stream, how);
  987. X    return 1;
  988. X}
  989. X
  990. Xint prnenvec(Obj a, Obj stream, int how){
  991. X
  992. X    writestr(stream, "#<ENV_0x");
  993. X    printnum(stream, a, 16, 0,0);
  994. X    writestr(stream, ">");
  995. X}
  996. X
  997. CEST_TOUT
  998.     if test `wc -c < jlisp-1.03/src/print.c` -ne 6894 ; then
  999.         echo "file jlisp-1.03/src/print.c has been corrupted (should be 6894 bytes)"
  1000.     fi
  1001. fi
  1002. if test -f jlisp-1.03/src/reader.c -a "$1" != "-c" ; then
  1003.     echo "will not overwrite jlisp-1.03/src/reader.c"
  1004. else
  1005.     echo "    x - jlisp-1.03/src/reader.c (7307 bytes)"
  1006.     sed 's/^X//' > jlisp-1.03/src/reader.c << \CEST_TOUT
  1007. X
  1008. X/*
  1009. X    Copyright (c) 1994 Jeff Weisberg
  1010. X
  1011. X    see the file "License"
  1012. X*/
  1013. X
  1014. X#ifdef RCSID
  1015. Xstatic const char *const rcsid
  1016. X= "@(#)$Id: reader.c,v 1.27 94/08/23 08:51:51 weisberg Exp Locker: weisberg $";
  1017. X#endif
  1018. X
  1019. X#include <jlisp.h>
  1020. X#include <stdio.h>
  1021. X
  1022. Xextern Obj makfloat(float);
  1023. Xextern Obj str_append(Obj, int, int);
  1024. X
  1025. XObj Fread();
  1026. Xint readchar(Obj port);
  1027. Xvoid unreadchar(Obj port, int c);
  1028. X
  1029. Xextern Obj sym_optional, sym_rest, sym_quote;
  1030. Xextern Obj sym_quote, sym_bquote, sym_bq_comma, sym_bq_comma_at;
  1031. X
  1032. Xextern Obj sym_iradix, sym_eof, sym_stdin;
  1033. X
  1034. XDEFVAR(".lineno", Vlineno, ".lineno the current line number", MAKINT(1))
  1035. X
  1036. X     
  1037. Xvoid inc_lineno(){
  1038. X    /* increment line number */
  1039. X    VALUE( Vlineno ) += MAKINT(1) - MAKINT(0);
  1040. X}
  1041. X    
  1042. Xint vallof(int c, int b){
  1043. X
  1044. X    if(c>='0' && c<='9') return c - '0';
  1045. X    if(c>='a' && c<='z') return c - 'a' + 0xa;
  1046. X    if(c>='A' && c<='Z') return c - 'A' + 0xA;
  1047. X
  1048. X    return 255;
  1049. X}
  1050. X
  1051. Xint isvalid(int c, int b){
  1052. X
  1053. X    return vallof(c, b) < b;
  1054. X}
  1055. X
  1056. Xvoid eatcomment(Obj stream){
  1057. X    /* eat #| comment |#
  1058. X       may be nested */
  1059. X    int c=0;
  1060. X    
  1061. X    while( c!='#'){
  1062. X        while(c!='|'){
  1063. X            c = readchar(stream);
  1064. X            switch(c){
  1065. X              case '#':
  1066. X                c = readchar(stream);
  1067. X                if(c=='|'){
  1068. X                    eatcomment(stream);
  1069. X                    c = readchar(stream);
  1070. X                }
  1071. X                break;
  1072. X              case '\n':
  1073. X                inc_lineno();
  1074. X              default:
  1075. X                break;
  1076. X            }
  1077. X        }
  1078. X        c = readchar(stream);
  1079. X    }
  1080. X    return;
  1081. X}
  1082. X
  1083. Xint special_char(Obj stream){
  1084. X    /* handle special \escaped characters */
  1085. X    int c;
  1086. X    int val=0, base;
  1087. X    c = readchar(stream);
  1088. X    switch( c ){
  1089. X      case 'a':    c = '\a';    break;    /* yes, I know that this is the ANSI C alert char... */
  1090. X      case 'n':    c = '\n';    break;
  1091. X      case 'r':    c = '\r';    break;
  1092. X      case 'b':    c = '\b';    break;
  1093. X      case 't':    c = '\t';    break;
  1094. X      case 's':    c = ' ';    break;
  1095. X      case 'f':    c = '\f';    break;
  1096. X      case 'v':    c = '\v';    break;
  1097. X      case 'e':    c = '\033';    break;
  1098. X
  1099. X      case '"':    c = '"';    break;
  1100. X        
  1101. X      case '0':
  1102. X        base = 8;  goto rnum;
  1103. X      case 'x':
  1104. X      case 'X':
  1105. X        c = readchar(stream);
  1106. X        base = 16; goto rnum;
  1107. X      case '1': case '2': case '3':
  1108. X      case '4': case '5': case '6':
  1109. X      case '7': case '8': case '9':
  1110. X        base = 10; goto rnum;
  1111. X      rnum:
  1112. X
  1113. X        while( isvalid(c, base)){
  1114. X            val *= base;
  1115. X            val += vallof(c, base);
  1116. X            c = readchar(stream);
  1117. X        }
  1118. X        unreadchar(stream, c);
  1119. X        c = val;
  1120. X        break;
  1121. X        
  1122. X      case '\n':
  1123. X        inc_lineno();
  1124. X      default:
  1125. X        Fdisplay( makstr_c("Warning: unknown escape \\"), stderr_port);
  1126. X        Fdisplay( MAKCHAR( c ),  stderr_port);
  1127. X        Fdisplay( MAKCHAR('\n'), stderr_port);
  1128. X        c = c;        break;
  1129. X
  1130. X    }
  1131. X    return c;
  1132. X}
  1133. X
  1134. Xint getc_skipws(Obj stream){
  1135. X    int c;
  1136. X    
  1137. X    while( 1 ){
  1138. X        c = readchar(stream);
  1139. X        switch(c){
  1140. X          case ';':
  1141. X            while( c != '\r' && c!= '\n' ) c = readchar(stream);
  1142. X            /* fall thru' */
  1143. X          case '\n':
  1144. X            inc_lineno();
  1145. X          case ' ':
  1146. X          case '\t':
  1147. X          case '\r':
  1148. X            continue;
  1149. X          case '#':
  1150. X            c = readchar(stream);
  1151. X            if(c!='|'){
  1152. X                unreadchar(stream, c);
  1153. X                return '#';
  1154. X            }
  1155. X            eatcomment(stream);
  1156. X            continue;
  1157. X        }
  1158. X        break;
  1159. X    }
  1160. X    return c;
  1161. X}
  1162. X
  1163. XObj readparen( Obj stream ){
  1164. X    int c;
  1165. X    Obj foo;
  1166. X
  1167. X    c = getc_skipws( stream );
  1168. X    if( c==')' ) return IC_NIL;
  1169. X    unreadchar(stream, c);
  1170. X    foo = Fread( stream );
  1171. X    if( SYMBOLP(foo) && !strcmp( CCHARS(foo), ".")){
  1172. X        /* KLUDGE ALERT */
  1173. X        /* a lone .
  1174. X        turn it into an improper list */
  1175. X        foo = Fread( stream );
  1176. X        c = getc_skipws( stream );
  1177. X        if( c!=')' ) unreadchar(stream, c);
  1178. X        return foo;
  1179. X    }
  1180. X    return Fcons( foo, readparen( stream ) );
  1181. X}
  1182. X
  1183. XDEFUN("read", Fread, Sread, 0, 1, 1,0,
  1184. X      "(read [port]) read in an expression",
  1185. X      (Obj stream))
  1186. X{
  1187. X
  1188. X    int c;
  1189. X    char buf[1024];
  1190. X    int i;
  1191. X    Obj val, frac, baseo;
  1192. X    int decmp, negp, base;
  1193. X    Obj radix;
  1194. X    Obj buffer;
  1195. X    
  1196. X    if( NBOUNDP( stream )) stream = getvalue(sym_stdin);
  1197. X    if( NULLP(stream)){
  1198. X        Fthrow(sym_eof, IC_EOF);
  1199. X        return IC_EOF;
  1200. X    }
  1201. X    if( !RPORTP( stream )){
  1202. X        return jlerror("read", stream, "wrong type of argument, inputportp");
  1203. X    }
  1204. X
  1205. X    c = getc_skipws( stream );
  1206. X    
  1207. X    switch( c ){
  1208. X      case EOF:
  1209. X        Fthrow(sym_eof, IC_TRUE);
  1210. X        return IC_EOF;
  1211. X        
  1212. X      case '(':
  1213. X        return readparen( stream );
  1214. X
  1215. X      case ')':
  1216. X        return jlerror("read", stream, "unexpected ')'");
  1217. X
  1218. X      case '"':
  1219. X        buffer = makstrn("", 0);
  1220. X        i = 0;
  1221. X        do {
  1222. X            c = readchar(stream);
  1223. X            if(c=='\\'){
  1224. X                c = special_char(stream);
  1225. X                str_append(buffer, i++, c);
  1226. X                c = 0;
  1227. X                continue;
  1228. X            }
  1229. X            if( c=='\n') inc_lineno();
  1230. X            if( c!= '"')
  1231. X                str_append(buffer, i++, c);
  1232. X        }while( c != '"' );
  1233. X
  1234. X        CCHARS(buffer)[i] = 0;
  1235. X        return buffer;
  1236. X
  1237. X      case '?':
  1238. X      rchar:
  1239. X        c = readchar(stream);
  1240. X        if( c == '\\' ){
  1241. X            i = special_char(stream);
  1242. X        }else
  1243. X            i = c;
  1244. X        return MAKCHAR( i );
  1245. X
  1246. X      case '#':
  1247. X        c = getc_skipws( stream );
  1248. X
  1249. X        switch( c ){
  1250. X          case '\\':
  1251. X            /* handle scheme-like character syntax #\x #\\n would be a newline... */
  1252. X            goto rchar;
  1253. X          case 't':
  1254. X          case 'T':
  1255. X            return IC_TRUE;
  1256. X          case 'f':
  1257. X          case 'F':
  1258. X            return IC_FALSE;
  1259. X          case '<':
  1260. X            while ( c != '>') c = getc_skipws(stream);
  1261. X            return jlerror("read", IC_UNSPEC, "unreadable syntax");
  1262. X          case '(':
  1263. X            return Flist_vect( readparen(stream) );
  1264. X          case 'x':
  1265. X          case 'X':
  1266. X            /* _I_ like spagetti... */
  1267. X            base = 16;    goto rnump;
  1268. X          case 'o':
  1269. X          case 'O':
  1270. X            base = 8;    goto rnump;
  1271. X          case 'd':
  1272. X          case 'D':
  1273. X            base = 10;    goto rnump;
  1274. X          case 'b':
  1275. X          case 'B':
  1276. X            base = 2;
  1277. X          rnump:
  1278. X            c = getc_skipws(stream);
  1279. X            goto rnum;
  1280. X          case '!':
  1281. X            if( VALUE(Vlineno)==MAKINT(1)){
  1282. X                /* special script file handling
  1283. X                   #! is a comment on the 1st line of a file
  1284. X                */
  1285. X                while( c != '\n') c = readchar(stream);
  1286. X                unreadchar(stream, c);
  1287. X                return Fread(stream);
  1288. X            }
  1289. X            /* fall thru' */
  1290. X          default:
  1291. X            return jlerror(Sread.name, IC_UNSPEC, "unreadable syntax");
  1292. X        }
  1293. X        break;
  1294. X        
  1295. X      case '\'':
  1296. X        return Fcons(sym_quote, Fcons(Fread( stream ), IC_NIL));
  1297. X        break;
  1298. X
  1299. X      case '`':
  1300. X        return Fcons(sym_bquote, Fcons(Fread( stream ), IC_NIL));
  1301. X        break;
  1302. X
  1303. X      case ',':
  1304. X        c = readchar(stream);
  1305. X        if( c=='@') return Fcons(sym_bq_comma_at, Fcons(Fread( stream ), IC_NIL));
  1306. X        unreadchar(stream, c);
  1307. X        return Fcons(sym_bq_comma, Fcons(Fread( stream ), IC_NIL));
  1308. X        
  1309. X      default:
  1310. X        radix = getvalue( sym_iradix );
  1311. X        
  1312. X        if( INUMP(radix))
  1313. X            base = CINT(radix);
  1314. X        else
  1315. X            base = 10;
  1316. X
  1317. X      rnum:
  1318. X        baseo = MAKINT(base);
  1319. X
  1320. X        i = 0;
  1321. X        while(1){
  1322. X            if( c==' ' ) break;
  1323. X            if( c=='\t') break;
  1324. X            if( c=='\r') break;
  1325. X            if( c=='\n') break;
  1326. X            if( c==')' ) break;
  1327. X            if( c=='(' ) break;
  1328. X            if( c==';' ) break;
  1329. X            if( c=='#' ) break;    /* XXX ? ought # be allowed in a symbol name? */
  1330. X            if( c==EOF ) break;
  1331. X
  1332. X            buf[i++] = c;
  1333. X            buf[i] = 0;
  1334. X            c = readchar(stream);
  1335. X        }
  1336. X        unreadchar(stream, c);
  1337. X
  1338. X        /* handle 2 special cases */
  1339. X        if(!strcmp(buf, "&rest"))     return sym_rest;
  1340. X        if(!strcmp(buf, "&optional"))     return sym_optional;
  1341. X
  1342. X        val = MAKINT(0);
  1343. X        frac= makfloat(1);
  1344. X        decmp = negp = 0;
  1345. X        i = 0;
  1346. X        
  1347. X        
  1348. X        if( buf[0]=='-'){
  1349. X            negp = 1;
  1350. X            i++;
  1351. X        }
  1352. X        while(buf[i]){
  1353. X            if( !isvalid(buf[i], base) && buf[i]!='.'){
  1354. X                /* a symbol */
  1355. X                return maksym( buf );
  1356. X            }
  1357. X            if( buf[i]=='.' ){
  1358. X                if( decmp ) return maksym( buf );
  1359. X                decmp = 1;
  1360. X                i++;
  1361. X                continue;
  1362. X            }
  1363. X
  1364. X            if( decmp ){
  1365. X                frac = Fdivide(frac, baseo);
  1366. X                val  = Ftimes(val, baseo);
  1367. X                val  = Fplus(val, MAKINT(vallof( buf[i], base )));
  1368. X            } else {
  1369. X                val = Ftimes(val, baseo);
  1370. X                val = Fplus(val, MAKINT(vallof( buf[i], base )));
  1371. X            }
  1372. X            i++;
  1373. X
  1374. X        }
  1375. X        if(negp && i==1)
  1376. X            return maksym( buf );
  1377. X        if(decmp && i==1)
  1378. X            return maksym( buf );
  1379. X        if(decmp)
  1380. X            val = Ftimes(val, frac);
  1381. X        if(negp)
  1382. X            val = Fminus(MAKINT(0), val);
  1383. X        return val;
  1384. X
  1385. X    }
  1386. X}
  1387. X
  1388. X
  1389. X
  1390. X
  1391. X
  1392. X
  1393. X
  1394. CEST_TOUT
  1395.     if test `wc -c < jlisp-1.03/src/reader.c` -ne 7307 ; then
  1396.         echo "file jlisp-1.03/src/reader.c has been corrupted (should be 7307 bytes)"
  1397.     fi
  1398. fi
  1399. echo part07 done.
  1400. exit 0
  1401.  
  1402.  
  1403.