1748Speter /* Copyright (c) 1979 Regents of the University of California */ 2748Speter 3*7951Speter static char sccsid[] = "@(#)const.c 1.5 08/29/82"; 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*7951Speter constbeg( lineofyconst , r ) 16*7951Speter int lineofyconst; 17748Speter { 18*7951Speter static bool const_order = FALSE; 19*7951Speter 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(); 31*7951Speter line = lineofyconst; 32834Speter if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { 33834Speter if ( opt( 's' ) ) { 34834Speter standard(); 35*7951Speter error("Constant declarations should precede type, var and routine declarations"); 36834Speter } else { 37*7951Speter if ( !const_order ) { 38*7951Speter const_order = TRUE; 39*7951Speter warning(); 40*7951Speter error("Constant declarations should precede type, var and routine declarations"); 41*7951Speter } 42834Speter } 43834Speter } 44834Speter if (parts[ cbn ] & CPRT) { 45834Speter if ( opt( 's' ) ) { 46834Speter standard(); 47*7951Speter error("All constants should be declared in one const part"); 48834Speter } else { 49*7951Speter if ( !const_seen ) { 50*7951Speter const_seen = TRUE; 51*7951Speter warning(); 52*7951Speter error("All constants should be declared in one const part"); 53*7951Speter } 54834Speter } 55834Speter } 56834Speter parts[ cbn ] |= CPRT; 57748Speter } 58748Speter #endif PI1 59748Speter 60748Speter const(cline, cid, cdecl) 61748Speter int cline; 62748Speter register char *cid; 63748Speter 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 ) 97748Speter 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; 102748Speter } 103748Speter 104748Speter #ifndef PI0 105748Speter #ifndef PI1 106748Speter constend() 107748Speter { 108748Speter 109748Speter } 110748Speter #endif 111748Speter #endif 112748Speter 113748Speter /* 114748Speter * Gconst extracts 115748Speter * a constant declaration 116748Speter * from the tree for it. 117748Speter * only types of constants 118748Speter * are integer, reals, strings 119748Speter * and scalars, the first two 120748Speter * being possibly signed. 121748Speter */ 122748Speter gconst(r) 123748Speter int *r; 124748Speter { 125748Speter register struct nl *np; 126748Speter register *cn; 127748Speter char *cp; 128748Speter int negd, sgnd; 129748Speter long ci; 130748Speter 131748Speter con.ctype = NIL; 132748Speter cn = r; 133748Speter negd = sgnd = 0; 134748Speter loop: 135748Speter if (cn == NIL || cn[1] == NIL) 136748Speter return (NIL); 137748Speter switch (cn[0]) { 138748Speter default: 139748Speter panic("gconst"); 140748Speter case T_MINUSC: 141748Speter negd = 1 - negd; 142748Speter case T_PLUSC: 143748Speter sgnd++; 144748Speter cn = cn[1]; 145748Speter goto loop; 146748Speter case T_ID: 147748Speter np = lookup(cn[1]); 148748Speter if (np == NIL) 149748Speter return; 150748Speter if (np->class != CONST) { 151748Speter derror("%s is a %s, not a constant as required", cn[1], classes[np->class]); 152748Speter return; 153748Speter } 154748Speter con.ctype = np->type; 155748Speter switch (classify(np->type)) { 156748Speter case TINT: 157748Speter con.crval = np->range[0]; 158748Speter break; 159748Speter case TDOUBLE: 160748Speter con.crval = np->real; 161748Speter break; 162748Speter case TBOOL: 163748Speter case TCHAR: 164748Speter case TSCAL: 165748Speter con.cival = np->value[0]; 166748Speter con.crval = con.cival; 167748Speter break; 168748Speter case TSTR: 169748Speter con.cpval = np->ptr[0]; 170748Speter break; 171748Speter case NIL: 172748Speter con.ctype = NIL; 173748Speter return; 174748Speter default: 175748Speter panic("gconst2"); 176748Speter } 177748Speter break; 178748Speter case T_CBINT: 179748Speter con.crval = a8tol(cn[1]); 180748Speter goto restcon; 181748Speter case T_CINT: 182748Speter con.crval = atof(cn[1]); 183748Speter if (con.crval > MAXINT || con.crval < MININT) { 184748Speter derror("Constant too large for this implementation"); 185748Speter con.crval = 0; 186748Speter } 187748Speter restcon: 188748Speter ci = con.crval; 189748Speter #ifndef PI0 190748Speter if (bytes(ci, ci) <= 2) 191748Speter con.ctype = nl+T2INT; 192748Speter else 193748Speter #endif 194748Speter con.ctype = nl+T4INT; 195748Speter break; 196748Speter case T_CFINT: 197748Speter con.ctype = nl+TDOUBLE; 198748Speter con.crval = atof(cn[1]); 199748Speter break; 200748Speter case T_CSTRNG: 201748Speter cp = cn[1]; 202748Speter if (cp[1] == 0) { 203748Speter con.ctype = nl+T1CHAR; 204748Speter con.cival = cp[0]; 205748Speter con.crval = con.cival; 206748Speter break; 207748Speter } 208748Speter con.ctype = nl+TSTR; 209748Speter con.cpval = savestr(cp); 210748Speter break; 211748Speter } 212748Speter if (sgnd) { 213748Speter if (isnta(con.ctype, "id")) 214748Speter derror("%s constants cannot be signed", nameof(con.ctype)); 215748Speter else { 216748Speter if (negd) 217748Speter con.crval = -con.crval; 218748Speter ci = con.crval; 219748Speter } 220748Speter } 221748Speter } 222748Speter 223748Speter #ifndef PI0 224748Speter isconst(r) 225748Speter register int *r; 226748Speter { 227748Speter 228748Speter if (r == NIL) 229748Speter return (1); 230748Speter switch (r[0]) { 231748Speter case T_MINUS: 232748Speter r[0] = T_MINUSC; 233748Speter r[1] = r[2]; 234748Speter return (isconst(r[1])); 235748Speter case T_PLUS: 236748Speter r[0] = T_PLUSC; 237748Speter r[1] = r[2]; 238748Speter return (isconst(r[1])); 239748Speter case T_VAR: 240748Speter if (r[3] != NIL) 241748Speter return (0); 242748Speter r[0] = T_ID; 243748Speter r[1] = r[2]; 244748Speter return (1); 245748Speter case T_BINT: 246748Speter r[0] = T_CBINT; 247748Speter r[1] = r[2]; 248748Speter return (1); 249748Speter case T_INT: 250748Speter r[0] = T_CINT; 251748Speter r[1] = r[2]; 252748Speter return (1); 253748Speter case T_FINT: 254748Speter r[0] = T_CFINT; 255748Speter r[1] = r[2]; 256748Speter return (1); 257748Speter case T_STRNG: 258748Speter r[0] = T_CSTRNG; 259748Speter r[1] = r[2]; 260748Speter return (1); 261748Speter } 262748Speter return (0); 263748Speter } 264748Speter #endif 265