home *** CD-ROM | disk | FTP | other *** search
- #include "apl.h"
-
- ex_take()
- {
- int takezr();
- int i, k, o, fill[MRANK], fflg;
-
- /* While TANSTAAFL, in APL there is a close approximation. It
- * is possible to perform a "take" of more elements than an
- * array actually contains (to be padded with zeros or blanks).
- * If "td1()" detects that a dimension exceeds what the array
- * actually contains it will return 1. Special code is then
- * required to force the extra elements in the new array to
- * zero or blank. This code is supposed to work for null items
- * also, but it doesn't.
- */
-
- o = 0;
- fflg = td1(0);
- for(i=0; i<idx.rank; i++) {
- fill[i] = 0;
- k = idx.idx[i];
- if(k < 0) {
- k = -k;
- if (k > idx.dim[i]) fill[i] = idx.dim[i] - k;
- o += idx.del[i] * (idx.dim[i] - k);
- }
- else {
- if (k > idx.dim[i]) fill[i] = idx.dim[i];
- }
- idx.dim[i] = k;
- }
- map(o);
-
- if (fflg){
- bidx(sp[-1]);
- forloop(takezr, fill);
- }
- }
-
- ex_drop()
- {
- int i, k, o;
-
- o = 0;
- td1(1);
- for(i=0; i<idx.rank; i++) {
- k = idx.idx[i];
- if(k > 0) o += idx.del[i] * k;
- else k = -k;
- idx.dim[i] -= k;
- }
- map(o);
- }
-
- td1(tdmode)
- {
- struct item *p, *q, *nq, *s2vect();
- int i, k;
- int r; /* set to 1 if take > array dim */
-
- p = fetch2();
- q = sp[-2];
- r = !q->size; /* Weird stuff for null items */
- if (q->rank == 0){ /* Extend scalars */
- nq = newdat(q->type, p->size, 1);
- *nq->datap = *q->datap;
- pop();
- *sp++ = q = nq;
- for(i=0; i<p->size; i++) q->dim[i] = 1;
- }
- if(p->rank > 1 || q->rank != p->size) error("take/drop C");
- bidx(q);
- for(i=0; i<p->size; i++) {
- k = fix(getdat(p));
- idx.idx[i] = k;
- if(k < 0) k = -k;
-
- /* If an attempt is made to drop more than what
- * exists, modify the drop to drop exactly what
- * exists.
- */
-
- if(k > idx.dim[i]) {
- if (tdmode) idx.idx[i] = idx.dim[i];
- else r = 1;
- }
- }
- pop();
- return(r);
- }
-
- ex_dtrn()
- {
- struct item *p, *q;
- int i;
-
- p = fetch2();
- q = sp[-2];
- if(p->rank > 1 || p->size != q->rank) error("tranpose C");
- for(i=0; i<p->size; i++) idx.idx[i] = fix(getdat(p)) - thread.iorg;
- pop();
- trn0();
- }
-
- ex_mtrn()
- {
- struct item *p;
- int i;
-
- p = fetch1();
- if(p->rank <= 1) return;
- for(i=0; i<p->rank; i++) idx.idx[i] = p->rank-1-i;
- trn0();
- }
-
- trn0()
- {
- int i, j;
- int d[MRANK], r[MRANK];
-
- bidx(sp[-1]);
- for(i=0; i<idx.rank; i++) d[i] = -1;
- for(i=0; i<idx.rank; i++) {
- j = idx.idx[i];
- if(j<0 || j>=idx.rank) error("tranpose X");
- if(d[j] != -1) {
- if(idx.dim[i] < d[j]) d[j] = idx.dim[i];
- r[j] += idx.del[i];
- }
- else {
- d[j] = idx.dim[i];
- r[j] = idx.del[i];
- }
- }
- j = idx.rank;
- for(i=0; i<idx.rank; i++) {
- if(d[i] != -1) {
- if(i > j) error("tranpose D");
- idx.dim[i] = d[i];
- idx.del[i] = r[i];
- }
- else if(i < j) j = i;
- }
- idx.rank = j;
- map(0);
- }
-
- ex_rev0()
- {
- fetch1();
- revk(0);
- }
-
- ex_revk()
- {
- int k;
-
- k = topfix() - thread.iorg;
- fetch1();
- revk(k);
- }
-
- ex_rev()
- {
- struct item *p;
-
- p = fetch1();
- revk(p->rank-1);
- }
-
- revk(k)
- {
- int o;
-
- bidx(sp[-1]);
- if(k < 0 || k >= idx.rank) error("reverse X");
- o = idx.del[k] * (idx.dim[k]-1);
- idx.del[k] = -idx.del[k];
- map(o);
- }
-
- map(o)
- {
- struct item *p;
- int n, i;
- int map1();
-
- n = 1;
- for(i=0; i<idx.rank; i++) n *= idx.dim[i];
- if(n == 0) idx.rank == 0;
- p = newdat(idx.type, idx.rank, n);
- copy(IN, idx.dim, p->dim, idx.rank);
- *sp++ = p;
- if(n != 0) forloop(map1, o);
- sp--;
- pop();
- *sp++ = p;
- }
-
- map1(o)
- {
- struct item *p;
-
- p = sp[-2];
- p->index = access() + o;
- putdat(sp[-1], getdat(p));
- }
-
- takezr(fill)
- int *fill;
- {
- struct item *p;
- int i;
-
- /* Zero appropriate elements of an array created by taking
- * more than you originally had. I apologize for the "dirty"
- * argument passing (passing a pointer to an integer array
- * through "forloop()" which treats it as an integer) and for
- * the general dumbness of this code.
- * --John Bruner
- */
-
- for(i=0; i<idx.rank; i++) {
- if (fill[i] > 0 && idx.idx[i] >= fill[i] || fill[i] < 0 && idx.idx[i] < -fill[i]){
- p = sp[-1];
- p->index = access();
- putdat(p, (p->type==DA) ? zero : (data)' ');
- return;
- }
- }
- }
-