putpcc.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990-1996, 2000-2001 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 /* INTERMEDIATE CODE GENERATION FOR S. C. JOHNSON C COMPILERS */
00025 /* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */
00026 
00027 #include "defs.h"
00028 #include "pccdefs.h"
00029 #include "output.h"             /* for nice_printf */
00030 #include "names.h"
00031 #include "p1defs.h"
00032 
00033 static Addrp intdouble Argdcl((Addrp));
00034 static Addrp putcx1 Argdcl((tagptr));
00035 static tagptr putaddr Argdcl((tagptr));
00036 static tagptr putcall Argdcl((tagptr, Addrp*));
00037 static tagptr putcat Argdcl((tagptr, tagptr));
00038 static Addrp putch1 Argdcl((tagptr));
00039 static tagptr putchcmp Argdcl((tagptr));
00040 static tagptr putcheq Argdcl((tagptr));
00041 static void putct1 Argdcl((tagptr, Addrp, Addrp, ptr));
00042 static tagptr putcxcmp Argdcl((tagptr));
00043 static Addrp putcxeq Argdcl((tagptr));
00044 static tagptr putmnmx Argdcl((tagptr));
00045 static tagptr putop Argdcl((tagptr));
00046 static tagptr putpower Argdcl((tagptr));
00047 static long p1_where;
00048 
00049 extern int init_ac[TYSUBR+1];
00050 extern int ops2[];
00051 extern int proc_argchanges, proc_protochanges;
00052 extern int krparens;
00053 
00054 #define P2BUFFMAX 128
00055 
00056 /* Puthead -- output the header information about subroutines, functions
00057    and entry points */
00058 
00059  void
00060 #ifdef KR_headers
00061 puthead(s, Class)
00062         char *s;
00063         int Class;
00064 #else
00065 puthead(char *s, int Class)
00066 #endif
00067 {
00068         if (headerdone == NO) {
00069                 if (Class == CLMAIN)
00070                         s = "MAIN__";
00071                 p1_head (Class, s);
00072                 headerdone = YES;
00073                 }
00074 }
00075 
00076  void
00077 #ifdef KR_headers
00078 putif(p, else_if_p)
00079         register expptr p;
00080         int else_if_p;
00081 #else
00082 putif(register expptr p, int else_if_p)
00083 #endif
00084 {
00085         int k, n;
00086 
00087         if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype )) )
00088         {
00089                 if(k != TYERROR)
00090                         err("non-logical expression in IF statement");
00091                 }
00092         else {
00093                 if (else_if_p) {
00094                         if (ei_next >= ei_last)
00095                                 {
00096                                 k = ei_last - ei_first;
00097                                 n = k + 100;
00098                                 ei_next = mem(n,0);
00099                                 ei_last = ei_first + n;
00100                                 if (k)
00101                                         memcpy(ei_next, ei_first, k);
00102                                 ei_first =  ei_next;
00103                                 ei_next += k;
00104                                 ei_last = ei_first + n;
00105                                 }
00106                         p = putx(p);
00107                         if (*ei_next++ = ftell(pass1_file) > p1_where) {
00108                                 p1_if(p);
00109                                 new_endif();
00110                                 }
00111                         else
00112                                 p1_elif(p);
00113                         }
00114                 else {
00115                         p = putx(p);
00116                         p1_if(p);
00117                         }
00118                 }
00119         }
00120 
00121  void
00122 #ifdef KR_headers
00123 putout(p)
00124         expptr p;
00125 #else
00126 putout(expptr p)
00127 #endif
00128 {
00129         p1_expr (p);
00130 
00131 /* Used to make temporaries in holdtemps available here, but they */
00132 /* may be reused too soon (e.g. when multiple **'s are involved). */
00133 }
00134 
00135 
00136  void
00137 #ifdef KR_headers
00138 putcmgo(index, nlab, labs)
00139         expptr index;
00140         int nlab;
00141         struct Labelblock **labs;
00142 #else
00143 putcmgo(expptr index, int nlab, struct Labelblock **labs)
00144 #endif
00145 {
00146         if(! ISINT(index->headblock.vtype) )
00147         {
00148                 execerr("computed goto index must be integer", CNULL);
00149                 return;
00150         }
00151 
00152         p1comp_goto (index, nlab, labs);
00153 }
00154 
00155  static expptr
00156 #ifdef KR_headers
00157 krput(p)
00158         register expptr p;
00159 #else
00160 krput(register expptr p)
00161 #endif
00162 {
00163         register expptr e, e1;
00164         register unsigned op;
00165         int t = krparens == 2 ? TYDREAL : p->exprblock.vtype;
00166 
00167         op = p->exprblock.opcode;
00168         e = p->exprblock.leftp;
00169         if (e->tag == TEXPR && e->exprblock.opcode == op) {
00170                 e1 = (expptr)mktmp(t, ENULL);
00171                 putout(putassign(cpexpr(e1), e));
00172                 p->exprblock.leftp = e1;
00173                 }
00174         else
00175                 p->exprblock.leftp = putx(e);
00176 
00177         e = p->exprblock.rightp;
00178         if (e->tag == TEXPR && e->exprblock.opcode == op) {
00179                 e1 = (expptr)mktmp(t, ENULL);
00180                 putout(putassign(cpexpr(e1), e));
00181                 p->exprblock.rightp = e1;
00182                 }
00183         else
00184                 p->exprblock.rightp = putx(e);
00185         return p;
00186         }
00187 
00188  expptr
00189 #ifdef KR_headers
00190 putx(p)
00191         register expptr p;
00192 #else
00193 putx(register expptr p)
00194 #endif
00195 {
00196         int opc;
00197         int k;
00198 
00199         if (p)
00200           switch(p->tag)
00201         {
00202         case TERROR:
00203                 break;
00204 
00205         case TCONST:
00206                 switch(p->constblock.vtype)
00207                 {
00208                 case TYLOGICAL1:
00209                 case TYLOGICAL2:
00210                 case TYLOGICAL:
00211 #ifdef TYQUAD
00212                 case TYQUAD:
00213 #endif
00214                 case TYLONG:
00215                 case TYSHORT:
00216                 case TYINT1:
00217                         break;
00218 
00219                 case TYADDR:
00220                         break;
00221                 case TYREAL:
00222                 case TYDREAL:
00223 
00224 /* Don't write it out to the p2 file, since you'd need to call putconst,
00225    which is just what we need to avoid in the translator */
00226 
00227                         break;
00228                 default:
00229                         p = putx( (expptr)putconst((Constp)p) );
00230                         break;
00231                 }
00232                 break;
00233 
00234         case TEXPR:
00235                 switch(opc = p->exprblock.opcode)
00236                 {
00237                 case OPCALL:
00238                 case OPCCALL:
00239                         if( ISCOMPLEX(p->exprblock.vtype) )
00240                                 p = putcxop(p);
00241                         else    p = putcall(p, (Addrp *)NULL);
00242                         break;
00243 
00244                 case OPMIN:
00245                 case OPMAX:
00246                         p = putmnmx(p);
00247                         break;
00248 
00249 
00250                 case OPASSIGN:
00251                         if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
00252                             || ISCOMPLEX(p->exprblock.rightp->headblock.vtype)) {
00253                                 (void) putcxeq(p);
00254                                 p = ENULL;
00255                         } else if( ISCHAR(p) )
00256                                 p = putcheq(p);
00257                         else
00258                                 goto putopp;
00259                         break;
00260 
00261                 case OPEQ:
00262                 case OPNE:
00263                         if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
00264                             ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
00265                         {
00266                                 p = putcxcmp(p);
00267                                 break;
00268                         }
00269                 case OPLT:
00270                 case OPLE:
00271                 case OPGT:
00272                 case OPGE:
00273                         if(ISCHAR(p->exprblock.leftp))
00274                         {
00275                                 p = putchcmp(p);
00276                                 break;
00277                         }
00278                         goto putopp;
00279 
00280                 case OPPOWER:
00281                         p = putpower(p);
00282                         break;
00283 
00284                 case OPSTAR:
00285                         /*   m * (2**k) -> m<<k   */
00286                         if(INT(p->exprblock.leftp->headblock.vtype) &&
00287                             ISICON(p->exprblock.rightp) &&
00288                             ( (k = log_2(p->exprblock.rightp->constblock.Const.ci))>0) )
00289                         {
00290                                 p->exprblock.opcode = OPLSHIFT;
00291                                 frexpr(p->exprblock.rightp);
00292                                 p->exprblock.rightp = ICON(k);
00293                                 goto putopp;
00294                         }
00295                         if (krparens && ISREAL(p->exprblock.vtype))
00296                                 return krput(p);
00297 
00298                 case OPMOD:
00299                         goto putopp;
00300                 case OPPLUS:
00301                         if (krparens && ISREAL(p->exprblock.vtype))
00302                                 return krput(p);
00303                 case OPMINUS:
00304                 case OPSLASH:
00305                 case OPNEG:
00306                 case OPNEG1:
00307                 case OPABS:
00308                 case OPDABS:
00309                         if( ISCOMPLEX(p->exprblock.vtype) )
00310                                 p = putcxop(p);
00311                         else    goto putopp;
00312                         break;
00313 
00314                 case OPCONV:
00315                         if( ISCOMPLEX(p->exprblock.vtype) )
00316                                 p = putcxop(p);
00317                         else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
00318                         {
00319                                 p = putx( mkconv(p->exprblock.vtype,
00320                                     (expptr)realpart(putcx1(p->exprblock.leftp))));
00321                         }
00322                         else    goto putopp;
00323                         break;
00324 
00325                 case OPNOT:
00326                 case OPOR:
00327                 case OPAND:
00328                 case OPEQV:
00329                 case OPNEQV:
00330                 case OPADDR:
00331                 case OPPLUSEQ:
00332                 case OPSTAREQ:
00333                 case OPCOMMA:
00334                 case OPQUEST:
00335                 case OPCOLON:
00336                 case OPBITOR:
00337                 case OPBITAND:
00338                 case OPBITXOR:
00339                 case OPBITNOT:
00340                 case OPLSHIFT:
00341                 case OPRSHIFT:
00342                 case OPASSIGNI:
00343                 case OPIDENTITY:
00344                 case OPCHARCAST:
00345                 case OPMIN2:
00346                 case OPMAX2:
00347                 case OPDMIN:
00348                 case OPDMAX:
00349                 case OPBITTEST:
00350                 case OPBITCLR:
00351                 case OPBITSET:
00352 #ifdef TYQUAD
00353                 case OPQBITSET:
00354                 case OPQBITCLR:
00355 #endif
00356 putopp:
00357                         p = putop(p);
00358                         break;
00359 
00360                 case OPCONCAT:
00361                         /* weird things like ichar(a//a) */
00362                         p = (expptr)putch1(p);
00363                         break;
00364 
00365                 default:
00366                         badop("putx", opc);
00367                         p = errnode ();
00368                 }
00369                 break;
00370 
00371         case TADDR:
00372                 p = putaddr(p);
00373                 break;
00374 
00375         default:
00376                 badtag("putx", p->tag);
00377                 p = errnode ();
00378         }
00379 
00380         return p;
00381 }
00382 
00383 
00384 
00385  LOCAL expptr
00386 #ifdef KR_headers
00387 putop(p)
00388         expptr p;
00389 #else
00390 putop(expptr p)
00391 #endif
00392 {
00393         expptr lp, tp;
00394         int pt, lt, lt1;
00395         int comma;
00396         char *hsave;
00397 
00398         switch(p->exprblock.opcode)     /* check for special cases and rewrite */
00399         {
00400         case OPCONV:
00401                 pt = p->exprblock.vtype;
00402                 lp = p->exprblock.leftp;
00403                 lt = lp->headblock.vtype;
00404 
00405 /* Simplify nested type casts */
00406 
00407                 while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
00408                     ( (ISREAL(pt)&&ONEOF(lt,MSKREAL|MSKCOMPLEX)) ||
00409                     (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
00410                 {
00411                         if(pt==TYDREAL && lt==TYREAL)
00412                         {
00413                                 if(lp->tag==TEXPR
00414                                 && lp->exprblock.opcode == OPCONV) {
00415                                     lt1 = lp->exprblock.leftp->headblock.vtype;
00416                                     if (lt1 == TYDREAL) {
00417                                         lp->exprblock.leftp =
00418                                                 putx(lp->exprblock.leftp);
00419                                         return p;
00420                                         }
00421                                     if (lt1 == TYDCOMPLEX) {
00422                                         lp->exprblock.leftp = putx(
00423                                                 (expptr)realpart(
00424                                                 putcx1(lp->exprblock.leftp)));
00425                                         return p;
00426                                         }
00427                                     }
00428                                 break;
00429                         }
00430                         else if (ISREAL(pt) && ISCOMPLEX(lt)) {
00431                                 p->exprblock.leftp = putx(mkconv(pt,
00432                                         (expptr)realpart(
00433                                                 putcx1(p->exprblock.leftp))));
00434                                 break;
00435                                 }
00436                         if(lt==TYCHAR && lp->tag==TEXPR &&
00437                             lp->exprblock.opcode==OPCALL)
00438                         {
00439 
00440 /* May want to make a comma expression here instead.  I had one, but took
00441    it out for my convenience, not for the convenience of the end user */
00442 
00443                                 putout (putcall (lp, (Addrp *) &(p ->
00444                                     exprblock.leftp)));
00445                                 return putop (p);
00446                         }
00447                         if (lt == TYCHAR) {
00448                                 if (ISCONST(p->exprblock.leftp)
00449                                  && ISNUMERIC(p->exprblock.vtype)) {
00450                                         hsave = halign;
00451                                         halign = 0;
00452                                         p->exprblock.leftp = putx((expptr)
00453                                                 putconst((Constp)
00454                                                         p->exprblock.leftp));
00455                                         halign = hsave;
00456                                         }
00457                                 else
00458                                         p->exprblock.leftp =
00459                                                 putx(p->exprblock.leftp);
00460                                 return p;
00461                                 }
00462                         if (pt < lt && ONEOF(lt,MSKINT|MSKREAL))
00463                                 break;
00464                         frexpr(p->exprblock.vleng);
00465                         free( (charptr) p );
00466                         p = lp;
00467                         if (p->tag != TEXPR)
00468                                 goto retputx;
00469                         pt = lt;
00470                         lp = p->exprblock.leftp;
00471                         lt = lp->headblock.vtype;
00472                 } /* while */
00473                 if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
00474                         break;
00475  retputx:
00476                 return putx(p);
00477 
00478         case OPADDR:
00479                 comma = NO;
00480                 lp = p->exprblock.leftp;
00481                 free( (charptr) p );
00482                 if(lp->tag != TADDR)
00483                 {
00484                         tp = (expptr)
00485                             mktmp(lp->headblock.vtype,lp->headblock.vleng);
00486                         p = putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
00487                         lp = tp;
00488                         comma = YES;
00489                 }
00490                 if(comma)
00491                         p = mkexpr(OPCOMMA, p, putaddr(lp));
00492                 else
00493                         p = (expptr)putaddr(lp);
00494                 return p;
00495 
00496         case OPASSIGN:
00497         case OPASSIGNI:
00498         case OPLT:
00499         case OPLE:
00500         case OPGT:
00501         case OPGE:
00502         case OPEQ:
00503         case OPNE:
00504             ;
00505         }
00506 
00507         if( ops2[p->exprblock.opcode] <= 0)
00508                 badop("putop", p->exprblock.opcode);
00509         lp = p->exprblock.leftp = putx(p->exprblock.leftp);
00510         if (p -> exprblock.rightp) {
00511                 tp = p->exprblock.rightp = putx(p->exprblock.rightp);
00512                 if (tp && ISCONST(tp) && ISCONST(lp))
00513                         p = fold(p);
00514                 }
00515         return p;
00516 }
00517 
00518  LOCAL expptr
00519 #ifdef KR_headers
00520 putpower(p)
00521         expptr p;
00522 #else
00523 putpower(expptr p)
00524 #endif
00525 {
00526         expptr base;
00527         Addrp t1, t2;
00528         ftnint k;
00529         int type;
00530         char buf[80];                   /* buffer for text of comment */
00531 
00532         if(!ISICON(p->exprblock.rightp) ||
00533             (k = p->exprblock.rightp->constblock.Const.ci)<2)
00534                 Fatal("putpower: bad call");
00535         base = p->exprblock.leftp;
00536         type = base->headblock.vtype;
00537         t1 = mktmp(type, ENULL);
00538         t2 = NULL;
00539 
00540         free ((charptr) p);
00541         p = putassign (cpexpr((expptr) t1), base);
00542 
00543         sprintf (buf, "Computing %ld%s power", k,
00544                 k == 2 ? "nd" : k == 3 ? "rd" : "th");
00545         p1_comment (buf);
00546 
00547         for( ; (k&1)==0 && k>2 ; k>>=1 )
00548         {
00549                 p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
00550         }
00551 
00552         if(k == 2) {
00553 
00554 /* Write the power computation out immediately */
00555                 putout (p);
00556                 p = putx( mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1)));
00557         } else if (k == 3) {
00558                 putout(p);
00559                 p = putx( mkexpr(OPSTAR, cpexpr((expptr)t1),
00560                     mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1))));
00561         } else {
00562                 t2 = mktmp(type, ENULL);
00563                 p = mkexpr (OPCOMMA, p, putassign(cpexpr((expptr)t2),
00564                                                 cpexpr((expptr)t1)));
00565 
00566                 for(k>>=1 ; k>1 ; k>>=1)
00567                 {
00568                         p = mkexpr (OPCOMMA, p, putsteq(t1, t1));
00569                         if(k & 1)
00570                         {
00571                                 p = mkexpr (OPCOMMA, p, putsteq(t2, t1));
00572                         }
00573                 }
00574 /* Write the power computation out immediately */
00575                 putout (p);
00576                 p = putx( mkexpr(OPSTAR, cpexpr((expptr)t2),
00577                     mkexpr(OPSTAR, cpexpr((expptr)t1), cpexpr((expptr)t1))));
00578         }
00579         frexpr((expptr)t1);
00580         if(t2)
00581                 frexpr((expptr)t2);
00582         return p;
00583 }
00584 
00585 
00586 
00587 
00588  LOCAL Addrp
00589 #ifdef KR_headers
00590 intdouble(p)
00591         Addrp p;
00592 #else
00593 intdouble(Addrp p)
00594 #endif
00595 {
00596         register Addrp t;
00597 
00598         t = mktmp(TYDREAL, ENULL);
00599         putout (putassign(cpexpr((expptr)t), (expptr)p));
00600         return(t);
00601 }
00602 
00603 
00604 
00605 
00606 
00607 /* Complex-type variable assignment */
00608 
00609  LOCAL Addrp
00610 #ifdef KR_headers
00611 putcxeq(p)
00612         register expptr p;
00613 #else
00614 putcxeq(register expptr p)
00615 #endif
00616 {
00617         register Addrp lp, rp;
00618         expptr code;
00619 
00620         if(p->tag != TEXPR)
00621                 badtag("putcxeq", p->tag);
00622 
00623         lp = putcx1(p->exprblock.leftp);
00624         rp = putcx1(p->exprblock.rightp);
00625         code = putassign ( (expptr)realpart(lp), (expptr)realpart(rp));
00626 
00627         if( ISCOMPLEX(p->exprblock.vtype) )
00628         {
00629                 code = mkexpr (OPCOMMA, code, putassign
00630                         (imagpart(lp), imagpart(rp)));
00631         }
00632         putout (code);
00633         frexpr((expptr)rp);
00634         free ((charptr) p);
00635         return lp;
00636 }
00637 
00638 
00639 
00640 /* putcxop -- used to write out embedded calls to complex functions, and
00641    complex arguments to procedures */
00642 
00643  expptr
00644 #ifdef KR_headers
00645 putcxop(p)
00646         expptr p;
00647 #else
00648 putcxop(expptr p)
00649 #endif
00650 {
00651         return (expptr)putaddr((expptr)putcx1(p));
00652 }
00653 
00654 #define PAIR(x,y) mkexpr (OPCOMMA, (x), (y))
00655 
00656  LOCAL Addrp
00657 #ifdef KR_headers
00658 putcx1(p)
00659         register expptr p;
00660 #else
00661 putcx1(register expptr p)
00662 #endif
00663 {
00664         expptr q;
00665         Addrp lp, rp;
00666         register Addrp resp;
00667         int opcode;
00668         int ltype, rtype;
00669         long ts, tskludge;
00670 
00671         if(p == NULL)
00672                 return(NULL);
00673 
00674         switch(p->tag)
00675         {
00676         case TCONST:
00677                 if( ISCOMPLEX(p->constblock.vtype) )
00678                         p = (expptr) putconst((Constp)p);
00679                 return( (Addrp) p );
00680 
00681         case TADDR:
00682                 resp = &p->addrblock;
00683                 if (addressable(p))
00684                         return (Addrp) p;
00685                 ts = tskludge = 0;
00686                 if (q = resp->memoffset) {
00687                         if (resp->uname_tag == UNAM_REF) {
00688                                 q = cpexpr((tagptr)resp);
00689                                 q->addrblock.vtype = tyint;
00690                                 q->addrblock.cmplx_sub = 1;
00691                                 p->addrblock.skip_offset = 1;
00692                                 resp->user.name->vsubscrused = 1;
00693                                 resp->uname_tag = UNAM_NAME;
00694                                 tskludge = typesize[resp->vtype]
00695                                         * (resp->Field ? 2 : 1);
00696                                 }
00697                         else if (resp->isarray
00698                                         && resp->vtype != TYCHAR) {
00699                                 if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
00700                                           && resp->uname_tag == UNAM_NAME)
00701                                         q = mkexpr(OPMINUS, q,
00702                                           mkintcon(resp->user.name->voffset));
00703                                 ts = typesize[resp->vtype]
00704                                         * (resp->Field ? 2 : 1);
00705                                 q = resp->memoffset = mkexpr(OPSLASH, q,
00706                                                                 ICON(ts));
00707                                 }
00708                         }
00709                 resp = mktmp(tyint, ENULL);
00710                 putout(putassign(cpexpr((expptr)resp), q));
00711                 p->addrblock.memoffset = tskludge
00712                         ? mkexpr(OPSTAR, (expptr)resp, ICON(tskludge))
00713                         : (expptr)resp;
00714                 if (ts) {
00715                         resp = &p->addrblock;
00716                         q = mkexpr(OPSTAR, resp->memoffset, ICON(ts));
00717                         if (ONEOF(resp->vstg, M(STGCOMMON)|M(STGEQUIV))
00718                                 && resp->uname_tag == UNAM_NAME)
00719                                 q = mkexpr(OPPLUS, q,
00720                                     mkintcon(resp->user.name->voffset));
00721                         resp->memoffset = q;
00722                         }
00723                 return (Addrp) p;
00724 
00725         case TEXPR:
00726                 if( ISCOMPLEX(p->exprblock.vtype) )
00727                         break;
00728                 resp = mktmp(p->exprblock.vtype, ENULL);
00729                 /*first arg of above mktmp call was TYDREAL before 19950102 */
00730                 putout (putassign( cpexpr((expptr)resp), p));
00731                 return(resp);
00732 
00733         case TERROR:
00734                 return NULL;
00735 
00736         default:
00737                 badtag("putcx1", p->tag);
00738         }
00739 
00740         opcode = p->exprblock.opcode;
00741         if(opcode==OPCALL || opcode==OPCCALL)
00742         {
00743                 Addrp t;
00744                 p = putcall(p, &t);
00745                 putout(p);
00746                 return t;
00747         }
00748         else if(opcode == OPASSIGN)
00749         {
00750                 return putcxeq (p);
00751         }
00752 
00753 /* BUG  (inefficient)  Generates too many temporary variables */
00754 
00755         resp = mktmp(p->exprblock.vtype, ENULL);
00756         if(lp = putcx1(p->exprblock.leftp) )
00757                 ltype = lp->vtype;
00758         if(rp = putcx1(p->exprblock.rightp) )
00759                 rtype = rp->vtype;
00760 
00761         switch(opcode)
00762         {
00763         case OPCOMMA:
00764                 frexpr((expptr)resp);
00765                 resp = rp;
00766                 rp = NULL;
00767                 break;
00768 
00769         case OPNEG:
00770         case OPNEG1:
00771                 putout (PAIR (
00772                         putassign( (expptr)realpart(resp),
00773                                 mkexpr(OPNEG, (expptr)realpart(lp), ENULL)),
00774                         putassign( imagpart(resp),
00775                                 mkexpr(OPNEG, imagpart(lp), ENULL))));
00776                 break;
00777 
00778         case OPPLUS:
00779         case OPMINUS: { expptr r;
00780                 r = putassign( (expptr)realpart(resp),
00781                     mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp) ));
00782                 if(rtype < TYCOMPLEX)
00783                         q = putassign( imagpart(resp), imagpart(lp) );
00784                 else if(ltype < TYCOMPLEX)
00785                 {
00786                         if(opcode == OPPLUS)
00787                                 q = putassign( imagpart(resp), imagpart(rp) );
00788                         else
00789                                 q = putassign( imagpart(resp),
00790                                     mkexpr(OPNEG, imagpart(rp), ENULL) );
00791                 }
00792                 else
00793                         q = putassign( imagpart(resp),
00794                             mkexpr(opcode, imagpart(lp), imagpart(rp) ));
00795                 r = PAIR (r, q);
00796                 putout (r);
00797                 break;
00798             } /* case OPPLUS, OPMINUS: */
00799         case OPSTAR:
00800                 if(ltype < TYCOMPLEX)
00801                 {
00802                         if( ISINT(ltype) )
00803                                 lp = intdouble(lp);
00804                         putout (PAIR (
00805                                 putassign( (expptr)realpart(resp),
00806                                     mkexpr(OPSTAR, cpexpr((expptr)lp),
00807                                         (expptr)realpart(rp))),
00808                                 putassign( imagpart(resp),
00809                                     mkexpr(OPSTAR, cpexpr((expptr)lp), imagpart(rp)))));
00810                 }
00811                 else if(rtype < TYCOMPLEX)
00812                 {
00813                         if( ISINT(rtype) )
00814                                 rp = intdouble(rp);
00815                         putout (PAIR (
00816                                 putassign( (expptr)realpart(resp),
00817                                     mkexpr(OPSTAR, cpexpr((expptr)rp),
00818                                         (expptr)realpart(lp))),
00819                                 putassign( imagpart(resp),
00820                                     mkexpr(OPSTAR, cpexpr((expptr)rp), imagpart(lp)))));
00821                 }
00822                 else    {
00823                         putout (PAIR (
00824                                 putassign( (expptr)realpart(resp), mkexpr(OPMINUS,
00825                                     mkexpr(OPSTAR, (expptr)realpart(lp),
00826                                         (expptr)realpart(rp)),
00827                                     mkexpr(OPSTAR, imagpart(lp), imagpart(rp)))),
00828                                 putassign( imagpart(resp), mkexpr(OPPLUS,
00829                                     mkexpr(OPSTAR, (expptr)realpart(lp), imagpart(rp)),
00830                                     mkexpr(OPSTAR, imagpart(lp),
00831                                         (expptr)realpart(rp))))));
00832                 }
00833                 break;
00834 
00835         case OPSLASH:
00836                 /* fixexpr has already replaced all divisions
00837                  * by a complex by a function call
00838                  */
00839                 if( ISINT(rtype) )
00840                         rp = intdouble(rp);
00841                 putout (PAIR (
00842                         putassign( (expptr)realpart(resp),
00843                             mkexpr(OPSLASH, (expptr)realpart(lp), cpexpr((expptr)rp))),
00844                         putassign( imagpart(resp),
00845                             mkexpr(OPSLASH, imagpart(lp), cpexpr((expptr)rp)))));
00846                 break;
00847 
00848         case OPCONV:
00849                 if (!lp)
00850                         break;
00851                 if(ISCOMPLEX(lp->vtype) )
00852                         q = imagpart(lp);
00853                 else if(rp != NULL)
00854                         q = (expptr) realpart(rp);
00855                 else
00856                         q = mkrealcon(TYDREAL, "0");
00857                 putout (PAIR (
00858                         putassign( (expptr)realpart(resp), (expptr)realpart(lp)),
00859                         putassign( imagpart(resp), q)));
00860                 break;
00861 
00862         default:
00863                 badop("putcx1", opcode);
00864         }
00865 
00866         frexpr((expptr)lp);
00867         frexpr((expptr)rp);
00868         free( (charptr) p );
00869         return(resp);
00870 }
00871 
00872 
00873 
00874 
00875 /* Only .EQ. and .NE. may be performed on COMPLEX data, other relations
00876    are not defined */
00877 
00878  LOCAL expptr
00879 #ifdef KR_headers
00880 putcxcmp(p)
00881         register expptr p;
00882 #else
00883 putcxcmp(register expptr p)
00884 #endif
00885 {
00886         int opcode;
00887         register Addrp lp, rp;
00888         expptr q;
00889 
00890         if(p->tag != TEXPR)
00891                 badtag("putcxcmp", p->tag);
00892 
00893         opcode = p->exprblock.opcode;
00894         lp = putcx1(p->exprblock.leftp);
00895         rp = putcx1(p->exprblock.rightp);
00896 
00897         q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
00898             mkexpr(opcode, (expptr)realpart(lp), (expptr)realpart(rp)),
00899             mkexpr(opcode, imagpart(lp), imagpart(rp)) );
00900 
00901         free( (charptr) lp);
00902         free( (charptr) rp);
00903         free( (charptr) p );
00904         if (ISCONST(q))
00905                 return q;
00906         return  putx( fixexpr((Exprp)q) );
00907 }
00908 
00909 /* putch1 -- Forces constants into the literal pool, among other things */
00910 
00911  LOCAL Addrp
00912 #ifdef KR_headers
00913 putch1(p)
00914         register expptr p;
00915 #else
00916 putch1(register expptr p)
00917 #endif
00918 {
00919         Addrp t;
00920         expptr e;
00921 
00922         switch(p->tag)
00923         {
00924         case TCONST:
00925                 return( putconst((Constp)p) );
00926 
00927         case TADDR:
00928                 return( (Addrp) p );
00929 
00930         case TEXPR:
00931                 switch(p->exprblock.opcode)
00932                 {
00933                         expptr q;
00934 
00935                 case OPCALL:
00936                 case OPCCALL:
00937 
00938                         p = putcall(p, &t);
00939                         putout (p);
00940                         break;
00941 
00942                 case OPCONCAT:
00943                         t = mktmp(TYCHAR, ICON(lencat(p)));
00944                         q = (expptr) cpexpr(p->headblock.vleng);
00945                         p = putcat( cpexpr((expptr)t), p );
00946                         /* put the correct length on the block */
00947                         frexpr(t->vleng);
00948                         t->vleng = q;
00949                         putout (p);
00950                         break;
00951 
00952                 case OPCONV:
00953                         if(!ISICON(p->exprblock.vleng)
00954                             || p->exprblock.vleng->constblock.Const.ci!=1
00955                             || ! INT(p->exprblock.leftp->headblock.vtype) )
00956                                 Fatal("putch1: bad character conversion");
00957                         t = mktmp(TYCHAR, ICON(1));
00958                         e = mkexpr(OPCONV, (expptr)t, ENULL);
00959                         e->headblock.vtype = TYCHAR;
00960                         p = putop( mkexpr(OPASSIGN, cpexpr(e), p));
00961                         putout (p);
00962                         break;
00963                 default:
00964                         badop("putch1", p->exprblock.opcode);
00965                 }
00966                 return(t);
00967 
00968         default:
00969                 badtag("putch1", p->tag);
00970         }
00971         /* NOT REACHED */ return 0;
00972 }
00973 
00974 
00975 /* putchop -- Write out a character actual parameter; that is, this is
00976    part of a procedure invocation */
00977 
00978  Addrp
00979 #ifdef KR_headers
00980 putchop(p)
00981         expptr p;
00982 #else
00983 putchop(expptr p)
00984 #endif
00985 {
00986         p = putaddr((expptr)putch1(p));
00987         return (Addrp)p;
00988 }
00989 
00990 
00991 
00992 
00993  LOCAL expptr
00994 #ifdef KR_headers
00995 putcheq(p)
00996         register expptr p;
00997 #else
00998 putcheq(register expptr p)
00999 #endif
01000 {
01001         expptr lp, rp;
01002         int nbad;
01003 
01004         if(p->tag != TEXPR)
01005                 badtag("putcheq", p->tag);
01006 
01007         lp = p->exprblock.leftp;
01008         rp = p->exprblock.rightp;
01009         frexpr(p->exprblock.vleng);
01010         free( (charptr) p );
01011 
01012 /* If s = t // u, don't bother copying the result, write it directly into
01013    this buffer */
01014 
01015         nbad = badchleng(lp) + badchleng(rp);
01016         if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
01017                 p = putcat(lp, rp);
01018         else if( !nbad
01019                 && ISONE(lp->headblock.vleng)
01020                 && ISONE(rp->headblock.vleng) ) {
01021                 lp = mkexpr(OPCONV, lp, ENULL);
01022                 rp = mkexpr(OPCONV, rp, ENULL);
01023                 lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
01024                 p = putop(mkexpr(OPASSIGN, lp, rp));
01025                 }
01026         else
01027                 p = putx( call2(TYSUBR, "s_copy", lp, rp) );
01028         return p;
01029 }
01030 
01031 
01032 
01033 
01034  LOCAL expptr
01035 #ifdef KR_headers
01036 putchcmp(p)
01037         register expptr p;
01038 #else
01039 putchcmp(register expptr p)
01040 #endif
01041 {
01042         expptr lp, rp;
01043 
01044         if(p->tag != TEXPR)
01045                 badtag("putchcmp", p->tag);
01046 
01047         lp = p->exprblock.leftp;
01048         rp = p->exprblock.rightp;
01049 
01050         if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) {
01051                 lp = mkexpr(OPCONV, lp, ENULL);
01052                 rp = mkexpr(OPCONV, rp, ENULL);
01053                 lp->headblock.vtype = rp->headblock.vtype = TYCHAR;
01054                 }
01055         else {
01056                 lp = call2(TYINT,"s_cmp", lp, rp);
01057                 rp = ICON(0);
01058                 }
01059         p->exprblock.leftp = lp;
01060         p->exprblock.rightp = rp;
01061         p = putop(p);
01062         return p;
01063 }
01064 
01065 
01066 
01067 
01068 
01069 /* putcat -- Writes out a concatenation operation.  Two temporary arrays
01070    are allocated,   putct1()   is called to initialize them, and then a
01071    call to runtime library routine   s_cat()   is inserted.
01072 
01073         This routine generates code which will perform an  (nconc lhs rhs)
01074    at runtime.  The runtime funciton does not return a value, the routine
01075    that calls this   putcat   must remember the name of   lhs.
01076 */
01077 
01078 
01079  LOCAL expptr
01080 #ifdef KR_headers
01081 putcat(lhs0, rhs)
01082         expptr lhs0;
01083         register expptr rhs;
01084 #else
01085 putcat(expptr lhs0, register expptr rhs)
01086 #endif
01087 {
01088         register Addrp lhs = (Addrp)lhs0;
01089         int n, tyi;
01090         Addrp length_var, string_var;
01091         expptr p;
01092         static char Writing_concatenation[] = "Writing concatenation";
01093 
01094 /* Create the temporary arrays */
01095 
01096         n = ncat(rhs);
01097         length_var = mktmpn(n, tyioint, ENULL);
01098         string_var = mktmpn(n, TYADDR, ENULL);
01099         frtemp((Addrp)cpexpr((expptr)length_var));
01100         frtemp((Addrp)cpexpr((expptr)string_var));
01101 
01102 /* Initialize the arrays */
01103 
01104         n = 0;
01105         /* p1_comment scribbles on its argument, so we
01106          * cannot safely pass a string literal here. */
01107         p1_comment(Writing_concatenation);
01108         putct1(rhs, length_var, string_var, &n);
01109 
01110 /* Create the invocation */
01111 
01112         tyi = tyint;
01113         tyint = tyioint;        /* for -I2 */
01114         p = putx (call4 (TYSUBR, "s_cat",
01115                                 (expptr)lhs,
01116                                 (expptr)string_var,
01117                                 (expptr)length_var,
01118                                 (expptr)putconst((Constp)ICON(n))));
01119         tyint = tyi;
01120 
01121         return p;
01122 }
01123 
01124 
01125 
01126 
01127 
01128  LOCAL void
01129 #ifdef KR_headers
01130 putct1(q, length_var, string_var, ip)
01131         register expptr q;
01132         register Addrp length_var;
01133         register Addrp string_var;
01134         int *ip;
01135 #else
01136 putct1(register expptr q, register Addrp length_var, register Addrp string_var, int *ip)
01137 #endif
01138 {
01139         int i;
01140         Addrp length_copy, string_copy;
01141         expptr e;
01142         extern int szleng;
01143 
01144         if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
01145         {
01146                 putct1(q->exprblock.leftp, length_var, string_var,
01147                     ip);
01148                 putct1(q->exprblock.rightp, length_var, string_var,
01149                     ip);
01150                 frexpr (q -> exprblock.vleng);
01151                 free ((charptr) q);
01152         }
01153         else
01154         {
01155                 i = (*ip)++;
01156                 e = cpexpr(q->headblock.vleng);
01157                 if (!e)
01158                         return; /* error -- character*(*) */
01159                 length_copy = (Addrp) cpexpr((expptr)length_var);
01160                 length_copy->memoffset =
01161                     mkexpr(OPPLUS,length_copy->memoffset, ICON(i*szleng));
01162                 string_copy = (Addrp) cpexpr((expptr)string_var);
01163                 string_copy->memoffset =
01164                     mkexpr(OPPLUS, string_copy->memoffset,
01165                         ICON(i*typesize[TYADDR]));
01166                 putout (PAIR (putassign((expptr)length_copy, e),
01167                         putassign((expptr)string_copy, addrof((expptr)putch1(q)))));
01168         }
01169 }
01170 
01171 /* putaddr -- seems to write out function invocation actual parameters */
01172 
01173         LOCAL expptr
01174 #ifdef KR_headers
01175 putaddr(p0)
01176         expptr p0;
01177 #else
01178 putaddr(expptr p0)
01179 #endif
01180 {
01181         register Addrp p;
01182         chainp cp;
01183 
01184         if (!(p = (Addrp)p0))
01185                 return ENULL;
01186 
01187         if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
01188         {
01189                 frexpr((expptr)p);
01190                 return ENULL;
01191         }
01192         if (p->isarray && p->memoffset)
01193                 if (p->uname_tag == UNAM_REF) {
01194                         cp = p->memoffset->listblock.listp;
01195                         for(; cp; cp = cp->nextp)
01196                                 cp->datap = (char *)fixtype((tagptr)cp->datap);
01197                         }
01198                 else
01199                         p->memoffset = putx(p->memoffset);
01200         return (expptr) p;
01201 }
01202 
01203  LOCAL expptr
01204 #ifdef KR_headers
01205 addrfix(e)
01206         expptr e;
01207 #else
01208 addrfix(expptr e)
01209 #endif
01210                 /* fudge character string length if it's a TADDR */
01211 {
01212         return e->tag == TADDR ? mkexpr(OPIDENTITY, e, ENULL) : e;
01213         }
01214 
01215  LOCAL int
01216 #ifdef KR_headers
01217 typekludge(ccall, q, at, j)
01218         int ccall;
01219         register expptr q;
01220         Atype *at;
01221         int j;
01222 #else
01223 typekludge(int ccall, register expptr q, Atype *at, int j)
01224 #endif
01225  /* j = alternate type */
01226 {
01227         register int i, k;
01228         extern int iocalladdr;
01229         register Namep np;
01230 
01231         /* Return value classes:
01232          *      < 100 ==> Fortran arg (pointer to type)
01233          *      < 200 ==> C arg
01234          *      < 300 ==> procedure arg
01235          *      < 400 ==> external, no explicit type
01236          *      < 500 ==> arg that may turn out to be
01237          *                either a variable or a procedure
01238          */
01239 
01240         k = q->headblock.vtype;
01241         if (ccall) {
01242                 if (k == TYREAL)
01243                         k = TYDREAL;    /* force double for library routines */
01244                 return k + 100;
01245                 }
01246         if (k == TYADDR)
01247                 return iocalladdr;
01248         i = q->tag;
01249         if ((i == TEXPR && q->exprblock.opcode != OPCOMMA_ARG)
01250         ||  (i == TADDR && q->addrblock.charleng)
01251         ||   i == TCONST)
01252                 k = TYFTNLEN + 100;
01253         else if (i == TADDR)
01254             switch(q->addrblock.vclass) {
01255                 case CLPROC:
01256                         if (q->addrblock.uname_tag != UNAM_NAME)
01257                                 k += 200;
01258                         else if ((np = q->addrblock.user.name)->vprocclass
01259                                         != PTHISPROC) {
01260                                 if (k && !np->vimpltype)
01261                                         k += 200;
01262                                 else {
01263                                         if (j > 200 && infertypes && j < 300) {
01264                                                 k = j;
01265                                                 inferdcl(np, j-200);
01266                                                 }
01267                                         else k = (np->vstg == STGEXT
01268                                                 ? extsymtab[np->vardesc.varno].extype
01269                                                 : 0) + 200;
01270                                         at->cp = mkchain((char *)np, at->cp);
01271                                         }
01272                                 }
01273                         else if (k == TYSUBR)
01274                                 k += 200;
01275                         break;
01276 
01277                 case CLUNKNOWN:
01278                         if (q->addrblock.vstg == STGARG
01279                          && q->addrblock.uname_tag == UNAM_NAME) {
01280                                 k += 400;
01281                                 at->cp = mkchain((char *)q->addrblock.user.name,
01282                                                 at->cp);
01283                                 }
01284                 }
01285         else if (i == TNAME && q->nameblock.vstg == STGARG) {
01286                 np = &q->nameblock;
01287                 switch(np->vclass) {
01288                     case CLPROC:
01289                         if (!np->vimpltype)
01290                                 k += 200;
01291                         else if (j <= 200 || !infertypes || j >= 300)
01292                                 k += 300;
01293                         else {
01294                                 k = j;
01295                                 inferdcl(np, j-200);
01296                                 }
01297                         goto add2chain;
01298 
01299                     case CLUNKNOWN:
01300                         /* argument may be a scalar variable or a function */
01301                         if (np->vimpltype && j && infertypes
01302                         && j < 300) {
01303                                 inferdcl(np, j % 100);
01304                                 k = j;
01305                                 }
01306                         else
01307                                 k += 400;
01308 
01309                         /* to handle procedure args only so far known to be
01310                          * external, save a pointer to the symbol table entry...
01311                          */
01312  add2chain:
01313                         at->cp = mkchain((char *)np, at->cp);
01314                     }
01315                 }
01316         return k;
01317         }
01318 
01319  char *
01320 #ifdef KR_headers
01321 Argtype(k, buf)
01322         int k;
01323         char *buf;
01324 #else
01325 Argtype(int k, char *buf)
01326 #endif
01327 {
01328         if (k < 100) {
01329                 sprintf(buf, "%s variable", ftn_types[k]);
01330                 return buf;
01331                 }
01332         if (k < 200) {
01333                 k -= 100;
01334                 return ftn_types[k];
01335                 }
01336         if (k < 300) {
01337                 k -= 200;
01338                 if (k == TYSUBR)
01339                         return ftn_types[TYSUBR];
01340                 sprintf(buf, "%s function", ftn_types[k]);
01341                 return buf;
01342                 }
01343         if (k < 400)
01344                 return "external argument";
01345         k -= 400;
01346         sprintf(buf, "%s argument", ftn_types[k]);
01347         return buf;
01348         }
01349 
01350  static void
01351 #ifdef KR_headers
01352 atype_squawk(at, msg)
01353         Argtypes *at;
01354         char *msg;
01355 #else
01356 atype_squawk(Argtypes *at, char *msg)
01357 #endif
01358 {
01359         register Atype *a, *ae;
01360         warn(msg);
01361         for(a = at->atypes, ae = a + at->nargs; a < ae; a++)
01362                 frchain(&a->cp);
01363         at->nargs = -1;
01364         if (at->changes & 2 && !at->defined)
01365                 proc_protochanges++;
01366         }
01367 
01368  static char inconsist[] = "inconsistent calling sequences for ";
01369 
01370  void
01371 #ifdef KR_headers
01372 bad_atypes(at, fname, i, j, k, here, prev)
01373         Argtypes *at;
01374         char *fname;
01375         int i;
01376         int j;
01377         int k;
01378         char *here;
01379         char *prev;
01380 #else
01381 bad_atypes(Argtypes *at, char *fname, int i, int j, int k, char *here, char *prev)
01382 #endif
01383 {
01384         char buf[208], buf1[32], buf2[32];
01385 
01386         sprintf(buf, "%s%.90s,\n\targ %d: %s%s%s %s.",
01387                 inconsist, fname, i, here, Argtype(k, buf1),
01388                 prev, Argtype(j, buf2));
01389         atype_squawk(at, buf);
01390         }
01391 
01392  int
01393 #ifdef KR_headers
01394 type_fixup(at, a, k)
01395         Argtypes *at;
01396         Atype *a;
01397         int k;
01398 #else
01399 type_fixup(Argtypes *at,  Atype *a,  int k)
01400 #endif
01401 {
01402         register struct Entrypoint *ep;
01403         if (!infertypes)
01404                 return 0;
01405         for(ep = entries; ep; ep = ep->entnextp)
01406                 if (ep->entryname && at == ep->entryname->arginfo) {
01407                         a->type = k % 100;
01408                         return proc_argchanges = 1;
01409                         }
01410         return 0;
01411         }
01412 
01413 
01414  void
01415 #ifdef KR_headers
01416 save_argtypes(arglist, at0, at1, ccall, fname, stg, nchargs, type, zap)
01417         chainp arglist;
01418         Argtypes **at0;
01419         Argtypes **at1;
01420         int ccall;
01421         char *fname;
01422         int stg;
01423         int nchargs;
01424         int type;
01425         int zap;
01426 #else
01427 save_argtypes(chainp arglist, Argtypes **at0, Argtypes **at1, int ccall, char *fname, int stg, int nchargs, int type, int zap)
01428 #endif
01429 {
01430         Argtypes *at;
01431         chainp cp;
01432         int i, i0, j, k, nargs, nbad, *t, *te;
01433         Atype *atypes;
01434         expptr q;
01435         char buf[208], buf1[32], buf2[32];
01436         static int initargs[4] = {TYCOMPLEX, TYDCOMPLEX, TYCHAR, TYFTNLEN+100};
01437         static int *init_ap[TYSUBR+1] = {0,0,0,0,0,0,0,
01438 #ifdef TYQUAD
01439                                                         0,
01440 #endif
01441                                 initargs, initargs+1,0,0,0,initargs+2};
01442 
01443         i0 = init_ac[type];
01444         t = init_ap[type];
01445         te = t + i0;
01446         if (at = *at0) {
01447                 *at1 = at;
01448                 nargs = at->nargs;
01449                 if (nargs < 0 && type && at->changes & 2 && !at->defined)
01450                         --proc_protochanges;
01451                 if (at->dnargs >= 0 && zap != 2)
01452                         type = 0;
01453                 if (nargs < 0) { /* inconsistent usage seen */
01454                         if (type)
01455                                 goto newlist;
01456                         return;
01457                         }
01458                 atypes = at->atypes;
01459                 i = nchargs;
01460                 for(nbad = 0; t < te; atypes++) {
01461                         if (++i > nargs) {
01462  toomany:
01463                                 i = nchargs + i0;
01464                                 for(cp = arglist; cp; cp = cp->nextp)
01465                                         i++;
01466  toofew:
01467                                 switch(zap) {
01468                                         case 2: zap = 6; break;
01469                                         case 1: if (at->defined & 4)
01470                                                         return;
01471                                         }
01472                                 sprintf(buf,
01473                 "%s%.90s:\n\there %d, previously %d args and string lengths.",
01474                                         inconsist, fname, i, nargs);
01475                                 atype_squawk(at, buf);
01476                                 if (type) {
01477                                         t = init_ap[type];
01478                                         goto newlist;
01479                                         }
01480                                 return;
01481                                 }
01482                         j = atypes->type;
01483                         k = *t++;
01484                         if (j != k && j-400 != k) {
01485                                 cp = 0;
01486                                 goto badtypes;
01487                                 }
01488                         }
01489                 for(cp = arglist; cp; atypes++, cp = cp->nextp) {
01490                         if (++i > nargs)
01491                                 goto toomany;
01492                         j = atypes->type;
01493                         if (!(q = (expptr)cp->datap))
01494                                 continue;
01495                         k = typekludge(ccall, q, atypes, j);
01496                         if (k >= 300 || k == j)
01497                                 continue;
01498                         if (j >= 300) {
01499                                 if (k >= 200) {
01500                                         if (k == TYUNKNOWN + 200)
01501                                                 continue;
01502                                         if (j % 100 != k - 200
01503                                          && k != TYSUBR + 200
01504                                          && j != TYUNKNOWN + 300
01505                                          && !type_fixup(at,atypes,k))
01506                                                 goto badtypes;
01507                                         }
01508                                 else if (j % 100 % TYSUBR != k % TYSUBR
01509                                                 && !type_fixup(at,atypes,k))
01510                                         goto badtypes;
01511                                 }
01512                         else if (k < 200 || j < 200)
01513                                 if (j) {
01514                                         if (k == TYUNKNOWN
01515                                          && q->tag == TNAME
01516                                          && q->nameblock.vinfproc) {
01517                                                 q->nameblock.vdcldone = 0;
01518                                                 impldcl((Namep)q);
01519                                                 }
01520                                         goto badtypes;
01521                                         }
01522                                 else ; /* fall through to update */
01523                         else if (k == TYUNKNOWN+200)
01524                                 continue;
01525                         else if (j != TYUNKNOWN+200)
01526                                 {
01527  badtypes:
01528                                 if (++nbad == 1)
01529                                         bad_atypes(at, fname, i - nchargs,
01530                                                 j, k, "here ", ", previously");
01531                                 else
01532                                         fprintf(stderr,
01533                                          "\targ %d: here %s, previously %s.\n",
01534                                                 i - nchargs, Argtype(k,buf1),
01535                                                 Argtype(j,buf2));
01536                                 if (!cp)
01537                                         break;
01538                                 continue;
01539                                 }
01540                         /* We've subsequently learned the right type,
01541                            as in the call on zoo below...
01542 
01543                                 subroutine foo(x, zap)
01544                                 external zap
01545                                 call goo(zap)
01546                                 x = zap(3)
01547                                 call zoo(zap)
01548                                 end
01549                          */
01550                         if (!nbad) {
01551                                 atypes->type = k;
01552                                 at->changes |= 1;
01553                                 }
01554                         }
01555                 if (i < nargs)
01556                         goto toofew;
01557                 if (nbad) {
01558                         if (type) {
01559                                 /* we're defining the procedure */
01560                                 t = init_ap[type];
01561                                 te = t + i0;
01562                                 proc_argchanges = 1;
01563                                 goto newlist;
01564                                 }
01565                         return;
01566                         }
01567                 if (zap == 1 && (at->changes & 5) != 5)
01568                         at->changes = 0;
01569                 return;
01570                 }
01571  newlist:
01572         i = i0 + nchargs;
01573         for(cp = arglist; cp; cp = cp->nextp)
01574                 i++;
01575         k = sizeof(Argtypes) + (i-1)*sizeof(Atype);
01576         *at0 = *at1 = at = stg == STGEXT ? (Argtypes *)gmem(k,1)
01577                                          : (Argtypes *) mem(k,1);
01578         at->dnargs = at->nargs = i;
01579         at->defined = zap & 6;
01580         at->changes = type ? 0 : 4;
01581         atypes = at->atypes;
01582         for(; t < te; atypes++) {
01583                 atypes->type = *t++;
01584                 atypes->cp = 0;
01585                 }
01586         for(cp = arglist; cp; atypes++, cp = cp->nextp) {
01587                 atypes->cp = 0;
01588                 atypes->type = (q = (expptr)cp->datap)
01589                         ? typekludge(ccall, q, atypes, 0)
01590                         : 0;
01591                 }
01592         for(; --nchargs >= 0; atypes++) {
01593                 atypes->type = TYFTNLEN + 100;
01594                 atypes->cp = 0;
01595                 }
01596         }
01597 
01598  static char*
01599 #ifdef KR_headers
01600 get_argtypes(p, pat0, pat1) Exprp p; Argtypes ***pat0, ***pat1;
01601 #else
01602 get_argtypes(Exprp p, Argtypes ***pat0, Argtypes ***pat1)
01603 #endif
01604 {
01605         Addrp a;
01606         Argtypes **at0, **at1;
01607         Namep np;
01608         Extsym *e;
01609         char *fname;
01610 
01611         a = (Addrp)p->leftp;
01612         switch(a->vstg) {
01613                 case STGEXT:
01614                         switch(a->uname_tag) {
01615                                 case UNAM_EXTERN:       /* e.g., sqrt() */
01616                                         e = extsymtab + a->memno;
01617                                         at0 = at1 = &e->arginfo;
01618                                         fname = e->fextname;
01619                                         break;
01620                                 case UNAM_NAME:
01621                                         np = a->user.name;
01622                                         at0 = &extsymtab[np->vardesc.varno].arginfo;
01623                                         at1 = &np->arginfo;
01624                                         fname = np->fvarname;
01625                                         break;
01626                                 default:
01627                                         goto bug;
01628                                 }
01629                         break;
01630                 case STGARG:
01631                         if (a->uname_tag != UNAM_NAME)
01632                                 goto bug;
01633                         np = a->user.name;
01634                         at0 = at1 = &np->arginfo;
01635                         fname = np->fvarname;
01636                         break;
01637                 default:
01638          bug:
01639                         Fatal("Confusion in saveargtypes");
01640                 }
01641         *pat0 = at0;
01642         *pat1 = at1;
01643         return fname;
01644         }
01645 
01646  void
01647 #ifdef KR_headers
01648 saveargtypes(p)
01649         register Exprp p;
01650 #else
01651 saveargtypes(register Exprp p)
01652 #endif
01653                                 /* for writing prototypes */
01654 {
01655         Argtypes **at0, **at1;
01656         chainp arglist;
01657         expptr rp;
01658         char *fname;
01659 
01660         fname = get_argtypes(p, &at0, &at1);
01661         rp = p->rightp;
01662         arglist = rp && rp->tag == TLIST ? rp->listblock.listp : 0;
01663         save_argtypes(arglist, at0, at1, p->opcode == OPCCALL,
01664                 fname, p->leftp->addrblock.vstg, 0, 0, 0);
01665         }
01666 
01667 /* putcall - fix up the argument list, and write out the invocation.   p
01668    is expected to be initialized and point to an OPCALL or OPCCALL
01669    expression.  The return value is a pointer to a temporary holding the
01670    result of a COMPLEX or CHARACTER operation, or NULL. */
01671 
01672  LOCAL expptr
01673 #ifdef KR_headers
01674 putcall(p0, temp)
01675         expptr p0;
01676         Addrp *temp;
01677 #else
01678 putcall(expptr p0, Addrp *temp)
01679 #endif
01680 {
01681     register Exprp p = (Exprp)p0;
01682     chainp arglist;             /* Pointer to actual arguments, if any */
01683     chainp charsp;              /* List of copies of the variables which
01684                                    hold the lengths of character
01685                                    parameters (other than procedure
01686                                    parameters) */
01687     chainp cp;                  /* Iterator over argument lists */
01688     register expptr q;          /* Pointer to the current argument */
01689     Addrp fval;                 /* Function return value */
01690     int type;                   /* type of the call - presumably this was
01691                                    set elsewhere */
01692     int byvalue;                /* True iff we don't want to massage the
01693                                    parameter list, since we're calling a C
01694                                    library routine */
01695     char *s;
01696     Argtypes *at, **at0, **at1;
01697     Atype *At, *Ate;
01698 
01699     type = p -> vtype;
01700     charsp = NULL;
01701     byvalue =  (p->opcode == OPCCALL);
01702 
01703 /* Verify the actual parameters */
01704 
01705     if (p == (Exprp) NULL)
01706         err ("putcall:  NULL call expression");
01707     else if (p -> tag != TEXPR)
01708         erri ("putcall:  expected TEXPR, got '%d'", p -> tag);
01709 
01710 /* Find the argument list */
01711 
01712     if(p->rightp && p -> rightp -> tag == TLIST)
01713         arglist = p->rightp->listblock.listp;
01714     else
01715         arglist = NULL;
01716 
01717 /* Count the number of explicit arguments, including lengths of character
01718    variables */
01719 
01720     if (!byvalue) {
01721         get_argtypes(p, &at0, &at1);
01722         At = Ate = 0;
01723         if ((at = *at0) && at->nargs >= 0) {
01724                 At = at->atypes;
01725                 Ate = At + at->nargs;
01726                 At += init_ac[type];
01727                 }
01728         for(cp = arglist ; cp ; cp = cp->nextp) {
01729             q = (expptr) cp->datap;
01730             if( ISCONST(q) ) {
01731 
01732 /* Even constants are passed by reference, so we need to put them in the
01733    literal table */
01734 
01735                 q = (expptr) putconst((Constp)q);
01736                 cp->datap = (char *) q;
01737                 }
01738 
01739 /* Save the length expression of character variables (NOT character
01740    procedures) for the end of the argument list */
01741 
01742             if( ISCHAR(q) &&
01743                 (q->headblock.vclass != CLPROC
01744                 || q->headblock.vstg == STGARG
01745                         && q->tag == TADDR
01746                         && q->addrblock.uname_tag == UNAM_NAME
01747                         && q->addrblock.user.name->vprocclass == PTHISPROC)
01748                 && (!At || At->type % 100 % TYSUBR == TYCHAR))
01749                 {
01750                 p0 = cpexpr(q->headblock.vleng);
01751                 charsp = mkchain((char *)p0, charsp);
01752                 if (q->headblock.vclass == CLUNKNOWN
01753                  && q->headblock.vstg == STGARG)
01754                         q->addrblock.user.name->vpassed = 1;
01755                 else if (q->tag == TADDR
01756                                 && q->addrblock.uname_tag == UNAM_CONST)
01757                         p0->constblock.Const.ci
01758                                 += q->addrblock.user.Const.ccp1.blanks;
01759                 }
01760             if (At && ++At == Ate)
01761                 At = 0;
01762             }
01763         }
01764     charsp = revchain(charsp);
01765 
01766 /* If the routine is a CHARACTER function ... */
01767 
01768     if(type == TYCHAR)
01769     {
01770         if( ISICON(p->vleng) )
01771         {
01772 
01773 /* Allocate a temporary to hold the return value of the function */
01774 
01775             fval = mktmp(TYCHAR, p->vleng);
01776         }
01777         else    {
01778                 err("adjustable character function");
01779                 if (temp)
01780                         *temp = 0;
01781                 return 0;
01782                 }
01783     }
01784 
01785 /* If the routine is a COMPLEX function ... */
01786 
01787     else if( ISCOMPLEX(type) )
01788         fval = mktmp(type, ENULL);
01789     else
01790         fval = NULL;
01791 
01792 /* Write the function name, without taking its address */
01793 
01794     p -> leftp = putx(fixtype(putaddr(p->leftp)));
01795 
01796     if(fval)
01797     {
01798         chainp prepend;
01799 
01800 /* Prepend a copy of the function return value buffer out as the first
01801    argument. */
01802 
01803         prepend = mkchain((char *)putx(putaddr(cpexpr((expptr)fval))), arglist);
01804 
01805 /* If it's a character function, also prepend the length of the result */
01806 
01807         if(type==TYCHAR)
01808         {
01809 
01810             prepend->nextp = mkchain((char *)putx(mkconv(TYLENG,
01811                                         p->vleng)), arglist);
01812         }
01813         if (!(q = p->rightp))
01814                 p->rightp = q = (expptr)mklist(CHNULL);
01815         q->listblock.listp = prepend;
01816     }
01817 
01818 /* Scan through the fortran argument list */
01819 
01820     for(cp = arglist ; cp ; cp = cp->nextp)
01821     {
01822         q = (expptr) (cp->datap);
01823         if (q == ENULL)
01824             err ("putcall:  NULL argument");
01825 
01826 /* call putaddr only when we've got a parameter for a C routine or a
01827    memory resident parameter */
01828 
01829         if (q -> tag == TCONST && !byvalue)
01830             q = (expptr) putconst ((Constp)q);
01831 
01832         if(q->tag==TADDR && (byvalue || q->addrblock.vstg!=STGREG) ) {
01833                 if (q->addrblock.parenused
01834                  && !byvalue && q->headblock.vtype != TYCHAR)
01835                         goto make_copy;
01836                 cp->datap = (char *)putaddr(q);
01837                 }
01838         else if( ISCOMPLEX(q->headblock.vtype) )
01839             cp -> datap = (char *) putx (fixtype(putcxop(q)));
01840         else if (ISCHAR(q) )
01841             cp -> datap = (char *) putx (fixtype((expptr)putchop(q)));
01842         else if( ! ISERROR(q) )
01843         {
01844             if(byvalue) {
01845                 if (q->tag == TEXPR && q->exprblock.opcode == OPCONV) {
01846                         if (ISCOMPLEX(q->exprblock.leftp->headblock.vtype)
01847                          && q->exprblock.leftp->tag == TEXPR)
01848                                 q->exprblock.leftp = putcxop(q->exprblock.leftp);
01849                         else
01850                                 q->exprblock.leftp = putx(q->exprblock.leftp);
01851                         }
01852                 else
01853                         cp -> datap = (char *) putx(q);
01854                 }
01855             else if (q->tag == TEXPR && q->exprblock.opcode == OPCHARCAST)
01856                 cp -> datap = (char *) putx(q);
01857             else {
01858                 expptr t, t1;
01859 
01860 /* If we've got a register parameter, or (maybe?) a constant, save it in a
01861    temporary first */
01862  make_copy:
01863                 t = (expptr) mktmp(q->headblock.vtype, q->headblock.vleng);
01864 
01865 /* Assign to temporary variables before invoking the subroutine or
01866    function */
01867 
01868                 t1 = putassign( cpexpr(t), q );
01869                 if (doin_setbound)
01870                         t = mkexpr(OPCOMMA_ARG, t1, t);
01871                 else
01872                         putout(t1);
01873                 cp -> datap = (char *) t;
01874             } /* else */
01875         } /* if !ISERROR(q) */
01876     }
01877 
01878 /* Now adjust the lengths of the CHARACTER parameters */
01879 
01880     for(cp = charsp ; cp ; cp = cp->nextp)
01881         cp->datap = (char *)addrfix(putx(
01882                         /* in case MAIN has a character*(*)... */
01883                         (s = cp->datap) ? mkconv(TYLENG,(expptr)s)
01884                                          : ICON(0)));
01885 
01886 /* ... and add them to the end of the argument list */
01887 
01888     hookup (arglist, charsp);
01889 
01890 /* Return the name of the temporary used to hold the results, if any was
01891    necessary. */
01892 
01893     if (temp) *temp = fval;
01894     else frexpr ((expptr)fval);
01895 
01896     saveargtypes(p);
01897 
01898     return (expptr) p;
01899 }
01900 
01901  static expptr
01902 #ifdef KR_headers
01903 foldminmax(op, type, p) int op; int type; chainp p;
01904 #else
01905 foldminmax(int op, int type, chainp p)
01906 #endif
01907 {
01908         Constp c, c1;
01909         ftnint i, i1;
01910         double d, d1;
01911         int dstg, d1stg;
01912         char *s, *s1;
01913 
01914         c = ALLOC(Constblock);
01915         c->tag = TCONST;
01916         c->vtype = type;
01917         s = s1 = 0;
01918 
01919         switch(type) {
01920           case TYREAL:
01921           case TYDREAL:
01922                 c1 = (Constp)p->datap;
01923                 d = ISINT(c1->vtype) ? (double)c1->Const.ci
01924                         : c1->vstg ? atof(c1->Const.cds[0]) : c1->Const.cd[0];
01925                 dstg = 0;
01926                 if (ISINT(c1->vtype))
01927                         d = (double)c1->Const.ci;
01928                 else if (dstg = c1->vstg)
01929                         d = atof(s = c1->Const.cds[0]);
01930                 else
01931                         d = c1->Const.cd[0];
01932                 while(p = p->nextp) {
01933                         c1 = (Constp)p->datap;
01934                         d1stg = 0;
01935                         if (ISINT(c1->vtype))
01936                                 d1 = (double)c1->Const.ci;
01937                         else if (d1stg = c1->vstg)
01938                                 d1 = atof(s1 = c1->Const.cds[0]);
01939                         else
01940                                 d1 = c1->Const.cd[0];
01941                         if (op == OPMIN) {
01942                                 if (d > d1)
01943                                         goto d1copy;
01944                                 }
01945                         else if (d < d1) {
01946  d1copy:
01947                                 d = d1;
01948                                 dstg = d1stg;
01949                                 s = s1;
01950                                 }
01951                         }
01952                 if (c->vstg = dstg)
01953                         c->Const.cds[0] = s;
01954                 else
01955                         c->Const.cd[0] = d;
01956                 break;
01957           default:
01958                 i = ((Constp)p->datap)->Const.ci;
01959                 while(p = p->nextp) {
01960                         i1 = ((Constp)p->datap)->Const.ci;
01961                         if (op == OPMIN) {
01962                                 if (i > i1)
01963                                         i = i1;
01964                                 }
01965                         else if (i < i1)
01966                                 i = i1;
01967                         }
01968                 c->Const.ci = i;
01969                 }
01970         return (expptr)c;
01971         }
01972 
01973 /* putmnmx -- Put min or max.   p   must point to an EXPR, not just a
01974    CONST */
01975 
01976  LOCAL expptr
01977 #ifdef KR_headers
01978 putmnmx(p)
01979         register expptr p;
01980 #else
01981 putmnmx(register expptr p)
01982 #endif
01983 {
01984         int op, op2, type;
01985         expptr arg, qp, temp;
01986         chainp p0, p1;
01987         Addrp sp, tp;
01988         char comment_buf[80];
01989         char *what;
01990 
01991         if(p->tag != TEXPR)
01992                 badtag("putmnmx", p->tag);
01993 
01994         type = p->exprblock.vtype;
01995         op = p->exprblock.opcode;
01996         op2 = op == OPMIN ? OPMIN2 : OPMAX2;
01997         p0 = p->exprblock.leftp->listblock.listp;
01998         free( (charptr) (p->exprblock.leftp) );
01999         free( (charptr) p );
02000 
02001         /* for param statements, deal with constant expressions now */
02002 
02003         for(p1 = p0;; p1 = p1->nextp) {
02004                 if (!p1) {
02005                         /* all constants */
02006                         p = foldminmax(op, type, p0);
02007                         frchain(&p0);
02008                         return p;
02009                         }
02010                 else if (!ISCONST(((expptr)p1->datap)))
02011                         break;
02012                 }
02013 
02014         /* special case for two addressable operands */
02015 
02016         if (addressable((expptr)p0->datap)
02017          && (p1 = p0->nextp)
02018          && addressable((expptr)p1->datap)
02019          && !p1->nextp) {
02020                 if (type == TYREAL && forcedouble)
02021                         op2 = op == OPMIN ? OPDMIN : OPDMAX;
02022                 p = mkexpr(op2, mkconv(type, cpexpr((expptr)p0->datap)),
02023                                 mkconv(type, cpexpr((expptr)p1->datap)));
02024                 frchain(&p0);
02025                 return p;
02026                 }
02027 
02028         /* general case */
02029 
02030         sp = mktmp(type, ENULL);
02031 
02032 /* We only need a second temporary if the arg list has an unaddressable
02033    value */
02034 
02035         tp = (Addrp) NULL;
02036         qp = ENULL;
02037         for (p1 = p0 -> nextp; p1; p1 = p1 -> nextp)
02038                 if (!addressable ((expptr) p1 -> datap)) {
02039                         tp = mktmp(type, ENULL);
02040                         qp = mkexpr(op2, cpexpr((expptr)sp), cpexpr((expptr)tp));
02041                         qp = fixexpr((Exprp)qp);
02042                         break;
02043                 } /* if */
02044 
02045 /* Now output the appropriate number of assignments and comparisons.  Min
02046    and max are implemented by the simple O(n) algorithm:
02047 
02048         min (a, b, c, d) ==>
02049         { <type> t1, t2;
02050 
02051             t1 = a;
02052             t2 = b; t1 = (t1 < t2) ? t1 : t2;
02053             t2 = c; t1 = (t1 < t2) ? t1 : t2;
02054             t2 = d; t1 = (t1 < t2) ? t1 : t2;
02055         }
02056 */
02057 
02058         if (!doin_setbound) {
02059                 switch(op) {
02060                         case OPLT:
02061                         case OPMIN:
02062                         case OPDMIN:
02063                         case OPMIN2:
02064                                 what = "IN";
02065                                 break;
02066                         default:
02067                                 what = "AX";
02068                         }
02069                 sprintf (comment_buf, "Computing M%s", what);
02070                 p1_comment (comment_buf);
02071                 }
02072 
02073         p1 = p0->nextp;
02074         temp = (expptr)p0->datap;
02075         if (addressable(temp) && addressable((expptr)p1->datap)) {
02076                 p = mkconv(type, cpexpr(temp));
02077                 arg = mkconv(type, cpexpr((expptr)p1->datap));
02078                 temp = mkexpr(op2, p, arg);
02079                 if (!ISCONST(temp))
02080                         temp = fixexpr((Exprp)temp);
02081                 p1 = p1->nextp;
02082                 }
02083         p = putassign (cpexpr((expptr)sp), temp);
02084 
02085         for(; p1 ; p1 = p1->nextp)
02086         {
02087                 if (addressable ((expptr) p1 -> datap)) {
02088                         arg = mkconv(type, cpexpr((expptr)p1->datap));
02089                         temp = mkexpr(op2, cpexpr((expptr)sp), arg);
02090                         temp = fixexpr((Exprp)temp);
02091                 } else {
02092                         temp = (expptr) cpexpr (qp);
02093                         p = mkexpr(OPCOMMA, p,
02094                                 putassign(cpexpr((expptr)tp), (expptr)p1->datap));
02095                 } /* else */
02096 
02097                 if(p1->nextp)
02098                         p = mkexpr(OPCOMMA, p,
02099                                 putassign(cpexpr((expptr)sp), temp));
02100                 else {
02101                         if (type == TYREAL && forcedouble)
02102                                 temp->exprblock.opcode =
02103                                         op == OPMIN ? OPDMIN : OPDMAX;
02104                         if (doin_setbound)
02105                                 p = mkexpr(OPCOMMA, p, temp);
02106                         else {
02107                                 putout (p);
02108                                 p = putx(temp);
02109                                 }
02110                         if (qp)
02111                                 frexpr (qp);
02112                 } /* else */
02113         } /* for */
02114 
02115         frchain( &p0 );
02116         return p;
02117 }
02118 
02119 
02120  void
02121 #ifdef KR_headers
02122 putwhile(p)
02123         expptr p;
02124 #else
02125 putwhile(expptr p)
02126 #endif
02127 {
02128         int k, n;
02129 
02130         if (wh_next >= wh_last)
02131                 {
02132                 k = wh_last - wh_first;
02133                 n = k + 100;
02134                 wh_next = mem(n,0);
02135                 wh_last = wh_first + n;
02136                 if (k)
02137                         memcpy(wh_next, wh_first, k);
02138                 wh_first =  wh_next;
02139                 wh_next += k;
02140                 wh_last = wh_first + n;
02141                 }
02142         if( !ISLOGICAL((k = (p = fixtype(p))->headblock.vtype)))
02143                 {
02144                 if(k != TYERROR)
02145                         err("non-logical expression in DO WHILE statement");
02146                 }
02147         else    {
02148                 p = putx(p);
02149                 *wh_next++ = ftell(pass1_file) > p1_where;
02150                 p1put(P1_WHILE2START);
02151                 p1_expr(p);
02152                 }
02153         }
02154 
02155  void
02156 #ifdef KR_headers
02157 westart(elseif) int elseif;
02158 #else
02159 westart(int elseif)
02160 #endif
02161 {
02162         static int we[2] = { P1_WHILE1START, P1_ELSEIFSTART };
02163         p1put(we[elseif]);
02164         p1_where = ftell(pass1_file);
02165         }

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