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