xref: /csrg-svn/usr.bin/pascal/src/const.c (revision 18344)
1748Speter /* Copyright (c) 1979 Regents of the University of California */
2748Speter 
3*18344Smckusick static	char sccsid[] = "@(#)const.c 1.5.1.1 03/15/85";
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*18344Smckusick constbeg( lineofyconst , r )
167951Speter     int	lineofyconst;
17748Speter {
187951Speter     static bool	const_order = FALSE;
197951Speter     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();
317951Speter 	line = lineofyconst;
32834Speter 	if (parts[ cbn ] & (TPRT|VPRT|RPRT)) {
33834Speter 	    if ( opt( 's' ) ) {
34834Speter 		standard();
357951Speter 		error("Constant declarations should precede type, var and routine declarations");
36834Speter 	    } else {
377951Speter 		if ( !const_order ) {
387951Speter 		    const_order = TRUE;
397951Speter 		    warning();
407951Speter 		    error("Constant declarations should precede type, var and routine declarations");
417951Speter 		}
42834Speter 	    }
43834Speter 	}
44834Speter 	if (parts[ cbn ] & CPRT) {
45834Speter 	    if ( opt( 's' ) ) {
46834Speter 		standard();
477951Speter 		error("All constants should be declared in one const part");
48834Speter 	    } else {
497951Speter 		if ( !const_seen ) {
507951Speter 		    const_seen = TRUE;
517951Speter 		    warning();
527951Speter 		    error("All constants should be declared in one const part");
537951Speter 		}
54834Speter 	    }
55834Speter 	}
56834Speter 	parts[ cbn ] |= CPRT;
57748Speter }
58748Speter #endif PI1
59748Speter 
60748Speter const(cline, cid, cdecl)
61748Speter 	int cline;
62748Speter 	register char *cid;
63*18344Smckusick 	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 )
97*18344Smckusick 		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;
102*18344Smckusick #       ifdef PC
103*18344Smckusick 	    if (cbn == 1 && con.ctype != NIL) {
104*18344Smckusick 		    stabconst(np);
105*18344Smckusick 	    }
106*18344Smckusick #       endif
107748Speter }
108748Speter 
109748Speter #ifndef PI0
110748Speter #ifndef PI1
111748Speter constend()
112748Speter {
113748Speter 
114748Speter }
115748Speter #endif
116748Speter #endif
117748Speter 
118748Speter /*
119748Speter  * Gconst extracts
120748Speter  * a constant declaration
121748Speter  * from the tree for it.
122748Speter  * only types of constants
123748Speter  * are integer, reals, strings
124748Speter  * and scalars, the first two
125748Speter  * being possibly signed.
126748Speter  */
127*18344Smckusick gconst(r)
128*18344Smckusick 	int *r;
129748Speter {
130748Speter 	register struct nl *np;
131*18344Smckusick 	register *cn;
132748Speter 	char *cp;
133748Speter 	int negd, sgnd;
134748Speter 	long ci;
135748Speter 
136748Speter 	con.ctype = NIL;
137*18344Smckusick 	cn = r;
138748Speter 	negd = sgnd = 0;
139748Speter loop:
140*18344Smckusick 	if (cn == NIL || cn[1] == NIL)
141*18344Smckusick 		return (NIL);
142*18344Smckusick 	switch (cn[0]) {
143748Speter 		default:
144748Speter 			panic("gconst");
145748Speter 		case T_MINUSC:
146748Speter 			negd = 1 - negd;
147748Speter 		case T_PLUSC:
148748Speter 			sgnd++;
149*18344Smckusick 			cn = cn[1];
150748Speter 			goto loop;
151748Speter 		case T_ID:
152*18344Smckusick 			np = lookup(cn[1]);
153*18344Smckusick 			if (np == NIL)
154748Speter 				return;
155748Speter 			if (np->class != CONST) {
156*18344Smckusick 				derror("%s is a %s, not a constant as required", cn[1], classes[np->class]);
157748Speter 				return;
158748Speter 			}
159748Speter 			con.ctype = np->type;
160748Speter 			switch (classify(np->type)) {
161748Speter 				case TINT:
162748Speter 					con.crval = np->range[0];
163748Speter 					break;
164748Speter 				case TDOUBLE:
165748Speter 					con.crval = np->real;
166748Speter 					break;
167748Speter 				case TBOOL:
168748Speter 				case TCHAR:
169748Speter 				case TSCAL:
170748Speter 					con.cival = np->value[0];
171748Speter 					con.crval = con.cival;
172748Speter 					break;
173748Speter 				case TSTR:
174*18344Smckusick 					con.cpval = np->ptr[0];
175748Speter 					break;
176748Speter 				case NIL:
177748Speter 					con.ctype = NIL;
178748Speter 					return;
179748Speter 				default:
180748Speter 					panic("gconst2");
181748Speter 			}
182748Speter 			break;
183748Speter 		case T_CBINT:
184*18344Smckusick 			con.crval = a8tol(cn[1]);
185748Speter 			goto restcon;
186748Speter 		case T_CINT:
187*18344Smckusick 			con.crval = atof(cn[1]);
188748Speter 			if (con.crval > MAXINT || con.crval < MININT) {
189748Speter 				derror("Constant too large for this implementation");
190748Speter 				con.crval = 0;
191748Speter 			}
192748Speter restcon:
193748Speter 			ci = con.crval;
194748Speter #ifndef PI0
195748Speter 			if (bytes(ci, ci) <= 2)
196748Speter 				con.ctype = nl+T2INT;
197748Speter 			else
198748Speter #endif
199748Speter 				con.ctype = nl+T4INT;
200748Speter 			break;
201748Speter 		case T_CFINT:
202748Speter 			con.ctype = nl+TDOUBLE;
203*18344Smckusick 			con.crval = atof(cn[1]);
204748Speter 			break;
205748Speter 		case T_CSTRNG:
206*18344Smckusick 			cp = cn[1];
207748Speter 			if (cp[1] == 0) {
208748Speter 				con.ctype = nl+T1CHAR;
209748Speter 				con.cival = cp[0];
210748Speter 				con.crval = con.cival;
211748Speter 				break;
212748Speter 			}
213748Speter 			con.ctype = nl+TSTR;
214748Speter 			con.cpval = savestr(cp);
215748Speter 			break;
216748Speter 	}
217748Speter 	if (sgnd) {
218*18344Smckusick 		if (isnta(con.ctype, "id"))
219*18344Smckusick 			derror("%s constants cannot be signed", nameof(con.ctype));
220748Speter 		else {
221748Speter 			if (negd)
222748Speter 				con.crval = -con.crval;
223748Speter 			ci = con.crval;
224748Speter 		}
225748Speter 	}
226748Speter }
227748Speter 
228748Speter #ifndef PI0
229*18344Smckusick isconst(r)
230*18344Smckusick 	register int *r;
231748Speter {
232748Speter 
233*18344Smckusick 	if (r == NIL)
234748Speter 		return (1);
235*18344Smckusick 	switch (r[0]) {
236748Speter 		case T_MINUS:
237*18344Smckusick 			r[0] = T_MINUSC;
238*18344Smckusick 			r[1] = r[2];
239*18344Smckusick 			return (isconst(r[1]));
240748Speter 		case T_PLUS:
241*18344Smckusick 			r[0] = T_PLUSC;
242*18344Smckusick 			r[1] = r[2];
243*18344Smckusick 			return (isconst(r[1]));
244748Speter 		case T_VAR:
245*18344Smckusick 			if (r[3] != NIL)
246748Speter 				return (0);
247*18344Smckusick 			r[0] = T_ID;
248*18344Smckusick 			r[1] = r[2];
249748Speter 			return (1);
250748Speter 		case T_BINT:
251*18344Smckusick 			r[0] = T_CBINT;
252*18344Smckusick 			r[1] = r[2];
253748Speter 			return (1);
254748Speter 		case T_INT:
255*18344Smckusick 			r[0] = T_CINT;
256*18344Smckusick 			r[1] = r[2];
257748Speter 			return (1);
258748Speter 		case T_FINT:
259*18344Smckusick 			r[0] = T_CFINT;
260*18344Smckusick 			r[1] = r[2];
261748Speter 			return (1);
262748Speter 		case T_STRNG:
263*18344Smckusick 			r[0] = T_CSTRNG;
264*18344Smckusick 			r[1] = r[2];
265748Speter 			return (1);
266748Speter 	}
267748Speter 	return (0);
268748Speter }
269748Speter #endif
270