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