xref: /csrg-svn/usr.bin/pascal/src/nl.c (revision 1197)
1760Speter /* Copyright (c) 1979 Regents of the University of California */
2760Speter 
3*1197Speter static	char sccsid[] = "@(#)nl.c 1.2 10/03/80";
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,
217760Speter 	O_DISPOSE,
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
339760Speter 
340760Speter 	/*
341760Speter 	 *	built in constants
342760Speter 	 */
343760Speter 	cp = in_consts;
344760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
345760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
346760Speter 	(nl + TBOOL)->chain = fp;
347760Speter 	fp->chain = np;
348760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
349760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
350760Speter 	fp->chain = np;
351760Speter 	if (opt('s'))
352760Speter 		(nl + TBOOL)->chain = fp;
353760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MININT;
354760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MAXINT;
355760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 0 );
356760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 127 );
357760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\007' );
358760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\t' );
359760Speter 
360760Speter 	/*
361760Speter 	 * Built-in functions and procedures
362760Speter 	 */
363760Speter #ifndef PI0
364760Speter 	ip = in_fops;
365760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
366760Speter 	    hdefnl ( *cp , FUNC , 0 , * ip ++ );
367760Speter 	ip = in_pops;
368760Speter 	for ( cp = in_procs ; *cp != 0 ; cp ++ )
369760Speter 	    hdefnl ( *cp , PROC , 0 , * ip ++ );
370760Speter #else
371760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
372760Speter 	    hdefnl ( *cp , FUNC , 0 , 0 );
373760Speter 	for ( cp = in_procs ; *cp != 0 , cp ++ )
374760Speter 	    hdefnl ( *cp , PROC , 0 , 0 );
375760Speter #endif
376760Speter #	ifdef PTREE
377760Speter 	    pTreeInit();
378760Speter #	endif
379760Speter     }
380760Speter 
381760Speter struct nl *
382760Speter hdefnl(sym, cls, typ, val)
383760Speter {
384760Speter 	register struct nl *p;
385760Speter 
386760Speter #ifndef PI1
387760Speter 	if (sym)
388760Speter 		hash(sym, 0);
389760Speter #endif
390760Speter 	p = defnl(sym, cls, typ, val);
391760Speter 	if (sym)
392760Speter 		enter(p);
393760Speter 	return (p);
394760Speter }
395760Speter 
396760Speter /*
397760Speter  * Free up the name list segments
398760Speter  * at the end of a statement/proc/func
399760Speter  * All segments are freed down to the one in which
400760Speter  * p points.
401760Speter  */
402760Speter nlfree(p)
403760Speter 	struct nl *p;
404760Speter {
405760Speter 
406760Speter 	nlp = p;
407760Speter 	while (nlact->nls_low > nlp || nlact->nls_high < nlp) {
408760Speter 		free(nlact->nls_low);
409760Speter 		nlact->nls_low = NIL;
410760Speter 		nlact->nls_high = NIL;
411760Speter 		--nlact;
412760Speter 		if (nlact < &ntab[0])
413760Speter 			panic("nlfree");
414760Speter 	}
415760Speter }
416760Speter 
417760Speter 
418760Speter char	*VARIABLE	= "variable";
419760Speter 
420760Speter char	*classes[ ] = {
421760Speter 	"undefined",
422760Speter 	"constant",
423760Speter 	"type",
424760Speter 	"variable",	/*	VARIABLE	*/
425760Speter 	"array",
426760Speter 	"pointer or file",
427760Speter 	"record",
428760Speter 	"field",
429760Speter 	"procedure",
430760Speter 	"function",
431760Speter 	"variable",	/*	VARIABLE	*/
432760Speter 	"variable",	/*	VARIABLE	*/
433760Speter 	"pointer",
434760Speter 	"file",
435760Speter 	"set",
436760Speter 	"subrange",
437760Speter 	"label",
438760Speter 	"withptr",
439760Speter 	"scalar",
440760Speter 	"string",
441760Speter 	"program",
442*1197Speter 	"improper",
443*1197Speter 	"variant",
444*1197Speter 	"formal procedure",
445*1197Speter 	"formal function"
446760Speter };
447760Speter 
448760Speter char	*snark	= "SNARK";
449760Speter 
450760Speter #ifdef PI
451760Speter #ifdef DEBUG
452760Speter char	*ctext[] =
453760Speter {
454760Speter 	"BADUSE",
455760Speter 	"CONST",
456760Speter 	"TYPE",
457760Speter 	"VAR",
458760Speter 	"ARRAY",
459760Speter 	"PTRFILE",
460760Speter 	"RECORD",
461760Speter 	"FIELD",
462760Speter 	"PROC",
463760Speter 	"FUNC",
464760Speter 	"FVAR",
465760Speter 	"REF",
466760Speter 	"PTR",
467760Speter 	"FILET",
468760Speter 	"SET",
469760Speter 	"RANGE",
470760Speter 	"LABEL",
471760Speter 	"WITHPTR",
472760Speter 	"SCAL",
473760Speter 	"STR",
474760Speter 	"PROG",
475760Speter 	"IMPROPER",
476*1197Speter 	"VARNT",
477*1197Speter 	"FPROC",
478*1197Speter 	"FFUNC"
479760Speter };
480760Speter 
481760Speter char	*stars	= "\t***";
482760Speter 
483760Speter /*
484760Speter  * Dump the namelist from the
485760Speter  * current nlp down to 'to'.
486760Speter  * All the namelist is dumped if
487760Speter  * to is NIL.
488760Speter  */
489760Speter dumpnl(to, rout)
490760Speter 	struct nl *to;
491760Speter {
492760Speter 	register struct nl *p;
493760Speter 	register int j;
494760Speter 	struct nls *nlsp;
495760Speter 	int i, v, head;
496760Speter 
497760Speter 	if (opt('y') == 0)
498760Speter 		return;
499760Speter 	if (to != NIL)
500760Speter 		printf("\n\"%s\" Block=%d\n", rout, cbn);
501760Speter 	nlsp = nlact;
502760Speter 	head = NIL;
503760Speter 	for (p = nlp; p != to;) {
504760Speter 		if (p == nlsp->nls_low) {
505760Speter 			if (nlsp == &ntab[0])
506760Speter 				break;
507760Speter 			nlsp--;
508760Speter 			p = nlsp->nls_high;
509760Speter 		}
510760Speter 		p--;
511760Speter 		if (head == NIL) {
512760Speter 			printf("\tName\tClass  Bn+Flags\tType\tVal\tChn\n");
513760Speter 			head++;
514760Speter 		}
515760Speter 		printf("%3d:", nloff(p));
516760Speter 		if (p->symbol)
517760Speter 			printf("\t%.7s", p->symbol);
518760Speter 		else
519760Speter 			printf(stars);
520760Speter 		if (p->class)
521760Speter 			printf("\t%s", ctext[p->class]);
522760Speter 		else
523760Speter 			printf(stars);
524760Speter 		if (p->nl_flags) {
525760Speter 			pchr('\t');
526760Speter 			if (p->nl_flags & 037)
527760Speter 				printf("%d ", p->nl_flags & 037);
528760Speter #ifndef PI0
529760Speter 			if (p->nl_flags & NMOD)
530760Speter 				pchr('M');
531760Speter 			if (p->nl_flags & NUSED)
532760Speter 				pchr('U');
533760Speter #endif
534760Speter 			if (p->nl_flags & NFILES)
535760Speter 				pchr('F');
536760Speter 		} else
537760Speter 			printf(stars);
538760Speter 		if (p->type)
539760Speter 			printf("\t[%d]", nloff(p->type));
540760Speter 		else
541760Speter 			printf(stars);
542760Speter 		v = p->value[0];
543760Speter 		switch (p->class) {
544760Speter 			case TYPE:
545760Speter 				break;
546760Speter 			case VARNT:
547760Speter 				goto con;
548760Speter 			case CONST:
549760Speter 				switch (nloff(p->type)) {
550760Speter 					default:
551760Speter 						printf("\t%d", v);
552760Speter 						break;
553760Speter 					case TDOUBLE:
554760Speter 						printf("\t%f", p->real);
555760Speter 						break;
556760Speter 					case TINT:
557760Speter 					case T4INT:
558760Speter con:
559760Speter 						printf("\t%ld", p->range[0]);
560760Speter 						break;
561760Speter 					case TSTR:
562760Speter 						printf("\t'%s'", p->ptr[0]);
563760Speter 						break;
564760Speter 					}
565760Speter 				break;
566760Speter 			case VAR:
567760Speter 			case REF:
568760Speter 			case WITHPTR:
569*1197Speter 			case FFUNC:
570*1197Speter 			case FPROC:
571760Speter 				printf("\t%d,%d", cbn, v);
572760Speter 				break;
573760Speter 			case SCAL:
574760Speter 			case RANGE:
575760Speter 				printf("\t%ld..%ld", p->range[0], p->range[1]);
576760Speter 				break;
577760Speter 			case RECORD:
578760Speter 				printf("\t%d(%d)", v, p->value[NL_FLDSZ]);
579760Speter 				break;
580760Speter 			case FIELD:
581760Speter 				printf("\t%d", v);
582760Speter 				break;
583760Speter 			case STR:
584760Speter 				printf("\t|%d|", p->value[0]);
585760Speter 				break;
586760Speter 			case FVAR:
587760Speter 			case FUNC:
588760Speter 			case PROC:
589760Speter 			case PROG:
590760Speter 				if (cbn == 0) {
591760Speter 					printf("\t<%o>", p->value[0] & 0377);
592760Speter #ifndef PI0
593760Speter 					if (p->value[0] & NSTAND)
594760Speter 						printf("\tNSTAND");
595760Speter #endif
596760Speter 					break;
597760Speter 				}
598760Speter 				v = p->value[1];
599760Speter 			default:
600760Speter casedef:
601760Speter 				if (v)
602760Speter 					printf("\t<%d>", v);
603760Speter 				else
604760Speter 					printf(stars);
605760Speter 		}
606760Speter 		if (p->chain)
607760Speter 			printf("\t[%d]", nloff(p->chain));
608760Speter 		switch (p->class) {
609760Speter 			case RECORD:
610760Speter 				if (p->ptr[NL_VARNT])
611760Speter 					printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT]));
612760Speter 				if (p->ptr[NL_TAG])
613760Speter 					printf(" TAG=[%d]", nloff(p->ptr[NL_TAG]));
614760Speter 				break;
615760Speter 			case VARNT:
616760Speter 				printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC]));
617760Speter 				break;
618760Speter 		}
619760Speter #		ifdef PTREE
620760Speter 		    pchr( '\t' );
621760Speter 		    pPrintPointer( stdout , "%s" , p -> inTree );
622760Speter #		endif
623760Speter 		pchr('\n');
624760Speter 	}
625760Speter 	if (head == 0)
626760Speter 		printf("\tNo entries\n");
627760Speter }
628760Speter #endif
629760Speter 
630760Speter 
631760Speter /*
632760Speter  * Define a new name list entry
633760Speter  * with initial symbol, class, type
634760Speter  * and value[0] as given.  A new name
635760Speter  * list segment is allocated to hold
636760Speter  * the next name list slot if necessary.
637760Speter  */
638760Speter struct nl *
639760Speter defnl(sym, cls, typ, val)
640760Speter 	char *sym;
641760Speter 	int cls;
642760Speter 	struct nl *typ;
643760Speter 	int val;
644760Speter {
645760Speter 	register struct nl *p;
646760Speter 	register int *q, i;
647760Speter 	char *cp;
648760Speter 
649760Speter 	p = nlp;
650760Speter 
651760Speter 	/*
652760Speter 	 * Zero out this entry
653760Speter 	 */
654760Speter 	q = p;
655760Speter 	i = (sizeof *p)/(sizeof (int));
656760Speter 	do
657760Speter 		*q++ = 0;
658760Speter 	while (--i);
659760Speter 
660760Speter 	/*
661760Speter 	 * Insert the values
662760Speter 	 */
663760Speter 	p->symbol = sym;
664760Speter 	p->class = cls;
665760Speter 	p->type = typ;
666760Speter 	p->nl_block = cbn;
667760Speter 	p->value[0] = val;
668760Speter 
669760Speter 	/*
670760Speter 	 * Insure that the next namelist
671760Speter 	 * entry actually exists. This is
672760Speter 	 * really not needed here, it would
673760Speter 	 * suffice to do it at entry if we
674760Speter 	 * need the slot.  It is done this
675760Speter 	 * way because, historically, nlp
676760Speter 	 * always pointed at the next namelist
677760Speter 	 * slot.
678760Speter 	 */
679760Speter 	nlp++;
680760Speter 	if (nlp >= nlact->nls_high) {
681760Speter 		i = NLINC;
682760Speter 		cp = malloc(NLINC * sizeof *nlp);
683760Speter 		if (cp == -1) {
684760Speter 			i = NLINC / 2;
685760Speter 			cp = malloc((NLINC / 2) * sizeof *nlp);
686760Speter 		}
687760Speter 		if (cp == -1) {
688760Speter 			error("Ran out of memory (defnl)");
689760Speter 			pexit(DIED);
690760Speter 		}
691760Speter 		nlact++;
692760Speter 		if (nlact >= &ntab[MAXNL]) {
693760Speter 			error("Ran out of name list tables");
694760Speter 			pexit(DIED);
695760Speter 		}
696760Speter 		nlp = cp;
697760Speter 		nlact->nls_low = nlp;
698760Speter 		nlact->nls_high = nlact->nls_low + i;
699760Speter 	}
700760Speter 	return (p);
701760Speter }
702760Speter 
703760Speter /*
704760Speter  * Make a duplicate of the argument
705760Speter  * namelist entry for, e.g., type
706760Speter  * declarations of the form 'type a = b'
707760Speter  * and array indicies.
708760Speter  */
709760Speter struct nl *
710760Speter nlcopy(p)
711760Speter 	struct nl *p;
712760Speter {
713760Speter 	register int *p1, *p2, i;
714760Speter 
715760Speter 	p1 = p;
716760Speter 	p = p2 = defnl(0, 0, 0, 0);
717760Speter 	i = (sizeof *p)/(sizeof (int));
718760Speter 	do
719760Speter 		*p2++ = *p1++;
720760Speter 	while (--i);
721760Speter 	p->chain = NIL;
722760Speter 	return (p);
723760Speter }
724760Speter 
725760Speter /*
726760Speter  * Compute a namelist offset
727760Speter  */
728760Speter nloff(p)
729760Speter 	struct nl *p;
730760Speter {
731760Speter 
732760Speter 	return (p - nl);
733760Speter }
734760Speter 
735760Speter /*
736760Speter  * Enter a symbol into the block
737760Speter  * symbol table.  Symbols are hashed
738760Speter  * 64 ways based on low 6 bits of the
739760Speter  * character pointer into the string
740760Speter  * table.
741760Speter  */
742760Speter struct nl *
743760Speter enter(np)
744760Speter 	struct nl *np;
745760Speter {
746760Speter 	register struct nl *rp, *hp;
747760Speter 	register struct nl *p;
748760Speter 	int i;
749760Speter 
750760Speter 	rp = np;
751760Speter 	if (rp == NIL)
752760Speter 		return (NIL);
753760Speter #ifndef PI1
754760Speter 	if (cbn > 0)
755760Speter 		if (rp->symbol == input->symbol || rp->symbol == output->symbol)
756760Speter 			error("Pre-defined files input and output must not be redefined");
757760Speter #endif
758760Speter 	i = rp->symbol;
759760Speter 	i &= 077;
760760Speter 	hp = disptab[i];
761760Speter 	if (rp->class != BADUSE && rp->class != FIELD)
762760Speter 	for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next)
763760Speter 		if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) {
764760Speter #ifndef PI1
765760Speter 			error("%s is already defined in this block", rp->symbol);
766760Speter #endif
767760Speter 			break;
768760Speter 
769760Speter 		}
770760Speter 	rp->nl_next = hp;
771760Speter 	disptab[i] = rp;
772760Speter 	return (rp);
773760Speter }
774760Speter #endif
775