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