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