xref: /csrg-svn/usr.bin/pascal/src/clas.c (revision 15975)
1747Speter /* Copyright (c) 1979 Regents of the University of California */
2747Speter 
314728Sthien #ifndef lint
4*15975Smckusick static	char sccsid[] = "@(#)clas.c 1.8 02/08/84";
514728Sthien #endif
6747Speter 
7747Speter #include "whoami.h"
8747Speter #include "0.h"
9747Speter #include "tree.h"
1014728Sthien #include "tree_ty.h"
11747Speter 
12747Speter /*
13747Speter  * This is the array of class
14747Speter  * names for the classes returned
15747Speter  * by classify.  The order of the
16747Speter  * classes is the same as the base
17747Speter  * of the namelist, with special
18747Speter  * negative index entries for structures,
19747Speter  * scalars, pointers, sets and strings
20747Speter  * to be collapsed into.
21747Speter  */
22747Speter char	*clnxxxx[] =
23747Speter {
24747Speter 	"file",			/* -7	TFILE */
25747Speter 	"record",		/* -6	TREC */
26747Speter 	"array",		/* -5	TARY */
27747Speter 	"scalar",		/* -4	TSCAL */
28747Speter 	"pointer",		/* -3	TPTR */
29747Speter 	"set",			/* -2	TSET */
30747Speter 	"string",		/* -1	TSTR */
31747Speter 	"SNARK",		/*  0	NIL */
32747Speter 	"Boolean",		/*  1	TBOOL */
33747Speter 	"char",			/*  2	TCHAR */
34747Speter 	"integer",		/*  3	TINT */
35747Speter 	"real",			/*  4	TREAL */
36747Speter 	"\"nil\"",		/*  5	TNIL */
37747Speter };
38747Speter 
39747Speter char **clnames	= &clnxxxx[-(TFIRST)];
40747Speter 
41747Speter /*
42747Speter  * Classify takes a pointer
43747Speter  * to a type and returns one
44747Speter  * of several interesting group
45747Speter  * classifications for easy use.
46747Speter  */
47747Speter classify(p1)
48747Speter 	struct nl *p1;
49747Speter {
50747Speter 	register struct nl *p;
51747Speter 
52747Speter 	p = p1;
53747Speter swit:
5414728Sthien 	if (p == NLNIL) {
55747Speter 		nocascade();
56747Speter 		return (NIL);
57747Speter 	}
58747Speter 	if (p == &nl[TSTR])
59747Speter 		return (TSTR);
60747Speter 	if ( p == &nl[ TSET ] ) {
61747Speter 	    return TSET;
62747Speter 	}
63747Speter 	switch (p->class) {
64747Speter 		case PTR:
65747Speter 			return (TPTR);
66747Speter 		case ARRAY:
67747Speter 			if (p->type == nl+T1CHAR)
68747Speter 				return (TSTR);
69747Speter 			return (TARY);
70747Speter 		case STR:
71747Speter 			return (TSTR);
72747Speter 		case SET:
73747Speter 			return (TSET);
74*15975Smckusick 		case CRANGE:
75747Speter 		case RANGE:
76747Speter 			p = p->type;
77747Speter 			goto swit;
78747Speter 		case TYPE:
79747Speter 			if (p <= nl+TLAST)
80747Speter 				return (p - nl);
81747Speter 			panic("clas2");
82747Speter 		case FILET:
83747Speter 			return (TFILE);
84747Speter 		case RECORD:
85747Speter 			return (TREC);
86747Speter 		case SCAL:
87747Speter 			return (TSCAL);
88747Speter 		default:
8914728Sthien 			{
9014728Sthien 			    panic("clas");
9114728Sthien 			    return(NIL);
9214728Sthien 			}
93747Speter 	}
94747Speter }
95747Speter 
96747Speter #ifndef	PI0
97747Speter /*
98747Speter  * Is p a text file?
99747Speter  */
100747Speter text(p)
101747Speter 	struct nl *p;
102747Speter {
103747Speter 
104747Speter 	return (p != NIL && p->class == FILET && p->type == nl+T1CHAR);
105747Speter }
106747Speter #endif
107747Speter 
108747Speter /*
109747Speter  * Scalar returns a pointer to
110747Speter  * the the base scalar type of
111747Speter  * its argument if its argument
112747Speter  * is a SCALar else NIL.
113747Speter  */
11414728Sthien struct nl *
115747Speter scalar(p1)
116747Speter 	struct nl *p1;
117747Speter {
118747Speter 	register struct nl *p;
119747Speter 
120747Speter 	p = p1;
12114728Sthien 	if (p == NLNIL)
12214728Sthien 		return (NLNIL);
123*15975Smckusick 	if (p->class == RANGE || p->class == CRANGE)
124747Speter 		p = p->type;
12514728Sthien 	if (p == NLNIL)
12614728Sthien 		return (NLNIL);
12714728Sthien 	return (p->class == SCAL ? p : NLNIL);
128747Speter }
129747Speter 
130747Speter /*
131747Speter  * Isa tells whether p
132747Speter  * is one of a group of
133747Speter  * namelist classes.  The
134747Speter  * classes wanted are specified
135747Speter  * by the characters in s.
136747Speter  * (Note that s would more efficiently,
137747Speter  * if less clearly, be given by a mask.)
138747Speter  */
139747Speter isa(p, s)
140747Speter 	register struct nl *p;
141747Speter 	char *s;
142747Speter {
143747Speter 	register i;
144747Speter 	register char *cp;
145747Speter 
146747Speter 	if (p == NIL)
147747Speter 		return (NIL);
148747Speter 	/*
149747Speter 	 * map ranges down to
150747Speter 	 * the base type
151747Speter 	 */
152*15975Smckusick 	if (p->class == RANGE) {
153747Speter 		p = p->type;
154*15975Smckusick 	}
155747Speter 	/*
156747Speter 	 * the following character/class
157747Speter 	 * associations are made:
158747Speter 	 *
159747Speter 	 *	s	scalar
160747Speter 	 *	b	Boolean
161747Speter 	 *	c	character
162747Speter 	 *	i	integer
163747Speter 	 *	d	double (real)
164747Speter 	 *	t	set
165747Speter 	 */
166747Speter 	switch (p->class) {
167747Speter 		case SET:
168747Speter 			i = TDOUBLE+1;
169747Speter 			break;
170747Speter 		case SCAL:
171747Speter 			i = 0;
172747Speter 			break;
173*15975Smckusick 		case CRANGE:
174*15975Smckusick 			/*
175*15975Smckusick 			 * find the base type of a conformant array range
176*15975Smckusick 			 */
177*15975Smckusick 			switch (classify(p->type)) {
178*15975Smckusick 				case TBOOL: i = 1; break;
179*15975Smckusick 				case TCHAR: i = 2; break;
180*15975Smckusick 				case TINT: i = 3; break;
181*15975Smckusick 				case TSCAL: i = 0; break;
182*15975Smckusick 				default:
183*15975Smckusick 					panic( "isa" );
184*15975Smckusick 			}
185*15975Smckusick 			break;
186747Speter 		default:
187747Speter 			i = p - nl;
188747Speter 	}
189747Speter 	if (i >= 0 && i <= TDOUBLE+1) {
190747Speter 		i = "sbcidt"[i];
191747Speter 		cp = s;
192747Speter 		while (*cp)
193747Speter 			if (*cp++ == i)
194747Speter 				return (1);
195747Speter 	}
196747Speter 	return (NIL);
197747Speter }
198747Speter 
199747Speter /*
200747Speter  * Isnta is !isa
201747Speter  */
202747Speter isnta(p, s)
20314728Sthien     struct nl *p;
20414728Sthien     char *s;
205747Speter {
206747Speter 
207747Speter 	return (!isa(p, s));
208747Speter }
209747Speter 
210747Speter /*
211747Speter  * "shorthand"
212747Speter  */
21314728Sthien char *
214747Speter nameof(p)
21514728Sthien struct nl *p;
216747Speter {
217747Speter 
218747Speter 	return (clnames[classify(p)]);
219747Speter }
220747Speter 
221747Speter #ifndef PI0
22214728Sthien /* find out for sure what kind of node this is being passed
22314728Sthien    possibly several different kinds of node are passed to it */
22414728Sthien int nowexp(r)
22514728Sthien 	struct tnode *r;
226747Speter {
22714728Sthien 	if (r->tag == T_WEXP) {
22814728Sthien 		if (r->var_node.cptr == NIL)
229747Speter 			error("Oct/hex allowed only on writeln/write calls");
230747Speter 		else
231747Speter 			error("Width expressions allowed only in writeln/write calls");
232747Speter 		return (1);
233747Speter 	}
234747Speter 	return (NIL);
235747Speter }
236747Speter #endif
2373276Smckusic 
2383276Smckusic     /*
2393825Speter      *	is a variable a local, a formal parameter, or a global?
2403276Smckusic      *	all this from just the offset:
2413825Speter      *	    globals are at levels 0 or 1
2423276Smckusic      *	    positives are parameters
2433276Smckusic      *	    negative evens are locals
2443276Smckusic      */
24514728Sthien /*ARGSUSED*/
24614728Sthien whereis( offset , other_flags )
2473825Speter     int		offset;
2487920Smckusick     char	other_flags;
2493276Smckusic {
2503276Smckusic 
2513825Speter #   ifdef OBJ
2523825Speter 	return ( offset >= 0 ? PARAMVAR : LOCALVAR );
2533825Speter #   endif OBJ
2543825Speter #   ifdef PC
2559127Smckusick 	switch ( other_flags & ( NGLOBAL | NPARAM | NLOCAL | NNLOCAL) ) {
25614728Sthien 	    default:
25714728Sthien 		panic( "whereis" );
2583825Speter 	    case NGLOBAL:
2593825Speter 		return GLOBALVAR;
2603825Speter 	    case NPARAM:
2613825Speter 		return PARAMVAR;
2629127Smckusick 	    case NNLOCAL:
2639127Smckusick 		return NAMEDLOCALVAR;
2643825Speter 	    case NLOCAL:
2653825Speter 		return LOCALVAR;
2663825Speter 	}
2673825Speter #   endif PC
2683276Smckusic }
269