1*22158Sdist /* 2*22158Sdist * Copyright (c) 1980 Regents of the University of California. 3*22158Sdist * All rights reserved. The Berkeley software License Agreement 4*22158Sdist * specifies the terms and conditions for redistribution. 5*22158Sdist */ 6748Speter 718345Smckusick #ifndef lint 8*22158Sdist static char sccsid[] = "@(#)const.c 5.1 (Berkeley) 06/05/85"; 9*22158Sdist #endif not lint 1018345Smckusick #endif 11748Speter 12748Speter #include "whoami.h" 13748Speter #include "0.h" 14748Speter #include "tree.h" 1518345Smckusick #include "tree_ty.h" 16748Speter 17748Speter /* 18748Speter * Const enters the definitions 19748Speter * of the constant declaration 20748Speter * part into the namelist. 21748Speter */ 22748Speter #ifndef PI1 2318345Smckusick constbeg( lineofyconst ) 247951Speter int lineofyconst; 25748Speter { 267951Speter static bool const_order = FALSE; 277951Speter static bool const_seen = FALSE; 28748Speter 29748Speter /* 30834Speter * this allows for multiple declaration 31748Speter * parts, unless the "standard" option 32748Speter * has been specified. 33748Speter * If a routine segment is being compiled, 34748Speter * do level one processing. 35748Speter */ 36748Speter 37748Speter if (!progseen) 38748Speter level1(); 397951Speter line = lineofyconst; 40834Speter if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { 41834Speter if ( opt( 's' ) ) { 42834Speter standard(); 437951Speter error("Constant declarations should precede type, var and routine declarations"); 44834Speter } else { 457951Speter if ( !const_order ) { 467951Speter const_order = TRUE; 477951Speter warning(); 487951Speter error("Constant declarations should precede type, var and routine declarations"); 497951Speter } 50834Speter } 51834Speter } 52834Speter if (parts[ cbn ] & CPRT) { 53834Speter if ( opt( 's' ) ) { 54834Speter standard(); 557951Speter error("All constants should be declared in one const part"); 56834Speter } else { 577951Speter if ( !const_seen ) { 587951Speter const_seen = TRUE; 597951Speter warning(); 607951Speter error("All constants should be declared in one const part"); 617951Speter } 62834Speter } 63834Speter } 64834Speter parts[ cbn ] |= CPRT; 65748Speter } 66748Speter #endif PI1 67748Speter 68748Speter const(cline, cid, cdecl) 69748Speter int cline; 70748Speter register char *cid; 7118345Smckusick register struct tnode *cdecl; 72748Speter { 73748Speter register struct nl *np; 74748Speter 75748Speter #ifdef PI0 76748Speter send(REVCNST, cline, cid, cdecl); 77748Speter #endif 78748Speter line = cline; 79748Speter gconst(cdecl); 80748Speter np = enter(defnl(cid, CONST, con.ctype, con.cival)); 81748Speter #ifndef PI0 82748Speter np->nl_flags |= NMOD; 83748Speter #endif 84748Speter 85748Speter #ifdef PC 86825Speter if (cbn == 1) { 87840Speter stabgconst( cid , line ); 88825Speter } 89748Speter #endif PC 90748Speter 91748Speter # ifdef PTREE 92748Speter { 93748Speter pPointer Const = ConstDecl( cid , cdecl ); 94748Speter pPointer *Consts; 95748Speter 96748Speter pSeize( PorFHeader[ nesting ] ); 97748Speter Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); 98748Speter *Consts = ListAppend( *Consts , Const ); 99748Speter pRelease( PorFHeader[ nesting ] ); 100748Speter } 101748Speter # endif 102748Speter if (con.ctype == NIL) 103748Speter return; 104748Speter if ( con.ctype == nl + TSTR ) 10518345Smckusick np->ptr[0] = (struct nl *) con.cpval; 106748Speter if (isa(con.ctype, "i")) 107748Speter np->range[0] = con.crval; 108748Speter else if (isa(con.ctype, "d")) 109748Speter np->real = con.crval; 11018344Smckusick # ifdef PC 11118344Smckusick if (cbn == 1 && con.ctype != NIL) { 11218344Smckusick stabconst(np); 11318344Smckusick } 11418344Smckusick # endif 115748Speter } 116748Speter 117748Speter #ifndef PI0 118748Speter #ifndef PI1 119748Speter constend() 120748Speter { 121748Speter 122748Speter } 123748Speter #endif 124748Speter #endif 125748Speter 126748Speter /* 127748Speter * Gconst extracts 128748Speter * a constant declaration 129748Speter * from the tree for it. 130748Speter * only types of constants 131748Speter * are integer, reals, strings 132748Speter * and scalars, the first two 133748Speter * being possibly signed. 134748Speter */ 13518345Smckusick gconst(c_node) 13618345Smckusick struct tnode *c_node; 137748Speter { 138748Speter register struct nl *np; 13918345Smckusick register struct tnode *cn; 140748Speter char *cp; 141748Speter int negd, sgnd; 142748Speter long ci; 143748Speter 144748Speter con.ctype = NIL; 14518345Smckusick cn = c_node; 146748Speter negd = sgnd = 0; 147748Speter loop: 14818345Smckusick if (cn == TR_NIL || cn->sign_const.number == TR_NIL) 14918345Smckusick return; 15018345Smckusick switch (cn->tag) { 151748Speter default: 152748Speter panic("gconst"); 153748Speter case T_MINUSC: 154748Speter negd = 1 - negd; 155748Speter case T_PLUSC: 156748Speter sgnd++; 15718345Smckusick cn = cn->sign_const.number; 158748Speter goto loop; 159748Speter case T_ID: 16018345Smckusick np = lookup(cn->char_const.cptr); 16118345Smckusick if (np == NLNIL) 162748Speter return; 163748Speter if (np->class != CONST) { 16418345Smckusick derror("%s is a %s, not a constant as required", cn->char_const.cptr, classes[np->class]); 165748Speter return; 166748Speter } 167748Speter con.ctype = np->type; 168748Speter switch (classify(np->type)) { 169748Speter case TINT: 170748Speter con.crval = np->range[0]; 171748Speter break; 172748Speter case TDOUBLE: 173748Speter con.crval = np->real; 174748Speter break; 175748Speter case TBOOL: 176748Speter case TCHAR: 177748Speter case TSCAL: 178748Speter con.cival = np->value[0]; 179748Speter con.crval = con.cival; 180748Speter break; 181748Speter case TSTR: 18218345Smckusick con.cpval = (char *) np->ptr[0]; 183748Speter break; 184748Speter case NIL: 185748Speter con.ctype = NIL; 186748Speter return; 187748Speter default: 188748Speter panic("gconst2"); 189748Speter } 190748Speter break; 191748Speter case T_CBINT: 19218345Smckusick con.crval = a8tol(cn->char_const.cptr); 193748Speter goto restcon; 194748Speter case T_CINT: 19518345Smckusick con.crval = atof(cn->char_const.cptr); 196748Speter if (con.crval > MAXINT || con.crval < MININT) { 197748Speter derror("Constant too large for this implementation"); 198748Speter con.crval = 0; 199748Speter } 200748Speter restcon: 201748Speter ci = con.crval; 202748Speter #ifndef PI0 203748Speter if (bytes(ci, ci) <= 2) 204748Speter con.ctype = nl+T2INT; 205748Speter else 206748Speter #endif 207748Speter con.ctype = nl+T4INT; 208748Speter break; 209748Speter case T_CFINT: 210748Speter con.ctype = nl+TDOUBLE; 21118345Smckusick con.crval = atof(cn->char_const.cptr); 212748Speter break; 213748Speter case T_CSTRNG: 21418345Smckusick cp = cn->char_const.cptr; 215748Speter if (cp[1] == 0) { 216748Speter con.ctype = nl+T1CHAR; 217748Speter con.cival = cp[0]; 218748Speter con.crval = con.cival; 219748Speter break; 220748Speter } 221748Speter con.ctype = nl+TSTR; 222748Speter con.cpval = savestr(cp); 223748Speter break; 224748Speter } 225748Speter if (sgnd) { 22618345Smckusick if (isnta((struct nl *) con.ctype, "id")) 22718345Smckusick derror("%s constants cannot be signed", 22818345Smckusick nameof((struct nl *) con.ctype)); 229748Speter else { 230748Speter if (negd) 231748Speter con.crval = -con.crval; 232748Speter ci = con.crval; 233748Speter } 234748Speter } 235748Speter } 236748Speter 237748Speter #ifndef PI0 23818345Smckusick isconst(cn) 23918345Smckusick register struct tnode *cn; 240748Speter { 241748Speter 24218345Smckusick if (cn == TR_NIL) 243748Speter return (1); 24418345Smckusick switch (cn->tag) { 245748Speter case T_MINUS: 24618345Smckusick cn->tag = T_MINUSC; 24718345Smckusick cn->sign_const.number = 24818345Smckusick cn->un_expr.expr; 24918345Smckusick return (isconst(cn->sign_const.number)); 250748Speter case T_PLUS: 25118345Smckusick cn->tag = T_PLUSC; 25218345Smckusick cn->sign_const.number = 25318345Smckusick cn->un_expr.expr; 25418345Smckusick return (isconst(cn->sign_const.number)); 255748Speter case T_VAR: 25618345Smckusick if (cn->var_node.qual != TR_NIL) 257748Speter return (0); 25818345Smckusick cn->tag = T_ID; 25918345Smckusick cn->char_const.cptr = 26018345Smckusick cn->var_node.cptr; 261748Speter return (1); 262748Speter case T_BINT: 26318345Smckusick cn->tag = T_CBINT; 26418345Smckusick cn->char_const.cptr = 26518345Smckusick cn->const_node.cptr; 266748Speter return (1); 267748Speter case T_INT: 26818345Smckusick cn->tag = T_CINT; 26918345Smckusick cn->char_const.cptr = 27018345Smckusick cn->const_node.cptr; 271748Speter return (1); 272748Speter case T_FINT: 27318345Smckusick cn->tag = T_CFINT; 27418345Smckusick cn->char_const.cptr = 27518345Smckusick cn->const_node.cptr; 276748Speter return (1); 277748Speter case T_STRNG: 27818345Smckusick cn->tag = T_CSTRNG; 27918345Smckusick cn->char_const.cptr = 28018345Smckusick cn->const_node.cptr; 281748Speter return (1); 282748Speter } 283748Speter return (0); 284748Speter } 285748Speter #endif 286