Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

expr.c File Reference

#include "defs.h"
#include "output.h"
#include "names.h"

Go to the source code of this file.


Data Structures

struct  dcomplex

Defines

#define ICONEQ(z, c)   (ISICON(z) && z->constblock.Const.ci==c)
#define COMMUTE   { e = lp; lp = rp; rp = e; }
#define ERR(s)   { errs = s; goto error; }

Functions

void consbinop Argdcl ((int, int, Constp, Constp, Constp))
void conspower Argdcl ((Constp, Constp, long int))
void zdiv Argdcl ((dcomplex *, dcomplex *, dcomplex *))
tagptr mkpower Argdcl ((tagptr))
tagptr stfcall Argdcl ((Namep, struct Listblock *))
Constp mkconst (register int t)
expptr mklogcon (register int l)
expptr mkintcon (ftnint l)
expptr mkaddcon (register long l)
expptr mkrealcon (register int t, char *d)
expptr mkbitcon (int shift, int leng, char *s)
expptr mkstrcon (int l, register char *v)
expptr mkcxcon (register expptr realp, register expptr imagp)
expptr mkconv (register int t, register expptr p)
expptr opconv (expptr p, int t)
expptr addrof (expptr p)
tagptr cpexpr (register tagptr p)
void frexpr (register tagptr p)
void wronginf (Namep np)
expptr fixtype (register tagptr p)
int badchleng (register expptr p)
expptr cplenexpr (expptr p)
expptr fixexpr (register Exprp p)
int fixargs (int doput, struct Listblock *p0)
Addrp mkscalar (register Namep np)
void adjust_arginfo (register Namep np)
expptr mkfunct (expptr p0)
expptr stfcall (Namep np, struct Listblock *actlist)
Addrp mkplace (register Namep np)
expptr subskept (struct Primblock *p, Addrp a)
expptr mklhs (register struct Primblock *p, int subkeep)
void deregister (Namep np)
Addrp memversion (register Namep np)
int inregister (register Namep np)
expptr suboffset (register struct Primblock *p)
expptr subcheck (Namep np, register expptr p)
Addrp mkaddr (register Namep p)
Addrp mkarg (int type, int argno)
expptr mkprim (Namep v0, struct Listblock *args, chainp substr)
void vardcl (register Namep v)
void impldcl (register Namep p)
void inferdcl (Namep np, int type)
LOCAL int zeroconst (expptr e)
expptr mkexpr (int opcode, register expptr lp, register expptr rp)
 cktype (register int op, register int lt, register int rt)
void intovfl (Void)
expptr fold (register expptr e)
void consconv (int lt, register Constp lc, register Constp rc)
void consnegop (register Constp p)
LOCAL void conspower (Constp p, Constp ap, ftnint n)
LOCAL void consbinop (int opcode, int type, Constp cpp, Constp app, Constp bpp)
 conssgn (register expptr p)
LOCAL expptr mkpower (register expptr p)
LOCAL void zdiv (register dcomplex *c, register dcomplex *a, register dcomplex *b)
void sserr (Namep np)

Variables

char dflttype [26]
int htype
expptr errnode (Void)
int replaced
int doing_vleng
char * powint []

Define Documentation

#define COMMUTE   { e = lp; lp = rp; rp = e; }
 

Definition at line 2014 of file expr.c.

Referenced by mkexpr().

#define ERR      { errs = s; goto error; }
 

Definition at line 2348 of file expr.c.

#define ICONEQ z,
c       (ISICON(z) && z->constblock.Const.ci==c)
 

Definition at line 2013 of file expr.c.

Referenced by mkexpr().


Function Documentation

expptr addrof expptr    p
 

Definition at line 380 of file expr.c.

References ENULL, mkexpr(), and OPADDR.

Referenced by ioseta(), iosetc(), iosetip(), and putct1().

00382 {
00383         return( mkexpr(OPADDR, p, ENULL) );
00384 }

void adjust_arginfo register Namep    np [static]
 

Definition at line 1001 of file expr.c.

References Extsym::arginfo, Entrypoint::arglist, args, Entrypoint::entnextp, Entrypoint::entryname, and Argtypes::nargs.

Referenced by mkfunct().

01006 {
01007         struct Entrypoint *ep;
01008         register chainp args;
01009         Argtypes *at;
01010 
01011         for(ep = entries; ep; ep = ep->entnextp)
01012                 for(args = ep->arglist; args; args = args->nextp)
01013                         if (np == (Namep)args->datap
01014                         && (at = ep->entryname->arginfo))
01015                                 --at->nargs;
01016         }

tagptr stfcall Argdcl (Namep, struct Listblock *)    [static]
 

tagptr mkpower Argdcl (tagptr   [static]
 

void zdiv Argdcl (dcomplex *, dcomplex *, dcomplex *)    [static]
 

void conspower Argdcl (Constp, Constp, long int)    [static]
 

void consbinop Argdcl (int, int, Constp, Constp, Constp   [static]
 

int badchleng register expptr    p
 

Definition at line 635 of file expr.c.

References Expression::addrblock, err, errstr(), Expression::headblock, TADDR, Headblock::tag, UNAM_NAME, Addrblock::uname_tag, Addrblock::user, and Headblock::vleng.

Referenced by cplenexpr(), and putcheq().

00637 {
00638         if (!p->headblock.vleng) {
00639                 if (p->headblock.tag == TADDR
00640                 && p->addrblock.uname_tag == UNAM_NAME)
00641                         errstr("bad use of character*(*) variable %.60s",
00642                                 p->addrblock.user.name->fvarname);
00643                 else
00644                         err("Bad use of character*(*)");
00645                 return 1;
00646                 }
00647         return 0;
00648         }

cktype register int    op,
register int    lt,
register int    rt
 

Definition at line 2358 of file expr.c.

References badop(), err, ERR, htype, is_unary_op, ISCOMPLEX, ISINT, ISLOGICAL, ISNUMERIC, maxtype(), OPABS, OPADDR, OPAND, OPARROW, OPASSIGN, OPASSIGNI, OPBITAND, OPBITANDEQ, OPBITCLR, OPBITNOT, OPBITOR, OPBITOREQ, OPBITSET, OPBITTEST, OPBITXOR, OPBITXOREQ, OPCALL, OPCCALL, OPCHARCAST, OPCOLON, OPCOMMA, OPCOMMA_ARG, OPCONCAT, OPCONV, OPDABS, OPDMAX, OPDMIN, OPDOT, OPEQ, OPEQV, OPGE, OPGT, OPIDENTITY, OPLE, OPLSHIFT, OPLSHIFTEQ, OPLT, OPMAX, OPMAX2, OPMIN, OPMIN2, OPMINUS, OPMINUSEQ, OPMOD, OPMODEQ, OPNE, OPNEG, OPNEG1, OPNEQV, OPNOT, OPOR, OPPLUS, OPPLUSEQ, OPPOWER, OPQBITCLR, OPQBITSET, OPQUEST, OPRSHIFT, OPRSHIFTEQ, OPSLASH, OPSLASHEQ, OPSTAR, OPSTAREQ, OPWHATSIN, TYERROR, and TYQUAD.

Referenced by fixexpr(), mkexpr(), and setdata().

02360 {
02361         char *errs;
02362 
02363         if(lt==TYERROR || rt==TYERROR)
02364                 goto error1;
02365 
02366         if(lt==TYUNKNOWN)
02367                 return(TYUNKNOWN);
02368         if(rt==TYUNKNOWN)
02369 
02370 /* If not unary operation, return UNKNOWN */
02371 
02372                 if(!is_unary_op (op) && op != OPCALL && op != OPCCALL)
02373                         return(TYUNKNOWN);
02374 
02375         switch(op)
02376         {
02377         case OPPLUS:
02378         case OPMINUS:
02379         case OPSTAR:
02380         case OPSLASH:
02381         case OPPOWER:
02382         case OPMOD:
02383                 if( ISNUMERIC(lt) && ISNUMERIC(rt) )
02384                         return( maxtype(lt, rt) );
02385                 ERR("nonarithmetic operand of arithmetic operator")
02386 
02387         case OPNEG:
02388         case OPNEG1:
02389                 if( ISNUMERIC(lt) )
02390                         return(lt);
02391                 ERR("nonarithmetic operand of negation")
02392 
02393         case OPNOT:
02394                 if(ISLOGICAL(lt))
02395                         return(lt);
02396                 ERR("NOT of nonlogical")
02397 
02398         case OPAND:
02399         case OPOR:
02400         case OPEQV:
02401         case OPNEQV:
02402                 if(ISLOGICAL(lt) && ISLOGICAL(rt))
02403                         return( maxtype(lt, rt) );
02404                 ERR("nonlogical operand of logical operator")
02405 
02406         case OPLT:
02407         case OPGT:
02408         case OPLE:
02409         case OPGE:
02410         case OPEQ:
02411         case OPNE:
02412                 if(lt==TYCHAR || rt==TYCHAR || ISLOGICAL(lt) || ISLOGICAL(rt))
02413                 {
02414                         if(lt != rt){
02415                                 if (htype
02416                                         && (lt == TYCHAR && ISNUMERIC(rt)
02417                                          || rt == TYCHAR && ISNUMERIC(lt)))
02418                                                 return TYLOGICAL;
02419                                 ERR("illegal comparison")
02420                                 }
02421                 }
02422 
02423                 else if( ISCOMPLEX(lt) || ISCOMPLEX(rt) )
02424                 {
02425                         if(op!=OPEQ && op!=OPNE)
02426                                 ERR("order comparison of complex data")
02427                 }
02428 
02429                 else if( ! ISNUMERIC(lt) || ! ISNUMERIC(rt) )
02430                         ERR("comparison of nonarithmetic data")
02431         case OPBITTEST:
02432                 return(TYLOGICAL);
02433 
02434         case OPCONCAT:
02435                 if(lt==TYCHAR && rt==TYCHAR)
02436                         return(TYCHAR);
02437                 ERR("concatenation of nonchar data")
02438 
02439         case OPCALL:
02440         case OPCCALL:
02441         case OPIDENTITY:
02442                 return(lt);
02443 
02444         case OPADDR:
02445         case OPCHARCAST:
02446                 return(TYADDR);
02447 
02448         case OPCONV:
02449                 if(rt == 0)
02450                         return(0);
02451                 if(lt==TYCHAR && ISINT(rt) )
02452                         return(TYCHAR);
02453                 if (ISLOGICAL(lt) && ISLOGICAL(rt))
02454                         return lt;
02455         case OPASSIGN:
02456         case OPASSIGNI:
02457         case OPMINUSEQ:
02458         case OPPLUSEQ:
02459         case OPSTAREQ:
02460         case OPSLASHEQ:
02461         case OPMODEQ:
02462         case OPLSHIFTEQ:
02463         case OPRSHIFTEQ:
02464         case OPBITANDEQ:
02465         case OPBITXOREQ:
02466         case OPBITOREQ:
02467                 if( ISINT(lt) && rt==TYCHAR)
02468                         return(lt);
02469                 if (ISLOGICAL(lt) && ISLOGICAL(rt) && op == OPASSIGN)
02470                         return lt;
02471                 if(lt==TYCHAR || rt==TYCHAR || ISLOGICAL(lt) || ISLOGICAL(rt))
02472                         if((op!=OPASSIGN && op != OPPLUSEQ && op != OPMINUSEQ)
02473                             || (lt!=rt))
02474                         {
02475                                 ERR("impossible conversion")
02476                         }
02477                 return(lt);
02478 
02479         case OPMIN:
02480         case OPMAX:
02481         case OPDMIN:
02482         case OPDMAX:
02483         case OPMIN2:
02484         case OPMAX2:
02485         case OPBITOR:
02486         case OPBITAND:
02487         case OPBITXOR:
02488         case OPBITNOT:
02489         case OPLSHIFT:
02490         case OPRSHIFT:
02491         case OPWHATSIN:
02492         case OPABS:
02493         case OPDABS:
02494                 return(lt);
02495 
02496         case OPBITCLR:
02497         case OPBITSET:
02498                 if (lt < TYLONG)
02499                         lt = TYLONG;
02500                 return(lt);
02501 #ifdef TYQUAD
02502         case OPQBITCLR:
02503         case OPQBITSET:
02504                 return TYQUAD;
02505 #endif
02506 
02507         case OPCOMMA:
02508         case OPCOMMA_ARG:
02509         case OPQUEST:
02510         case OPCOLON:           /* Only checks the rightmost type because
02511                                    of C language definition (rightmost
02512                                    comma-expr is the value of the expr) */
02513                 return(rt);
02514 
02515         case OPDOT:
02516         case OPARROW:
02517             return (lt);
02518         default:
02519                 badop("cktype", op);
02520         }
02521 error:
02522         err(errs);
02523 error1:
02524         return(TYERROR);
02525 }

LOCAL void consbinop int    opcode,
int    type,
Constp    cpp,
Constp    app,
Constp    bpp
 

Definition at line 2994 of file expr.c.

References a, Constant::cd, Constant::cds, Constant::ci, Constblock::Const, Fatal(), intovfl(), ISCOMPLEX, ISINT, MSKCOMPLEX, MSKREAL, ONEOF, OPDMAX, OPDMIN, OPEQ, OPGE, OPGT, OPLE, OPLT, OPMAX2, OPMIN2, OPMINUS, OPMOD, OPNE, OPPLUS, OPSLASH, OPSTAR, TYQUAD, Constblock::vstg, and zdiv().

Referenced by conspower(), and fold().

02996 {
02997         register union Constant *ap = &app->Const,
02998                                 *bp = &bpp->Const,
02999                                 *cp = &cpp->Const;
03000         int k;
03001         double ad[2], bd[2], temp;
03002         ftnint a, b;
03003 
03004         cpp->vstg = 0;
03005 
03006         if (ONEOF(type, MSKREAL|MSKCOMPLEX)) {
03007                 ad[0] = app->vstg ? atof(ap->cds[0]) : ap->cd[0];
03008                 bd[0] = bpp->vstg ? atof(bp->cds[0]) : bp->cd[0];
03009                 if (ISCOMPLEX(type)) {
03010                         ad[1] = app->vstg ? atof(ap->cds[1]) : ap->cd[1];
03011                         bd[1] = bpp->vstg ? atof(bp->cds[1]) : bp->cd[1];
03012                         }
03013                 }
03014         switch(opcode)
03015         {
03016         case OPPLUS:
03017                 switch(type)
03018                 {
03019                 case TYINT1:
03020                 case TYSHORT:
03021                 case TYLONG:
03022 #ifdef TYQUAD
03023                 case TYQUAD:
03024 #endif
03025                         cp->ci = ap->ci + bp->ci;
03026                         if (ap->ci != cp->ci - bp->ci)
03027                                 intovfl();
03028                         break;
03029                 case TYCOMPLEX:
03030                 case TYDCOMPLEX:
03031                         cp->cd[1] = ad[1] + bd[1];
03032                 case TYREAL:
03033                 case TYDREAL:
03034                         cp->cd[0] = ad[0] + bd[0];
03035                         break;
03036                 }
03037                 break;
03038 
03039         case OPMINUS:
03040                 switch(type)
03041                 {
03042                 case TYINT1:
03043                 case TYSHORT:
03044                 case TYLONG:
03045 #ifdef TYQUAD
03046                 case TYQUAD:
03047 #endif
03048                         cp->ci = ap->ci - bp->ci;
03049                         if (ap->ci != bp->ci + cp->ci)
03050                                 intovfl();
03051                         break;
03052                 case TYCOMPLEX:
03053                 case TYDCOMPLEX:
03054                         cp->cd[1] = ad[1] - bd[1];
03055                 case TYREAL:
03056                 case TYDREAL:
03057                         cp->cd[0] = ad[0] - bd[0];
03058                         break;
03059                 }
03060                 break;
03061 
03062         case OPSTAR:
03063                 switch(type)
03064                 {
03065                 case TYINT1:
03066                 case TYSHORT:
03067                 case TYLONG:
03068 #ifdef TYQUAD
03069                 case TYQUAD:
03070 #endif
03071                         cp->ci = (a = ap->ci) * (b = bp->ci);
03072                         if (a && cp->ci / a != b)
03073                                 intovfl();
03074                         break;
03075                 case TYREAL:
03076                 case TYDREAL:
03077                         cp->cd[0] = ad[0] * bd[0];
03078                         break;
03079                 case TYCOMPLEX:
03080                 case TYDCOMPLEX:
03081                         temp = ad[0] * bd[0]  -  ad[1] * bd[1] ;
03082                         cp->cd[1] = ad[0] * bd[1]  +  ad[1] * bd[0] ;
03083                         cp->cd[0] = temp;
03084                         break;
03085                 }
03086                 break;
03087         case OPSLASH:
03088                 switch(type)
03089                 {
03090                 case TYINT1:
03091                 case TYSHORT:
03092                 case TYLONG:
03093 #ifdef TYQUAD
03094                 case TYQUAD:
03095 #endif
03096                         cp->ci = ap->ci / bp->ci;
03097                         break;
03098                 case TYREAL:
03099                 case TYDREAL:
03100                         cp->cd[0] = ad[0] / bd[0];
03101                         break;
03102                 case TYCOMPLEX:
03103                 case TYDCOMPLEX:
03104                         zdiv((dcomplex*)cp, (dcomplex*)ad, (dcomplex*)bd);
03105                         break;
03106                 }
03107                 break;
03108 
03109         case OPMOD:
03110                 if( ISINT(type) )
03111                 {
03112                         cp->ci = ap->ci % bp->ci;
03113                         break;
03114                 }
03115                 else
03116                         Fatal("inline mod of noninteger");
03117 
03118         case OPMIN2:
03119         case OPDMIN:
03120                 switch(type)
03121                 {
03122                 case TYINT1:
03123                 case TYSHORT:
03124                 case TYLONG:
03125 #ifdef TYQUAD
03126                 case TYQUAD:
03127 #endif
03128                         cp->ci = ap->ci <= bp->ci ? ap->ci : bp->ci;
03129                         break;
03130                 case TYREAL:
03131                 case TYDREAL:
03132                         cp->cd[0] = ad[0] <= bd[0] ? ad[0] : bd[0];
03133                         break;
03134                 default:
03135                         Fatal("inline min of exected type");
03136                 }
03137                 break;
03138 
03139         case OPMAX2:
03140         case OPDMAX:
03141                 switch(type)
03142                 {
03143                 case TYINT1:
03144                 case TYSHORT:
03145                 case TYLONG:
03146 #ifdef TYQUAD
03147                 case TYQUAD:
03148 #endif
03149                         cp->ci = ap->ci >= bp->ci ? ap->ci : bp->ci;
03150                         break;
03151                 case TYREAL:
03152                 case TYDREAL:
03153                         cp->cd[0] = ad[0] >= bd[0] ? ad[0] : bd[0];
03154                         break;
03155                 default:
03156                         Fatal("inline max of exected type");
03157                 }
03158                 break;
03159 
03160         default:          /* relational ops */
03161                 switch(type)
03162                 {
03163                 case TYINT1:
03164                 case TYSHORT:
03165                 case TYLONG:
03166 #ifdef TYQUAD
03167                 case TYQUAD:
03168 #endif
03169                         if(ap->ci < bp->ci)
03170                                 k = -1;
03171                         else if(ap->ci == bp->ci)
03172                                 k = 0;
03173                         else    k = 1;
03174                         break;
03175                 case TYREAL:
03176                 case TYDREAL:
03177                         if(ad[0] < bd[0])
03178                                 k = -1;
03179                         else if(ad[0] == bd[0])
03180                                 k = 0;
03181                         else    k = 1;
03182                         break;
03183                 case TYCOMPLEX:
03184                 case TYDCOMPLEX:
03185                         if(ad[0] == bd[0] &&
03186                             ad[1] == bd[1] )
03187                                 k = 0;
03188                         else    k = 1;
03189                         break;
03190                 case TYLOGICAL:
03191                         k = ap->ci - bp->ci;
03192                 }
03193 
03194                 switch(opcode)
03195                 {
03196                 case OPEQ:
03197                         cp->ci = (k == 0);
03198                         break;
03199                 case OPNE:
03200                         cp->ci = (k != 0);
03201                         break;
03202                 case OPGT:
03203                         cp->ci = (k == 1);
03204                         break;
03205                 case OPLT:
03206                         cp->ci = (k == -1);
03207                         break;
03208                 case OPGE:
03209                         cp->ci = (k >= 0);
03210                         break;
03211                 case OPLE:
03212                         cp->ci = (k <= 0);
03213                         break;
03214                 }
03215                 break;
03216         }
03217 }

void consconv int    lt,
register Constp    lc,
register Constp    rc
 

Definition at line 2759 of file expr.c.

References Constant::ccp1, Constant::cd, cds(), Constant::cds, Constant::ci, ckalloc(), CNULL, Constblock::Const, ISCOMPLEX, ISINT, ISREAL, MSKCOMPLEX, MSKREAL, ONEOF, TYQUAD, Constblock::vstg, and Constblock::vtype.

Referenced by fold(), mkconv(), and setdata().

02761 {
02762         int rt = rc->vtype;
02763         register union Constant *lv = &lc->Const, *rv = &rc->Const;
02764 
02765         lc->vtype = lt;
02766         if (ONEOF(lt, MSKREAL|MSKCOMPLEX) && ONEOF(rt, MSKREAL|MSKCOMPLEX)) {
02767                 memcpy((char *)lv, (char *)rv, sizeof(union Constant));
02768                 lc->vstg = rc->vstg;
02769                 if (ISCOMPLEX(lt) && ISREAL(rt)) {
02770                         if (rc->vstg)
02771                                 lv->cds[1] = cds("0",CNULL);
02772                         else
02773                                 lv->cd[1] = 0.;
02774                         }
02775                 return;
02776                 }
02777         lc->vstg = 0;
02778 
02779         switch(lt)
02780         {
02781 
02782 /* Casting to character means just copying the first sizeof (character)
02783    bytes into a new 1 character string.  This is weird. */
02784 
02785         case TYCHAR:
02786                 *(lv->ccp = (char *) ckalloc(1)) = rv->ci;
02787                 lv->ccp1.blanks = 0;
02788                 break;
02789 
02790         case TYINT1:
02791         case TYSHORT:
02792         case TYLONG:
02793 #ifdef TYQUAD
02794         case TYQUAD:
02795 #endif
02796                 if(rt == TYCHAR)
02797                         lv->ci = rv->ccp[0];
02798                 else if( ISINT(rt) )
02799                         lv->ci = rv->ci;
02800                 else    lv->ci = rc->vstg ? atof(rv->cds[0]) : rv->cd[0];
02801 
02802                 break;
02803 
02804         case TYCOMPLEX:
02805         case TYDCOMPLEX:
02806                 lv->cd[1] = 0.;
02807                 lv->cd[0] = rv->ci;
02808                 break;
02809 
02810         case TYREAL:
02811         case TYDREAL:
02812                 lv->cd[0] = rv->ci;
02813                 break;
02814 
02815         case TYLOGICAL:
02816         case TYLOGICAL1:
02817         case TYLOGICAL2:
02818                 lv->ci = rv->ci;
02819                 break;
02820         }
02821 }

void consnegop register Constp    p
 

Definition at line 2832 of file expr.c.

References badtype(), intovfl(), ISCOMPLEX, L, and TYQUAD.

Referenced by fold(), mkexpr(), and yyparse().

02834 {
02835         register char *s;
02836         ftnint L;
02837 
02838         if (p->vstg) {
02839                 if (ISCOMPLEX(p->vtype)) {
02840                         s = p->Const.cds[1];
02841                         p->Const.cds[1] = *s == '-' ? s+1
02842                                         : *s == '0' ? s : s-1;
02843                         }
02844                 s = p->Const.cds[0];
02845                 p->Const.cds[0] = *s == '-' ? s+1
02846                                 : *s == '0' ? s : s-1;
02847                 return;
02848                 }
02849         switch(p->vtype)
02850         {
02851         case TYINT1:
02852         case TYSHORT:
02853         case TYLONG:
02854 #ifdef TYQUAD
02855         case TYQUAD:
02856 #endif
02857                 p->Const.ci = -(L = p->Const.ci);
02858                 if (L != -p->Const.ci)
02859                         intovfl();
02860                 break;
02861 
02862         case TYCOMPLEX:
02863         case TYDCOMPLEX:
02864                 p->Const.cd[1] = - p->Const.cd[1];
02865                 /* fall through and do the real parts */
02866         case TYREAL:
02867         case TYDREAL:
02868                 p->Const.cd[0] = - p->Const.cd[0];
02869                 break;
02870         default:
02871                 badtype("consnegop", p->vtype);
02872         }
02873 }

LOCAL void conspower Constp    p,
Constp    ap,
ftnint    n
 

Definition at line 2886 of file expr.c.

References badtype(), Constant::cd, Constant::cds, Constant::ci, consbinop(), Constblock::Const, err, ISCOMPLEX, ISINT, OPSLASH, OPSTAR, TYQUAD, Constblock::vstg, and Constblock::vtype.

Referenced by fold().

02888 {
02889         register union Constant *powp = &p->Const;
02890         register int type;
02891         struct Constblock x, x0;
02892 
02893         if (n == 1) {
02894                 memcpy((char *)powp, (char *)&ap->Const, sizeof(ap->Const));
02895                 return;
02896                 }
02897 
02898         switch(type = ap->vtype)        /* pow = 1 */
02899         {
02900         case TYINT1:
02901         case TYSHORT:
02902         case TYLONG:
02903 #ifdef TYQUAD
02904         case TYQUAD:
02905 #endif
02906                 powp->ci = 1;
02907                 break;
02908         case TYCOMPLEX:
02909         case TYDCOMPLEX:
02910                 powp->cd[1] = 0;
02911         case TYREAL:
02912         case TYDREAL:
02913                 powp->cd[0] = 1;
02914                 break;
02915         default:
02916                 badtype("conspower", type);
02917         }
02918 
02919         if(n == 0)
02920                 return;
02921         switch(type)    /* x0 = ap */
02922         {
02923         case TYINT1:
02924         case TYSHORT:
02925         case TYLONG:
02926 #ifdef TYQUAD
02927         case TYQUAD:
02928 #endif
02929                 x0.Const.ci = ap->Const.ci;
02930                 break;
02931         case TYCOMPLEX:
02932         case TYDCOMPLEX:
02933                 x0.Const.cd[1] =
02934                         ap->vstg ? atof(ap->Const.cds[1]) : ap->Const.cd[1];
02935         case TYREAL:
02936         case TYDREAL:
02937                 x0.Const.cd[0] =
02938                         ap->vstg ? atof(ap->Const.cds[0]) : ap->Const.cd[0];
02939                 break;
02940         }
02941         x0.vtype = type;
02942         x0.vstg = 0;
02943         if(n < 0)
02944         {
02945                 n = -n;
02946                 if( ISINT(type) )
02947                 {
02948                         switch(ap->Const.ci) {
02949                                 case 0:
02950                                         err("0 ** negative number");
02951                                         return;
02952                                 case 1:
02953                                 case -1:
02954                                         goto mult;
02955                                 }
02956                         err("integer ** negative number");
02957                         return;
02958                 }
02959                 else if (!x0.Const.cd[0]
02960                                 && (!ISCOMPLEX(type) || !x0.Const.cd[1])) {
02961                         err("0.0 ** negative number");
02962                         return;
02963                         }
02964                 consbinop(OPSLASH, type, &x, p, &x0);
02965         }
02966         else
02967  mult:          consbinop(OPSTAR, type, &x, p, &x0);
02968 
02969         for( ; ; )
02970         {
02971                 if(n & 01)
02972                         consbinop(OPSTAR, type, p, p, &x);
02973                 if(n >>= 1)
02974                         consbinop(OPSTAR, type, &x, &x, &x);
02975                 else
02976                         break;
02977         }
02978 }

conssgn register expptr    p
 

Definition at line 3227 of file expr.c.

References badtype(), Constant::cd, Constant::cds, Constant::ci, Constblock::Const, Expression::constblock, Fatal(), Expression::headblock, ISCONST, TYQUAD, Constblock::vstg, Constblock::vtype, and Headblock::vtype.

Referenced by exdo().

03229 {
03230         register char *s;
03231 
03232         if( ! ISCONST(p) )
03233                 Fatal( "sgn(nonconstant)" );
03234 
03235         switch(p->headblock.vtype)
03236         {
03237         case TYINT1:
03238         case TYSHORT:
03239         case TYLONG:
03240 #ifdef TYQUAD
03241         case TYQUAD:
03242 #endif
03243                 if(p->constblock.Const.ci > 0) return(1);
03244                 if(p->constblock.Const.ci < 0) return(-1);
03245                 return(0);
03246 
03247         case TYREAL:
03248         case TYDREAL:
03249                 if (p->constblock.vstg) {
03250                         s = p->constblock.Const.cds[0];
03251                         if (*s == '-')
03252                                 return -1;
03253                         if (*s == '0')
03254                                 return 0;
03255                         return 1;
03256                         }
03257                 if(p->constblock.Const.cd[0] > 0) return(1);
03258                 if(p->constblock.Const.cd[0] < 0) return(-1);
03259                 return(0);
03260 
03261 
03262 /* The sign of a complex number is 0 iff the number is 0 + 0i, else it's 1 */
03263 
03264         case TYCOMPLEX:
03265         case TYDCOMPLEX:
03266                 if (p->constblock.vstg)
03267                         return *p->constblock.Const.cds[0] != '0'
03268                             && *p->constblock.Const.cds[1] != '0';
03269                 return(p->constblock.Const.cd[0]!=0 || p->constblock.Const.cd[1]!=0);
03270 
03271         default:
03272                 badtype( "conssgn", p->constblock.vtype);
03273         }
03274         /* NOT REACHED */ return 0;
03275 }

tagptr cpexpr register tagptr    p
 

Definition at line 395 of file expr.c.

References Expression::addrblock, Primblock::argsp, badtag(), CHNULL, Constant::ci, Constblock::Const, Expression::constblock, copyn(), cpblock(), Chain::datap, ep, Expression::exprblock, frexpr(), Addrblock::istemp, Exprblock::leftp, Expression::listblock, Listblock::listp, Addrblock::memoffset, mkchain(), Chain::nextp, NO, Expression::primblock, Exprblock::rightp, TADDR, Expression::tag, TCONST, TERROR, TEXPR, TLIST, TNAME, TPRIM, Addrblock::vleng, Constblock::vleng, and Constblock::vtype.

Referenced by add_extern_to_list(), cast_args(), copy_data(), cplenexpr(), declare_new_addr(), dofclose(), dofinquire(), dofmove(), dofopen(), doiolist(), endio(), exarif(), exdo(), imagpart(), Inline(), intdouble(), iosetc(), iosetip(), iosetlc(), krput(), mkaddr(), mkfunct(), mklhs(), mkplace(), mkprim(), mktmp(), nextdata(), p1_const(), p1_subr_ret(), prolog(), putcall(), putcat(), putch1(), putconst(), putct1(), putcx1(), putiocall(), putmnmx(), putop(), putpower(), putsteq(), realpart(), retval(), setbound(), startrw(), stfcall(), subcheck(), suboffset(), subskept(), and yyparse().

00397 {
00398         register tagptr e;
00399         int tag;
00400         register chainp ep, pp;
00401 
00402 /* This table depends on the ordering of the T macros, e.g. TNAME */
00403 
00404         static int blksize[ ] =
00405         {
00406                 0,
00407                 sizeof(struct Nameblock),
00408                 sizeof(struct Constblock),
00409                 sizeof(struct Exprblock),
00410                 sizeof(struct Addrblock),
00411                 sizeof(struct Primblock),
00412                 sizeof(struct Listblock),
00413                 sizeof(struct Impldoblock),
00414                 sizeof(struct Errorblock)
00415         };
00416 
00417         if(p == NULL)
00418                 return(NULL);
00419 
00420 /* TNAMEs are special, and don't get copied.  Each name in the current
00421    symbol table has a unique TNAME structure. */
00422 
00423         if( (tag = p->tag) == TNAME)
00424                 return(p);
00425 
00426         e = cpblock(blksize[p->tag], (char *)p);
00427 
00428         switch(tag)
00429         {
00430         case TCONST:
00431                 if(e->constblock.vtype == TYCHAR)
00432                 {
00433                         e->constblock.Const.ccp =
00434                             copyn((int)e->constblock.vleng->constblock.Const.ci+1,
00435                                 e->constblock.Const.ccp);
00436                         e->constblock.vleng =
00437                             (expptr) cpexpr(e->constblock.vleng);
00438                 }
00439         case TERROR:
00440                 break;
00441 
00442         case TEXPR:
00443                 e->exprblock.leftp =  (expptr) cpexpr(p->exprblock.leftp);
00444                 e->exprblock.rightp = (expptr) cpexpr(p->exprblock.rightp);
00445                 break;
00446 
00447         case TLIST:
00448                 if(pp = p->listblock.listp)
00449                 {
00450                         ep = e->listblock.listp =
00451                             mkchain((char *)cpexpr((tagptr)pp->datap), CHNULL);
00452                         for(pp = pp->nextp ; pp ; pp = pp->nextp)
00453                                 ep = ep->nextp =
00454                                     mkchain((char *)cpexpr((tagptr)pp->datap),
00455                                                 CHNULL);
00456                 }
00457                 break;
00458 
00459         case TADDR:
00460                 e->addrblock.vleng = (expptr)  cpexpr(e->addrblock.vleng);
00461                 e->addrblock.memoffset = (expptr)cpexpr(e->addrblock.memoffset);
00462                 e->addrblock.istemp = NO;
00463                 break;
00464 
00465         case TPRIM:
00466                 e->primblock.argsp = (struct Listblock *)
00467                     cpexpr((expptr)e->primblock.argsp);
00468                 e->primblock.fcharp = (expptr) cpexpr(e->primblock.fcharp);
00469                 e->primblock.lcharp = (expptr) cpexpr(e->primblock.lcharp);
00470                 break;
00471 
00472         default:
00473                 badtag("cpexpr", tag);
00474         }
00475 
00476         return(e);
00477 }

expptr cplenexpr expptr    p [static]
 

Definition at line 656 of file expr.c.

References badchleng(), Constant::ccp1, Constant::ci, Constblock::Const, Expression::constblock, cpexpr(), Expression::headblock, ICON, ISCONST, Headblock::vleng, and Constblock::vtype.

Referenced by fixexpr().

00658 {
00659         expptr rv;
00660 
00661         if (badchleng(p))
00662                 return ICON(1);
00663         rv = cpexpr(p->headblock.vleng);
00664         if (ISCONST(p) && p->constblock.vtype == TYCHAR)
00665                 rv->constblock.Const.ci += p->constblock.Const.ccp1.blanks;
00666         return rv;
00667         }

void deregister Namep    np
 

Definition at line 1464 of file expr.c.

Referenced by enddo().

01466 {
01467         if(nregvar>0 && regnamep[nregvar-1]==np)
01468         {
01469                 --nregvar;
01470         }
01471 }

int fixargs int    doput,
struct Listblock   p0
 

Definition at line 902 of file expr.c.

References Primblock::argsp, CLPROC, Chain::datap, Primblock::fcharp, fixtype(), Primblock::lcharp, Listblock::listp, memversion(), mkaddr(), mkscalar(), Primblock::namep, Chain::nextp, Expression::primblock, PTHISPROC, putconst(), q, sserr(), Expression::tag, TCONST, TPRIM, Nameblock::vclass, Nameblock::vdim, Nameblock::vdovar, Nameblock::vprocclass, and Nameblock::vtype.

Referenced by intrcall(), and mkfunct().

00905 {
00906         register chainp p;
00907         register tagptr q, t;
00908         register int qtag;
00909         int nargs;
00910 
00911         nargs = 0;
00912         if(p0)
00913                 for(p = p0->listp ; p ; p = p->nextp)
00914                 {
00915                         ++nargs;
00916                         q = (tagptr)p->datap;
00917                         qtag = q->tag;
00918                         if(qtag == TCONST)
00919                         {
00920 
00921 /* Call putconst() to store values in a constant table.  Since even
00922    constants must be passed by reference, this can optimize on the storage
00923    required */
00924 
00925                                 p->datap = doput ? (char *)putconst((Constp)q)
00926                                                  : (char *)q;
00927                                 continue;
00928                         }
00929 
00930 /* Take a function name and turn it into an Addr.  This only happens when
00931    nothing else has figured out the function beforehand */
00932 
00933                         if (qtag == TPRIM && q->primblock.argsp == 0) {
00934                             if (q->primblock.namep->vclass==CLPROC
00935                              && q->primblock.namep->vprocclass != PTHISPROC) {
00936                                 p->datap = (char *)mkaddr(q->primblock.namep);
00937                                 continue;
00938                                 }
00939 
00940                             if (q->primblock.namep->vdim != NULL) {
00941                                 p->datap = (char *)mkscalar(q->primblock.namep);
00942                                 if ((q->primblock.fcharp||q->primblock.lcharp)
00943                                  && (q->primblock.namep->vtype != TYCHAR
00944                                   || q->primblock.namep->vdim))
00945                                         sserr(q->primblock.namep);
00946                                 continue;
00947                                 }
00948 
00949                             if (q->primblock.namep->vdovar
00950                              && (t = (tagptr) memversion(q->primblock.namep))) {
00951                                 p->datap = (char *)fixtype(t);
00952                                 continue;
00953                                 }
00954                             }
00955                         p->datap = (char *)fixtype(q);
00956                 }
00957         return(nargs);
00958 }

expptr fixexpr register Exprp    p
 

Definition at line 679 of file expr.c.

References badtag(), call2(), charptr, cktype(), Expression::constblock, cplenexpr(), err, errnode, Expression::exprblock, Fatal(), fixtype(), free, frexpr(), Expression::headblock, ISCOMPLEX, ISCONST, ISERROR, ISLOGICAL, ISREAL, mkconv(), mkexpr(), mkpower(), MSKADDR, MSKINT, ONEOF, OPABS, OPADDR, OPASSIGN, Exprblock::opcode, OPCOLON, OPCOMMA, OPCONCAT, OPCONV, OPDABS, OPDMAX, OPDMIN, OPEQ, OPGE, OPGT, OPLE, OPLT, OPMAX, OPMAX2, OPMIN, OPMIN2, OPMINUS, OPMOD, OPNE, OPPLUS, OPPLUSEQ, OPPOWER, OPQUEST, OPSLASH, OPSTAR, OPSTAREQ, putconst(), q, Exprblock::rightp, TADDR, Expression::tag, TEXPR, TYERROR, Exprblock::typefixed, Headblock::vtype, and Constblock::vtype.

Referenced by fixtype(), intrcall(), make_param(), mkpower(), putassign(), putcxcmp(), putiocall(), putmnmx(), and putsteq().

00681 {
00682         expptr lp;
00683         register expptr rp;
00684         register expptr q;
00685         char *hsave;
00686         int opcode, ltype, rtype, ptype, mtype;
00687 
00688         if( ISERROR(p) || p->typefixed )
00689                 return( (expptr) p );
00690         else if(p->tag != TEXPR)
00691                 badtag("fixexpr", p->tag);
00692         opcode = p->opcode;
00693 
00694 /* First set the types of the left and right subexpressions */
00695 
00696         lp = p->leftp;
00697         if (!ISCONST(lp) || lp->constblock.vtype != TYCHAR)
00698                 lp = p->leftp = fixtype(lp);
00699         ltype = lp->headblock.vtype;
00700 
00701         if(opcode==OPASSIGN && lp->tag!=TADDR)
00702         {
00703                 err("left side of assignment must be variable");
00704  eret:
00705                 frexpr((expptr)p);
00706                 return( errnode() );
00707         }
00708 
00709         if(rp = p->rightp)
00710         {
00711                 if (!ISCONST(rp) || rp->constblock.vtype != TYCHAR)
00712                         rp = p->rightp = fixtype(rp);
00713                 rtype = rp->headblock.vtype;
00714         }
00715         else
00716                 rtype = 0;
00717 
00718         if(ltype==TYERROR || rtype==TYERROR)
00719                 goto eret;
00720 
00721 /* Now work on the whole expression */
00722 
00723         /* force folding if possible */
00724 
00725         if( ISCONST(lp) && (rp==NULL || ISCONST(rp)) )
00726         {
00727                 q = opcode == OPCONV && lp->constblock.vtype == p->vtype
00728                         ? lp : mkexpr(opcode, lp, rp);
00729 
00730 /* mkexpr is expected to reduce constant expressions */
00731 
00732                 if( ISCONST(q) ) {
00733                         p->leftp = p->rightp = 0;
00734                         frexpr((expptr)p);
00735                         return(q);
00736                         }
00737                 free( (charptr) q );    /* constants did not fold */
00738         }
00739 
00740         if( (ptype = cktype(opcode, ltype, rtype)) == TYERROR)
00741                 goto eret;
00742 
00743         if (ltype == TYCHAR && ISCONST(lp)) {
00744                 if (opcode == OPCONV) {
00745                         hsave = halign;
00746                         halign = 0;
00747                         lp = (expptr)putconst((Constp)lp);
00748                         halign = hsave;
00749                         }
00750                 else
00751                         lp = (expptr)putconst((Constp)lp);
00752                 p->leftp = lp;
00753                 }
00754         if (rtype == TYCHAR && ISCONST(rp))
00755                 p->rightp = rp = (expptr)putconst((Constp)rp);
00756 
00757         switch(opcode)
00758         {
00759         case OPCONCAT:
00760                 if(p->vleng == NULL)
00761                         p->vleng = mkexpr(OPPLUS, cplenexpr(lp),
00762                                         cplenexpr(rp) );
00763                 break;
00764 
00765         case OPASSIGN:
00766                 if (rtype == TYREAL || ISLOGICAL(ptype)
00767                  || rtype == TYDREAL && ltype == TYREAL && !ISCONST(rp))
00768                         break;
00769         case OPPLUSEQ:
00770         case OPSTAREQ:
00771                 if(ltype == rtype)
00772                         break;
00773                 if( ! ISCONST(rp) && ISREAL(ltype) && ISREAL(rtype) )
00774                         break;
00775                 if( ISCOMPLEX(ltype) || ISCOMPLEX(rtype) )
00776                         break;
00777                 if( ONEOF(ltype, MSKADDR|MSKINT) && ONEOF(rtype, MSKADDR|MSKINT)
00778                     && typesize[ltype]>=typesize[rtype] )
00779                             break;
00780 
00781 /* Cast the right hand side to match the type of the expression */
00782 
00783                 p->rightp = fixtype( mkconv(ptype, rp) );
00784                 break;
00785 
00786         case OPSLASH:
00787                 if( ISCOMPLEX(rtype) )
00788                 {
00789                         p = (Exprp) call2(ptype,
00790 
00791 /* Handle double precision complex variables */
00792 
00793                             ptype == TYCOMPLEX ? "c_div" : "z_div",
00794                             mkconv(ptype, lp), mkconv(ptype, rp) );
00795                         break;
00796                 }
00797         case OPPLUS:
00798         case OPMINUS:
00799         case OPSTAR:
00800         case OPMOD:
00801                 if(ptype==TYDREAL && ( (ltype==TYREAL && ! ISCONST(lp) ) ||
00802                     (rtype==TYREAL && ! ISCONST(rp) ) ))
00803                         break;
00804                 if( ISCOMPLEX(ptype) )
00805                         break;
00806 
00807 /* Cast both sides of the expression to match the type of the whole
00808    expression.  */
00809 
00810                 if(ltype != ptype && (ltype < TYINT1 || ptype > TYDREAL))
00811                         p->leftp = fixtype(mkconv(ptype,lp));
00812                 if(rtype != ptype && (rtype < TYINT1 || ptype > TYDREAL))
00813                         p->rightp = fixtype(mkconv(ptype,rp));
00814                 break;
00815 
00816         case OPPOWER:
00817                 rp = mkpower((expptr)p);
00818                 if (rp->tag == TEXPR)
00819                         rp->exprblock.typefixed = 1;
00820                 return rp;
00821 
00822         case OPLT:
00823         case OPLE:
00824         case OPGT:
00825         case OPGE:
00826         case OPEQ:
00827         case OPNE:
00828                 if(ltype == rtype)
00829                         break;
00830                 if (htype) {
00831                         if (ltype == TYCHAR) {
00832                                 p->leftp = fixtype(mkconv(rtype,lp));
00833                                 break;
00834                                 }
00835                         if (rtype == TYCHAR) {
00836                                 p->rightp = fixtype(mkconv(ltype,rp));
00837                                 break;
00838                                 }
00839                         }
00840                 mtype = cktype(OPMINUS, ltype, rtype);
00841                 if(mtype==TYDREAL && (ltype==TYREAL || rtype==TYREAL))
00842                         break;
00843                 if( ISCOMPLEX(mtype) )
00844                         break;
00845                 if(ltype != mtype)
00846                         p->leftp = fixtype(mkconv(mtype,lp));
00847                 if(rtype != mtype)
00848                         p->rightp = fixtype(mkconv(mtype,rp));
00849                 break;
00850 
00851         case OPCONV:
00852                 ptype = cktype(OPCONV, p->vtype, ltype);
00853                 if(lp->tag==TEXPR && lp->exprblock.opcode==OPCOMMA
00854                  && !ISCOMPLEX(ptype))
00855                 {
00856                         lp->exprblock.rightp =
00857                             fixtype( mkconv(ptype, lp->exprblock.rightp) );
00858                         free( (charptr) p );
00859                         p = (Exprp) lp;
00860                 }
00861                 break;
00862 
00863         case OPADDR:
00864                 if(lp->tag==TEXPR && lp->exprblock.opcode==OPADDR)
00865                         Fatal("addr of addr");
00866                 break;
00867 
00868         case OPCOMMA:
00869         case OPQUEST:
00870         case OPCOLON:
00871                 break;
00872 
00873         case OPMIN:
00874         case OPMAX:
00875         case OPMIN2:
00876         case OPMAX2:
00877         case OPDMIN:
00878         case OPDMAX:
00879         case OPABS:
00880         case OPDABS:
00881                 ptype = p->vtype;
00882                 break;
00883 
00884         default:
00885                 break;
00886         }
00887 
00888         p->vtype = ptype;
00889         p->typefixed = 1;
00890         return((expptr) p);
00891 }

expptr fixtype register tagptr    p
 

Definition at line 570 of file expr.c.

References Expression::addrblock, Primblock::argsp, badtag(), CLVAR, Expression::constblock, err, errnode, fixexpr(), Addrblock::memoffset, mkfunct(), mklhs(), MSKADDR, MSKINT, MSKLOGICAL, MSKREAL, Primblock::namep, ONEOF, Expression::primblock, putconst(), TADDR, Expression::tag, TCONST, TERROR, TEXPR, TLIST, TPRIM, Nameblock::vclass, Nameblock::vinftype, Nameblock::vtype, Constblock::vtype, and wronginf().

Referenced by dim_finish(), doiolist(), exar2(), exarif(), excall(), exdo(), exequals(), exreturn(), fixargs(), fixexpr(), ioclause(), iosetc(), make_param(), mklhs(), nextdata(), prolog(), putaddr(), putcall(), putexpr(), putif(), putio(), putwhile(), retval(), startrw(), stfcall(), suboffset(), subskept(), and yyparse().

00572 {
00573 
00574         if(p == 0)
00575                 return(0);
00576 
00577         switch(p->tag)
00578         {
00579         case TCONST:
00580                 if(ONEOF(p->constblock.vtype,MSKINT|MSKLOGICAL|MSKADDR|
00581                     MSKREAL) )
00582                         return( (expptr) p);
00583 
00584                 return( (expptr) putconst((Constp)p) );
00585 
00586         case TADDR:
00587                 p->addrblock.memoffset = fixtype(p->addrblock.memoffset);
00588                 return( (expptr) p);
00589 
00590         case TERROR:
00591                 return( (expptr) p);
00592 
00593         default:
00594                 badtag("fixtype", p->tag);
00595 
00596 /* This case means that   fixexpr   can't call   fixtype   with any expr,
00597    only a subexpr of its parameter. */
00598 
00599         case TEXPR:
00600                 if (((Exprp)p)->typefixed)
00601                         return (expptr)p;
00602                 return( fixexpr((Exprp)p) );
00603 
00604         case TLIST:
00605                 return( (expptr) p );
00606 
00607         case TPRIM:
00608                 if(p->primblock.argsp && p->primblock.namep->vclass!=CLVAR)
00609                 {
00610                         if(p->primblock.namep->vtype == TYSUBR)
00611                         {
00612                                 err("function invocation of subroutine");
00613                                 return( errnode() );
00614                         }
00615                         else {
00616                                 if (p->primblock.namep->vinftype)
00617                                         wronginf(p->primblock.namep);
00618                                 return( mkfunct(p) );
00619                                 }
00620                 }
00621 
00622 /* The lack of args makes   p   a function name, substring reference
00623    or variable name. */
00624 
00625                 else    return mklhs((struct Primblock *) p, keepsubs);
00626         }
00627 }

expptr fold register expptr    e
 

Definition at line 2539 of file expr.c.

References ALLOC, badop(), Constant::ccp1, Constant::cd, Constant::cds, Constant::ci, ckalloc(), cmpstr(), consbinop(), consconv(), consnegop(), conspower(), Constblock::Const, Expression::constblock, Expression::exprblock, free, frexpr(), Expression::headblock, i, ICON, intovfl(), ISINT, L, Exprblock::leftp, maxtype(), OPABS, OPADDR, OPAND, OPBITAND, OPBITCLR, OPBITNOT, OPBITOR, OPBITSET, OPBITTEST, OPBITXOR, Exprblock::opcode, OPCOLON, OPCOMMA, OPCOMMA_ARG, OPCONCAT, OPCONV, OPDABS, OPEQV, OPLSHIFT, OPNEG, OPNEG1, OPNEQV, OPNOT, OPOR, OPPOWER, OPQUEST, OPRSHIFT, OPSLASH, q, Exprblock::rightp, Constblock::tag, TCONST, TYQUAD, Exprblock::vleng, Constblock::vleng, Constblock::vstg, Constblock::vtype, Headblock::vtype, Exprblock::vtype, and zeroconst().

Referenced by coarsen(), eval_registration(), main(), mkexpr(), putop(), and THD_copy_file().

02541 {
02542         Constp p;
02543         register expptr lp, rp;
02544         int etype, mtype, ltype, rtype, opcode;
02545         int i, bl, ll, lr;
02546         char *q, *s;
02547         struct Constblock lcon, rcon;
02548         ftnint L;
02549         double d;
02550 
02551         opcode = e->exprblock.opcode;
02552         etype = e->exprblock.vtype;
02553 
02554         lp = e->exprblock.leftp;
02555         ltype = lp->headblock.vtype;
02556         rp = e->exprblock.rightp;
02557 
02558         if(rp == 0)
02559                 switch(opcode)
02560                 {
02561                 case OPNOT:
02562                         lp->constblock.Const.ci = ! lp->constblock.Const.ci;
02563  retlp:
02564                         e->exprblock.leftp = 0;
02565                         frexpr(e);
02566                         return(lp);
02567 
02568                 case OPBITNOT:
02569                         lp->constblock.Const.ci = ~ lp->constblock.Const.ci;
02570                         goto retlp;
02571 
02572                 case OPNEG:
02573                 case OPNEG1:
02574                         consnegop((Constp)lp);
02575                         goto retlp;
02576 
02577                 case OPCONV:
02578                 case OPADDR:
02579                         return(e);
02580 
02581                 case OPABS:
02582                 case OPDABS:
02583                         switch(ltype) {
02584                             case TYINT1:
02585                             case TYSHORT:
02586                             case TYLONG:
02587 #ifdef TYQUAD
02588                             case TYQUAD:
02589 #endif
02590                                 if ((L = lp->constblock.Const.ci) < 0) {
02591                                         lp->constblock.Const.ci = -L;
02592                                         if (L != -lp->constblock.Const.ci)
02593                                                 intovfl();
02594                                         }
02595                                 goto retlp;
02596                             case TYREAL:
02597                             case TYDREAL:
02598                                 if (lp->constblock.vstg) {
02599                                     s = lp->constblock.Const.cds[0];
02600                                     if (*s == '-')
02601                                         lp->constblock.Const.cds[0] = s + 1;
02602                                     goto retlp;
02603                                 }
02604                                 if ((d = lp->constblock.Const.cd[0]) < 0.)
02605                                         lp->constblock.Const.cd[0] = -d;
02606                             case TYCOMPLEX:
02607                             case TYDCOMPLEX:
02608                                 return e;       /* lazy way out */
02609                             }
02610                 default:
02611                         badop("fold", opcode);
02612                 }
02613 
02614         rtype = rp->headblock.vtype;
02615 
02616         p = ALLOC(Constblock);
02617         p->tag = TCONST;
02618         p->vtype = etype;
02619         p->vleng = e->exprblock.vleng;
02620 
02621         switch(opcode)
02622         {
02623         case OPCOMMA:
02624         case OPCOMMA_ARG:
02625         case OPQUEST:
02626         case OPCOLON:
02627                 goto ereturn;
02628 
02629         case OPAND:
02630                 p->Const.ci = lp->constblock.Const.ci &&
02631                     rp->constblock.Const.ci;
02632                 break;
02633 
02634         case OPOR:
02635                 p->Const.ci = lp->constblock.Const.ci ||
02636                     rp->constblock.Const.ci;
02637                 break;
02638 
02639         case OPEQV:
02640                 p->Const.ci = lp->constblock.Const.ci ==
02641                     rp->constblock.Const.ci;
02642                 break;
02643 
02644         case OPNEQV:
02645                 p->Const.ci = lp->constblock.Const.ci !=
02646                     rp->constblock.Const.ci;
02647                 break;
02648 
02649         case OPBITAND:
02650                 p->Const.ci = lp->constblock.Const.ci &
02651                     rp->constblock.Const.ci;
02652                 break;
02653 
02654         case OPBITOR:
02655                 p->Const.ci = lp->constblock.Const.ci |
02656                     rp->constblock.Const.ci;
02657                 break;
02658 
02659         case OPBITXOR:
02660                 p->Const.ci = lp->constblock.Const.ci ^
02661                     rp->constblock.Const.ci;
02662                 break;
02663 
02664         case OPLSHIFT:
02665                 p->Const.ci = lp->constblock.Const.ci <<
02666                     rp->constblock.Const.ci;
02667                 if ((((unsigned long)p->Const.ci) >> rp->constblock.Const.ci)
02668                                 != lp->constblock.Const.ci)
02669                         intovfl();
02670                 break;
02671 
02672         case OPRSHIFT:
02673                 p->Const.ci = (unsigned long)lp->constblock.Const.ci >>
02674                     rp->constblock.Const.ci;
02675                 break;
02676 
02677         case OPBITTEST:
02678                 p->Const.ci = (lp->constblock.Const.ci &
02679                                 1L << rp->constblock.Const.ci) != 0;
02680                 break;
02681 
02682         case OPBITCLR:
02683                 p->Const.ci = lp->constblock.Const.ci &
02684                                 ~(1L << rp->constblock.Const.ci);
02685                 break;
02686 
02687         case OPBITSET:
02688                 p->Const.ci = lp->constblock.Const.ci |
02689                                 1L << rp->constblock.Const.ci;
02690                 break;
02691 
02692         case OPCONCAT:
02693                 ll = lp->constblock.vleng->constblock.Const.ci;
02694                 lr = rp->constblock.vleng->constblock.Const.ci;
02695                 bl = lp->constblock.Const.ccp1.blanks;
02696                 p->Const.ccp = q = (char *) ckalloc(ll+lr+bl);
02697                 p->Const.ccp1.blanks = rp->constblock.Const.ccp1.blanks;
02698                 p->vleng = ICON(ll+lr+bl);
02699                 s = lp->constblock.Const.ccp;
02700                 for(i = 0 ; i < ll ; ++i)
02701                         *q++ = *s++;
02702                 for(i = 0 ; i < bl ; i++)
02703                         *q++ = ' ';
02704                 s = rp->constblock.Const.ccp;
02705                 for(i = 0; i < lr; ++i)
02706                         *q++ = *s++;
02707                 break;
02708 
02709 
02710         case OPPOWER:
02711                 if( !ISINT(rtype)
02712                  || rp->constblock.Const.ci < 0 && zeroconst(lp))
02713                         goto ereturn;
02714                 conspower(p, (Constp)lp, rp->constblock.Const.ci);
02715                 break;
02716 
02717         case OPSLASH:
02718                 if (zeroconst(rp))
02719                         goto ereturn;
02720                 /* no break */
02721 
02722         default:
02723                 if(ltype == TYCHAR)
02724                 {
02725                         lcon.Const.ci = cmpstr(lp->constblock.Const.ccp,
02726                             rp->constblock.Const.ccp,
02727                             lp->constblock.vleng->constblock.Const.ci,
02728                             rp->constblock.vleng->constblock.Const.ci);
02729                         rcon.Const.ci = 0;
02730                         mtype = tyint;
02731                 }
02732                 else    {
02733                         mtype = maxtype(ltype, rtype);
02734                         consconv(mtype, &lcon, &lp->constblock);
02735                         consconv(mtype, &rcon, &rp->constblock);
02736                 }
02737                 consbinop(opcode, mtype, p, &lcon, &rcon);
02738                 break;
02739         }
02740 
02741         frexpr(e);
02742         return( (expptr) p );
02743  ereturn:
02744         free((char *)p);
02745         return e;
02746 }

void frexpr register tagptr    p
 

Definition at line 486 of file expr.c.

References Expression::addrblock, Primblock::argsp, badtag(), charptr, Constblock::Const, Expression::constblock, Chain::datap, Expression::exprblock, Primblock::fcharp, frchain(), free, ISCHAR, Primblock::lcharp, Exprblock::leftp, Expression::listblock, Listblock::listp, Addrblock::memoffset, Chain::nextp, Expression::primblock, q, Exprblock::rightp, TADDR, Expression::tag, TCONST, TERROR, TEXPR, TLIST, TNAME, TPRIM, TYERROR, Addrblock::vleng, Constblock::vleng, and Addrblock::vtype.

Referenced by cpexpr(), dataval(), doequiv(), doiolist(), enddo(), endio(), endioctl(), exarif(), excall(), exdo(), exequals(), expr_out(), exstop(), fixexpr(), fold(), frdata(), freetemps(), frexchain(), hashclear(), inferdcl(), Inline(), ioset(), make_param(), mkconv(), mkcxcon(), mkexpr(), mkfunct(), mklhs(), mkpower(), mkprim(), mkscalar(), nextdata(), procinit(), putaddr(), putcall(), putch1(), putcheq(), putconst(), putct1(), putcx1(), putcxeq(), putmnmx(), putop(), putpower(), putx(), setbound(), settype(), startrw(), stfcall(), subcheck(), wr_globals(), and wr_nv_ident_help().

00488 {
00489         register chainp q;
00490 
00491         if(p == NULL)
00492                 return;
00493 
00494         switch(p->tag)
00495         {
00496         case TCONST:
00497                 if( ISCHAR(p) )
00498                 {
00499                         free( (charptr) (p->constblock.Const.ccp) );
00500                         frexpr(p->constblock.vleng);
00501                 }
00502                 break;
00503 
00504         case TADDR:
00505                 if (p->addrblock.vtype > TYERROR)       /* i/o block */
00506                         break;
00507                 frexpr(p->addrblock.vleng);
00508                 frexpr(p->addrblock.memoffset);
00509                 break;
00510 
00511         case TERROR:
00512                 break;
00513 
00514 /* TNAME blocks don't get free'd - probably because they're pointed to in
00515    the hash table. 14-Jun-88 -- mwm */
00516 
00517         case TNAME:
00518                 return;
00519 
00520         case TPRIM:
00521                 frexpr((expptr)p->primblock.argsp);
00522                 frexpr(p->primblock.fcharp);
00523                 frexpr(p->primblock.lcharp);
00524                 break;
00525 
00526         case TEXPR:
00527                 frexpr(p->exprblock.leftp);
00528                 if(p->exprblock.rightp)
00529                         frexpr(p->exprblock.rightp);
00530                 break;
00531 
00532         case TLIST:
00533                 for(q = p->listblock.listp ; q ; q = q->nextp)
00534                         frexpr((tagptr)q->datap);
00535                 frchain( &(p->listblock.listp) );
00536                 break;
00537 
00538         default:
00539                 badtag("frexpr", p->tag);
00540         }
00541 
00542         free( (charptr) p );
00543 }

void impldcl register Namep    p
 

Definition at line 1930 of file expr.c.

References CLPROC, dclerr(), dflttype, letter, PINTRINSIC, and settype().

Referenced by doentry(), make_param(), mkfunct(), mkstfunct(), save_argtypes(), and vardcl().

01932 {
01933         register int k;
01934         int type;
01935         ftnint leng;
01936 
01937         if(p->vdcldone || (p->vclass==CLPROC && p->vprocclass==PINTRINSIC) )
01938                 return;
01939         if(p->vtype == TYUNKNOWN)
01940         {
01941                 k = letter(p->fvarname[0]);
01942                 type = impltype[ k ];
01943                 leng = implleng[ k ];
01944                 if(type == TYUNKNOWN)
01945                 {
01946                         if(p->vclass == CLPROC)
01947                                 return;
01948                         dclerr("attempt to use undefined variable", p);
01949                         type = dflttype[k];
01950                         leng = 0;
01951                 }
01952                 settype(p, type, leng);
01953                 p->vimpltype = 1;
01954         }
01955 }

void inferdcl Namep    np,
int    type
 

Definition at line 1963 of file expr.c.

References frexpr(), and letter.

Referenced by mkaddr(), and typekludge().

01965 {
01966         int k = impltype[letter(np->fvarname[0])];
01967         if (k != type) {
01968                 np->vinftype = 1;
01969                 np->vtype = type;
01970                 frexpr(np->vleng);
01971                 np->vleng = 0;
01972                 }
01973         np->vimpltype = 0;
01974         np->vinfproc = 1;
01975         }

int inregister register Namep    np
 

Definition at line 1506 of file expr.c.

References i.

Referenced by memversion(), and mkplace().

01508 {
01509         register int i;
01510 
01511         for(i = 0 ; i < nregvar ; ++i)
01512                 if(regnamep[i] == np)
01513                         return( regnum[i] );
01514         return(-1);
01515 }

void intovfl Void    [static]
 

Definition at line 2528 of file expr.c.

References err.

Referenced by consbinop(), consnegop(), and fold().

02529 { err("overflow simplifying integer constants."); }

Addrp memversion register Namep    np
 

Definition at line 1484 of file expr.c.

References inregister(), mkplace(), NO, and YES.

Referenced by doiolist(), enddo(), and fixargs().

01486 {
01487         register Addrp s;
01488 
01489         if(np->vdovar==NO || (inregister(np)<0) )
01490                 return(NULL);
01491         np->vdovar = NO;
01492         s = mkplace(np);
01493         np->vdovar = YES;
01494         return(s);
01495 }

expptr mkaddcon register long    l
 

Definition at line 104 of file expr.c.

References Constant::ci, Constblock::Const, l, mkconst(), and p.

Referenced by startrw().

00106 {
00107         register Constp p;
00108 
00109         p = mkconst(TYADDR);
00110         p->Const.ci = l;
00111         return( (expptr) p );
00112 }

Addrp mkaddr register Namep    p
 

Definition at line 1677 of file expr.c.

References addunder(), ALLOC, badstg(), Constant::ci, CLPROC, Constblock::Const, Expression::constblock, cpexpr(), errstr(), Extsym::exproto, Extsym::extstg, Extsym::extype, ICON, inferdcl(), intraddr(), Addrblock::isarray, ISICON, Addrblock::memno, Addrblock::memoffset, mkext(), Addrblock::name, PEXTERNAL, PTHISPROC, putconst(), STGARG, STGAUTO, STGBSS, STGCOMMON, STGEQUIV, STGEXT, STGINIT, STGINTR, STGLENG, STGSTFUNCT, STGUNKNOWN, TADDR, Addrblock::tag, UNAM_NAME, Addrblock::varleng, Addrblock::vclass, Addrblock::vleng, Addrblock::vstg, and Addrblock::vtype.

Referenced by fixargs(), mkfunct(), mkplace(), mkscalar(), and nextdata().

01679 {
01680         Extsym *extp;
01681         register Addrp t;
01682         int k;
01683 
01684         switch( p->vstg)
01685         {
01686         case STGAUTO:
01687                 if(p->vclass == CLPROC && p->vprocclass == PTHISPROC)
01688                         return (Addrp) cpexpr((expptr)xretslot[p->vtype]);
01689                 goto other;
01690 
01691         case STGUNKNOWN:
01692                 if(p->vclass != CLPROC)
01693                         break;  /* Error */
01694                 extp = mkext(p->fvarname, addunder(p->cvarname));
01695                 extp->extstg = STGEXT;
01696                 p->vstg = STGEXT;
01697                 p->vardesc.varno = extp - extsymtab;
01698                 p->vprocclass = PEXTERNAL;
01699                 if ((extp->exproto || infertypes)
01700                 && (p->vtype == TYUNKNOWN || p->vimpltype)
01701                 && (k = extp->extype))
01702                         inferdcl(p, k);
01703 
01704 
01705         case STGCOMMON:
01706         case STGEXT:
01707         case STGBSS:
01708         case STGINIT:
01709         case STGEQUIV:
01710         case STGARG:
01711         case STGLENG:
01712  other:
01713                 t = ALLOC(Addrblock);
01714                 t->tag = TADDR;
01715 
01716                 t->vclass = p->vclass;
01717                 t->vtype = p->vtype;
01718                 t->vstg = p->vstg;
01719                 t->memno = p->vardesc.varno;
01720                 t->memoffset = ICON(p->voffset);
01721                 if (p->vdim)
01722                     t->isarray = 1;
01723                 if(p->vleng)
01724                 {
01725                         t->vleng = (expptr) cpexpr(p->vleng);
01726                         if( ISICON(t->vleng) )
01727                                 t->varleng = t->vleng->constblock.Const.ci;
01728                 }
01729 
01730 /* Keep the original name around for the C code generation */
01731 
01732                 t -> uname_tag = UNAM_NAME;
01733                 t -> user.name = p;
01734                 return(t);
01735 
01736         case STGINTR:
01737 
01738                 return ( intraddr (p));
01739 
01740         case STGSTFUNCT:
01741 
01742                 errstr("invalid use of statement function %.64s.", p->fvarname);
01743                 return putconst((Constp)ICON(0));
01744         }
01745         badstg("mkaddr", p->vstg);
01746         /* NOT REACHED */ return 0;
01747 }

Addrp mkarg int    type,
int    argno
 

Definition at line 1762 of file expr.c.

References ALLOC, CLVAR, Addrblock::memno, STGARG, STGLENG, TADDR, Addrblock::tag, TYLENG, Addrblock::vclass, Addrblock::vstg, and Addrblock::vtype.

Referenced by doentry().

01764 {
01765         register Addrp p;
01766 
01767         p = ALLOC(Addrblock);
01768         p->tag = TADDR;
01769         p->vtype = type;
01770         p->vclass = CLVAR;
01771 
01772 /* TYLENG is the type of the field holding the length of a character string */
01773 
01774         p->vstg = (type==TYLENG ? STGLENG : STGARG);
01775         p->memno = argno;
01776         return(p);
01777 }

expptr mkbitcon int    shift,
int    leng,
char *    s
 

Definition at line 150 of file expr.c.

References Constant::ci, Constblock::Const, err, hextoi, mkconst(), and p.

Referenced by yyparse().

00152 {
00153         register Constp p;
00154         register long x, y, z;
00155         int len;
00156         char buff[100], *fmt, *s0 = s;
00157         static char *kind[3] = { "Binary", "Hex", "Octal" };
00158 
00159         p = mkconst(TYLONG);
00160         x = y = 0;
00161         while(--leng >= 0)
00162                 if(*s != ' ') {
00163                         z = x;
00164                         x = (x << shift) | hextoi(*s++);
00165                         y |= (((unsigned long)x) >> shift) - z;
00166                         }
00167         /* Don't change the type to short for short constants, as
00168          * that is dangerous -- there is no syntax for long constants
00169          * with small values.
00170          */
00171         p->Const.ci = x;
00172         if (y) {
00173                 if (--shift == 3)
00174                         shift = 1;
00175                 if ((len = (int)leng) > 60)
00176                         sprintf(buff, "%s constant '%.60s' truncated.",
00177                                 kind[shift], s0);
00178                 else
00179                         sprintf(buff, "%s constant '%.*s' truncated.",
00180                                 kind[shift], len, s0);
00181                 err(buff);
00182                 }
00183         return( (expptr) p );
00184 }

Constp mkconst register int    t
 

Definition at line 46 of file expr.c.

References ALLOC, p, Constblock::tag, TCONST, and Constblock::vtype.

Referenced by make_param(), mkaddcon(), mkbitcon(), mkconv(), mkcxcon(), mkintcon(), mklogcon(), mkrealcon(), and mkstrcon().

00048 {
00049         register Constp p;
00050 
00051         p = ALLOC(Constblock);
00052         p->tag = TCONST;
00053         p->vtype = t;
00054         return(p);
00055 }

expptr mkconv register int    t,
register expptr    p
 

Definition at line 299 of file expr.c.

References Expression::addrblock, badtype(), consconv(), Expression::constblock, frexpr(), Expression::headblock, ICON, ISCONST, ISINT, ISREAL, mkconst(), opconv(), q, TADDR, Expression::tag, TYERROR, UNAM_CONST, Addrblock::uname_tag, Addrblock::user, Constblock::vleng, Constblock::vstg, Headblock::vtype, and warn().

Referenced by cast_args(), exdo(), exreturn(), fixexpr(), Inline(), intrcall(), make_param(), mkpower(), prolog(), putcall(), putio(), putmnmx(), putop(), putx(), retval(), setbound(), stfcall(), and suboffset().

00301 {
00302         register expptr q;
00303         register int pt, charwarn = 1;
00304 
00305         if (t >= 100) {
00306                 t -= 100;
00307                 charwarn = 0;
00308                 }
00309         if(t==TYUNKNOWN || t==TYERROR)
00310                 badtype("mkconv", t);
00311         pt = p->headblock.vtype;
00312 
00313 /* Casting to the same type is a no-op */
00314 
00315         if(t == pt)
00316                 return(p);
00317 
00318 /* If we're casting a constant which is not in the literal table ... */
00319 
00320         else if( ISCONST(p) && pt!=TYADDR && pt != TYCHAR
00321                 || p->tag == TADDR && p->addrblock.uname_tag == UNAM_CONST)
00322         {
00323                 if (ISINT(t) && ISINT(pt) || ISREAL(t) && ISREAL(pt)) {
00324                         /* avoid trouble with -i2 */
00325                         p->headblock.vtype = t;
00326                         return p;
00327                         }
00328                 q = (expptr) mkconst(t);
00329                 consconv(t, &q->constblock, &p->constblock );
00330                 if (p->tag == TADDR)
00331                         q->constblock.vstg = p->addrblock.user.kludge.vstg1;
00332                 frexpr(p);
00333         }
00334         else {
00335                 if (pt == TYCHAR && t != TYADDR && charwarn
00336                                 && (!halign || p->tag != TADDR
00337                                 || p->addrblock.uname_tag != UNAM_CONST))
00338                         warn(
00339                  "ichar([first char. of] char. string) assumed for conversion to numeric");
00340                 q = opconv(p, t);
00341                 }
00342 
00343         if(t == TYCHAR)
00344                 q->constblock.vleng = ICON(1);
00345         return(q);
00346 }

expptr mkcxcon register expptr    realp,
register expptr    imagp
 

Definition at line 226 of file expr.c.

References Constant::cd, Constant::cds, Constant::ci, Constblock::Const, Expression::constblock, dtos(), err, errnode, frexpr(), Expression::headblock, ISCONST, ISINT, ISNUMERIC, mkconst(), p, string_num(), Constblock::vstg, and Headblock::vtype.

Referenced by intrcall(), and yyparse().

00228 {
00229         int rtype, itype;
00230         register Constp p;
00231 
00232         rtype = realp->headblock.vtype;
00233         itype = imagp->headblock.vtype;
00234 
00235         if( ISCONST(realp) && ISNUMERIC(rtype) && ISCONST(imagp) && ISNUMERIC(itype) )
00236         {
00237                 p = mkconst( (rtype==TYDREAL||itype==TYDREAL)
00238                                 ? TYDCOMPLEX : tycomplex);
00239                 if (realp->constblock.vstg || imagp->constblock.vstg) {
00240                         p->vstg = 1;
00241                         p->Const.cds[0] = ISINT(rtype)
00242                                 ? string_num("", realp->constblock.Const.ci)
00243                                 : realp->constblock.vstg
00244                                         ? realp->constblock.Const.cds[0]
00245                                         : dtos(realp->constblock.Const.cd[0]);
00246                         p->Const.cds[1] = ISINT(itype)
00247                                 ? string_num("", imagp->constblock.Const.ci)
00248                                 : imagp->constblock.vstg
00249                                         ? imagp->constblock.Const.cds[0]
00250                                         : dtos(imagp->constblock.Const.cd[0]);
00251                         }
00252                 else {
00253                         p->Const.cd[0] = ISINT(rtype)
00254                                 ? realp->constblock.Const.ci
00255                                 : realp->constblock.Const.cd[0];
00256                         p->Const.cd[1] = ISINT(itype)
00257                                 ? imagp->constblock.Const.ci
00258                                 : imagp->constblock.Const.cd[0];
00259                         }
00260         }
00261         else
00262         {
00263                 err("invalid complex constant");
00264                 p = (Constp)errnode();
00265         }
00266 
00267         frexpr(realp);
00268         frexpr(imagp);
00269         return( (expptr) p );
00270 }

expptr mkexpr int    opcode,
register expptr    lp,
register expptr    rp
 

Definition at line 2027 of file expr.c.

References ALLOC, Primblock::argsp, badop(), charptr, Constant::ci, cktype(), COMMUTE, consnegop(), Constblock::Const, Expression::constblock, doing_vleng, ENULL, errnode, Expression::exprblock, fold(), free, frexpr(), Expression::headblock, ICON, ICONEQ, is_negatable(), ISCONST, ISICON, ISINT, ISPLUSOP, L, Exprblock::leftp, Expression::listblock, Listblock::listp, Primblock::namep, OPABS, OPADDR, OPAND, OPARROW, OPASSIGN, OPASSIGNI, OPBITAND, OPBITANDEQ, OPBITCLR, OPBITNOT, OPBITOR, OPBITOREQ, OPBITSET, OPBITTEST, OPBITXOR, OPBITXOREQ, OPCALL, OPCCALL, OPCHARCAST, Exprblock::opcode, OPCOLON, OPCOMMA, OPCOMMA_ARG, OPCONCAT, OPCONV, OPDABS, OPDMAX, OPDMIN, OPDOT, OPEQ, OPEQV, OPGE, OPGT, OPIDENTITY, OPLE, OPLSHIFT, OPLSHIFTEQ, OPLT, OPMAX, OPMAX2, OPMIN, OPMIN2, OPMINUS, OPMINUSEQ, OPMOD, OPMODEQ, OPNE, OPNEG, OPNEG1, OPNEQV, OPNOT, OPOR, OPPLUS, OPPLUSEQ, OPPOWER, OPQBITCLR, OPQBITSET, OPQUEST, OPRSHIFT, OPRSHIFTEQ, OPSLASH, OPSLASHEQ, OPSTAR, OPSTAREQ, OPWHATSIN, Primblock::parenused, Expression::primblock, Exprblock::rightp, Exprblock::tag, Expression::tag, TCONST, TEXPR, TPRIM, TYERROR, Exprblock::vtype, Headblock::vtype, warn(), and zeroconst().

Referenced by addrfix(), addrof(), callk(), endio(), exar2(), exarif(), exassign(), exdo(), fixexpr(), Inline(), intrcall(), ioset(), ioseta(), make_int_expr(), mkfunct(), mklhs(), mkpower(), mkscalar(), nextdata(), opconv(), opconv_fudge(), out_addr(), prolog(), putassign(), putcall(), putch1(), putchcmp(), putcheq(), putct1(), putcx1(), putcxcmp(), putcxeq(), puteq(), putio(), putiocall(), putmnmx(), putop(), putpower(), putsteq(), setbound(), stfcall(), subcheck(), suboffset(), subskept(), and yyparse().

02029 {
02030         register expptr e, e1;
02031         int etype;
02032         int ltype, rtype;
02033         int ltag, rtag;
02034         long L;
02035         static long divlineno;
02036 
02037         ltype = lp->headblock.vtype;
02038         ltag = lp->tag;
02039         if(rp && opcode!=OPCALL && opcode!=OPCCALL)
02040         {
02041                 rtype = rp->headblock.vtype;
02042                 rtag = rp->tag;
02043         }
02044         else rtype = 0;
02045 
02046         etype = cktype(opcode, ltype, rtype);
02047         if(etype == TYERROR)
02048                 goto error;
02049 
02050         switch(opcode)
02051         {
02052                 /* check for multiplication by 0 and 1 and addition to 0 */
02053 
02054         case OPSTAR:
02055                 if( ISCONST(lp) )
02056                         COMMUTE
02057 
02058                 if( ISICON(rp) )
02059                         {
02060                                 if(rp->constblock.Const.ci == 0)
02061                                         goto retright;
02062                                 goto mulop;
02063                         }
02064                 break;
02065 
02066         case OPSLASH:
02067         case OPMOD:
02068                 if( zeroconst(rp) && lineno != divlineno ) {
02069                         warn("attempted division by zero");
02070                         divlineno = lineno;
02071                         }
02072                 if(opcode == OPMOD)
02073                         break;
02074 
02075 /* Handle multiplying or dividing by 1, -1 */
02076 
02077 mulop:
02078                 if( ISICON(rp) )
02079                 {
02080                         if(rp->constblock.Const.ci == 1)
02081                                 goto retleft;
02082 
02083                         if(rp->constblock.Const.ci == -1)
02084                         {
02085                                 frexpr(rp);
02086                                 return( mkexpr(OPNEG, lp, ENULL) );
02087                         }
02088                 }
02089 
02090 /* Group all constants together.  In particular,
02091 
02092         (x * CONST1) * CONST2 ==> x * (CONST1 * CONST2)
02093         (x * CONST1) / CONST2 ==> x * (CONST1 / CONST2)
02094 */
02095 
02096                 if (!ISINT(etype) || lp->tag != TEXPR || !lp->exprblock.rightp
02097                                 || !ISICON(lp->exprblock.rightp))
02098                         break;
02099 
02100                 if (lp->exprblock.opcode == OPLSHIFT) {
02101                         L = 1 << lp->exprblock.rightp->constblock.Const.ci;
02102                         if (opcode == OPSTAR || ISICON(rp) &&
02103                                         !(L % rp->constblock.Const.ci)) {
02104                                 lp->exprblock.opcode = OPSTAR;
02105                                 lp->exprblock.rightp->constblock.Const.ci = L;
02106                                 }
02107                         }
02108 
02109                 if (lp->exprblock.opcode == OPSTAR) {
02110                         if(opcode == OPSTAR)
02111                                 e = mkexpr(OPSTAR, lp->exprblock.rightp, rp);
02112                         else if(ISICON(rp) &&
02113                             (lp->exprblock.rightp->constblock.Const.ci %
02114                             rp->constblock.Const.ci) == 0)
02115                                 e = mkexpr(OPSLASH, lp->exprblock.rightp, rp);
02116                         else    break;
02117 
02118                         e1 = lp->exprblock.leftp;
02119                         free( (charptr) lp );
02120                         return( mkexpr(OPSTAR, e1, e) );
02121                         }
02122                 break;
02123 
02124 
02125         case OPPLUS:
02126                 if( ISCONST(lp) )
02127                         COMMUTE
02128                             goto addop;
02129 
02130         case OPMINUS:
02131                 if( ICONEQ(lp, 0) )
02132                 {
02133                         frexpr(lp);
02134                         return( mkexpr(OPNEG, rp, ENULL) );
02135                 }
02136 
02137                 if( ISCONST(rp) && is_negatable((Constp)rp))
02138                 {
02139                         opcode = OPPLUS;
02140                         consnegop((Constp)rp);
02141                 }
02142 
02143 /* Group constants in an addition expression (also subtraction, since the
02144    subtracted value was negated above).  In particular,
02145 
02146         (x + CONST1) + CONST2 ==> x + (CONST1 + CONST2)
02147 */
02148 
02149 addop:
02150                 if( ISICON(rp) )
02151                 {
02152                         if(rp->constblock.Const.ci == 0)
02153                                 goto retleft;
02154                         if( ISPLUSOP(lp) && ISICON(lp->exprblock.rightp) )
02155                         {
02156                                 e = mkexpr(OPPLUS, lp->exprblock.rightp, rp);
02157                                 e1 = lp->exprblock.leftp;
02158                                 free( (charptr) lp );
02159                                 return( mkexpr(OPPLUS, e1, e) );
02160                         }
02161                 }
02162                 if (opcode == OPMINUS && (ISINT(etype) || doing_vleng)) {
02163                         /* check for (i [+const]) - (i [+const]) */
02164                         if (lp->tag == TPRIM)
02165                                 e = lp;
02166                         else if (lp->tag == TEXPR && lp->exprblock.opcode == OPPLUS
02167                                         && lp->exprblock.rightp->tag == TCONST) {
02168                                 e = lp->exprblock.leftp;
02169                                 if (e->tag != TPRIM)
02170                                         break;
02171                                 }
02172                         else
02173                                 break;
02174                         if (e->primblock.argsp)
02175                                 break;
02176                         if (rp->tag == TPRIM)
02177                                 e1 = rp;
02178                         else if (rp->tag == TEXPR && rp->exprblock.opcode == OPPLUS
02179                                         && rp->exprblock.rightp->tag == TCONST) {
02180                                 e1 = rp->exprblock.leftp;
02181                                 if (e1->tag != TPRIM)
02182                                         break;
02183                                 }
02184                         else
02185                                 break;
02186                         if (e->primblock.namep != e1->primblock.namep
02187                                         || e1->primblock.argsp)
02188                                 break;
02189                         L = e == lp ? 0 : lp->exprblock.rightp->constblock.Const.ci;
02190                         if (e1 != rp)
02191                                 L -= rp->exprblock.rightp->constblock.Const.ci;
02192                         frexpr(lp);
02193                         frexpr(rp);
02194                         return ICON(L);
02195                         }
02196 
02197                 break;
02198 
02199 
02200         case OPPOWER:
02201                 break;
02202 
02203 /* Eliminate outermost double negations */
02204 
02205         case OPNEG:
02206         case OPNEG1:
02207                 if(ltag==TEXPR && lp->exprblock.opcode==OPNEG)
02208                 {
02209                         e = lp->exprblock.leftp;
02210                         free( (charptr) lp );
02211                         return(e);
02212                 }
02213                 break;
02214 
02215 /* Eliminate outermost double NOTs */
02216 
02217         case OPNOT:
02218                 if(ltag==TEXPR && lp->exprblock.opcode==OPNOT)
02219                 {
02220                         e = lp->exprblock.leftp;
02221                         free( (charptr) lp );
02222                         return(e);
02223                 }
02224                 break;
02225 
02226         case OPCALL:
02227         case OPCCALL:
02228                 etype = ltype;
02229                 if(rp!=NULL && rp->listblock.listp==NULL)
02230                 {
02231                         free( (charptr) rp );
02232                         rp = NULL;
02233                 }
02234                 break;
02235 
02236         case OPAND:
02237         case OPOR:
02238                 if( ISCONST(lp) )
02239                         COMMUTE
02240 
02241                             if( ISCONST(rp) )
02242                         {
02243                                 if(rp->constblock.Const.ci == 0)
02244                                         if(opcode == OPOR)
02245                                                 goto retleft;
02246                                         else
02247                                                 goto retright;
02248                                 else if(opcode == OPOR)
02249                                         goto retright;
02250                                 else
02251                                         goto retleft;
02252                         }
02253         case OPEQV:
02254         case OPNEQV:
02255 
02256         case OPBITAND:
02257         case OPBITOR:
02258         case OPBITXOR:
02259         case OPBITNOT:
02260         case OPLSHIFT:
02261         case OPRSHIFT:
02262         case OPBITTEST:
02263         case OPBITCLR:
02264         case OPBITSET:
02265 #ifdef TYQUAD
02266         case OPQBITCLR:
02267         case OPQBITSET:
02268 #endif
02269 
02270         case OPLT:
02271         case OPGT:
02272         case OPLE:
02273         case OPGE:
02274         case OPEQ:
02275         case OPNE:
02276 
02277         case OPCONCAT:
02278                 break;
02279         case OPMIN:
02280         case OPMAX:
02281         case OPMIN2:
02282         case OPMAX2:
02283         case OPDMIN:
02284         case OPDMAX:
02285 
02286         case OPASSIGN:
02287         case OPASSIGNI:
02288         case OPPLUSEQ:
02289         case OPSTAREQ:
02290         case OPMINUSEQ:
02291         case OPSLASHEQ:
02292         case OPMODEQ:
02293         case OPLSHIFTEQ:
02294         case OPRSHIFTEQ:
02295         case OPBITANDEQ:
02296         case OPBITXOREQ:
02297         case OPBITOREQ:
02298 
02299         case OPCONV:
02300         case OPADDR:
02301         case OPWHATSIN:
02302 
02303         case OPCOMMA:
02304         case OPCOMMA_ARG:
02305         case OPQUEST:
02306         case OPCOLON:
02307         case OPDOT:
02308         case OPARROW:
02309         case OPIDENTITY:
02310         case OPCHARCAST:
02311         case OPABS:
02312         case OPDABS:
02313                 break;
02314 
02315         default:
02316                 badop("mkexpr", opcode);
02317         }
02318 
02319         e = (expptr) ALLOC(Exprblock);
02320         e->exprblock.tag = TEXPR;
02321         e->exprblock.opcode = opcode;
02322         e->exprblock.vtype = etype;
02323         e->exprblock.leftp = lp;
02324         e->exprblock.rightp = rp;
02325         if(ltag==TCONST && (rp==0 || rtag==TCONST) )
02326                 e = fold(e);
02327         return(e);
02328 
02329 retleft:
02330         frexpr(rp);
02331         if (lp->tag == TPRIM)
02332                 lp->primblock.parenused = 1;
02333         return(lp);
02334 
02335 retright:
02336         frexpr(lp);
02337         if (rp->tag == TPRIM)
02338                 rp->primblock.parenused = 1;
02339         return(rp);
02340 
02341 error:
02342         frexpr(lp);
02343         if(rp && opcode!=OPCALL && opcode!=OPCCALL)
02344                 frexpr(rp);
02345         return( errnode() );
02346 }

expptr mkfunct expptr    p0
 

Definition at line 1024 of file expr.c.

References addunder(), adjust_arginfo(), Primblock::argsp, builtin(), Extsym::cextname, charptr, CLPROC, CLUNKNOWN, cpexpr(), Nameblock::cvarname, dclerr(), dflttype, Entrypoint::enamep, Entrypoint::entnextp, Entrypoint::entryname, err, errnode, errstr(), Expression::exprblock, Extsym::extstg, Fatal(), fatali(), fatalstr(), Primblock::fcharp, fixargs(), free, frexpr(), Nameblock::fvarname, impldcl(), intrcall(), intrfunct(), Primblock::lcharp, letter, mkaddr(), mkchain(), mkexpr(), mkext(), Primblock::namep, new_procs, OPCALL, PEXTERNAL, PINTRINSIC, PSTFUNCT, PTHISPROC, q, stfcall(), STGARG, STGCOMMON, STGEXT, STGINTR, STGUNKNOWN, Primblock::tag, TPRIM, Nameblock::vardesc, Nameblock::vcalled, Nameblock::vclass, Nameblock::vimpltype, Exprblock::vleng, Nameblock::vleng, Nameblock::vpassed, Nameblock::vprocclass, Nameblock::vstg, Exprblock::vtype, Nameblock::vtype, and warn().

Referenced by excall(), and fixtype().

01026 {
01027         register struct Primblock *p = (struct Primblock *)p0;
01028         struct Entrypoint *ep;
01029         Addrp ap;
01030         Extsym *extp;
01031         register Namep np;
01032         register expptr q;
01033         extern chainp new_procs;
01034         int k, nargs;
01035         int classKRH;
01036 
01037         if(p->tag != TPRIM)
01038                 return( errnode() );
01039 
01040         np = p->namep;
01041         classKRH = np->vclass;
01042 
01043 
01044         if(classKRH == CLUNKNOWN)
01045         {
01046                 np->vclass = classKRH = CLPROC;
01047                 if(np->vstg == STGUNKNOWN)
01048                 {
01049                         if(np->vtype!=TYSUBR && (k = intrfunct(np->fvarname))
01050                                 && (zflag || !(*(struct Intrpacked *)&k).f4
01051                                         || dcomplex_seen))
01052                         {
01053                                 np->vstg = STGINTR;
01054                                 np->vardesc.varno = k;
01055                                 np->vprocclass = PINTRINSIC;
01056                         }
01057                         else
01058                         {
01059                                 extp = mkext(np->fvarname,
01060                                         addunder(np->cvarname));
01061                                 extp->extstg = STGEXT;
01062                                 np->vstg = STGEXT;
01063                                 np->vardesc.varno = extp - extsymtab;
01064                                 np->vprocclass = PEXTERNAL;
01065                         }
01066                 }
01067                 else if(np->vstg==STGARG)
01068                 {
01069                     if(np->vtype == TYCHAR) {
01070                         adjust_arginfo(np);
01071                         if (np->vpassed) {
01072                                 char wbuf[160], *who;
01073                                 who = np->fvarname;
01074                                 sprintf(wbuf, "%s%s%s\n\t%s%s%s",
01075                                         "Character-valued dummy procedure ",
01076                                         who, " not declared EXTERNAL.",
01077                         "Code may be wrong for previous function calls having ",
01078                                         who, " as a parameter.");
01079                                 warn(wbuf);
01080                                 }
01081                         }
01082                     np->vprocclass = PEXTERNAL;
01083                 }
01084         }
01085 
01086         if(classKRH != CLPROC) {
01087                 if (np->vstg == STGCOMMON)
01088                         fatalstr(
01089                          "Cannot invoke common variable %.50s as a function.",
01090                                 np->fvarname);
01091                 errstr("%.80s cannot be called.", np->fvarname);
01092                 goto error;
01093                 }
01094 
01095 /* F77 doesn't allow subscripting of function calls */
01096 
01097         if(p->fcharp || p->lcharp)
01098         {
01099                 err("no substring of function call");
01100                 goto error;
01101         }
01102         impldcl(np);
01103         np->vimpltype = 0;      /* invoking as function ==> inferred type */
01104         np->vcalled = 1;
01105         nargs = fixargs( np->vprocclass!=PINTRINSIC,  p->argsp);
01106 
01107         switch(np->vprocclass)
01108         {
01109         case PEXTERNAL:
01110                 if(np->vtype == TYUNKNOWN)
01111                 {
01112                         dclerr("attempt to use untyped function", np);
01113                         np->vtype = dflttype[letter(np->fvarname[0])];
01114                 }
01115                 ap = mkaddr(np);
01116                 if (!extsymtab[np->vardesc.varno].extseen) {
01117                         new_procs = mkchain((char *)np, new_procs);
01118                         extsymtab[np->vardesc.varno].extseen = 1;
01119                         }
01120 call:
01121                 q = mkexpr(OPCALL, (expptr)ap, (expptr)p->argsp);
01122                 q->exprblock.vtype = np->vtype;
01123                 if(np->vleng)
01124                         q->exprblock.vleng = (expptr) cpexpr(np->vleng);
01125                 break;
01126 
01127         case PINTRINSIC:
01128                 q = intrcall(np, p->argsp, nargs);
01129                 break;
01130 
01131         case PSTFUNCT:
01132                 q = stfcall(np, p->argsp);
01133                 break;
01134 
01135         case PTHISPROC:
01136                 warn("recursive call");
01137 
01138 /* entries   is the list of multiple entry points */
01139 
01140                 for(ep = entries ; ep ; ep = ep->entnextp)
01141                         if(ep->enamep == np)
01142                                 break;
01143                 if(ep == NULL)
01144                         Fatal("mkfunct: impossible recursion");
01145 
01146                 ap = builtin(np->vtype, ep->entryname->cextname, -2);
01147                 /* the negative last arg prevents adding */
01148                 /* this name to the list of used builtins */
01149                 goto call;
01150 
01151         default:
01152                 fatali("mkfunct: impossible vprocclass %d",
01153                     (int) (np->vprocclass) );
01154         }
01155         free( (charptr) p );
01156         return(q);
01157 
01158 error:
01159         frexpr((expptr)p);
01160         return( errnode() );
01161 }

expptr mkintcon ftnint    l
 

Definition at line 84 of file expr.c.

References Constant::ci, Constblock::Const, l, mkconst(), and p.

Referenced by exassign(), intrcall(), nextdata(), out_addr(), putcx1(), and yyparse().

00086 {
00087         register Constp p;
00088 
00089         p = mkconst(tyint);
00090         p->Const.ci = l;
00091         return( (expptr) p );
00092 }

expptr mklhs register struct Primblock   p,
int    subkeep
 

Definition at line 1390 of file expr.c.

References Primblock::argsp, charptr, Constant::ci, Constblock::Const, Expression::constblock, cpexpr(), doing_vleng, Primblock::fcharp, fixtype(), free, frexpr(), ICON, ISCONST, Primblock::lcharp, Addrblock::memoffset, mkexpr(), mkplace(), Primblock::namep, Dimblock::ndim, OPMINUS, OPPLUS, Primblock::parenused, Addrblock::parenused, replaced, sserr(), STGREG, suboffset(), subskept(), TADDR, Addrblock::tag, Primblock::tag, TPRIM, Nameblock::vdim, Addrblock::vleng, Nameblock::vleng, Addrblock::vstg, and Nameblock::vtype.

Referenced by exequals(), fixtype(), and nextdata().

01392 {
01393         register Addrp s;
01394         Namep np;
01395 
01396         if(p->tag != TPRIM)
01397                 return( (expptr) p );
01398         np = p->namep;
01399 
01400         replaced = 0;
01401         s = mkplace(np);
01402         if(s->tag!=TADDR || s->vstg==STGREG)
01403         {
01404                 free( (charptr) p );
01405                 return( (expptr) s );
01406         }
01407         s->parenused = p->parenused;
01408 
01409         /* compute the address modified by subscripts */
01410 
01411         if (!replaced)
01412                 s->memoffset = (subkeep && np->vdim
01413                                 && (np->vdim->ndim > 1 || np->vtype == TYCHAR
01414                                 && (!ISCONST(np->vleng)
01415                                   || np->vleng->constblock.Const.ci != 1)))
01416                                 ? subskept(p,s)
01417                                 : mkexpr(OPPLUS, s->memoffset, suboffset(p) );
01418         frexpr((expptr)p->argsp);
01419         p->argsp = NULL;
01420 
01421         /* now do substring part */
01422 
01423         if(p->fcharp || p->lcharp)
01424         {
01425                 if(np->vtype != TYCHAR)
01426                         sserr(np);
01427                 else    {
01428                         if(p->lcharp == NULL)
01429                                 p->lcharp = (expptr)(
01430                                         /* s->vleng == 0 only with errors */
01431                                         s->vleng ? cpexpr(s->vleng) : ICON(1));
01432                         if(p->fcharp) {
01433                                 doing_vleng = 1;
01434                                 s->vleng = fixtype(mkexpr(OPMINUS,
01435                                                 p->lcharp,
01436                                         mkexpr(OPMINUS, p->fcharp, ICON(1) )));
01437                                 doing_vleng = 0;
01438                                 }
01439                         else    {
01440                                 frexpr(s->vleng);
01441                                 s->vleng = p->lcharp;
01442                         }
01443                 }
01444         }
01445 
01446         s->vleng = fixtype( s->vleng );
01447         s->memoffset = fixtype( s->memoffset );
01448         free( (charptr) p );
01449         return( (expptr) s );
01450 }

expptr mklogcon register int    l
 

Definition at line 65 of file expr.c.

References Constant::ci, Constblock::Const, l, mkconst(), and p.

Referenced by yyparse().

00067 {
00068         register Constp  p;
00069 
00070         p = mkconst(tylog);
00071         p->Const.ci = l;
00072         return( (expptr) p );
00073 }

Addrp mkplace register Namep    np
 

Definition at line 1302 of file expr.c.

References ALLOC, CLPROC, cpexpr(), errnode, errstr(), ICON, inregister(), Addrblock::memno, Addrblock::memoffset, mkaddr(), Addrblock::name, PTHISPROC, replaced, Rplblock::rplnextp, Rplblock::rplnp, Rplblock::rpltag, Rplblock::rplvp, STGREG, TADDR, Addrblock::tag, TNAME, TYERROR, TYIREG, UNAM_NAME, vardcl(), Addrblock::vstg, and Addrblock::vtype.

Referenced by enddo(), exasgoto(), exassign(), exdo(), memversion(), and mklhs().

01304 {
01305         register Addrp s;
01306         register struct Rplblock *rp;
01307         int regn;
01308 
01309         /* is name on the replace list? */
01310 
01311         for(rp = rpllist ; rp ; rp = rp->rplnextp)
01312         {
01313                 if(np == rp->rplnp)
01314                 {
01315                         replaced = 1;
01316                         if(rp->rpltag == TNAME)
01317                         {
01318                                 np = (Namep) (rp->rplvp);
01319                                 break;
01320                         }
01321                         else    return( (Addrp) cpexpr(rp->rplvp) );
01322                 }
01323         }
01324 
01325         /* is variable a DO index in a register ? */
01326 
01327         if(np->vdovar && ( (regn = inregister(np)) >= 0) )
01328                 if(np->vtype == TYERROR)
01329                         return((Addrp) errnode() );
01330                 else
01331                 {
01332                         s = ALLOC(Addrblock);
01333                         s->tag = TADDR;
01334                         s->vstg = STGREG;
01335                         s->vtype = TYIREG;
01336                         s->memno = regn;
01337                         s->memoffset = ICON(0);
01338                         s -> uname_tag = UNAM_NAME;
01339                         s -> user.name = np;
01340                         return(s);
01341                 }
01342 
01343         if (np->vclass == CLPROC && np->vprocclass != PTHISPROC)
01344                 errstr("external %.60s used as a variable", np->fvarname);
01345         vardcl(np);
01346         return(mkaddr(np));
01347 }

LOCAL expptr mkpower register expptr    p
 

Definition at line 3289 of file expr.c.

References Expression::addrblock, call2(), callk_kludge, charptr, Constant::ci, Constblock::Const, Expression::constblock, err, errnode, Expression::exprblock, fixexpr(), free, frexpr(), Expression::headblock, ICON, ISCONST, ISICON, ISINT, ISREAL, Exprblock::leftp, M, maxtype(), mkconv(), mkexpr(), MSKINT, MSKREAL, ONEOF, OPSLASH, Addrblock::parenused, powint, putconst(), q, Exprblock::rightp, TADDR, Expression::tag, TYQUAD, Exprblock::vtype, and Headblock::vtype.

Referenced by fixexpr().

03291 {
03292         register expptr q, lp, rp;
03293         int ltype, rtype, mtype, tyi;
03294 
03295         lp = p->exprblock.leftp;
03296         rp = p->exprblock.rightp;
03297         ltype = lp->headblock.vtype;
03298         rtype = rp->headblock.vtype;
03299 
03300         if (lp->tag == TADDR)
03301                 lp->addrblock.parenused = 0;
03302 
03303         if (rp->tag == TADDR)
03304                 rp->addrblock.parenused = 0;
03305 
03306         if(ISICON(rp))
03307         {
03308                 if(rp->constblock.Const.ci == 0)
03309                 {
03310                         frexpr(p);
03311                         if( ISINT(ltype) )
03312                                 return( ICON(1) );
03313                         else if (ISREAL (ltype))
03314                                 return mkconv (ltype, ICON (1));
03315                         else
03316                                 return( (expptr) putconst((Constp)
03317                                         mkconv(ltype, ICON(1))) );
03318                 }
03319                 if(rp->constblock.Const.ci < 0)
03320                 {
03321                         if( ISINT(ltype) )
03322                         {
03323                                 frexpr(p);
03324                                 err("integer**negative");
03325                                 return( errnode() );
03326                         }
03327                         rp->constblock.Const.ci = - rp->constblock.Const.ci;
03328                         p->exprblock.leftp = lp
03329                                 = fixexpr((Exprp)mkexpr(OPSLASH, ICON(1), lp));
03330                 }
03331                 if(rp->constblock.Const.ci == 1)
03332                 {
03333                         frexpr(rp);
03334                         free( (charptr) p );
03335                         return(lp);
03336                 }
03337 
03338                 if( ONEOF(ltype, MSKINT|MSKREAL) ) {
03339                         p->exprblock.vtype = ltype;
03340                         return(p);
03341                 }
03342         }
03343         if( ISINT(rtype) )
03344         {
03345                 if(ltype==TYSHORT && rtype==TYSHORT && (!ISCONST(lp) || tyint==TYSHORT) )
03346                         q = call2(TYSHORT, "pow_hh", lp, rp);
03347                 else    {
03348                         if(ONEOF(ltype,M(TYINT1)|M(TYSHORT)))
03349                         {
03350                                 ltype = TYLONG;
03351                                 lp = mkconv(TYLONG,lp);
03352                         }
03353 #ifdef TYQUAD
03354                         if (ltype == TYQUAD)
03355                                 rp = mkconv(TYQUAD,rp);
03356                         else
03357 #endif
03358                         rp = mkconv(TYLONG,rp);
03359                         if (ISCONST(rp)) {
03360                                 tyi = tyint;
03361                                 tyint = TYLONG;
03362                                 rp = (expptr)putconst((Constp)rp);
03363                                 tyint = tyi;
03364                                 }
03365                         q = call2(ltype, powint[ltype-TYLONG], lp, rp);
03366                 }
03367         }
03368         else if( ISREAL( (mtype = maxtype(ltype,rtype)) )) {
03369                 extern int callk_kludge;
03370                 callk_kludge = TYDREAL;
03371                 q = call2(mtype, "pow_dd", mkconv(TYDREAL,lp), mkconv(TYDREAL,rp));
03372                 callk_kludge = 0;
03373                 }
03374         else    {
03375                 q  = call2(TYDCOMPLEX, "pow_zz",
03376                     mkconv(TYDCOMPLEX,lp), mkconv(TYDCOMPLEX,rp));
03377                 if(mtype == TYCOMPLEX)
03378                         q = mkconv(TYCOMPLEX, q);
03379         }
03380         free( (charptr) p );
03381         return(q);
03382 }

expptr mkprim Namep    v0,
struct Listblock   args,
chainp    substr
 

Definition at line 1795 of file expr.c.

References ALLOC, Primblock::argsp, CLPARAM, cpexpr(), errnode, errstr(), Primblock::fcharp, frchain(), frexpr(), Primblock::lcharp, Primblock::namep, Primblock::tag, TPRIM, v, and Primblock::vtype.

Referenced by excall(), and yyparse().

01797 {
01798         typedef union {
01799                 struct Paramblock paramblock;
01800                 struct Nameblock nameblock;
01801                 struct Headblock headblock;
01802                 } *Primu;
01803         register Primu v = (Primu)v0;
01804         register struct Primblock *p;
01805 
01806         if(v->headblock.vclass == CLPARAM)
01807         {
01808 
01809 /* v   is to be a Paramblock */
01810 
01811                 if(args || substr)
01812                 {
01813                         errstr("no qualifiers on parameter name %s",
01814                             v->paramblock.fvarname);
01815                         frexpr((expptr)args);
01816                         if(substr)
01817                         {
01818                                 frexpr((tagptr)substr->datap);
01819                                 frexpr((tagptr)substr->nextp->datap);
01820                                 frchain(&substr);
01821                         }
01822                         frexpr((expptr)v);
01823                         return( errnode() );
01824                 }
01825                 return( (expptr) cpexpr(v->paramblock.paramval) );
01826         }
01827 
01828         p = ALLOC(Primblock);
01829         p->tag = TPRIM;
01830         p->vtype = v->nameblock.vtype;
01831 
01832 /* v   is to be a Nameblock */
01833 
01834         p->namep = (Namep) v;
01835         p->argsp = args;
01836         if(substr)
01837         {
01838                 p->fcharp = (expptr) substr->datap;
01839                 p->lcharp = (expptr) substr->nextp->datap;
01840                 frchain(&substr);
01841         }
01842         return( (expptr) p);
01843 }

expptr mkrealcon register int    t,
char *    d
 

Definition at line 125 of file expr.c.

References cds(), Constant::cds, CNULL, Constblock::Const, mkconst(), p, and Constblock::vstg.

Referenced by imagpart(), intrcall(), putcx1(), realpart(), and yyparse().

00127 {
00128         register Constp p;
00129 
00130         p = mkconst(t);
00131         p->Const.cds[0] = cds(d,CNULL);
00132         p->vstg = 1;
00133         return( (expptr) p );
00134 }

Addrp mkscalar register Namep    np
 

Definition at line 970 of file expr.c.

References Dimblock::baseoffset, frexpr(), ICON, Addrblock::memoffset, mkaddr(), mkexpr(), OPSTAR, STGARG, and vardcl().

Referenced by doiolist(), fixargs(), and startrw().

00972 {
00973         register Addrp ap;
00974 
00975         vardcl(np);
00976         ap = mkaddr(np);
00977 
00978         /* The prolog causes array arguments to point to the
00979          * (0,...,0) element, unless subscript checking is on.
00980          */
00981         if( !checksubs && np->vstg==STGARG)
00982         {
00983                 register struct Dimblock *dp;
00984                 dp = np->vdim;
00985                 frexpr(ap->memoffset);
00986                 ap->memoffset = mkexpr(OPSTAR,
00987                     (np->vtype==TYCHAR ?
00988                     cpexpr(np->vleng) :
00989                     (tagptr)ICON(typesize[np->vtype]) ),
00990                     cpexpr(dp->baseoffset) );
00991         }
00992         return(ap);
00993 }

expptr mkstrcon int    l,
register char *    v
 

Definition at line 199 of file expr.c.

References Constant::ccp1, ckalloc(), Constblock::Const, ICON, l, mkconst(), p, v, and Constblock::vleng.

Referenced by exstop(), subcheck(), and yyparse().

00201 {
00202         register Constp p;
00203         register char *s;
00204 
00205         p = mkconst(TYCHAR);
00206         p->vleng = ICON(l);
00207         p->Const.ccp = s = (char *) ckalloc(l+1);
00208         p->Const.ccp1.blanks = 0;
00209         while(--l >= 0)
00210                 *s++ = *v++;
00211         *s = '\0';
00212         return( (expptr) p );
00213 }

expptr opconv expptr    p,
int    t
 

Definition at line 359 of file expr.c.

References ENULL, err, Expression::headblock, mkexpr(), OPCONV, q, and Headblock::vtype.

Referenced by mkconv().

00361 {
00362         register expptr q;
00363 
00364         if (t == TYSUBR)
00365                 err("illegal use of subroutine name");
00366         q = mkexpr(OPCONV, p, ENULL);
00367         q->headblock.vtype = t;
00368         return(q);
00369 }

void sserr Namep    np
 

Definition at line 3430 of file expr.c.

References errstr().

Referenced by fixargs(), mklhs(), and yyparse().

03432 {
03433         errstr(np->vtype == TYCHAR
03434                 ? "substring of character array %.70s"
03435                 : "substring of noncharacter %.73s", np->fvarname);
03436         }

expptr stfcall Namep    np,
struct Listblock   actlist
[static]
 

Definition at line 1171 of file expr.c.

References ALLOC, charptr, Constant::ci, Constblock::Const, Expression::constblock, cpexpr(), Chain::datap, dclerr(), dflttype, err, errstr(), Expression::exprblock, fixtype(), frchain(), free, frexpr(), Expression::headblock, ICON, letter, Listblock::listp, mkconv(), mkexpr(), mktmp(), Chain::nextp, OPASSIGN, OPCOMMA, putexpr(), q, Rplblock::rplnextp, Rplblock::rplnp, Rplblock::rpltag, Rplblock::rplvp, Rplblock::rplxp, TADDR, Expression::tag, TCONST, TERROR, Exprblock::vleng, Nameblock::vleng, Headblock::vtype, and Nameblock::vtype.

Referenced by mkfunct().

01173 {
01174         register chainp actuals;
01175         int nargs;
01176         chainp oactp, formals;
01177         int type;
01178         expptr Ln, Lq, q, q1, rhs, ap;
01179         Namep tnp;
01180         register struct Rplblock *rp;
01181         struct Rplblock *tlist;
01182 
01183         if (np->arginfo) {
01184                 errstr("statement function %.66s calls itself.",
01185                         np->fvarname);
01186                 return ICON(0);
01187                 }
01188         np->arginfo = (Argtypes *)np;   /* arbitrary nonzero value */
01189         if(actlist)
01190         {
01191                 actuals = actlist->listp;
01192                 free( (charptr) actlist);
01193         }
01194         else
01195                 actuals = NULL;
01196         oactp = actuals;
01197 
01198         nargs = 0;
01199         tlist = NULL;
01200         if( (type = np->vtype) == TYUNKNOWN)
01201         {
01202                 dclerr("attempt to use untyped statement function", np);
01203                 type = np->vtype = dflttype[letter(np->fvarname[0])];
01204         }
01205         formals = (chainp) np->varxptr.vstfdesc->datap;
01206         rhs = (expptr) (np->varxptr.vstfdesc->nextp);
01207 
01208         /* copy actual arguments into temporaries */
01209         while(actuals!=NULL && formals!=NULL)
01210         {
01211                 if (!(tnp = (Namep) formals->datap)) {
01212                         /* buggy statement function declaration */
01213                         q = ICON(1);
01214                         goto done;
01215                         }
01216                 rp = ALLOC(Rplblock);
01217                 rp->rplnp = tnp;
01218                 ap = fixtype((tagptr)actuals->datap);
01219                 if(tnp->vtype==ap->headblock.vtype && tnp->vtype!=TYCHAR
01220                     && (ap->tag==TCONST || ap->tag==TADDR) )
01221                 {
01222 
01223 /* If actuals are constants or variable names, no temporaries are required */
01224                         rp->rplvp = (expptr) ap;
01225                         rp->rplxp = NULL;
01226                         rp->rpltag = ap->tag;
01227                 }
01228                 else    {
01229                         rp->rplvp = (expptr) mktmp(tnp->vtype, tnp->vleng);
01230                         rp -> rplxp = NULL;
01231                         putexpr ( mkexpr(OPASSIGN, cpexpr(rp->rplvp), ap));
01232                         if((rp->rpltag = rp->rplvp->tag) == TERROR)
01233                                 err("disagreement of argument types in statement function call");
01234                 }
01235                 rp->rplnextp = tlist;
01236                 tlist = rp;
01237                 actuals = actuals->nextp;
01238                 formals = formals->nextp;
01239                 ++nargs;
01240         }
01241 
01242         if(actuals!=NULL || formals!=NULL)
01243                 err("statement function definition and argument list differ");
01244 
01245         /*
01246    now push down names involved in formal argument list, then
01247    evaluate rhs of statement function definition in this environment
01248 */
01249 
01250         if(tlist)       /* put tlist in front of the rpllist */
01251         {
01252                 for(rp = tlist; rp->rplnextp; rp = rp->rplnextp)
01253                         ;
01254                 rp->rplnextp = rpllist;
01255                 rpllist = tlist;
01256         }
01257 
01258 /* So when the expression finally gets evaled, that evaluator must read
01259    from the globl   rpllist   14-jun-88 mwm */
01260 
01261         q = (expptr) mkconv(type, fixtype(cpexpr(rhs)) );
01262 
01263         /* get length right of character-valued statement functions... */
01264         if (type == TYCHAR
01265          && (Ln = np->vleng)
01266          && q->tag != TERROR
01267          && (Lq = q->exprblock.vleng)
01268          && (Lq->tag != TCONST
01269                 || Ln->constblock.Const.ci != Lq->constblock.Const.ci)) {
01270                 q1 = (expptr) mktmp(type, Ln);
01271                 putexpr ( mkexpr(OPASSIGN, cpexpr(q1), q));
01272                 q = q1;
01273                 }
01274 
01275         /* now generate the tree ( t1=a1, (t2=a2,... , f))))) */
01276         while(--nargs >= 0)
01277         {
01278                 if(rpllist->rplxp)
01279                         q = mkexpr(OPCOMMA, rpllist->rplxp, q);
01280                 rp = rpllist->rplnextp;
01281                 frexpr(rpllist->rplvp);
01282                 free((char *)rpllist);
01283                 rpllist = rp;
01284         }
01285  done:
01286         frchain( &oactp );
01287         np->arginfo = 0;
01288         return(q);
01289 }

expptr subcheck Namep    np,
register expptr    p
 

Definition at line 1606 of file expr.c.

References Expression::addrblock, call4(), Constant::ci, Constblock::Const, Expression::constblock, cpexpr(), ENULL, errstr(), frexpr(), Expression::headblock, ICON, ISICON, mkexpr(), mkstrcon(), mktmp(), Dimblock::nelt, OPAND, OPASSIGN, OPCCALL, OPCOLON, OPLE, OPLT, OPQUEST, STGREG, TADDR, Expression::tag, Addrblock::vstg, and Headblock::vtype.

Referenced by suboffset().

01608 {
01609         struct Dimblock *dimp;
01610         expptr t, checkvar, checkcond, badcall;
01611 
01612         dimp = np->vdim;
01613         if(dimp->nelt == NULL)
01614                 return(p);      /* don't check arrays with * bounds */
01615         np->vlastdim = 0;
01616         if( ISICON(p) )
01617         {
01618 
01619 /* check for negative (constant) offset */
01620 
01621                 if(p->constblock.Const.ci < 0)
01622                         goto badsub;
01623                 if( ISICON(dimp->nelt) )
01624 
01625 /* see if constant offset exceeds the array declaration */
01626 
01627                         if(p->constblock.Const.ci < dimp->nelt->constblock.Const.ci)
01628                                 return(p);
01629                         else
01630                                 goto badsub;
01631         }
01632 
01633 /* We know that the subscript offset   p   or   dimp -> nelt   is not a constant.
01634    Now find a register to use for run-time bounds checking */
01635 
01636         if(p->tag==TADDR && p->addrblock.vstg==STGREG)
01637         {
01638                 checkvar = (expptr) cpexpr(p);
01639                 t = p;
01640         }
01641         else    {
01642                 checkvar = (expptr) mktmp(p->headblock.vtype, ENULL);
01643                 t = mkexpr(OPASSIGN, cpexpr(checkvar), p);
01644         }
01645         checkcond = mkexpr(OPLT, t, cpexpr(dimp->nelt) );
01646         if( ! ISICON(p) )
01647                 checkcond = mkexpr(OPAND, checkcond,
01648                     mkexpr(OPLE, ICON(0), cpexpr(checkvar)) );
01649 
01650 /* Construct the actual test */
01651 
01652         badcall = call4(p->headblock.vtype, "s_rnge",
01653             mkstrcon(strlen(np->fvarname), np->fvarname),
01654             mkconv(TYLONG,  cpexpr(checkvar)),
01655             mkstrcon(strlen(procname), procname),
01656             ICON(lineno) );
01657         badcall->exprblock.opcode = OPCCALL;
01658         p = mkexpr(OPQUEST, checkcond,
01659             mkexpr(OPCOLON, checkvar, badcall));
01660 
01661         return(p);
01662 
01663 badsub:
01664         frexpr(p);
01665         errstr("subscript on variable %s out of range", np->fvarname);
01666         return ( ICON(0) );
01667 }

expptr suboffset register struct Primblock   p
 

Definition at line 1527 of file expr.c.

References Primblock::argsp, Dimblock::baseoffset, cpexpr(), Chain::datap, Dimblock::dims, ENULL, erri(), errstr(), Primblock::fcharp, fixtype(), Nameblock::fvarname, Expression::headblock, ICON, ISCONST, ISINT, Listblock::listp, mkconv(), mkexpr(), mktmp(), Primblock::namep, Dimblock::ndim, Chain::nextp, NOEXT, OPMINUS, OPPLUS, OPSTAR, Expression::primblock, putassign(), putout(), STGARG, subcheck(), Expression::tag, TPRIM, Nameblock::vdim, Nameblock::vleng, Nameblock::vstg, Nameblock::vtype, and Headblock::vtype.

Referenced by doequiv(), and mklhs().

01529 {
01530         int n;
01531         expptr si, size;
01532         chainp cp;
01533         expptr e, e1, offp, prod;
01534         struct Dimblock *dimp;
01535         expptr sub[MAXDIM+1];
01536         register Namep np;
01537 
01538         np = p->namep;
01539         offp = ICON(0);
01540         n = 0;
01541         if(p->argsp)
01542                 for(cp = p->argsp->listp ; cp ; cp = cp->nextp)
01543                 {
01544                         si = fixtype(cpexpr((tagptr)cp->datap));
01545                         if (!ISINT(si->headblock.vtype)) {
01546                                 NOEXT("non-integer subscript");
01547                                 si = mkconv(TYLONG, si);
01548                                 }
01549                         sub[n++] = si;
01550                         if(n > maxdim)
01551                         {
01552                                 erri("more than %d subscripts", maxdim);
01553                                 break;
01554                         }
01555                 }
01556 
01557         dimp = np->vdim;
01558         if(n>0 && dimp==NULL)
01559                 errstr("subscripts on scalar variable %.68s", np->fvarname);
01560         else if(dimp && dimp->ndim!=n)
01561                 errstr("wrong number of subscripts on %.68s", np->fvarname);
01562         else if(n > 0)
01563         {
01564                 prod = sub[--n];
01565                 while( --n >= 0)
01566                         prod = mkexpr(OPPLUS, sub[n],
01567                             mkexpr(OPSTAR, prod, cpexpr(dimp->dims[n].dimsize)) );
01568                 if(checksubs || np->vstg!=STGARG)
01569                         prod = mkexpr(OPMINUS, prod, cpexpr(dimp->baseoffset));
01570 
01571 /* Add in the run-time bounds check */
01572 
01573                 if(checksubs)
01574                         prod = subcheck(np, prod);
01575                 size = np->vtype == TYCHAR ?
01576                     (expptr) cpexpr(np->vleng) : ICON(typesize[np->vtype]);
01577                 prod = mkexpr(OPSTAR, prod, size);
01578                 offp = mkexpr(OPPLUS, offp, prod);
01579         }
01580 
01581 /* Check for substring indicator */
01582 
01583         if(p->fcharp && np->vtype==TYCHAR) {
01584                 e = p->fcharp;
01585                 e1 = mkexpr(OPMINUS, cpexpr(e), ICON(1));
01586                 if (!ISCONST(e) && (e->tag != TPRIM || e->primblock.argsp)) {
01587                         e = (expptr)mktmp(TYLONG, ENULL);
01588                         putout(putassign(cpexpr(e), e1));
01589                         p->fcharp = mkexpr(OPPLUS, cpexpr(e), ICON(1));
01590                         e1 = e;
01591                         }
01592                 offp = mkexpr(OPPLUS, offp, e1);
01593                 }
01594         return(offp);
01595 }

expptr subskept struct Primblock   p,
Addrp    a
[static]
 

Definition at line 1355 of file expr.c.

References a, cpexpr(), erri(), fixtype(), ICON, Listblock::listp, mkchain(), mkexpr(), Chain::nextp, OPMINUS, putx(), UNAM_NAME, and UNAM_REF.

Referenced by mklhs().

01357 {
01358         expptr ep;
01359         struct Listblock *Lb;
01360         chainp cp;
01361 
01362         if (a->uname_tag != UNAM_NAME)
01363                 erri("subskept: uname_tag %d", a->uname_tag);
01364         a->user.name->vrefused = 1;
01365         a->user.name->visused = 1;
01366         a->uname_tag = UNAM_REF;
01367         Lb = (struct Listblock *)cpexpr((tagptr)p->argsp);
01368         for(cp = Lb->listp; cp; cp = cp->nextp)
01369                 cp->datap = (char *)putx(fixtype((tagptr)cp->datap));
01370         if (a->vtype == TYCHAR) {
01371                 ep = p->fcharp  ? mkexpr(OPMINUS, cpexpr(p->fcharp), ICON(1))
01372                                 : ICON(0);
01373                 Lb->listp = mkchain((char *)ep, Lb->listp);
01374                 }
01375         return (expptr)Lb;
01376         }

void vardcl register Namep    v
 

Definition at line 1856 of file expr.c.

References CLNAMELIST, CLPROC, CLUNKNOWN, CLVAR, dclerr(), doing_stmtfcn, impldcl(), ISCONST, letter, Dimblock::nelt, PTHISPROC, STGAUTO, STGBSS, STGUNKNOWN, v, and YES.

Referenced by docommon(), doequiv(), doiolist(), ioclause(), mkplace(), mkscalar(), mkstfunct(), namelist(), startrw(), and yyparse().

01858 {
01859         struct Dimblock *t;
01860         expptr neltp;
01861         extern int doing_stmtfcn;
01862 
01863         if(v->vclass == CLUNKNOWN) {
01864                 v->vclass = CLVAR;
01865                 if (v->vinftype) {
01866                         v->vtype = TYUNKNOWN;
01867                         if (v->vdcldone) {
01868                                 v->vdcldone = 0;
01869                                 impldcl(v);
01870                                 }
01871                         }
01872                 }
01873         if(v->vdcldone)
01874                 return;
01875         if(v->vclass == CLNAMELIST)
01876                 return;
01877 
01878         if(v->vtype == TYUNKNOWN)
01879                 impldcl(v);
01880         else if(v->vclass!=CLVAR && v->vprocclass!=PTHISPROC)
01881         {
01882                 dclerr("used as variable", v);
01883                 return;
01884         }
01885         if(v->vstg==STGUNKNOWN) {
01886                 if (doing_stmtfcn) {
01887                         /* neither declare this variable if its only use */
01888                         /* is in defining a stmt function, nor complain  */
01889                         /* that it is never used */
01890                         v->vimpldovar = 1;
01891                         return;
01892                         }
01893                 v->vstg = implstg[ letter(v->fvarname[0]) ];
01894                 v->vimplstg = 1;
01895                 }
01896 
01897 /* Compute the actual storage location, i.e. offsets from base addresses,
01898    possibly the stack pointer */
01899 
01900         switch(v->vstg)
01901         {
01902         case STGBSS:
01903                 v->vardesc.varno = ++lastvarno;
01904                 break;
01905         case STGAUTO:
01906                 if(v->vclass==CLPROC && v->vprocclass==PTHISPROC)
01907                         break;
01908                 if(t = v->vdim)
01909                         if( (neltp = t->nelt) && ISCONST(neltp) ) ;
01910                         else
01911                                 dclerr("adjustable automatic array", v);
01912                 break;
01913 
01914         default:
01915                 break;
01916         }
01917         v->vdcldone = YES;
01918 }

void wronginf Namep    np
 

Definition at line 550 of file expr.c.

References c, ICON, letter, and warn1().

Referenced by fixtype().

00552 {
00553         int c, k;
00554         warn1("fixing wrong type inferred for %.65s", np->fvarname);
00555         np->vinftype = 0;
00556         c = letter(np->fvarname[0]);
00557         if ((np->vtype = impltype[c]) == TYCHAR
00558         && (k = implleng[c]))
00559                 np->vleng = ICON(k);
00560         }

LOCAL void zdiv register dcomplex   c,
register dcomplex   a,
register dcomplex   b
 

Definition at line 3396 of file expr.c.

References c, dcomplex::dimag, dcomplex::dreal, and Fatal().

Referenced by consbinop().

03398 {
03399         double ratio, den;
03400         double abr, abi;
03401 
03402         if( (abr = b->dreal) < 0.)
03403                 abr = - abr;
03404         if( (abi = b->dimag) < 0.)
03405                 abi = - abi;
03406         if( abr <= abi )
03407         {
03408                 if(abi == 0)
03409                         Fatal("complex division by zero");
03410                 ratio = b->dreal / b->dimag ;
03411                 den = b->dimag * (1 + ratio*ratio);
03412                 c->dreal = (a->dreal*ratio + a->dimag) / den;
03413                 c->dimag = (a->dimag*ratio - a->dreal) / den;
03414         }
03415 
03416         else
03417         {
03418                 ratio = b->dimag / b->dreal ;
03419                 den = b->dreal * (1 + ratio*ratio);
03420                 c->dreal = (a->dreal + a->dimag*ratio) / den;
03421                 c->dimag = (a->dimag - a->dreal*ratio) / den;
03422         }
03423 }

LOCAL int zeroconst expptr    e
 

Definition at line 1982 of file expr.c.

References c, Constant::cd, Constant::cds, Constant::ci, Constblock::Const, Constblock::tag, TCONST, TYQUAD, Constblock::vstg, and Constblock::vtype.

Referenced by fold(), and mkexpr().

01984 {
01985         register Constp c = (Constp) e;
01986         if (c->tag == TCONST)
01987                 switch(c->vtype) {
01988                 case TYINT1:
01989                 case TYSHORT:
01990                 case TYLONG:
01991 #ifdef TYQUAD
01992                 case TYQUAD:
01993 #endif
01994                         return c->Const.ci == 0;
01995 
01996                 case TYREAL:
01997                 case TYDREAL:
01998                         if (c->vstg == 1)
01999                                 return !strcmp(c->Const.cds[0],"0.");
02000                         return c->Const.cd[0] == 0.;
02001 
02002                 case TYCOMPLEX:
02003                 case TYDCOMPLEX:
02004                         if (c->vstg == 1)
02005                                 return !strcmp(c->Const.cds[0],"0.")
02006                                     && !strcmp(c->Const.cds[1],"0.");
02007                         return c->Const.cd[0] == 0. && c->Const.cd[1] == 0.;
02008                 }
02009         return 0;
02010         }

Variable Documentation

char dflttype[26]
 

Definition at line 36 of file expr.c.

Referenced by fileinit(), impldcl(), mkfunct(), and stfcall().

int doing_vleng [static]
 

Definition at line 1378 of file expr.c.

Referenced by mkexpr(), and mklhs().

expptr errnode(Void)
 

Definition at line 276 of file expr.c.

Referenced by fixexpr(), fixtype(), intraddr(), intrcall(), mkcxcon(), mkexpr(), mkfunct(), mkplace(), mkpower(), mkprim(), mktmpn(), and putx().

00277 {
00278         struct Errorblock *p;
00279         p = ALLOC(Errorblock);
00280         p->tag = TERROR;
00281         p->vtype = TYERROR;
00282         return( (expptr) p );
00283 }

int htype
 

Definition at line 37 of file expr.c.

Referenced by cktype(), and set_externs().

char* powint[ ]
 

Initial value:

 {
        "pow_ii",

                  "pow_qq",

                  "pow_ri", "pow_di", "pow_ci", "pow_zi" }

Definition at line 3277 of file expr.c.

Referenced by mkpower().

int replaced [static]
 

Definition at line 1292 of file expr.c.

Referenced by mklhs(), and mkplace().

 

Powered by Plone

This site conforms to the following standards: