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