xref: /csrg-svn/usr.bin/pascal/src/clas.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%
622078Sdist  */
722078Sdist 
822078Sdist #ifndef lint
9*62205Sbostic static char sccsid[] = "@(#)clas.c	8.1 (Berkeley) 06/06/93";
1048116Sbostic #endif /* not lint */
1148116Sbostic 
12747Speter #include "whoami.h"
13747Speter #include "0.h"
14747Speter #include "tree.h"
1514728Sthien #include "tree_ty.h"
16747Speter 
17747Speter /*
18747Speter  * This is the array of class
19747Speter  * names for the classes returned
20747Speter  * by classify.  The order of the
21747Speter  * classes is the same as the base
22747Speter  * of the namelist, with special
23747Speter  * negative index entries for structures,
24747Speter  * scalars, pointers, sets and strings
25747Speter  * to be collapsed into.
26747Speter  */
27747Speter char	*clnxxxx[] =
28747Speter {
29747Speter 	"file",			/* -7	TFILE */
30747Speter 	"record",		/* -6	TREC */
31747Speter 	"array",		/* -5	TARY */
32747Speter 	"scalar",		/* -4	TSCAL */
33747Speter 	"pointer",		/* -3	TPTR */
34747Speter 	"set",			/* -2	TSET */
35747Speter 	"string",		/* -1	TSTR */
36747Speter 	"SNARK",		/*  0	NIL */
37747Speter 	"Boolean",		/*  1	TBOOL */
38747Speter 	"char",			/*  2	TCHAR */
39747Speter 	"integer",		/*  3	TINT */
40747Speter 	"real",			/*  4	TREAL */
41747Speter 	"\"nil\"",		/*  5	TNIL */
42747Speter };
43747Speter 
44747Speter char **clnames	= &clnxxxx[-(TFIRST)];
45747Speter 
46747Speter /*
47747Speter  * Classify takes a pointer
48747Speter  * to a type and returns one
49747Speter  * of several interesting group
50747Speter  * classifications for easy use.
51747Speter  */
52747Speter classify(p1)
53747Speter 	struct nl *p1;
54747Speter {
55747Speter 	register struct nl *p;
56747Speter 
57747Speter 	p = p1;
58747Speter swit:
5914728Sthien 	if (p == NLNIL) {
60747Speter 		nocascade();
61747Speter 		return (NIL);
62747Speter 	}
63747Speter 	if (p == &nl[TSTR])
64747Speter 		return (TSTR);
65747Speter 	if ( p == &nl[ TSET ] ) {
66747Speter 	    return TSET;
67747Speter 	}
68747Speter 	switch (p->class) {
69747Speter 		case PTR:
70747Speter 			return (TPTR);
71747Speter 		case ARRAY:
72747Speter 			if (p->type == nl+T1CHAR)
73747Speter 				return (TSTR);
74747Speter 			return (TARY);
75747Speter 		case STR:
76747Speter 			return (TSTR);
77747Speter 		case SET:
78747Speter 			return (TSET);
7915975Smckusick 		case CRANGE:
80747Speter 		case RANGE:
81747Speter 			p = p->type;
82747Speter 			goto swit;
83747Speter 		case TYPE:
84747Speter 			if (p <= nl+TLAST)
85747Speter 				return (p - nl);
86747Speter 			panic("clas2");
87747Speter 		case FILET:
88747Speter 			return (TFILE);
89747Speter 		case RECORD:
90747Speter 			return (TREC);
91747Speter 		case SCAL:
92747Speter 			return (TSCAL);
93747Speter 		default:
9414728Sthien 			{
9514728Sthien 			    panic("clas");
9614728Sthien 			    return(NIL);
9714728Sthien 			}
98747Speter 	}
99747Speter }
100747Speter 
101747Speter #ifndef	PI0
102747Speter /*
103747Speter  * Is p a text file?
104747Speter  */
105747Speter text(p)
106747Speter 	struct nl *p;
107747Speter {
108747Speter 
109747Speter 	return (p != NIL && p->class == FILET && p->type == nl+T1CHAR);
110747Speter }
111747Speter #endif
112747Speter 
113747Speter /*
114747Speter  * Scalar returns a pointer to
115747Speter  * the the base scalar type of
116747Speter  * its argument if its argument
117747Speter  * is a SCALar else NIL.
118747Speter  */
11914728Sthien struct nl *
scalar(p1)120747Speter scalar(p1)
121747Speter 	struct nl *p1;
122747Speter {
123747Speter 	register struct nl *p;
124747Speter 
125747Speter 	p = p1;
12614728Sthien 	if (p == NLNIL)
12714728Sthien 		return (NLNIL);
12815975Smckusick 	if (p->class == RANGE || p->class == CRANGE)
129747Speter 		p = p->type;
13014728Sthien 	if (p == NLNIL)
13114728Sthien 		return (NLNIL);
13214728Sthien 	return (p->class == SCAL ? p : NLNIL);
133747Speter }
134747Speter 
135747Speter /*
136747Speter  * Isa tells whether p
137747Speter  * is one of a group of
138747Speter  * namelist classes.  The
139747Speter  * classes wanted are specified
140747Speter  * by the characters in s.
141747Speter  * (Note that s would more efficiently,
142747Speter  * if less clearly, be given by a mask.)
143747Speter  */
isa(p,s)144747Speter isa(p, s)
145747Speter 	register struct nl *p;
146747Speter 	char *s;
147747Speter {
148747Speter 	register i;
149747Speter 	register char *cp;
150747Speter 
151747Speter 	if (p == NIL)
152747Speter 		return (NIL);
153747Speter 	/*
154747Speter 	 * map ranges down to
155747Speter 	 * the base type
156747Speter 	 */
15715975Smckusick 	if (p->class == RANGE) {
158747Speter 		p = p->type;
15915975Smckusick 	}
160747Speter 	/*
161747Speter 	 * the following character/class
162747Speter 	 * associations are made:
163747Speter 	 *
164747Speter 	 *	s	scalar
165747Speter 	 *	b	Boolean
166747Speter 	 *	c	character
167747Speter 	 *	i	integer
168747Speter 	 *	d	double (real)
169747Speter 	 *	t	set
170747Speter 	 */
171747Speter 	switch (p->class) {
172747Speter 		case SET:
173747Speter 			i = TDOUBLE+1;
174747Speter 			break;
175747Speter 		case SCAL:
176747Speter 			i = 0;
177747Speter 			break;
17815975Smckusick 		case CRANGE:
17915975Smckusick 			/*
18015975Smckusick 			 * find the base type of a conformant array range
18115975Smckusick 			 */
18215975Smckusick 			switch (classify(p->type)) {
18315975Smckusick 				case TBOOL: i = 1; break;
18415975Smckusick 				case TCHAR: i = 2; break;
18515975Smckusick 				case TINT: i = 3; break;
18615975Smckusick 				case TSCAL: i = 0; break;
18715975Smckusick 				default:
18815975Smckusick 					panic( "isa" );
18915975Smckusick 			}
19015975Smckusick 			break;
191747Speter 		default:
192747Speter 			i = p - nl;
193747Speter 	}
194747Speter 	if (i >= 0 && i <= TDOUBLE+1) {
195747Speter 		i = "sbcidt"[i];
196747Speter 		cp = s;
197747Speter 		while (*cp)
198747Speter 			if (*cp++ == i)
199747Speter 				return (1);
200747Speter 	}
201747Speter 	return (NIL);
202747Speter }
203747Speter 
204747Speter /*
205747Speter  * Isnta is !isa
206747Speter  */
207747Speter isnta(p, s)
20814728Sthien     struct nl *p;
20914728Sthien     char *s;
210747Speter {
211747Speter 
212747Speter 	return (!isa(p, s));
213747Speter }
214747Speter 
215747Speter /*
216747Speter  * "shorthand"
217747Speter  */
21814728Sthien char *
nameof(p)219747Speter nameof(p)
22014728Sthien struct nl *p;
221747Speter {
222747Speter 
223747Speter 	return (clnames[classify(p)]);
224747Speter }
225747Speter 
226747Speter #ifndef PI0
22714728Sthien /* find out for sure what kind of node this is being passed
22814728Sthien    possibly several different kinds of node are passed to it */
nowexp(r)22914728Sthien int nowexp(r)
23014728Sthien 	struct tnode *r;
231747Speter {
23214728Sthien 	if (r->tag == T_WEXP) {
23314728Sthien 		if (r->var_node.cptr == NIL)
234747Speter 			error("Oct/hex allowed only on writeln/write calls");
235747Speter 		else
236747Speter 			error("Width expressions allowed only in writeln/write calls");
237747Speter 		return (1);
238747Speter 	}
239747Speter 	return (NIL);
240747Speter }
241747Speter #endif
2423276Smckusic 
2433276Smckusic     /*
2443825Speter      *	is a variable a local, a formal parameter, or a global?
2453276Smckusic      *	all this from just the offset:
2463825Speter      *	    globals are at levels 0 or 1
2473276Smckusic      *	    positives are parameters
2483276Smckusic      *	    negative evens are locals
2493276Smckusic      */
25014728Sthien /*ARGSUSED*/
whereis(offset,other_flags)25114728Sthien whereis( offset , other_flags )
2523825Speter     int		offset;
2537920Smckusick     char	other_flags;
2543276Smckusic {
2553276Smckusic 
2563825Speter #   ifdef OBJ
2573825Speter 	return ( offset >= 0 ? PARAMVAR : LOCALVAR );
2583825Speter #   endif OBJ
2593825Speter #   ifdef PC
2609127Smckusick 	switch ( other_flags & ( NGLOBAL | NPARAM | NLOCAL | NNLOCAL) ) {
26114728Sthien 	    default:
26214728Sthien 		panic( "whereis" );
2633825Speter 	    case NGLOBAL:
2643825Speter 		return GLOBALVAR;
2653825Speter 	    case NPARAM:
2663825Speter 		return PARAMVAR;
2679127Smckusick 	    case NNLOCAL:
2689127Smckusick 		return NAMEDLOCALVAR;
2693825Speter 	    case NLOCAL:
2703825Speter 		return LOCALVAR;
2713825Speter 	}
2723825Speter #   endif PC
2733276Smckusic }
274