xref: /csrg-svn/usr.bin/pascal/src/nl.c (revision 3828)
1760Speter /* Copyright (c) 1979 Regents of the University of California */
2760Speter 
3*3828Speter static	char sccsid[] = "@(#)nl.c 1.5 06/01/81";
4760Speter 
5760Speter #include "whoami.h"
6760Speter #include "0.h"
7760Speter #include "opcode.h"
8760Speter #include "objfmt.h"
9760Speter 
10760Speter /*
11760Speter  * NAMELIST SEGMENT DEFINITIONS
12760Speter  */
13760Speter struct nls {
14760Speter 	struct nl *nls_low;
15760Speter 	struct nl *nls_high;
16760Speter } ntab[MAXNL], *nlact;
17760Speter 
18760Speter struct	nl nl[INL];
19760Speter struct	nl *nlp = nl;
20760Speter struct	nls *nlact = ntab;
21760Speter 
22760Speter     /*
23760Speter      *	all these strings must be places where people can find them
24760Speter      *	since lookup only looks at the string pointer, not the chars.
25760Speter      *	see, for example, pTreeInit.
26760Speter      */
27760Speter 
28760Speter     /*
29760Speter      *	built in constants
30760Speter      */
31760Speter char	*in_consts[] = {
32760Speter 	    "true" ,
33760Speter 	    "false" ,
34760Speter 	    "TRUE",
35760Speter 	    "FALSE",
36760Speter 	    "minint" ,
37760Speter 	    "maxint" ,
38760Speter 	    "minchar" ,
39760Speter 	    "maxchar" ,
40760Speter 	    "bell" ,
41760Speter 	    "tab" ,
42760Speter 	    0
43760Speter 	};
44760Speter 
45760Speter     /*
46760Speter      *	built in simple types
47760Speter      */
48760Speter char *in_types[] =
49760Speter     {
50760Speter 	"boolean",
51760Speter 	"char",
52760Speter 	"integer",
53760Speter 	"real",
54760Speter 	"_nil",		/* dummy name */
55760Speter 	0
56760Speter     };
57760Speter 
58760Speter int in_rclasses[] =
59760Speter     {
60760Speter 	TINT ,
61760Speter 	TINT ,
62760Speter 	TINT ,
63760Speter 	TCHAR ,
64760Speter 	TBOOL ,
65760Speter 	TDOUBLE ,
66760Speter 	0
67760Speter     };
68760Speter 
69760Speter long in_ranges[] =
70760Speter     {
71760Speter 	-128L	 , 128L ,
72760Speter 	-32768L	 , 32767L ,
73760Speter 	-2147483648L , 2147483647L ,
74760Speter 	0L		 , 127L ,
75760Speter 	0L		 , 1L ,
76760Speter 	0L		 , 0L 		/* fake for reals */
77760Speter     };
78760Speter 
79760Speter     /*
80760Speter      *	built in constructed types
81760Speter      */
82760Speter char	*in_ctypes[] = {
83760Speter 	    "Boolean" ,
84760Speter 	    "intset" ,
85760Speter 	    "alfa" ,
86760Speter 	    "text" ,
87760Speter 	    0
88760Speter 	};
89760Speter 
90760Speter     /*
91760Speter      *	built in variables
92760Speter      */
93760Speter char	*in_vars[] = {
94760Speter 	    "input" ,
95760Speter 	    "output" ,
96760Speter 	    0
97760Speter 	};
98760Speter 
99760Speter     /*
100760Speter      *	built in functions
101760Speter      */
102760Speter char *in_funcs[] =
103760Speter     {
104760Speter 	"abs" ,
105760Speter 	"arctan" ,
106760Speter 	"card" ,
107760Speter 	"chr" ,
108760Speter 	"clock" ,
109760Speter 	"cos" ,
110760Speter 	"eof" ,
111760Speter 	"eoln" ,
112760Speter 	"eos" ,
113760Speter 	"exp" ,
114760Speter 	"expo" ,
115760Speter 	"ln" ,
116760Speter 	"odd" ,
117760Speter 	"ord" ,
118760Speter 	"pred" ,
119760Speter 	"round" ,
120760Speter 	"sin" ,
121760Speter 	"sqr" ,
122760Speter 	"sqrt" ,
123760Speter 	"succ" ,
124760Speter 	"trunc" ,
125760Speter 	"undefined" ,
126760Speter 	/*
127760Speter 	 * Extensions
128760Speter 	 */
129760Speter 	"argc" ,
130760Speter 	"random" ,
131760Speter 	"seed" ,
132760Speter 	"wallclock" ,
133760Speter 	"sysclock" ,
134760Speter 	0
135760Speter     };
136760Speter 
137760Speter 	/*
138760Speter 	 * Built-in procedures
139760Speter 	 */
140760Speter char *in_procs[] =
141760Speter     {
142760Speter 	"date" ,
143760Speter 	"dispose" ,
144760Speter 	"flush" ,
145760Speter 	"get" ,
146760Speter 	"getseg" ,
147760Speter 	"halt" ,
148760Speter 	"linelimit" ,
149760Speter 	"message" ,
150760Speter 	"new" ,
151760Speter 	"pack" ,
152760Speter 	"page" ,
153760Speter 	"put" ,
154760Speter 	"putseg" ,
155760Speter 	"read" ,
156760Speter 	"readln" ,
157760Speter 	"remove" ,
158760Speter 	"reset" ,
159760Speter 	"rewrite" ,
160760Speter 	"time" ,
161760Speter 	"unpack" ,
162760Speter 	"write" ,
163760Speter 	"writeln" ,
164760Speter 	/*
165760Speter 	 * Extensions
166760Speter 	 */
167760Speter 	"argv" ,
168760Speter 	"null" ,
169760Speter 	"stlimit" ,
170760Speter 	0
171760Speter     };
172760Speter 
173760Speter #ifndef PI0
174760Speter     /*
175760Speter      *	and their opcodes
176760Speter      */
177760Speter int in_fops[] =
178760Speter     {
179760Speter 	O_ABS2,
180760Speter 	O_ATAN,
181760Speter 	O_CARD|NSTAND,
182760Speter 	O_CHR2,
183760Speter 	O_CLCK|NSTAND,
184760Speter 	O_COS,
185760Speter 	O_EOF,
186760Speter 	O_EOLN,
187760Speter 	0,
188760Speter 	O_EXP,
189760Speter 	O_EXPO|NSTAND,
190760Speter 	O_LN,
191760Speter 	O_ODD2,
192760Speter 	O_ORD2,
193760Speter 	O_PRED2,
194760Speter 	O_ROUND,
195760Speter 	O_SIN,
196760Speter 	O_SQR2,
197760Speter 	O_SQRT,
198760Speter 	O_SUCC2,
199760Speter 	O_TRUNC,
200760Speter 	O_UNDEF|NSTAND,
201760Speter 	/*
202760Speter 	 * Extensions
203760Speter 	 */
204760Speter 	O_ARGC|NSTAND,
205760Speter 	O_RANDOM|NSTAND,
206760Speter 	O_SEED|NSTAND,
207760Speter 	O_WCLCK|NSTAND,
208760Speter 	O_SCLCK|NSTAND
209760Speter     };
210760Speter 
211760Speter     /*
212760Speter      * Built-in procedures
213760Speter      */
214760Speter int in_pops[] =
215760Speter     {
216760Speter 	O_DATE|NSTAND,
2171817Speter 	O_DISPOSE|NSTAND,
218760Speter 	O_FLUSH|NSTAND,
219760Speter 	O_GET,
220760Speter 	0,
221760Speter 	O_HALT|NSTAND,
222760Speter 	O_LLIMIT|NSTAND,
223760Speter 	O_MESSAGE|NSTAND,
224760Speter 	O_NEW,
225760Speter 	O_PACK,
226760Speter 	O_PAGE,
227760Speter 	O_PUT,
228760Speter 	0,
229760Speter 	O_READ4,
230760Speter 	O_READLN,
231760Speter 	O_REMOVE|NSTAND,
232760Speter 	O_RESET,
233760Speter 	O_REWRITE,
234760Speter 	O_TIME|NSTAND,
235760Speter 	O_UNPACK,
236760Speter 	O_WRITEF,
237760Speter 	O_WRITLN,
238760Speter 	/*
239760Speter 	 * Extensions
240760Speter 	 */
241760Speter 	O_ARGV|NSTAND,
242760Speter 	O_ABORT|NSTAND,
243760Speter 	O_STLIM|NSTAND
244760Speter     };
245760Speter #endif
246760Speter 
247760Speter /*
248760Speter  * Initnl initializes the first namelist segment and then
249760Speter  * initializes the name list for block 0.
250760Speter  */
251760Speter initnl()
252760Speter     {
253760Speter 	register char		**cp;
254760Speter 	register struct nl	*np;
255760Speter 	struct nl		*fp;
256760Speter 	int			*ip;
257760Speter 	long			*lp;
258760Speter 
259760Speter #ifdef	DEBUG
260760Speter 	if ( hp21mx )
261760Speter 	    {
262760Speter 		MININT = -32768.;
263760Speter 		MAXINT = 32767.;
264760Speter #ifndef	PI0
265760Speter 		genmx();
266760Speter #endif
267760Speter 	    }
268760Speter #endif
269760Speter 	ntab[0].nls_low = nl;
270760Speter 	ntab[0].nls_high = &nl[INL];
271760Speter 	defnl ( 0 , 0 , 0 , 0 );
272760Speter 
273760Speter 	/*
274760Speter 	 *	Types
275760Speter 	 */
276760Speter 	for ( cp = in_types ; *cp != 0 ; cp ++ )
277760Speter 	    hdefnl ( *cp , TYPE , nlp , 0 );
278760Speter 
279760Speter 	/*
280760Speter 	 *	Ranges
281760Speter 	 */
282760Speter 	lp = in_ranges;
283760Speter 	for ( ip = in_rclasses ; *ip != 0 ; ip ++ )
284760Speter 	    {
285760Speter 		np = defnl ( 0 , RANGE , nl+(*ip) , 0 );
286760Speter 		nl[*ip].type = np;
287760Speter 		np -> range[0] = *lp ++ ;
288760Speter 		np -> range[1] = *lp ++ ;
289760Speter 
290760Speter 	    };
291760Speter 
292760Speter 	/*
293760Speter 	 *	built in constructed types
294760Speter 	 */
295760Speter 
296760Speter 	cp = in_ctypes;
297760Speter 	/*
298760Speter 	 *	Boolean = boolean;
299760Speter 	 */
300760Speter 	hdefnl ( *cp++ , TYPE , nl+T1BOOL , 0 );
301760Speter 
302760Speter 	/*
303760Speter 	 *	intset = set of 0 .. 127;
304760Speter 	 */
305760Speter 	intset = *cp++;
306760Speter 	hdefnl( intset , TYPE , nlp+1 , 0 );
307760Speter 	defnl ( 0 , SET , nlp+1 , 0 );
308760Speter 	np = defnl ( 0 , RANGE , nl+TINT , 0 );
309760Speter 	np -> range[0] = 0L;
310760Speter 	np -> range[1] = 127L;
311760Speter 
312760Speter 	/*
313760Speter 	 *	alfa = array [ 1 .. 10 ] of char;
314760Speter 	 */
315760Speter 	np = defnl ( 0 , RANGE , nl+TINT , 0 );
316760Speter 	np -> range[0] = 1L;
317760Speter 	np -> range[1] = 10L;
318760Speter 	defnl ( 0 , ARRAY , nl+T1CHAR , 1 ) -> chain = np;
319760Speter 	hdefnl ( *cp++ , TYPE , nlp-1 , 0 );
320760Speter 
321760Speter 	/*
322760Speter 	 *	text = file of char;
323760Speter 	 */
324760Speter 	hdefnl ( *cp++ , TYPE , nlp+1 , 0 );
325760Speter 	np = defnl ( 0 , FILET , nl+T1CHAR , 0 );
326760Speter 	np -> nl_flags |= NFILES;
327760Speter 
328760Speter 	/*
329760Speter 	 *	input,output : text;
330760Speter 	 */
331760Speter 	cp = in_vars;
332760Speter #	ifndef	PI0
333760Speter 		input = hdefnl ( *cp++ , VAR , np , INPUT_OFF );
334760Speter 		output = hdefnl (  *cp++ , VAR , np , OUTPUT_OFF );
335760Speter #	else
336760Speter 		input = hdefnl ( *cp++ , VAR , np , 0 );
337760Speter 		output = hdefnl ( *cp++ , VAR , np , 0 );
338760Speter #	endif
339*3828Speter #	ifdef PC
340*3828Speter 	    input -> extra_flags |= NGLOBAL;
341*3828Speter 	    output -> extra_flags |= NGLOBAL;
342*3828Speter #	endif PC
343760Speter 
344760Speter 	/*
345760Speter 	 *	built in constants
346760Speter 	 */
347760Speter 	cp = in_consts;
348760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
349760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
350760Speter 	(nl + TBOOL)->chain = fp;
351760Speter 	fp->chain = np;
352760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
353760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
354760Speter 	fp->chain = np;
355760Speter 	if (opt('s'))
356760Speter 		(nl + TBOOL)->chain = fp;
357760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MININT;
358760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MAXINT;
359760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 0 );
360760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 127 );
361760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\007' );
362760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\t' );
363760Speter 
364760Speter 	/*
365760Speter 	 * Built-in functions and procedures
366760Speter 	 */
367760Speter #ifndef PI0
368760Speter 	ip = in_fops;
369760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
370760Speter 	    hdefnl ( *cp , FUNC , 0 , * ip ++ );
371760Speter 	ip = in_pops;
372760Speter 	for ( cp = in_procs ; *cp != 0 ; cp ++ )
373760Speter 	    hdefnl ( *cp , PROC , 0 , * ip ++ );
374760Speter #else
375760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
376760Speter 	    hdefnl ( *cp , FUNC , 0 , 0 );
377760Speter 	for ( cp = in_procs ; *cp != 0 , cp ++ )
378760Speter 	    hdefnl ( *cp , PROC , 0 , 0 );
379760Speter #endif
380760Speter #	ifdef PTREE
381760Speter 	    pTreeInit();
382760Speter #	endif
383760Speter     }
384760Speter 
385760Speter struct nl *
386760Speter hdefnl(sym, cls, typ, val)
387760Speter {
388760Speter 	register struct nl *p;
389760Speter 
390760Speter #ifndef PI1
391760Speter 	if (sym)
392760Speter 		hash(sym, 0);
393760Speter #endif
394760Speter 	p = defnl(sym, cls, typ, val);
395760Speter 	if (sym)
396760Speter 		enter(p);
397760Speter 	return (p);
398760Speter }
399760Speter 
400760Speter /*
401760Speter  * Free up the name list segments
402760Speter  * at the end of a statement/proc/func
403760Speter  * All segments are freed down to the one in which
404760Speter  * p points.
405760Speter  */
406760Speter nlfree(p)
407760Speter 	struct nl *p;
408760Speter {
409760Speter 
410760Speter 	nlp = p;
411760Speter 	while (nlact->nls_low > nlp || nlact->nls_high < nlp) {
412760Speter 		free(nlact->nls_low);
413760Speter 		nlact->nls_low = NIL;
414760Speter 		nlact->nls_high = NIL;
415760Speter 		--nlact;
416760Speter 		if (nlact < &ntab[0])
417760Speter 			panic("nlfree");
418760Speter 	}
419760Speter }
420760Speter 
421760Speter 
422760Speter char	*VARIABLE	= "variable";
423760Speter 
424760Speter char	*classes[ ] = {
425760Speter 	"undefined",
426760Speter 	"constant",
427760Speter 	"type",
428760Speter 	"variable",	/*	VARIABLE	*/
429760Speter 	"array",
430760Speter 	"pointer or file",
431760Speter 	"record",
432760Speter 	"field",
433760Speter 	"procedure",
434760Speter 	"function",
435760Speter 	"variable",	/*	VARIABLE	*/
436760Speter 	"variable",	/*	VARIABLE	*/
437760Speter 	"pointer",
438760Speter 	"file",
439760Speter 	"set",
440760Speter 	"subrange",
441760Speter 	"label",
442760Speter 	"withptr",
443760Speter 	"scalar",
444760Speter 	"string",
445760Speter 	"program",
4461197Speter 	"improper",
4471197Speter 	"variant",
4481197Speter 	"formal procedure",
4491197Speter 	"formal function"
450760Speter };
451760Speter 
452760Speter char	*snark	= "SNARK";
453760Speter 
454760Speter #ifdef PI
455760Speter #ifdef DEBUG
456760Speter char	*ctext[] =
457760Speter {
458760Speter 	"BADUSE",
459760Speter 	"CONST",
460760Speter 	"TYPE",
461760Speter 	"VAR",
462760Speter 	"ARRAY",
463760Speter 	"PTRFILE",
464760Speter 	"RECORD",
465760Speter 	"FIELD",
466760Speter 	"PROC",
467760Speter 	"FUNC",
468760Speter 	"FVAR",
469760Speter 	"REF",
470760Speter 	"PTR",
471760Speter 	"FILET",
472760Speter 	"SET",
473760Speter 	"RANGE",
474760Speter 	"LABEL",
475760Speter 	"WITHPTR",
476760Speter 	"SCAL",
477760Speter 	"STR",
478760Speter 	"PROG",
479760Speter 	"IMPROPER",
4801197Speter 	"VARNT",
4811197Speter 	"FPROC",
4821197Speter 	"FFUNC"
483760Speter };
484760Speter 
485760Speter char	*stars	= "\t***";
486760Speter 
487760Speter /*
488760Speter  * Dump the namelist from the
489760Speter  * current nlp down to 'to'.
490760Speter  * All the namelist is dumped if
491760Speter  * to is NIL.
492760Speter  */
493760Speter dumpnl(to, rout)
494760Speter 	struct nl *to;
495760Speter {
496760Speter 	register struct nl *p;
497760Speter 	register int j;
498760Speter 	struct nls *nlsp;
499760Speter 	int i, v, head;
500760Speter 
501760Speter 	if (opt('y') == 0)
502760Speter 		return;
503760Speter 	if (to != NIL)
504760Speter 		printf("\n\"%s\" Block=%d\n", rout, cbn);
505760Speter 	nlsp = nlact;
506760Speter 	head = NIL;
507760Speter 	for (p = nlp; p != to;) {
508760Speter 		if (p == nlsp->nls_low) {
509760Speter 			if (nlsp == &ntab[0])
510760Speter 				break;
511760Speter 			nlsp--;
512760Speter 			p = nlsp->nls_high;
513760Speter 		}
514760Speter 		p--;
515760Speter 		if (head == NIL) {
516760Speter 			printf("\tName\tClass  Bn+Flags\tType\tVal\tChn\n");
517760Speter 			head++;
518760Speter 		}
519760Speter 		printf("%3d:", nloff(p));
520760Speter 		if (p->symbol)
521760Speter 			printf("\t%.7s", p->symbol);
522760Speter 		else
523760Speter 			printf(stars);
524760Speter 		if (p->class)
525760Speter 			printf("\t%s", ctext[p->class]);
526760Speter 		else
527760Speter 			printf(stars);
528760Speter 		if (p->nl_flags) {
529760Speter 			pchr('\t');
530760Speter 			if (p->nl_flags & 037)
531760Speter 				printf("%d ", p->nl_flags & 037);
532760Speter #ifndef PI0
533760Speter 			if (p->nl_flags & NMOD)
534760Speter 				pchr('M');
535760Speter 			if (p->nl_flags & NUSED)
536760Speter 				pchr('U');
537760Speter #endif
538760Speter 			if (p->nl_flags & NFILES)
539760Speter 				pchr('F');
540760Speter 		} else
541760Speter 			printf(stars);
542760Speter 		if (p->type)
543760Speter 			printf("\t[%d]", nloff(p->type));
544760Speter 		else
545760Speter 			printf(stars);
546760Speter 		v = p->value[0];
547760Speter 		switch (p->class) {
548760Speter 			case TYPE:
549760Speter 				break;
550760Speter 			case VARNT:
551760Speter 				goto con;
552760Speter 			case CONST:
553760Speter 				switch (nloff(p->type)) {
554760Speter 					default:
555760Speter 						printf("\t%d", v);
556760Speter 						break;
557760Speter 					case TDOUBLE:
558760Speter 						printf("\t%f", p->real);
559760Speter 						break;
560760Speter 					case TINT:
561760Speter 					case T4INT:
562760Speter con:
563760Speter 						printf("\t%ld", p->range[0]);
564760Speter 						break;
565760Speter 					case TSTR:
566760Speter 						printf("\t'%s'", p->ptr[0]);
567760Speter 						break;
568760Speter 					}
569760Speter 				break;
570760Speter 			case VAR:
571760Speter 			case REF:
572760Speter 			case WITHPTR:
5731197Speter 			case FFUNC:
5741197Speter 			case FPROC:
575760Speter 				printf("\t%d,%d", cbn, v);
576760Speter 				break;
577760Speter 			case SCAL:
578760Speter 			case RANGE:
579760Speter 				printf("\t%ld..%ld", p->range[0], p->range[1]);
580760Speter 				break;
581760Speter 			case RECORD:
582760Speter 				printf("\t%d(%d)", v, p->value[NL_FLDSZ]);
583760Speter 				break;
584760Speter 			case FIELD:
585760Speter 				printf("\t%d", v);
586760Speter 				break;
587760Speter 			case STR:
588760Speter 				printf("\t|%d|", p->value[0]);
589760Speter 				break;
590760Speter 			case FVAR:
591760Speter 			case FUNC:
592760Speter 			case PROC:
593760Speter 			case PROG:
594760Speter 				if (cbn == 0) {
595760Speter 					printf("\t<%o>", p->value[0] & 0377);
596760Speter #ifndef PI0
597760Speter 					if (p->value[0] & NSTAND)
598760Speter 						printf("\tNSTAND");
599760Speter #endif
600760Speter 					break;
601760Speter 				}
602760Speter 				v = p->value[1];
603760Speter 			default:
604760Speter casedef:
605760Speter 				if (v)
606760Speter 					printf("\t<%d>", v);
607760Speter 				else
608760Speter 					printf(stars);
609760Speter 		}
610760Speter 		if (p->chain)
611760Speter 			printf("\t[%d]", nloff(p->chain));
612760Speter 		switch (p->class) {
613760Speter 			case RECORD:
614760Speter 				if (p->ptr[NL_VARNT])
615760Speter 					printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT]));
616760Speter 				if (p->ptr[NL_TAG])
617760Speter 					printf(" TAG=[%d]", nloff(p->ptr[NL_TAG]));
618760Speter 				break;
619760Speter 			case VARNT:
620760Speter 				printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC]));
621760Speter 				break;
622760Speter 		}
623*3828Speter #		ifdef PC
624*3828Speter 		    if ( p -> extra_flags != 0 ) {
625*3828Speter 			pchr( '\t' );
626*3828Speter 			if ( p -> extra_flags & NEXTERN )
627*3828Speter 			    printf( "NEXTERN " );
628*3828Speter 			if ( p -> extra_flags & NLOCAL )
629*3828Speter 			    printf( "NLOCAL " );
630*3828Speter 			if ( p -> extra_flags & NPARAM )
631*3828Speter 			    printf( "NPARAM " );
632*3828Speter 			if ( p -> extra_flags & NGLOBAL )
633*3828Speter 			    printf( "NGLOBAL " );
634*3828Speter 			if ( p -> extra_flags & NREGVAR )
635*3828Speter 			    printf( "NREGVAR " );
636*3828Speter 		    }
637*3828Speter #		endif PC
638760Speter #		ifdef PTREE
639760Speter 		    pchr( '\t' );
640760Speter 		    pPrintPointer( stdout , "%s" , p -> inTree );
641760Speter #		endif
642760Speter 		pchr('\n');
643760Speter 	}
644760Speter 	if (head == 0)
645760Speter 		printf("\tNo entries\n");
646760Speter }
647760Speter #endif
648760Speter 
649760Speter 
650760Speter /*
651760Speter  * Define a new name list entry
652760Speter  * with initial symbol, class, type
653760Speter  * and value[0] as given.  A new name
654760Speter  * list segment is allocated to hold
655760Speter  * the next name list slot if necessary.
656760Speter  */
657760Speter struct nl *
658760Speter defnl(sym, cls, typ, val)
659760Speter 	char *sym;
660760Speter 	int cls;
661760Speter 	struct nl *typ;
662760Speter 	int val;
663760Speter {
664760Speter 	register struct nl *p;
665760Speter 	register int *q, i;
666760Speter 	char *cp;
667760Speter 
668760Speter 	p = nlp;
669760Speter 
670760Speter 	/*
671760Speter 	 * Zero out this entry
672760Speter 	 */
673760Speter 	q = p;
674760Speter 	i = (sizeof *p)/(sizeof (int));
675760Speter 	do
676760Speter 		*q++ = 0;
677760Speter 	while (--i);
678760Speter 
679760Speter 	/*
680760Speter 	 * Insert the values
681760Speter 	 */
682760Speter 	p->symbol = sym;
683760Speter 	p->class = cls;
684760Speter 	p->type = typ;
685760Speter 	p->nl_block = cbn;
686760Speter 	p->value[0] = val;
687760Speter 
688760Speter 	/*
689760Speter 	 * Insure that the next namelist
690760Speter 	 * entry actually exists. This is
691760Speter 	 * really not needed here, it would
692760Speter 	 * suffice to do it at entry if we
693760Speter 	 * need the slot.  It is done this
694760Speter 	 * way because, historically, nlp
695760Speter 	 * always pointed at the next namelist
696760Speter 	 * slot.
697760Speter 	 */
698760Speter 	nlp++;
699760Speter 	if (nlp >= nlact->nls_high) {
700760Speter 		i = NLINC;
701760Speter 		cp = malloc(NLINC * sizeof *nlp);
7021834Speter 		if (cp == 0) {
703760Speter 			i = NLINC / 2;
704760Speter 			cp = malloc((NLINC / 2) * sizeof *nlp);
705760Speter 		}
7061834Speter 		if (cp == 0) {
707760Speter 			error("Ran out of memory (defnl)");
708760Speter 			pexit(DIED);
709760Speter 		}
710760Speter 		nlact++;
711760Speter 		if (nlact >= &ntab[MAXNL]) {
712760Speter 			error("Ran out of name list tables");
713760Speter 			pexit(DIED);
714760Speter 		}
715760Speter 		nlp = cp;
716760Speter 		nlact->nls_low = nlp;
717760Speter 		nlact->nls_high = nlact->nls_low + i;
718760Speter 	}
719760Speter 	return (p);
720760Speter }
721760Speter 
722760Speter /*
723760Speter  * Make a duplicate of the argument
724760Speter  * namelist entry for, e.g., type
725760Speter  * declarations of the form 'type a = b'
726760Speter  * and array indicies.
727760Speter  */
728760Speter struct nl *
729760Speter nlcopy(p)
730760Speter 	struct nl *p;
731760Speter {
732760Speter 	register int *p1, *p2, i;
733760Speter 
734760Speter 	p1 = p;
735760Speter 	p = p2 = defnl(0, 0, 0, 0);
736760Speter 	i = (sizeof *p)/(sizeof (int));
737760Speter 	do
738760Speter 		*p2++ = *p1++;
739760Speter 	while (--i);
740760Speter 	p->chain = NIL;
741760Speter 	return (p);
742760Speter }
743760Speter 
744760Speter /*
745760Speter  * Compute a namelist offset
746760Speter  */
747760Speter nloff(p)
748760Speter 	struct nl *p;
749760Speter {
750760Speter 
751760Speter 	return (p - nl);
752760Speter }
753760Speter 
754760Speter /*
755760Speter  * Enter a symbol into the block
756760Speter  * symbol table.  Symbols are hashed
757760Speter  * 64 ways based on low 6 bits of the
758760Speter  * character pointer into the string
759760Speter  * table.
760760Speter  */
761760Speter struct nl *
762760Speter enter(np)
763760Speter 	struct nl *np;
764760Speter {
765760Speter 	register struct nl *rp, *hp;
766760Speter 	register struct nl *p;
767760Speter 	int i;
768760Speter 
769760Speter 	rp = np;
770760Speter 	if (rp == NIL)
771760Speter 		return (NIL);
772760Speter #ifndef PI1
773760Speter 	if (cbn > 0)
774760Speter 		if (rp->symbol == input->symbol || rp->symbol == output->symbol)
775760Speter 			error("Pre-defined files input and output must not be redefined");
776760Speter #endif
777760Speter 	i = rp->symbol;
778760Speter 	i &= 077;
779760Speter 	hp = disptab[i];
780760Speter 	if (rp->class != BADUSE && rp->class != FIELD)
781760Speter 	for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next)
782760Speter 		if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) {
783760Speter #ifndef PI1
784760Speter 			error("%s is already defined in this block", rp->symbol);
785760Speter #endif
786760Speter 			break;
787760Speter 
788760Speter 		}
789760Speter 	rp->nl_next = hp;
790760Speter 	disptab[i] = rp;
791760Speter 	return (rp);
792760Speter }
793760Speter #endif
794