|
|
1.1 root 1: #include "apl.h"
2: /*#include "/usr/sys/tty.h" /* pick up TECO-mode bit */
3: #define APLMOD 01000
4: short TERMtype = 0 ; /* for now ( very stupid variable) */
5:
6: short chartab[];
7: char partab[1];
8:
9: int ifile = 0,
10: ofile = 1;
11:
12: data zero = 0.0;
13: data one = 1.0;
14: data pi = 3.141592653589793238462643383;
15: data maxexp = 88.0;
16:
17: struct env thread = {
18: 1.0e-13, 1,
19: 9, 72
20: };
21:
22: main(ac,av)
23: char **av;
24: {
25: register a, c;
26: int fflag;
27: int intr();
28: int floatover();
29: extern headline[];
30:
31: memstart = sbrk(0);
32:
33: Reset();
34: signal(8,floatover);
35: if(--ac&&*av[1]=='-')
36: ++echoflg;
37: time(stime);
38: setterm(1); /* turn off APL mode */
39: aprintf(headline);
40:
41: if(ttyname(0) == 'x')
42: echoflg++;
43:
44: a = "apl_ws";
45: while((wfile = open(a, 2)) < 0) {
46: c = creat(a, 0666);
47: if(c < 0) {
48: aprintf("cannot create apl_ws");
49: exit(0);
50: }
51: close(c);
52: }
53:
54: fflag = 1;
55:
56: sp = stack;
57: signal(2, intr);
58: setexit();
59:
60: if(fflag) {
61: fflag =0;
62: if((a=open("continue",0)) < 0) {
63: aprintf("clear ws\n");
64: goto loop;
65: }
66: wsload(a);
67: aprintf(" continue\n");
68: }
69:
70: loop:
71: while(sp > stack)
72: pop();
73: Reset();
74: signal(8,floatover);
75: if(intflg)
76: error("I");
77: if(!ifile&&ofile==1)
78: aputchar('\t');
79: a = rline(8);
80: if(a==0) {
81: if(ifile) {
82: ifile = 0;
83: goto loop;
84: }
85: ctrld();
86: }
87: c = compile(a, 0);
88: afree(a);
89: if(c == 0)
90: goto loop;
91: execute(c);
92: afree(c);
93: goto loop;
94: }
95:
96: /* this procedure is for trapping floating point exceptions, and */
97: /* then reset the program. added june 1979 */
98:
99: floatover() {
100: printf("\t\nerror -- floating point exception\n");
101: signal(8,floatover);
102: reset();
103: };
104:
105:
106:
107: setterm(toggle)
108: { TERMtype = toggle;
109: aplmod(toggle + 1);
110: }
111:
112:
113: nargs()
114: {
115: return 1;
116: }
117:
118: Reset()
119: {
120: afree(stack);
121: cs_size = STKS;
122: stack = alloc(sizeof(sp)*STKS); /* Set up internal stack */
123: sp = stack;
124: staktop = &stack[STKS-1];
125: }
126:
127: intr()
128: {
129:
130: intflg = 1;
131: signal(2, intr);
132: lseek(0, 0, 2);
133: }
134:
135: rline(s)
136: {
137: int rlcmp();
138: char line[CANBS];
139: register char *p;
140: register c, col;
141: char *cp;
142: char *dp;
143: short i;
144: int j;
145:
146: column = 0;
147: col = s;
148: p = line;
149: loop:
150: c = agetchar();
151: if(intflg)
152: error("I");
153: switch(c) {
154:
155: case '\0':
156: case -1:
157: return(0);
158:
159: case '\b':
160: if(col)
161: col--;
162: goto loop;
163:
164: case '\t':
165: col = (col+8) & ~7;
166: goto loop;
167:
168: case ' ':
169: case 016: /* cursor right */
170: col++;
171: goto loop;
172:
173: case '\r':
174: col = 0;
175: goto loop;
176:
177: default:
178: *p++ = col;
179: *p++ = c & 0177;
180: col++;
181: goto loop;
182:
183: case 033: /* escape - APL line feed */
184: for(cp=dp=line; cp<p; cp+= 2)
185: if(*cp < col) {
186: *dp++ = *cp;
187: *dp++ = cp[1];
188: }
189: p = dp;
190: aputchar('\n');
191: putto(col);
192: aputchar(')');
193: aputchar('\n');
194: putto(col);
195: column=0;
196: goto loop;
197:
198: case '\n':
199: ;
200: }
201: qsort(line, (p-line)/2, 2, rlcmp);
202: c = p[-2];
203: if(p == line)
204: c = 1; /* check for blank line */
205: *p = -1;
206: c = alloc((int)(c+3));
207: col = -1;
208: cp = c - 1;
209: for(p=line; p[0] != -1; p+=2) {
210: while(++col != p[0])
211: *++cp = ' ';
212: *++cp = p[1];
213: while(p[2] == col) {
214: if(p[3] != *cp) {
215: i = *cp ;
216: *cp = p[3];
217: break;
218: }
219: p += 2;
220: }
221: if(p[2] != col) continue;
222: while(p[2] == col) {
223: if(p[3] != *cp)
224: goto yuck;
225: p += 2;
226: }
227: i |= *cp << 8;
228: for (j=41;j>=0;j--)
229: if ((i.c[0] == chartab[j].a1) && ( i.c[1]==chartab[j].a2)) {
230: *cp = j | 0200;
231: j = 0;
232: break;
233: }
234: if(j) {
235: yuck:
236: *cp = '\n';
237: pline(c,++col);
238: error("Y E");
239: }
240: }
241: *++cp = '\n';
242: return(c);
243: }
244:
245: rlcmp(a, b)
246: char *a, *b;
247: {
248: register c;
249:
250: if(c = a[0] - b[0])
251: return(c);
252: return(a[1] - b[1]);
253: }
254:
255: pline(str, loc)
256: char *str;
257: {
258: register c, l, col;
259:
260: col = 0;
261: l = 0;
262: do {
263: c = *str++;
264: l++;
265: if(l == loc)
266: col = column;
267: aputchar(c);
268: } while(c != '\n');
269: if(col) {
270: putto(col);
271: if (TERMtype == 0)aputchar(')');
272: else aputchar('^');
273: aputchar('\n');
274: }
275: }
276:
277: putto(col)
278: {
279: while(col > column+8)
280: aputchar('\t');
281: while(col > column)
282: aputchar(' ');
283: }
284:
285: term()
286: {
287:
288: unlink("apl_ws");
289: aputchar('\n');
290: aplmod(0); /*turn off APL mode */
291: exit(0);
292: }
293:
294: fix(d)
295: data d;
296: {
297: register i;
298:
299: i = floor(d+0.5);
300: return(i);
301: }
302:
303: xeq_mark()
304: {
305: if(now_xeq.name) {
306: aprintf(now_xeq.name);
307: aprintf(" ;%d'\n", now_xeq.line);
308: }
309: now_xeq.name = now_xeq.line = 0;
310: }
311:
312: error(s)
313: char *s;
314: {
315: register c;
316: register char *cp;
317:
318: intflg = 0;
319: if(ifile)
320: close(ifile);
321: if(ofile&&ofile!=1)
322: close(ofile);
323: ifile = 0;
324: ofile = 1;
325: xeq_mark();
326: cp = s;
327: while(c = *cp++) {
328: if(c >= 'A' && c <= 'Z') {
329: switch(c) {
330:
331: case 'L':
332: c = "length";
333: break;
334: case 'I':
335: c = "\ninterrupt";
336: break;
337:
338: case 'C':
339: c = "conformability";
340: break;
341:
342: case 'S':
343: c = "syntax";
344: break;
345:
346: case 'R':
347: c = "rank";
348: break;
349:
350: case 'X':
351: c = "index";
352: break;
353:
354: case 'Y':
355: c = "character";
356: break;
357:
358: case 'M':
359: c = "memory";
360: break;
361:
362: case 'D':
363: c = "domain";
364: break;
365:
366: case 'T':
367: c = "type";
368: break;
369:
370: case 'E':
371: c = "error";
372: break;
373:
374: case 'B':
375: default:
376: c = "botch";
377: }
378: aprintf(c);
379: continue;
380: }
381: aputchar(c);
382: }
383: aputchar('\n');
384: reset();
385: };
386:
387: /* procedure to catch control d and prevent it from logging out the user*/
388:
389: ctrld(){
390: aprintf("\nto exit type \"off\nto exit and save workspace type \"continue\n");
391: reset();
392: }
393:
394: aprintf(f, a)
395: char *f;
396: {
397: register char *s;
398: register *p;
399:
400: s = f;
401: p = &a;
402: while(*s) {
403: if(s[0] == '%' && s[1] == 'd') {
404: putn(*p++);
405: s += 2;
406: continue;
407: }
408: aputchar(*s++);
409: }
410: }
411:
412: putn(n)
413: {
414: register a;
415:
416: if(n < 0) {
417: n = -n;
418: if(n < 0) {
419: aprintf("2147483648");
420: return;
421: }
422: aputchar('@'); /* apl minus sign */
423: }
424: if(a=n/10)
425: putn(a);
426: aputchar(n%10 + '0');
427: }
428: agetchar()
429: {
430: int c;
431:
432: c = 0;
433: read(ifile, &c, 1);
434: if(echoflg)
435: write(1, &c, 1);
436: return(c);
437: }
438:
439: aputchar(c)
440: register c;
441: {
442: register i;
443: unsigned char c2;
444: extern unsigned char changeoutput[];
445:
446: if(TERMtype == 1) /* ascii terminal */
447: c = changeoutput [ (0377 & c) ];
448:
449:
450: switch(c) {
451:
452: case '\0':
453: return;
454:
455: case '\b':
456: if(column)
457: column--;
458: break;
459:
460: case '\t':
461: column = (column+8) & ~7;
462: break;
463:
464: case '\r':
465: case '\n':
466: column = 0;
467: break;
468:
469: default:
470: column++;
471: }
472: /* for encode numbers */
473: if(mencflg) {
474: if(c != '\n') {
475: mencflg = 1;
476: *mencptr++ = c;
477: }
478: else
479: if(mencflg > 1)
480: mencptr += rowsz;
481: else
482: mencflg = 2;
483: return;
484: }
485: if(intflg == 0) {
486: if(c & 0200) {
487: i = chartab[c & 0177];
488: aputchar(i>>8);
489: c = i & 0177;
490: aputchar('\b');
491: }
492: c2 = c;
493: write(ofile, &c2, 1);
494: }
495: }
496:
497: fuzz(d1, d2)
498: data d1, d2;
499: {
500: double f1, f2;
501:
502: f1 = d1;
503: if(f1 < 0.)
504: f1 = -f1;
505: f2 = d2;
506: if(f2 < 0.)
507: f2 = -f2;
508: if(f2 > f1)
509: f1 = f2;
510: f1 *= thread.fuzz;
511: if(d1 > d2) {
512: if(d2+f1 >= d1)
513: return(0);
514: return(1);
515: }
516: if(d1+f1 >= d2)
517: return(0);
518: return(-1);
519: }
520:
521: pop()
522: {
523: dealloc(*--sp);
524: }
525:
526: erase(np)
527: struct nlist *np;
528: {
529: register *p;
530:
531: p = np->itemp;
532: if(p) {
533: switch(np->use) {
534: case NF:
535: case MF:
536: case DF:
537: for(; *p>0; (*p)--)
538: afree(p[*p]);
539:
540: }
541: afree(p);
542: np->itemp = 0;
543: }
544: np->use = 0;
545: }
546:
547: dealloc(p)
548: struct item *p;
549: {
550:
551: switch(p->type) {
552:
553: case DA:
554: case CH:
555: case QQ:
556: case QD:
557: case QC:
558: case EL:
559: afree(p);
560: }
561: }
562:
563: newdat(type, rank, size)
564: {
565: register i;
566: register struct item *p;
567:
568: if(rank > MRANK)
569: error("R E");
570: i = sizeof *p + rank * SINT;
571: if(type == DA)
572: i += size * SDAT; else
573: if(type == CH)
574: i += size;
575: p = alloc(i);
576: p->rank = rank;
577: p->type = type;
578: p->size = size;
579: p->index = 0;
580: if(rank == 1)
581: p->dim[0] = size;
582: p->datap = &p->dim[rank];
583: return(p);
584: }
585:
586: copy(type, from, to, size)
587: char *from, *to;
588: {
589: register i;
590: register char *a, *b;
591: int s;
592:
593:
594:
595: if((i = size) == 0)
596: return(0);
597: a = from;
598: b = to;
599: if(type == DA)
600: i *= SDAT; else
601: if(type == IN)
602: i *= SINT;
603: s = i;
604: do
605: *b++ = *a++;
606: while(--i);
607: return(s);
608: }
609:
610: fetch1()
611: {
612: return sp[-1] = fetch(sp[-1]);
613: }
614:
615: fetch2()
616: {
617: sp[-2] = fetch(sp[-2]);
618: return sp[-1] = fetch(sp[-1]);
619: }
620:
621: fetch(ip)
622: struct item *ip;
623: {
624: register struct item *p, *q;
625: char *ubset;
626: register i;
627: int c;
628:
629: p = ip;
630:
631: loop:
632: switch(p->type) {
633:
634: case QQ:
635: afree(p);
636: c = rline(0);
637: if(c == 0)
638: error("eof");
639: for(i=0; c->c[i] != '\n'; i++)
640: continue;
641: p = newdat(CH, 1, i);
642: copy(CH, c, p->datap, i);
643: goto loop;
644:
645: case QD:
646: case QC:
647: if(!ifile&&ofile==1)
648: aprintf("L>\n\t");
649: i = rline(8);
650: if(i == 0)
651: error("eof");
652: c = compile(i, 1);
653: afree(i);
654: if(c == 0)
655: goto loop;
656: i = pcp;
657: execute(c);
658: pcp = i;
659: afree(c);
660: afree(p);
661: p = *--sp;
662: goto loop;
663:
664: case DA:
665: case CH:
666: p->index = 0;
667: return(p);
668:
669: case LV:
670: if(p->use != DA) {
671: ubset = ip->namep;
672: xeq_mark();
673: while(*ubset)
674: aputchar(*ubset++);
675: error("> used before set\n");
676: }
677: p = p->itemp;
678: q = newdat(p->type, p->rank, p->size);
679: copy(IN, p->dim, q->dim, p->rank);
680: copy(p->type, p->datap, q->datap, p->size);
681: return(q);
682:
683: default:
684: error("fetch B");
685: }
686: }
687:
688: topfix()
689: {
690: register struct item *p;
691: register i;
692:
693: p = fetch1();
694: if(p->type != DA || p->size != 1)
695: error("topval C");
696: i = fix(p->datap[0]);
697: pop();
698: return(i);
699: }
700:
701: bidx(ip)
702: struct item *ip;
703: {
704: register struct item *p;
705:
706: p = ip;
707: idx.type = p->type;
708: idx.rank = p->rank;
709: copy(IN, p->dim, idx.dim, idx.rank);
710: size();
711: }
712:
713: size()
714: {
715: register i, s;
716:
717: s = 1;
718: for(i=idx.rank-1; i>=0; i--) {
719: idx.del[i] = s;
720: s *= idx.dim[i];
721: }
722: idx.size = s;
723: return(s);
724: }
725:
726: colapse(k)
727: {
728: register i;
729:
730: if(k < 0 || k >= idx.rank)
731: error("collapse X");
732: idx.dimk = idx.dim[k];
733: idx.delk = idx.del[k];
734: for(i=k; i<idx.rank; i++) {
735: idx.del[i] = idx.del[i+1];
736: idx.dim[i] = idx.dim[i+1];
737: }
738: idx.size /= idx.dimk;
739: idx.rank--;
740: }
741:
742: forloop(co, arg)
743: int (*co)();
744: {
745: register i;
746:
747: if(idx.rank == 0) {
748: (*co)(arg);
749: return;
750: }
751: for(i=0;;) {
752: while(i < idx.rank)
753: idx.idx[i++] = 0;
754: (*co)(arg);
755: while(++idx.idx[i-1] >= idx.dim[i-1])
756: if(--i <= 0)
757: return;
758: }
759: }
760:
761: access()
762: {
763: register i, n;
764:
765: n = 0;
766: for(i=0; i<idx.rank; i++)
767: n += idx.idx[i] * idx.del[i];
768: return(n);
769: }
770:
771: data
772: getdat(ip)
773: struct item *ip;
774: {
775: register struct item *p;
776: register i;
777: data d;
778:
779: p = ip;
780: i = p->index;
781: while(i >= p->size) {
782: if(i == 0)
783: error("getdat B");
784: i -= p->size;
785: }
786: if(p->type == DA) {
787: d = p->datap[i];
788: } else
789: if(p->type == CH) {
790: d = p->datap->c[i];
791: } else
792: error("getdat B");
793: i++;
794: p->index = i;
795: return(d);
796: }
797:
798: putdat(ip, d)
799: data d;
800: struct item *ip;
801: {
802: register struct item *p;
803: register i;
804:
805: p = ip;
806: i = p->index;
807: if(i >= p->size)
808: error("putdat B");
809: if(p->type == DA) {
810: p->datap[i] = d;
811: } else
812: if(p->type == CH) {
813: p->datap->c[i] = d;
814: } else
815: error("putdat B");
816: i++;
817: p->index = i;
818: }
819:
820: aplmod(xyz)
821: {
822: static firstvisit=0;
823: static short old[3], new[3];
824: static short diff;
825: if(xyz> 0) {
826: if (firstvisit == 0){
827: if(gtty(0,old)<0) {
828: diff = 0;
829: return;
830: }
831: diff = 1;
832: }
833: if (diff == 1) {
834: gtty(0, new);
835: if (xyz == 1)new[1] = 'W'|'A'<<8; /* apl terminal */
836: else new[1] = ''|'@'<<8; /* ascii terminal */
837: stty(0, new);
838: if (firstvisit)
839: if (xyz == 1)aprintf("erase%KWK kill%KAK\n\n");
840: else aprintf("erase ^H kill @\n\n");
841: }
842: firstvisit++;
843: } else {
844: if(diff)
845: stty(0, old);
846: }
847: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.