148116Sbostic /*-
2*62205Sbostic * Copyright (c) 1980, 1993
3*62205Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
622158Sdist */
7748Speter
818345Smckusick #ifndef lint
9*62205Sbostic static char sccsid[] = "@(#)const.c 8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
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
constbeg(lineofyconst,linenum)2332287Smckusick constbeg( lineofyconst , linenum )
2432287Smckusick int lineofyconst, linenum;
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
constant(cline,cid,cdecl)6833234Sbostic constant(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
constend()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
isconst(cn)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