exec.c File Reference

#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


Define Documentation

#define DOINCR   par[2]

Definition at line 449 of file exec.c.

Referenced by exdo().

#define DOINIT   par[0]

Definition at line 447 of file exec.c.

Referenced by exdo().

#define DOLIMIT   par[1]

Definition at line 448 of file exec.c.

Referenced by exdo().

#define NEGSTEP   2

Definition at line 456 of file exec.c.

Referenced by exdo().

#define POSSTEP   1

Definition at line 455 of file exec.c.

Referenced by exdo().

#define VARSTEP   0

Definition at line 454 of file exec.c.

Referenced by exdo().


Function Documentation

static void pushctl Argdcl ( (int  )  [static]

static void popctl Argdcl ( (void)   )  [static]

static void exar2 Argdcl ( (int, tagptr, struct Labelblock *, struct Labelblock *)   )  [static]

static expptr cktype1 ( expptr  p  )  [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:

void exdo ( int  range,
Namep  loopname,
chainp  spec 
)

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:

void exequals ( register struct Primblock lp,
register expptr  rp 
)

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().

00181 {
00182         lab->labused = 1;
00183         p1_goto (lab -> stateno);
00184 }

Here is the call graph for this function:

Here is the caller graph for this function:

void exif ( expptr  p  ) 

Definition at line 40 of file exec.c.

References CTLIF, p, pushctl(), and putif().

Referenced by endio(), putiocall(), and yyparse().

00042 {
00043     pushctl(CTLIF);
00044     putif(p, 0);        /* 0 => if, not elseif */
00045 }

Here is the call graph for this function:

Here is the caller graph for this function:

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:

void exstop ( int  stop,
register expptr  p 
)

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:

void mkstfunct ( struct Primblock lp,
expptr  rp 
)

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   ) 

Definition at line 141 of file exec.c.

References blklevel, ctls, ctlstack, and Fatal().

Referenced by enddo(), and exendif().

00142 {
00143         if( ctlstack-- < ctls )
00144                 Fatal("control stack empty");
00145         --blklevel;
00146 }

Here is the call graph for this function:

Here is the caller graph for this function:

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:


Variable Documentation

int doing_stmtfcn

Definition at line 282 of file exec.c.

Referenced by vardcl().

long laststfcn = -1

Definition at line 281 of file exec.c.

Referenced by yyparse().

long thisstno

Definition at line 281 of file exec.c.

Referenced by mkstfunct(), and yyparse().


Generated on Sun Mar 4 15:06:51 2007 for Scilab [trunk] by  doxygen 1.5.1