Doxygen Source Code Documentation
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
|
|
Definition at line 2014 of file expr.c. Referenced by mkexpr(). |
|
|
|
|
|
Definition at line 2013 of file expr.c. Referenced by mkexpr(). |
Function Documentation
|
|
Definition at line 380 of file expr.c. References ENULL, mkexpr(), and OPADDR. Referenced by ioseta(), iosetc(), iosetip(), and putct1().
|
|
|
Definition at line 1001 of file expr.c. References Extsym::arginfo, Entrypoint::arglist, args, Entrypoint::entnextp, Entrypoint::entryname, and Argtypes::nargs. Referenced by mkfunct().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
Definition at line 1963 of file expr.c. References frexpr(), and letter. Referenced by mkaddr(), and typekludge().
|
|
|
Definition at line 1506 of file expr.c. References i. Referenced by memversion(), and mkplace().
|
|
|
Definition at line 2528 of file expr.c. References err. Referenced by consbinop(), consnegop(), and fold().
02529 { err("overflow simplifying integer constants."); }
|
|
|
Definition at line 1484 of file expr.c. References inregister(), mkplace(), NO, and YES. Referenced by doiolist(), enddo(), and fixargs().
|
|
|
Definition at line 104 of file expr.c. References Constant::ci, Constblock::Const, l, mkconst(), and p. Referenced by startrw().
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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().
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 }
|
|
|
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().
|
|
||||||||||||
|
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 }
|
|
|
Definition at line 65 of file expr.c. References Constant::ci, Constblock::Const, l, mkconst(), and p. Referenced by yyparse().
|
|
|
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 }
|
|
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||
|
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().
|
|
|
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 }
|
|
||||||||||||
|
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().
|
|
||||||||||||
|
Definition at line 359 of file expr.c. References ENULL, err, Expression::headblock, mkexpr(), OPCONV, q, and Headblock::vtype. Referenced by mkconv().
|
|
|
Definition at line 3430 of file expr.c. References errstr(). Referenced by fixargs(), mklhs(), and yyparse().
|
|
||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
||||||||||||
|
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 }
|
|
|
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 }
|
|
|
Definition at line 550 of file expr.c. References c, ICON, letter, and warn1(). Referenced by fixtype().
|
|
||||||||||||||||
|
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 }
|
|
|
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
|
|
Definition at line 36 of file expr.c. Referenced by fileinit(), impldcl(), mkfunct(), and stfcall(). |
|
|
|
|
|
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 }
|
|
|
Definition at line 37 of file expr.c. Referenced by cktype(), and set_externs(). |
|
|
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(). |
|
|
|