|
|
1.1 ! root 1: #include "defs" ! 2: ! 3: LOCAL int exar2(), popctl(), pushctl(); ! 4: ! 5: /* Logical IF codes ! 6: */ ! 7: ! 8: ! 9: exif(p) ! 10: expptr p; ! 11: { ! 12: pushctl(CTLIF); ! 13: ctlstack->elselabel = newlabel(); ! 14: putif(p, ctlstack->elselabel); ! 15: } ! 16: ! 17: ! 18: ! 19: exelif(p) ! 20: expptr p; ! 21: { ! 22: if(ctlstack->ctltype == CTLIF) ! 23: { ! 24: if(ctlstack->endlabel == 0) ! 25: ctlstack->endlabel = newlabel(); ! 26: putgoto(ctlstack->endlabel); ! 27: putlabel(ctlstack->elselabel); ! 28: ctlstack->elselabel = newlabel(); ! 29: putif(p, ctlstack->elselabel); ! 30: } ! 31: ! 32: else execerr("elseif out of place", CNULL); ! 33: } ! 34: ! 35: ! 36: ! 37: ! 38: ! 39: exelse() ! 40: { ! 41: if(ctlstack->ctltype==CTLIF) ! 42: { ! 43: if(ctlstack->endlabel == 0) ! 44: ctlstack->endlabel = newlabel(); ! 45: putgoto( ctlstack->endlabel ); ! 46: putlabel(ctlstack->elselabel); ! 47: ctlstack->ctltype = CTLELSE; ! 48: } ! 49: ! 50: else execerr("else out of place", CNULL); ! 51: } ! 52: ! 53: ! 54: exendif() ! 55: { ! 56: if(ctlstack->ctltype == CTLIF) ! 57: { ! 58: putlabel(ctlstack->elselabel); ! 59: if(ctlstack->endlabel) ! 60: putlabel(ctlstack->endlabel); ! 61: popctl(); ! 62: } ! 63: else if(ctlstack->ctltype == CTLELSE) ! 64: { ! 65: putlabel(ctlstack->endlabel); ! 66: popctl(); ! 67: } ! 68: ! 69: else ! 70: execerr("endif out of place", CNULL); ! 71: } ! 72: ! 73: ! 74: ! 75: LOCAL pushctl(code) ! 76: int code; ! 77: { ! 78: register int i; ! 79: ! 80: if(++ctlstack >= lastctl) ! 81: many("loops or if-then-elses", 'c', maxctl); ! 82: ctlstack->ctltype = code; ! 83: for(i = 0 ; i < 4 ; ++i) ! 84: ctlstack->ctlabels[i] = 0; ! 85: ++blklevel; ! 86: } ! 87: ! 88: ! 89: LOCAL popctl() ! 90: { ! 91: if( ctlstack-- < ctls ) ! 92: fatal("control stack empty"); ! 93: --blklevel; ! 94: } ! 95: ! 96: ! 97: ! 98: LOCAL poplab() ! 99: { ! 100: register struct Labelblock *lp; ! 101: ! 102: for(lp = labeltab ; lp < highlabtab ; ++lp) ! 103: if(lp->labdefined) ! 104: { ! 105: /* mark all labels in inner blocks unreachable */ ! 106: if(lp->blklevel > blklevel) ! 107: lp->labinacc = YES; ! 108: } ! 109: else if(lp->blklevel > blklevel) ! 110: { ! 111: /* move all labels referred to in inner blocks out a level */ ! 112: lp->blklevel = blklevel; ! 113: } ! 114: } ! 115: ! 116: ! 117: ! 118: /* BRANCHING CODE ! 119: */ ! 120: ! 121: exgoto(lab) ! 122: struct Labelblock *lab; ! 123: { ! 124: putgoto(lab->labelno); ! 125: } ! 126: ! 127: ! 128: ! 129: ! 130: ! 131: ! 132: ! 133: exequals(lp, rp) ! 134: register struct Primblock *lp; ! 135: register expptr rp; ! 136: { ! 137: if(lp->tag != TPRIM) ! 138: { ! 139: err("assignment to a non-variable"); ! 140: frexpr(lp); ! 141: frexpr(rp); ! 142: } ! 143: else if(lp->namep->vclass!=CLVAR && lp->argsp) ! 144: { ! 145: if(parstate >= INEXEC) ! 146: err("statement function amid executables"); ! 147: else ! 148: mkstfunct(lp, rp); ! 149: } ! 150: else ! 151: { ! 152: if(parstate < INDATA) ! 153: enddcl(); ! 154: puteq(mklhs(lp), fixtype(rp)); ! 155: } ! 156: } ! 157: ! 158: ! 159: long laststfcn = -1, thisstno; ! 160: ! 161: mkstfunct(lp, rp) ! 162: struct Primblock *lp; ! 163: expptr rp; ! 164: { ! 165: register struct Primblock *p; ! 166: register Namep np; ! 167: chainp args; ! 168: ! 169: laststfcn = thisstno; ! 170: np = lp->namep; ! 171: if(np->vclass == CLUNKNOWN) ! 172: np->vclass = CLPROC; ! 173: else ! 174: { ! 175: dclerr("redeclaration of statement function", np); ! 176: return; ! 177: } ! 178: np->vprocclass = PSTFUNCT; ! 179: np->vstg = STGSTFUNCT; ! 180: impldcl(np); ! 181: args = (lp->argsp ? lp->argsp->listp : CHNULL); ! 182: np->varxptr.vstfdesc = mkchain(args , rp ); ! 183: ! 184: for( ; args ; args = args->nextp) ! 185: if( args->datap->tag!=TPRIM || ! 186: (p = (struct Primblock *) (args->datap) )->argsp || ! 187: p->fcharp || p->lcharp ) ! 188: err("non-variable argument in statement function definition"); ! 189: else ! 190: { ! 191: args->datap = (tagptr) (p->namep); ! 192: vardcl(p->namep); ! 193: free(p); ! 194: } ! 195: } ! 196: ! 197: ! 198: ! 199: excall(name, args, nstars, labels) ! 200: Namep name; ! 201: struct Listblock *args; ! 202: int nstars; ! 203: struct Labelblock *labels[ ]; ! 204: { ! 205: register expptr p; ! 206: ! 207: settype(name, TYSUBR, ENULL); ! 208: p = mkfunct( mkprim(name, args, CHNULL) ); ! 209: p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT; ! 210: if(nstars > 0) ! 211: putcmgo(p, nstars, labels); ! 212: else putexpr(p); ! 213: } ! 214: ! 215: ! 216: ! 217: exstop(stop, p) ! 218: int stop; ! 219: register expptr p; ! 220: { ! 221: char *q; ! 222: int n; ! 223: expptr mkstrcon(); ! 224: ! 225: if(p) ! 226: { ! 227: if( ! ISCONST(p) ) ! 228: { ! 229: execerr("pause/stop argument must be constant", CNULL); ! 230: frexpr(p); ! 231: p = mkstrcon(0, CNULL); ! 232: } ! 233: else if( ISINT(p->constblock.vtype) ) ! 234: { ! 235: q = convic(p->constblock.Const.ci); ! 236: n = strlen(q); ! 237: if(n > 0) ! 238: { ! 239: p->constblock.Const.ccp = copyn(n, q); ! 240: p->constblock.vtype = TYCHAR; ! 241: p->constblock.vleng = (expptr) ICON(n); ! 242: } ! 243: else ! 244: p = (expptr) mkstrcon(0, CNULL); ! 245: } ! 246: else if(p->constblock.vtype != TYCHAR) ! 247: { ! 248: execerr("pause/stop argument must be integer or string", CNULL); ! 249: p = (expptr) mkstrcon(0, CNULL); ! 250: } ! 251: } ! 252: else p = (expptr) mkstrcon(0, CNULL); ! 253: ! 254: putexpr( call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p) ); ! 255: } ! 256: ! 257: /* DO LOOP CODE */ ! 258: ! 259: #define DOINIT par[0] ! 260: #define DOLIMIT par[1] ! 261: #define DOINCR par[2] ! 262: ! 263: #define VARSTEP 0 ! 264: #define POSSTEP 1 ! 265: #define NEGSTEP 2 ! 266: ! 267: ! 268: exdo(range, spec) ! 269: int range; ! 270: chainp spec; ! 271: { ! 272: register expptr p, q; ! 273: expptr q1; ! 274: register Namep np; ! 275: chainp cp; ! 276: register int i; ! 277: int dotype, incsign; ! 278: Addrp dovarp, dostgp; ! 279: expptr par[3]; ! 280: ! 281: pushctl(CTLDO); ! 282: dorange = ctlstack->dolabel = range; ! 283: np = (Namep) (spec->datap); ! 284: ctlstack->donamep = NULL; ! 285: if(np->vdovar) ! 286: { ! 287: errstr("nested loops with variable %s", varstr(VL,np->varname)); ! 288: ctlstack->donamep = NULL; ! 289: return; ! 290: } ! 291: ! 292: dovarp = mkplace(np); ! 293: if( ! ONEOF(dovarp->vtype, MSKINT|MSKREAL) ) ! 294: { ! 295: err("bad type on do variable"); ! 296: return; ! 297: } ! 298: ctlstack->donamep = np; ! 299: ! 300: np->vdovar = YES; ! 301: if( enregister(np) ) ! 302: { ! 303: /* stgp points to a storage version, varp to a register version */ ! 304: dostgp = dovarp; ! 305: dovarp = mkplace(np); ! 306: } ! 307: else ! 308: dostgp = NULL; ! 309: dotype = dovarp->vtype; ! 310: ! 311: for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp) ! 312: { ! 313: p = par[i++] = fixtype(cp->datap); ! 314: if( ! ONEOF(p->headblock.vtype, MSKINT|MSKREAL) ) ! 315: { ! 316: err("bad type on DO parameter"); ! 317: return; ! 318: } ! 319: } ! 320: ! 321: frchain(&spec); ! 322: switch(i) ! 323: { ! 324: case 0: ! 325: case 1: ! 326: err("too few DO parameters"); ! 327: return; ! 328: ! 329: default: ! 330: err("too many DO parameters"); ! 331: return; ! 332: ! 333: case 2: ! 334: DOINCR = (expptr) ICON(1); ! 335: ! 336: case 3: ! 337: break; ! 338: } ! 339: ! 340: ctlstack->endlabel = newlabel(); ! 341: ctlstack->dobodylabel = newlabel(); ! 342: ! 343: if( ISCONST(DOLIMIT) ) ! 344: ctlstack->domax = mkconv(dotype, DOLIMIT); ! 345: else ! 346: ctlstack->domax = (expptr) mktemp(dotype, PNULL); ! 347: ! 348: if( ISCONST(DOINCR) ) ! 349: { ! 350: ctlstack->dostep = mkconv(dotype, DOINCR); ! 351: if( (incsign = conssgn(ctlstack->dostep)) == 0) ! 352: err("zero DO increment"); ! 353: ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP); ! 354: } ! 355: else ! 356: { ! 357: ctlstack->dostep = (expptr) mktemp(dotype, PNULL); ! 358: ctlstack->dostepsign = VARSTEP; ! 359: ctlstack->doposlabel = newlabel(); ! 360: ctlstack->doneglabel = newlabel(); ! 361: } ! 362: ! 363: if( ISCONST(ctlstack->domax) && ISCONST(DOINIT) && ctlstack->dostepsign!=VARSTEP) ! 364: { ! 365: puteq(cpexpr(dovarp), cpexpr(DOINIT)); ! 366: if( onetripflag ) ! 367: frexpr(DOINIT); ! 368: else ! 369: { ! 370: q = mkexpr(OPMINUS, cpexpr(DOINIT), ! 371: cpexpr(ctlstack->domax)); ! 372: if(incsign == (i = conssgn(q)) || !i && bugwarn & 2) ! 373: { ! 374: warn("DO range never executed"); ! 375: putgoto(ctlstack->endlabel); ! 376: } ! 377: else if (!i && bugwarn) ! 378: warnb("old f77 never executed the DO range"); ! 379: frexpr(q); ! 380: } ! 381: } ! 382: else if(ctlstack->dostepsign!=VARSTEP && !onetripflag) ! 383: { ! 384: if( ISCONST(ctlstack->domax) ) ! 385: q = (expptr) cpexpr(ctlstack->domax); ! 386: else ! 387: q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT); ! 388: ! 389: q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT); ! 390: q = mkexpr( (ctlstack->dostepsign==POSSTEP ? OPLE : OPGE), q1, q); ! 391: putif(q, ctlstack->endlabel); ! 392: } ! 393: else ! 394: { ! 395: if(! ISCONST(ctlstack->domax) ) ! 396: puteq( cpexpr(ctlstack->domax), DOLIMIT); ! 397: q = DOINIT; ! 398: if( ! onetripflag ) ! 399: q = mkexpr(OPMINUS, q, ! 400: mkexpr(OPASSIGN, cpexpr(ctlstack->dostep), DOINCR) ); ! 401: puteq( cpexpr(dovarp), q); ! 402: if(onetripflag && ctlstack->dostepsign==VARSTEP) ! 403: puteq( cpexpr(ctlstack->dostep), DOINCR); ! 404: } ! 405: ! 406: if(ctlstack->dostepsign == VARSTEP) ! 407: { ! 408: if(onetripflag) ! 409: putgoto(ctlstack->dobodylabel); ! 410: else ! 411: putif( mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)), ! 412: ctlstack->doneglabel ); ! 413: putlabel(ctlstack->doposlabel); ! 414: putif( mkexpr(OPLE, ! 415: mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep)), ! 416: cpexpr(ctlstack->domax) ), ! 417: ctlstack->endlabel); ! 418: } ! 419: putlabel(ctlstack->dobodylabel); ! 420: if(dostgp) ! 421: puteq(dostgp, cpexpr(dovarp)); ! 422: frexpr(dovarp); ! 423: } ! 424: ! 425: ! 426: ! 427: enddo(here) ! 428: int here; ! 429: { ! 430: register struct Ctlframe *q; ! 431: register expptr t; ! 432: Namep np; ! 433: Addrp ap; ! 434: register int i; ! 435: ! 436: while(here == dorange) ! 437: { ! 438: if(np = ctlstack->donamep) ! 439: { ! 440: t = mkexpr(OPPLUSEQ, mkplace(ctlstack->donamep), ! 441: cpexpr(ctlstack->dostep) ); ! 442: ! 443: if(ctlstack->dostepsign == VARSTEP) ! 444: { ! 445: putif( mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), ctlstack->doposlabel); ! 446: putlabel(ctlstack->doneglabel); ! 447: putif( mkexpr(OPLT, t, ctlstack->domax), ctlstack->dobodylabel); ! 448: } ! 449: else ! 450: putif( mkexpr( (ctlstack->dostepsign==POSSTEP ? OPGT : OPLT), ! 451: t, ctlstack->domax), ! 452: ctlstack->dobodylabel); ! 453: putlabel(ctlstack->endlabel); ! 454: if(ap = memversion(np)) ! 455: puteq(ap, mkplace(np)); ! 456: for(i = 0 ; i < 4 ; ++i) ! 457: ctlstack->ctlabels[i] = 0; ! 458: deregister(ctlstack->donamep); ! 459: ctlstack->donamep->vdovar = NO; ! 460: frexpr(ctlstack->dostep); ! 461: } ! 462: ! 463: popctl(); ! 464: poplab(); ! 465: dorange = 0; ! 466: for(q = ctlstack ; q>=ctls ; --q) ! 467: if(q->ctltype == CTLDO) ! 468: { ! 469: dorange = q->dolabel; ! 470: break; ! 471: } ! 472: } ! 473: } ! 474: ! 475: chainp Lblfudgelist; ! 476: ! 477: expptr ! 478: labelfudge(t, newno) ! 479: register int t; ! 480: { ! 481: register chainp cp; ! 482: register Addrp A; ! 483: ! 484: for(cp = Lblfudgelist; cp; cp = cp->nextp->nextp) ! 485: if ((int)cp->datap == t) ! 486: break; ! 487: if (cp) { ! 488: A = (Addrp)cp->nextp->datap; ! 489: if (newno) ! 490: cp->datap = (tagptr)newno; ! 491: } ! 492: else { ! 493: if (newno) ! 494: return 0; ! 495: A = ALLOC(Addrblock); ! 496: A->tag = TADDR; ! 497: A->vtype = TYLONG; ! 498: A->vclass = CLVAR; ! 499: A->vstg = STGINIT; ! 500: A->memno = ++lastvarno; ! 501: A->memoffset = ICON(0); ! 502: Lblfudgelist = mkchain((tagptr)t, ! 503: mkchain((tagptr)A, Lblfudgelist)); ! 504: } ! 505: return (expptr)cpexpr((tagptr)A); ! 506: } ! 507: ! 508: exassign(vname, labelval) ! 509: Namep vname; ! 510: struct Labelblock *labelval; ! 511: { ! 512: Addrp p; ! 513: expptr mkaddcon(); ! 514: ! 515: p = mkplace(vname); ! 516: if( ! ONEOF(p->vtype, MSKINT|MSKADDR) ) ! 517: err("noninteger assign variable"); ! 518: else ! 519: puteq(p, labelval->labtype == LABUNKNOWN ! 520: ? labelfudge(labelval->labelno,0) ! 521: : mkaddcon(labelval->labelno) ); ! 522: } ! 523: ! 524: ! 525: ! 526: exarif(expr, neglab, zerlab, poslab) ! 527: expptr expr; ! 528: struct Labelblock *neglab, *zerlab, *poslab; ! 529: { ! 530: register int lm, lz, lp; ! 531: ! 532: lm = neglab->labelno; ! 533: lz = zerlab->labelno; ! 534: lp = poslab->labelno; ! 535: expr = fixtype(expr); ! 536: ! 537: if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) ) ! 538: { ! 539: err("invalid type of arithmetic if expression"); ! 540: frexpr(expr); ! 541: } ! 542: else ! 543: { ! 544: if(lm == lz) ! 545: exar2(OPLE, expr, lm, lp); ! 546: else if(lm == lp) ! 547: exar2(OPNE, expr, lm, lz); ! 548: else if(lz == lp) ! 549: exar2(OPGE, expr, lz, lm); ! 550: else ! 551: prarif(expr, lm, lz, lp); ! 552: } ! 553: } ! 554: ! 555: ! 556: ! 557: LOCAL exar2(op, e, l1, l2) ! 558: int op; ! 559: expptr e; ! 560: int l1, l2; ! 561: { ! 562: putif( mkexpr(op, e, ICON(0)), l2); ! 563: putgoto(l1); ! 564: } ! 565: ! 566: ! 567: exreturn(p) ! 568: register expptr p; ! 569: { ! 570: if(procclass != CLPROC) ! 571: warn("RETURN statement in main or block data"); ! 572: if(p && (proctype!=TYSUBR || procclass!=CLPROC) ) ! 573: { ! 574: err("alternate return in nonsubroutine"); ! 575: p = 0; ! 576: } ! 577: ! 578: if(p) ! 579: { ! 580: putforce(TYINT, p); ! 581: putgoto(retlabel); ! 582: } ! 583: else ! 584: putgoto(proctype==TYSUBR ? ret0label : retlabel); ! 585: } ! 586: ! 587: ! 588: ! 589: exasgoto(labvar) ! 590: struct Hashentry *labvar; ! 591: { ! 592: register Addrp p; ! 593: ! 594: p = mkplace(labvar); ! 595: if( ! ISINT(p->vtype) ) ! 596: err("assigned goto variable must be integer"); ! 597: else ! 598: putbranch(p); ! 599: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.