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