1 /* $OpenBSD: parse.c,v 1.14 2023/09/10 14:59:00 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 "awkgram.tab.h"
32
nodealloc(size_t n)33 Node *nodealloc(size_t n)
34 {
35 Node *x;
36
37 x = (Node *) malloc(sizeof(*x) + (n-1) * sizeof(x));
38 if (x == NULL)
39 FATAL("out of space in nodealloc");
40 x->nnext = NULL;
41 x->lineno = lineno;
42 return(x);
43 }
44
exptostat(Node * a)45 Node *exptostat(Node *a)
46 {
47 a->ntype = NSTAT;
48 return(a);
49 }
50
node1(int a,Node * b)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
node2(int a,Node * b,Node * c)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
node3(int a,Node * b,Node * c,Node * d)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
node4(int a,Node * b,Node * c,Node * d,Node * e)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
node5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)97 Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
98 {
99 Node *x;
100
101 x = nodealloc(5);
102 x->nobj = a;
103 x->narg[0] = b;
104 x->narg[1] = c;
105 x->narg[2] = d;
106 x->narg[3] = e;
107 x->narg[4] = f;
108 return(x);
109 }
110
stat1(int a,Node * b)111 Node *stat1(int a, Node *b)
112 {
113 Node *x;
114
115 x = node1(a,b);
116 x->ntype = NSTAT;
117 return(x);
118 }
119
stat2(int a,Node * b,Node * c)120 Node *stat2(int a, Node *b, Node *c)
121 {
122 Node *x;
123
124 x = node2(a,b,c);
125 x->ntype = NSTAT;
126 return(x);
127 }
128
stat3(int a,Node * b,Node * c,Node * d)129 Node *stat3(int a, Node *b, Node *c, Node *d)
130 {
131 Node *x;
132
133 x = node3(a,b,c,d);
134 x->ntype = NSTAT;
135 return(x);
136 }
137
stat4(int a,Node * b,Node * c,Node * d,Node * e)138 Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
139 {
140 Node *x;
141
142 x = node4(a,b,c,d,e);
143 x->ntype = NSTAT;
144 return(x);
145 }
146
op1(int a,Node * b)147 Node *op1(int a, Node *b)
148 {
149 Node *x;
150
151 x = node1(a,b);
152 x->ntype = NEXPR;
153 return(x);
154 }
155
op2(int a,Node * b,Node * c)156 Node *op2(int a, Node *b, Node *c)
157 {
158 Node *x;
159
160 x = node2(a,b,c);
161 x->ntype = NEXPR;
162 return(x);
163 }
164
op3(int a,Node * b,Node * c,Node * d)165 Node *op3(int a, Node *b, Node *c, Node *d)
166 {
167 Node *x;
168
169 x = node3(a,b,c,d);
170 x->ntype = NEXPR;
171 return(x);
172 }
173
op4(int a,Node * b,Node * c,Node * d,Node * e)174 Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
175 {
176 Node *x;
177
178 x = node4(a,b,c,d,e);
179 x->ntype = NEXPR;
180 return(x);
181 }
182
op5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)183 Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
184 {
185 Node *x;
186
187 x = node5(a,b,c,d,e,f);
188 x->ntype = NEXPR;
189 return(x);
190 }
191
celltonode(Cell * a,int b)192 Node *celltonode(Cell *a, int b)
193 {
194 Node *x;
195
196 a->ctype = OCELL;
197 a->csub = b;
198 x = node1(0, (Node *) a);
199 x->ntype = NVALUE;
200 return(x);
201 }
202
rectonode(void)203 Node *rectonode(void) /* make $0 into a Node */
204 {
205 extern Cell *literal0;
206 return op1(INDIRECT, celltonode(literal0, CUNK));
207 }
208
makearr(Node * p)209 Node *makearr(Node *p)
210 {
211 Cell *cp;
212
213 if (isvalue(p)) {
214 cp = (Cell *) (p->narg[0]);
215 if (isfcn(cp))
216 SYNTAX( "%s is a function, not an array", cp->nval );
217 else if (!isarr(cp)) {
218 xfree(cp->sval);
219 cp->sval = (char *) makesymtab(NSYMTAB);
220 cp->tval = ARR;
221 }
222 }
223 return p;
224 }
225
226 #define PA2NUM 50 /* max number of pat,pat patterns allowed */
227 int paircnt; /* number of them in use */
228 int pairstack[PA2NUM]; /* state of each pat,pat */
229
pa2stat(Node * a,Node * b,Node * c)230 Node *pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */
231 {
232 Node *x;
233
234 x = node4(PASTAT2, a, b, c, itonp(paircnt));
235 if (paircnt++ >= PA2NUM)
236 SYNTAX( "limited to %d pat,pat statements", PA2NUM );
237 x->ntype = NSTAT;
238 return(x);
239 }
240
linkum(Node * a,Node * b)241 Node *linkum(Node *a, Node *b)
242 {
243 Node *c;
244
245 if (errorflag) /* don't link things that are wrong */
246 return a;
247 if (a == NULL)
248 return(b);
249 else if (b == NULL)
250 return(a);
251 for (c = a; c->nnext != NULL; c = c->nnext)
252 ;
253 c->nnext = b;
254 return(a);
255 }
256
defn(Cell * v,Node * vl,Node * st)257 void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
258 { /* body of function, arglist */
259 Node *p;
260 int n;
261
262 if (isarr(v)) {
263 SYNTAX( "`%s' is an array name and a function name", v->nval );
264 return;
265 }
266 if (isarg(v->nval) != -1) {
267 SYNTAX( "`%s' is both function name and argument name", v->nval );
268 return;
269 }
270
271 v->tval = FCN;
272 v->sval = (char *) st;
273 n = 0; /* count arguments */
274 for (p = vl; p; p = p->nnext)
275 n++;
276 v->fval = n;
277 DPRINTF("defining func %s (%d args)\n", v->nval, n);
278 }
279
isarg(const char * s)280 int isarg(const char *s) /* is s in argument list for current function? */
281 { /* return -1 if not, otherwise arg # */
282 extern Node *arglist;
283 Node *p = arglist;
284 int n;
285
286 for (n = 0; p != NULL; p = p->nnext, n++)
287 if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
288 return n;
289 return -1;
290 }
291
ptoi(void * p)292 int ptoi(void *p) /* convert pointer to integer */
293 {
294 return (int) (long) p; /* swearing that p fits, of course */
295 }
296
itonp(int i)297 Node *itonp(int i) /* and vice versa */
298 {
299 return (Node *) (long) i;
300 }
301