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