12a55deb1SDavid E. O'Brien /****************************************************************
22a55deb1SDavid E. O'Brien Copyright (C) Lucent Technologies 1997
32a55deb1SDavid E. O'Brien All Rights Reserved
42a55deb1SDavid E. O'Brien
52a55deb1SDavid E. O'Brien Permission to use, copy, modify, and distribute this software and
62a55deb1SDavid E. O'Brien its documentation for any purpose and without fee is hereby
72a55deb1SDavid E. O'Brien granted, provided that the above copyright notice appear in all
82a55deb1SDavid E. O'Brien copies and that both that the copyright notice and this
92a55deb1SDavid E. O'Brien permission notice and warranty disclaimer appear in supporting
102a55deb1SDavid E. O'Brien documentation, and that the name Lucent Technologies or any of
112a55deb1SDavid E. O'Brien its entities not be used in advertising or publicity pertaining
122a55deb1SDavid E. O'Brien to distribution of the software without specific, written prior
132a55deb1SDavid E. O'Brien permission.
142a55deb1SDavid E. O'Brien
152a55deb1SDavid E. O'Brien LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
162a55deb1SDavid E. O'Brien INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
172a55deb1SDavid E. O'Brien IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
182a55deb1SDavid E. O'Brien SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
192a55deb1SDavid E. O'Brien WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
202a55deb1SDavid E. O'Brien IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
212a55deb1SDavid E. O'Brien ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
222a55deb1SDavid E. O'Brien THIS SOFTWARE.
232a55deb1SDavid E. O'Brien ****************************************************************/
242a55deb1SDavid E. O'Brien
252a55deb1SDavid E. O'Brien #define DEBUG
262a55deb1SDavid E. O'Brien #include <stdio.h>
272a55deb1SDavid E. O'Brien #include <string.h>
282a55deb1SDavid E. O'Brien #include <stdlib.h>
292a55deb1SDavid E. O'Brien #include "awk.h"
30f39dd6a9SWarner Losh #include "awkgram.tab.h"
312a55deb1SDavid E. O'Brien
nodealloc(size_t n)32f32a6403SWarner Losh Node *nodealloc(size_t n)
332a55deb1SDavid E. O'Brien {
342a55deb1SDavid E. O'Brien Node *x;
352a55deb1SDavid E. O'Brien
36f39dd6a9SWarner Losh x = (Node *) malloc(sizeof(*x) + (n-1) * sizeof(x));
372a55deb1SDavid E. O'Brien if (x == NULL)
382a55deb1SDavid E. O'Brien FATAL("out of space in nodealloc");
392a55deb1SDavid E. O'Brien x->nnext = NULL;
402a55deb1SDavid E. O'Brien x->lineno = lineno;
412a55deb1SDavid E. O'Brien return(x);
422a55deb1SDavid E. O'Brien }
432a55deb1SDavid E. O'Brien
exptostat(Node * a)442a55deb1SDavid E. O'Brien Node *exptostat(Node *a)
452a55deb1SDavid E. O'Brien {
462a55deb1SDavid E. O'Brien a->ntype = NSTAT;
472a55deb1SDavid E. O'Brien return(a);
482a55deb1SDavid E. O'Brien }
492a55deb1SDavid E. O'Brien
node1(int a,Node * b)502a55deb1SDavid E. O'Brien Node *node1(int a, Node *b)
512a55deb1SDavid E. O'Brien {
522a55deb1SDavid E. O'Brien Node *x;
532a55deb1SDavid E. O'Brien
542a55deb1SDavid E. O'Brien x = nodealloc(1);
552a55deb1SDavid E. O'Brien x->nobj = a;
562a55deb1SDavid E. O'Brien x->narg[0]=b;
572a55deb1SDavid E. O'Brien return(x);
582a55deb1SDavid E. O'Brien }
592a55deb1SDavid E. O'Brien
node2(int a,Node * b,Node * c)602a55deb1SDavid E. O'Brien Node *node2(int a, Node *b, Node *c)
612a55deb1SDavid E. O'Brien {
622a55deb1SDavid E. O'Brien Node *x;
632a55deb1SDavid E. O'Brien
642a55deb1SDavid E. O'Brien x = nodealloc(2);
652a55deb1SDavid E. O'Brien x->nobj = a;
662a55deb1SDavid E. O'Brien x->narg[0] = b;
672a55deb1SDavid E. O'Brien x->narg[1] = c;
682a55deb1SDavid E. O'Brien return(x);
692a55deb1SDavid E. O'Brien }
702a55deb1SDavid E. O'Brien
node3(int a,Node * b,Node * c,Node * d)712a55deb1SDavid E. O'Brien Node *node3(int a, Node *b, Node *c, Node *d)
722a55deb1SDavid E. O'Brien {
732a55deb1SDavid E. O'Brien Node *x;
742a55deb1SDavid E. O'Brien
752a55deb1SDavid E. O'Brien x = nodealloc(3);
762a55deb1SDavid E. O'Brien x->nobj = a;
772a55deb1SDavid E. O'Brien x->narg[0] = b;
782a55deb1SDavid E. O'Brien x->narg[1] = c;
792a55deb1SDavid E. O'Brien x->narg[2] = d;
802a55deb1SDavid E. O'Brien return(x);
812a55deb1SDavid E. O'Brien }
822a55deb1SDavid E. O'Brien
node4(int a,Node * b,Node * c,Node * d,Node * e)832a55deb1SDavid E. O'Brien Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
842a55deb1SDavid E. O'Brien {
852a55deb1SDavid E. O'Brien Node *x;
862a55deb1SDavid E. O'Brien
872a55deb1SDavid E. O'Brien x = nodealloc(4);
882a55deb1SDavid E. O'Brien x->nobj = a;
892a55deb1SDavid E. O'Brien x->narg[0] = b;
902a55deb1SDavid E. O'Brien x->narg[1] = c;
912a55deb1SDavid E. O'Brien x->narg[2] = d;
922a55deb1SDavid E. O'Brien x->narg[3] = e;
932a55deb1SDavid E. O'Brien return(x);
942a55deb1SDavid E. O'Brien }
952a55deb1SDavid E. O'Brien
node5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)96*eb690a05SWarner Losh Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
97*eb690a05SWarner Losh {
98*eb690a05SWarner Losh Node *x;
99*eb690a05SWarner Losh
100*eb690a05SWarner Losh x = nodealloc(5);
101*eb690a05SWarner Losh x->nobj = a;
102*eb690a05SWarner Losh x->narg[0] = b;
103*eb690a05SWarner Losh x->narg[1] = c;
104*eb690a05SWarner Losh x->narg[2] = d;
105*eb690a05SWarner Losh x->narg[3] = e;
106*eb690a05SWarner Losh x->narg[4] = f;
107*eb690a05SWarner Losh return(x);
108*eb690a05SWarner Losh }
109*eb690a05SWarner Losh
stat1(int a,Node * b)1102a55deb1SDavid E. O'Brien Node *stat1(int a, Node *b)
1112a55deb1SDavid E. O'Brien {
1122a55deb1SDavid E. O'Brien Node *x;
1132a55deb1SDavid E. O'Brien
1142a55deb1SDavid E. O'Brien x = node1(a,b);
1152a55deb1SDavid E. O'Brien x->ntype = NSTAT;
1162a55deb1SDavid E. O'Brien return(x);
1172a55deb1SDavid E. O'Brien }
1182a55deb1SDavid E. O'Brien
stat2(int a,Node * b,Node * c)1192a55deb1SDavid E. O'Brien Node *stat2(int a, Node *b, Node *c)
1202a55deb1SDavid E. O'Brien {
1212a55deb1SDavid E. O'Brien Node *x;
1222a55deb1SDavid E. O'Brien
1232a55deb1SDavid E. O'Brien x = node2(a,b,c);
1242a55deb1SDavid E. O'Brien x->ntype = NSTAT;
1252a55deb1SDavid E. O'Brien return(x);
1262a55deb1SDavid E. O'Brien }
1272a55deb1SDavid E. O'Brien
stat3(int a,Node * b,Node * c,Node * d)1282a55deb1SDavid E. O'Brien Node *stat3(int a, Node *b, Node *c, Node *d)
1292a55deb1SDavid E. O'Brien {
1302a55deb1SDavid E. O'Brien Node *x;
1312a55deb1SDavid E. O'Brien
1322a55deb1SDavid E. O'Brien x = node3(a,b,c,d);
1332a55deb1SDavid E. O'Brien x->ntype = NSTAT;
1342a55deb1SDavid E. O'Brien return(x);
1352a55deb1SDavid E. O'Brien }
1362a55deb1SDavid E. O'Brien
stat4(int a,Node * b,Node * c,Node * d,Node * e)1372a55deb1SDavid E. O'Brien Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
1382a55deb1SDavid E. O'Brien {
1392a55deb1SDavid E. O'Brien Node *x;
1402a55deb1SDavid E. O'Brien
1412a55deb1SDavid E. O'Brien x = node4(a,b,c,d,e);
1422a55deb1SDavid E. O'Brien x->ntype = NSTAT;
1432a55deb1SDavid E. O'Brien return(x);
1442a55deb1SDavid E. O'Brien }
1452a55deb1SDavid E. O'Brien
op1(int a,Node * b)1462a55deb1SDavid E. O'Brien Node *op1(int a, Node *b)
1472a55deb1SDavid E. O'Brien {
1482a55deb1SDavid E. O'Brien Node *x;
1492a55deb1SDavid E. O'Brien
1502a55deb1SDavid E. O'Brien x = node1(a,b);
1512a55deb1SDavid E. O'Brien x->ntype = NEXPR;
1522a55deb1SDavid E. O'Brien return(x);
1532a55deb1SDavid E. O'Brien }
1542a55deb1SDavid E. O'Brien
op2(int a,Node * b,Node * c)1552a55deb1SDavid E. O'Brien Node *op2(int a, Node *b, Node *c)
1562a55deb1SDavid E. O'Brien {
1572a55deb1SDavid E. O'Brien Node *x;
1582a55deb1SDavid E. O'Brien
1592a55deb1SDavid E. O'Brien x = node2(a,b,c);
1602a55deb1SDavid E. O'Brien x->ntype = NEXPR;
1612a55deb1SDavid E. O'Brien return(x);
1622a55deb1SDavid E. O'Brien }
1632a55deb1SDavid E. O'Brien
op3(int a,Node * b,Node * c,Node * d)1642a55deb1SDavid E. O'Brien Node *op3(int a, Node *b, Node *c, Node *d)
1652a55deb1SDavid E. O'Brien {
1662a55deb1SDavid E. O'Brien Node *x;
1672a55deb1SDavid E. O'Brien
1682a55deb1SDavid E. O'Brien x = node3(a,b,c,d);
1692a55deb1SDavid E. O'Brien x->ntype = NEXPR;
1702a55deb1SDavid E. O'Brien return(x);
1712a55deb1SDavid E. O'Brien }
1722a55deb1SDavid E. O'Brien
op4(int a,Node * b,Node * c,Node * d,Node * e)1732a55deb1SDavid E. O'Brien Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
1742a55deb1SDavid E. O'Brien {
1752a55deb1SDavid E. O'Brien Node *x;
1762a55deb1SDavid E. O'Brien
1772a55deb1SDavid E. O'Brien x = node4(a,b,c,d,e);
1782a55deb1SDavid E. O'Brien x->ntype = NEXPR;
1792a55deb1SDavid E. O'Brien return(x);
1802a55deb1SDavid E. O'Brien }
1812a55deb1SDavid E. O'Brien
op5(int a,Node * b,Node * c,Node * d,Node * e,Node * f)182*eb690a05SWarner Losh Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f)
183*eb690a05SWarner Losh {
184*eb690a05SWarner Losh Node *x;
185*eb690a05SWarner Losh
186*eb690a05SWarner Losh x = node5(a,b,c,d,e,f);
187*eb690a05SWarner Losh x->ntype = NEXPR;
188*eb690a05SWarner Losh return(x);
189*eb690a05SWarner Losh }
190*eb690a05SWarner Losh
celltonode(Cell * a,int b)1912a55deb1SDavid E. O'Brien Node *celltonode(Cell *a, int b)
1922a55deb1SDavid E. O'Brien {
1932a55deb1SDavid E. O'Brien Node *x;
1942a55deb1SDavid E. O'Brien
1952a55deb1SDavid E. O'Brien a->ctype = OCELL;
1962a55deb1SDavid E. O'Brien a->csub = b;
1972a55deb1SDavid E. O'Brien x = node1(0, (Node *) a);
1982a55deb1SDavid E. O'Brien x->ntype = NVALUE;
1992a55deb1SDavid E. O'Brien return(x);
2002a55deb1SDavid E. O'Brien }
2012a55deb1SDavid E. O'Brien
rectonode(void)2022a55deb1SDavid E. O'Brien Node *rectonode(void) /* make $0 into a Node */
2032a55deb1SDavid E. O'Brien {
2042a55deb1SDavid E. O'Brien extern Cell *literal0;
2052a55deb1SDavid E. O'Brien return op1(INDIRECT, celltonode(literal0, CUNK));
2062a55deb1SDavid E. O'Brien }
2072a55deb1SDavid E. O'Brien
makearr(Node * p)2082a55deb1SDavid E. O'Brien Node *makearr(Node *p)
2092a55deb1SDavid E. O'Brien {
2102a55deb1SDavid E. O'Brien Cell *cp;
2112a55deb1SDavid E. O'Brien
2122a55deb1SDavid E. O'Brien if (isvalue(p)) {
2132a55deb1SDavid E. O'Brien cp = (Cell *) (p->narg[0]);
2142a55deb1SDavid E. O'Brien if (isfcn(cp))
2152a55deb1SDavid E. O'Brien SYNTAX( "%s is a function, not an array", cp->nval );
2162a55deb1SDavid E. O'Brien else if (!isarr(cp)) {
2172a55deb1SDavid E. O'Brien xfree(cp->sval);
2182a55deb1SDavid E. O'Brien cp->sval = (char *) makesymtab(NSYMTAB);
2192a55deb1SDavid E. O'Brien cp->tval = ARR;
2202a55deb1SDavid E. O'Brien }
2212a55deb1SDavid E. O'Brien }
2222a55deb1SDavid E. O'Brien return p;
2232a55deb1SDavid E. O'Brien }
2242a55deb1SDavid E. O'Brien
2252a55deb1SDavid E. O'Brien #define PA2NUM 50 /* max number of pat,pat patterns allowed */
2262a55deb1SDavid E. O'Brien int paircnt; /* number of them in use */
2272a55deb1SDavid E. O'Brien int pairstack[PA2NUM]; /* state of each pat,pat */
2282a55deb1SDavid E. O'Brien
pa2stat(Node * a,Node * b,Node * c)2292a55deb1SDavid E. O'Brien Node *pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */
2302a55deb1SDavid E. O'Brien {
2312a55deb1SDavid E. O'Brien Node *x;
2322a55deb1SDavid E. O'Brien
2332a55deb1SDavid E. O'Brien x = node4(PASTAT2, a, b, c, itonp(paircnt));
2342a55deb1SDavid E. O'Brien if (paircnt++ >= PA2NUM)
2352a55deb1SDavid E. O'Brien SYNTAX( "limited to %d pat,pat statements", PA2NUM );
2362a55deb1SDavid E. O'Brien x->ntype = NSTAT;
2372a55deb1SDavid E. O'Brien return(x);
2382a55deb1SDavid E. O'Brien }
2392a55deb1SDavid E. O'Brien
linkum(Node * a,Node * b)2402a55deb1SDavid E. O'Brien Node *linkum(Node *a, Node *b)
2412a55deb1SDavid E. O'Brien {
2422a55deb1SDavid E. O'Brien Node *c;
2432a55deb1SDavid E. O'Brien
2442a55deb1SDavid E. O'Brien if (errorflag) /* don't link things that are wrong */
2452a55deb1SDavid E. O'Brien return a;
2462a55deb1SDavid E. O'Brien if (a == NULL)
2472a55deb1SDavid E. O'Brien return(b);
2482a55deb1SDavid E. O'Brien else if (b == NULL)
2492a55deb1SDavid E. O'Brien return(a);
2502a55deb1SDavid E. O'Brien for (c = a; c->nnext != NULL; c = c->nnext)
2512a55deb1SDavid E. O'Brien ;
2522a55deb1SDavid E. O'Brien c->nnext = b;
2532a55deb1SDavid E. O'Brien return(a);
2542a55deb1SDavid E. O'Brien }
2552a55deb1SDavid E. O'Brien
defn(Cell * v,Node * vl,Node * st)2562a55deb1SDavid E. O'Brien void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
2572a55deb1SDavid E. O'Brien { /* body of function, arglist */
2582a55deb1SDavid E. O'Brien Node *p;
2592a55deb1SDavid E. O'Brien int n;
2602a55deb1SDavid E. O'Brien
2612a55deb1SDavid E. O'Brien if (isarr(v)) {
2622a55deb1SDavid E. O'Brien SYNTAX( "`%s' is an array name and a function name", v->nval );
2632a55deb1SDavid E. O'Brien return;
2642a55deb1SDavid E. O'Brien }
2652a55deb1SDavid E. O'Brien if (isarg(v->nval) != -1) {
2662a55deb1SDavid E. O'Brien SYNTAX( "`%s' is both function name and argument name", v->nval );
2672a55deb1SDavid E. O'Brien return;
2682a55deb1SDavid E. O'Brien }
2692a55deb1SDavid E. O'Brien
2702a55deb1SDavid E. O'Brien v->tval = FCN;
2712a55deb1SDavid E. O'Brien v->sval = (char *) st;
2722a55deb1SDavid E. O'Brien n = 0; /* count arguments */
2732a55deb1SDavid E. O'Brien for (p = vl; p; p = p->nnext)
2742a55deb1SDavid E. O'Brien n++;
2752a55deb1SDavid E. O'Brien v->fval = n;
276f39dd6a9SWarner Losh DPRINTF("defining func %s (%d args)\n", v->nval, n);
2772a55deb1SDavid E. O'Brien }
2782a55deb1SDavid E. O'Brien
isarg(const char * s)279813da98dSDavid E. O'Brien int isarg(const char *s) /* is s in argument list for current function? */
2802a55deb1SDavid E. O'Brien { /* return -1 if not, otherwise arg # */
2812a55deb1SDavid E. O'Brien extern Node *arglist;
2822a55deb1SDavid E. O'Brien Node *p = arglist;
2832a55deb1SDavid E. O'Brien int n;
2842a55deb1SDavid E. O'Brien
28510ce5b99SWarner Losh for (n = 0; p != NULL; p = p->nnext, n++)
2862a55deb1SDavid E. O'Brien if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
2872a55deb1SDavid E. O'Brien return n;
2882a55deb1SDavid E. O'Brien return -1;
2892a55deb1SDavid E. O'Brien }
2902a55deb1SDavid E. O'Brien
ptoi(void * p)2912a55deb1SDavid E. O'Brien int ptoi(void *p) /* convert pointer to integer */
2922a55deb1SDavid E. O'Brien {
2932a55deb1SDavid E. O'Brien return (int) (long) p; /* swearing that p fits, of course */
2942a55deb1SDavid E. O'Brien }
2952a55deb1SDavid E. O'Brien
itonp(int i)2962a55deb1SDavid E. O'Brien Node *itonp(int i) /* and vice versa */
2972a55deb1SDavid E. O'Brien {
2982a55deb1SDavid E. O'Brien return (Node *) (long) i;
2992a55deb1SDavid E. O'Brien }
300