1748Speter /* Copyright (c) 1979 Regents of the University of California */ 2748Speter 3*18344Smckusick static char sccsid[] = "@(#)const.c 1.5.1.1 03/15/85"; 4748Speter 5748Speter #include "whoami.h" 6748Speter #include "0.h" 7748Speter #include "tree.h" 8748Speter 9748Speter /* 10748Speter * Const enters the definitions 11748Speter * of the constant declaration 12748Speter * part into the namelist. 13748Speter */ 14748Speter #ifndef PI1 15*18344Smckusick constbeg( lineofyconst , r ) 167951Speter int lineofyconst; 17748Speter { 187951Speter static bool const_order = FALSE; 197951Speter static bool const_seen = FALSE; 20748Speter 21748Speter /* 22834Speter * this allows for multiple declaration 23748Speter * parts, unless the "standard" option 24748Speter * has been specified. 25748Speter * If a routine segment is being compiled, 26748Speter * do level one processing. 27748Speter */ 28748Speter 29748Speter if (!progseen) 30748Speter level1(); 317951Speter line = lineofyconst; 32834Speter if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { 33834Speter if ( opt( 's' ) ) { 34834Speter standard(); 357951Speter error("Constant declarations should precede type, var and routine declarations"); 36834Speter } else { 377951Speter if ( !const_order ) { 387951Speter const_order = TRUE; 397951Speter warning(); 407951Speter error("Constant declarations should precede type, var and routine declarations"); 417951Speter } 42834Speter } 43834Speter } 44834Speter if (parts[ cbn ] & CPRT) { 45834Speter if ( opt( 's' ) ) { 46834Speter standard(); 477951Speter error("All constants should be declared in one const part"); 48834Speter } else { 497951Speter if ( !const_seen ) { 507951Speter const_seen = TRUE; 517951Speter warning(); 527951Speter error("All constants should be declared in one const part"); 537951Speter } 54834Speter } 55834Speter } 56834Speter parts[ cbn ] |= CPRT; 57748Speter } 58748Speter #endif PI1 59748Speter 60748Speter const(cline, cid, cdecl) 61748Speter int cline; 62748Speter register char *cid; 63*18344Smckusick register int *cdecl; 64748Speter { 65748Speter register struct nl *np; 66748Speter 67748Speter #ifdef PI0 68748Speter send(REVCNST, cline, cid, cdecl); 69748Speter #endif 70748Speter line = cline; 71748Speter gconst(cdecl); 72748Speter np = enter(defnl(cid, CONST, con.ctype, con.cival)); 73748Speter #ifndef PI0 74748Speter np->nl_flags |= NMOD; 75748Speter #endif 76748Speter 77748Speter #ifdef PC 78825Speter if (cbn == 1) { 79840Speter stabgconst( cid , line ); 80825Speter } 81748Speter #endif PC 82748Speter 83748Speter # ifdef PTREE 84748Speter { 85748Speter pPointer Const = ConstDecl( cid , cdecl ); 86748Speter pPointer *Consts; 87748Speter 88748Speter pSeize( PorFHeader[ nesting ] ); 89748Speter Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); 90748Speter *Consts = ListAppend( *Consts , Const ); 91748Speter pRelease( PorFHeader[ nesting ] ); 92748Speter } 93748Speter # endif 94748Speter if (con.ctype == NIL) 95748Speter return; 96748Speter if ( con.ctype == nl + TSTR ) 97*18344Smckusick np->ptr[0] = con.cpval; 98748Speter if (isa(con.ctype, "i")) 99748Speter np->range[0] = con.crval; 100748Speter else if (isa(con.ctype, "d")) 101748Speter np->real = con.crval; 102*18344Smckusick # ifdef PC 103*18344Smckusick if (cbn == 1 && con.ctype != NIL) { 104*18344Smckusick stabconst(np); 105*18344Smckusick } 106*18344Smckusick # endif 107748Speter } 108748Speter 109748Speter #ifndef PI0 110748Speter #ifndef PI1 111748Speter constend() 112748Speter { 113748Speter 114748Speter } 115748Speter #endif 116748Speter #endif 117748Speter 118748Speter /* 119748Speter * Gconst extracts 120748Speter * a constant declaration 121748Speter * from the tree for it. 122748Speter * only types of constants 123748Speter * are integer, reals, strings 124748Speter * and scalars, the first two 125748Speter * being possibly signed. 126748Speter */ 127*18344Smckusick gconst(r) 128*18344Smckusick int *r; 129748Speter { 130748Speter register struct nl *np; 131*18344Smckusick register *cn; 132748Speter char *cp; 133748Speter int negd, sgnd; 134748Speter long ci; 135748Speter 136748Speter con.ctype = NIL; 137*18344Smckusick cn = r; 138748Speter negd = sgnd = 0; 139748Speter loop: 140*18344Smckusick if (cn == NIL || cn[1] == NIL) 141*18344Smckusick return (NIL); 142*18344Smckusick switch (cn[0]) { 143748Speter default: 144748Speter panic("gconst"); 145748Speter case T_MINUSC: 146748Speter negd = 1 - negd; 147748Speter case T_PLUSC: 148748Speter sgnd++; 149*18344Smckusick cn = cn[1]; 150748Speter goto loop; 151748Speter case T_ID: 152*18344Smckusick np = lookup(cn[1]); 153*18344Smckusick if (np == NIL) 154748Speter return; 155748Speter if (np->class != CONST) { 156*18344Smckusick derror("%s is a %s, not a constant as required", cn[1], classes[np->class]); 157748Speter return; 158748Speter } 159748Speter con.ctype = np->type; 160748Speter switch (classify(np->type)) { 161748Speter case TINT: 162748Speter con.crval = np->range[0]; 163748Speter break; 164748Speter case TDOUBLE: 165748Speter con.crval = np->real; 166748Speter break; 167748Speter case TBOOL: 168748Speter case TCHAR: 169748Speter case TSCAL: 170748Speter con.cival = np->value[0]; 171748Speter con.crval = con.cival; 172748Speter break; 173748Speter case TSTR: 174*18344Smckusick con.cpval = np->ptr[0]; 175748Speter break; 176748Speter case NIL: 177748Speter con.ctype = NIL; 178748Speter return; 179748Speter default: 180748Speter panic("gconst2"); 181748Speter } 182748Speter break; 183748Speter case T_CBINT: 184*18344Smckusick con.crval = a8tol(cn[1]); 185748Speter goto restcon; 186748Speter case T_CINT: 187*18344Smckusick con.crval = atof(cn[1]); 188748Speter if (con.crval > MAXINT || con.crval < MININT) { 189748Speter derror("Constant too large for this implementation"); 190748Speter con.crval = 0; 191748Speter } 192748Speter restcon: 193748Speter ci = con.crval; 194748Speter #ifndef PI0 195748Speter if (bytes(ci, ci) <= 2) 196748Speter con.ctype = nl+T2INT; 197748Speter else 198748Speter #endif 199748Speter con.ctype = nl+T4INT; 200748Speter break; 201748Speter case T_CFINT: 202748Speter con.ctype = nl+TDOUBLE; 203*18344Smckusick con.crval = atof(cn[1]); 204748Speter break; 205748Speter case T_CSTRNG: 206*18344Smckusick cp = cn[1]; 207748Speter if (cp[1] == 0) { 208748Speter con.ctype = nl+T1CHAR; 209748Speter con.cival = cp[0]; 210748Speter con.crval = con.cival; 211748Speter break; 212748Speter } 213748Speter con.ctype = nl+TSTR; 214748Speter con.cpval = savestr(cp); 215748Speter break; 216748Speter } 217748Speter if (sgnd) { 218*18344Smckusick if (isnta(con.ctype, "id")) 219*18344Smckusick derror("%s constants cannot be signed", nameof(con.ctype)); 220748Speter else { 221748Speter if (negd) 222748Speter con.crval = -con.crval; 223748Speter ci = con.crval; 224748Speter } 225748Speter } 226748Speter } 227748Speter 228748Speter #ifndef PI0 229*18344Smckusick isconst(r) 230*18344Smckusick register int *r; 231748Speter { 232748Speter 233*18344Smckusick if (r == NIL) 234748Speter return (1); 235*18344Smckusick switch (r[0]) { 236748Speter case T_MINUS: 237*18344Smckusick r[0] = T_MINUSC; 238*18344Smckusick r[1] = r[2]; 239*18344Smckusick return (isconst(r[1])); 240748Speter case T_PLUS: 241*18344Smckusick r[0] = T_PLUSC; 242*18344Smckusick r[1] = r[2]; 243*18344Smckusick return (isconst(r[1])); 244748Speter case T_VAR: 245*18344Smckusick if (r[3] != NIL) 246748Speter return (0); 247*18344Smckusick r[0] = T_ID; 248*18344Smckusick r[1] = r[2]; 249748Speter return (1); 250748Speter case T_BINT: 251*18344Smckusick r[0] = T_CBINT; 252*18344Smckusick r[1] = r[2]; 253748Speter return (1); 254748Speter case T_INT: 255*18344Smckusick r[0] = T_CINT; 256*18344Smckusick r[1] = r[2]; 257748Speter return (1); 258748Speter case T_FINT: 259*18344Smckusick r[0] = T_CFINT; 260*18344Smckusick r[1] = r[2]; 261748Speter return (1); 262748Speter case T_STRNG: 263*18344Smckusick r[0] = T_CSTRNG; 264*18344Smckusick r[1] = r[2]; 265748Speter return (1); 266748Speter } 267748Speter return (0); 268748Speter } 269748Speter #endif 270