xref: /csrg-svn/usr.bin/pascal/src/const.c (revision 33234)
122158Sdist /*
222158Sdist  * Copyright (c) 1980 Regents of the University of California.
322158Sdist  * All rights reserved.  The Berkeley software License Agreement
422158Sdist  * specifies the terms and conditions for redistribution.
522158Sdist  */
6748Speter 
718345Smckusick #ifndef lint
8*33234Sbostic static char sccsid[] = "@(#)const.c	5.4 (Berkeley) 01/03/88";
922158Sdist #endif not lint
10748Speter 
11748Speter #include "whoami.h"
12748Speter #include "0.h"
13748Speter #include "tree.h"
1418345Smckusick #include "tree_ty.h"
15748Speter 
16748Speter /*
17748Speter  * Const enters the definitions
18748Speter  * of the constant declaration
19748Speter  * part into the namelist.
20748Speter  */
21748Speter #ifndef PI1
2232287Smckusick constbeg( lineofyconst , linenum )
2332287Smckusick     int	lineofyconst, linenum;
24748Speter {
257951Speter     static bool	const_order = FALSE;
267951Speter     static bool	const_seen = FALSE;
27748Speter 
28748Speter /*
29834Speter  * this allows for multiple declaration
30748Speter  * parts, unless the "standard" option
31748Speter  * has been specified.
32748Speter  * If a routine segment is being compiled,
33748Speter  * do level one processing.
34748Speter  */
35748Speter 
36748Speter 	if (!progseen)
37748Speter 		level1();
387951Speter 	line = lineofyconst;
39834Speter 	if (parts[ cbn ] & (TPRT|VPRT|RPRT)) {
40834Speter 	    if ( opt( 's' ) ) {
41834Speter 		standard();
427951Speter 		error("Constant declarations should precede type, var and routine declarations");
43834Speter 	    } else {
447951Speter 		if ( !const_order ) {
457951Speter 		    const_order = TRUE;
467951Speter 		    warning();
477951Speter 		    error("Constant declarations should precede type, var and routine declarations");
487951Speter 		}
49834Speter 	    }
50834Speter 	}
51834Speter 	if (parts[ cbn ] & CPRT) {
52834Speter 	    if ( opt( 's' ) ) {
53834Speter 		standard();
547951Speter 		error("All constants should be declared in one const part");
55834Speter 	    } else {
567951Speter 		if ( !const_seen ) {
577951Speter 		    const_seen = TRUE;
587951Speter 		    warning();
597951Speter 		    error("All constants should be declared in one const part");
607951Speter 		}
61834Speter 	    }
62834Speter 	}
63834Speter 	parts[ cbn ] |= CPRT;
64748Speter }
65748Speter #endif PI1
66748Speter 
67*33234Sbostic constant(cline, cid, cdecl)
68748Speter 	int cline;
69748Speter 	register char *cid;
7018345Smckusick 	register struct tnode *cdecl;
71748Speter {
72748Speter 	register struct nl *np;
73748Speter 
74748Speter #ifdef PI0
75748Speter 	send(REVCNST, cline, cid, cdecl);
76748Speter #endif
77748Speter 	line = cline;
78748Speter 	gconst(cdecl);
79748Speter 	np = enter(defnl(cid, CONST, con.ctype, con.cival));
80748Speter #ifndef PI0
81748Speter 	np->nl_flags |= NMOD;
82748Speter #endif
83748Speter 
84748Speter #ifdef PC
85825Speter 	if (cbn == 1) {
86840Speter 	    stabgconst( cid , line );
87825Speter 	}
88748Speter #endif PC
89748Speter 
90748Speter #	ifdef PTREE
91748Speter 	    {
92748Speter 		pPointer	Const = ConstDecl( cid , cdecl );
93748Speter 		pPointer	*Consts;
94748Speter 
95748Speter 		pSeize( PorFHeader[ nesting ] );
96748Speter 		Consts = &( pDEF( PorFHeader[ nesting ] ).PorFConsts );
97748Speter 		*Consts = ListAppend( *Consts , Const );
98748Speter 		pRelease( PorFHeader[ nesting ] );
99748Speter 	    }
100748Speter #	endif
101748Speter 	if (con.ctype == NIL)
102748Speter 		return;
103748Speter 	if ( con.ctype == nl + TSTR )
10418345Smckusick 		np->ptr[0] = (struct nl *) con.cpval;
105748Speter 	if (isa(con.ctype, "i"))
106748Speter 		np->range[0] = con.crval;
107748Speter 	else if (isa(con.ctype, "d"))
108748Speter 		np->real = con.crval;
10918344Smckusick #       ifdef PC
11018344Smckusick 	    if (cbn == 1 && con.ctype != NIL) {
11118344Smckusick 		    stabconst(np);
11218344Smckusick 	    }
11318344Smckusick #       endif
114748Speter }
115748Speter 
116748Speter #ifndef PI0
117748Speter #ifndef PI1
118748Speter constend()
119748Speter {
120748Speter 
121748Speter }
122748Speter #endif
123748Speter #endif
124748Speter 
125748Speter /*
126748Speter  * Gconst extracts
127748Speter  * a constant declaration
128748Speter  * from the tree for it.
129748Speter  * only types of constants
130748Speter  * are integer, reals, strings
131748Speter  * and scalars, the first two
132748Speter  * being possibly signed.
133748Speter  */
13418345Smckusick gconst(c_node)
13518345Smckusick 	struct tnode *c_node;
136748Speter {
137748Speter 	register struct nl *np;
13818345Smckusick 	register struct tnode *cn;
139748Speter 	char *cp;
140748Speter 	int negd, sgnd;
141748Speter 	long ci;
142748Speter 
143748Speter 	con.ctype = NIL;
14418345Smckusick 	cn = c_node;
145748Speter 	negd = sgnd = 0;
146748Speter loop:
14718345Smckusick 	if (cn == TR_NIL || cn->sign_const.number == TR_NIL)
14818345Smckusick 		return;
14918345Smckusick 	switch (cn->tag) {
150748Speter 		default:
151748Speter 			panic("gconst");
152748Speter 		case T_MINUSC:
153748Speter 			negd = 1 - negd;
154748Speter 		case T_PLUSC:
155748Speter 			sgnd++;
15618345Smckusick 			cn = cn->sign_const.number;
157748Speter 			goto loop;
158748Speter 		case T_ID:
15918345Smckusick 			np = lookup(cn->char_const.cptr);
16018345Smckusick 			if (np == NLNIL)
161748Speter 				return;
162748Speter 			if (np->class != CONST) {
16318345Smckusick 				derror("%s is a %s, not a constant as required", cn->char_const.cptr, classes[np->class]);
164748Speter 				return;
165748Speter 			}
166748Speter 			con.ctype = np->type;
167748Speter 			switch (classify(np->type)) {
168748Speter 				case TINT:
169748Speter 					con.crval = np->range[0];
170748Speter 					break;
171748Speter 				case TDOUBLE:
172748Speter 					con.crval = np->real;
173748Speter 					break;
174748Speter 				case TBOOL:
175748Speter 				case TCHAR:
176748Speter 				case TSCAL:
177748Speter 					con.cival = np->value[0];
178748Speter 					con.crval = con.cival;
179748Speter 					break;
180748Speter 				case TSTR:
18118345Smckusick 					con.cpval = (char *) np->ptr[0];
182748Speter 					break;
183748Speter 				case NIL:
184748Speter 					con.ctype = NIL;
185748Speter 					return;
186748Speter 				default:
187748Speter 					panic("gconst2");
188748Speter 			}
189748Speter 			break;
190748Speter 		case T_CBINT:
19118345Smckusick 			con.crval = a8tol(cn->char_const.cptr);
192748Speter 			goto restcon;
193748Speter 		case T_CINT:
19418345Smckusick 			con.crval = atof(cn->char_const.cptr);
195748Speter 			if (con.crval > MAXINT || con.crval < MININT) {
196748Speter 				derror("Constant too large for this implementation");
197748Speter 				con.crval = 0;
198748Speter 			}
199748Speter restcon:
200748Speter 			ci = con.crval;
201748Speter #ifndef PI0
202748Speter 			if (bytes(ci, ci) <= 2)
203748Speter 				con.ctype = nl+T2INT;
204748Speter 			else
205748Speter #endif
206748Speter 				con.ctype = nl+T4INT;
207748Speter 			break;
208748Speter 		case T_CFINT:
209748Speter 			con.ctype = nl+TDOUBLE;
21018345Smckusick 			con.crval = atof(cn->char_const.cptr);
211748Speter 			break;
212748Speter 		case T_CSTRNG:
21318345Smckusick 			cp = cn->char_const.cptr;
214748Speter 			if (cp[1] == 0) {
215748Speter 				con.ctype = nl+T1CHAR;
216748Speter 				con.cival = cp[0];
217748Speter 				con.crval = con.cival;
218748Speter 				break;
219748Speter 			}
220748Speter 			con.ctype = nl+TSTR;
221748Speter 			con.cpval = savestr(cp);
222748Speter 			break;
223748Speter 	}
224748Speter 	if (sgnd) {
22518345Smckusick 		if (isnta((struct nl *) con.ctype, "id"))
22618345Smckusick 			derror("%s constants cannot be signed",
22718345Smckusick 				nameof((struct nl *) con.ctype));
228748Speter 		else {
229748Speter 			if (negd)
230748Speter 				con.crval = -con.crval;
231748Speter 			ci = con.crval;
232748Speter 		}
233748Speter 	}
234748Speter }
235748Speter 
236748Speter #ifndef PI0
23718345Smckusick isconst(cn)
23818345Smckusick 	register struct tnode *cn;
239748Speter {
240748Speter 
24118345Smckusick 	if (cn == TR_NIL)
242748Speter 		return (1);
24318345Smckusick 	switch (cn->tag) {
244748Speter 		case T_MINUS:
24518345Smckusick 			cn->tag = T_MINUSC;
24618345Smckusick 			cn->sign_const.number =
24718345Smckusick 					 cn->un_expr.expr;
24818345Smckusick 			return (isconst(cn->sign_const.number));
249748Speter 		case T_PLUS:
25018345Smckusick 			cn->tag = T_PLUSC;
25118345Smckusick 			cn->sign_const.number =
25218345Smckusick 					 cn->un_expr.expr;
25318345Smckusick 			return (isconst(cn->sign_const.number));
254748Speter 		case T_VAR:
25518345Smckusick 			if (cn->var_node.qual != TR_NIL)
256748Speter 				return (0);
25718345Smckusick 			cn->tag = T_ID;
25818345Smckusick 			cn->char_const.cptr =
25918345Smckusick 					cn->var_node.cptr;
260748Speter 			return (1);
261748Speter 		case T_BINT:
26218345Smckusick 			cn->tag = T_CBINT;
26318345Smckusick 			cn->char_const.cptr =
26418345Smckusick 				cn->const_node.cptr;
265748Speter 			return (1);
266748Speter 		case T_INT:
26718345Smckusick 			cn->tag = T_CINT;
26818345Smckusick 			cn->char_const.cptr =
26918345Smckusick 				cn->const_node.cptr;
270748Speter 			return (1);
271748Speter 		case T_FINT:
27218345Smckusick 			cn->tag = T_CFINT;
27318345Smckusick 			cn->char_const.cptr =
27418345Smckusick 				cn->const_node.cptr;
275748Speter 			return (1);
276748Speter 		case T_STRNG:
27718345Smckusick 			cn->tag = T_CSTRNG;
27818345Smckusick 			cn->char_const.cptr =
27918345Smckusick 				cn->const_node.cptr;
280748Speter 			return (1);
281748Speter 	}
282748Speter 	return (0);
283748Speter }
284748Speter #endif
285