dc.c 36 KB

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