1/****************************************************************
2Copyright (C) Lucent Technologies 1997
3All Rights Reserved
4
5Permission to use, copy, modify, and distribute this software and
6its documentation for any purpose and without fee is hereby
7granted, provided that the above copyright notice appear in all
8copies and that both that the copyright notice and this
9permission notice and warranty disclaimer appear in supporting
10documentation, and that the name Lucent Technologies or any of
11its entities not be used in advertising or publicity pertaining
12to distribution of the software without specific, written prior
13permission.
14
15LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22THIS SOFTWARE.
23****************************************************************/
24
25#define DEBUG
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include "awk.h"
30#include "ytab.h"
31
32Node *nodealloc(int n)
33{
34	Node *x;
35
36	x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *));
37	if (x == NULL)
38		FATAL("out of space in nodealloc");
39	x->nnext = NULL;
40	x->lineno = lineno;
41	return(x);
42}
43
44Node *exptostat(Node *a)
45{
46	a->ntype = NSTAT;
47	return(a);
48}
49
50Node *node1(int a, Node *b)
51{
52	Node *x;
53
54	x = nodealloc(1);
55	x->nobj = a;
56	x->narg[0]=b;
57	return(x);
58}
59
60Node *node2(int a, Node *b, Node *c)
61{
62	Node *x;
63
64	x = nodealloc(2);
65	x->nobj = a;
66	x->narg[0] = b;
67	x->narg[1] = c;
68	return(x);
69}
70
71Node *node3(int a, Node *b, Node *c, Node *d)
72{
73	Node *x;
74
75	x = nodealloc(3);
76	x->nobj = a;
77	x->narg[0] = b;
78	x->narg[1] = c;
79	x->narg[2] = d;
80	return(x);
81}
82
83Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
84{
85	Node *x;
86
87	x = nodealloc(4);
88	x->nobj = a;
89	x->narg[0] = b;
90	x->narg[1] = c;
91	x->narg[2] = d;
92	x->narg[3] = e;
93	return(x);
94}
95
96Node *stat1(int a, Node *b)
97{
98	Node *x;
99
100	x = node1(a,b);
101	x->ntype = NSTAT;
102	return(x);
103}
104
105Node *stat2(int a, Node *b, Node *c)
106{
107	Node *x;
108
109	x = node2(a,b,c);
110	x->ntype = NSTAT;
111	return(x);
112}
113
114Node *stat3(int a, Node *b, Node *c, Node *d)
115{
116	Node *x;
117
118	x = node3(a,b,c,d);
119	x->ntype = NSTAT;
120	return(x);
121}
122
123Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
124{
125	Node *x;
126
127	x = node4(a,b,c,d,e);
128	x->ntype = NSTAT;
129	return(x);
130}
131
132Node *op1(int a, Node *b)
133{
134	Node *x;
135
136	x = node1(a,b);
137	x->ntype = NEXPR;
138	return(x);
139}
140
141Node *op2(int a, Node *b, Node *c)
142{
143	Node *x;
144
145	x = node2(a,b,c);
146	x->ntype = NEXPR;
147	return(x);
148}
149
150Node *op3(int a, Node *b, Node *c, Node *d)
151{
152	Node *x;
153
154	x = node3(a,b,c,d);
155	x->ntype = NEXPR;
156	return(x);
157}
158
159Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
160{
161	Node *x;
162
163	x = node4(a,b,c,d,e);
164	x->ntype = NEXPR;
165	return(x);
166}
167
168Node *celltonode(Cell *a, int b)
169{
170	Node *x;
171
172	a->ctype = OCELL;
173	a->csub = b;
174	x = node1(0, (Node *) a);
175	x->ntype = NVALUE;
176	return(x);
177}
178
179Node *rectonode(void)	/* make $0 into a Node */
180{
181	extern Cell *literal0;
182	return op1(INDIRECT, celltonode(literal0, CUNK));
183}
184
185Node *makearr(Node *p)
186{
187	Cell *cp;
188
189	if (isvalue(p)) {
190		cp = (Cell *) (p->narg[0]);
191		if (isfcn(cp))
192			SYNTAX( "%s is a function, not an array", cp->nval );
193		else if (!isarr(cp)) {
194			xfree(cp->sval);
195			cp->sval = (char *) makesymtab(NSYMTAB);
196			cp->tval = ARR;
197		}
198	}
199	return p;
200}
201
202#define PA2NUM	50	/* max number of pat,pat patterns allowed */
203int	paircnt;		/* number of them in use */
204int	pairstack[PA2NUM];	/* state of each pat,pat */
205
206Node *pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
207{
208	Node *x;
209
210	x = node4(PASTAT2, a, b, c, itonp(paircnt));
211	if (paircnt++ >= PA2NUM)
212		SYNTAX( "limited to %d pat,pat statements", PA2NUM );
213	x->ntype = NSTAT;
214	return(x);
215}
216
217Node *linkum(Node *a, Node *b)
218{
219	Node *c;
220
221	if (errorflag)	/* don't link things that are wrong */
222		return a;
223	if (a == NULL)
224		return(b);
225	else if (b == NULL)
226		return(a);
227	for (c = a; c->nnext != NULL; c = c->nnext)
228		;
229	c->nnext = b;
230	return(a);
231}
232
233void defn(Cell *v, Node *vl, Node *st)	/* turn on FCN bit in definition, */
234{					/*   body of function, arglist */
235	Node *p;
236	int n;
237
238	if (isarr(v)) {
239		SYNTAX( "`%s' is an array name and a function name", v->nval );
240		return;
241	}
242	if (isarg(v->nval) != -1) {
243		SYNTAX( "`%s' is both function name and argument name", v->nval );
244		return;
245	}
246
247	v->tval = FCN;
248	v->sval = (char *) st;
249	n = 0;	/* count arguments */
250	for (p = vl; p; p = p->nnext)
251		n++;
252	v->fval = n;
253	dprintf( ("defining func %s (%d args)\n", v->nval, n) );
254}
255
256int isarg(const char *s)		/* is s in argument list for current function? */
257{			/* return -1 if not, otherwise arg # */
258	extern Node *arglist;
259	Node *p = arglist;
260	int n;
261
262	for (n = 0; p != NULL; p = p->nnext, n++)
263		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
264			return n;
265	return -1;
266}
267
268int ptoi(void *p)	/* convert pointer to integer */
269{
270	return (int) (long) p;	/* swearing that p fits, of course */
271}
272
273Node *itonp(int i)	/* and vice versa */
274{
275	return (Node *) (long) i;
276}
277