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" 30*f39dd6a9SWarner Losh #include "awkgram.tab.h" 312a55deb1SDavid E. O'Brien 322a55deb1SDavid E. O'Brien Node *nodealloc(int n) 332a55deb1SDavid E. O'Brien { 342a55deb1SDavid E. O'Brien Node *x; 352a55deb1SDavid E. O'Brien 36*f39dd6a9SWarner 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 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 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 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 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 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 96*f39dd6a9SWarner Losh Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f) 97*f39dd6a9SWarner Losh { 98*f39dd6a9SWarner Losh Node *x; 99*f39dd6a9SWarner Losh 100*f39dd6a9SWarner Losh x = nodealloc(5); 101*f39dd6a9SWarner Losh x->nobj = a; 102*f39dd6a9SWarner Losh x->narg[0] = b; 103*f39dd6a9SWarner Losh x->narg[1] = c; 104*f39dd6a9SWarner Losh x->narg[2] = d; 105*f39dd6a9SWarner Losh x->narg[3] = e; 106*f39dd6a9SWarner Losh x->narg[4] = f; 107*f39dd6a9SWarner Losh return(x); 108*f39dd6a9SWarner Losh } 109*f39dd6a9SWarner Losh 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 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 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 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 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 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 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 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 182*f39dd6a9SWarner Losh Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f) 183*f39dd6a9SWarner Losh { 184*f39dd6a9SWarner Losh Node *x; 185*f39dd6a9SWarner Losh 186*f39dd6a9SWarner Losh x = node5(a,b,c,d,e,f); 187*f39dd6a9SWarner Losh x->ntype = NEXPR; 188*f39dd6a9SWarner Losh return(x); 189*f39dd6a9SWarner Losh } 190*f39dd6a9SWarner Losh 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 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 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 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 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 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; 276*f39dd6a9SWarner Losh DPRINTF("defining func %s (%d args)\n", v->nval, n); 2772a55deb1SDavid E. O'Brien } 2782a55deb1SDavid E. O'Brien 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 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 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