xref: /csrg-svn/usr.bin/pascal/src/clas.c (revision 3825)
1747Speter /* Copyright (c) 1979 Regents of the University of California */
2747Speter 
3*3825Speter static	char sccsid[] = "@(#)clas.c 1.4 06/01/81";
4747Speter 
5747Speter #include "whoami.h"
6747Speter #include "0.h"
7747Speter #include "tree.h"
8747Speter 
9747Speter /*
10747Speter  * This is the array of class
11747Speter  * names for the classes returned
12747Speter  * by classify.  The order of the
13747Speter  * classes is the same as the base
14747Speter  * of the namelist, with special
15747Speter  * negative index entries for structures,
16747Speter  * scalars, pointers, sets and strings
17747Speter  * to be collapsed into.
18747Speter  */
19747Speter char	*clnxxxx[] =
20747Speter {
21747Speter 	"file",			/* -7	TFILE */
22747Speter 	"record",		/* -6	TREC */
23747Speter 	"array",		/* -5	TARY */
24747Speter 	"scalar",		/* -4	TSCAL */
25747Speter 	"pointer",		/* -3	TPTR */
26747Speter 	"set",			/* -2	TSET */
27747Speter 	"string",		/* -1	TSTR */
28747Speter 	"SNARK",		/*  0	NIL */
29747Speter 	"Boolean",		/*  1	TBOOL */
30747Speter 	"char",			/*  2	TCHAR */
31747Speter 	"integer",		/*  3	TINT */
32747Speter 	"real",			/*  4	TREAL */
33747Speter 	"\"nil\"",		/*  5	TNIL */
34747Speter };
35747Speter 
36747Speter char **clnames	= &clnxxxx[-(TFIRST)];
37747Speter 
38747Speter /*
39747Speter  * Classify takes a pointer
40747Speter  * to a type and returns one
41747Speter  * of several interesting group
42747Speter  * classifications for easy use.
43747Speter  */
44747Speter classify(p1)
45747Speter 	struct nl *p1;
46747Speter {
47747Speter 	register struct nl *p;
48747Speter 
49747Speter 	p = p1;
50747Speter swit:
51747Speter 	if (p == NIL) {
52747Speter 		nocascade();
53747Speter 		return (NIL);
54747Speter 	}
55747Speter 	if (p == &nl[TSTR])
56747Speter 		return (TSTR);
57747Speter 	if ( p == &nl[ TSET ] ) {
58747Speter 	    return TSET;
59747Speter 	}
60747Speter 	switch (p->class) {
61747Speter 		case PTR:
62747Speter 			return (TPTR);
63747Speter 		case ARRAY:
64747Speter 			if (p->type == nl+T1CHAR)
65747Speter 				return (TSTR);
66747Speter 			return (TARY);
67747Speter 		case STR:
68747Speter 			return (TSTR);
69747Speter 		case SET:
70747Speter 			return (TSET);
71747Speter 		case RANGE:
72747Speter 			p = p->type;
73747Speter 			goto swit;
74747Speter 		case TYPE:
75747Speter 			if (p <= nl+TLAST)
76747Speter 				return (p - nl);
77747Speter 			panic("clas2");
78747Speter 		case FILET:
79747Speter 			return (TFILE);
80747Speter 		case RECORD:
81747Speter 			return (TREC);
82747Speter 		case SCAL:
83747Speter 			return (TSCAL);
84747Speter 		default:
85747Speter 			panic("clas");
86747Speter 	}
87747Speter }
88747Speter 
89747Speter #ifndef	PI0
90747Speter /*
91747Speter  * Is p a text file?
92747Speter  */
93747Speter text(p)
94747Speter 	struct nl *p;
95747Speter {
96747Speter 
97747Speter 	return (p != NIL && p->class == FILET && p->type == nl+T1CHAR);
98747Speter }
99747Speter #endif
100747Speter 
101747Speter /*
102747Speter  * Scalar returns a pointer to
103747Speter  * the the base scalar type of
104747Speter  * its argument if its argument
105747Speter  * is a SCALar else NIL.
106747Speter  */
107747Speter scalar(p1)
108747Speter 	struct nl *p1;
109747Speter {
110747Speter 	register struct nl *p;
111747Speter 
112747Speter 	p = p1;
113747Speter 	if (p == NIL)
114747Speter 		return (NIL);
115747Speter 	if (p->class == RANGE)
116747Speter 		p = p->type;
117747Speter 	if (p == NIL)
118747Speter 		return (NIL);
119747Speter 	return (p->class == SCAL ? p : NIL);
120747Speter }
121747Speter 
122747Speter /*
123747Speter  * Isa tells whether p
124747Speter  * is one of a group of
125747Speter  * namelist classes.  The
126747Speter  * classes wanted are specified
127747Speter  * by the characters in s.
128747Speter  * (Note that s would more efficiently,
129747Speter  * if less clearly, be given by a mask.)
130747Speter  */
131747Speter isa(p, s)
132747Speter 	register struct nl *p;
133747Speter 	char *s;
134747Speter {
135747Speter 	register i;
136747Speter 	register char *cp;
137747Speter 
138747Speter 	if (p == NIL)
139747Speter 		return (NIL);
140747Speter 	/*
141747Speter 	 * map ranges down to
142747Speter 	 * the base type
143747Speter 	 */
144747Speter 	if (p->class == RANGE)
145747Speter 		p = p->type;
146747Speter 	/*
147747Speter 	 * the following character/class
148747Speter 	 * associations are made:
149747Speter 	 *
150747Speter 	 *	s	scalar
151747Speter 	 *	b	Boolean
152747Speter 	 *	c	character
153747Speter 	 *	i	integer
154747Speter 	 *	d	double (real)
155747Speter 	 *	t	set
156747Speter 	 */
157747Speter 	switch (p->class) {
158747Speter 		case SET:
159747Speter 			i = TDOUBLE+1;
160747Speter 			break;
161747Speter 		case SCAL:
162747Speter 			i = 0;
163747Speter 			break;
164747Speter 		default:
165747Speter 			i = p - nl;
166747Speter 	}
167747Speter 	if (i >= 0 && i <= TDOUBLE+1) {
168747Speter 		i = "sbcidt"[i];
169747Speter 		cp = s;
170747Speter 		while (*cp)
171747Speter 			if (*cp++ == i)
172747Speter 				return (1);
173747Speter 	}
174747Speter 	return (NIL);
175747Speter }
176747Speter 
177747Speter /*
178747Speter  * Isnta is !isa
179747Speter  */
180747Speter isnta(p, s)
181747Speter {
182747Speter 
183747Speter 	return (!isa(p, s));
184747Speter }
185747Speter 
186747Speter /*
187747Speter  * "shorthand"
188747Speter  */
189747Speter nameof(p)
190747Speter {
191747Speter 
192747Speter 	return (clnames[classify(p)]);
193747Speter }
194747Speter 
195747Speter #ifndef PI0
196747Speter nowexp(r)
197747Speter 	int *r;
198747Speter {
199747Speter 	if (r[0] == T_WEXP) {
200747Speter 		if (r[2] == NIL)
201747Speter 			error("Oct/hex allowed only on writeln/write calls");
202747Speter 		else
203747Speter 			error("Width expressions allowed only in writeln/write calls");
204747Speter 		return (1);
205747Speter 	}
206747Speter 	return (NIL);
207747Speter }
208747Speter #endif
2093276Smckusic 
2103276Smckusic     /*
211*3825Speter      *	is a variable a local, a formal parameter, or a global?
2123276Smckusic      *	all this from just the offset:
213*3825Speter      *	    globals are at levels 0 or 1
2143276Smckusic      *	    positives are parameters
2153276Smckusic      *	    negative evens are locals
2163276Smckusic      */
217*3825Speter whereis( level , offset , extra_flags )
218*3825Speter     int		level;
219*3825Speter     int		offset;
220*3825Speter     char	extra_flags;
2213276Smckusic {
2223276Smckusic 
223*3825Speter #   ifdef OBJ
224*3825Speter 	return ( offset >= 0 ? PARAMVAR : LOCALVAR );
225*3825Speter #   endif OBJ
226*3825Speter #   ifdef PC
227*3825Speter 	switch ( extra_flags & ( NGLOBAL | NPARAM | NLOCAL ) ) {
228*3825Speter 	    case NGLOBAL:
229*3825Speter 		return GLOBALVAR;
230*3825Speter 	    case NPARAM:
231*3825Speter 		return PARAMVAR;
232*3825Speter 	    case NLOCAL:
233*3825Speter 		return LOCALVAR;
234*3825Speter 	    default:
235*3825Speter 		panic( "whereis" );
236*3825Speter 	}
237*3825Speter #   endif PC
2383276Smckusic }
239