00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "defs.h"
00025 #include "p1defs.h"
00026 #include "names.h"
00027
00028 static void exar2 Argdcl((int, tagptr, struct Labelblock*, struct Labelblock*));
00029 static void popctl Argdcl((void));
00030 static void pushctl Argdcl((int));
00031
00032
00033
00034
00035 void
00036 #ifdef KR_headers
00037 exif(p)
00038 expptr p;
00039 #else
00040 exif(expptr p)
00041 #endif
00042 {
00043 pushctl(CTLIF);
00044 putif(p, 0);
00045 }
00046
00047
00048 void
00049 #ifdef KR_headers
00050 exelif(p)
00051 expptr p;
00052 #else
00053 exelif(expptr p)
00054 #endif
00055 {
00056 if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX)
00057 putif(p, 1);
00058 else
00059 execerr("elseif out of place", CNULL);
00060 }
00061
00062
00063
00064
00065 void
00066 exelse(Void)
00067 {
00068 register struct Ctlframe *c;
00069
00070 for(c = ctlstack; c->ctltype == CTLIFX; --c);
00071 if(c->ctltype == CTLIF) {
00072 p1_else ();
00073 c->ctltype = CTLELSE;
00074 }
00075 else
00076 execerr("else out of place", CNULL);
00077 }
00078
00079 void
00080 #ifdef KR_headers
00081 exendif()
00082 #else
00083 exendif()
00084 #endif
00085 {
00086 while(ctlstack->ctltype == CTLIFX) {
00087 popctl();
00088 p1else_end();
00089 }
00090 if(ctlstack->ctltype == CTLIF) {
00091 popctl();
00092 p1_endif ();
00093 }
00094 else if(ctlstack->ctltype == CTLELSE) {
00095 popctl();
00096 p1else_end ();
00097 }
00098 else
00099 execerr("endif out of place", CNULL);
00100 }
00101
00102
00103 void
00104 #ifdef KR_headers
00105 new_endif()
00106 #else
00107 new_endif()
00108 #endif
00109 {
00110 if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX)
00111 pushctl(CTLIFX);
00112 else
00113 err("new_endif bug");
00114 }
00115
00116
00117
00118
00119 LOCAL void
00120 #ifdef KR_headers
00121 pushctl(code)
00122 int code;
00123 #else
00124 pushctl(int code)
00125 #endif
00126 {
00127 register int i;
00128
00129 if(++ctlstack >= lastctl)
00130 many("loops or if-then-elses", 'c', maxctl);
00131 ctlstack->ctltype = code;
00132 for(i = 0 ; i < 4 ; ++i)
00133 ctlstack->ctlabels[i] = 0;
00134 ctlstack->dowhile = 0;
00135 ctlstack->domax = ctlstack->dostep = 0;
00136 ++blklevel;
00137 }
00138
00139
00140 LOCAL void
00141 popctl(Void)
00142 {
00143 if( ctlstack-- < ctls )
00144 Fatal("control stack empty");
00145 --blklevel;
00146 }
00147
00148
00149
00150
00151
00152 LOCAL void
00153 poplab(Void)
00154 {
00155 register struct Labelblock *lp;
00156
00157 for(lp = labeltab ; lp < highlabtab ; ++lp)
00158 if(lp->labdefined)
00159 {
00160
00161 if(lp->blklevel > (unsigned int)(blklevel))
00162 lp->labinacc = YES;
00163 }
00164 else if(lp->blklevel > (unsigned int)(blklevel))
00165 {
00166
00167 lp->blklevel = blklevel;
00168 }
00169 }
00170
00171
00172
00173
00174 void
00175 #ifdef KR_headers
00176 exgoto(lab)
00177 struct Labelblock *lab;
00178 #else
00179 exgoto(struct Labelblock *lab)
00180 #endif
00181 {
00182 lab->labused = 1;
00183 p1_goto (lab -> stateno);
00184 }
00185
00186
00187 static expptr
00188 #ifdef KR_headers
00189 cktype1(p) expptr p;
00190 #else
00191 cktype1(expptr p)
00192 #endif
00193 {
00194
00195
00196
00197 chainp c;
00198 tagptr t;
00199
00200 if(p == 0)
00201 return(0);
00202
00203 switch(p->tag) {
00204 case TCONST:
00205 case TADDR:
00206 case TERROR:
00207 break;
00208
00209
00210
00211
00212 case TEXPR:
00213 t = mkexpr(p->exprblock.opcode, cktype1(p->exprblock.leftp),
00214 cktype1(p->exprblock.rightp));
00215 free((charptr)p);
00216 p = (expptr) t;
00217 break;
00218
00219 case TLIST:
00220 for(c = p->listblock.listp; c; c = c->nextp)
00221 c->datap = (char*)cktype1((expptr)c->datap);
00222 break;
00223
00224 case TPRIM:
00225 p->primblock.argsp = (struct Listblock*)
00226 cktype1((expptr)p->primblock.argsp);
00227 p->primblock.fcharp = cktype1(p->primblock.fcharp);
00228 p->primblock.lcharp = cktype1(p->primblock.lcharp);
00229 break;
00230
00231 default:
00232 badtag("cktype1", p->tag);
00233 }
00234 return p;
00235 }
00236
00237
00238 void
00239 #ifdef KR_headers
00240 exequals(lp, rp)
00241 register struct Primblock *lp;
00242 register expptr rp;
00243 #else
00244 exequals(register struct Primblock *lp, register expptr rp)
00245 #endif
00246 {
00247 if(lp->tag != TPRIM)
00248 {
00249 err("assignment to a non-variable");
00250 frexpr((expptr)lp);
00251 frexpr(rp);
00252 }
00253 else if(lp->namep->vclass!=CLVAR && lp->argsp)
00254 {
00255 if(parstate >= INEXEC)
00256 errstr("statement function %.62s amid executables.",
00257 lp->namep->fvarname);
00258 mkstfunct(lp, rp);
00259 }
00260 else if (lp->vtype == TYSUBR)
00261 err("illegal use of subroutine name");
00262 else
00263 {
00264 expptr new_lp, new_rp;
00265
00266 if(parstate < INDATA) {
00267 enddcl();
00268 lp = (struct Primblock *)cktype1((expptr)lp);
00269 rp = cktype1(rp);
00270 }
00271 new_lp = mklhs (lp, keepsubs);
00272 new_rp = fixtype (rp);
00273 puteq(new_lp, new_rp);
00274 }
00275 }
00276
00277
00278
00279
00280
00281 long laststfcn = -1, thisstno;
00282 int doing_stmtfcn;
00283
00284 void
00285 #ifdef KR_headers
00286 mkstfunct(lp, rp)
00287 struct Primblock *lp;
00288 expptr rp;
00289 #else
00290 mkstfunct(struct Primblock *lp, expptr rp)
00291 #endif
00292 {
00293 register struct Primblock *p;
00294 register Namep np;
00295 chainp args;
00296
00297 laststfcn = thisstno;
00298 np = lp->namep;
00299 if(np->vclass == CLUNKNOWN)
00300 np->vclass = CLPROC;
00301 else
00302 {
00303 dclerr("redeclaration of statement function", np);
00304 return;
00305 }
00306 np->vprocclass = PSTFUNCT;
00307 np->vstg = STGSTFUNCT;
00308
00309
00310
00311 impldcl(np);
00312 if (np->vtype == TYCHAR && !np->vleng)
00313 err("character statement function with length (*)");
00314 args = (lp->argsp ? lp->argsp->listp : CHNULL);
00315 np->varxptr.vstfdesc = mkchain((char *)args, (chainp)rp);
00316
00317 for(doing_stmtfcn = 1 ; args ; args = args->nextp)
00318
00319
00320
00321
00322 if( ((tagptr)(args->datap))->tag!=TPRIM ||
00323 (p = (struct Primblock *)(args->datap) )->argsp ||
00324 p->fcharp || p->lcharp ) {
00325 err("non-variable argument in statement function definition");
00326 args->datap = 0;
00327 }
00328 else
00329 {
00330
00331
00332
00333 args->datap = (char *)p->namep;
00334 vardcl(p -> namep);
00335 free((char *)p);
00336 }
00337 doing_stmtfcn = 0;
00338 }
00339
00340 static void
00341 #ifdef KR_headers
00342 mixed_type(np)
00343 Namep np;
00344 #else
00345 mixed_type(Namep np)
00346 #endif
00347 {
00348 char buf[128];
00349 sprintf(buf, "%s function %.90s invoked as subroutine",
00350 ftn_types[np->vtype], np->fvarname);
00351 warn(buf);
00352 }
00353
00354 void
00355 #ifdef KR_headers
00356 excall(name, args, nstars, labels)
00357 Namep name;
00358 struct Listblock *args;
00359 int nstars;
00360 struct Labelblock **labels;
00361 #else
00362 excall(Namep name, struct Listblock *args, int nstars, struct Labelblock **labels)
00363 #endif
00364 {
00365 register expptr p;
00366
00367 if (name->vtype != TYSUBR) {
00368 if (name->vinfproc && !name->vcalled) {
00369 name->vtype = TYSUBR;
00370 frexpr(name->vleng);
00371 name->vleng = 0;
00372 }
00373 else if (!name->vimpltype && name->vtype != TYUNKNOWN)
00374 mixed_type(name);
00375 else
00376 settype(name, TYSUBR, (ftnint)0);
00377 }
00378 p = mkfunct( mkprim(name, args, CHNULL) );
00379 if (p->tag == TERROR)
00380 return;
00381
00382
00383
00384 p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT;
00385
00386
00387
00388 if(nstars > 0)
00389 putcmgo(putx(fixtype(p)), nstars, labels);
00390 else
00391 putexpr(p);
00392 }
00393
00394
00395 void
00396 #ifdef KR_headers
00397 exstop(stop, p)
00398 int stop;
00399 register expptr p;
00400 #else
00401 exstop(int stop, register expptr p)
00402 #endif
00403 {
00404 char *str;
00405 int n;
00406
00407 if(p)
00408 {
00409 if( ! ISCONST(p) )
00410 {
00411 execerr("pause/stop argument must be constant", CNULL);
00412 frexpr(p);
00413 p = mkstrcon(0, CNULL);
00414 }
00415 else if( ISINT(p->constblock.vtype) )
00416 {
00417 str = convic(p->constblock.Const.ci);
00418 n = strlen(str);
00419 if(n > 0)
00420 {
00421 p->constblock.Const.ccp = copyn(n, str);
00422 p->constblock.Const.ccp1.blanks = 0;
00423 p->constblock.vtype = TYCHAR;
00424 p->constblock.vleng = (expptr) ICON(n);
00425 }
00426 else
00427 p = (expptr) mkstrcon(0, CNULL);
00428 }
00429 else if(p->constblock.vtype != TYCHAR)
00430 {
00431 execerr("pause/stop argument must be integer or string", CNULL);
00432 p = (expptr) mkstrcon(0, CNULL);
00433 }
00434 }
00435 else p = (expptr) mkstrcon(0, CNULL);
00436
00437 {
00438 expptr subr_call;
00439
00440 subr_call = call1(TYSUBR, (char*)(stop ? "s_stop" : "s_paus"), p);
00441 putexpr( subr_call );
00442 }
00443 }
00444
00445
00446
00447 #define DOINIT par[0]
00448 #define DOLIMIT par[1]
00449 #define DOINCR par[2]
00450
00451
00452
00453
00454 #define VARSTEP 0
00455 #define POSSTEP 1
00456 #define NEGSTEP 2
00457
00458
00459
00460
00461
00462
00463 void
00464 #ifdef KR_headers
00465 exdo(range, loopname, spec)
00466 int range;
00467 Namep loopname;
00468 chainp spec;
00469 #else
00470 exdo(int range, Namep loopname, chainp spec)
00471 #endif
00472
00473
00474 {
00475 register expptr p;
00476 register Namep np;
00477 chainp cp;
00478 register int i;
00479 int dotype;
00480 int incsign;
00481
00482 Addrp dovarp;
00483 expptr doinit;
00484 expptr par[3];
00485
00486 expptr init, test, inc;
00487
00488
00489 test = ENULL;
00490
00491 pushctl(CTLDO);
00492 dorange = ctlstack->dolabel = range;
00493 ctlstack->loopname = loopname;
00494
00495
00496
00497 np = (Namep)spec->datap;
00498 ctlstack->donamep = NULL;
00499 if (!np) {
00500 ctlstack->dowhile = 1;
00501 #if 0
00502 if (loopname) {
00503 if (loopname->vtype == TYUNKNOWN) {
00504 loopname->vdcldone = 1;
00505 loopname->vclass = CLLABEL;
00506 loopname->vprocclass = PLABEL;
00507 loopname->vtype = TYLABEL;
00508 }
00509 if (loopname->vtype == TYLABEL)
00510 if (loopname->vdovar)
00511 dclerr("already in use as a loop name",
00512 loopname);
00513 else
00514 loopname->vdovar = 1;
00515 else
00516 dclerr("already declared; cannot be a loop name",
00517 loopname);
00518 }
00519 #endif
00520 putwhile((expptr)spec->nextp);
00521 NOEXT("do while");
00522 spec->nextp = 0;
00523 frchain(&spec);
00524 return;
00525 }
00526 if(np->vdovar)
00527 {
00528 errstr("nested loops with variable %s", np->fvarname);
00529 ctlstack->donamep = NULL;
00530 return;
00531 }
00532
00533
00534
00535 dovarp = mkplace(np);
00536 if( ! ONEOF(dovarp->vtype, MSKINT|MSKREAL) )
00537 {
00538 err("bad type on do variable");
00539 return;
00540 }
00541 ctlstack->donamep = np;
00542
00543 np->vdovar = YES;
00544
00545
00546
00547
00548 dotype = dovarp->vtype;
00549
00550
00551
00552
00553 for(i=0 , cp = spec->nextp ; cp!=NULL && i<3 ; cp = cp->nextp)
00554 {
00555 p = par[i++] = fixtype((tagptr)cp->datap);
00556 if( ! ONEOF(p->headblock.vtype, MSKINT|MSKREAL) )
00557 {
00558 err("bad type on DO parameter");
00559 return;
00560 }
00561 }
00562
00563 frchain(&spec);
00564 switch(i)
00565 {
00566 case 0:
00567 case 1:
00568 err("too few DO parameters");
00569 return;
00570
00571 default:
00572 err("too many DO parameters");
00573 return;
00574
00575 case 2:
00576 DOINCR = (expptr) ICON(1);
00577
00578 case 3:
00579 break;
00580 }
00581
00582
00583
00584
00585
00586
00587
00588
00589 ctlstack->doinit = 0;
00590 if (ISCONST (DOINIT) || !onetripflag)
00591
00592
00593 doinit = putx (mkconv (dotype, DOINIT));
00594 else {
00595 if (onetripflag)
00596 ctlstack->doinit = doinit = (expptr) mktmp0(dotype, ENULL);
00597 else
00598 doinit = (expptr) mktmp(dotype, ENULL);
00599 puteq (cpexpr (doinit), DOINIT);
00600 }
00601
00602
00603
00604
00605 if( ISCONST(DOLIMIT) )
00606 ctlstack->domax = mkconv(dotype, DOLIMIT);
00607 else {
00608 ctlstack->domax = (expptr) mktmp0(dotype, ENULL);
00609 puteq (cpexpr (ctlstack -> domax), DOLIMIT);
00610 }
00611
00612
00613
00614
00615 if( ISCONST(DOINCR) )
00616 {
00617 ctlstack->dostep = mkconv(dotype, DOINCR);
00618 if( (incsign = conssgn(ctlstack->dostep)) == 0)
00619 err("zero DO increment");
00620 ctlstack->dostepsign = (incsign > 0 ? POSSTEP : NEGSTEP);
00621 }
00622 else
00623 {
00624 ctlstack->dostep = (expptr) mktmp0(dotype, ENULL);
00625 ctlstack->dostepsign = VARSTEP;
00626 puteq (cpexpr (ctlstack -> dostep), DOINCR);
00627 }
00628
00629
00630
00631
00632 switch (ctlstack -> dostepsign) {
00633 case VARSTEP:
00634 test = mkexpr (OPQUEST, mkexpr (OPLT,
00635 cpexpr (ctlstack -> dostep), ICON(0)),
00636 mkexpr (OPCOLON,
00637 mkexpr (OPGE, cpexpr((expptr)dovarp),
00638 cpexpr (ctlstack -> domax)),
00639 mkexpr (OPLE, cpexpr((expptr)dovarp),
00640 cpexpr (ctlstack -> domax))));
00641 break;
00642 case POSSTEP:
00643 test = mkexpr (OPLE, cpexpr((expptr)dovarp),
00644 cpexpr (ctlstack -> domax));
00645 break;
00646 case NEGSTEP:
00647 test = mkexpr (OPGE, cpexpr((expptr)dovarp),
00648 cpexpr (ctlstack -> domax));
00649 break;
00650 default:
00651 erri ("exdo: bad dostepsign '%d'", ctlstack -> dostepsign);
00652 break;
00653 }
00654
00655 if (onetripflag)
00656 test = mkexpr (OPOR, test,
00657 mkexpr (OPEQ, cpexpr((expptr)dovarp), cpexpr (doinit)));
00658 init = mkexpr (OPASSIGN, cpexpr((expptr)dovarp),
00659 ctlstack->doinit ? cpexpr(doinit) : doinit);
00660 inc = mkexpr (OPPLUSEQ, (expptr)dovarp, cpexpr (ctlstack -> dostep));
00661
00662 if (!onetripflag && ISCONST (ctlstack -> domax) && ISCONST (doinit)
00663 && ctlstack -> dostepsign != VARSTEP) {
00664 expptr tester;
00665
00666 tester = mkexpr (OPMINUS, cpexpr (doinit),
00667 cpexpr (ctlstack -> domax));
00668 if (incsign == conssgn (tester))
00669 warn ("DO range never executed");
00670 frexpr (tester);
00671 }
00672
00673 p1_for (init, test, inc);
00674 }
00675
00676 void
00677 #ifdef KR_headers
00678 exenddo(np)
00679 Namep np;
00680 #else
00681 exenddo(Namep np)
00682 #endif
00683 {
00684 Namep np1;
00685 int here;
00686 struct Ctlframe *cf;
00687
00688 if( ctlstack < ctls )
00689 goto misplaced;
00690 here = ctlstack->dolabel;
00691 if (ctlstack->ctltype != CTLDO
00692 || here >= 0 && (!thislabel || thislabel->labelno != here)) {
00693 misplaced:
00694 err("misplaced ENDDO");
00695 return;
00696 }
00697 if (np != ctlstack->loopname) {
00698 if (np1 = ctlstack->loopname)
00699 errstr("expected \"enddo %s\"", np1->fvarname);
00700 else
00701 err("expected unnamed ENDDO");
00702 for(cf = ctls; cf < ctlstack; cf++)
00703 if (cf->ctltype == CTLDO && cf->loopname == np) {
00704 here = cf->dolabel;
00705 break;
00706 }
00707 }
00708 enddo(here);
00709 }
00710
00711 void
00712 #ifdef KR_headers
00713 enddo(here)
00714 int here;
00715 #else
00716 enddo(int here)
00717 #endif
00718 {
00719 register struct Ctlframe *q;
00720 Namep np;
00721 Addrp ap;
00722 register int i;
00723 register expptr e;
00724
00725
00726
00727
00728 while(here == dorange)
00729 {
00730 if(np = ctlstack->donamep)
00731 {
00732 p1for_end ();
00733
00734
00735
00736
00737 if(ap = memversion(np))
00738 puteq((expptr)ap, (expptr)mkplace(np));
00739 for(i = 0 ; i < 4 ; ++i)
00740 ctlstack->ctlabels[i] = 0;
00741 deregister(ctlstack->donamep);
00742 ctlstack->donamep->vdovar = NO;
00743
00744
00745 if (e = ctlstack->dostep)
00746 if (e->tag == TADDR && e->addrblock.istemp)
00747 frtemp((Addrp)e);
00748 else
00749 frexpr(e);
00750 if (e = ctlstack->domax)
00751 if (e->tag == TADDR && e->addrblock.istemp)
00752 frtemp((Addrp)e);
00753 else
00754 frexpr(e);
00755 if (e = ctlstack->doinit)
00756 frtemp((Addrp)e);
00757 }
00758 else if (ctlstack->dowhile)
00759 p1for_end ();
00760
00761
00762
00763
00764 popctl();
00765 poplab();
00766 dorange = 0;
00767 for(q = ctlstack ; q>=ctls ; --q)
00768 if(q->ctltype == CTLDO)
00769 {
00770 dorange = q->dolabel;
00771 break;
00772 }
00773 }
00774 }
00775
00776 void
00777 #ifdef KR_headers
00778 exassign(vname, labelval)
00779 register Namep vname;
00780 struct Labelblock *labelval;
00781 #else
00782 exassign(register Namep vname, struct Labelblock *labelval)
00783 #endif
00784 {
00785 Addrp p;
00786 register Addrp q;
00787 char *fs;
00788 register chainp cp, cpprev;
00789 register ftnint k, stno;
00790
00791 p = mkplace(vname);
00792 if( ! ONEOF(p->vtype, MSKINT|MSKADDR) ) {
00793 err("noninteger assign variable");
00794 return;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806 fs = labelval->fmtstring;
00807 if (!labelval->labdefined || !fs) {
00808
00809 if (vname -> vis_assigned == 0) {
00810 vname -> varxptr.assigned_values = CHNULL;
00811 vname -> vis_assigned = 1;
00812 }
00813
00814
00815
00816 stno = labelval->stateno;
00817 cpprev = 0;
00818 for(k = 0, cp = vname->varxptr.assigned_values;
00819 cp; cpprev = cp, cp = cp->nextp, k++)
00820 if ((ftnint)cp->datap == stno)
00821 break;
00822 if (!cp) {
00823 cp = mkchain((char *)stno, CHNULL);
00824 if (cpprev)
00825 cpprev->nextp = cp;
00826 else
00827 vname->varxptr.assigned_values = cp;
00828 labelval->labused = 1;
00829 }
00830 putout(mkexpr(OPASSIGN, (expptr)p, mkintcon(k)));
00831 }
00832
00833
00834
00835 if (!labelval->labdefined || fs) {
00836
00837 labelval->fmtlabused = 1;
00838 p = ALLOC(Addrblock);
00839 p->tag = TADDR;
00840 p->vtype = TYCHAR;
00841 p->vstg = STGAUTO;
00842 p->memoffset = ICON(0);
00843 fmtname(vname, p);
00844 q = ALLOC(Addrblock);
00845 q->tag = TADDR;
00846 q->vtype = TYCHAR;
00847 q->vstg = STGAUTO;
00848 q->ntempelt = 1;
00849 q->memoffset = ICON(0);
00850 q->uname_tag = UNAM_IDENT;
00851 sprintf(q->user.ident, "fmt_%ld", labelval->stateno);
00852 putout(mkexpr(OPASSIGN, (expptr)p, (expptr)q));
00853 }
00854
00855 }
00856
00857
00858 void
00859 #ifdef KR_headers
00860 exarif(expr, neglab, zerlab, poslab)
00861 expptr expr;
00862 struct Labelblock *neglab;
00863 struct Labelblock *zerlab;
00864 struct Labelblock *poslab;
00865 #else
00866 exarif(expptr expr, struct Labelblock *neglab, struct Labelblock *zerlab, struct Labelblock *poslab)
00867 #endif
00868 {
00869 ftnint lm, lz, lp;
00870
00871 lm = neglab->stateno;
00872 lz = zerlab->stateno;
00873 lp = poslab->stateno;
00874 expr = fixtype(expr);
00875
00876 if( ! ONEOF(expr->headblock.vtype, MSKINT|MSKREAL) )
00877 {
00878 err("invalid type of arithmetic if expression");
00879 frexpr(expr);
00880 }
00881 else
00882 {
00883 if (lm == lz && lz == lp)
00884 exgoto (neglab);
00885 else if(lm == lz)
00886 exar2(OPLE, expr, neglab, poslab);
00887 else if(lm == lp)
00888 exar2(OPNE, expr, neglab, zerlab);
00889 else if(lz == lp)
00890 exar2(OPGE, expr, zerlab, neglab);
00891 else {
00892 expptr t;
00893
00894 if (!addressable (expr)) {
00895 t = (expptr) mktmp(expr -> headblock.vtype, ENULL);
00896 expr = mkexpr (OPASSIGN, cpexpr (t), expr);
00897 } else
00898 t = (expptr) cpexpr (expr);
00899
00900 p1_if(putx(fixtype(mkexpr (OPLT, expr, ICON (0)))));
00901 exgoto(neglab);
00902 p1_elif (mkexpr (OPEQ, t, ICON (0)));
00903 exgoto(zerlab);
00904 p1_else ();
00905 exgoto(poslab);
00906 p1else_end ();
00907 }
00908 }
00909 }
00910
00911
00912
00913
00914
00915
00916
00917 LOCAL void
00918 #ifdef KR_headers
00919 exar2(op, e, l1, l2)
00920 int op;
00921 expptr e;
00922 struct Labelblock *l1;
00923 struct Labelblock *l2;
00924 #else
00925 exar2(int op, expptr e, struct Labelblock *l1, struct Labelblock *l2)
00926 #endif
00927 {
00928 expptr comp;
00929
00930 comp = mkexpr (op, e, ICON (0));
00931 p1_if(putx(fixtype(comp)));
00932 exgoto(l1);
00933 p1_else ();
00934 exgoto(l2);
00935 p1else_end ();
00936 }
00937
00938
00939
00940
00941
00942 void
00943 #ifdef KR_headers
00944 exreturn(p)
00945 register expptr p;
00946 #else
00947 exreturn(register expptr p)
00948 #endif
00949 {
00950 if(procclass != CLPROC)
00951 warn("RETURN statement in main or block data");
00952 if(p && (proctype!=TYSUBR || procclass!=CLPROC) )
00953 {
00954 err("alternate return in nonsubroutine");
00955 p = 0;
00956 }
00957
00958 if (p || proctype == TYSUBR) {
00959 if (p == ENULL) p = ICON (0);
00960 p = mkconv (TYLONG, fixtype (p));
00961 p1_subr_ret (p);
00962 }
00963 else
00964 p1_subr_ret((expptr)retslot);
00965 }
00966
00967
00968 void
00969 #ifdef KR_headers
00970 exasgoto(labvar)
00971 Namep labvar;
00972 #else
00973 exasgoto(Namep labvar)
00974 #endif
00975 {
00976 register Addrp p;
00977
00978 p = mkplace(labvar);
00979 if( ! ISINT(p->vtype) )
00980 err("assigned goto variable must be integer");
00981 else {
00982 p1_asgoto (p);
00983 }
00984 }