|
|
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 ^U\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.