static char Sccsid[] = "a4.c @(#)a4.c 1.2 10/5/82 Berkeley "; #include "apl.h" /* * parser generates the following for each label * * AUTO-name CONST NAME-name LABEL * * (where CONST is the label address) */ ex_label() { register struct nlist *n; ex_asgn(); n = (struct nlist *)sp[-1]; n->itemp->type = LBL; /* lock out assignments */ sp--; /* discard stack */ } ex_asgn() { register struct nlist *p; register 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(); return; case QQ: pop(); epr0(); /* print w/out '\n' (in a2.c) */ return; case LV: /* The following line checks that it is not the first assignment * to the local variable, in which case itemp has not be set yet * This used to produce an interesting bug when adress 1 was * holding the manifest constant LBL ... just by chance ! */ if (((struct nlist *)p)->itemp != 0) { if(((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() { register struct item *p; struct item *q; register i, j; int 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; itype == EL) { idx.dim[idx.rank++] = q->dim[i]; continue; } p = fetch(p); sp[-i-2] = p; for(j=0; jrank; 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= 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; jindex = 0; for(j=0; jsize; 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); } }