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