xref: /freebsd/contrib/one-true-awk/parse.c (revision eb69d1f144a6fcc765d1b9d44a5ae8082353e70b)
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 "ytab.h"
31 
32 Node *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 
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 *stat1(int a, Node *b)
97 {
98 	Node *x;
99 
100 	x = node1(a,b);
101 	x->ntype = NSTAT;
102 	return(x);
103 }
104 
105 Node *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 
114 Node *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 
123 Node *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 
132 Node *op1(int a, Node *b)
133 {
134 	Node *x;
135 
136 	x = node1(a,b);
137 	x->ntype = NEXPR;
138 	return(x);
139 }
140 
141 Node *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 
150 Node *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 
159 Node *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 
168 Node *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 
179 Node *rectonode(void)	/* make $0 into a Node */
180 {
181 	extern Cell *literal0;
182 	return op1(INDIRECT, celltonode(literal0, CUNK));
183 }
184 
185 Node *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 */
203 int	paircnt;		/* number of them in use */
204 int	pairstack[PA2NUM];	/* state of each pat,pat */
205 
206 Node *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 
217 Node *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 
233 void 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 
256 int 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 
268 int ptoi(void *p)	/* convert pointer to integer */
269 {
270 	return (int) (long) p;	/* swearing that p fits, of course */
271 }
272 
273 Node *itonp(int i)	/* and vice versa */
274 {
275 	return (Node *) (long) i;
276 }
277