intr.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990, 1992, 1994-6, 1998 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 #include "defs.h"
00025 #include "names.h"
00026 
00027 union
00028         {
00029         int ijunk;
00030         struct Intrpacked bits;
00031         } packed;
00032 
00033 struct Intrbits
00034         {
00035         char intrgroup /* :3 */;
00036         char intrstuff /* result type or number of generics */;
00037         char intrno /* :7 */;
00038         char dblcmplx;
00039         char dblintrno; /* for -r8 */
00040         char extflag;   /* for -cd, -i90 */
00041         };
00042 
00043 /* List of all intrinsic functions.  */
00044 
00045 LOCAL struct Intrblock
00046         {
00047         char intrfname[8];
00048         struct Intrbits intrval;
00049         } intrtab[ ] =
00050 {
00051 "int",          { INTRCONV, TYLONG },
00052 "real",         { INTRCONV, TYREAL, 1 },
00053                 /* 1 ==> real(TYDCOMPLEX) yields TYDREAL */
00054 "dble",         { INTRCONV, TYDREAL },
00055 "dreal",        { INTRCONV, TYDREAL, 0, 0, 0, 1 },
00056 "cmplx",        { INTRCONV, TYCOMPLEX },
00057 "dcmplx",       { INTRCONV, TYDCOMPLEX, 0, 1 },
00058 "ifix",         { INTRCONV, TYLONG },
00059 "idint",        { INTRCONV, TYLONG },
00060 "float",        { INTRCONV, TYREAL },
00061 "dfloat",       { INTRCONV, TYDREAL },
00062 "sngl",         { INTRCONV, TYREAL },
00063 "ichar",        { INTRCONV, TYLONG },
00064 "iachar",       { INTRCONV, TYLONG },
00065 "char",         { INTRCONV, TYCHAR },
00066 "achar",        { INTRCONV, TYCHAR },
00067 
00068 /* any MAX or MIN can be used with any types; the compiler will cast them
00069    correctly.  So rules against bad syntax in these expressions are not
00070    enforced */
00071 
00072 "max",          { INTRMAX, TYUNKNOWN },
00073 "max0",         { INTRMAX, TYLONG },
00074 "amax0",        { INTRMAX, TYREAL },
00075 "max1",         { INTRMAX, TYLONG },
00076 "amax1",        { INTRMAX, TYREAL },
00077 "dmax1",        { INTRMAX, TYDREAL },
00078 
00079 "and",          { INTRBOOL, TYUNKNOWN, OPBITAND },
00080 "or",           { INTRBOOL, TYUNKNOWN, OPBITOR },
00081 "xor",          { INTRBOOL, TYUNKNOWN, OPBITXOR },
00082 "not",          { INTRBOOL, TYUNKNOWN, OPBITNOT },
00083 "lshift",       { INTRBOOL, TYUNKNOWN, OPLSHIFT },
00084 "rshift",       { INTRBOOL, TYUNKNOWN, OPRSHIFT },
00085 
00086 "min",          { INTRMIN, TYUNKNOWN },
00087 "min0",         { INTRMIN, TYLONG },
00088 "amin0",        { INTRMIN, TYREAL },
00089 "min1",         { INTRMIN, TYLONG },
00090 "amin1",        { INTRMIN, TYREAL },
00091 "dmin1",        { INTRMIN, TYDREAL },
00092 
00093 "aint",         { INTRGEN, 2, 0 },
00094 "dint",         { INTRSPEC, TYDREAL, 1 },
00095 
00096 "anint",        { INTRGEN, 2, 2 },
00097 "dnint",        { INTRSPEC, TYDREAL, 3 },
00098 
00099 "nint",         { INTRGEN, 4, 4 },
00100 "idnint",       { INTRGEN, 2, 6 },
00101 
00102 "abs",          { INTRGEN, 6, 8 },
00103 "iabs",         { INTRGEN, 2, 9 },
00104 "dabs",         { INTRSPEC, TYDREAL, 11 },
00105 "cabs",         { INTRSPEC, TYREAL, 12, 0, 13 },
00106 "zabs",         { INTRSPEC, TYDREAL, 13, 1 },
00107 
00108 "mod",          { INTRGEN, 4, 14 },
00109 "amod",         { INTRSPEC, TYREAL, 16, 0, 17 },
00110 "dmod",         { INTRSPEC, TYDREAL, 17 },
00111 
00112 "sign",         { INTRGEN, 4, 18 },
00113 "isign",        { INTRGEN, 2, 19 },
00114 "dsign",        { INTRSPEC, TYDREAL, 21 },
00115 
00116 "dim",          { INTRGEN, 4, 22 },
00117 "idim",         { INTRGEN, 2, 23 },
00118 "ddim",         { INTRSPEC, TYDREAL, 25 },
00119 
00120 "dprod",        { INTRSPEC, TYDREAL, 26 },
00121 
00122 "len",          { INTRSPEC, TYLONG, 27 },
00123 "index",        { INTRSPEC, TYLONG, 29 },
00124 
00125 "imag",         { INTRGEN, 2, 31 },
00126 "aimag",        { INTRSPEC, TYREAL, 31, 0, 32 },
00127 "dimag",        { INTRSPEC, TYDREAL, 32 },
00128 
00129 "conjg",        { INTRGEN, 2, 33 },
00130 "dconjg",       { INTRSPEC, TYDCOMPLEX, 34, 1 },
00131 
00132 "sqrt",         { INTRGEN, 4, 35 },
00133 "dsqrt",        { INTRSPEC, TYDREAL, 36 },
00134 "csqrt",        { INTRSPEC, TYCOMPLEX, 37, 0, 38 },
00135 "zsqrt",        { INTRSPEC, TYDCOMPLEX, 38, 1 },
00136 
00137 "exp",          { INTRGEN, 4, 39 },
00138 "dexp",         { INTRSPEC, TYDREAL, 40 },
00139 "cexp",         { INTRSPEC, TYCOMPLEX, 41, 0, 42 },
00140 "zexp",         { INTRSPEC, TYDCOMPLEX, 42, 1 },
00141 
00142 "log",          { INTRGEN, 4, 43 },
00143 "alog",         { INTRSPEC, TYREAL, 43, 0, 44 },
00144 "dlog",         { INTRSPEC, TYDREAL, 44 },
00145 "clog",         { INTRSPEC, TYCOMPLEX, 45, 0, 46 },
00146 "zlog",         { INTRSPEC, TYDCOMPLEX, 46, 1 },
00147 
00148 "log10",        { INTRGEN, 2, 47 },
00149 "alog10",       { INTRSPEC, TYREAL, 47, 0, 48 },
00150 "dlog10",       { INTRSPEC, TYDREAL, 48 },
00151 
00152 "sin",          { INTRGEN, 4, 49 },
00153 "dsin",         { INTRSPEC, TYDREAL, 50 },
00154 "csin",         { INTRSPEC, TYCOMPLEX, 51, 0, 52 },
00155 "zsin",         { INTRSPEC, TYDCOMPLEX, 52, 1 },
00156 
00157 "cos",          { INTRGEN, 4, 53 },
00158 "dcos",         { INTRSPEC, TYDREAL, 54 },
00159 "ccos",         { INTRSPEC, TYCOMPLEX, 55, 0, 56 },
00160 "zcos",         { INTRSPEC, TYDCOMPLEX, 56, 1 },
00161 
00162 "tan",          { INTRGEN, 2, 57 },
00163 "dtan",         { INTRSPEC, TYDREAL, 58 },
00164 
00165 "asin",         { INTRGEN, 2, 59 },
00166 "dasin",        { INTRSPEC, TYDREAL, 60 },
00167 
00168 "acos",         { INTRGEN, 2, 61 },
00169 "dacos",        { INTRSPEC, TYDREAL, 62 },
00170 
00171 "atan",         { INTRGEN, 2, 63 },
00172 "datan",        { INTRSPEC, TYDREAL, 64 },
00173 
00174 "atan2",        { INTRGEN, 2, 65 },
00175 "datan2",       { INTRSPEC, TYDREAL, 66 },
00176 
00177 "sinh",         { INTRGEN, 2, 67 },
00178 "dsinh",        { INTRSPEC, TYDREAL, 68 },
00179 
00180 "cosh",         { INTRGEN, 2, 69 },
00181 "dcosh",        { INTRSPEC, TYDREAL, 70 },
00182 
00183 "tanh",         { INTRGEN, 2, 71 },
00184 "dtanh",        { INTRSPEC, TYDREAL, 72 },
00185 
00186 "lge",          { INTRSPEC, TYLOGICAL, 73},
00187 "lgt",          { INTRSPEC, TYLOGICAL, 75},
00188 "lle",          { INTRSPEC, TYLOGICAL, 77},
00189 "llt",          { INTRSPEC, TYLOGICAL, 79},
00190 
00191 #if 0
00192 "epbase",       { INTRCNST, 4, 0 },
00193 "epprec",       { INTRCNST, 4, 4 },
00194 "epemin",       { INTRCNST, 2, 8 },
00195 "epemax",       { INTRCNST, 2, 10 },
00196 "eptiny",       { INTRCNST, 2, 12 },
00197 "ephuge",       { INTRCNST, 4, 14 },
00198 "epmrsp",       { INTRCNST, 2, 18 },
00199 #endif
00200 
00201 "fpexpn",       { INTRGEN, 4, 81 },
00202 "fpabsp",       { INTRGEN, 2, 85 },
00203 "fprrsp",       { INTRGEN, 2, 87 },
00204 "fpfrac",       { INTRGEN, 2, 89 },
00205 "fpmake",       { INTRGEN, 2, 91 },
00206 "fpscal",       { INTRGEN, 2, 93 },
00207 
00208 "cdabs",        { INTRSPEC, TYDREAL,    13, 1, 0, 1 },
00209 "cdsqrt",       { INTRSPEC, TYDCOMPLEX, 38, 1, 0, 1 },
00210 "cdexp",        { INTRSPEC, TYDCOMPLEX, 42, 1, 0, 1 },
00211 "cdlog",        { INTRSPEC, TYDCOMPLEX, 46, 1, 0, 1 },
00212 "cdsin",        { INTRSPEC, TYDCOMPLEX, 52, 1, 0, 1 },
00213 "cdcos",        { INTRSPEC, TYDCOMPLEX, 56, 1, 0, 1 },
00214 
00215 "iand",         { INTRBOOL, TYUNKNOWN, OPBITAND, 0, 0, 2 },
00216 "ior",          { INTRBOOL, TYUNKNOWN, OPBITOR,  0, 0, 2 },
00217 "ieor",         { INTRBOOL, TYUNKNOWN, OPBITXOR, 0, 0, 2 },
00218 
00219 "btest",        { INTRBGEN, TYLOGICAL, OPBITTEST,0, 0, 2 },
00220 "ibclr",        { INTRBGEN, TYUNKNOWN, OPBITCLR, 0, 0, 2 },
00221 "ibset",        { INTRBGEN, TYUNKNOWN, OPBITSET, 0, 0, 2 },
00222 "ibits",        { INTRBGEN, TYUNKNOWN, OPBITBITS,0, 0, 2 },
00223 "ishft",        { INTRBGEN, TYUNKNOWN, OPBITSH,  0, 0, 2 },
00224 "ishftc",       { INTRBGEN, TYUNKNOWN, OPBITSHC, 0, 0, 2 },
00225 
00226 "" };
00227 
00228 
00229 LOCAL struct Specblock
00230         {
00231         char atype;             /* Argument type; every arg must have
00232                                    this type */
00233         char rtype;             /* Result type */
00234         char nargs;             /* Number of arguments */
00235         char spxname[8];        /* Name of the function in Fortran */
00236         char othername;         /* index into callbyvalue table */
00237         } spectab[ ] =
00238 {
00239         { TYREAL,TYREAL,1,"r_int" },
00240         { TYDREAL,TYDREAL,1,"d_int" },
00241 
00242         { TYREAL,TYREAL,1,"r_nint" },
00243         { TYDREAL,TYDREAL,1,"d_nint" },
00244 
00245         { TYREAL,TYSHORT,1,"h_nint" },
00246         { TYREAL,TYLONG,1,"i_nint" },
00247 
00248         { TYDREAL,TYSHORT,1,"h_dnnt" },
00249         { TYDREAL,TYLONG,1,"i_dnnt" },
00250 
00251         { TYREAL,TYREAL,1,"r_abs" },
00252         { TYSHORT,TYSHORT,1,"h_abs" },
00253         { TYLONG,TYLONG,1,"i_abs" },
00254         { TYDREAL,TYDREAL,1,"d_abs" },
00255         { TYCOMPLEX,TYREAL,1,"c_abs" },
00256         { TYDCOMPLEX,TYDREAL,1,"z_abs" },
00257 
00258         { TYSHORT,TYSHORT,2,"h_mod" },
00259         { TYLONG,TYLONG,2,"i_mod" },
00260         { TYREAL,TYREAL,2,"r_mod" },
00261         { TYDREAL,TYDREAL,2,"d_mod" },
00262 
00263         { TYREAL,TYREAL,2,"r_sign" },
00264         { TYSHORT,TYSHORT,2,"h_sign" },
00265         { TYLONG,TYLONG,2,"i_sign" },
00266         { TYDREAL,TYDREAL,2,"d_sign" },
00267 
00268         { TYREAL,TYREAL,2,"r_dim" },
00269         { TYSHORT,TYSHORT,2,"h_dim" },
00270         { TYLONG,TYLONG,2,"i_dim" },
00271         { TYDREAL,TYDREAL,2,"d_dim" },
00272 
00273         { TYREAL,TYDREAL,2,"d_prod" },
00274 
00275         { TYCHAR,TYSHORT,1,"h_len" },
00276         { TYCHAR,TYLONG,1,"i_len" },
00277 
00278         { TYCHAR,TYSHORT,2,"h_indx" },
00279         { TYCHAR,TYLONG,2,"i_indx" },
00280 
00281         { TYCOMPLEX,TYREAL,1,"r_imag" },
00282         { TYDCOMPLEX,TYDREAL,1,"d_imag" },
00283         { TYCOMPLEX,TYCOMPLEX,1,"r_cnjg" },
00284         { TYDCOMPLEX,TYDCOMPLEX,1,"d_cnjg" },
00285 
00286         { TYREAL,TYREAL,1,"r_sqrt", 1 },
00287         { TYDREAL,TYDREAL,1,"d_sqrt", 1 },
00288         { TYCOMPLEX,TYCOMPLEX,1,"c_sqrt" },
00289         { TYDCOMPLEX,TYDCOMPLEX,1,"z_sqrt" },
00290 
00291         { TYREAL,TYREAL,1,"r_exp", 2 },
00292         { TYDREAL,TYDREAL,1,"d_exp", 2 },
00293         { TYCOMPLEX,TYCOMPLEX,1,"c_exp" },
00294         { TYDCOMPLEX,TYDCOMPLEX,1,"z_exp" },
00295 
00296         { TYREAL,TYREAL,1,"r_log", 3 },
00297         { TYDREAL,TYDREAL,1,"d_log", 3 },
00298         { TYCOMPLEX,TYCOMPLEX,1,"c_log" },
00299         { TYDCOMPLEX,TYDCOMPLEX,1,"z_log" },
00300 
00301         { TYREAL,TYREAL,1,"r_lg10" },
00302         { TYDREAL,TYDREAL,1,"d_lg10" },
00303 
00304         { TYREAL,TYREAL,1,"r_sin", 4 },
00305         { TYDREAL,TYDREAL,1,"d_sin", 4 },
00306         { TYCOMPLEX,TYCOMPLEX,1,"c_sin" },
00307         { TYDCOMPLEX,TYDCOMPLEX,1,"z_sin" },
00308 
00309         { TYREAL,TYREAL,1,"r_cos", 5 },
00310         { TYDREAL,TYDREAL,1,"d_cos", 5 },
00311         { TYCOMPLEX,TYCOMPLEX,1,"c_cos" },
00312         { TYDCOMPLEX,TYDCOMPLEX,1,"z_cos" },
00313 
00314         { TYREAL,TYREAL,1,"r_tan", 6 },
00315         { TYDREAL,TYDREAL,1,"d_tan", 6 },
00316 
00317         { TYREAL,TYREAL,1,"r_asin", 7 },
00318         { TYDREAL,TYDREAL,1,"d_asin", 7 },
00319 
00320         { TYREAL,TYREAL,1,"r_acos", 8 },
00321         { TYDREAL,TYDREAL,1,"d_acos", 8 },
00322 
00323         { TYREAL,TYREAL,1,"r_atan", 9 },
00324         { TYDREAL,TYDREAL,1,"d_atan", 9 },
00325 
00326         { TYREAL,TYREAL,2,"r_atn2", 10 },
00327         { TYDREAL,TYDREAL,2,"d_atn2", 10 },
00328 
00329         { TYREAL,TYREAL,1,"r_sinh", 11 },
00330         { TYDREAL,TYDREAL,1,"d_sinh", 11 },
00331 
00332         { TYREAL,TYREAL,1,"r_cosh", 12 },
00333         { TYDREAL,TYDREAL,1,"d_cosh", 12 },
00334 
00335         { TYREAL,TYREAL,1,"r_tanh", 13 },
00336         { TYDREAL,TYDREAL,1,"d_tanh", 13 },
00337 
00338         { TYCHAR,TYLOGICAL,2,"hl_ge" },
00339         { TYCHAR,TYLOGICAL,2,"l_ge" },
00340 
00341         { TYCHAR,TYLOGICAL,2,"hl_gt" },
00342         { TYCHAR,TYLOGICAL,2,"l_gt" },
00343 
00344         { TYCHAR,TYLOGICAL,2,"hl_le" },
00345         { TYCHAR,TYLOGICAL,2,"l_le" },
00346 
00347         { TYCHAR,TYLOGICAL,2,"hl_lt" },
00348         { TYCHAR,TYLOGICAL,2,"l_lt" },
00349 
00350         { TYREAL,TYSHORT,1,"hr_expn" },
00351         { TYREAL,TYLONG,1,"ir_expn" },
00352         { TYDREAL,TYSHORT,1,"hd_expn" },
00353         { TYDREAL,TYLONG,1,"id_expn" },
00354 
00355         { TYREAL,TYREAL,1,"r_absp" },
00356         { TYDREAL,TYDREAL,1,"d_absp" },
00357 
00358         { TYREAL,TYDREAL,1,"r_rrsp" },
00359         { TYDREAL,TYDREAL,1,"d_rrsp" },
00360 
00361         { TYREAL,TYREAL,1,"r_frac" },
00362         { TYDREAL,TYDREAL,1,"d_frac" },
00363 
00364         { TYREAL,TYREAL,2,"r_make" },
00365         { TYDREAL,TYDREAL,2,"d_make" },
00366 
00367         { TYREAL,TYREAL,2,"r_scal" },
00368         { TYDREAL,TYDREAL,2,"d_scal" },
00369 
00370         { 0 }
00371 } ;
00372 
00373 #if 0
00374 LOCAL struct Incstblock
00375         {
00376         char atype;
00377         char rtype;
00378         char constno;
00379         } consttab[ ] =
00380 {
00381         { TYSHORT, TYLONG, 0 },
00382         { TYLONG, TYLONG, 1 },
00383         { TYREAL, TYLONG, 2 },
00384         { TYDREAL, TYLONG, 3 },
00385 
00386         { TYSHORT, TYLONG, 4 },
00387         { TYLONG, TYLONG, 5 },
00388         { TYREAL, TYLONG, 6 },
00389         { TYDREAL, TYLONG, 7 },
00390 
00391         { TYREAL, TYLONG, 8 },
00392         { TYDREAL, TYLONG, 9 },
00393 
00394         { TYREAL, TYLONG, 10 },
00395         { TYDREAL, TYLONG, 11 },
00396 
00397         { TYREAL, TYREAL, 0 },
00398         { TYDREAL, TYDREAL, 1 },
00399 
00400         { TYSHORT, TYLONG, 12 },
00401         { TYLONG, TYLONG, 13 },
00402         { TYREAL, TYREAL, 2 },
00403         { TYDREAL, TYDREAL, 3 },
00404 
00405         { TYREAL, TYREAL, 4 },
00406         { TYDREAL, TYDREAL, 5 }
00407 };
00408 #endif
00409 
00410 char *callbyvalue[ ] =
00411         {0,
00412         "sqrt",
00413         "exp",
00414         "log",
00415         "sin",
00416         "cos",
00417         "tan",
00418         "asin",
00419         "acos",
00420         "atan",
00421         "atan2",
00422         "sinh",
00423         "cosh",
00424         "tanh"
00425         };
00426 
00427  void
00428 r8fix(Void)     /* adjust tables for -r8 */
00429 {
00430         register struct Intrblock *I;
00431         register struct Specblock *S;
00432 
00433         for(I = intrtab; I->intrfname[0]; I++)
00434                 if (I->intrval.intrgroup != INTRGEN)
00435                     switch(I->intrval.intrstuff) {
00436                         case TYREAL:
00437                                 I->intrval.intrstuff = TYDREAL;
00438                                 I->intrval.intrno = I->intrval.dblintrno;
00439                                 break;
00440                         case TYCOMPLEX:
00441                                 I->intrval.intrstuff = TYDCOMPLEX;
00442                                 I->intrval.intrno = I->intrval.dblintrno;
00443                                 I->intrval.dblcmplx = 1;
00444                         }
00445 
00446         for(S = spectab; S->atype; S++)
00447             switch(S->atype) {
00448                 case TYCOMPLEX:
00449                         S->atype = TYDCOMPLEX;
00450                         if (S->rtype == TYREAL)
00451                                 S->rtype = TYDREAL;
00452                         else if (S->rtype == TYCOMPLEX)
00453                                 S->rtype = TYDCOMPLEX;
00454                         switch(S->spxname[0]) {
00455                                 case 'r':
00456                                         S->spxname[0] = 'd';
00457                                         break;
00458                                 case 'c':
00459                                         S->spxname[0] = 'z';
00460                                         break;
00461                                 default:
00462                                         Fatal("r8fix bug");
00463                                 }
00464                         break;
00465                 case TYREAL:
00466                         S->atype = TYDREAL;
00467                         switch(S->rtype) {
00468                             case TYREAL:
00469                                 S->rtype = TYDREAL;
00470                                 if (S->spxname[0] != 'r')
00471                                         Fatal("r8fix bug");
00472                                 S->spxname[0] = 'd';
00473                             case TYDREAL:       /* d_prod */
00474                                 break;
00475 
00476                             case TYSHORT:
00477                                 if (!strcmp(S->spxname, "hr_expn"))
00478                                         S->spxname[1] = 'd';
00479                                 else if (!strcmp(S->spxname, "h_nint"))
00480                                         strcpy(S->spxname, "h_dnnt");
00481                                 else Fatal("r8fix bug");
00482                                 break;
00483 
00484                             case TYLONG:
00485                                 if (!strcmp(S->spxname, "ir_expn"))
00486                                         S->spxname[1] = 'd';
00487                                 else if (!strcmp(S->spxname, "i_nint"))
00488                                         strcpy(S->spxname, "i_dnnt");
00489                                 else Fatal("r8fix bug");
00490                                 break;
00491 
00492                             default:
00493                                 Fatal("r8fix bug");
00494                             }
00495                 }
00496         }
00497 
00498  static expptr
00499 #ifdef KR_headers
00500 foldminmax(ismin, argsp) int ismin; struct Listblock *argsp;
00501 #else
00502 foldminmax(int ismin, struct Listblock *argsp)
00503 #endif
00504 {
00505 #ifndef NO_LONG_LONG
00506         Llong cq, cq1;
00507 #endif
00508         Constp h;
00509         double cd, cd1;
00510         ftnint ci;
00511         int mtype;
00512         struct Chain *cp, *cpx;
00513 
00514         mtype = argsp->vtype;
00515         cp = cpx = argsp->listp;
00516         h = &((expptr)cp->datap)->constblock;
00517 #ifndef NO_LONG_LONG
00518         if (mtype == TYQUAD) {
00519                 cq = h->vtype == TYQUAD ? h->Const.cq : h->Const.ci;
00520                 while(cp = cp->nextp) {
00521                         h = &((expptr)cp->datap)->constblock;
00522                         cq1 = h->vtype == TYQUAD ? h->Const.cq : h->Const.ci;
00523                         if (ismin) {
00524                                 if (cq > cq1) {
00525                                         cq = cq1;
00526                                         cpx = cp;
00527                                         }
00528                                 }
00529                         else {
00530                                 if (cq < cq1) {
00531                                         cq = cq1;
00532                                         cpx = cp;
00533                                         }
00534                                 }
00535                         }
00536                 }
00537         else
00538 #endif
00539         if (ISINT(mtype)) {
00540                 ci = h->Const.ci;
00541                 if (ismin)
00542                         while(cp = cp->nextp) {
00543                                 h = &((expptr)cp->datap)->constblock;
00544                                 if (ci > h->Const.ci) {
00545                                         ci = h->Const.ci;
00546                                         cpx = cp;
00547                                         }
00548                                 }
00549                 else
00550                         while(cp = cp->nextp) {
00551                                 h = &((expptr)cp->datap)->constblock;
00552                                 if (ci < h->Const.ci) {
00553                                         ci = h->Const.ci;
00554                                         cpx = cp;
00555                                         }
00556                                 }
00557                 }
00558         else {
00559                 if (ISREAL(h->vtype))
00560                         cd = h->vstg ? atof(h->Const.cds[0]) : h->Const.cd[0];
00561 #ifndef NO_LONG_LONG
00562                 else if (h->vtype == TYQUAD)
00563                         cd = (double)(h->Const.cq);
00564 #endif
00565                 else
00566                         cd = h->Const.ci;
00567                 while(cp = cp->nextp) {
00568                         h = &((expptr)cp->datap)->constblock;
00569                         if (ISREAL(h->vtype))
00570                                 cd1 = h->vstg   ? atof(h->Const.cds[0])
00571                                                 : h->Const.cd[0];
00572 #ifndef NO_LONG_LONG
00573                         else if (h->vtype == TYQUAD)
00574                                 cd1 = (double)(h->Const.cq);
00575 #endif
00576                         else
00577                                 cd1 = h->Const.ci;
00578                         if (ismin) {
00579                                 if (cd > cd1) {
00580                                         cd = cd1;
00581                                         cpx = cp;
00582                                         }
00583                                 }
00584                         else {
00585                                 if (cd < cd1) {
00586                                         cd = cd1;
00587                                         cpx = cp;
00588                                         }
00589                                 }
00590                         }
00591                 }
00592         h = &((expptr)cpx->datap)->constblock;
00593         cpx->datap = 0;
00594         frexpr((tagptr)argsp);
00595         if (h->vtype != mtype)
00596                 return mkconv(mtype, (expptr)h);
00597         return (expptr)h;
00598         }
00599 
00600 
00601  expptr
00602 #ifdef KR_headers
00603 intrcall(np, argsp, nargs)
00604         Namep np;
00605         struct Listblock *argsp;
00606         int nargs;
00607 #else
00608 intrcall(Namep np, struct Listblock *argsp, int nargs)
00609 #endif
00610 {
00611         int i, rettype;
00612         ftnint k;
00613         Addrp ap;
00614         register struct Specblock *sp;
00615         register struct Chain *cp;
00616         expptr q, ep;
00617         int constargs, mtype, op;
00618         int f1field, f2field, f3field;
00619         char *s;
00620         static char     bit_bits[] =    "?bit_bits",
00621                         bit_shift[] =   "?bit_shift",
00622                         bit_cshift[] =  "?bit_cshift";
00623         static char *bitop[3] = { bit_bits, bit_shift, bit_cshift };
00624         static int t_pref[2] = { 'l', 'q' };
00625 
00626         packed.ijunk = np->vardesc.varno;
00627         f1field = packed.bits.f1;
00628         f2field = packed.bits.f2;
00629         f3field = packed.bits.f3;
00630         if(nargs == 0)
00631                 goto badnargs;
00632 
00633         mtype = 0;
00634         constargs = 1;
00635         for(cp = argsp->listp ; cp ; cp = cp->nextp)
00636         {
00637                 ep = (expptr)cp->datap;
00638                 if (!ISCONST(ep))
00639                         constargs = 0;
00640                 else if( ep->headblock.vtype==TYSHORT )
00641                         cp->datap = (char *) mkconv(tyint, ep);
00642                 mtype = maxtype(mtype, ep->headblock.vtype);
00643         }
00644 
00645         switch(f1field)
00646         {
00647         case INTRBGEN:
00648                 op = f3field;
00649                 if( ! ONEOF(mtype, MSKINT) )
00650                         goto badtype;
00651                 if (op < OPBITBITS) {
00652                         if(nargs != 2)
00653                                 goto badnargs;
00654                         if (op != OPBITTEST) {
00655 #ifdef TYQUAD
00656                                 if (mtype == TYQUAD)
00657                                         op += 2;
00658 #endif
00659                                 goto intrbool2;
00660                                 }
00661                         q = mkexpr(op, (expptr)argsp->listp->datap,
00662                                         (expptr)argsp->listp->nextp->datap);
00663                         q->exprblock.vtype = TYLOGICAL;
00664                         goto intrbool2a;
00665                         }
00666                 if (nargs != 2 && (nargs != 3 || op == OPBITSH))
00667                         goto badnargs;
00668                 cp = argsp->listp;
00669                 ep = (expptr)cp->datap;
00670                 if (ep->headblock.vtype < TYLONG)
00671                         cp->datap = (char *)mkconv(TYLONG, ep);
00672                 while(cp->nextp) {
00673                         cp = cp->nextp;
00674                         ep = (expptr)cp->datap;
00675                         if (ep->headblock.vtype != TYLONG)
00676                                 cp->datap = (char *)mkconv(TYLONG, ep);
00677                         }
00678                 if (op == OPBITSH) {
00679                         ep = (expptr)argsp->listp->nextp->datap;
00680                         if (ISCONST(ep)) {
00681                                 if ((k = ep->constblock.Const.ci) < 0) {
00682                                         q = (expptr)argsp->listp->datap;
00683                                         if (ISCONST(q)) {
00684                                                 ep->constblock.Const.ci = -k;
00685                                                 op = OPRSHIFT;
00686                                                 goto intrbool2;
00687                                                 }
00688                                         }
00689                                 else {
00690                                         op = OPLSHIFT;
00691                                         goto intrbool2;
00692                                         }
00693                                 }
00694                         }
00695                 else if (nargs == 2) {
00696                         if (op == OPBITBITS)
00697                                 goto badnargs;
00698                         cp->nextp = mkchain((char*)ICON(-1), 0);
00699                         }
00700                 ep = (expptr)argsp->listp->datap;
00701                 i = ep->headblock.vtype;
00702                 s = bitop[op - OPBITBITS];
00703                 *s = t_pref[i - TYLONG];
00704                 ap = builtin(i, s, 1);
00705                 return fixexpr((Exprp)
00706                                 mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
00707 
00708         case INTRBOOL:
00709                 op = f3field;
00710                 if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )
00711                         goto badtype;
00712                 if(op == OPBITNOT)
00713                 {
00714                         if(nargs != 1)
00715                                 goto badnargs;
00716                         q = mkexpr(OPBITNOT, (expptr)argsp->listp->datap, ENULL);
00717                 }
00718                 else
00719                 {
00720                         if(nargs != 2)
00721                                 goto badnargs;
00722  intrbool2:
00723                         q = mkexpr(op, (expptr)argsp->listp->datap,
00724                                         (expptr)argsp->listp->nextp->datap);
00725                 }
00726  intrbool2a:
00727                 frchain( &(argsp->listp) );
00728                 free( (charptr) argsp);
00729                 return(q);
00730 
00731         case INTRCONV:
00732                 rettype = f2field;
00733                 switch(rettype) {
00734                   case TYLONG:
00735                         rettype = tyint;
00736                         break;
00737                   case TYLOGICAL:
00738                         rettype = tylog;
00739                   }
00740                 if( ISCOMPLEX(rettype) && nargs==2)
00741                 {
00742                         expptr qr, qi;
00743                         qr = (expptr) argsp->listp->datap;
00744                         qi = (expptr) argsp->listp->nextp->datap;
00745                         if (qr->headblock.vtype == TYDREAL
00746                          || qi->headblock.vtype == TYDREAL)
00747                                 rettype = TYDCOMPLEX;
00748                         if(ISCONST(qr) && ISCONST(qi))
00749                                 q = mkcxcon(qr,qi);
00750                         else    q = mkexpr(OPCONV,mkconv(rettype-2,qr),
00751                             mkconv(rettype-2,qi));
00752                 }
00753                 else if(nargs == 1) {
00754                         if (f3field && ((Exprp)argsp->listp->datap)->vtype
00755                                         == TYDCOMPLEX)
00756                                 rettype = TYDREAL;
00757                         q = mkconv(rettype+100, (expptr)argsp->listp->datap);
00758                         if (q->tag == TADDR)
00759                                 q->addrblock.parenused = 1;
00760                         }
00761                 else goto badnargs;
00762 
00763                 q->headblock.vtype = rettype;
00764                 frchain(&(argsp->listp));
00765                 free( (charptr) argsp);
00766                 return(q);
00767 
00768 
00769 #if 0
00770         case INTRCNST:
00771 
00772 /* Machine-dependent f77 stuff that f2c omits:
00773 
00774 intcon contains
00775         radix for short int
00776         radix for long int
00777         radix for single precision
00778         radix for double precision
00779         precision for short int
00780         precision for long int
00781         precision for single precision
00782         precision for double precision
00783         emin for single precision
00784         emin for double precision
00785         emax for single precision
00786         emax for double prcision
00787         largest short int
00788         largest long int
00789 
00790 realcon contains
00791         tiny for single precision
00792         tiny for double precision
00793         huge for single precision
00794         huge for double precision
00795         mrsp (epsilon) for single precision
00796         mrsp (epsilon) for double precision
00797 */
00798         {       register struct Incstblock *cstp;
00799                 extern ftnint intcon[14];
00800                 extern double realcon[6];
00801 
00802                 cstp = consttab + f3field;
00803                 for(i=0 ; i<f2field ; ++i)
00804                         if(cstp->atype == mtype)
00805                                 goto foundconst;
00806                         else
00807                                 ++cstp;
00808                 goto badtype;
00809 
00810 foundconst:
00811                 switch(cstp->rtype)
00812                 {
00813                 case TYLONG:
00814                         return(mkintcon(intcon[cstp->constno]));
00815 
00816                 case TYREAL:
00817                 case TYDREAL:
00818                         return(mkrealcon(cstp->rtype,
00819                             realcon[cstp->constno]) );
00820 
00821                 default:
00822                         Fatal("impossible intrinsic constant");
00823                 }
00824         }
00825 #endif
00826 
00827         case INTRGEN:
00828                 sp = spectab + f3field;
00829                 if(no66flag)
00830                         if(sp->atype == mtype)
00831                                 goto specfunct;
00832                         else err66("generic function");
00833 
00834                 for(i=0; i<f2field ; ++i)
00835                         if(sp->atype == mtype)
00836                                 goto specfunct;
00837                         else
00838                                 ++sp;
00839                 warn1 ("bad argument type to intrinsic %s", np->fvarname);
00840 
00841 /* Made this a warning rather than an error so things like "log (5) ==>
00842    log (5.0)" can be accommodated.  When none of these cases matches, the
00843    argument is cast up to the first type in the spectab list; this first
00844    type is assumed to be the "smallest" type, e.g. REAL before DREAL
00845    before COMPLEX, before DCOMPLEX */
00846 
00847                 sp = spectab + f3field;
00848                 mtype = sp -> atype;
00849                 goto specfunct;
00850 
00851         case INTRSPEC:
00852                 sp = spectab + f3field;
00853 specfunct:
00854                 if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))
00855                     && (sp+1)->atype==sp->atype)
00856                         ++sp;
00857 
00858                 if(nargs != sp->nargs)
00859                         goto badnargs;
00860                 if(mtype != sp->atype)
00861                         goto badtype;
00862 
00863 /* NOTE!!  I moved fixargs (YES) into the ELSE branch so that constants in
00864    the inline expression wouldn't get put into the constant table */
00865 
00866                 fixargs (NO, argsp);
00867                 cast_args (mtype, argsp -> listp);
00868 
00869                 if(q = Inline((int)(sp-spectab), mtype, argsp->listp))
00870                 {
00871                         frchain( &(argsp->listp) );
00872                         free( (charptr) argsp);
00873                 } else {
00874 
00875                     if(sp->othername) {
00876                         /* C library routines that return double... */
00877                         /* sp->rtype might be TYREAL */
00878                         ap = builtin(sp->rtype,
00879                                 callbyvalue[sp->othername], 1);
00880                         q = fixexpr((Exprp)
00881                                 mkexpr(OPCCALL, (expptr)ap, (expptr)argsp) );
00882                     } else {
00883                         fixargs(YES, argsp);
00884                         ap = builtin(sp->rtype, sp->spxname, 0);
00885                         q = fixexpr((Exprp)
00886                                 mkexpr(OPCALL, (expptr)ap, (expptr)argsp) );
00887                     } /* else */
00888                 } /* else */
00889                 return(q);
00890 
00891         case INTRMIN:
00892         case INTRMAX:
00893                 if(nargs < 2)
00894                         goto badnargs;
00895                 if( ! ONEOF(mtype, MSKINT|MSKREAL) )
00896                         goto badtype;
00897                 argsp->vtype = mtype;
00898                 if (constargs)
00899                         q = foldminmax(f1field==INTRMIN, argsp);
00900                 else
00901                         q = mkexpr(f1field==INTRMIN ? OPMIN : OPMAX,
00902                                         (expptr)argsp, ENULL);
00903 
00904                 q->headblock.vtype = mtype;
00905                 rettype = f2field;
00906                 if(rettype == TYLONG)
00907                         rettype = tyint;
00908                 else if(rettype == TYUNKNOWN)
00909                         rettype = mtype;
00910                 return( mkconv(rettype, q) );
00911 
00912         default:
00913                 fatali("intrcall: bad intrgroup %d", f1field);
00914         }
00915 badnargs:
00916         errstr("bad number of arguments to intrinsic %s", np->fvarname);
00917         goto bad;
00918 
00919 badtype:
00920         errstr("bad argument type to intrinsic %s", np->fvarname);
00921 
00922 bad:
00923         return( errnode() );
00924 }
00925 
00926 
00927 
00928  int
00929 #ifdef KR_headers
00930 intrfunct(s)
00931         char *s;
00932 #else
00933 intrfunct(char *s)
00934 #endif
00935 {
00936         register struct Intrblock *p;
00937         int i;
00938         extern int intr_omit;
00939 
00940         for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)
00941         {
00942                 if( !strcmp(s, p->intrfname) )
00943                 {
00944                         if (i = p->intrval.extflag) {
00945                                 if (i & intr_omit)
00946                                         return 0;
00947                                 if (noextflag)
00948                                         errext(s);
00949                                 }
00950                         packed.bits.f1 = p->intrval.intrgroup;
00951                         packed.bits.f2 = p->intrval.intrstuff;
00952                         packed.bits.f3 = p->intrval.intrno;
00953                         packed.bits.f4 = p->intrval.dblcmplx;
00954                         return(packed.ijunk);
00955                 }
00956         }
00957 
00958         return(0);
00959 }
00960 
00961 
00962 
00963 
00964 
00965  Addrp
00966 #ifdef KR_headers
00967 intraddr(np)
00968         Namep np;
00969 #else
00970 intraddr(Namep np)
00971 #endif
00972 {
00973         Addrp q;
00974         register struct Specblock *sp;
00975         int f3field;
00976 
00977         if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)
00978                 fatalstr("intraddr: %s is not intrinsic", np->fvarname);
00979         packed.ijunk = np->vardesc.varno;
00980         f3field = packed.bits.f3;
00981 
00982         switch(packed.bits.f1)
00983         {
00984         case INTRGEN:
00985                 /* imag, log, and log10 arent specific functions */
00986                 if(f3field==31 || f3field==43 || f3field==47)
00987                         goto bad;
00988 
00989         case INTRSPEC:
00990                 sp = spectab + f3field;
00991                 if (tyint == TYLONG
00992                 && (sp->rtype == TYSHORT || sp->rtype == TYLOGICAL))
00993                         ++sp;
00994                 q = builtin(sp->rtype, sp->spxname,
00995                         sp->othername ? 1 : 0);
00996                 return(q);
00997 
00998         case INTRCONV:
00999         case INTRMIN:
01000         case INTRMAX:
01001         case INTRBOOL:
01002         case INTRCNST:
01003         case INTRBGEN:
01004 bad:
01005                 errstr("cannot pass %s as actual", np->fvarname);
01006                 return((Addrp)errnode());
01007         }
01008         fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);
01009         /* NOT REACHED */ return 0;
01010 }
01011 
01012 
01013 
01014  void
01015 #ifdef KR_headers
01016 cast_args(maxtype, args)
01017         int maxtype;
01018         chainp args;
01019 #else
01020 cast_args(int maxtype, chainp args)
01021 #endif
01022 {
01023     for (; args; args = args -> nextp) {
01024         expptr e = (expptr) args->datap;
01025         if (e -> headblock.vtype != maxtype)
01026             if (e -> tag == TCONST)
01027                 args->datap = (char *) mkconv(maxtype, e);
01028             else {
01029                 Addrp temp = mktmp(maxtype, ENULL);
01030 
01031                 puteq(cpexpr((expptr)temp), e);
01032                 args->datap = (char *)temp;
01033             } /* else */
01034     } /* for */
01035 } /* cast_args */
01036 
01037 
01038 
01039  expptr
01040 #ifdef KR_headers
01041 Inline(fno, type, args)
01042         int fno;
01043         int type;
01044         struct Chain *args;
01045 #else
01046 Inline(int fno, int type, struct Chain *args)
01047 #endif
01048 {
01049         register expptr q, t, t1;
01050 
01051         switch(fno)
01052         {
01053         case 8: /* real abs */
01054         case 9: /* short int abs */
01055         case 10:        /* long int abs */
01056         case 11:        /* double precision abs */
01057                 if( addressable(q = (expptr) args->datap) )
01058                 {
01059                         t = q;
01060                         q = NULL;
01061                 }
01062                 else
01063                         t = (expptr) mktmp(type,ENULL);
01064                 t1 = mkexpr(type == TYREAL && forcedouble ? OPDABS : OPABS,
01065                         cpexpr(t), ENULL);
01066                 if(q)
01067                         t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);
01068                 frexpr(t);
01069                 return(t1);
01070 
01071         case 26:        /* dprod */
01072                 q = mkexpr(OPSTAR, mkconv(TYDREAL,(expptr)args->datap),
01073                         (expptr)args->nextp->datap);
01074                 return(q);
01075 
01076         case 27:        /* len of character string */
01077                 q = (expptr) cpexpr(((tagptr)args->datap)->headblock.vleng);
01078                 frexpr((expptr)args->datap);
01079                 return mkconv(tyioint, q);
01080 
01081         case 14:        /* half-integer mod */
01082         case 15:        /* mod */
01083                 return mkexpr(OPMOD, (expptr) args->datap,
01084                                 (expptr) args->nextp->datap);
01085         }
01086         return(NULL);
01087 }

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