Commit | Line | Data |
---|---|---|
1259848a DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
57e8da55 | 6 | |
72fbef68 | 7 | #ifndef lint |
e3c19ac1 | 8 | static char sccsid[] = "@(#)const.c 5.3 (Berkeley) %G%"; |
1259848a | 9 | #endif not lint |
57e8da55 PK |
10 | |
11 | #include "whoami.h" | |
12 | #include "0.h" | |
13 | #include "tree.h" | |
72fbef68 | 14 | #include "tree_ty.h" |
57e8da55 PK |
15 | |
16 | /* | |
17 | * Const enters the definitions | |
18 | * of the constant declaration | |
19 | * part into the namelist. | |
20 | */ | |
21 | #ifndef PI1 | |
e3c19ac1 KM |
22 | constbeg( lineofyconst , linenum ) |
23 | int lineofyconst, linenum; | |
57e8da55 | 24 | { |
7204688c PK |
25 | static bool const_order = FALSE; |
26 | static bool const_seen = FALSE; | |
57e8da55 PK |
27 | |
28 | /* | |
af97bcfa | 29 | * this allows for multiple declaration |
57e8da55 PK |
30 | * parts, unless the "standard" option |
31 | * has been specified. | |
32 | * If a routine segment is being compiled, | |
33 | * do level one processing. | |
34 | */ | |
35 | ||
36 | if (!progseen) | |
37 | level1(); | |
7204688c | 38 | line = lineofyconst; |
af97bcfa PK |
39 | if (parts[ cbn ] & (TPRT|VPRT|RPRT)) { |
40 | if ( opt( 's' ) ) { | |
41 | standard(); | |
7204688c | 42 | error("Constant declarations should precede type, var and routine declarations"); |
af97bcfa | 43 | } else { |
7204688c PK |
44 | if ( !const_order ) { |
45 | const_order = TRUE; | |
46 | warning(); | |
47 | error("Constant declarations should precede type, var and routine declarations"); | |
48 | } | |
af97bcfa | 49 | } |
af97bcfa PK |
50 | } |
51 | if (parts[ cbn ] & CPRT) { | |
52 | if ( opt( 's' ) ) { | |
53 | standard(); | |
7204688c | 54 | error("All constants should be declared in one const part"); |
af97bcfa | 55 | } else { |
7204688c PK |
56 | if ( !const_seen ) { |
57 | const_seen = TRUE; | |
58 | warning(); | |
59 | error("All constants should be declared in one const part"); | |
60 | } | |
af97bcfa | 61 | } |
af97bcfa PK |
62 | } |
63 | parts[ cbn ] |= CPRT; | |
57e8da55 PK |
64 | } |
65 | #endif PI1 | |
66 | ||
67 | const(cline, cid, cdecl) | |
68 | int cline; | |
69 | register char *cid; | |
72fbef68 | 70 | register struct tnode *cdecl; |
57e8da55 PK |
71 | { |
72 | register struct nl *np; | |
73 | ||
74 | #ifdef PI0 | |
75 | send(REVCNST, cline, cid, cdecl); | |
76 | #endif | |
77 | line = cline; | |
78 | gconst(cdecl); | |
79 | np = enter(defnl(cid, CONST, con.ctype, con.cival)); | |
80 | #ifndef PI0 | |
81 | np->nl_flags |= NMOD; | |
82 | #endif | |
83 | ||
84 | #ifdef PC | |
b721c131 | 85 | if (cbn == 1) { |
99f6998f | 86 | stabgconst( cid , line ); |
b721c131 | 87 | } |
57e8da55 PK |
88 | #endif PC |
89 | ||
90 | # ifdef PTREE | |
91 | { | |
92 | pPointer Const = ConstDecl( cid , cdecl ); | |
93 | pPointer *Consts; | |
94 | ||
95 | pSeize( PorFHeader[ nesting ] ); | |
96 | Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts ); | |
97 | *Consts = ListAppend( *Consts , Const ); | |
98 | pRelease( PorFHeader[ nesting ] ); | |
99 | } | |
100 | # endif | |
101 | if (con.ctype == NIL) | |
102 | return; | |
103 | if ( con.ctype == nl + TSTR ) | |
72fbef68 | 104 | np->ptr[0] = (struct nl *) con.cpval; |
57e8da55 PK |
105 | if (isa(con.ctype, "i")) |
106 | np->range[0] = con.crval; | |
107 | else if (isa(con.ctype, "d")) | |
108 | np->real = con.crval; | |
8fcc1e8f KM |
109 | # ifdef PC |
110 | if (cbn == 1 && con.ctype != NIL) { | |
111 | stabconst(np); | |
112 | } | |
113 | # endif | |
57e8da55 PK |
114 | } |
115 | ||
116 | #ifndef PI0 | |
117 | #ifndef PI1 | |
118 | constend() | |
119 | { | |
120 | ||
121 | } | |
122 | #endif | |
123 | #endif | |
124 | \f | |
125 | /* | |
126 | * Gconst extracts | |
127 | * a constant declaration | |
128 | * from the tree for it. | |
129 | * only types of constants | |
130 | * are integer, reals, strings | |
131 | * and scalars, the first two | |
132 | * being possibly signed. | |
133 | */ | |
72fbef68 RT |
134 | gconst(c_node) |
135 | struct tnode *c_node; | |
57e8da55 PK |
136 | { |
137 | register struct nl *np; | |
72fbef68 | 138 | register struct tnode *cn; |
57e8da55 PK |
139 | char *cp; |
140 | int negd, sgnd; | |
141 | long ci; | |
142 | ||
143 | con.ctype = NIL; | |
72fbef68 | 144 | cn = c_node; |
57e8da55 PK |
145 | negd = sgnd = 0; |
146 | loop: | |
72fbef68 RT |
147 | if (cn == TR_NIL || cn->sign_const.number == TR_NIL) |
148 | return; | |
149 | switch (cn->tag) { | |
57e8da55 PK |
150 | default: |
151 | panic("gconst"); | |
152 | case T_MINUSC: | |
153 | negd = 1 - negd; | |
154 | case T_PLUSC: | |
155 | sgnd++; | |
72fbef68 | 156 | cn = cn->sign_const.number; |
57e8da55 PK |
157 | goto loop; |
158 | case T_ID: | |
72fbef68 RT |
159 | np = lookup(cn->char_const.cptr); |
160 | if (np == NLNIL) | |
57e8da55 PK |
161 | return; |
162 | if (np->class != CONST) { | |
72fbef68 | 163 | derror("%s is a %s, not a constant as required", cn->char_const.cptr, classes[np->class]); |
57e8da55 PK |
164 | return; |
165 | } | |
166 | con.ctype = np->type; | |
167 | switch (classify(np->type)) { | |
168 | case TINT: | |
169 | con.crval = np->range[0]; | |
170 | break; | |
171 | case TDOUBLE: | |
172 | con.crval = np->real; | |
173 | break; | |
174 | case TBOOL: | |
175 | case TCHAR: | |
176 | case TSCAL: | |
177 | con.cival = np->value[0]; | |
178 | con.crval = con.cival; | |
179 | break; | |
180 | case TSTR: | |
72fbef68 | 181 | con.cpval = (char *) np->ptr[0]; |
57e8da55 PK |
182 | break; |
183 | case NIL: | |
184 | con.ctype = NIL; | |
185 | return; | |
186 | default: | |
187 | panic("gconst2"); | |
188 | } | |
189 | break; | |
190 | case T_CBINT: | |
72fbef68 | 191 | con.crval = a8tol(cn->char_const.cptr); |
57e8da55 PK |
192 | goto restcon; |
193 | case T_CINT: | |
72fbef68 | 194 | con.crval = atof(cn->char_const.cptr); |
57e8da55 PK |
195 | if (con.crval > MAXINT || con.crval < MININT) { |
196 | derror("Constant too large for this implementation"); | |
197 | con.crval = 0; | |
198 | } | |
199 | restcon: | |
200 | ci = con.crval; | |
201 | #ifndef PI0 | |
202 | if (bytes(ci, ci) <= 2) | |
203 | con.ctype = nl+T2INT; | |
204 | else | |
205 | #endif | |
206 | con.ctype = nl+T4INT; | |
207 | break; | |
208 | case T_CFINT: | |
209 | con.ctype = nl+TDOUBLE; | |
72fbef68 | 210 | con.crval = atof(cn->char_const.cptr); |
57e8da55 PK |
211 | break; |
212 | case T_CSTRNG: | |
72fbef68 | 213 | cp = cn->char_const.cptr; |
57e8da55 PK |
214 | if (cp[1] == 0) { |
215 | con.ctype = nl+T1CHAR; | |
216 | con.cival = cp[0]; | |
217 | con.crval = con.cival; | |
218 | break; | |
219 | } | |
220 | con.ctype = nl+TSTR; | |
221 | con.cpval = savestr(cp); | |
222 | break; | |
223 | } | |
224 | if (sgnd) { | |
72fbef68 RT |
225 | if (isnta((struct nl *) con.ctype, "id")) |
226 | derror("%s constants cannot be signed", | |
227 | nameof((struct nl *) con.ctype)); | |
57e8da55 PK |
228 | else { |
229 | if (negd) | |
230 | con.crval = -con.crval; | |
231 | ci = con.crval; | |
232 | } | |
233 | } | |
234 | } | |
235 | ||
236 | #ifndef PI0 | |
72fbef68 RT |
237 | isconst(cn) |
238 | register struct tnode *cn; | |
57e8da55 PK |
239 | { |
240 | ||
72fbef68 | 241 | if (cn == TR_NIL) |
57e8da55 | 242 | return (1); |
72fbef68 | 243 | switch (cn->tag) { |
57e8da55 | 244 | case T_MINUS: |
72fbef68 RT |
245 | cn->tag = T_MINUSC; |
246 | cn->sign_const.number = | |
247 | cn->un_expr.expr; | |
248 | return (isconst(cn->sign_const.number)); | |
57e8da55 | 249 | case T_PLUS: |
72fbef68 RT |
250 | cn->tag = T_PLUSC; |
251 | cn->sign_const.number = | |
252 | cn->un_expr.expr; | |
253 | return (isconst(cn->sign_const.number)); | |
57e8da55 | 254 | case T_VAR: |
72fbef68 | 255 | if (cn->var_node.qual != TR_NIL) |
57e8da55 | 256 | return (0); |
72fbef68 RT |
257 | cn->tag = T_ID; |
258 | cn->char_const.cptr = | |
259 | cn->var_node.cptr; | |
57e8da55 PK |
260 | return (1); |
261 | case T_BINT: | |
72fbef68 RT |
262 | cn->tag = T_CBINT; |
263 | cn->char_const.cptr = | |
264 | cn->const_node.cptr; | |
57e8da55 PK |
265 | return (1); |
266 | case T_INT: | |
72fbef68 RT |
267 | cn->tag = T_CINT; |
268 | cn->char_const.cptr = | |
269 | cn->const_node.cptr; | |
57e8da55 PK |
270 | return (1); |
271 | case T_FINT: | |
72fbef68 RT |
272 | cn->tag = T_CFINT; |
273 | cn->char_const.cptr = | |
274 | cn->const_node.cptr; | |
57e8da55 PK |
275 | return (1); |
276 | case T_STRNG: | |
72fbef68 RT |
277 | cn->tag = T_CSTRNG; |
278 | cn->char_const.cptr = | |
279 | cn->const_node.cptr; | |
57e8da55 PK |
280 | return (1); |
281 | } | |
282 | return (0); | |
283 | } | |
284 | #endif |