xref: /csrg-svn/usr.bin/pascal/src/nl.c (revision 7914)
1760Speter /* Copyright (c) 1979 Regents of the University of California */
2760Speter 
3*7914Smckusick static	char sccsid[] = "@(#)nl.c 1.7 08/26/82";
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,
217*7914Smckusick 	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
2656356Speter #ifdef OBJ
266760Speter 		genmx();
2676356Speter #endif OBJ
268760Speter #endif
269760Speter 	    }
270760Speter #endif
271760Speter 	ntab[0].nls_low = nl;
272760Speter 	ntab[0].nls_high = &nl[INL];
273760Speter 	defnl ( 0 , 0 , 0 , 0 );
274760Speter 
275760Speter 	/*
276760Speter 	 *	Types
277760Speter 	 */
278760Speter 	for ( cp = in_types ; *cp != 0 ; cp ++ )
279760Speter 	    hdefnl ( *cp , TYPE , nlp , 0 );
280760Speter 
281760Speter 	/*
282760Speter 	 *	Ranges
283760Speter 	 */
284760Speter 	lp = in_ranges;
285760Speter 	for ( ip = in_rclasses ; *ip != 0 ; ip ++ )
286760Speter 	    {
287760Speter 		np = defnl ( 0 , RANGE , nl+(*ip) , 0 );
288760Speter 		nl[*ip].type = np;
289760Speter 		np -> range[0] = *lp ++ ;
290760Speter 		np -> range[1] = *lp ++ ;
291760Speter 
292760Speter 	    };
293760Speter 
294760Speter 	/*
295760Speter 	 *	built in constructed types
296760Speter 	 */
297760Speter 
298760Speter 	cp = in_ctypes;
299760Speter 	/*
300760Speter 	 *	Boolean = boolean;
301760Speter 	 */
302760Speter 	hdefnl ( *cp++ , TYPE , nl+T1BOOL , 0 );
303760Speter 
304760Speter 	/*
305760Speter 	 *	intset = set of 0 .. 127;
306760Speter 	 */
307760Speter 	intset = *cp++;
308760Speter 	hdefnl( intset , TYPE , nlp+1 , 0 );
309760Speter 	defnl ( 0 , SET , nlp+1 , 0 );
310760Speter 	np = defnl ( 0 , RANGE , nl+TINT , 0 );
311760Speter 	np -> range[0] = 0L;
312760Speter 	np -> range[1] = 127L;
313760Speter 
314760Speter 	/*
315760Speter 	 *	alfa = array [ 1 .. 10 ] of char;
316760Speter 	 */
317760Speter 	np = defnl ( 0 , RANGE , nl+TINT , 0 );
318760Speter 	np -> range[0] = 1L;
319760Speter 	np -> range[1] = 10L;
320760Speter 	defnl ( 0 , ARRAY , nl+T1CHAR , 1 ) -> chain = np;
321760Speter 	hdefnl ( *cp++ , TYPE , nlp-1 , 0 );
322760Speter 
323760Speter 	/*
324760Speter 	 *	text = file of char;
325760Speter 	 */
326760Speter 	hdefnl ( *cp++ , TYPE , nlp+1 , 0 );
327760Speter 	np = defnl ( 0 , FILET , nl+T1CHAR , 0 );
328760Speter 	np -> nl_flags |= NFILES;
329760Speter 
330760Speter 	/*
331760Speter 	 *	input,output : text;
332760Speter 	 */
333760Speter 	cp = in_vars;
334760Speter #	ifndef	PI0
335760Speter 		input = hdefnl ( *cp++ , VAR , np , INPUT_OFF );
336760Speter 		output = hdefnl (  *cp++ , VAR , np , OUTPUT_OFF );
337760Speter #	else
338760Speter 		input = hdefnl ( *cp++ , VAR , np , 0 );
339760Speter 		output = hdefnl ( *cp++ , VAR , np , 0 );
340760Speter #	endif
3413828Speter #	ifdef PC
3423828Speter 	    input -> extra_flags |= NGLOBAL;
3433828Speter 	    output -> extra_flags |= NGLOBAL;
3443828Speter #	endif PC
345760Speter 
346760Speter 	/*
347760Speter 	 *	built in constants
348760Speter 	 */
349760Speter 	cp = in_consts;
350760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
351760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
352760Speter 	(nl + TBOOL)->chain = fp;
353760Speter 	fp->chain = np;
354760Speter 	np = hdefnl ( *cp++ , CONST , nl + TBOOL , 1 );
355760Speter 	fp = hdefnl ( *cp++ , CONST , nl + TBOOL , 0 );
356760Speter 	fp->chain = np;
357760Speter 	if (opt('s'))
358760Speter 		(nl + TBOOL)->chain = fp;
359760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MININT;
360760Speter 	hdefnl ( *cp++ , CONST , nl + T4INT , 0 ) -> range[0] = MAXINT;
361760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 0 );
362760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , 127 );
363760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\007' );
364760Speter 	hdefnl ( *cp++ , CONST , nl + T1CHAR , '\t' );
365760Speter 
366760Speter 	/*
367760Speter 	 * Built-in functions and procedures
368760Speter 	 */
369760Speter #ifndef PI0
370760Speter 	ip = in_fops;
371760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
372760Speter 	    hdefnl ( *cp , FUNC , 0 , * ip ++ );
373760Speter 	ip = in_pops;
374760Speter 	for ( cp = in_procs ; *cp != 0 ; cp ++ )
375760Speter 	    hdefnl ( *cp , PROC , 0 , * ip ++ );
376760Speter #else
377760Speter 	for ( cp = in_funcs ; *cp != 0 ; cp ++ )
378760Speter 	    hdefnl ( *cp , FUNC , 0 , 0 );
379760Speter 	for ( cp = in_procs ; *cp != 0 , cp ++ )
380760Speter 	    hdefnl ( *cp , PROC , 0 , 0 );
381760Speter #endif
382760Speter #	ifdef PTREE
383760Speter 	    pTreeInit();
384760Speter #	endif
385760Speter     }
386760Speter 
387760Speter struct nl *
388760Speter hdefnl(sym, cls, typ, val)
389760Speter {
390760Speter 	register struct nl *p;
391760Speter 
392760Speter #ifndef PI1
393760Speter 	if (sym)
394760Speter 		hash(sym, 0);
395760Speter #endif
396760Speter 	p = defnl(sym, cls, typ, val);
397760Speter 	if (sym)
398760Speter 		enter(p);
399760Speter 	return (p);
400760Speter }
401760Speter 
402760Speter /*
403760Speter  * Free up the name list segments
404760Speter  * at the end of a statement/proc/func
405760Speter  * All segments are freed down to the one in which
406760Speter  * p points.
407760Speter  */
408760Speter nlfree(p)
409760Speter 	struct nl *p;
410760Speter {
411760Speter 
412760Speter 	nlp = p;
413760Speter 	while (nlact->nls_low > nlp || nlact->nls_high < nlp) {
414760Speter 		free(nlact->nls_low);
415760Speter 		nlact->nls_low = NIL;
416760Speter 		nlact->nls_high = NIL;
417760Speter 		--nlact;
418760Speter 		if (nlact < &ntab[0])
419760Speter 			panic("nlfree");
420760Speter 	}
421760Speter }
422760Speter 
423760Speter 
424760Speter char	*VARIABLE	= "variable";
425760Speter 
426760Speter char	*classes[ ] = {
427760Speter 	"undefined",
428760Speter 	"constant",
429760Speter 	"type",
430760Speter 	"variable",	/*	VARIABLE	*/
431760Speter 	"array",
432760Speter 	"pointer or file",
433760Speter 	"record",
434760Speter 	"field",
435760Speter 	"procedure",
436760Speter 	"function",
437760Speter 	"variable",	/*	VARIABLE	*/
438760Speter 	"variable",	/*	VARIABLE	*/
439760Speter 	"pointer",
440760Speter 	"file",
441760Speter 	"set",
442760Speter 	"subrange",
443760Speter 	"label",
444760Speter 	"withptr",
445760Speter 	"scalar",
446760Speter 	"string",
447760Speter 	"program",
4481197Speter 	"improper",
4491197Speter 	"variant",
4501197Speter 	"formal procedure",
4511197Speter 	"formal function"
452760Speter };
453760Speter 
454760Speter char	*snark	= "SNARK";
455760Speter 
456760Speter #ifdef PI
457760Speter #ifdef DEBUG
458760Speter char	*ctext[] =
459760Speter {
460760Speter 	"BADUSE",
461760Speter 	"CONST",
462760Speter 	"TYPE",
463760Speter 	"VAR",
464760Speter 	"ARRAY",
465760Speter 	"PTRFILE",
466760Speter 	"RECORD",
467760Speter 	"FIELD",
468760Speter 	"PROC",
469760Speter 	"FUNC",
470760Speter 	"FVAR",
471760Speter 	"REF",
472760Speter 	"PTR",
473760Speter 	"FILET",
474760Speter 	"SET",
475760Speter 	"RANGE",
476760Speter 	"LABEL",
477760Speter 	"WITHPTR",
478760Speter 	"SCAL",
479760Speter 	"STR",
480760Speter 	"PROG",
481760Speter 	"IMPROPER",
4821197Speter 	"VARNT",
4831197Speter 	"FPROC",
4841197Speter 	"FFUNC"
485760Speter };
486760Speter 
487760Speter char	*stars	= "\t***";
488760Speter 
489760Speter /*
490760Speter  * Dump the namelist from the
491760Speter  * current nlp down to 'to'.
492760Speter  * All the namelist is dumped if
493760Speter  * to is NIL.
494760Speter  */
495760Speter dumpnl(to, rout)
496760Speter 	struct nl *to;
497760Speter {
498760Speter 	register struct nl *p;
499760Speter 	register int j;
500760Speter 	struct nls *nlsp;
501760Speter 	int i, v, head;
502760Speter 
503760Speter 	if (opt('y') == 0)
504760Speter 		return;
505760Speter 	if (to != NIL)
506760Speter 		printf("\n\"%s\" Block=%d\n", rout, cbn);
507760Speter 	nlsp = nlact;
508760Speter 	head = NIL;
509760Speter 	for (p = nlp; p != to;) {
510760Speter 		if (p == nlsp->nls_low) {
511760Speter 			if (nlsp == &ntab[0])
512760Speter 				break;
513760Speter 			nlsp--;
514760Speter 			p = nlsp->nls_high;
515760Speter 		}
516760Speter 		p--;
517760Speter 		if (head == NIL) {
518760Speter 			printf("\tName\tClass  Bn+Flags\tType\tVal\tChn\n");
519760Speter 			head++;
520760Speter 		}
521760Speter 		printf("%3d:", nloff(p));
522760Speter 		if (p->symbol)
523760Speter 			printf("\t%.7s", p->symbol);
524760Speter 		else
525760Speter 			printf(stars);
526760Speter 		if (p->class)
527760Speter 			printf("\t%s", ctext[p->class]);
528760Speter 		else
529760Speter 			printf(stars);
530760Speter 		if (p->nl_flags) {
531760Speter 			pchr('\t');
532760Speter 			if (p->nl_flags & 037)
533760Speter 				printf("%d ", p->nl_flags & 037);
534760Speter #ifndef PI0
535760Speter 			if (p->nl_flags & NMOD)
536760Speter 				pchr('M');
537760Speter 			if (p->nl_flags & NUSED)
538760Speter 				pchr('U');
539760Speter #endif
540760Speter 			if (p->nl_flags & NFILES)
541760Speter 				pchr('F');
542760Speter 		} else
543760Speter 			printf(stars);
544760Speter 		if (p->type)
545760Speter 			printf("\t[%d]", nloff(p->type));
546760Speter 		else
547760Speter 			printf(stars);
548760Speter 		v = p->value[0];
549760Speter 		switch (p->class) {
550760Speter 			case TYPE:
551760Speter 				break;
552760Speter 			case VARNT:
553760Speter 				goto con;
554760Speter 			case CONST:
555760Speter 				switch (nloff(p->type)) {
556760Speter 					default:
557760Speter 						printf("\t%d", v);
558760Speter 						break;
559760Speter 					case TDOUBLE:
560760Speter 						printf("\t%f", p->real);
561760Speter 						break;
562760Speter 					case TINT:
563760Speter 					case T4INT:
564760Speter con:
565760Speter 						printf("\t%ld", p->range[0]);
566760Speter 						break;
567760Speter 					case TSTR:
568760Speter 						printf("\t'%s'", p->ptr[0]);
569760Speter 						break;
570760Speter 					}
571760Speter 				break;
572760Speter 			case VAR:
573760Speter 			case REF:
574760Speter 			case WITHPTR:
5751197Speter 			case FFUNC:
5761197Speter 			case FPROC:
577760Speter 				printf("\t%d,%d", cbn, v);
578760Speter 				break;
579760Speter 			case SCAL:
580760Speter 			case RANGE:
581760Speter 				printf("\t%ld..%ld", p->range[0], p->range[1]);
582760Speter 				break;
583760Speter 			case RECORD:
584760Speter 				printf("\t%d(%d)", v, p->value[NL_FLDSZ]);
585760Speter 				break;
586760Speter 			case FIELD:
587760Speter 				printf("\t%d", v);
588760Speter 				break;
589760Speter 			case STR:
590760Speter 				printf("\t|%d|", p->value[0]);
591760Speter 				break;
592760Speter 			case FVAR:
593760Speter 			case FUNC:
594760Speter 			case PROC:
595760Speter 			case PROG:
596760Speter 				if (cbn == 0) {
597760Speter 					printf("\t<%o>", p->value[0] & 0377);
598760Speter #ifndef PI0
599760Speter 					if (p->value[0] & NSTAND)
600760Speter 						printf("\tNSTAND");
601760Speter #endif
602760Speter 					break;
603760Speter 				}
604760Speter 				v = p->value[1];
605760Speter 			default:
606760Speter casedef:
607760Speter 				if (v)
608760Speter 					printf("\t<%d>", v);
609760Speter 				else
610760Speter 					printf(stars);
611760Speter 		}
612760Speter 		if (p->chain)
613760Speter 			printf("\t[%d]", nloff(p->chain));
614760Speter 		switch (p->class) {
615760Speter 			case RECORD:
616760Speter 				if (p->ptr[NL_VARNT])
617760Speter 					printf("\tVARNT=[%d]", nloff(p->ptr[NL_VARNT]));
618760Speter 				if (p->ptr[NL_TAG])
619760Speter 					printf(" TAG=[%d]", nloff(p->ptr[NL_TAG]));
620760Speter 				break;
621760Speter 			case VARNT:
622760Speter 				printf("\tVTOREC=[%d]", nloff(p->ptr[NL_VTOREC]));
623760Speter 				break;
624760Speter 		}
6253828Speter #		ifdef PC
6263828Speter 		    if ( p -> extra_flags != 0 ) {
6273828Speter 			pchr( '\t' );
6283828Speter 			if ( p -> extra_flags & NEXTERN )
6293828Speter 			    printf( "NEXTERN " );
6303828Speter 			if ( p -> extra_flags & NLOCAL )
6313828Speter 			    printf( "NLOCAL " );
6323828Speter 			if ( p -> extra_flags & NPARAM )
6333828Speter 			    printf( "NPARAM " );
6343828Speter 			if ( p -> extra_flags & NGLOBAL )
6353828Speter 			    printf( "NGLOBAL " );
6363828Speter 			if ( p -> extra_flags & NREGVAR )
6373828Speter 			    printf( "NREGVAR " );
6383828Speter 		    }
6393828Speter #		endif PC
640760Speter #		ifdef PTREE
641760Speter 		    pchr( '\t' );
642760Speter 		    pPrintPointer( stdout , "%s" , p -> inTree );
643760Speter #		endif
644760Speter 		pchr('\n');
645760Speter 	}
646760Speter 	if (head == 0)
647760Speter 		printf("\tNo entries\n");
648760Speter }
649760Speter #endif
650760Speter 
651760Speter 
652760Speter /*
653760Speter  * Define a new name list entry
654760Speter  * with initial symbol, class, type
655760Speter  * and value[0] as given.  A new name
656760Speter  * list segment is allocated to hold
657760Speter  * the next name list slot if necessary.
658760Speter  */
659760Speter struct nl *
660760Speter defnl(sym, cls, typ, val)
661760Speter 	char *sym;
662760Speter 	int cls;
663760Speter 	struct nl *typ;
664760Speter 	int val;
665760Speter {
666760Speter 	register struct nl *p;
667760Speter 	register int *q, i;
668760Speter 	char *cp;
669760Speter 
670760Speter 	p = nlp;
671760Speter 
672760Speter 	/*
673760Speter 	 * Zero out this entry
674760Speter 	 */
675760Speter 	q = p;
676760Speter 	i = (sizeof *p)/(sizeof (int));
677760Speter 	do
678760Speter 		*q++ = 0;
679760Speter 	while (--i);
680760Speter 
681760Speter 	/*
682760Speter 	 * Insert the values
683760Speter 	 */
684760Speter 	p->symbol = sym;
685760Speter 	p->class = cls;
686760Speter 	p->type = typ;
687760Speter 	p->nl_block = cbn;
688760Speter 	p->value[0] = val;
689760Speter 
690760Speter 	/*
691760Speter 	 * Insure that the next namelist
692760Speter 	 * entry actually exists. This is
693760Speter 	 * really not needed here, it would
694760Speter 	 * suffice to do it at entry if we
695760Speter 	 * need the slot.  It is done this
696760Speter 	 * way because, historically, nlp
697760Speter 	 * always pointed at the next namelist
698760Speter 	 * slot.
699760Speter 	 */
700760Speter 	nlp++;
701760Speter 	if (nlp >= nlact->nls_high) {
702760Speter 		i = NLINC;
703760Speter 		cp = malloc(NLINC * sizeof *nlp);
7041834Speter 		if (cp == 0) {
705760Speter 			i = NLINC / 2;
706760Speter 			cp = malloc((NLINC / 2) * sizeof *nlp);
707760Speter 		}
7081834Speter 		if (cp == 0) {
709760Speter 			error("Ran out of memory (defnl)");
710760Speter 			pexit(DIED);
711760Speter 		}
712760Speter 		nlact++;
713760Speter 		if (nlact >= &ntab[MAXNL]) {
714760Speter 			error("Ran out of name list tables");
715760Speter 			pexit(DIED);
716760Speter 		}
717760Speter 		nlp = cp;
718760Speter 		nlact->nls_low = nlp;
719760Speter 		nlact->nls_high = nlact->nls_low + i;
720760Speter 	}
721760Speter 	return (p);
722760Speter }
723760Speter 
724760Speter /*
725760Speter  * Make a duplicate of the argument
726760Speter  * namelist entry for, e.g., type
727760Speter  * declarations of the form 'type a = b'
728760Speter  * and array indicies.
729760Speter  */
730760Speter struct nl *
731760Speter nlcopy(p)
732760Speter 	struct nl *p;
733760Speter {
734760Speter 	register int *p1, *p2, i;
735760Speter 
736760Speter 	p1 = p;
737760Speter 	p = p2 = defnl(0, 0, 0, 0);
738760Speter 	i = (sizeof *p)/(sizeof (int));
739760Speter 	do
740760Speter 		*p2++ = *p1++;
741760Speter 	while (--i);
742760Speter 	p->chain = NIL;
743760Speter 	return (p);
744760Speter }
745760Speter 
746760Speter /*
747760Speter  * Compute a namelist offset
748760Speter  */
749760Speter nloff(p)
750760Speter 	struct nl *p;
751760Speter {
752760Speter 
753760Speter 	return (p - nl);
754760Speter }
755760Speter 
756760Speter /*
757760Speter  * Enter a symbol into the block
758760Speter  * symbol table.  Symbols are hashed
759760Speter  * 64 ways based on low 6 bits of the
760760Speter  * character pointer into the string
761760Speter  * table.
762760Speter  */
763760Speter struct nl *
764760Speter enter(np)
765760Speter 	struct nl *np;
766760Speter {
767760Speter 	register struct nl *rp, *hp;
768760Speter 	register struct nl *p;
769760Speter 	int i;
770760Speter 
771760Speter 	rp = np;
772760Speter 	if (rp == NIL)
773760Speter 		return (NIL);
774760Speter #ifndef PI1
775760Speter 	if (cbn > 0)
776760Speter 		if (rp->symbol == input->symbol || rp->symbol == output->symbol)
777760Speter 			error("Pre-defined files input and output must not be redefined");
778760Speter #endif
779760Speter 	i = rp->symbol;
780760Speter 	i &= 077;
781760Speter 	hp = disptab[i];
782760Speter 	if (rp->class != BADUSE && rp->class != FIELD)
783760Speter 	for (p = hp; p != NIL && (p->nl_block & 037) == cbn; p = p->nl_next)
784760Speter 		if (p->symbol == rp->symbol && p->class != BADUSE && p->class != FIELD) {
785760Speter #ifndef PI1
786760Speter 			error("%s is already defined in this block", rp->symbol);
787760Speter #endif
788760Speter 			break;
789760Speter 
790760Speter 		}
791760Speter 	rp->nl_next = hp;
792760Speter 	disptab[i] = rp;
793760Speter 	return (rp);
794760Speter }
795760Speter #endif
796