home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 13 / MA_Cover_13.bin / source / c / apl / ab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-23  |  3.9 KB  |  233 lines

  1. #include "apl.h"
  2.  
  3. ex_take()
  4. {
  5.     int takezr();
  6.     int i, k, o, fill[MRANK], fflg;
  7.  
  8.     /* While TANSTAAFL, in APL there is a close approximation.  It
  9.      * is possible to perform a "take" of more elements than an
  10.      * array actually contains (to be padded with zeros or blanks).
  11.      * If "td1()" detects that a dimension exceeds what the array
  12.      * actually contains it will return 1.  Special code is then
  13.      * required to force the extra elements in the new array to
  14.      * zero or blank.  This code is supposed to work for null items
  15.      * also, but it doesn't.
  16.      */
  17.  
  18.     o = 0;
  19.     fflg = td1(0);
  20.     for(i=0; i<idx.rank; i++) {
  21.         fill[i] = 0;
  22.         k = idx.idx[i];
  23.         if(k < 0) {
  24.             k = -k;
  25.             if (k > idx.dim[i]) fill[i] = idx.dim[i] - k;
  26.             o += idx.del[i] * (idx.dim[i] - k);
  27.         }
  28.         else {
  29.             if (k > idx.dim[i]) fill[i] = idx.dim[i];
  30.         }
  31.         idx.dim[i] = k;
  32.     }
  33.     map(o);
  34.  
  35.     if (fflg){
  36.         bidx(sp[-1]);
  37.         forloop(takezr, fill);
  38.     }
  39. }
  40.  
  41. ex_drop()
  42. {
  43.     int i, k, o;
  44.  
  45.     o = 0;
  46.     td1(1);
  47.     for(i=0; i<idx.rank; i++) {
  48.         k = idx.idx[i];
  49.         if(k > 0) o += idx.del[i] * k;
  50.         else k = -k;
  51.         idx.dim[i] -= k;
  52.     }
  53.     map(o);
  54. }
  55.  
  56. td1(tdmode)
  57. {
  58.     struct item *p, *q, *nq, *s2vect();
  59.     int i, k;
  60.     int r;                    /* set to 1 if take > array dim */
  61.  
  62.     p = fetch2();
  63.     q = sp[-2];
  64.     r = !q->size;            /* Weird stuff for null items */
  65.     if (q->rank == 0){        /* Extend scalars */
  66.         nq = newdat(q->type, p->size, 1);
  67.         *nq->datap = *q->datap;
  68.         pop();
  69.         *sp++ = q = nq;
  70.         for(i=0; i<p->size; i++) q->dim[i] = 1;
  71.     }
  72.     if(p->rank > 1 || q->rank !=  p->size) error("take/drop C");
  73.     bidx(q);
  74.     for(i=0; i<p->size; i++) {
  75.         k = fix(getdat(p));
  76.         idx.idx[i] = k;
  77.         if(k < 0) k = -k;
  78.  
  79.         /* If an attempt is made to drop more than what
  80.          * exists, modify the drop to drop exactly what
  81.          * exists.
  82.          */
  83.  
  84.         if(k > idx.dim[i]) {
  85.             if (tdmode) idx.idx[i] = idx.dim[i];
  86.             else r = 1;
  87.         }
  88.     }
  89.     pop();
  90.     return(r);
  91. }
  92.  
  93. ex_dtrn()
  94. {
  95.     struct item *p, *q;
  96.     int i;
  97.  
  98.     p = fetch2();
  99.     q = sp[-2];
  100.     if(p->rank > 1 || p->size != q->rank) error("tranpose C");
  101.     for(i=0; i<p->size; i++) idx.idx[i] = fix(getdat(p)) - thread.iorg;
  102.     pop();
  103.     trn0();
  104. }
  105.  
  106. ex_mtrn()
  107. {
  108.     struct item *p;
  109.     int i;
  110.  
  111.     p = fetch1();
  112.     if(p->rank <= 1) return;
  113.     for(i=0; i<p->rank; i++) idx.idx[i] = p->rank-1-i;
  114.     trn0();
  115. }
  116.  
  117. trn0()
  118. {
  119.     int i, j;
  120.     int d[MRANK], r[MRANK];
  121.  
  122.     bidx(sp[-1]);
  123.     for(i=0; i<idx.rank; i++) d[i] = -1;
  124.     for(i=0; i<idx.rank; i++) {
  125.         j = idx.idx[i];
  126.         if(j<0 || j>=idx.rank) error("tranpose X");
  127.         if(d[j] != -1) {
  128.             if(idx.dim[i] < d[j]) d[j] = idx.dim[i];
  129.             r[j] += idx.del[i];
  130.         }
  131.         else {
  132.             d[j] = idx.dim[i];
  133.             r[j] = idx.del[i];
  134.         }
  135.     }
  136.     j = idx.rank;
  137.     for(i=0; i<idx.rank; i++) {
  138.         if(d[i] != -1) {
  139.             if(i > j) error("tranpose D");
  140.             idx.dim[i] = d[i];
  141.             idx.del[i] = r[i];
  142.         }
  143.         else if(i < j) j = i;
  144.     }
  145.     idx.rank = j;
  146.     map(0);
  147. }
  148.  
  149. ex_rev0()
  150. {
  151.     fetch1();
  152.     revk(0);
  153. }
  154.  
  155. ex_revk()
  156. {
  157.     int k;
  158.  
  159.     k = topfix() - thread.iorg;
  160.     fetch1();
  161.     revk(k);
  162. }
  163.  
  164. ex_rev()
  165. {
  166.     struct item *p;
  167.  
  168.     p = fetch1();
  169.     revk(p->rank-1);
  170. }
  171.  
  172. revk(k)
  173. {
  174.     int o;
  175.  
  176.     bidx(sp[-1]);
  177.     if(k < 0 || k >= idx.rank) error("reverse X");
  178.     o = idx.del[k] * (idx.dim[k]-1);
  179.     idx.del[k] = -idx.del[k];
  180.     map(o);
  181. }
  182.  
  183. map(o)
  184. {
  185.     struct item *p;
  186.     int n, i;
  187.     int map1();
  188.  
  189.     n = 1;
  190.     for(i=0; i<idx.rank; i++) n *= idx.dim[i];
  191.     if(n == 0) idx.rank == 0;
  192.     p = newdat(idx.type, idx.rank, n);
  193.     copy(IN, idx.dim, p->dim, idx.rank);
  194.     *sp++ = p;
  195.     if(n != 0) forloop(map1, o);
  196.     sp--;
  197.     pop();
  198.     *sp++ = p;
  199. }
  200.  
  201. map1(o)
  202. {
  203.     struct item *p;
  204.  
  205.     p = sp[-2];
  206.     p->index = access() + o;
  207.     putdat(sp[-1], getdat(p));
  208. }
  209.  
  210. takezr(fill)
  211. int *fill;
  212. {
  213.     struct item *p;
  214.     int i;
  215.  
  216.     /* Zero appropriate elements of an array created by taking
  217.      * more than you originally had.  I apologize for the "dirty"
  218.      * argument passing (passing a pointer to an integer array
  219.      * through "forloop()" which treats it as an integer) and for
  220.      * the general dumbness of this code.
  221.      *                    --John Bruner
  222.      */
  223.  
  224.     for(i=0; i<idx.rank; i++) {
  225.         if (fill[i] > 0 && idx.idx[i] >= fill[i] || fill[i] < 0 && idx.idx[i] < -fill[i]){
  226.             p = sp[-1];
  227.             p->index = access();
  228.             putdat(p, (p->type==DA) ? zero : (data)' ');
  229.             return;
  230.         }
  231.     }
  232. }
  233.