#include "defs.h"#include "p1defs.h"#include "names.h"Include dependency graph for exec.c:

Go to the source code of this file.
Defines | |
| #define | DOINIT par[0] |
| #define | DOLIMIT par[1] |
| #define | DOINCR par[2] |
| #define | VARSTEP 0 |
| #define | POSSTEP 1 |
| #define | NEGSTEP 2 |
Functions | |
| static void exar2 | Argdcl ((int, tagptr, struct Labelblock *, struct Labelblock *)) |
| static void popctl | Argdcl ((void)) |
| static void pushctl | Argdcl ((int)) |
| void | exif (expptr p) |
| void | exelif (expptr p) |
| void | exelse (Void) |
| void | exendif () |
| void | new_endif () |
| LOCAL void | pushctl (int code) |
| LOCAL void | popctl (Void) |
| LOCAL void | poplab (Void) |
| void | exgoto (struct Labelblock *lab) |
| static expptr | cktype1 (expptr p) |
| void | exequals (register struct Primblock *lp, register expptr rp) |
| void | mkstfunct (struct Primblock *lp, expptr rp) |
| static void | mixed_type (Namep np) |
| void | excall (Namep name, struct Listblock *args, int nstars, struct Labelblock **labels) |
| void | exstop (int stop, register expptr p) |
| void | exdo (int range, Namep loopname, chainp spec) |
| void | exenddo (Namep np) |
| void | enddo (int here) |
| void | exassign (register Namep vname, struct Labelblock *labelval) |
| void | exarif (expptr expr, struct Labelblock *neglab, struct Labelblock *zerlab, struct Labelblock *poslab) |
| LOCAL void | exar2 (int op, expptr e, struct Labelblock *l1, struct Labelblock *l2) |
| void | exreturn (register expptr p) |
| void | exasgoto (Namep labvar) |
Variables | |
| long | laststfcn = -1 |
| long | thisstno |
| int | doing_stmtfcn |
| static void pushctl Argdcl | ( | (int) | ) | [static] |
| static void popctl Argdcl | ( | (void) | ) | [static] |
| static void exar2 Argdcl | ( | (int, tagptr, struct Labelblock *, struct Labelblock *) | ) | [static] |
Definition at line 191 of file exec.c.
References badtag(), Chain::datap, Primblock::fcharp, free(), mkexpr(), Chain::nextp, p, Expression::primblock, t, TADDR, TCONST, TERROR, TEXPR, TLIST, and TPRIM.
Referenced by exequals().
00193 { 00194 /* Do things omitted because we might have been parsing a */ 00195 /* statement function... Check types and fold constants. */ 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 /* This case means that fixexpr can't call fixtype with any expr, 00210 only a subexpr of its parameter. */ 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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void enddo | ( | int | here | ) |
Definition at line 716 of file exec.c.
References Expression::addrblock, Ctlframe::ctlabels, CTLDO, ctls, ctlstack, Ctlframe::ctltype, deregister(), Ctlframe::doinit, Ctlframe::dolabel, Ctlframe::domax, Ctlframe::donamep, dorange, Ctlframe::dostep, Ctlframe::dowhile, frexpr(), frtemp(), i, Addrblock::istemp, memversion(), mkplace(), NO, p1for_end(), popctl(), poplab(), puteq(), TADDR, Expression::tag, and Nameblock::vdovar.
Referenced by doiolist(), and yyparse().
00718 { 00719 register struct Ctlframe *q; 00720 Namep np; /* name of the current DO index */ 00721 Addrp ap; 00722 register int i; 00723 register expptr e; 00724 00725 /* Many DO's can end at the same statement, so keep looping over all 00726 nested indicies */ 00727 00728 while(here == dorange) 00729 { 00730 if(np = ctlstack->donamep) 00731 { 00732 p1for_end (); 00733 00734 /* Now we're done with all of the tests, and the loop has terminated. 00735 Store the index value back in long-term memory */ 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 /* ctlstack->dostep and ctlstack->domax can be zero */ 00744 /* with sufficiently bizarre (erroneous) syntax */ 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 /* Set dorange to the closing label of the next most enclosing DO loop 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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| LOCAL void exar2 | ( | int | op, | |
| expptr | e, | |||
| struct Labelblock * | l1, | |||
| struct Labelblock * | l2 | |||
| ) |
Definition at line 925 of file exec.c.
References comp, exgoto(), fixtype(), ICON, mkexpr(), p1_else(), p1_if(), p1else_end(), and putx().
Referenced by exarif().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exarif | ( | expptr | expr, | |
| struct Labelblock * | neglab, | |||
| struct Labelblock * | zerlab, | |||
| struct Labelblock * | poslab | |||
| ) |
Definition at line 866 of file exec.c.
References addressable(), cpexpr(), ENULL, err, exar2(), exgoto(), expr(), fixtype(), frexpr(), ICON, lp, mkexpr(), mktmp(), MSKINT, MSKREAL, ONEOF, OPASSIGN, OPEQ, OPGE, OPLE, OPLT, OPNE, p1_elif(), p1_else(), p1_if(), p1else_end(), putx(), Labelblock::stateno, and t.
Referenced by yyparse().
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 } /* else */ 00908 } 00909 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exasgoto | ( | Namep | labvar | ) |
Definition at line 973 of file exec.c.
References err, ISINT, mkplace(), p, and p1_asgoto().
Referenced by yyparse().
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 } /* else */ 00984 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exassign | ( | register Namep | vname, | |
| struct Labelblock * | labelval | |||
| ) |
Definition at line 782 of file exec.c.
References ALLOC, CHNULL, Chain::datap, err, Labelblock::fmtlabused, fmtname(), Labelblock::fmtstring, ICON, Addrblock::ident, Labelblock::labdefined, Labelblock::labused, Addrblock::memoffset, mkchain(), mkexpr(), mkintcon(), mkplace(), MSKADDR, MSKINT, Chain::nextp, Addrblock::ntempelt, ONEOF, OPASSIGN, p, putout(), Labelblock::stateno, STGAUTO, stno, TADDR, Addrblock::tag, TYCHAR, UNAM_IDENT, Addrblock::uname_tag, Addrblock::user, Addrblock::vstg, and Addrblock::vtype.
Referenced by yyparse().
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 /* If the label hasn't been defined, then we do things twice: 00798 * once for an executable stmt label, once for a format 00799 */ 00800 00801 /* code for executable label... */ 00802 00803 /* Now store the assigned value in a list associated with this variable. 00804 This will be used later to generate a switch() statement in the C output */ 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 /* don't duplicate labels... */ 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 /* Code for FORMAT label... */ 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 } /* exassign */
Here is the call graph for this function:

Here is the caller graph for this function:

| void excall | ( | Namep | name, | |
| struct Listblock * | args, | |||
| int | nstars, | |||
| struct Labelblock ** | labels | |||
| ) |
Definition at line 362 of file exec.c.
References args, CHNULL, fixtype(), frexpr(), mixed_type(), mkfunct(), mkprim(), name, p, putcmgo(), putexpr(), putx(), settype(), TERROR, TYINT, TYSUBR, and TYUNKNOWN.
Referenced by yyparse().
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 /* Subroutines and their identifiers acquire the type INT */ 00383 00384 p->exprblock.vtype = p->exprblock.leftp->headblock.vtype = TYINT; 00385 00386 /* Handle the alternate return mechanism */ 00387 00388 if(nstars > 0) 00389 putcmgo(putx(fixtype(p)), nstars, labels); 00390 else 00391 putexpr(p); 00392 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 470 of file exec.c.
References conssgn(), cpexpr(), CTLDO, ctlstack, Chain::datap, dclerr(), DOINCR, DOINIT, Ctlframe::doinit, Ctlframe::dolabel, DOLIMIT, Ctlframe::domax, Ctlframe::donamep, dorange, Ctlframe::dostep, Ctlframe::dostepsign, Ctlframe::dowhile, ENULL, err, erri(), errstr(), fixtype(), frchain(), frexpr(), Nameblock::fvarname, i, ICON, init, ISCONST, Ctlframe::loopname, mkconv(), mkexpr(), mkplace(), mktmp(), mktmp0(), MSKINT, MSKREAL, NEGSTEP, Chain::nextp, NOEXT, NULL, ONEOF, onetripflag, OPASSIGN, OPCOLON, OPEQ, OPGE, OPLE, OPLT, OPMINUS, OPOR, OPPLUSEQ, OPQUEST, p, p1_for(), POSSTEP, pushctl(), puteq(), putwhile(), putx(), test, TYLABEL, TYUNKNOWN, VARSTEP, Nameblock::vclass, Nameblock::vdcldone, Nameblock::vdovar, Nameblock::vprocclass, Addrblock::vtype, Nameblock::vtype, warn(), and YES.
Referenced by doiolist(), and yyparse().
00474 { 00475 register expptr p; 00476 register Namep np; 00477 chainp cp; /* loops over the fields in spec */ 00478 register int i; 00479 int dotype; /* type of the index variable */ 00480 int incsign; /* sign of the increment, if it's constant 00481 */ 00482 Addrp dovarp; /* loop index variable */ 00483 expptr doinit; /* constant or register for init param */ 00484 expptr par[3]; /* local specification parameters */ 00485 00486 expptr init, test, inc; /* Expressions in the resulting FOR loop */ 00487 00488 00489 test = ENULL; 00490 00491 pushctl(CTLDO); 00492 dorange = ctlstack->dolabel = range; 00493 ctlstack->loopname = loopname; 00494 00495 /* Declare the loop index */ 00496 00497 np = (Namep)spec->datap; 00498 ctlstack->donamep = NULL; 00499 if (!np) { /* do while */ 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 /* Create a memory-resident version of the index variable */ 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 /* Now dovarp points to the index to be used within the loop, dostgp 00546 points to the one which may need to be stored */ 00547 00548 dotype = dovarp->vtype; 00549 00550 /* Count the input specifications and type-check each one independently; 00551 this just eliminates non-numeric values from the specification */ 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 /* Now all of the local specification fields are set, but their types are 00584 not yet consistent */ 00585 00586 /* Declare the loop initialization value, casting it properly and declaring a 00587 register if need be */ 00588 00589 ctlstack->doinit = 0; 00590 if (ISCONST (DOINIT) || !onetripflag) 00591 /* putx added 6-29-89 (mwm), not sure if fixtype is required, but I doubt it 00592 since mkconv is called just before */ 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 } /* else */ 00601 00602 /* Declare the loop ending value, casting it to the type of the index 00603 variable */ 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 } /* else */ 00611 00612 /* Declare the loop increment value, casting it to the type of the index 00613 variable */ 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 /* All data is now properly typed and in the ctlstack, except for the 00630 initial value. Assignments of temps have been generated already */ 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 } /* switch (ctlstack -> dostepsign) */ 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 } /* if !onetripflag && */ 00672 00673 p1_for (init, test, inc); 00674 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exelif | ( | expptr | p | ) |
Definition at line 53 of file exec.c.
References CNULL, CTLIF, CTLIFX, ctlstack, Ctlframe::ctltype, execerr(), p, and putif().
Referenced by yyparse().
00055 { 00056 if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX) 00057 putif(p, 1); /* 1 ==> elseif */ 00058 else 00059 execerr("elseif out of place", CNULL); 00060 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exelse | ( | Void | ) |
Definition at line 66 of file exec.c.
References CTLELSE, CTLIF, CTLIFX, ctlstack, Ctlframe::ctltype, and p1_else().
Referenced by yyparse().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exenddo | ( | Namep | np | ) |
Definition at line 681 of file exec.c.
References CTLDO, ctls, ctlstack, Ctlframe::ctltype, Ctlframe::dolabel, err, errstr(), Nameblock::fvarname, Labelblock::labelno, Ctlframe::loopname, and thislabel.
Referenced by yyparse().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exendif | ( | ) |
Definition at line 83 of file exec.c.
References CNULL, CTLELSE, CTLIF, CTLIFX, ctlstack, Ctlframe::ctltype, execerr(), p1_endif(), p1else_end(), and popctl().
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 }
Here is the call graph for this function:

Definition at line 244 of file exec.c.
References cktype1(), CLVAR, enddcl(), err, errstr(), fixtype(), frexpr(), INDATA, INEXEC, keepsubs, mklhs(), mkstfunct(), parstate, puteq(), TPRIM, and TYSUBR.
Referenced by yyparse().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void exgoto | ( | struct Labelblock * | lab | ) |
Definition at line 179 of file exec.c.
References Labelblock::labused, p1_goto(), and Labelblock::stateno.
Referenced by endio(), exar2(), exarif(), putiocall(), and yyparse().
Here is the call graph for this function:

Here is the caller graph for this function:

| void exif | ( | expptr | p | ) |
| void exreturn | ( | register expptr | p | ) |
Definition at line 947 of file exec.c.
References CLPROC, ENULL, err, fixtype(), ICON, mkconv(), p1_subr_ret(), procclass, proctype, retslot, TYLONG, TYSUBR, and warn().
Referenced by yyparse().
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 } /* if p || proctype == TYSUBR */ 00963 else 00964 p1_subr_ret((expptr)retslot); 00965 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 401 of file exec.c.
References call1(), CNULL, convic(), copyn(), execerr(), frexpr(), ICON, ISCONST, ISINT, mkstrcon(), n, putexpr(), str, TYCHAR, and TYSUBR.
Referenced by yyparse().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void mixed_type | ( | Namep | np | ) | [static] |
Definition at line 345 of file exec.c.
References buf, ftn_types, Nameblock::fvarname, Nameblock::vtype, and warn().
Referenced by excall().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 290 of file exec.c.
References args, CHNULL, CLPROC, CLUNKNOWN, dclerr(), err, impldcl(), lp, mkchain(), p, PSTFUNCT, STGSTFUNCT, thisstno, TPRIM, TYCHAR, Nameblock::varxptr, Nameblock::vclass, Nameblock::vleng, Nameblock::vprocclass, Nameblock::vstfdesc, Nameblock::vstg, and Nameblock::vtype.
Referenced by exequals().
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 /* Set the type of the function */ 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 /* It is an error for the formal parameters to have arguments or 00320 subscripts */ 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 /* Replace the name on the left-hand side */ 00332 00333 args->datap = (char *)p->namep; 00334 vardcl(p -> namep); 00335 free((char *)p); 00336 } 00337 doing_stmtfcn = 0; 00338 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void new_endif | ( | ) |
Definition at line 107 of file exec.c.
References CTLIF, CTLIFX, ctlstack, Ctlframe::ctltype, err, and pushctl().
00109 { 00110 if (ctlstack->ctltype == CTLIF || ctlstack->ctltype == CTLIFX) 00111 pushctl(CTLIFX); 00112 else 00113 err("new_endif bug"); 00114 }
Here is the call graph for this function:

| LOCAL void popctl | ( | Void | ) |
| LOCAL void poplab | ( | Void | ) |
Definition at line 153 of file exec.c.
References blklevel, highlabtab, labeltab, lp, and YES.
Referenced by enddo().
00154 { 00155 register struct Labelblock *lp; 00156 00157 for(lp = labeltab ; lp < highlabtab ; ++lp) 00158 if(lp->labdefined) 00159 { 00160 /* mark all labels in inner blocks unreachable */ 00161 if(lp->blklevel > (unsigned int)(blklevel)) 00162 lp->labinacc = YES; 00163 } 00164 else if(lp->blklevel > (unsigned int)(blklevel)) 00165 { 00166 /* move all labels referred to in inner blocks out a level */ 00167 lp->blklevel = blklevel; 00168 } 00169 }
Here is the caller graph for this function:

| LOCAL void pushctl | ( | int | code | ) |
Definition at line 124 of file exec.c.
References blklevel, Ctlframe::ctlabels, ctlstack, Ctlframe::ctltype, Ctlframe::domax, Ctlframe::dostep, Ctlframe::dowhile, i, lastctl, many(), and maxctl.
Referenced by exdo(), exif(), and new_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; /* in case of errors */ 00136 ++blklevel; 00137 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.5.1