xref: /csrg-svn/usr.bin/pascal/src/const.c (revision 7951)
1748Speter /* Copyright (c) 1979 Regents of the University of California */
2748Speter 
3*7951Speter static	char sccsid[] = "@(#)const.c 1.5 08/29/82";
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
15*7951Speter constbeg( lineofyconst , r )
16*7951Speter     int	lineofyconst;
17748Speter {
18*7951Speter     static bool	const_order = FALSE;
19*7951Speter     static bool	const_seen = FALSE;
20748Speter 
21748Speter /*
22834Speter  * this allows for multiple declaration
23748Speter  * parts, unless the "standard" option
24748Speter  * has been specified.
25748Speter  * If a routine segment is being compiled,
26748Speter  * do level one processing.
27748Speter  */
28748Speter 
29748Speter 	if (!progseen)
30748Speter 		level1();
31*7951Speter 	line = lineofyconst;
32834Speter 	if (parts[ cbn ] & (TPRT|VPRT|RPRT)) {
33834Speter 	    if ( opt( 's' ) ) {
34834Speter 		standard();
35*7951Speter 		error("Constant declarations should precede type, var and routine declarations");
36834Speter 	    } else {
37*7951Speter 		if ( !const_order ) {
38*7951Speter 		    const_order = TRUE;
39*7951Speter 		    warning();
40*7951Speter 		    error("Constant declarations should precede type, var and routine declarations");
41*7951Speter 		}
42834Speter 	    }
43834Speter 	}
44834Speter 	if (parts[ cbn ] & CPRT) {
45834Speter 	    if ( opt( 's' ) ) {
46834Speter 		standard();
47*7951Speter 		error("All constants should be declared in one const part");
48834Speter 	    } else {
49*7951Speter 		if ( !const_seen ) {
50*7951Speter 		    const_seen = TRUE;
51*7951Speter 		    warning();
52*7951Speter 		    error("All constants should be declared in one const part");
53*7951Speter 		}
54834Speter 	    }
55834Speter 	}
56834Speter 	parts[ cbn ] |= CPRT;
57748Speter }
58748Speter #endif PI1
59748Speter 
60748Speter const(cline, cid, cdecl)
61748Speter 	int cline;
62748Speter 	register char *cid;
63748Speter 	register int *cdecl;
64748Speter {
65748Speter 	register struct nl *np;
66748Speter 
67748Speter #ifdef PI0
68748Speter 	send(REVCNST, cline, cid, cdecl);
69748Speter #endif
70748Speter 	line = cline;
71748Speter 	gconst(cdecl);
72748Speter 	np = enter(defnl(cid, CONST, con.ctype, con.cival));
73748Speter #ifndef PI0
74748Speter 	np->nl_flags |= NMOD;
75748Speter #endif
76748Speter 
77748Speter #ifdef PC
78825Speter 	if (cbn == 1) {
79840Speter 	    stabgconst( cid , line );
80825Speter 	}
81748Speter #endif PC
82748Speter 
83748Speter #	ifdef PTREE
84748Speter 	    {
85748Speter 		pPointer	Const = ConstDecl( cid , cdecl );
86748Speter 		pPointer	*Consts;
87748Speter 
88748Speter 		pSeize( PorFHeader[ nesting ] );
89748Speter 		Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts );
90748Speter 		*Consts = ListAppend( *Consts , Const );
91748Speter 		pRelease( PorFHeader[ nesting ] );
92748Speter 	    }
93748Speter #	endif
94748Speter 	if (con.ctype == NIL)
95748Speter 		return;
96748Speter 	if ( con.ctype == nl + TSTR )
97748Speter 		np->ptr[0] = con.cpval;
98748Speter 	if (isa(con.ctype, "i"))
99748Speter 		np->range[0] = con.crval;
100748Speter 	else if (isa(con.ctype, "d"))
101748Speter 		np->real = con.crval;
102748Speter }
103748Speter 
104748Speter #ifndef PI0
105748Speter #ifndef PI1
106748Speter constend()
107748Speter {
108748Speter 
109748Speter }
110748Speter #endif
111748Speter #endif
112748Speter 
113748Speter /*
114748Speter  * Gconst extracts
115748Speter  * a constant declaration
116748Speter  * from the tree for it.
117748Speter  * only types of constants
118748Speter  * are integer, reals, strings
119748Speter  * and scalars, the first two
120748Speter  * being possibly signed.
121748Speter  */
122748Speter gconst(r)
123748Speter 	int *r;
124748Speter {
125748Speter 	register struct nl *np;
126748Speter 	register *cn;
127748Speter 	char *cp;
128748Speter 	int negd, sgnd;
129748Speter 	long ci;
130748Speter 
131748Speter 	con.ctype = NIL;
132748Speter 	cn = r;
133748Speter 	negd = sgnd = 0;
134748Speter loop:
135748Speter 	if (cn == NIL || cn[1] == NIL)
136748Speter 		return (NIL);
137748Speter 	switch (cn[0]) {
138748Speter 		default:
139748Speter 			panic("gconst");
140748Speter 		case T_MINUSC:
141748Speter 			negd = 1 - negd;
142748Speter 		case T_PLUSC:
143748Speter 			sgnd++;
144748Speter 			cn = cn[1];
145748Speter 			goto loop;
146748Speter 		case T_ID:
147748Speter 			np = lookup(cn[1]);
148748Speter 			if (np == NIL)
149748Speter 				return;
150748Speter 			if (np->class != CONST) {
151748Speter 				derror("%s is a %s, not a constant as required", cn[1], classes[np->class]);
152748Speter 				return;
153748Speter 			}
154748Speter 			con.ctype = np->type;
155748Speter 			switch (classify(np->type)) {
156748Speter 				case TINT:
157748Speter 					con.crval = np->range[0];
158748Speter 					break;
159748Speter 				case TDOUBLE:
160748Speter 					con.crval = np->real;
161748Speter 					break;
162748Speter 				case TBOOL:
163748Speter 				case TCHAR:
164748Speter 				case TSCAL:
165748Speter 					con.cival = np->value[0];
166748Speter 					con.crval = con.cival;
167748Speter 					break;
168748Speter 				case TSTR:
169748Speter 					con.cpval = np->ptr[0];
170748Speter 					break;
171748Speter 				case NIL:
172748Speter 					con.ctype = NIL;
173748Speter 					return;
174748Speter 				default:
175748Speter 					panic("gconst2");
176748Speter 			}
177748Speter 			break;
178748Speter 		case T_CBINT:
179748Speter 			con.crval = a8tol(cn[1]);
180748Speter 			goto restcon;
181748Speter 		case T_CINT:
182748Speter 			con.crval = atof(cn[1]);
183748Speter 			if (con.crval > MAXINT || con.crval < MININT) {
184748Speter 				derror("Constant too large for this implementation");
185748Speter 				con.crval = 0;
186748Speter 			}
187748Speter restcon:
188748Speter 			ci = con.crval;
189748Speter #ifndef PI0
190748Speter 			if (bytes(ci, ci) <= 2)
191748Speter 				con.ctype = nl+T2INT;
192748Speter 			else
193748Speter #endif
194748Speter 				con.ctype = nl+T4INT;
195748Speter 			break;
196748Speter 		case T_CFINT:
197748Speter 			con.ctype = nl+TDOUBLE;
198748Speter 			con.crval = atof(cn[1]);
199748Speter 			break;
200748Speter 		case T_CSTRNG:
201748Speter 			cp = cn[1];
202748Speter 			if (cp[1] == 0) {
203748Speter 				con.ctype = nl+T1CHAR;
204748Speter 				con.cival = cp[0];
205748Speter 				con.crval = con.cival;
206748Speter 				break;
207748Speter 			}
208748Speter 			con.ctype = nl+TSTR;
209748Speter 			con.cpval = savestr(cp);
210748Speter 			break;
211748Speter 	}
212748Speter 	if (sgnd) {
213748Speter 		if (isnta(con.ctype, "id"))
214748Speter 			derror("%s constants cannot be signed", nameof(con.ctype));
215748Speter 		else {
216748Speter 			if (negd)
217748Speter 				con.crval = -con.crval;
218748Speter 			ci = con.crval;
219748Speter 		}
220748Speter 	}
221748Speter }
222748Speter 
223748Speter #ifndef PI0
224748Speter isconst(r)
225748Speter 	register int *r;
226748Speter {
227748Speter 
228748Speter 	if (r == NIL)
229748Speter 		return (1);
230748Speter 	switch (r[0]) {
231748Speter 		case T_MINUS:
232748Speter 			r[0] = T_MINUSC;
233748Speter 			r[1] = r[2];
234748Speter 			return (isconst(r[1]));
235748Speter 		case T_PLUS:
236748Speter 			r[0] = T_PLUSC;
237748Speter 			r[1] = r[2];
238748Speter 			return (isconst(r[1]));
239748Speter 		case T_VAR:
240748Speter 			if (r[3] != NIL)
241748Speter 				return (0);
242748Speter 			r[0] = T_ID;
243748Speter 			r[1] = r[2];
244748Speter 			return (1);
245748Speter 		case T_BINT:
246748Speter 			r[0] = T_CBINT;
247748Speter 			r[1] = r[2];
248748Speter 			return (1);
249748Speter 		case T_INT:
250748Speter 			r[0] = T_CINT;
251748Speter 			r[1] = r[2];
252748Speter 			return (1);
253748Speter 		case T_FINT:
254748Speter 			r[0] = T_CFINT;
255748Speter 			r[1] = r[2];
256748Speter 			return (1);
257748Speter 		case T_STRNG:
258748Speter 			r[0] = T_CSTRNG;
259748Speter 			r[1] = r[2];
260748Speter 			return (1);
261748Speter 	}
262748Speter 	return (0);
263748Speter }
264748Speter #endif
265