1*748Speter /* Copyright (c) 1979 Regents of the University of California */ 2*748Speter 3*748Speter static char sccsid[] = "@(#)const.c 1.1 08/27/80"; 4*748Speter 5*748Speter #include "whoami.h" 6*748Speter #include "0.h" 7*748Speter #include "tree.h" 8*748Speter 9*748Speter /* 10*748Speter * Const enters the definitions 11*748Speter * of the constant declaration 12*748Speter * part into the namelist. 13*748Speter */ 14*748Speter #ifndef PI1 15*748Speter constbeg() 16*748Speter { 17*748Speter 18*748Speter /* 19*748Speter * PC allows for multiple declaration 20*748Speter * parts, unless the "standard" option 21*748Speter * has been specified. 22*748Speter * If a routine segment is being compiled, 23*748Speter * do level one processing. 24*748Speter */ 25*748Speter 26*748Speter if (!progseen) 27*748Speter level1(); 28*748Speter # ifdef PC 29*748Speter if (opt('s')) { 30*748Speter if (parts & (TPRT|VPRT)) { 31*748Speter standard(); 32*748Speter error("Constant declarations must precede type and variable declarations"); 33*748Speter } 34*748Speter if (parts & CPRT) { 35*748Speter standard(); 36*748Speter error("All constants must be declared in one const part"); 37*748Speter } 38*748Speter } 39*748Speter # endif PC 40*748Speter # ifdef OBJ 41*748Speter if (parts & (TPRT|VPRT)) 42*748Speter error("Constant declarations must precede type and variable declarations"); 43*748Speter if (parts & CPRT) 44*748Speter error("All constants must be declared in one const part"); 45*748Speter # endif OBJ 46*748Speter parts |= CPRT; 47*748Speter } 48*748Speter #endif PI1 49*748Speter 50*748Speter const(cline, cid, cdecl) 51*748Speter int cline; 52*748Speter register char *cid; 53*748Speter register int *cdecl; 54*748Speter { 55*748Speter register struct nl *np; 56*748Speter 57*748Speter #ifdef PI0 58*748Speter send(REVCNST, cline, cid, cdecl); 59*748Speter #endif 60*748Speter line = cline; 61*748Speter gconst(cdecl); 62*748Speter np = enter(defnl(cid, CONST, con.ctype, con.cival)); 63*748Speter #ifndef PI0 64*748Speter np->nl_flags |= NMOD; 65*748Speter #endif 66*748Speter 67*748Speter #ifdef PC 68*748Speter if (cbn == 1) 69*748Speter stabcname( cid ); 70*748Speter #endif PC 71*748Speter 72*748Speter # ifdef PTREE 73*748Speter { 74*748Speter pPointer Const = ConstDecl( cid , cdecl ); 75*748Speter pPointer *Consts; 76*748Speter 77*748Speter pSeize( PorFHeader[ nesting ] ); 78*748Speter Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); 79*748Speter *Consts = ListAppend( *Consts , Const ); 80*748Speter pRelease( PorFHeader[ nesting ] ); 81*748Speter } 82*748Speter # endif 83*748Speter if (con.ctype == NIL) 84*748Speter return; 85*748Speter if ( con.ctype == nl + TSTR ) 86*748Speter np->ptr[0] = con.cpval; 87*748Speter if (isa(con.ctype, "i")) 88*748Speter np->range[0] = con.crval; 89*748Speter else if (isa(con.ctype, "d")) 90*748Speter np->real = con.crval; 91*748Speter } 92*748Speter 93*748Speter #ifndef PI0 94*748Speter #ifndef PI1 95*748Speter constend() 96*748Speter { 97*748Speter 98*748Speter } 99*748Speter #endif 100*748Speter #endif 101*748Speter 102*748Speter /* 103*748Speter * Gconst extracts 104*748Speter * a constant declaration 105*748Speter * from the tree for it. 106*748Speter * only types of constants 107*748Speter * are integer, reals, strings 108*748Speter * and scalars, the first two 109*748Speter * being possibly signed. 110*748Speter */ 111*748Speter gconst(r) 112*748Speter int *r; 113*748Speter { 114*748Speter register struct nl *np; 115*748Speter register *cn; 116*748Speter char *cp; 117*748Speter int negd, sgnd; 118*748Speter long ci; 119*748Speter 120*748Speter con.ctype = NIL; 121*748Speter cn = r; 122*748Speter negd = sgnd = 0; 123*748Speter loop: 124*748Speter if (cn == NIL || cn[1] == NIL) 125*748Speter return (NIL); 126*748Speter switch (cn[0]) { 127*748Speter default: 128*748Speter panic("gconst"); 129*748Speter case T_MINUSC: 130*748Speter negd = 1 - negd; 131*748Speter case T_PLUSC: 132*748Speter sgnd++; 133*748Speter cn = cn[1]; 134*748Speter goto loop; 135*748Speter case T_ID: 136*748Speter np = lookup(cn[1]); 137*748Speter if (np == NIL) 138*748Speter return; 139*748Speter if (np->class != CONST) { 140*748Speter derror("%s is a %s, not a constant as required", cn[1], classes[np->class]); 141*748Speter return; 142*748Speter } 143*748Speter con.ctype = np->type; 144*748Speter switch (classify(np->type)) { 145*748Speter case TINT: 146*748Speter con.crval = np->range[0]; 147*748Speter break; 148*748Speter case TDOUBLE: 149*748Speter con.crval = np->real; 150*748Speter break; 151*748Speter case TBOOL: 152*748Speter case TCHAR: 153*748Speter case TSCAL: 154*748Speter con.cival = np->value[0]; 155*748Speter con.crval = con.cival; 156*748Speter break; 157*748Speter case TSTR: 158*748Speter con.cpval = np->ptr[0]; 159*748Speter break; 160*748Speter case NIL: 161*748Speter con.ctype = NIL; 162*748Speter return; 163*748Speter default: 164*748Speter panic("gconst2"); 165*748Speter } 166*748Speter break; 167*748Speter case T_CBINT: 168*748Speter con.crval = a8tol(cn[1]); 169*748Speter goto restcon; 170*748Speter case T_CINT: 171*748Speter con.crval = atof(cn[1]); 172*748Speter if (con.crval > MAXINT || con.crval < MININT) { 173*748Speter derror("Constant too large for this implementation"); 174*748Speter con.crval = 0; 175*748Speter } 176*748Speter restcon: 177*748Speter ci = con.crval; 178*748Speter #ifndef PI0 179*748Speter if (bytes(ci, ci) <= 2) 180*748Speter con.ctype = nl+T2INT; 181*748Speter else 182*748Speter #endif 183*748Speter con.ctype = nl+T4INT; 184*748Speter break; 185*748Speter case T_CFINT: 186*748Speter con.ctype = nl+TDOUBLE; 187*748Speter con.crval = atof(cn[1]); 188*748Speter break; 189*748Speter case T_CSTRNG: 190*748Speter cp = cn[1]; 191*748Speter if (cp[1] == 0) { 192*748Speter con.ctype = nl+T1CHAR; 193*748Speter con.cival = cp[0]; 194*748Speter con.crval = con.cival; 195*748Speter break; 196*748Speter } 197*748Speter con.ctype = nl+TSTR; 198*748Speter con.cpval = savestr(cp); 199*748Speter break; 200*748Speter } 201*748Speter if (sgnd) { 202*748Speter if (isnta(con.ctype, "id")) 203*748Speter derror("%s constants cannot be signed", nameof(con.ctype)); 204*748Speter else { 205*748Speter if (negd) 206*748Speter con.crval = -con.crval; 207*748Speter ci = con.crval; 208*748Speter } 209*748Speter } 210*748Speter } 211*748Speter 212*748Speter #ifndef PI0 213*748Speter isconst(r) 214*748Speter register int *r; 215*748Speter { 216*748Speter 217*748Speter if (r == NIL) 218*748Speter return (1); 219*748Speter switch (r[0]) { 220*748Speter case T_MINUS: 221*748Speter r[0] = T_MINUSC; 222*748Speter r[1] = r[2]; 223*748Speter return (isconst(r[1])); 224*748Speter case T_PLUS: 225*748Speter r[0] = T_PLUSC; 226*748Speter r[1] = r[2]; 227*748Speter return (isconst(r[1])); 228*748Speter case T_VAR: 229*748Speter if (r[3] != NIL) 230*748Speter return (0); 231*748Speter r[0] = T_ID; 232*748Speter r[1] = r[2]; 233*748Speter return (1); 234*748Speter case T_BINT: 235*748Speter r[0] = T_CBINT; 236*748Speter r[1] = r[2]; 237*748Speter return (1); 238*748Speter case T_INT: 239*748Speter r[0] = T_CINT; 240*748Speter r[1] = r[2]; 241*748Speter return (1); 242*748Speter case T_FINT: 243*748Speter r[0] = T_CFINT; 244*748Speter r[1] = r[2]; 245*748Speter return (1); 246*748Speter case T_STRNG: 247*748Speter r[0] = T_CSTRNG; 248*748Speter r[1] = r[2]; 249*748Speter return (1); 250*748Speter } 251*748Speter return (0); 252*748Speter } 253*748Speter #endif 254