xref: /freebsd/contrib/one-true-awk/parse.c (revision eb690a05)
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 
nodealloc(size_t n)32 Node *nodealloc(size_t 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 
exptostat(Node * a)44 Node *exptostat(Node *a)
45 {
46 	a->ntype = NSTAT;
47 	return(a);
48 }
49 
node1(int a,Node * b)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 
node2(int a,Node * b,Node * c)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 
node3(int a,Node * b,Node * c,Node * d)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 
node4(int a,Node * b,Node * c,Node * d,Node * e)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 
node5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)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 
stat1(int a,Node * b)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 
stat2(int a,Node * b,Node * c)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 
stat3(int a,Node * b,Node * c,Node * d)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 
stat4(int a,Node * b,Node * c,Node * d,Node * e)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 
op1(int a,Node * b)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 
op2(int a,Node * b,Node * c)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 
op3(int a,Node * b,Node * c,Node * d)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 
op4(int a,Node * b,Node * c,Node * d,Node * e)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 
op5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)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 
celltonode(Cell * a,int b)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 
rectonode(void)202 Node *rectonode(void)	/* make $0 into a Node */
203 {
204 	extern Cell *literal0;
205 	return op1(INDIRECT, celltonode(literal0, CUNK));
206 }
207 
makearr(Node * p)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 
pa2stat(Node * a,Node * b,Node * c)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 
linkum(Node * a,Node * b)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 
defn(Cell * v,Node * vl,Node * st)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 
isarg(const char * s)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 
ptoi(void * p)291 int ptoi(void *p)	/* convert pointer to integer */
292 {
293 	return (int) (long) p;	/* swearing that p fits, of course */
294 }
295 
itonp(int i)296 Node *itonp(int i)	/* and vice versa */
297 {
298 	return (Node *) (long) i;
299 }
300