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