xref: /csrg-svn/usr.bin/pascal/src/const.c (revision 62205)
148116Sbostic /*-
2*62205Sbostic  * Copyright (c) 1980, 1993
3*62205Sbostic  *	The Regents of the University of California.  All rights reserved.
448116Sbostic  *
548116Sbostic  * %sccs.include.redist.c%
622158Sdist  */
7748Speter 
818345Smckusick #ifndef lint
9*62205Sbostic static char sccsid[] = "@(#)const.c	8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
11748Speter 
12748Speter #include "whoami.h"
13748Speter #include "0.h"
14748Speter #include "tree.h"
1518345Smckusick #include "tree_ty.h"
16748Speter 
17748Speter /*
18748Speter  * Const enters the definitions
19748Speter  * of the constant declaration
20748Speter  * part into the namelist.
21748Speter  */
22748Speter #ifndef PI1
constbeg(lineofyconst,linenum)2332287Smckusick constbeg( lineofyconst , linenum )
2432287Smckusick     int	lineofyconst, linenum;
25748Speter {
267951Speter     static bool	const_order = FALSE;
277951Speter     static bool	const_seen = FALSE;
28748Speter 
29748Speter /*
30834Speter  * this allows for multiple declaration
31748Speter  * parts, unless the "standard" option
32748Speter  * has been specified.
33748Speter  * If a routine segment is being compiled,
34748Speter  * do level one processing.
35748Speter  */
36748Speter 
37748Speter 	if (!progseen)
38748Speter 		level1();
397951Speter 	line = lineofyconst;
40834Speter 	if (parts[ cbn ] & (TPRT|VPRT|RPRT)) {
41834Speter 	    if ( opt( 's' ) ) {
42834Speter 		standard();
437951Speter 		error("Constant declarations should precede type, var and routine declarations");
44834Speter 	    } else {
457951Speter 		if ( !const_order ) {
467951Speter 		    const_order = TRUE;
477951Speter 		    warning();
487951Speter 		    error("Constant declarations should precede type, var and routine declarations");
497951Speter 		}
50834Speter 	    }
51834Speter 	}
52834Speter 	if (parts[ cbn ] & CPRT) {
53834Speter 	    if ( opt( 's' ) ) {
54834Speter 		standard();
557951Speter 		error("All constants should be declared in one const part");
56834Speter 	    } else {
577951Speter 		if ( !const_seen ) {
587951Speter 		    const_seen = TRUE;
597951Speter 		    warning();
607951Speter 		    error("All constants should be declared in one const part");
617951Speter 		}
62834Speter 	    }
63834Speter 	}
64834Speter 	parts[ cbn ] |= CPRT;
65748Speter }
66748Speter #endif PI1
67748Speter 
constant(cline,cid,cdecl)6833234Sbostic constant(cline, cid, cdecl)
69748Speter 	int cline;
70748Speter 	register char *cid;
7118345Smckusick 	register struct tnode *cdecl;
72748Speter {
73748Speter 	register struct nl *np;
74748Speter 
75748Speter #ifdef PI0
76748Speter 	send(REVCNST, cline, cid, cdecl);
77748Speter #endif
78748Speter 	line = cline;
79748Speter 	gconst(cdecl);
80748Speter 	np = enter(defnl(cid, CONST, con.ctype, con.cival));
81748Speter #ifndef PI0
82748Speter 	np->nl_flags |= NMOD;
83748Speter #endif
84748Speter 
85748Speter #ifdef PC
86825Speter 	if (cbn == 1) {
87840Speter 	    stabgconst( cid , line );
88825Speter 	}
89748Speter #endif PC
90748Speter 
91748Speter #	ifdef PTREE
92748Speter 	    {
93748Speter 		pPointer	Const = ConstDecl( cid , cdecl );
94748Speter 		pPointer	*Consts;
95748Speter 
96748Speter 		pSeize( PorFHeader[ nesting ] );
97748Speter 		Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts );
98748Speter 		*Consts = ListAppend( *Consts , Const );
99748Speter 		pRelease( PorFHeader[ nesting ] );
100748Speter 	    }
101748Speter #	endif
102748Speter 	if (con.ctype == NIL)
103748Speter 		return;
104748Speter 	if ( con.ctype == nl + TSTR )
10518345Smckusick 		np->ptr[0] = (struct nl *) con.cpval;
106748Speter 	if (isa(con.ctype, "i"))
107748Speter 		np->range[0] = con.crval;
108748Speter 	else if (isa(con.ctype, "d"))
109748Speter 		np->real = con.crval;
11018344Smckusick #       ifdef PC
11118344Smckusick 	    if (cbn == 1 && con.ctype != NIL) {
11218344Smckusick 		    stabconst(np);
11318344Smckusick 	    }
11418344Smckusick #       endif
115748Speter }
116748Speter 
117748Speter #ifndef PI0
118748Speter #ifndef PI1
constend()119748Speter constend()
120748Speter {
121748Speter 
122748Speter }
123748Speter #endif
124748Speter #endif
125748Speter 
126748Speter /*
127748Speter  * Gconst extracts
128748Speter  * a constant declaration
129748Speter  * from the tree for it.
130748Speter  * only types of constants
131748Speter  * are integer, reals, strings
132748Speter  * and scalars, the first two
133748Speter  * being possibly signed.
134748Speter  */
13518345Smckusick gconst(c_node)
13618345Smckusick 	struct tnode *c_node;
137748Speter {
138748Speter 	register struct nl *np;
13918345Smckusick 	register struct tnode *cn;
140748Speter 	char *cp;
141748Speter 	int negd, sgnd;
142748Speter 	long ci;
143748Speter 
144748Speter 	con.ctype = NIL;
14518345Smckusick 	cn = c_node;
146748Speter 	negd = sgnd = 0;
147748Speter loop:
14818345Smckusick 	if (cn == TR_NIL || cn->sign_const.number == TR_NIL)
14918345Smckusick 		return;
15018345Smckusick 	switch (cn->tag) {
151748Speter 		default:
152748Speter 			panic("gconst");
153748Speter 		case T_MINUSC:
154748Speter 			negd = 1 - negd;
155748Speter 		case T_PLUSC:
156748Speter 			sgnd++;
15718345Smckusick 			cn = cn->sign_const.number;
158748Speter 			goto loop;
159748Speter 		case T_ID:
16018345Smckusick 			np = lookup(cn->char_const.cptr);
16118345Smckusick 			if (np == NLNIL)
162748Speter 				return;
163748Speter 			if (np->class != CONST) {
16418345Smckusick 				derror("%s is a %s, not a constant as required", cn->char_const.cptr, classes[np->class]);
165748Speter 				return;
166748Speter 			}
167748Speter 			con.ctype = np->type;
168748Speter 			switch (classify(np->type)) {
169748Speter 				case TINT:
170748Speter 					con.crval = np->range[0];
171748Speter 					break;
172748Speter 				case TDOUBLE:
173748Speter 					con.crval = np->real;
174748Speter 					break;
175748Speter 				case TBOOL:
176748Speter 				case TCHAR:
177748Speter 				case TSCAL:
178748Speter 					con.cival = np->value[0];
179748Speter 					con.crval = con.cival;
180748Speter 					break;
181748Speter 				case TSTR:
18218345Smckusick 					con.cpval = (char *) np->ptr[0];
183748Speter 					break;
184748Speter 				case NIL:
185748Speter 					con.ctype = NIL;
186748Speter 					return;
187748Speter 				default:
188748Speter 					panic("gconst2");
189748Speter 			}
190748Speter 			break;
191748Speter 		case T_CBINT:
19218345Smckusick 			con.crval = a8tol(cn->char_const.cptr);
193748Speter 			goto restcon;
194748Speter 		case T_CINT:
19518345Smckusick 			con.crval = atof(cn->char_const.cptr);
196748Speter 			if (con.crval > MAXINT || con.crval < MININT) {
197748Speter 				derror("Constant too large for this implementation");
198748Speter 				con.crval = 0;
199748Speter 			}
200748Speter restcon:
201748Speter 			ci = con.crval;
202748Speter #ifndef PI0
203748Speter 			if (bytes(ci, ci) <= 2)
204748Speter 				con.ctype = nl+T2INT;
205748Speter 			else
206748Speter #endif
207748Speter 				con.ctype = nl+T4INT;
208748Speter 			break;
209748Speter 		case T_CFINT:
210748Speter 			con.ctype = nl+TDOUBLE;
21118345Smckusick 			con.crval = atof(cn->char_const.cptr);
212748Speter 			break;
213748Speter 		case T_CSTRNG:
21418345Smckusick 			cp = cn->char_const.cptr;
215748Speter 			if (cp[1] == 0) {
216748Speter 				con.ctype = nl+T1CHAR;
217748Speter 				con.cival = cp[0];
218748Speter 				con.crval = con.cival;
219748Speter 				break;
220748Speter 			}
221748Speter 			con.ctype = nl+TSTR;
222748Speter 			con.cpval = savestr(cp);
223748Speter 			break;
224748Speter 	}
225748Speter 	if (sgnd) {
22618345Smckusick 		if (isnta((struct nl *) con.ctype, "id"))
22718345Smckusick 			derror("%s constants cannot be signed",
22818345Smckusick 				nameof((struct nl *) con.ctype));
229748Speter 		else {
230748Speter 			if (negd)
231748Speter 				con.crval = -con.crval;
232748Speter 			ci = con.crval;
233748Speter 		}
234748Speter 	}
235748Speter }
236748Speter 
237748Speter #ifndef PI0
isconst(cn)23818345Smckusick isconst(cn)
23918345Smckusick 	register struct tnode *cn;
240748Speter {
241748Speter 
24218345Smckusick 	if (cn == TR_NIL)
243748Speter 		return (1);
24418345Smckusick 	switch (cn->tag) {
245748Speter 		case T_MINUS:
24618345Smckusick 			cn->tag = T_MINUSC;
24718345Smckusick 			cn->sign_const.number =
24818345Smckusick 					 cn->un_expr.expr;
24918345Smckusick 			return (isconst(cn->sign_const.number));
250748Speter 		case T_PLUS:
25118345Smckusick 			cn->tag = T_PLUSC;
25218345Smckusick 			cn->sign_const.number =
25318345Smckusick 					 cn->un_expr.expr;
25418345Smckusick 			return (isconst(cn->sign_const.number));
255748Speter 		case T_VAR:
25618345Smckusick 			if (cn->var_node.qual != TR_NIL)
257748Speter 				return (0);
25818345Smckusick 			cn->tag = T_ID;
25918345Smckusick 			cn->char_const.cptr =
26018345Smckusick 					cn->var_node.cptr;
261748Speter 			return (1);
262748Speter 		case T_BINT:
26318345Smckusick 			cn->tag = T_CBINT;
26418345Smckusick 			cn->char_const.cptr =
26518345Smckusick 				cn->const_node.cptr;
266748Speter 			return (1);
267748Speter 		case T_INT:
26818345Smckusick 			cn->tag = T_CINT;
26918345Smckusick 			cn->char_const.cptr =
27018345Smckusick 				cn->const_node.cptr;
271748Speter 			return (1);
272748Speter 		case T_FINT:
27318345Smckusick 			cn->tag = T_CFINT;
27418345Smckusick 			cn->char_const.cptr =
27518345Smckusick 				cn->const_node.cptr;
276748Speter 			return (1);
277748Speter 		case T_STRNG:
27818345Smckusick 			cn->tag = T_CSTRNG;
27918345Smckusick 			cn->char_const.cptr =
28018345Smckusick 				cn->const_node.cptr;
281748Speter 			return (1);
282748Speter 	}
283748Speter 	return (0);
284748Speter }
285748Speter #endif
286