dc.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. typedef void* pointer;
  5. #pragma varargck type "lx" pointer
  6. #define FATAL 0
  7. #define NFATAL 1
  8. #define BLK sizeof(Blk)
  9. #define PTRSZ sizeof(int*)
  10. #define HEADSZ 1024
  11. #define STKSZ 100
  12. #define RDSKSZ 100
  13. #define TBLSZ 256
  14. #define ARRAYST 221
  15. #define MAXIND 2048
  16. #define NL 1
  17. #define NG 2
  18. #define NE 3
  19. #define length(p) ((p)->wt-(p)->beg)
  20. #define rewind(p) (p)->rd=(p)->beg
  21. #define create(p) (p)->rd = (p)->wt = (p)->beg
  22. #define fsfile(p) (p)->rd = (p)->wt
  23. #define truncate(p) (p)->wt = (p)->rd
  24. #define sfeof(p) (((p)->rd==(p)->wt)?1:0)
  25. #define sfbeg(p) (((p)->rd==(p)->beg)?1:0)
  26. #define sungetc(p,c) *(--(p)->rd)=c
  27. #define sgetc(p) (((p)->rd==(p)->wt)?-1:*(p)->rd++)
  28. #define skipc(p) {if((p)->rd<(p)->wt)(p)->rd++;}
  29. #define slookc(p) (((p)->rd==(p)->wt)?-1:*(p)->rd)
  30. #define sbackc(p) (((p)->rd==(p)->beg)?-1:*(--(p)->rd))
  31. #define backc(p) {if((p)->rd>(p)->beg) --(p)->rd;}
  32. #define sputc(p,c) {if((p)->wt==(p)->last)more(p);\
  33. *(p)->wt++ = c; }
  34. #define salterc(p,c) {if((p)->rd==(p)->last)more(p);\
  35. *(p)->rd++ = c;\
  36. if((p)->rd>(p)->wt)(p)->wt=(p)->rd;}
  37. #define sunputc(p) (*((p)->rd = --(p)->wt))
  38. #define sclobber(p) ((p)->rd = --(p)->wt)
  39. #define zero(p) for(pp=(p)->beg;pp<(p)->last;)\
  40. *pp++='\0'
  41. #define OUTC(x) {Bputc(&bout,x); if(--count == 0){Bprint(&bout,"\\\n"); count=ll;} }
  42. #define TEST2 {if((count -= 2) <=0){Bprint(&bout,"\\\n");count=ll;}}
  43. #define EMPTY if(stkerr != 0){Bprint(&bout,"stack empty\n"); continue; }
  44. #define EMPTYR(x) if(stkerr!=0){pushp(x);Bprint(&bout,"stack empty\n");continue;}
  45. #define EMPTYS if(stkerr != 0){Bprint(&bout,"stack empty\n"); return(1);}
  46. #define EMPTYSR(x) if(stkerr !=0){Bprint(&bout,"stack empty\n");pushp(x);return(1);}
  47. #define error(p) {Bprint(&bout,p); continue; }
  48. #define errorrt(p) {Bprint(&bout,p); return(1); }
  49. #define LASTFUN 026
  50. typedef struct Blk Blk;
  51. struct Blk
  52. {
  53. char *rd;
  54. char *wt;
  55. char *beg;
  56. char *last;
  57. };
  58. typedef struct Sym Sym;
  59. struct Sym
  60. {
  61. Sym *next;
  62. Blk *val;
  63. };
  64. typedef struct Wblk Wblk;
  65. struct Wblk
  66. {
  67. Blk **rdw;
  68. Blk **wtw;
  69. Blk **begw;
  70. Blk **lastw;
  71. };
  72. Biobuf *curfile, *fsave;
  73. Blk *arg1, *arg2;
  74. uchar savk;
  75. int dbg;
  76. int ifile;
  77. Blk *scalptr, *basptr, *tenptr, *inbas;
  78. Blk *sqtemp, *chptr, *strptr, *divxyz;
  79. Blk *stack[STKSZ];
  80. Blk **stkptr,**stkbeg;
  81. Blk **stkend;
  82. Blk *hfree;
  83. int stkerr;
  84. int lastchar;
  85. Blk *readstk[RDSKSZ];
  86. Blk **readptr;
  87. Blk *rem;
  88. int k;
  89. Blk *irem;
  90. int skd,skr;
  91. int neg;
  92. Sym symlst[TBLSZ];
  93. Sym *stable[TBLSZ];
  94. Sym *sptr, *sfree;
  95. long rel;
  96. long nbytes;
  97. long all;
  98. long headmor;
  99. long obase;
  100. int fw,fw1,ll;
  101. void (*outdit)(Blk *p, int flg);
  102. int logo;
  103. int logten;
  104. int count;
  105. char *pp;
  106. char *dummy;
  107. long longest, maxsize, active;
  108. int lall, lrel, lcopy, lmore, lbytes;
  109. int inside;
  110. Biobuf bin;
  111. Biobuf bout;
  112. void main(int argc, char *argv[]);
  113. void commnds(void);
  114. Blk* readin(void);
  115. Blk* div(Blk *ddivd, Blk *ddivr);
  116. int dscale(void);
  117. Blk* removr(Blk *p, int n);
  118. Blk* dcsqrt(Blk *p);
  119. void init(int argc, char *argv[]);
  120. void onintr(void);
  121. void pushp(Blk *p);
  122. Blk* pop(void);
  123. Blk* readin(void);
  124. Blk* add0(Blk *p, int ct);
  125. Blk* mult(Blk *p, Blk *q);
  126. void chsign(Blk *p);
  127. int readc(void);
  128. void unreadc(char c);
  129. void binop(char c);
  130. void dcprint(Blk *hptr);
  131. Blk* dcexp(Blk *base, Blk *ex);
  132. Blk* getdec(Blk *p, int sc);
  133. void tenot(Blk *p, int sc);
  134. void oneot(Blk *p, int sc, char ch);
  135. void hexot(Blk *p, int flg);
  136. void bigot(Blk *p, int flg);
  137. Blk* add(Blk *a1, Blk *a2);
  138. int eqk(void);
  139. Blk* removc(Blk *p, int n);
  140. Blk* scalint(Blk *p);
  141. Blk* scale(Blk *p, int n);
  142. int subt(void);
  143. int command(void);
  144. int cond(char c);
  145. void load(void);
  146. int log2(long n);
  147. Blk* salloc(int size);
  148. Blk* morehd(void);
  149. Blk* copy(Blk *hptr, int size);
  150. void sdump(char *s1, Blk *hptr);
  151. void seekc(Blk *hptr, int n);
  152. void salterwd(Blk *hptr, Blk *n);
  153. void more(Blk *hptr);
  154. void ospace(char *s);
  155. void garbage(char *s);
  156. void release(Blk *p);
  157. Blk* dcgetwd(Blk *p);
  158. void putwd(Blk *p, Blk *c);
  159. Blk* lookwd(Blk *p);
  160. char* nalloc(char *p, unsigned nbytes);
  161. int getstk(void);
  162. /********debug only**/
  163. void
  164. tpr(char *cp, Blk *bp)
  165. {
  166. print("%s-> ", cp);
  167. print("beg: %lx rd: %lx wt: %lx last: %lx\n", bp->beg, bp->rd,
  168. bp->wt, bp->last);
  169. for (cp = bp->beg; cp != bp->wt; cp++) {
  170. print("%d", *cp);
  171. if (cp != bp->wt-1)
  172. print("/");
  173. }
  174. print("\n");
  175. }
  176. /************/
  177. void
  178. main(int argc, char *argv[])
  179. {
  180. Binit(&bin, 0, OREAD);
  181. Binit(&bout, 1, OWRITE);
  182. init(argc,argv);
  183. commnds();
  184. exits(0);
  185. }
  186. void
  187. commnds(void)
  188. {
  189. Blk *p, *q, **ptr, *s, *t;
  190. long l;
  191. Sym *sp;
  192. int sk, sk1, sk2, c, sign, n, d;
  193. while(1) {
  194. Bflush(&bout);
  195. if(((c = readc())>='0' && c <= '9') ||
  196. (c>='A' && c <='F') || c == '.') {
  197. unreadc(c);
  198. p = readin();
  199. pushp(p);
  200. continue;
  201. }
  202. switch(c) {
  203. case ' ':
  204. case '\n':
  205. case -1:
  206. continue;
  207. case 'Y':
  208. sdump("stk",*stkptr);
  209. Bprint(&bout, "all %ld rel %ld headmor %ld\n",all,rel,headmor);
  210. Bprint(&bout, "nbytes %ld\n",nbytes);
  211. Bprint(&bout, "longest %ld active %ld maxsize %ld\n", longest,
  212. active, maxsize);
  213. Bprint(&bout, "new all %d rel %d copy %d more %d lbytes %d\n",
  214. lall, lrel, lcopy, lmore, lbytes);
  215. lall = lrel = lcopy = lmore = lbytes = 0;
  216. continue;
  217. case '_':
  218. p = readin();
  219. savk = sunputc(p);
  220. chsign(p);
  221. sputc(p,savk);
  222. pushp(p);
  223. continue;
  224. case '-':
  225. subt();
  226. continue;
  227. case '+':
  228. if(eqk() != 0)
  229. continue;
  230. binop('+');
  231. continue;
  232. case '*':
  233. arg1 = pop();
  234. EMPTY;
  235. arg2 = pop();
  236. EMPTYR(arg1);
  237. sk1 = sunputc(arg1);
  238. sk2 = sunputc(arg2);
  239. savk = sk1+sk2;
  240. binop('*');
  241. p = pop();
  242. if(savk>k && savk>sk1 && savk>sk2) {
  243. sclobber(p);
  244. sk = sk1;
  245. if(sk<sk2)
  246. sk = sk2;
  247. if(sk<k)
  248. sk = k;
  249. p = removc(p,savk-sk);
  250. savk = sk;
  251. sputc(p,savk);
  252. }
  253. pushp(p);
  254. continue;
  255. case '/':
  256. casediv:
  257. if(dscale() != 0)
  258. continue;
  259. binop('/');
  260. if(irem != 0)
  261. release(irem);
  262. release(rem);
  263. continue;
  264. case '%':
  265. if(dscale() != 0)
  266. continue;
  267. binop('/');
  268. p = pop();
  269. release(p);
  270. if(irem == 0) {
  271. sputc(rem,skr+k);
  272. pushp(rem);
  273. continue;
  274. }
  275. p = add0(rem,skd-(skr+k));
  276. q = add(p,irem);
  277. release(p);
  278. release(irem);
  279. sputc(q,skd);
  280. pushp(q);
  281. continue;
  282. case 'v':
  283. p = pop();
  284. EMPTY;
  285. savk = sunputc(p);
  286. if(length(p) == 0) {
  287. sputc(p,savk);
  288. pushp(p);
  289. continue;
  290. }
  291. if(sbackc(p)<0) {
  292. error("sqrt of neg number\n");
  293. }
  294. if(k<savk)
  295. n = savk;
  296. else {
  297. n = k*2-savk;
  298. savk = k;
  299. }
  300. arg1 = add0(p,n);
  301. arg2 = dcsqrt(arg1);
  302. sputc(arg2,savk);
  303. pushp(arg2);
  304. continue;
  305. case '^':
  306. neg = 0;
  307. arg1 = pop();
  308. EMPTY;
  309. if(sunputc(arg1) != 0)
  310. error("exp not an integer\n");
  311. arg2 = pop();
  312. EMPTYR(arg1);
  313. if(sfbeg(arg1) == 0 && sbackc(arg1)<0) {
  314. neg++;
  315. chsign(arg1);
  316. }
  317. if(length(arg1)>=3) {
  318. error("exp too big\n");
  319. }
  320. savk = sunputc(arg2);
  321. p = dcexp(arg2,arg1);
  322. release(arg2);
  323. rewind(arg1);
  324. c = sgetc(arg1);
  325. if(c == -1)
  326. c = 0;
  327. else
  328. if(sfeof(arg1) == 0)
  329. c = sgetc(arg1)*100 + c;
  330. d = c*savk;
  331. release(arg1);
  332. /* if(neg == 0) { removed to fix -exp bug*/
  333. if(k>=savk)
  334. n = k;
  335. else
  336. n = savk;
  337. if(n<d) {
  338. q = removc(p,d-n);
  339. sputc(q,n);
  340. pushp(q);
  341. } else {
  342. sputc(p,d);
  343. pushp(p);
  344. }
  345. /* } else { this is disaster for exp <-127 */
  346. /* sputc(p,d); */
  347. /* pushp(p); */
  348. /* } */
  349. if(neg == 0)
  350. continue;
  351. p = pop();
  352. q = salloc(2);
  353. sputc(q,1);
  354. sputc(q,0);
  355. pushp(q);
  356. pushp(p);
  357. goto casediv;
  358. case 'z':
  359. p = salloc(2);
  360. n = stkptr - stkbeg;
  361. if(n >= 100) {
  362. sputc(p,n/100);
  363. n %= 100;
  364. }
  365. sputc(p,n);
  366. sputc(p,0);
  367. pushp(p);
  368. continue;
  369. case 'Z':
  370. p = pop();
  371. EMPTY;
  372. n = (length(p)-1)<<1;
  373. fsfile(p);
  374. backc(p);
  375. if(sfbeg(p) == 0) {
  376. if((c = sbackc(p))<0) {
  377. n -= 2;
  378. if(sfbeg(p) == 1)
  379. n++;
  380. else {
  381. if((c = sbackc(p)) == 0)
  382. n++;
  383. else
  384. if(c > 90)
  385. n--;
  386. }
  387. } else
  388. if(c < 10)
  389. n--;
  390. }
  391. release(p);
  392. q = salloc(1);
  393. if(n >= 100) {
  394. sputc(q,n%100);
  395. n /= 100;
  396. }
  397. sputc(q,n);
  398. sputc(q,0);
  399. pushp(q);
  400. continue;
  401. case 'i':
  402. p = pop();
  403. EMPTY;
  404. p = scalint(p);
  405. release(inbas);
  406. inbas = p;
  407. continue;
  408. case 'I':
  409. p = copy(inbas,length(inbas)+1);
  410. sputc(p,0);
  411. pushp(p);
  412. continue;
  413. case 'o':
  414. p = pop();
  415. EMPTY;
  416. p = scalint(p);
  417. sign = 0;
  418. n = length(p);
  419. q = copy(p,n);
  420. fsfile(q);
  421. l = c = sbackc(q);
  422. if(n != 1) {
  423. if(c<0) {
  424. sign = 1;
  425. chsign(q);
  426. n = length(q);
  427. fsfile(q);
  428. l = c = sbackc(q);
  429. }
  430. if(n != 1) {
  431. while(sfbeg(q) == 0)
  432. l = l*100+sbackc(q);
  433. }
  434. }
  435. logo = log2(l);
  436. obase = l;
  437. release(basptr);
  438. if(sign == 1)
  439. obase = -l;
  440. basptr = p;
  441. outdit = bigot;
  442. if(n == 1 && sign == 0) {
  443. if(c <= 16) {
  444. outdit = hexot;
  445. fw = 1;
  446. fw1 = 0;
  447. ll = 70;
  448. release(q);
  449. continue;
  450. }
  451. }
  452. n = 0;
  453. if(sign == 1)
  454. n++;
  455. p = salloc(1);
  456. sputc(p,-1);
  457. t = add(p,q);
  458. n += length(t)*2;
  459. fsfile(t);
  460. if(sbackc(t)>9)
  461. n++;
  462. release(t);
  463. release(q);
  464. release(p);
  465. fw = n;
  466. fw1 = n-1;
  467. ll = 70;
  468. if(fw>=ll)
  469. continue;
  470. ll = (70/fw)*fw;
  471. continue;
  472. case 'O':
  473. p = copy(basptr,length(basptr)+1);
  474. sputc(p,0);
  475. pushp(p);
  476. continue;
  477. case '[':
  478. n = 0;
  479. p = salloc(0);
  480. for(;;) {
  481. if((c = readc()) == ']') {
  482. if(n == 0)
  483. break;
  484. n--;
  485. }
  486. sputc(p,c);
  487. if(c == '[')
  488. n++;
  489. }
  490. pushp(p);
  491. continue;
  492. case 'k':
  493. p = pop();
  494. EMPTY;
  495. p = scalint(p);
  496. if(length(p)>1) {
  497. error("scale too big\n");
  498. }
  499. rewind(p);
  500. k = 0;
  501. if(!sfeof(p))
  502. k = sgetc(p);
  503. release(scalptr);
  504. scalptr = p;
  505. continue;
  506. case 'K':
  507. p = copy(scalptr,length(scalptr)+1);
  508. sputc(p,0);
  509. pushp(p);
  510. continue;
  511. case 'X':
  512. p = pop();
  513. EMPTY;
  514. fsfile(p);
  515. n = sbackc(p);
  516. release(p);
  517. p = salloc(2);
  518. sputc(p,n);
  519. sputc(p,0);
  520. pushp(p);
  521. continue;
  522. case 'Q':
  523. p = pop();
  524. EMPTY;
  525. if(length(p)>2) {
  526. error("Q?\n");
  527. }
  528. rewind(p);
  529. if((c = sgetc(p))<0) {
  530. error("neg Q\n");
  531. }
  532. release(p);
  533. while(c-- > 0) {
  534. if(readptr == &readstk[0]) {
  535. error("readstk?\n");
  536. }
  537. if(*readptr != 0)
  538. release(*readptr);
  539. readptr--;
  540. }
  541. continue;
  542. case 'q':
  543. if(readptr <= &readstk[1])
  544. exits(0);
  545. if(*readptr != 0)
  546. release(*readptr);
  547. readptr--;
  548. if(*readptr != 0)
  549. release(*readptr);
  550. readptr--;
  551. continue;
  552. case 'f':
  553. if(stkptr == &stack[0])
  554. Bprint(&bout,"empty stack\n");
  555. else {
  556. for(ptr = stkptr; ptr > &stack[0];) {
  557. dcprint(*ptr--);
  558. }
  559. }
  560. continue;
  561. case 'p':
  562. if(stkptr == &stack[0])
  563. Bprint(&bout,"empty stack\n");
  564. else {
  565. dcprint(*stkptr);
  566. }
  567. continue;
  568. case 'P':
  569. p = pop();
  570. EMPTY;
  571. sputc(p,0);
  572. Bprint(&bout,"%s",p->beg);
  573. release(p);
  574. continue;
  575. case 'd':
  576. if(stkptr == &stack[0]) {
  577. Bprint(&bout,"empty stack\n");
  578. continue;
  579. }
  580. q = *stkptr;
  581. n = length(q);
  582. p = copy(*stkptr,n);
  583. pushp(p);
  584. continue;
  585. case 'c':
  586. while(stkerr == 0) {
  587. p = pop();
  588. if(stkerr == 0)
  589. release(p);
  590. }
  591. continue;
  592. case 'S':
  593. if(stkptr == &stack[0]) {
  594. error("save: args\n");
  595. }
  596. c = getstk() & 0377;
  597. sptr = stable[c];
  598. sp = stable[c] = sfree;
  599. sfree = sfree->next;
  600. if(sfree == 0)
  601. goto sempty;
  602. sp->next = sptr;
  603. p = pop();
  604. EMPTY;
  605. if(c >= ARRAYST) {
  606. q = copy(p,length(p)+PTRSZ);
  607. for(n = 0;n < PTRSZ;n++) {
  608. sputc(q,0);
  609. }
  610. release(p);
  611. p = q;
  612. }
  613. sp->val = p;
  614. continue;
  615. sempty:
  616. error("symbol table overflow\n");
  617. case 's':
  618. if(stkptr == &stack[0]) {
  619. error("save:args\n");
  620. }
  621. c = getstk() & 0377;
  622. sptr = stable[c];
  623. if(sptr != 0) {
  624. p = sptr->val;
  625. if(c >= ARRAYST) {
  626. rewind(p);
  627. while(sfeof(p) == 0)
  628. release(dcgetwd(p));
  629. }
  630. release(p);
  631. } else {
  632. sptr = stable[c] = sfree;
  633. sfree = sfree->next;
  634. if(sfree == 0)
  635. goto sempty;
  636. sptr->next = 0;
  637. }
  638. p = pop();
  639. sptr->val = p;
  640. continue;
  641. case 'l':
  642. load();
  643. continue;
  644. case 'L':
  645. c = getstk() & 0377;
  646. sptr = stable[c];
  647. if(sptr == 0) {
  648. error("L?\n");
  649. }
  650. stable[c] = sptr->next;
  651. sptr->next = sfree;
  652. sfree = sptr;
  653. p = sptr->val;
  654. if(c >= ARRAYST) {
  655. rewind(p);
  656. while(sfeof(p) == 0) {
  657. q = dcgetwd(p);
  658. if(q != 0)
  659. release(q);
  660. }
  661. }
  662. pushp(p);
  663. continue;
  664. case ':':
  665. p = pop();
  666. EMPTY;
  667. q = scalint(p);
  668. fsfile(q);
  669. c = 0;
  670. if((sfbeg(q) == 0) && ((c = sbackc(q))<0)) {
  671. error("neg index\n");
  672. }
  673. if(length(q)>2) {
  674. error("index too big\n");
  675. }
  676. if(sfbeg(q) == 0)
  677. c = c*100+sbackc(q);
  678. if(c >= MAXIND) {
  679. error("index too big\n");
  680. }
  681. release(q);
  682. n = getstk() & 0377;
  683. sptr = stable[n];
  684. if(sptr == 0) {
  685. sptr = stable[n] = sfree;
  686. sfree = sfree->next;
  687. if(sfree == 0)
  688. goto sempty;
  689. sptr->next = 0;
  690. p = salloc((c+PTRSZ)*PTRSZ);
  691. zero(p);
  692. } else {
  693. p = sptr->val;
  694. if(length(p)-PTRSZ < c*PTRSZ) {
  695. q = copy(p,(c+PTRSZ)*PTRSZ);
  696. release(p);
  697. p = q;
  698. }
  699. }
  700. seekc(p,c*PTRSZ);
  701. q = lookwd(p);
  702. if(q!=0)
  703. release(q);
  704. s = pop();
  705. EMPTY;
  706. salterwd(p, s);
  707. sptr->val = p;
  708. continue;
  709. case ';':
  710. p = pop();
  711. EMPTY;
  712. q = scalint(p);
  713. fsfile(q);
  714. c = 0;
  715. if((sfbeg(q) == 0) && ((c = sbackc(q))<0)) {
  716. error("neg index\n");
  717. }
  718. if(length(q)>2) {
  719. error("index too big\n");
  720. }
  721. if(sfbeg(q) == 0)
  722. c = c*100+sbackc(q);
  723. if(c >= MAXIND) {
  724. error("index too big\n");
  725. }
  726. release(q);
  727. n = getstk() & 0377;
  728. sptr = stable[n];
  729. if(sptr != 0){
  730. p = sptr->val;
  731. if(length(p)-PTRSZ >= c*PTRSZ) {
  732. seekc(p,c*PTRSZ);
  733. s = dcgetwd(p);
  734. if(s != 0) {
  735. q = copy(s,length(s));
  736. pushp(q);
  737. continue;
  738. }
  739. }
  740. }
  741. q = salloc(1); /*so uninitialized array elt prints as 0*/
  742. sputc(q, 0);
  743. pushp(q);
  744. continue;
  745. case 'x':
  746. execute:
  747. p = pop();
  748. EMPTY;
  749. if((readptr != &readstk[0]) && (*readptr != 0)) {
  750. if((*readptr)->rd == (*readptr)->wt)
  751. release(*readptr);
  752. else {
  753. if(readptr++ == &readstk[RDSKSZ]) {
  754. error("nesting depth\n");
  755. }
  756. }
  757. } else
  758. readptr++;
  759. *readptr = p;
  760. if(p != 0)
  761. rewind(p);
  762. else {
  763. if((c = readc()) != '\n')
  764. unreadc(c);
  765. }
  766. continue;
  767. case '?':
  768. if(++readptr == &readstk[RDSKSZ]) {
  769. error("nesting depth\n");
  770. }
  771. *readptr = 0;
  772. fsave = curfile;
  773. curfile = &bin;
  774. while((c = readc()) == '!')
  775. command();
  776. p = salloc(0);
  777. sputc(p,c);
  778. while((c = readc()) != '\n') {
  779. sputc(p,c);
  780. if(c == '\\')
  781. sputc(p,readc());
  782. }
  783. curfile = fsave;
  784. *readptr = p;
  785. continue;
  786. case '!':
  787. if(command() == 1)
  788. goto execute;
  789. continue;
  790. case '<':
  791. case '>':
  792. case '=':
  793. if(cond(c) == 1)
  794. goto execute;
  795. continue;
  796. default:
  797. Bprint(&bout,"%o is unimplemented\n",c);
  798. }
  799. }
  800. }
  801. Blk*
  802. div(Blk *ddivd, Blk *ddivr)
  803. {
  804. int divsign, remsign, offset, divcarry,
  805. carry, dig, magic, d, dd, under, first;
  806. long c, td, cc;
  807. Blk *ps, *px, *p, *divd, *divr;
  808. dig = 0;
  809. under = 0;
  810. divcarry = 0;
  811. rem = 0;
  812. p = salloc(0);
  813. if(length(ddivr) == 0) {
  814. pushp(ddivr);
  815. Bprint(&bout,"divide by 0\n");
  816. return(p);
  817. }
  818. divsign = remsign = first = 0;
  819. divr = ddivr;
  820. fsfile(divr);
  821. if(sbackc(divr) == -1) {
  822. divr = copy(ddivr,length(ddivr));
  823. chsign(divr);
  824. divsign = ~divsign;
  825. }
  826. divd = copy(ddivd,length(ddivd));
  827. fsfile(divd);
  828. if(sfbeg(divd) == 0 && sbackc(divd) == -1) {
  829. chsign(divd);
  830. divsign = ~divsign;
  831. remsign = ~remsign;
  832. }
  833. offset = length(divd) - length(divr);
  834. if(offset < 0)
  835. goto ddone;
  836. seekc(p,offset+1);
  837. sputc(divd,0);
  838. magic = 0;
  839. fsfile(divr);
  840. c = sbackc(divr);
  841. if(c < 10)
  842. magic++;
  843. c = c * 100 + (sfbeg(divr)?0:sbackc(divr));
  844. if(magic>0){
  845. c = (c * 100 +(sfbeg(divr)?0:sbackc(divr)))*2;
  846. c /= 25;
  847. }
  848. while(offset >= 0) {
  849. first++;
  850. fsfile(divd);
  851. td = sbackc(divd) * 100;
  852. dd = sfbeg(divd)?0:sbackc(divd);
  853. td = (td + dd) * 100;
  854. dd = sfbeg(divd)?0:sbackc(divd);
  855. td = td + dd;
  856. cc = c;
  857. if(offset == 0)
  858. td++;
  859. else
  860. cc++;
  861. if(magic != 0)
  862. td = td<<3;
  863. dig = td/cc;
  864. under=0;
  865. if(td%cc < 8 && dig > 0 && magic) {
  866. dig--;
  867. under=1;
  868. }
  869. rewind(divr);
  870. rewind(divxyz);
  871. carry = 0;
  872. while(sfeof(divr) == 0) {
  873. d = sgetc(divr)*dig+carry;
  874. carry = d / 100;
  875. salterc(divxyz,d%100);
  876. }
  877. salterc(divxyz,carry);
  878. rewind(divxyz);
  879. seekc(divd,offset);
  880. carry = 0;
  881. while(sfeof(divd) == 0) {
  882. d = slookc(divd);
  883. d = d-(sfeof(divxyz)?0:sgetc(divxyz))-carry;
  884. carry = 0;
  885. if(d < 0) {
  886. d += 100;
  887. carry = 1;
  888. }
  889. salterc(divd,d);
  890. }
  891. divcarry = carry;
  892. backc(p);
  893. salterc(p,dig);
  894. backc(p);
  895. fsfile(divd);
  896. d=sbackc(divd);
  897. if((d != 0) && /*!divcarry*/ (offset != 0)) {
  898. d = sbackc(divd) + 100;
  899. salterc(divd,d);
  900. }
  901. if(--offset >= 0)
  902. divd->wt--;
  903. }
  904. if(under) { /* undershot last - adjust*/
  905. px = copy(divr,length(divr)); /*11/88 don't corrupt ddivr*/
  906. chsign(px);
  907. ps = add(px,divd);
  908. fsfile(ps);
  909. if(length(ps) > 0 && sbackc(ps) < 0) {
  910. release(ps); /*only adjust in really undershot*/
  911. } else {
  912. release(divd);
  913. salterc(p, dig+1);
  914. divd=ps;
  915. }
  916. }
  917. if(divcarry != 0) {
  918. salterc(p,dig-1);
  919. salterc(divd,-1);
  920. ps = add(divr,divd);
  921. release(divd);
  922. divd = ps;
  923. }
  924. rewind(p);
  925. divcarry = 0;
  926. while(sfeof(p) == 0){
  927. d = slookc(p)+divcarry;
  928. divcarry = 0;
  929. if(d >= 100){
  930. d -= 100;
  931. divcarry = 1;
  932. }
  933. salterc(p,d);
  934. }
  935. if(divcarry != 0)salterc(p,divcarry);
  936. fsfile(p);
  937. while(sfbeg(p) == 0) {
  938. if(sbackc(p) != 0)
  939. break;
  940. truncate(p);
  941. }
  942. if(divsign < 0)
  943. chsign(p);
  944. fsfile(divd);
  945. while(sfbeg(divd) == 0) {
  946. if(sbackc(divd) != 0)
  947. break;
  948. truncate(divd);
  949. }
  950. ddone:
  951. if(remsign<0)
  952. chsign(divd);
  953. if(divr != ddivr)
  954. release(divr);
  955. rem = divd;
  956. return(p);
  957. }
  958. int
  959. dscale(void)
  960. {
  961. Blk *dd, *dr, *r;
  962. int c;
  963. dr = pop();
  964. EMPTYS;
  965. dd = pop();
  966. EMPTYSR(dr);
  967. fsfile(dd);
  968. skd = sunputc(dd);
  969. fsfile(dr);
  970. skr = sunputc(dr);
  971. if(sfbeg(dr) == 1 || (sfbeg(dr) == 0 && sbackc(dr) == 0)) {
  972. sputc(dr,skr);
  973. pushp(dr);
  974. Bprint(&bout,"divide by 0\n");
  975. return(1);
  976. }
  977. if(sfbeg(dd) == 1 || (sfbeg(dd) == 0 && sbackc(dd) == 0)) {
  978. sputc(dd,skd);
  979. pushp(dd);
  980. return(1);
  981. }
  982. c = k-skd+skr;
  983. if(c < 0)
  984. r = removr(dd,-c);
  985. else {
  986. r = add0(dd,c);
  987. irem = 0;
  988. }
  989. arg1 = r;
  990. arg2 = dr;
  991. savk = k;
  992. return(0);
  993. }
  994. Blk*
  995. removr(Blk *p, int n)
  996. {
  997. int nn, neg;
  998. Blk *q, *s, *r;
  999. fsfile(p);
  1000. neg = sbackc(p);
  1001. if(neg < 0)
  1002. chsign(p);
  1003. rewind(p);
  1004. nn = (n+1)/2;
  1005. q = salloc(nn);
  1006. while(n>1) {
  1007. sputc(q,sgetc(p));
  1008. n -= 2;
  1009. }
  1010. r = salloc(2);
  1011. while(sfeof(p) == 0)
  1012. sputc(r,sgetc(p));
  1013. release(p);
  1014. if(n == 1){
  1015. s = div(r,tenptr);
  1016. release(r);
  1017. rewind(rem);
  1018. if(sfeof(rem) == 0)
  1019. sputc(q,sgetc(rem));
  1020. release(rem);
  1021. if(neg < 0){
  1022. chsign(s);
  1023. chsign(q);
  1024. irem = q;
  1025. return(s);
  1026. }
  1027. irem = q;
  1028. return(s);
  1029. }
  1030. if(neg < 0) {
  1031. chsign(r);
  1032. chsign(q);
  1033. irem = q;
  1034. return(r);
  1035. }
  1036. irem = q;
  1037. return(r);
  1038. }
  1039. Blk*
  1040. dcsqrt(Blk *p)
  1041. {
  1042. Blk *t, *r, *q, *s;
  1043. int c, n, nn;
  1044. n = length(p);
  1045. fsfile(p);
  1046. c = sbackc(p);
  1047. if((n&1) != 1)
  1048. c = c*100+(sfbeg(p)?0:sbackc(p));
  1049. n = (n+1)>>1;
  1050. r = salloc(n);
  1051. zero(r);
  1052. seekc(r,n);
  1053. nn=1;
  1054. while((c -= nn)>=0)
  1055. nn+=2;
  1056. c=(nn+1)>>1;
  1057. fsfile(r);
  1058. backc(r);
  1059. if(c>=100) {
  1060. c -= 100;
  1061. salterc(r,c);
  1062. sputc(r,1);
  1063. } else
  1064. salterc(r,c);
  1065. for(;;){
  1066. q = div(p,r);
  1067. s = add(q,r);
  1068. release(q);
  1069. release(rem);
  1070. q = div(s,sqtemp);
  1071. release(s);
  1072. release(rem);
  1073. s = copy(r,length(r));
  1074. chsign(s);
  1075. t = add(s,q);
  1076. release(s);
  1077. fsfile(t);
  1078. nn = sfbeg(t)?0:sbackc(t);
  1079. if(nn>=0)
  1080. break;
  1081. release(r);
  1082. release(t);
  1083. r = q;
  1084. }
  1085. release(t);
  1086. release(q);
  1087. release(p);
  1088. return(r);
  1089. }
  1090. Blk*
  1091. dcexp(Blk *base, Blk *ex)
  1092. {
  1093. Blk *r, *e, *p, *e1, *t, *cp;
  1094. int temp, c, n;
  1095. r = salloc(1);
  1096. sputc(r,1);
  1097. p = copy(base,length(base));
  1098. e = copy(ex,length(ex));
  1099. fsfile(e);
  1100. if(sfbeg(e) != 0)
  1101. goto edone;
  1102. temp=0;
  1103. c = sbackc(e);
  1104. if(c<0) {
  1105. temp++;
  1106. chsign(e);
  1107. }
  1108. while(length(e) != 0) {
  1109. e1=div(e,sqtemp);
  1110. release(e);
  1111. e = e1;
  1112. n = length(rem);
  1113. release(rem);
  1114. if(n != 0) {
  1115. e1=mult(p,r);
  1116. release(r);
  1117. r = e1;
  1118. }
  1119. t = copy(p,length(p));
  1120. cp = mult(p,t);
  1121. release(p);
  1122. release(t);
  1123. p = cp;
  1124. }
  1125. if(temp != 0) {
  1126. if((c = length(base)) == 0) {
  1127. goto edone;
  1128. }
  1129. if(c>1)
  1130. create(r);
  1131. else {
  1132. rewind(base);
  1133. if((c = sgetc(base))<=1) {
  1134. create(r);
  1135. sputc(r,c);
  1136. } else
  1137. create(r);
  1138. }
  1139. }
  1140. edone:
  1141. release(p);
  1142. release(e);
  1143. return(r);
  1144. }
  1145. void
  1146. init(int argc, char *argv[])
  1147. {
  1148. Sym *sp;
  1149. Dir *d;
  1150. ARGBEGIN {
  1151. default:
  1152. dbg = 1;
  1153. break;
  1154. } ARGEND
  1155. ifile = 1;
  1156. curfile = &bin;
  1157. if(*argv){
  1158. d = dirstat(*argv);
  1159. if(d == nil) {
  1160. fprint(2, "dc: can't open file %s\n", *argv);
  1161. exits("open");
  1162. }
  1163. if(d->mode & DMDIR) {
  1164. fprint(2, "dc: file %s is a directory\n", *argv);
  1165. exits("open");
  1166. }
  1167. free(d);
  1168. if((curfile = Bopen(*argv, OREAD)) == 0) {
  1169. fprint(2,"dc: can't open file %s\n", *argv);
  1170. exits("open");
  1171. }
  1172. }
  1173. /* dummy = malloc(0); /* prepare for garbage-collection */
  1174. scalptr = salloc(1);
  1175. sputc(scalptr,0);
  1176. basptr = salloc(1);
  1177. sputc(basptr,10);
  1178. obase=10;
  1179. logten=log2(10L);
  1180. ll=70;
  1181. fw=1;
  1182. fw1=0;
  1183. tenptr = salloc(1);
  1184. sputc(tenptr,10);
  1185. obase=10;
  1186. inbas = salloc(1);
  1187. sputc(inbas,10);
  1188. sqtemp = salloc(1);
  1189. sputc(sqtemp,2);
  1190. chptr = salloc(0);
  1191. strptr = salloc(0);
  1192. divxyz = salloc(0);
  1193. stkbeg = stkptr = &stack[0];
  1194. stkend = &stack[STKSZ];
  1195. stkerr = 0;
  1196. readptr = &readstk[0];
  1197. k=0;
  1198. sp = sptr = &symlst[0];
  1199. while(sptr < &symlst[TBLSZ]) {
  1200. sptr->next = ++sp;
  1201. sptr++;
  1202. }
  1203. sptr->next=0;
  1204. sfree = &symlst[0];
  1205. }
  1206. void
  1207. pushp(Blk *p)
  1208. {
  1209. if(stkptr == stkend) {
  1210. Bprint(&bout,"out of stack space\n");
  1211. return;
  1212. }
  1213. stkerr=0;
  1214. *++stkptr = p;
  1215. return;
  1216. }
  1217. Blk*
  1218. pop(void)
  1219. {
  1220. if(stkptr == stack) {
  1221. stkerr=1;
  1222. return(0);
  1223. }
  1224. return(*stkptr--);
  1225. }
  1226. Blk*
  1227. readin(void)
  1228. {
  1229. Blk *p, *q;
  1230. int dp, dpct, c;
  1231. dp = dpct=0;
  1232. p = salloc(0);
  1233. for(;;){
  1234. c = readc();
  1235. switch(c) {
  1236. case '.':
  1237. if(dp != 0)
  1238. goto gotnum;
  1239. dp++;
  1240. continue;
  1241. case '\\':
  1242. readc();
  1243. continue;
  1244. default:
  1245. if(c >= 'A' && c <= 'F')
  1246. c = c - 'A' + 10;
  1247. else
  1248. if(c >= '0' && c <= '9')
  1249. c -= '0';
  1250. else
  1251. goto gotnum;
  1252. if(dp != 0) {
  1253. if(dpct >= 99)
  1254. continue;
  1255. dpct++;
  1256. }
  1257. create(chptr);
  1258. if(c != 0)
  1259. sputc(chptr,c);
  1260. q = mult(p,inbas);
  1261. release(p);
  1262. p = add(chptr,q);
  1263. release(q);
  1264. }
  1265. }
  1266. gotnum:
  1267. unreadc(c);
  1268. if(dp == 0) {
  1269. sputc(p,0);
  1270. return(p);
  1271. } else {
  1272. q = scale(p,dpct);
  1273. return(q);
  1274. }
  1275. }
  1276. /*
  1277. * returns pointer to struct with ct 0's & p
  1278. */
  1279. Blk*
  1280. add0(Blk *p, int ct)
  1281. {
  1282. Blk *q, *t;
  1283. q = salloc(length(p)+(ct+1)/2);
  1284. while(ct>1) {
  1285. sputc(q,0);
  1286. ct -= 2;
  1287. }
  1288. rewind(p);
  1289. while(sfeof(p) == 0) {
  1290. sputc(q,sgetc(p));
  1291. }
  1292. release(p);
  1293. if(ct == 1) {
  1294. t = mult(tenptr,q);
  1295. release(q);
  1296. return(t);
  1297. }
  1298. return(q);
  1299. }
  1300. Blk*
  1301. mult(Blk *p, Blk *q)
  1302. {
  1303. Blk *mp, *mq, *mr;
  1304. int sign, offset, carry;
  1305. int cq, cp, mt, mcr;
  1306. offset = sign = 0;
  1307. fsfile(p);
  1308. mp = p;
  1309. if(sfbeg(p) == 0) {
  1310. if(sbackc(p)<0) {
  1311. mp = copy(p,length(p));
  1312. chsign(mp);
  1313. sign = ~sign;
  1314. }
  1315. }
  1316. fsfile(q);
  1317. mq = q;
  1318. if(sfbeg(q) == 0){
  1319. if(sbackc(q)<0) {
  1320. mq = copy(q,length(q));
  1321. chsign(mq);
  1322. sign = ~sign;
  1323. }
  1324. }
  1325. mr = salloc(length(mp)+length(mq));
  1326. zero(mr);
  1327. rewind(mq);
  1328. while(sfeof(mq) == 0) {
  1329. cq = sgetc(mq);
  1330. rewind(mp);
  1331. rewind(mr);
  1332. mr->rd += offset;
  1333. carry=0;
  1334. while(sfeof(mp) == 0) {
  1335. cp = sgetc(mp);
  1336. mcr = sfeof(mr)?0:slookc(mr);
  1337. mt = cp*cq + carry + mcr;
  1338. carry = mt/100;
  1339. salterc(mr,mt%100);
  1340. }
  1341. offset++;
  1342. if(carry != 0) {
  1343. mcr = sfeof(mr)?0:slookc(mr);
  1344. salterc(mr,mcr+carry);
  1345. }
  1346. }
  1347. if(sign < 0) {
  1348. chsign(mr);
  1349. }
  1350. if(mp != p)
  1351. release(mp);
  1352. if(mq != q)
  1353. release(mq);
  1354. return(mr);
  1355. }
  1356. void
  1357. chsign(Blk *p)
  1358. {
  1359. int carry;
  1360. char ct;
  1361. carry=0;
  1362. rewind(p);
  1363. while(sfeof(p) == 0) {
  1364. ct=100-slookc(p)-carry;
  1365. carry=1;
  1366. if(ct>=100) {
  1367. ct -= 100;
  1368. carry=0;
  1369. }
  1370. salterc(p,ct);
  1371. }
  1372. if(carry != 0) {
  1373. sputc(p,-1);
  1374. fsfile(p);
  1375. backc(p);
  1376. ct = sbackc(p);
  1377. if(ct == 99 /*&& !sfbeg(p)*/) {
  1378. truncate(p);
  1379. sputc(p,-1);
  1380. }
  1381. } else{
  1382. fsfile(p);
  1383. ct = sbackc(p);
  1384. if(ct == 0)
  1385. truncate(p);
  1386. }
  1387. return;
  1388. }
  1389. int
  1390. readc(void)
  1391. {
  1392. loop:
  1393. if((readptr != &readstk[0]) && (*readptr != 0)) {
  1394. if(sfeof(*readptr) == 0)
  1395. return(lastchar = sgetc(*readptr));
  1396. release(*readptr);
  1397. readptr--;
  1398. goto loop;
  1399. }
  1400. lastchar = Bgetc(curfile);
  1401. if(lastchar != -1)
  1402. return(lastchar);
  1403. if(readptr != &readptr[0]) {
  1404. readptr--;
  1405. if(*readptr == 0)
  1406. curfile = &bin;
  1407. goto loop;
  1408. }
  1409. if(curfile != &bin) {
  1410. Bterm(curfile);
  1411. curfile = &bin;
  1412. goto loop;
  1413. }
  1414. exits(0);
  1415. return 0; /* shut up ken */
  1416. }
  1417. void
  1418. unreadc(char c)
  1419. {
  1420. if((readptr != &readstk[0]) && (*readptr != 0)) {
  1421. sungetc(*readptr,c);
  1422. } else
  1423. Bungetc(curfile);
  1424. return;
  1425. }
  1426. void
  1427. binop(char c)
  1428. {
  1429. Blk *r;
  1430. r = 0;
  1431. switch(c) {
  1432. case '+':
  1433. r = add(arg1,arg2);
  1434. break;
  1435. case '*':
  1436. r = mult(arg1,arg2);
  1437. break;
  1438. case '/':
  1439. r = div(arg1,arg2);
  1440. break;
  1441. }
  1442. release(arg1);
  1443. release(arg2);
  1444. sputc(r,savk);
  1445. pushp(r);
  1446. }
  1447. void
  1448. dcprint(Blk *hptr)
  1449. {
  1450. Blk *p, *q, *dec;
  1451. int dig, dout, ct, sc;
  1452. rewind(hptr);
  1453. while(sfeof(hptr) == 0) {
  1454. if(sgetc(hptr)>99) {
  1455. rewind(hptr);
  1456. while(sfeof(hptr) == 0) {
  1457. Bprint(&bout,"%c",sgetc(hptr));
  1458. }
  1459. Bprint(&bout,"\n");
  1460. return;
  1461. }
  1462. }
  1463. fsfile(hptr);
  1464. sc = sbackc(hptr);
  1465. if(sfbeg(hptr) != 0) {
  1466. Bprint(&bout,"0\n");
  1467. return;
  1468. }
  1469. count = ll;
  1470. p = copy(hptr,length(hptr));
  1471. sclobber(p);
  1472. fsfile(p);
  1473. if(sbackc(p)<0) {
  1474. chsign(p);
  1475. OUTC('-');
  1476. }
  1477. if((obase == 0) || (obase == -1)) {
  1478. oneot(p,sc,'d');
  1479. return;
  1480. }
  1481. if(obase == 1) {
  1482. oneot(p,sc,'1');
  1483. return;
  1484. }
  1485. if(obase == 10) {
  1486. tenot(p,sc);
  1487. return;
  1488. }
  1489. /* sleazy hack to scale top of stack - divide by 1 */
  1490. pushp(p);
  1491. sputc(p, sc);
  1492. p=salloc(0);
  1493. create(p);
  1494. sputc(p, 1);
  1495. sputc(p, 0);
  1496. pushp(p);
  1497. if(dscale() != 0)
  1498. return;
  1499. p = div(arg1, arg2);
  1500. release(arg1);
  1501. release(arg2);
  1502. sc = savk;
  1503. create(strptr);
  1504. dig = logten*sc;
  1505. dout = ((dig/10) + dig) / logo;
  1506. dec = getdec(p,sc);
  1507. p = removc(p,sc);
  1508. while(length(p) != 0) {
  1509. q = div(p,basptr);
  1510. release(p);
  1511. p = q;
  1512. (*outdit)(rem,0);
  1513. }
  1514. release(p);
  1515. fsfile(strptr);
  1516. while(sfbeg(strptr) == 0)
  1517. OUTC(sbackc(strptr));
  1518. if(sc == 0) {
  1519. release(dec);
  1520. Bprint(&bout,"\n");
  1521. return;
  1522. }
  1523. create(strptr);
  1524. OUTC('.');
  1525. ct=0;
  1526. do {
  1527. q = mult(basptr,dec);
  1528. release(dec);
  1529. dec = getdec(q,sc);
  1530. p = removc(q,sc);
  1531. (*outdit)(p,1);
  1532. } while(++ct < dout);
  1533. release(dec);
  1534. rewind(strptr);
  1535. while(sfeof(strptr) == 0)
  1536. OUTC(sgetc(strptr));
  1537. Bprint(&bout,"\n");
  1538. }
  1539. Blk*
  1540. getdec(Blk *p, int sc)
  1541. {
  1542. int cc;
  1543. Blk *q, *t, *s;
  1544. rewind(p);
  1545. if(length(p)*2 < sc) {
  1546. q = copy(p,length(p));
  1547. return(q);
  1548. }
  1549. q = salloc(length(p));
  1550. while(sc >= 1) {
  1551. sputc(q,sgetc(p));
  1552. sc -= 2;
  1553. }
  1554. if(sc != 0) {
  1555. t = mult(q,tenptr);
  1556. s = salloc(cc = length(q));
  1557. release(q);
  1558. rewind(t);
  1559. while(cc-- > 0)
  1560. sputc(s,sgetc(t));
  1561. sputc(s,0);
  1562. release(t);
  1563. t = div(s,tenptr);
  1564. release(s);
  1565. release(rem);
  1566. return(t);
  1567. }
  1568. return(q);
  1569. }
  1570. void
  1571. tenot(Blk *p, int sc)
  1572. {
  1573. int c, f;
  1574. fsfile(p);
  1575. f=0;
  1576. while((sfbeg(p) == 0) && ((p->rd-p->beg-1)*2 >= sc)) {
  1577. c = sbackc(p);
  1578. if((c<10) && (f == 1))
  1579. Bprint(&bout,"0%d",c);
  1580. else
  1581. Bprint(&bout,"%d",c);
  1582. f=1;
  1583. TEST2;
  1584. }
  1585. if(sc == 0) {
  1586. Bprint(&bout,"\n");
  1587. release(p);
  1588. return;
  1589. }
  1590. if((p->rd-p->beg)*2 > sc) {
  1591. c = sbackc(p);
  1592. Bprint(&bout,"%d.",c/10);
  1593. TEST2;
  1594. OUTC(c%10 +'0');
  1595. sc--;
  1596. } else {
  1597. OUTC('.');
  1598. }
  1599. while(sc>(p->rd-p->beg)*2) {
  1600. OUTC('0');
  1601. sc--;
  1602. }
  1603. while(sc > 1) {
  1604. c = sbackc(p);
  1605. if(c<10)
  1606. Bprint(&bout,"0%d",c);
  1607. else
  1608. Bprint(&bout,"%d",c);
  1609. sc -= 2;
  1610. TEST2;
  1611. }
  1612. if(sc == 1) {
  1613. OUTC(sbackc(p)/10 +'0');
  1614. }
  1615. Bprint(&bout,"\n");
  1616. release(p);
  1617. }
  1618. void
  1619. oneot(Blk *p, int sc, char ch)
  1620. {
  1621. Blk *q;
  1622. q = removc(p,sc);
  1623. create(strptr);
  1624. sputc(strptr,-1);
  1625. while(length(q)>0) {
  1626. p = add(strptr,q);
  1627. release(q);
  1628. q = p;
  1629. OUTC(ch);
  1630. }
  1631. release(q);
  1632. Bprint(&bout,"\n");
  1633. }
  1634. void
  1635. hexot(Blk *p, int flg)
  1636. {
  1637. int c;
  1638. USED(flg);
  1639. rewind(p);
  1640. if(sfeof(p) != 0) {
  1641. sputc(strptr,'0');
  1642. release(p);
  1643. return;
  1644. }
  1645. c = sgetc(p);
  1646. release(p);
  1647. if(c >= 16) {
  1648. Bprint(&bout,"hex digit > 16");
  1649. return;
  1650. }
  1651. sputc(strptr,c<10?c+'0':c-10+'a');
  1652. }
  1653. void
  1654. bigot(Blk *p, int flg)
  1655. {
  1656. Blk *t, *q;
  1657. int neg, l;
  1658. if(flg == 1) {
  1659. t = salloc(0);
  1660. l = 0;
  1661. } else {
  1662. t = strptr;
  1663. l = length(strptr)+fw-1;
  1664. }
  1665. neg=0;
  1666. if(length(p) != 0) {
  1667. fsfile(p);
  1668. if(sbackc(p)<0) {
  1669. neg=1;
  1670. chsign(p);
  1671. }
  1672. while(length(p) != 0) {
  1673. q = div(p,tenptr);
  1674. release(p);
  1675. p = q;
  1676. rewind(rem);
  1677. sputc(t,sfeof(rem)?'0':sgetc(rem)+'0');
  1678. release(rem);
  1679. }
  1680. }
  1681. release(p);
  1682. if(flg == 1) {
  1683. l = fw1-length(t);
  1684. if(neg != 0) {
  1685. l--;
  1686. sputc(strptr,'-');
  1687. }
  1688. fsfile(t);
  1689. while(l-- > 0)
  1690. sputc(strptr,'0');
  1691. while(sfbeg(t) == 0)
  1692. sputc(strptr,sbackc(t));
  1693. release(t);
  1694. } else {
  1695. l -= length(strptr);
  1696. while(l-- > 0)
  1697. sputc(strptr,'0');
  1698. if(neg != 0) {
  1699. sclobber(strptr);
  1700. sputc(strptr,'-');
  1701. }
  1702. }
  1703. sputc(strptr,' ');
  1704. }
  1705. Blk*
  1706. add(Blk *a1, Blk *a2)
  1707. {
  1708. Blk *p;
  1709. int carry, n, size, c, n1, n2;
  1710. size = length(a1)>length(a2)?length(a1):length(a2);
  1711. p = salloc(size);
  1712. rewind(a1);
  1713. rewind(a2);
  1714. carry=0;
  1715. while(--size >= 0) {
  1716. n1 = sfeof(a1)?0:sgetc(a1);
  1717. n2 = sfeof(a2)?0:sgetc(a2);
  1718. n = n1 + n2 + carry;
  1719. if(n>=100) {
  1720. carry=1;
  1721. n -= 100;
  1722. } else
  1723. if(n<0) {
  1724. carry = -1;
  1725. n += 100;
  1726. } else
  1727. carry = 0;
  1728. sputc(p,n);
  1729. }
  1730. if(carry != 0)
  1731. sputc(p,carry);
  1732. fsfile(p);
  1733. if(sfbeg(p) == 0) {
  1734. c = 0;
  1735. while(sfbeg(p) == 0 && (c = sbackc(p)) == 0)
  1736. ;
  1737. if(c != 0)
  1738. salterc(p,c);
  1739. truncate(p);
  1740. }
  1741. fsfile(p);
  1742. if(sfbeg(p) == 0 && sbackc(p) == -1) {
  1743. while((c = sbackc(p)) == 99) {
  1744. if(c == -1)
  1745. break;
  1746. }
  1747. skipc(p);
  1748. salterc(p,-1);
  1749. truncate(p);
  1750. }
  1751. return(p);
  1752. }
  1753. int
  1754. eqk(void)
  1755. {
  1756. Blk *p, *q;
  1757. int skp, skq;
  1758. p = pop();
  1759. EMPTYS;
  1760. q = pop();
  1761. EMPTYSR(p);
  1762. skp = sunputc(p);
  1763. skq = sunputc(q);
  1764. if(skp == skq) {
  1765. arg1=p;
  1766. arg2=q;
  1767. savk = skp;
  1768. return(0);
  1769. }
  1770. if(skp < skq) {
  1771. savk = skq;
  1772. p = add0(p,skq-skp);
  1773. } else {
  1774. savk = skp;
  1775. q = add0(q,skp-skq);
  1776. }
  1777. arg1=p;
  1778. arg2=q;
  1779. return(0);
  1780. }
  1781. Blk*
  1782. removc(Blk *p, int n)
  1783. {
  1784. Blk *q, *r;
  1785. rewind(p);
  1786. while(n>1) {
  1787. skipc(p);
  1788. n -= 2;
  1789. }
  1790. q = salloc(2);
  1791. while(sfeof(p) == 0)
  1792. sputc(q,sgetc(p));
  1793. if(n == 1) {
  1794. r = div(q,tenptr);
  1795. release(q);
  1796. release(rem);
  1797. q = r;
  1798. }
  1799. release(p);
  1800. return(q);
  1801. }
  1802. Blk*
  1803. scalint(Blk *p)
  1804. {
  1805. int n;
  1806. n = sunputc(p);
  1807. p = removc(p,n);
  1808. return(p);
  1809. }
  1810. Blk*
  1811. scale(Blk *p, int n)
  1812. {
  1813. Blk *q, *s, *t;
  1814. t = add0(p,n);
  1815. q = salloc(1);
  1816. sputc(q,n);
  1817. s = dcexp(inbas,q);
  1818. release(q);
  1819. q = div(t,s);
  1820. release(t);
  1821. release(s);
  1822. release(rem);
  1823. sputc(q,n);
  1824. return(q);
  1825. }
  1826. int
  1827. subt(void)
  1828. {
  1829. arg1=pop();
  1830. EMPTYS;
  1831. savk = sunputc(arg1);
  1832. chsign(arg1);
  1833. sputc(arg1,savk);
  1834. pushp(arg1);
  1835. if(eqk() != 0)
  1836. return(1);
  1837. binop('+');
  1838. return(0);
  1839. }
  1840. int
  1841. command(void)
  1842. {
  1843. char line[100], *sl;
  1844. int pid, p, c;
  1845. switch(c = readc()) {
  1846. case '<':
  1847. return(cond(NL));
  1848. case '>':
  1849. return(cond(NG));
  1850. case '=':
  1851. return(cond(NE));
  1852. default:
  1853. sl = line;
  1854. *sl++ = c;
  1855. while((c = readc()) != '\n')
  1856. *sl++ = c;
  1857. *sl = 0;
  1858. if((pid = fork()) == 0) {
  1859. execl("/bin/rc","rc","-c",line,nil);
  1860. exits("shell");
  1861. }
  1862. for(;;) {
  1863. if((p = waitpid()) < 0)
  1864. break;
  1865. if(p== pid)
  1866. break;
  1867. }
  1868. Bprint(&bout,"!\n");
  1869. return(0);
  1870. }
  1871. }
  1872. int
  1873. cond(char c)
  1874. {
  1875. Blk *p;
  1876. int cc;
  1877. if(subt() != 0)
  1878. return(1);
  1879. p = pop();
  1880. sclobber(p);
  1881. if(length(p) == 0) {
  1882. release(p);
  1883. if(c == '<' || c == '>' || c == NE) {
  1884. getstk();
  1885. return(0);
  1886. }
  1887. load();
  1888. return(1);
  1889. }
  1890. if(c == '='){
  1891. release(p);
  1892. getstk();
  1893. return(0);
  1894. }
  1895. if(c == NE) {
  1896. release(p);
  1897. load();
  1898. return(1);
  1899. }
  1900. fsfile(p);
  1901. cc = sbackc(p);
  1902. release(p);
  1903. if((cc<0 && (c == '<' || c == NG)) ||
  1904. (cc >0) && (c == '>' || c == NL)) {
  1905. getstk();
  1906. return(0);
  1907. }
  1908. load();
  1909. return(1);
  1910. }
  1911. void
  1912. load(void)
  1913. {
  1914. int c;
  1915. Blk *p, *q, *t, *s;
  1916. c = getstk() & 0377;
  1917. sptr = stable[c];
  1918. if(sptr != 0) {
  1919. p = sptr->val;
  1920. if(c >= ARRAYST) {
  1921. q = salloc(length(p));
  1922. rewind(p);
  1923. while(sfeof(p) == 0) {
  1924. s = dcgetwd(p);
  1925. if(s == 0) {
  1926. putwd(q, (Blk*)0);
  1927. } else {
  1928. t = copy(s,length(s));
  1929. putwd(q,t);
  1930. }
  1931. }
  1932. pushp(q);
  1933. } else {
  1934. q = copy(p,length(p));
  1935. pushp(q);
  1936. }
  1937. } else {
  1938. q = salloc(1);
  1939. if(c <= LASTFUN) {
  1940. Bprint(&bout,"function %c undefined\n",c+'a'-1);
  1941. sputc(q,'c');
  1942. sputc(q,'0');
  1943. sputc(q,' ');
  1944. sputc(q,'1');
  1945. sputc(q,'Q');
  1946. }
  1947. else
  1948. sputc(q,0);
  1949. pushp(q);
  1950. }
  1951. }
  1952. int
  1953. log2(long n)
  1954. {
  1955. int i;
  1956. if(n == 0)
  1957. return(0);
  1958. i=31;
  1959. if(n<0)
  1960. return(i);
  1961. while((n= n<<1) >0)
  1962. i--;
  1963. return i-1;
  1964. }
  1965. Blk*
  1966. salloc(int size)
  1967. {
  1968. Blk *hdr;
  1969. char *ptr;
  1970. all++;
  1971. lall++;
  1972. if(all - rel > active)
  1973. active = all - rel;
  1974. nbytes += size;
  1975. lbytes += size;
  1976. if(nbytes >maxsize)
  1977. maxsize = nbytes;
  1978. if(size > longest)
  1979. longest = size;
  1980. ptr = malloc((unsigned)size);
  1981. if(ptr == 0){
  1982. garbage("salloc");
  1983. if((ptr = malloc((unsigned)size)) == 0)
  1984. ospace("salloc");
  1985. }
  1986. if((hdr = hfree) == 0)
  1987. hdr = morehd();
  1988. hfree = (Blk *)hdr->rd;
  1989. hdr->rd = hdr->wt = hdr->beg = ptr;
  1990. hdr->last = ptr+size;
  1991. return(hdr);
  1992. }
  1993. Blk*
  1994. morehd(void)
  1995. {
  1996. Blk *h, *kk;
  1997. headmor++;
  1998. nbytes += HEADSZ;
  1999. hfree = h = (Blk *)malloc(HEADSZ);
  2000. if(hfree == 0) {
  2001. garbage("morehd");
  2002. if((hfree = h = (Blk*)malloc(HEADSZ)) == 0)
  2003. ospace("headers");
  2004. }
  2005. kk = h;
  2006. while(h<hfree+(HEADSZ/BLK))
  2007. (h++)->rd = (char*)++kk;
  2008. (h-1)->rd=0;
  2009. return(hfree);
  2010. }
  2011. Blk*
  2012. copy(Blk *hptr, int size)
  2013. {
  2014. Blk *hdr;
  2015. unsigned sz;
  2016. char *ptr;
  2017. all++;
  2018. lall++;
  2019. lcopy++;
  2020. nbytes += size;
  2021. lbytes += size;
  2022. if(size > longest)
  2023. longest = size;
  2024. if(size > maxsize)
  2025. maxsize = size;
  2026. sz = length(hptr);
  2027. ptr = nalloc(hptr->beg, size);
  2028. if(ptr == 0) {
  2029. garbage("copy");
  2030. if((ptr = nalloc(hptr->beg, size)) == 0) {
  2031. Bprint(&bout,"copy size %d\n",size);
  2032. ospace("copy");
  2033. }
  2034. }
  2035. if((hdr = hfree) == 0)
  2036. hdr = morehd();
  2037. hfree = (Blk *)hdr->rd;
  2038. hdr->rd = hdr->beg = ptr;
  2039. hdr->last = ptr+size;
  2040. hdr->wt = ptr+sz;
  2041. ptr = hdr->wt;
  2042. while(ptr<hdr->last)
  2043. *ptr++ = '\0';
  2044. return(hdr);
  2045. }
  2046. void
  2047. sdump(char *s1, Blk *hptr)
  2048. {
  2049. char *p;
  2050. Bprint(&bout,"%s %lx rd %lx wt %lx beg %lx last %lx\n",
  2051. s1,hptr,hptr->rd,hptr->wt,hptr->beg,hptr->last);
  2052. p = hptr->beg;
  2053. while(p < hptr->wt)
  2054. Bprint(&bout,"%d ",*p++);
  2055. Bprint(&bout,"\n");
  2056. }
  2057. void
  2058. seekc(Blk *hptr, int n)
  2059. {
  2060. char *nn,*p;
  2061. nn = hptr->beg+n;
  2062. if(nn > hptr->last) {
  2063. nbytes += nn - hptr->last;
  2064. if(nbytes > maxsize)
  2065. maxsize = nbytes;
  2066. lbytes += nn - hptr->last;
  2067. if(n > longest)
  2068. longest = n;
  2069. /* free(hptr->beg); /**/
  2070. p = realloc(hptr->beg, n);
  2071. if(p == 0) {
  2072. /* hptr->beg = realloc(hptr->beg, hptr->last-hptr->beg);
  2073. ** garbage("seekc");
  2074. ** if((p = realloc(hptr->beg, n)) == 0)
  2075. */ ospace("seekc");
  2076. }
  2077. hptr->beg = p;
  2078. hptr->wt = hptr->last = hptr->rd = p+n;
  2079. return;
  2080. }
  2081. hptr->rd = nn;
  2082. if(nn>hptr->wt)
  2083. hptr->wt = nn;
  2084. }
  2085. void
  2086. salterwd(Blk *ahptr, Blk *n)
  2087. {
  2088. Wblk *hptr;
  2089. hptr = (Wblk*)ahptr;
  2090. if(hptr->rdw == hptr->lastw)
  2091. more(ahptr);
  2092. *hptr->rdw++ = n;
  2093. if(hptr->rdw > hptr->wtw)
  2094. hptr->wtw = hptr->rdw;
  2095. }
  2096. void
  2097. more(Blk *hptr)
  2098. {
  2099. unsigned size;
  2100. char *p;
  2101. if((size=(hptr->last-hptr->beg)*2) == 0)
  2102. size=2;
  2103. nbytes += size/2;
  2104. if(nbytes > maxsize)
  2105. maxsize = nbytes;
  2106. if(size > longest)
  2107. longest = size;
  2108. lbytes += size/2;
  2109. lmore++;
  2110. /* free(hptr->beg);/**/
  2111. p = realloc(hptr->beg, size);
  2112. if(p == 0) {
  2113. /* hptr->beg = realloc(hptr->beg, (hptr->last-hptr->beg));
  2114. ** garbage("more");
  2115. ** if((p = realloc(hptr->beg,size)) == 0)
  2116. */ ospace("more");
  2117. }
  2118. hptr->rd = p + (hptr->rd - hptr->beg);
  2119. hptr->wt = p + (hptr->wt - hptr->beg);
  2120. hptr->beg = p;
  2121. hptr->last = p+size;
  2122. }
  2123. void
  2124. ospace(char *s)
  2125. {
  2126. Bprint(&bout,"out of space: %s\n",s);
  2127. Bprint(&bout,"all %ld rel %ld headmor %ld\n",all,rel,headmor);
  2128. Bprint(&bout,"nbytes %ld\n",nbytes);
  2129. sdump("stk",*stkptr);
  2130. abort();
  2131. }
  2132. void
  2133. garbage(char *s)
  2134. {
  2135. USED(s);
  2136. }
  2137. void
  2138. release(Blk *p)
  2139. {
  2140. rel++;
  2141. lrel++;
  2142. nbytes -= p->last - p->beg;
  2143. p->rd = (char*)hfree;
  2144. hfree = p;
  2145. free(p->beg);
  2146. }
  2147. Blk*
  2148. dcgetwd(Blk *p)
  2149. {
  2150. Wblk *wp;
  2151. wp = (Wblk*)p;
  2152. if(wp->rdw == wp->wtw)
  2153. return(0);
  2154. return(*wp->rdw++);
  2155. }
  2156. void
  2157. putwd(Blk *p, Blk *c)
  2158. {
  2159. Wblk *wp;
  2160. wp = (Wblk*)p;
  2161. if(wp->wtw == wp->lastw)
  2162. more(p);
  2163. *wp->wtw++ = c;
  2164. }
  2165. Blk*
  2166. lookwd(Blk *p)
  2167. {
  2168. Wblk *wp;
  2169. wp = (Wblk*)p;
  2170. if(wp->rdw == wp->wtw)
  2171. return(0);
  2172. return(*wp->rdw);
  2173. }
  2174. char*
  2175. nalloc(char *p, unsigned nbytes)
  2176. {
  2177. char *q, *r;
  2178. q = r = malloc(nbytes);
  2179. if(q==0)
  2180. return(0);
  2181. while(nbytes--)
  2182. *q++ = *p++;
  2183. return(r);
  2184. }
  2185. int
  2186. getstk(void)
  2187. {
  2188. int n;
  2189. uchar c;
  2190. c = readc();
  2191. if(c != '<')
  2192. return c;
  2193. n = 0;
  2194. while(1) {
  2195. c = readc();
  2196. if(c == '>')
  2197. break;
  2198. n = n*10+c-'0';
  2199. }
  2200. return n;
  2201. }