dc.c 36 KB

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