|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)exec.c 5.2 (Berkeley) 6/7/85"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * exec.c ! 13: * ! 14: * Routines for handling the semantics of control structures. ! 15: * F77 compiler, pass 1. ! 16: * ! 17: * University of Utah CS Dept modification history: ! 18: * ! 19: * Revision 2.3 85/03/18 08:03:31 donn ! 20: * Hacks for conversions from type address to numeric type -- prevent addresses ! 21: * from being stored in shorts and prevent warnings about implicit conversions. ! 22: * ! 23: * Revision 2.2 84/09/03 23:18:30 donn ! 24: * When a DO loop had the same variable as its loop variable and its limit, ! 25: * the limit temporary was assigned to AFTER the original value of the variable ! 26: * was destroyed by assigning the initial value to the loop variable. I ! 27: * swapped the operands of a comparison and changed the direction of the ! 28: * operator... This only affected programs when optimizing. (This may not ! 29: * be enough if something alters the order of evaluation of side effects ! 30: * later on... sigh.) ! 31: * ! 32: * Revision 2.1 84/07/19 12:02:53 donn ! 33: * Changed comment headers for UofU. ! 34: * ! 35: * Revision 1.3 84/07/12 18:35:12 donn ! 36: * Added change to enddo() to detect open 'if' blocks at the ends of loops. ! 37: * ! 38: * Revision 1.2 84/06/08 11:22:53 donn ! 39: * Fixed bug in exdo() -- if a loop parameter contained an instance of the loop ! 40: * variable and the optimizer was off, the loop variable got converted to ! 41: * register before the parameters were processed and so the loop parameters ! 42: * were initialized from garbage in the register instead of the memory version ! 43: * of the loop variable. ! 44: * ! 45: */ ! 46: ! 47: #include "defs.h" ! 48: #include "optim.h" ! 49: ! 50: ! 51: /* Logical IF codes ! 52: */ ! 53: ! 54: ! 55: exif(p) ! 56: expptr p; ! 57: { ! 58: register int k; ! 59: pushctl(CTLIF); ! 60: ctlstack->elselabel = newlabel(); ! 61: ! 62: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) ! 63: { ! 64: if(k != TYERROR) ! 65: err("non-logical expression in IF statement"); ! 66: frexpr(p); ! 67: } ! 68: else if (optimflag) ! 69: optbuff (SKIFN, p, ctlstack->elselabel, 0); ! 70: else ! 71: putif (p, ctlstack->elselabel); ! 72: } ! 73: ! 74: ! 75: ! 76: exelif(p) ! 77: expptr p; ! 78: { ! 79: int k,oldelse; ! 80: ! 81: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) ! 82: { ! 83: if(k != TYERROR) ! 84: err("non-logical expression in IF statement"); ! 85: frexpr(p); ! 86: } ! 87: else { ! 88: if(ctlstack->ctltype == CTLIF) ! 89: { ! 90: if(ctlstack->endlabel == 0) ctlstack->endlabel = newlabel(); ! 91: oldelse=ctlstack->elselabel; ! 92: ctlstack->elselabel = newlabel(); ! 93: if (optimflag) ! 94: { ! 95: optbuff (SKGOTO, 0, ctlstack->endlabel, 0); ! 96: optbuff (SKLABEL, 0, oldelse, 0); ! 97: optbuff (SKIFN, p, ctlstack->elselabel, 0); ! 98: } ! 99: else ! 100: { ! 101: putgoto (ctlstack->endlabel); ! 102: putlabel (oldelse); ! 103: putif (p, ctlstack->elselabel); ! 104: } ! 105: } ! 106: else execerr("elseif out of place", CNULL); ! 107: } ! 108: } ! 109: ! 110: ! 111: ! 112: ! 113: ! 114: exelse() ! 115: { ! 116: if(ctlstack->ctltype==CTLIF) ! 117: { ! 118: if(ctlstack->endlabel == 0) ! 119: ctlstack->endlabel = newlabel(); ! 120: ctlstack->ctltype = CTLELSE; ! 121: if (optimflag) ! 122: { ! 123: optbuff (SKGOTO, 0, ctlstack->endlabel, 0); ! 124: optbuff (SKLABEL, 0, ctlstack->elselabel, 0); ! 125: } ! 126: else ! 127: { ! 128: putgoto (ctlstack->endlabel); ! 129: putlabel (ctlstack->elselabel); ! 130: } ! 131: } ! 132: ! 133: else execerr("else out of place", CNULL); ! 134: } ! 135: ! 136: ! 137: exendif() ! 138: { ! 139: if (ctlstack->ctltype == CTLIF) ! 140: { ! 141: if (optimflag) ! 142: { ! 143: optbuff (SKLABEL, 0, ctlstack->elselabel, 0); ! 144: if (ctlstack->endlabel) ! 145: optbuff (SKLABEL, 0, ctlstack->endlabel, 0); ! 146: } ! 147: else ! 148: { ! 149: putlabel (ctlstack->elselabel); ! 150: if (ctlstack->endlabel) ! 151: putlabel (ctlstack->endlabel); ! 152: } ! 153: popctl (); ! 154: } ! 155: else if (ctlstack->ctltype == CTLELSE) ! 156: { ! 157: if (optimflag) ! 158: optbuff (SKLABEL, 0, ctlstack->endlabel, 0); ! 159: else ! 160: putlabel (ctlstack->endlabel); ! 161: popctl (); ! 162: } ! 163: else ! 164: execerr("endif out of place", CNULL); ! 165: } ! 166: ! 167: ! 168: ! 169: LOCAL pushctl(code) ! 170: int code; ! 171: { ! 172: register int i; ! 173: ! 174: /* fprintf(diagfile,"old blklevel %d \n",blklevel); dmpframe(ctlstack); */ ! 175: if(++ctlstack >= lastctl) ! 176: many("loops or if-then-elses", 'c'); ! 177: ctlstack->ctltype = code; ! 178: for(i = 0 ; i < 4 ; ++i) ! 179: ctlstack->ctlabels[i] = 0; ! 180: ++blklevel; ! 181: } ! 182: ! 183: ! 184: LOCAL popctl() ! 185: { ! 186: if( ctlstack-- < ctls ) ! 187: fatal("control stack empty"); ! 188: --blklevel; ! 189: } ! 190: ! 191: ! 192: ! 193: LOCAL poplab() ! 194: { ! 195: register struct Labelblock *lp; ! 196: ! 197: for(lp = labeltab ; lp < highlabtab ; ++lp) ! 198: if(lp->labdefined) ! 199: { ! 200: /* mark all labels in inner blocks unreachable */ ! 201: if(lp->blklevel > blklevel) ! 202: lp->labinacc = YES; ! 203: } ! 204: else if(lp->blklevel > blklevel) ! 205: { ! 206: /* move all labels referred to in inner blocks out a level */ ! 207: lp->blklevel = blklevel; ! 208: } ! 209: } ! 210: ! 211: ! 212: ! 213: /* BRANCHING CODE ! 214: */ ! 215: ! 216: exgoto(lab) ! 217: struct Labelblock *lab; ! 218: { ! 219: if (optimflag) ! 220: optbuff (SKGOTO, 0, lab->labelno, 0); ! 221: else ! 222: putgoto (lab->labelno); ! 223: } ! 224: ! 225: ! 226: ! 227: ! 228: ! 229: ! 230: ! 231: exequals(lp, rp) ! 232: register struct Primblock *lp; ! 233: register expptr rp; ! 234: { ! 235: register Namep np; ! 236: ! 237: if(lp->tag != TPRIM) ! 238: { ! 239: err("assignment to a non-variable"); ! 240: frexpr(lp); ! 241: frexpr(rp); ! 242: } ! 243: else if(lp->namep->vclass!=CLVAR && lp->argsp) ! 244: { ! 245: if(parstate >= INEXEC) ! 246: err("assignment to an undimemsioned array"); ! 247: else ! 248: mkstfunct(lp, rp); ! 249: } ! 250: else ! 251: { ! 252: np = (Namep) lp->namep; ! 253: if (np->vclass == CLPROC && np->vprocclass == PTHISPROC ! 254: && proctype == TYSUBR) ! 255: { ! 256: err("assignment to a subroutine name"); ! 257: return; ! 258: } ! 259: if(parstate < INDATA) ! 260: enddcl(); ! 261: if (optimflag) ! 262: optbuff (SKEQ, mkexpr(OPASSIGN, mklhs(lp), fixtype(rp)), 0, 0); ! 263: else ! 264: puteq (mklhs(lp), fixtype(rp)); ! 265: } ! 266: } ! 267: ! 268: ! 269: ! 270: mkstfunct(lp, rp) ! 271: struct Primblock *lp; ! 272: expptr rp; ! 273: { ! 274: register struct Primblock *p; ! 275: register Namep np; ! 276: chainp args; ! 277: ! 278: if(parstate < INDATA) ! 279: { ! 280: enddcl(); ! 281: parstate = INDATA; ! 282: } ! 283: ! 284: np = lp->namep; ! 285: if(np->vclass == CLUNKNOWN) ! 286: np->vclass = CLPROC; ! 287: else ! 288: { ! 289: dclerr("redeclaration of statement function", np); ! 290: return; ! 291: } ! 292: np->vprocclass = PSTFUNCT; ! 293: np->vstg = STGSTFUNCT; ! 294: impldcl(np); ! 295: args = (lp->argsp ? lp->argsp->listp : CHNULL); ! 296: np->varxptr.vstfdesc = mkchain(args , rp ); ! 297: ! 298: for( ; args ; args = args->nextp) ! 299: if( args->datap->tag!=TPRIM || ! 300: (p = (struct Primblock *) (args->datap) )->argsp || ! 301: p->fcharp || p->lcharp ) ! 302: err("non-variable argument in statement function definition"); ! 303: else ! 304: { ! 305: args->datap = (tagptr) (p->namep); ! 306: vardcl(p->namep); ! 307: free(p); ! 308: } ! 309: } ! 310: ! 311: ! 312: ! 313: excall(name, args, nstars, labels) ! 314: Namep name; ! 315: struct Listblock *args; ! 316: int nstars; ! 317: struct Labelblock *labels[ ]; ! 318: { ! 319: register expptr p; ! 320: ! 321: settype(name, TYSUBR, ENULL); ! 322: p = mkfunct( mkprim(name, args, CHNULL) ); ! 323: p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT; ! 324: if (nstars > 0) ! 325: if (optimflag) ! 326: optbuff (SKCMGOTO, p, nstars, labels); ! 327: else ! 328: putcmgo (p, nstars, labels); ! 329: else ! 330: if (optimflag) ! 331: optbuff (SKCALL, p, 0, 0); ! 332: else ! 333: putexpr (p); ! 334: } ! 335: ! 336: ! 337: ! 338: exstop(stop, p) ! 339: int stop; ! 340: register expptr p; ! 341: { ! 342: char *q; ! 343: int n; ! 344: expptr mkstrcon(); ! 345: ! 346: if(p) ! 347: { ! 348: if( ! ISCONST(p) ) ! 349: { ! 350: execerr("pause/stop argument must be constant", CNULL); ! 351: frexpr(p); ! 352: p = mkstrcon(0, CNULL); ! 353: } ! 354: else if( ISINT(p->constblock.vtype) ) ! 355: { ! 356: q = convic(p->constblock.const.ci); ! 357: n = strlen(q); ! 358: if(n > 0) ! 359: { ! 360: p->constblock.const.ccp = copyn(n, q); ! 361: p->constblock.vtype = TYCHAR; ! 362: p->constblock.vleng = (expptr) ICON(n); ! 363: } ! 364: else ! 365: p = (expptr) mkstrcon(0, CNULL); ! 366: } ! 367: else if(p->constblock.vtype != TYCHAR) ! 368: { ! 369: execerr("pause/stop argument must be integer or string", CNULL); ! 370: p = (expptr) mkstrcon(0, CNULL); ! 371: } ! 372: } ! 373: else p = (expptr) mkstrcon(0, CNULL); ! 374: ! 375: if (optimflag) ! 376: optbuff ((stop ? SKSTOP : SKPAUSE), p, 0, 0); ! 377: else ! 378: putexpr (call1(TYSUBR, (stop ? "s_stop" : "s_paus"), p)); ! 379: } ! 380: ! 381: ! 382: /* UCB DO LOOP CODE */ ! 383: ! 384: #define DOINIT par[0] ! 385: #define DOLIMIT par[1] ! 386: #define DOINCR par[2] ! 387: ! 388: #define CONSTINIT const[0] ! 389: #define CONSTLIMIT const[1] ! 390: #define CONSTINCR const[2] ! 391: ! 392: #define VARSTEP 0 ! 393: #define POSSTEP 1 ! 394: #define NEGSTEP 2 ! 395: ! 396: ! 397: exdo(range, spec) ! 398: int range; ! 399: chainp spec; ! 400: ! 401: { ! 402: register expptr p, q; ! 403: expptr q1; ! 404: register Namep np; ! 405: chainp cp; ! 406: register int i; ! 407: int dotype, incsign; ! 408: Addrp dovarp, dostgp; ! 409: expptr par[3]; ! 410: expptr const[3]; ! 411: Slotp doslot; ! 412: ! 413: pushctl(CTLDO); ! 414: dorange = ctlstack->dolabel = range; ! 415: np = (Namep) (spec->datap); ! 416: ctlstack->donamep = NULL; ! 417: if(np->vdovar) ! 418: { ! 419: errstr("nested loops with variable %s", varstr(VL,np->varname)); ! 420: return; ! 421: } ! 422: ! 423: dovarp = mkplace(np); ! 424: dotype = dovarp->vtype; ! 425: ! 426: if( ! ONEOF(dotype, MSKINT|MSKREAL) ) ! 427: { ! 428: err("bad type on DO variable"); ! 429: return; ! 430: } ! 431: ! 432: ! 433: for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp) ! 434: { ! 435: p = fixtype((expptr) cpexpr((tagptr) q = cp->datap)); ! 436: if(!ONEOF(p->headblock.vtype, MSKINT|MSKREAL) ) ! 437: { ! 438: err("bad type on DO parameter"); ! 439: return; ! 440: } ! 441: ! 442: ! 443: if (ISCONST(q)) ! 444: const[i] = mkconv(dotype, q); ! 445: else ! 446: { ! 447: frexpr(q); ! 448: const[i] = NULL; ! 449: } ! 450: ! 451: par[i++] = mkconv(dotype, p); ! 452: } ! 453: ! 454: frchain(&spec); ! 455: switch(i) ! 456: { ! 457: case 0: ! 458: case 1: ! 459: err("too few DO parameters"); ! 460: return; ! 461: ! 462: case 2: ! 463: DOINCR = (expptr) ICON(1); ! 464: CONSTINCR = ICON(1); ! 465: ! 466: case 3: ! 467: break; ! 468: ! 469: default: ! 470: err("too many DO parameters"); ! 471: return; ! 472: } ! 473: ! 474: ctlstack->donamep = np; ! 475: ! 476: np->vdovar = YES; ! 477: if( !optimflag && enregister(np) ) ! 478: { ! 479: /* stgp points to a storage version, varp to a register version */ ! 480: dostgp = dovarp; ! 481: dovarp = mkplace(np); ! 482: } ! 483: else ! 484: dostgp = NULL; ! 485: ! 486: for (i = 0; i < 4; i++) ! 487: ctlstack->ctlabels[i] = newlabel(); ! 488: ! 489: if( CONSTLIMIT ) ! 490: ctlstack->domax = DOLIMIT; ! 491: else ! 492: ctlstack->domax = (expptr) mktemp(dotype, PNULL); ! 493: ! 494: if( CONSTINCR ) ! 495: { ! 496: ctlstack->dostep = DOINCR; ! 497: if( (incsign = conssgn(CONSTINCR)) == 0) ! 498: err("zero DO increment"); ! 499: ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP); ! 500: } ! 501: else ! 502: { ! 503: ctlstack->dostep = (expptr) mktemp(dotype, PNULL); ! 504: ctlstack->dostepsign = VARSTEP; ! 505: } ! 506: ! 507: if (optimflag) ! 508: doslot = optbuff (SKDOHEAD,0,0,ctlstack); ! 509: ! 510: if( CONSTLIMIT && CONSTINIT && ctlstack->dostepsign!=VARSTEP) ! 511: { ! 512: if (optimflag) ! 513: optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp),cpexpr(DOINIT)), ! 514: 0,0); ! 515: else ! 516: puteq (cpexpr(dovarp), cpexpr(DOINIT)); ! 517: if( ! onetripflag ) ! 518: { ! 519: q = mkexpr(OPMINUS, cpexpr(CONSTLIMIT), cpexpr(CONSTINIT)); ! 520: if((incsign * conssgn(q)) == -1) ! 521: { ! 522: warn("DO range never executed"); ! 523: if (optimflag) ! 524: optbuff (SKGOTO,0,ctlstack->endlabel,0); ! 525: else ! 526: putgoto (ctlstack->endlabel); ! 527: } ! 528: frexpr(q); ! 529: } ! 530: } ! 531: ! 532: ! 533: else if (ctlstack->dostepsign != VARSTEP && !onetripflag) ! 534: { ! 535: if (CONSTLIMIT) ! 536: q = (expptr) cpexpr(ctlstack->domax); ! 537: else ! 538: q = mkexpr(OPASSIGN, cpexpr(ctlstack->domax), DOLIMIT); ! 539: q1 = mkexpr(OPASSIGN, cpexpr(dovarp), DOINIT); ! 540: q = mkexpr( (ctlstack->dostepsign == POSSTEP ? OPGE : OPLE), ! 541: q, q1); ! 542: if (optimflag) ! 543: optbuff (SKIFN,q, ctlstack->endlabel,0); ! 544: else ! 545: putif (q, ctlstack->endlabel); ! 546: } ! 547: else ! 548: { ! 549: if (!CONSTLIMIT) ! 550: if (optimflag) ! 551: optbuff (SKEQ, ! 552: mkexpr(OPASSIGN,cpexpr(ctlstack->domax),DOLIMIT),0,0); ! 553: else ! 554: puteq (cpexpr(ctlstack->domax), DOLIMIT); ! 555: q = DOINIT; ! 556: if (!onetripflag) ! 557: q = mkexpr(OPMINUS, q, ! 558: mkexpr(OPASSIGN, cpexpr(ctlstack->dostep), ! 559: DOINCR) ); ! 560: if (optimflag) ! 561: optbuff (SKEQ,mkexpr(OPASSIGN,cpexpr(dovarp), q),0,0); ! 562: else ! 563: puteq (cpexpr(dovarp), q); ! 564: if (onetripflag && ctlstack->dostepsign == VARSTEP) ! 565: if (optimflag) ! 566: optbuff (SKEQ, ! 567: mkexpr(OPASSIGN,cpexpr(ctlstack->dostep),DOINCR),0,0); ! 568: else ! 569: puteq (cpexpr(ctlstack->dostep), DOINCR); ! 570: } ! 571: ! 572: if (ctlstack->dostepsign == VARSTEP) ! 573: { ! 574: expptr incr,test; ! 575: if (onetripflag) ! 576: if (optimflag) ! 577: optbuff (SKGOTO,0,ctlstack->dobodylabel,0); ! 578: else ! 579: putgoto (ctlstack->dobodylabel); ! 580: else ! 581: if (optimflag) ! 582: optbuff (SKIFN,mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)), ! 583: ctlstack->doneglabel,0); ! 584: else ! 585: putif (mkexpr(OPGE, cpexpr(ctlstack->dostep), ICON(0)), ! 586: ctlstack->doneglabel); ! 587: if (optimflag) ! 588: optbuff (SKLABEL,0,ctlstack->doposlabel,0); ! 589: else ! 590: putlabel (ctlstack->doposlabel); ! 591: incr = mkexpr(OPPLUSEQ, cpexpr(dovarp), cpexpr(ctlstack->dostep)); ! 592: test = mkexpr(OPLE, incr, cpexpr(ctlstack->domax)); ! 593: if (optimflag) ! 594: optbuff (SKIFN,test, ctlstack->endlabel,0); ! 595: else ! 596: putif (test, ctlstack->endlabel); ! 597: } ! 598: ! 599: if (optimflag) ! 600: optbuff (SKLABEL,0,ctlstack->dobodylabel,0); ! 601: else ! 602: putlabel (ctlstack->dobodylabel); ! 603: if (dostgp) ! 604: { ! 605: if (optimflag) ! 606: optbuff (SKEQ,mkexpr(OPASSIGN,dostgp, dovarp),0,0); ! 607: else ! 608: puteq (dostgp, dovarp); ! 609: } ! 610: else ! 611: frexpr(dovarp); ! 612: if (optimflag) ! 613: doslot->nullslot = optbuff (SKNULL,0,0,0); ! 614: ! 615: frexpr(CONSTINIT); ! 616: frexpr(CONSTLIMIT); ! 617: frexpr(CONSTINCR); ! 618: } ! 619: ! 620: ! 621: enddo(here) ! 622: int here; ! 623: ! 624: { ! 625: register struct Ctlframe *q; ! 626: Namep np; ! 627: Addrp ap, rv; ! 628: expptr t; ! 629: register int i; ! 630: Slotp doslot; ! 631: ! 632: while (here == dorange) ! 633: { ! 634: while (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLELSE) ! 635: { ! 636: execerr("missing endif", CNULL); ! 637: exendif(); ! 638: } ! 639: ! 640: if (np = ctlstack->donamep) ! 641: { ! 642: rv = mkplace (np); ! 643: ! 644: t = mkexpr(OPPLUSEQ, cpexpr(rv), cpexpr(ctlstack->dostep) ); ! 645: ! 646: if (optimflag) ! 647: doslot = optbuff (SKENDDO,0,0,ctlstack); ! 648: ! 649: if (ctlstack->dostepsign == VARSTEP) ! 650: if (optimflag) ! 651: { ! 652: optbuff (SKIFN, ! 653: mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), ! 654: ctlstack->doposlabel,0); ! 655: optbuff (SKLABEL,0,ctlstack->doneglabel,0); ! 656: optbuff (SKIFN,mkexpr(OPLT, t, ctlstack->domax), ! 657: ctlstack->dobodylabel,0); ! 658: } ! 659: else ! 660: { ! 661: putif (mkexpr(OPLE, cpexpr(ctlstack->dostep), ICON(0)), ! 662: ctlstack->doposlabel); ! 663: putlabel (ctlstack->doneglabel); ! 664: putif (mkexpr(OPLT, t, ctlstack->domax), ! 665: ctlstack->dobodylabel); ! 666: } ! 667: else ! 668: { ! 669: int op; ! 670: op = (ctlstack->dostepsign == POSSTEP ? OPGT : OPLT); ! 671: if (optimflag) ! 672: optbuff (SKIFN, mkexpr(op,t,ctlstack->domax), ! 673: ctlstack->dobodylabel,0); ! 674: else ! 675: putif (mkexpr(op, t, ctlstack->domax), ! 676: ctlstack->dobodylabel); ! 677: } ! 678: if (optimflag) ! 679: optbuff (SKLABEL,0,ctlstack->endlabel,0); ! 680: else ! 681: putlabel (ctlstack->endlabel); ! 682: ! 683: if (ap = memversion(np)) ! 684: { ! 685: if (optimflag) ! 686: optbuff (SKEQ,mkexpr(OPASSIGN,ap, rv),0,0); ! 687: else ! 688: puteq (ap, rv); ! 689: } ! 690: else ! 691: frexpr(rv); ! 692: for (i = 0; i < 4; i++) ! 693: ctlstack->ctlabels[i] = 0; ! 694: if (!optimflag) ! 695: deregister(ctlstack->donamep); ! 696: ctlstack->donamep->vdovar = NO; ! 697: if (optimflag) ! 698: doslot->nullslot = optbuff (SKNULL,0,0,0); ! 699: } ! 700: ! 701: popctl(); ! 702: poplab(); ! 703: ! 704: dorange = 0; ! 705: for (q = ctlstack; q >= ctls; --q) ! 706: if (q->ctltype == CTLDO) ! 707: { ! 708: dorange = q->dolabel; ! 709: break; ! 710: } ! 711: } ! 712: } ! 713: ! 714: ! 715: exassign(vname, labelval) ! 716: Namep vname; ! 717: struct Labelblock *labelval; ! 718: { ! 719: Addrp p; ! 720: expptr mkaddcon(); ! 721: ! 722: p = mkplace(vname); ! 723: #if SZADDR > SZSHORT ! 724: if( p->vtype == TYSHORT ) ! 725: err("insufficient precision in ASSIGN variable"); ! 726: else ! 727: #endif ! 728: if( ! ONEOF(p->vtype, MSKINT|MSKADDR) ) ! 729: err("noninteger assign variable"); ! 730: else ! 731: { ! 732: if (optimflag) ! 733: optbuff (SKASSIGN, p, labelval->labelno, 0); ! 734: else ! 735: puteq (p, intrconv(p->vtype, mkaddcon(labelval->labelno))); ! 736: } ! 737: } ! 738: ! 739: ! 740: ! 741: exarif(expr, neglab, zerlab, poslab) ! 742: expptr expr; ! 743: struct Labelblock *neglab, *zerlab, *poslab; ! 744: { ! 745: register int lm, lz, lp; ! 746: struct Labelblock *labels[3]; ! 747: ! 748: lm = neglab->labelno; ! 749: lz = zerlab->labelno; ! 750: lp = poslab->labelno; ! 751: expr = fixtype(expr); ! 752: ! 753: if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) ) ! 754: { ! 755: err("invalid type of arithmetic if expression"); ! 756: frexpr(expr); ! 757: } ! 758: else ! 759: { ! 760: if(lm == lz) ! 761: exar2(OPLE, expr, lm, lp); ! 762: else if(lm == lp) ! 763: exar2(OPNE, expr, lm, lz); ! 764: else if(lz == lp) ! 765: exar2(OPGE, expr, lz, lm); ! 766: else ! 767: if (optimflag) ! 768: { ! 769: labels[0] = neglab; ! 770: labels[1] = zerlab; ! 771: labels[2] = poslab; ! 772: optbuff (SKARIF, expr, 0, labels); ! 773: } ! 774: else ! 775: prarif(expr, lm, lz, lp); ! 776: } ! 777: } ! 778: ! 779: ! 780: ! 781: LOCAL exar2 (op, e, l1, l2) ! 782: int op; ! 783: expptr e; ! 784: int l1,l2; ! 785: { ! 786: if (optimflag) ! 787: { ! 788: optbuff (SKIFN, mkexpr(op, e, ICON(0)), l2, 0); ! 789: optbuff (SKGOTO, 0, l1, 0); ! 790: } ! 791: else ! 792: { ! 793: putif (mkexpr(op, e, ICON(0)), l2); ! 794: putgoto (l1); ! 795: } ! 796: } ! 797: ! 798: ! 799: exreturn(p) ! 800: register expptr p; ! 801: { ! 802: if(procclass != CLPROC) ! 803: warn("RETURN statement in main or block data"); ! 804: if(p && (proctype!=TYSUBR || procclass!=CLPROC) ) ! 805: { ! 806: err("alternate return in nonsubroutine"); ! 807: p = 0; ! 808: } ! 809: ! 810: if(p) ! 811: if (optimflag) ! 812: optbuff (SKRETURN, p, retlabel, 0); ! 813: else ! 814: { ! 815: putforce (TYINT, p); ! 816: putgoto (retlabel); ! 817: } ! 818: else ! 819: if (optimflag) ! 820: optbuff (SKRETURN, p, ! 821: (proctype==TYSUBR ? ret0label : retlabel), 0); ! 822: else ! 823: putgoto (proctype==TYSUBR ? ret0label : retlabel); ! 824: } ! 825: ! 826: ! 827: ! 828: exasgoto(labvar) ! 829: struct Hashentry *labvar; ! 830: { ! 831: register Addrp p; ! 832: ! 833: p = mkplace(labvar); ! 834: if( ! ISINT(p->vtype) ) ! 835: err("assigned goto variable must be integer"); ! 836: else ! 837: if (optimflag) ! 838: optbuff (SKASGOTO, p, 0, 0); ! 839: else ! 840: putbranch (p); ! 841: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.