122158Sdist /* 222158Sdist * Copyright (c) 1980 Regents of the University of California. 322158Sdist * All rights reserved. The Berkeley software License Agreement 422158Sdist * specifies the terms and conditions for redistribution. 522158Sdist */ 6748Speter 718345Smckusick #ifndef lint 8*33234Sbostic static char sccsid[] = "@(#)const.c 5.4 (Berkeley) 01/03/88"; 922158Sdist #endif not lint 10748Speter 11748Speter #include "whoami.h" 12748Speter #include "0.h" 13748Speter #include "tree.h" 1418345Smckusick #include "tree_ty.h" 15748Speter 16748Speter /* 17748Speter * Const enters the definitions 18748Speter * of the constant declaration 19748Speter * part into the namelist. 20748Speter */ 21748Speter #ifndef PI1 2232287Smckusick constbeg( lineofyconst , linenum ) 2332287Smckusick int lineofyconst, linenum; 24748Speter { 257951Speter static bool const_order = FALSE; 267951Speter static bool const_seen = FALSE; 27748Speter 28748Speter /* 29834Speter * this allows for multiple declaration 30748Speter * parts, unless the "standard" option 31748Speter * has been specified. 32748Speter * If a routine segment is being compiled, 33748Speter * do level one processing. 34748Speter */ 35748Speter 36748Speter if (!progseen) 37748Speter level1(); 387951Speter line = lineofyconst; 39834Speter if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { 40834Speter if ( opt( 's' ) ) { 41834Speter standard(); 427951Speter error("Constant declarations should precede type, var and routine declarations"); 43834Speter } else { 447951Speter if ( !const_order ) { 457951Speter const_order = TRUE; 467951Speter warning(); 477951Speter error("Constant declarations should precede type, var and routine declarations"); 487951Speter } 49834Speter } 50834Speter } 51834Speter if (parts[ cbn ] & CPRT) { 52834Speter if ( opt( 's' ) ) { 53834Speter standard(); 547951Speter error("All constants should be declared in one const part"); 55834Speter } else { 567951Speter if ( !const_seen ) { 577951Speter const_seen = TRUE; 587951Speter warning(); 597951Speter error("All constants should be declared in one const part"); 607951Speter } 61834Speter } 62834Speter } 63834Speter parts[ cbn ] |= CPRT; 64748Speter } 65748Speter #endif PI1 66748Speter 67*33234Sbostic constant(cline, cid, cdecl) 68748Speter int cline; 69748Speter register char *cid; 7018345Smckusick register struct tnode *cdecl; 71748Speter { 72748Speter register struct nl *np; 73748Speter 74748Speter #ifdef PI0 75748Speter send(REVCNST, cline, cid, cdecl); 76748Speter #endif 77748Speter line = cline; 78748Speter gconst(cdecl); 79748Speter np = enter(defnl(cid, CONST, con.ctype, con.cival)); 80748Speter #ifndef PI0 81748Speter np->nl_flags |= NMOD; 82748Speter #endif 83748Speter 84748Speter #ifdef PC 85825Speter if (cbn == 1) { 86840Speter stabgconst( cid , line ); 87825Speter } 88748Speter #endif PC 89748Speter 90748Speter # ifdef PTREE 91748Speter { 92748Speter pPointer Const = ConstDecl( cid , cdecl ); 93748Speter pPointer *Consts; 94748Speter 95748Speter pSeize( PorFHeader[ nesting ] ); 96748Speter Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); 97748Speter *Consts = ListAppend( *Consts , Const ); 98748Speter pRelease( PorFHeader[ nesting ] ); 99748Speter } 100748Speter # endif 101748Speter if (con.ctype == NIL) 102748Speter return; 103748Speter if ( con.ctype == nl + TSTR ) 10418345Smckusick np->ptr[0] = (struct nl *) con.cpval; 105748Speter if (isa(con.ctype, "i")) 106748Speter np->range[0] = con.crval; 107748Speter else if (isa(con.ctype, "d")) 108748Speter np->real = con.crval; 10918344Smckusick # ifdef PC 11018344Smckusick if (cbn == 1 && con.ctype != NIL) { 11118344Smckusick stabconst(np); 11218344Smckusick } 11318344Smckusick # endif 114748Speter } 115748Speter 116748Speter #ifndef PI0 117748Speter #ifndef PI1 118748Speter constend() 119748Speter { 120748Speter 121748Speter } 122748Speter #endif 123748Speter #endif 124748Speter 125748Speter /* 126748Speter * Gconst extracts 127748Speter * a constant declaration 128748Speter * from the tree for it. 129748Speter * only types of constants 130748Speter * are integer, reals, strings 131748Speter * and scalars, the first two 132748Speter * being possibly signed. 133748Speter */ 13418345Smckusick gconst(c_node) 13518345Smckusick struct tnode *c_node; 136748Speter { 137748Speter register struct nl *np; 13818345Smckusick register struct tnode *cn; 139748Speter char *cp; 140748Speter int negd, sgnd; 141748Speter long ci; 142748Speter 143748Speter con.ctype = NIL; 14418345Smckusick cn = c_node; 145748Speter negd = sgnd = 0; 146748Speter loop: 14718345Smckusick if (cn == TR_NIL || cn->sign_const.number == TR_NIL) 14818345Smckusick return; 14918345Smckusick switch (cn->tag) { 150748Speter default: 151748Speter panic("gconst"); 152748Speter case T_MINUSC: 153748Speter negd = 1 - negd; 154748Speter case T_PLUSC: 155748Speter sgnd++; 15618345Smckusick cn = cn->sign_const.number; 157748Speter goto loop; 158748Speter case T_ID: 15918345Smckusick np = lookup(cn->char_const.cptr); 16018345Smckusick if (np == NLNIL) 161748Speter return; 162748Speter if (np->class != CONST) { 16318345Smckusick derror("%s is a %s, not a constant as required", cn->char_const.cptr, classes[np->class]); 164748Speter return; 165748Speter } 166748Speter con.ctype = np->type; 167748Speter switch (classify(np->type)) { 168748Speter case TINT: 169748Speter con.crval = np->range[0]; 170748Speter break; 171748Speter case TDOUBLE: 172748Speter con.crval = np->real; 173748Speter break; 174748Speter case TBOOL: 175748Speter case TCHAR: 176748Speter case TSCAL: 177748Speter con.cival = np->value[0]; 178748Speter con.crval = con.cival; 179748Speter break; 180748Speter case TSTR: 18118345Smckusick con.cpval = (char *) np->ptr[0]; 182748Speter break; 183748Speter case NIL: 184748Speter con.ctype = NIL; 185748Speter return; 186748Speter default: 187748Speter panic("gconst2"); 188748Speter } 189748Speter break; 190748Speter case T_CBINT: 19118345Smckusick con.crval = a8tol(cn->char_const.cptr); 192748Speter goto restcon; 193748Speter case T_CINT: 19418345Smckusick con.crval = atof(cn->char_const.cptr); 195748Speter if (con.crval > MAXINT || con.crval < MININT) { 196748Speter derror("Constant too large for this implementation"); 197748Speter con.crval = 0; 198748Speter } 199748Speter restcon: 200748Speter ci = con.crval; 201748Speter #ifndef PI0 202748Speter if (bytes(ci, ci) <= 2) 203748Speter con.ctype = nl+T2INT; 204748Speter else 205748Speter #endif 206748Speter con.ctype = nl+T4INT; 207748Speter break; 208748Speter case T_CFINT: 209748Speter con.ctype = nl+TDOUBLE; 21018345Smckusick con.crval = atof(cn->char_const.cptr); 211748Speter break; 212748Speter case T_CSTRNG: 21318345Smckusick cp = cn->char_const.cptr; 214748Speter if (cp[1] == 0) { 215748Speter con.ctype = nl+T1CHAR; 216748Speter con.cival = cp[0]; 217748Speter con.crval = con.cival; 218748Speter break; 219748Speter } 220748Speter con.ctype = nl+TSTR; 221748Speter con.cpval = savestr(cp); 222748Speter break; 223748Speter } 224748Speter if (sgnd) { 22518345Smckusick if (isnta((struct nl *) con.ctype, "id")) 22618345Smckusick derror("%s constants cannot be signed", 22718345Smckusick nameof((struct nl *) con.ctype)); 228748Speter else { 229748Speter if (negd) 230748Speter con.crval = -con.crval; 231748Speter ci = con.crval; 232748Speter } 233748Speter } 234748Speter } 235748Speter 236748Speter #ifndef PI0 23718345Smckusick isconst(cn) 23818345Smckusick register struct tnode *cn; 239748Speter { 240748Speter 24118345Smckusick if (cn == TR_NIL) 242748Speter return (1); 24318345Smckusick switch (cn->tag) { 244748Speter case T_MINUS: 24518345Smckusick cn->tag = T_MINUSC; 24618345Smckusick cn->sign_const.number = 24718345Smckusick cn->un_expr.expr; 24818345Smckusick return (isconst(cn->sign_const.number)); 249748Speter case T_PLUS: 25018345Smckusick cn->tag = T_PLUSC; 25118345Smckusick cn->sign_const.number = 25218345Smckusick cn->un_expr.expr; 25318345Smckusick return (isconst(cn->sign_const.number)); 254748Speter case T_VAR: 25518345Smckusick if (cn->var_node.qual != TR_NIL) 256748Speter return (0); 25718345Smckusick cn->tag = T_ID; 25818345Smckusick cn->char_const.cptr = 25918345Smckusick cn->var_node.cptr; 260748Speter return (1); 261748Speter case T_BINT: 26218345Smckusick cn->tag = T_CBINT; 26318345Smckusick cn->char_const.cptr = 26418345Smckusick cn->const_node.cptr; 265748Speter return (1); 266748Speter case T_INT: 26718345Smckusick cn->tag = T_CINT; 26818345Smckusick cn->char_const.cptr = 26918345Smckusick cn->const_node.cptr; 270748Speter return (1); 271748Speter case T_FINT: 27218345Smckusick cn->tag = T_CFINT; 27318345Smckusick cn->char_const.cptr = 27418345Smckusick cn->const_node.cptr; 275748Speter return (1); 276748Speter case T_STRNG: 27718345Smckusick cn->tag = T_CSTRNG; 27818345Smckusick cn->char_const.cptr = 27918345Smckusick cn->const_node.cptr; 280748Speter return (1); 281748Speter } 282748Speter return (0); 283748Speter } 284748Speter #endif 285