1748Speter /* Copyright (c) 1979 Regents of the University of California */ 2748Speter 3*834Speter static char sccsid[] = "@(#)const.c 1.3 09/02/80"; 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 15748Speter constbeg() 16748Speter { 17748Speter 18748Speter /* 19*834Speter * this allows for multiple declaration 20748Speter * parts, unless the "standard" option 21748Speter * has been specified. 22748Speter * If a routine segment is being compiled, 23748Speter * do level one processing. 24748Speter */ 25748Speter 26748Speter if (!progseen) 27748Speter level1(); 28*834Speter if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { 29*834Speter if ( opt( 's' ) ) { 30*834Speter standard(); 31*834Speter } else { 32*834Speter warning(); 33*834Speter } 34*834Speter error("Constant declarations should precede type, var and routine declarations"); 35*834Speter } 36*834Speter if (parts[ cbn ] & CPRT) { 37*834Speter if ( opt( 's' ) ) { 38*834Speter standard(); 39*834Speter } else { 40*834Speter warning(); 41*834Speter } 42*834Speter error("All constants should be declared in one const part"); 43*834Speter } 44*834Speter parts[ cbn ] |= CPRT; 45748Speter } 46748Speter #endif PI1 47748Speter 48748Speter const(cline, cid, cdecl) 49748Speter int cline; 50748Speter register char *cid; 51748Speter register int *cdecl; 52748Speter { 53748Speter register struct nl *np; 54748Speter 55748Speter #ifdef PI0 56748Speter send(REVCNST, cline, cid, cdecl); 57748Speter #endif 58748Speter line = cline; 59748Speter gconst(cdecl); 60748Speter np = enter(defnl(cid, CONST, con.ctype, con.cival)); 61748Speter #ifndef PI0 62748Speter np->nl_flags |= NMOD; 63748Speter #endif 64748Speter 65748Speter #ifdef PC 66825Speter if (cbn == 1) { 67825Speter stabcname( cid , line ); 68825Speter } 69748Speter #endif PC 70748Speter 71748Speter # ifdef PTREE 72748Speter { 73748Speter pPointer Const = ConstDecl( cid , cdecl ); 74748Speter pPointer *Consts; 75748Speter 76748Speter pSeize( PorFHeader[ nesting ] ); 77748Speter Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); 78748Speter *Consts = ListAppend( *Consts , Const ); 79748Speter pRelease( PorFHeader[ nesting ] ); 80748Speter } 81748Speter # endif 82748Speter if (con.ctype == NIL) 83748Speter return; 84748Speter if ( con.ctype == nl + TSTR ) 85748Speter np->ptr[0] = con.cpval; 86748Speter if (isa(con.ctype, "i")) 87748Speter np->range[0] = con.crval; 88748Speter else if (isa(con.ctype, "d")) 89748Speter np->real = con.crval; 90748Speter } 91748Speter 92748Speter #ifndef PI0 93748Speter #ifndef PI1 94748Speter constend() 95748Speter { 96748Speter 97748Speter } 98748Speter #endif 99748Speter #endif 100748Speter 101748Speter /* 102748Speter * Gconst extracts 103748Speter * a constant declaration 104748Speter * from the tree for it. 105748Speter * only types of constants 106748Speter * are integer, reals, strings 107748Speter * and scalars, the first two 108748Speter * being possibly signed. 109748Speter */ 110748Speter gconst(r) 111748Speter int *r; 112748Speter { 113748Speter register struct nl *np; 114748Speter register *cn; 115748Speter char *cp; 116748Speter int negd, sgnd; 117748Speter long ci; 118748Speter 119748Speter con.ctype = NIL; 120748Speter cn = r; 121748Speter negd = sgnd = 0; 122748Speter loop: 123748Speter if (cn == NIL || cn[1] == NIL) 124748Speter return (NIL); 125748Speter switch (cn[0]) { 126748Speter default: 127748Speter panic("gconst"); 128748Speter case T_MINUSC: 129748Speter negd = 1 - negd; 130748Speter case T_PLUSC: 131748Speter sgnd++; 132748Speter cn = cn[1]; 133748Speter goto loop; 134748Speter case T_ID: 135748Speter np = lookup(cn[1]); 136748Speter if (np == NIL) 137748Speter return; 138748Speter if (np->class != CONST) { 139748Speter derror("%s is a %s, not a constant as required", cn[1], classes[np->class]); 140748Speter return; 141748Speter } 142748Speter con.ctype = np->type; 143748Speter switch (classify(np->type)) { 144748Speter case TINT: 145748Speter con.crval = np->range[0]; 146748Speter break; 147748Speter case TDOUBLE: 148748Speter con.crval = np->real; 149748Speter break; 150748Speter case TBOOL: 151748Speter case TCHAR: 152748Speter case TSCAL: 153748Speter con.cival = np->value[0]; 154748Speter con.crval = con.cival; 155748Speter break; 156748Speter case TSTR: 157748Speter con.cpval = np->ptr[0]; 158748Speter break; 159748Speter case NIL: 160748Speter con.ctype = NIL; 161748Speter return; 162748Speter default: 163748Speter panic("gconst2"); 164748Speter } 165748Speter break; 166748Speter case T_CBINT: 167748Speter con.crval = a8tol(cn[1]); 168748Speter goto restcon; 169748Speter case T_CINT: 170748Speter con.crval = atof(cn[1]); 171748Speter if (con.crval > MAXINT || con.crval < MININT) { 172748Speter derror("Constant too large for this implementation"); 173748Speter con.crval = 0; 174748Speter } 175748Speter restcon: 176748Speter ci = con.crval; 177748Speter #ifndef PI0 178748Speter if (bytes(ci, ci) <= 2) 179748Speter con.ctype = nl+T2INT; 180748Speter else 181748Speter #endif 182748Speter con.ctype = nl+T4INT; 183748Speter break; 184748Speter case T_CFINT: 185748Speter con.ctype = nl+TDOUBLE; 186748Speter con.crval = atof(cn[1]); 187748Speter break; 188748Speter case T_CSTRNG: 189748Speter cp = cn[1]; 190748Speter if (cp[1] == 0) { 191748Speter con.ctype = nl+T1CHAR; 192748Speter con.cival = cp[0]; 193748Speter con.crval = con.cival; 194748Speter break; 195748Speter } 196748Speter con.ctype = nl+TSTR; 197748Speter con.cpval = savestr(cp); 198748Speter break; 199748Speter } 200748Speter if (sgnd) { 201748Speter if (isnta(con.ctype, "id")) 202748Speter derror("%s constants cannot be signed", nameof(con.ctype)); 203748Speter else { 204748Speter if (negd) 205748Speter con.crval = -con.crval; 206748Speter ci = con.crval; 207748Speter } 208748Speter } 209748Speter } 210748Speter 211748Speter #ifndef PI0 212748Speter isconst(r) 213748Speter register int *r; 214748Speter { 215748Speter 216748Speter if (r == NIL) 217748Speter return (1); 218748Speter switch (r[0]) { 219748Speter case T_MINUS: 220748Speter r[0] = T_MINUSC; 221748Speter r[1] = r[2]; 222748Speter return (isconst(r[1])); 223748Speter case T_PLUS: 224748Speter r[0] = T_PLUSC; 225748Speter r[1] = r[2]; 226748Speter return (isconst(r[1])); 227748Speter case T_VAR: 228748Speter if (r[3] != NIL) 229748Speter return (0); 230748Speter r[0] = T_ID; 231748Speter r[1] = r[2]; 232748Speter return (1); 233748Speter case T_BINT: 234748Speter r[0] = T_CBINT; 235748Speter r[1] = r[2]; 236748Speter return (1); 237748Speter case T_INT: 238748Speter r[0] = T_CINT; 239748Speter r[1] = r[2]; 240748Speter return (1); 241748Speter case T_FINT: 242748Speter r[0] = T_CFINT; 243748Speter r[1] = r[2]; 244748Speter return (1); 245748Speter case T_STRNG: 246748Speter r[0] = T_CSTRNG; 247748Speter r[1] = r[2]; 248748Speter return (1); 249748Speter } 250748Speter return (0); 251748Speter } 252748Speter #endif 253