xref: /csrg-svn/usr.bin/pascal/src/clas.c (revision 22078)
1*22078Sdist /*
2*22078Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22078Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22078Sdist  * specifies the terms and conditions for redistribution.
5*22078Sdist  */
6*22078Sdist 
7*22078Sdist #ifndef lint
8*22078Sdist static char sccsid[] = "@(#)clas.c	5.1 (Berkeley) 06/05/85";
9*22078Sdist #endif not lint
10*22078Sdist 
11747Speter /* Copyright (c) 1979 Regents of the University of California */
12747Speter 
1314728Sthien #ifndef lint
14*22078Sdist static	char sccsid[] = "@(#)clas.c 5.1 06/05/85";
1514728Sthien #endif
16747Speter 
17747Speter #include "whoami.h"
18747Speter #include "0.h"
19747Speter #include "tree.h"
2014728Sthien #include "tree_ty.h"
21747Speter 
22747Speter /*
23747Speter  * This is the array of class
24747Speter  * names for the classes returned
25747Speter  * by classify.  The order of the
26747Speter  * classes is the same as the base
27747Speter  * of the namelist, with special
28747Speter  * negative index entries for structures,
29747Speter  * scalars, pointers, sets and strings
30747Speter  * to be collapsed into.
31747Speter  */
32747Speter char	*clnxxxx[] =
33747Speter {
34747Speter 	"file",			/* -7	TFILE */
35747Speter 	"record",		/* -6	TREC */
36747Speter 	"array",		/* -5	TARY */
37747Speter 	"scalar",		/* -4	TSCAL */
38747Speter 	"pointer",		/* -3	TPTR */
39747Speter 	"set",			/* -2	TSET */
40747Speter 	"string",		/* -1	TSTR */
41747Speter 	"SNARK",		/*  0	NIL */
42747Speter 	"Boolean",		/*  1	TBOOL */
43747Speter 	"char",			/*  2	TCHAR */
44747Speter 	"integer",		/*  3	TINT */
45747Speter 	"real",			/*  4	TREAL */
46747Speter 	"\"nil\"",		/*  5	TNIL */
47747Speter };
48747Speter 
49747Speter char **clnames	= &clnxxxx[-(TFIRST)];
50747Speter 
51747Speter /*
52747Speter  * Classify takes a pointer
53747Speter  * to a type and returns one
54747Speter  * of several interesting group
55747Speter  * classifications for easy use.
56747Speter  */
57747Speter classify(p1)
58747Speter 	struct nl *p1;
59747Speter {
60747Speter 	register struct nl *p;
61747Speter 
62747Speter 	p = p1;
63747Speter swit:
6414728Sthien 	if (p == NLNIL) {
65747Speter 		nocascade();
66747Speter 		return (NIL);
67747Speter 	}
68747Speter 	if (p == &nl[TSTR])
69747Speter 		return (TSTR);
70747Speter 	if ( p == &nl[ TSET ] ) {
71747Speter 	    return TSET;
72747Speter 	}
73747Speter 	switch (p->class) {
74747Speter 		case PTR:
75747Speter 			return (TPTR);
76747Speter 		case ARRAY:
77747Speter 			if (p->type == nl+T1CHAR)
78747Speter 				return (TSTR);
79747Speter 			return (TARY);
80747Speter 		case STR:
81747Speter 			return (TSTR);
82747Speter 		case SET:
83747Speter 			return (TSET);
8415975Smckusick 		case CRANGE:
85747Speter 		case RANGE:
86747Speter 			p = p->type;
87747Speter 			goto swit;
88747Speter 		case TYPE:
89747Speter 			if (p <= nl+TLAST)
90747Speter 				return (p - nl);
91747Speter 			panic("clas2");
92747Speter 		case FILET:
93747Speter 			return (TFILE);
94747Speter 		case RECORD:
95747Speter 			return (TREC);
96747Speter 		case SCAL:
97747Speter 			return (TSCAL);
98747Speter 		default:
9914728Sthien 			{
10014728Sthien 			    panic("clas");
10114728Sthien 			    return(NIL);
10214728Sthien 			}
103747Speter 	}
104747Speter }
105747Speter 
106747Speter #ifndef	PI0
107747Speter /*
108747Speter  * Is p a text file?
109747Speter  */
110747Speter text(p)
111747Speter 	struct nl *p;
112747Speter {
113747Speter 
114747Speter 	return (p != NIL && p->class == FILET && p->type == nl+T1CHAR);
115747Speter }
116747Speter #endif
117747Speter 
118747Speter /*
119747Speter  * Scalar returns a pointer to
120747Speter  * the the base scalar type of
121747Speter  * its argument if its argument
122747Speter  * is a SCALar else NIL.
123747Speter  */
12414728Sthien struct nl *
125747Speter scalar(p1)
126747Speter 	struct nl *p1;
127747Speter {
128747Speter 	register struct nl *p;
129747Speter 
130747Speter 	p = p1;
13114728Sthien 	if (p == NLNIL)
13214728Sthien 		return (NLNIL);
13315975Smckusick 	if (p->class == RANGE || p->class == CRANGE)
134747Speter 		p = p->type;
13514728Sthien 	if (p == NLNIL)
13614728Sthien 		return (NLNIL);
13714728Sthien 	return (p->class == SCAL ? p : NLNIL);
138747Speter }
139747Speter 
140747Speter /*
141747Speter  * Isa tells whether p
142747Speter  * is one of a group of
143747Speter  * namelist classes.  The
144747Speter  * classes wanted are specified
145747Speter  * by the characters in s.
146747Speter  * (Note that s would more efficiently,
147747Speter  * if less clearly, be given by a mask.)
148747Speter  */
149747Speter isa(p, s)
150747Speter 	register struct nl *p;
151747Speter 	char *s;
152747Speter {
153747Speter 	register i;
154747Speter 	register char *cp;
155747Speter 
156747Speter 	if (p == NIL)
157747Speter 		return (NIL);
158747Speter 	/*
159747Speter 	 * map ranges down to
160747Speter 	 * the base type
161747Speter 	 */
16215975Smckusick 	if (p->class == RANGE) {
163747Speter 		p = p->type;
16415975Smckusick 	}
165747Speter 	/*
166747Speter 	 * the following character/class
167747Speter 	 * associations are made:
168747Speter 	 *
169747Speter 	 *	s	scalar
170747Speter 	 *	b	Boolean
171747Speter 	 *	c	character
172747Speter 	 *	i	integer
173747Speter 	 *	d	double (real)
174747Speter 	 *	t	set
175747Speter 	 */
176747Speter 	switch (p->class) {
177747Speter 		case SET:
178747Speter 			i = TDOUBLE+1;
179747Speter 			break;
180747Speter 		case SCAL:
181747Speter 			i = 0;
182747Speter 			break;
18315975Smckusick 		case CRANGE:
18415975Smckusick 			/*
18515975Smckusick 			 * find the base type of a conformant array range
18615975Smckusick 			 */
18715975Smckusick 			switch (classify(p->type)) {
18815975Smckusick 				case TBOOL: i = 1; break;
18915975Smckusick 				case TCHAR: i = 2; break;
19015975Smckusick 				case TINT: i = 3; break;
19115975Smckusick 				case TSCAL: i = 0; break;
19215975Smckusick 				default:
19315975Smckusick 					panic( "isa" );
19415975Smckusick 			}
19515975Smckusick 			break;
196747Speter 		default:
197747Speter 			i = p - nl;
198747Speter 	}
199747Speter 	if (i >= 0 && i <= TDOUBLE+1) {
200747Speter 		i = "sbcidt"[i];
201747Speter 		cp = s;
202747Speter 		while (*cp)
203747Speter 			if (*cp++ == i)
204747Speter 				return (1);
205747Speter 	}
206747Speter 	return (NIL);
207747Speter }
208747Speter 
209747Speter /*
210747Speter  * Isnta is !isa
211747Speter  */
212747Speter isnta(p, s)
21314728Sthien     struct nl *p;
21414728Sthien     char *s;
215747Speter {
216747Speter 
217747Speter 	return (!isa(p, s));
218747Speter }
219747Speter 
220747Speter /*
221747Speter  * "shorthand"
222747Speter  */
22314728Sthien char *
224747Speter nameof(p)
22514728Sthien struct nl *p;
226747Speter {
227747Speter 
228747Speter 	return (clnames[classify(p)]);
229747Speter }
230747Speter 
231747Speter #ifndef PI0
23214728Sthien /* find out for sure what kind of node this is being passed
23314728Sthien    possibly several different kinds of node are passed to it */
23414728Sthien int nowexp(r)
23514728Sthien 	struct tnode *r;
236747Speter {
23714728Sthien 	if (r->tag == T_WEXP) {
23814728Sthien 		if (r->var_node.cptr == NIL)
239747Speter 			error("Oct/hex allowed only on writeln/write calls");
240747Speter 		else
241747Speter 			error("Width expressions allowed only in writeln/write calls");
242747Speter 		return (1);
243747Speter 	}
244747Speter 	return (NIL);
245747Speter }
246747Speter #endif
2473276Smckusic 
2483276Smckusic     /*
2493825Speter      *	is a variable a local, a formal parameter, or a global?
2503276Smckusic      *	all this from just the offset:
2513825Speter      *	    globals are at levels 0 or 1
2523276Smckusic      *	    positives are parameters
2533276Smckusic      *	    negative evens are locals
2543276Smckusic      */
25514728Sthien /*ARGSUSED*/
25614728Sthien whereis( offset , other_flags )
2573825Speter     int		offset;
2587920Smckusick     char	other_flags;
2593276Smckusic {
2603276Smckusic 
2613825Speter #   ifdef OBJ
2623825Speter 	return ( offset >= 0 ? PARAMVAR : LOCALVAR );
2633825Speter #   endif OBJ
2643825Speter #   ifdef PC
2659127Smckusick 	switch ( other_flags & ( NGLOBAL | NPARAM | NLOCAL | NNLOCAL) ) {
26614728Sthien 	    default:
26714728Sthien 		panic( "whereis" );
2683825Speter 	    case NGLOBAL:
2693825Speter 		return GLOBALVAR;
2703825Speter 	    case NPARAM:
2713825Speter 		return PARAMVAR;
2729127Smckusick 	    case NNLOCAL:
2739127Smckusick 		return NAMEDLOCALVAR;
2743825Speter 	    case NLOCAL:
2753825Speter 		return LOCALVAR;
2763825Speter 	}
2773825Speter #   endif PC
2783276Smckusic }
279