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