home *** CD-ROM | disk | FTP | other *** search
- #include "apl.h"
-
- /*
- * parser generates the following for each label
- *
- * AUTO-name CONST NAME-name LABEL
- *
- * (where CONST is the label address)
- */
-
- ex_label()
- {
- struct nlist *n;
-
- ex_asgn();
- n = (struct nlist *)sp[-1];
- n->itemp->type = LBL; /* lock out assignments */
- sp--; /* discard stack */
- }
-
-
- ex_asgn()
- {
- struct nlist *p;
- struct item *q;
-
- p = (struct nlist *)sp[-1];
- switch(p->type){
- case QX:
- pop();
- p = nlook("Llx");
- if(p == 0){
- /*
- * allocate new name:
- */
- for(p=nlist; p->namep; p++) ;
- p->namep = alloc(4);
- copy(CH, "Llx", p->namep, 4);
- p->type = LV;
- p->use = 0;
- p->itemp = newdat(CH, 0, 0);
- }
- sp++; /* reset stack */
- break;
- case QD:
- pop();
- ex_print();
- return;
- case QC:
- pop();
- /* ex_plot(); */ /* don't understand QC data yet -- MEC */
- return;
- case QQ:
- pop();
- epr0(); /* print w/out '\n' (in a2.c) */
- return;
- case LV:
- if (((struct nlist *)p->itemp) && ((struct nlist *)p)->itemp->type == LBL) error("asgn to label");
- break;
- default:
- error("asgn lv");
- }
- if(p->use != 0 && p->use != DA) error("asgn var");
- sp--;
- q = fetch1();
- erase(p);
- p->use = DA;
- ((struct nlist *)p)->itemp = q;
- sp[-1] = (struct item *)p;
- }
-
- ex_elid()
- {
- *sp++ = newdat(EL, 0, 0);
- }
-
- ex_index()
- {
- struct item *p, *q;
- int i, j, f, n, lv;
-
- n = *pcp++;
- f = *pcp;
- p = sp[-1];
- if(f == ASGN) {
- pcp++;
- if(p->type != LV) error("indexed assign value");
- if(((struct nlist *)p)->use != DA) fetch1(); /* error("used before set"); */
- q = ((struct nlist *)p)->itemp;
- }
- else q = fetch1();
- if(q->rank != n) error("subscript C");
- idx.rank = 0;
- for(i=0; i<n; i++) {
- p = sp[-i-2];
- if(p->type == EL) {
- idx.dim[idx.rank++] = q->dim[i];
- continue;
- }
- p = fetch(p);
- sp[-i-2] = p;
- for(j=0; j<p->rank; j++) idx.dim[idx.rank++] = p->dim[j];
- }
- size();
- if(f == ASGN) {
- p = fetch(sp[-n-2]);
- sp[-n-2] = p;
- if (p->size > 1) {
- if(idx.size != p->size) error("assign C");
- f = 1; /* v[i] <- v */
- }
- else {
- if (idx.size && !p->size) error("assign C");
- /* Note -- for idx.size = 0, no assign occurs
- * anyway, so it is safe to set "datum" to 0
- */
- datum = p->size ? getdat(p) : 0;
- f = 2; /* v[i] <- s */
- }
- ex_elid();
- }
- else {
- p = newdat(q->type, idx.rank, idx.size);
- copy(IN, idx.dim, p->dim, idx.rank);
- *sp++ = p;
- f = 0; /* v[i] */
- }
- bidx(q);
- index1(0, f);
- if(f == 0) {
- p = sp[-1];
- sp--;
- for(i=0; i<=n; i++) pop();
- *sp++ = p;
- }
- else {
- pop(); /* pop ELID */
- sp--; /* skip over LV */
- for(i=0; i<n; i++) pop();
- }
- }
-
- index1(i, f)
- {
- struct item *p;
- int j, k;
-
- if(i >= idx.rank) {
- switch(f) {
-
- case 0:
- p = sp[-2];
- p->index = access();
- putdat(sp[-1], getdat(p));
- return;
-
- case 1:
- datum = getdat(sp[-idx.rank-3]);
-
- case 2:
- p = ((struct nlist *)sp[-2])->itemp;
- p->index = access();
- putdat(p, datum);
- return;
- }
- }
- p = sp[-i-3];
- if(p->type == EL) {
- for(j=0; j<idx.dim[i]; j++) {
- idx.idx[i] = j;
- index1(i+1, f);
- }
- return;
- }
- p->index = 0;
- for(j=0; j<p->size; j++) {
- k = fix(getdat(p)) - thread.iorg;
- if(k < 0 || k >= idx.dim[i]) error("subscript X");
- idx.idx[i] = k;
- index1(i+1, f);
- }
- }
-