185587Sobrien/**************************************************************** 285587SobrienCopyright (C) Lucent Technologies 1997 385587SobrienAll Rights Reserved 485587Sobrien 585587SobrienPermission to use, copy, modify, and distribute this software and 685587Sobrienits documentation for any purpose and without fee is hereby 785587Sobriengranted, provided that the above copyright notice appear in all 885587Sobriencopies and that both that the copyright notice and this 985587Sobrienpermission notice and warranty disclaimer appear in supporting 1085587Sobriendocumentation, and that the name Lucent Technologies or any of 1185587Sobrienits entities not be used in advertising or publicity pertaining 1285587Sobriento distribution of the software without specific, written prior 1385587Sobrienpermission. 1485587Sobrien 1585587SobrienLUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1685587SobrienINCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 1785587SobrienIN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 1885587SobrienSPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1985587SobrienWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 2085587SobrienIN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 2185587SobrienARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 2285587SobrienTHIS SOFTWARE. 2385587Sobrien****************************************************************/ 2485587Sobrien 2585587Sobrien#define DEBUG 2685587Sobrien#include <stdio.h> 2785587Sobrien#include <string.h> 2885587Sobrien#include <stdlib.h> 2985587Sobrien#include "awk.h" 3085587Sobrien#include "ytab.h" 3185587Sobrien 3285587SobrienNode *nodealloc(int n) 3385587Sobrien{ 3485587Sobrien Node *x; 3585587Sobrien 3685587Sobrien x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *)); 3785587Sobrien if (x == NULL) 3885587Sobrien FATAL("out of space in nodealloc"); 3985587Sobrien x->nnext = NULL; 4085587Sobrien x->lineno = lineno; 4185587Sobrien return(x); 4285587Sobrien} 4385587Sobrien 4485587SobrienNode *exptostat(Node *a) 4585587Sobrien{ 4685587Sobrien a->ntype = NSTAT; 4785587Sobrien return(a); 4885587Sobrien} 4985587Sobrien 5085587SobrienNode *node1(int a, Node *b) 5185587Sobrien{ 5285587Sobrien Node *x; 5385587Sobrien 5485587Sobrien x = nodealloc(1); 5585587Sobrien x->nobj = a; 5685587Sobrien x->narg[0]=b; 5785587Sobrien return(x); 5885587Sobrien} 5985587Sobrien 6085587SobrienNode *node2(int a, Node *b, Node *c) 6185587Sobrien{ 6285587Sobrien Node *x; 6385587Sobrien 6485587Sobrien x = nodealloc(2); 6585587Sobrien x->nobj = a; 6685587Sobrien x->narg[0] = b; 6785587Sobrien x->narg[1] = c; 6885587Sobrien return(x); 6985587Sobrien} 7085587Sobrien 7185587SobrienNode *node3(int a, Node *b, Node *c, Node *d) 7285587Sobrien{ 7385587Sobrien Node *x; 7485587Sobrien 7585587Sobrien x = nodealloc(3); 7685587Sobrien x->nobj = a; 7785587Sobrien x->narg[0] = b; 7885587Sobrien x->narg[1] = c; 7985587Sobrien x->narg[2] = d; 8085587Sobrien return(x); 8185587Sobrien} 8285587Sobrien 8385587SobrienNode *node4(int a, Node *b, Node *c, Node *d, Node *e) 8485587Sobrien{ 8585587Sobrien Node *x; 8685587Sobrien 8785587Sobrien x = nodealloc(4); 8885587Sobrien x->nobj = a; 8985587Sobrien x->narg[0] = b; 9085587Sobrien x->narg[1] = c; 9185587Sobrien x->narg[2] = d; 9285587Sobrien x->narg[3] = e; 9385587Sobrien return(x); 9485587Sobrien} 9585587Sobrien 9685587SobrienNode *stat1(int a, Node *b) 9785587Sobrien{ 9885587Sobrien Node *x; 9985587Sobrien 10085587Sobrien x = node1(a,b); 10185587Sobrien x->ntype = NSTAT; 10285587Sobrien return(x); 10385587Sobrien} 10485587Sobrien 10585587SobrienNode *stat2(int a, Node *b, Node *c) 10685587Sobrien{ 10785587Sobrien Node *x; 10885587Sobrien 10985587Sobrien x = node2(a,b,c); 11085587Sobrien x->ntype = NSTAT; 11185587Sobrien return(x); 11285587Sobrien} 11385587Sobrien 11485587SobrienNode *stat3(int a, Node *b, Node *c, Node *d) 11585587Sobrien{ 11685587Sobrien Node *x; 11785587Sobrien 11885587Sobrien x = node3(a,b,c,d); 11985587Sobrien x->ntype = NSTAT; 12085587Sobrien return(x); 12185587Sobrien} 12285587Sobrien 12385587SobrienNode *stat4(int a, Node *b, Node *c, Node *d, Node *e) 12485587Sobrien{ 12585587Sobrien Node *x; 12685587Sobrien 12785587Sobrien x = node4(a,b,c,d,e); 12885587Sobrien x->ntype = NSTAT; 12985587Sobrien return(x); 13085587Sobrien} 13185587Sobrien 13285587SobrienNode *op1(int a, Node *b) 13385587Sobrien{ 13485587Sobrien Node *x; 13585587Sobrien 13685587Sobrien x = node1(a,b); 13785587Sobrien x->ntype = NEXPR; 13885587Sobrien return(x); 13985587Sobrien} 14085587Sobrien 14185587SobrienNode *op2(int a, Node *b, Node *c) 14285587Sobrien{ 14385587Sobrien Node *x; 14485587Sobrien 14585587Sobrien x = node2(a,b,c); 14685587Sobrien x->ntype = NEXPR; 14785587Sobrien return(x); 14885587Sobrien} 14985587Sobrien 15085587SobrienNode *op3(int a, Node *b, Node *c, Node *d) 15185587Sobrien{ 15285587Sobrien Node *x; 15385587Sobrien 15485587Sobrien x = node3(a,b,c,d); 15585587Sobrien x->ntype = NEXPR; 15685587Sobrien return(x); 15785587Sobrien} 15885587Sobrien 15985587SobrienNode *op4(int a, Node *b, Node *c, Node *d, Node *e) 16085587Sobrien{ 16185587Sobrien Node *x; 16285587Sobrien 16385587Sobrien x = node4(a,b,c,d,e); 16485587Sobrien x->ntype = NEXPR; 16585587Sobrien return(x); 16685587Sobrien} 16785587Sobrien 16885587SobrienNode *celltonode(Cell *a, int b) 16985587Sobrien{ 17085587Sobrien Node *x; 17185587Sobrien 17285587Sobrien a->ctype = OCELL; 17385587Sobrien a->csub = b; 17485587Sobrien x = node1(0, (Node *) a); 17585587Sobrien x->ntype = NVALUE; 17685587Sobrien return(x); 17785587Sobrien} 17885587Sobrien 17985587SobrienNode *rectonode(void) /* make $0 into a Node */ 18085587Sobrien{ 18185587Sobrien extern Cell *literal0; 18285587Sobrien return op1(INDIRECT, celltonode(literal0, CUNK)); 18385587Sobrien} 18485587Sobrien 18585587SobrienNode *makearr(Node *p) 18685587Sobrien{ 18785587Sobrien Cell *cp; 18885587Sobrien 18985587Sobrien if (isvalue(p)) { 19085587Sobrien cp = (Cell *) (p->narg[0]); 19185587Sobrien if (isfcn(cp)) 19285587Sobrien SYNTAX( "%s is a function, not an array", cp->nval ); 19385587Sobrien else if (!isarr(cp)) { 19485587Sobrien xfree(cp->sval); 19585587Sobrien cp->sval = (char *) makesymtab(NSYMTAB); 19685587Sobrien cp->tval = ARR; 19785587Sobrien } 19885587Sobrien } 19985587Sobrien return p; 20085587Sobrien} 20185587Sobrien 20285587Sobrien#define PA2NUM 50 /* max number of pat,pat patterns allowed */ 20385587Sobrienint paircnt; /* number of them in use */ 20485587Sobrienint pairstack[PA2NUM]; /* state of each pat,pat */ 20585587Sobrien 20685587SobrienNode *pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */ 20785587Sobrien{ 20885587Sobrien Node *x; 20985587Sobrien 21085587Sobrien x = node4(PASTAT2, a, b, c, itonp(paircnt)); 21185587Sobrien if (paircnt++ >= PA2NUM) 21285587Sobrien SYNTAX( "limited to %d pat,pat statements", PA2NUM ); 21385587Sobrien x->ntype = NSTAT; 21485587Sobrien return(x); 21585587Sobrien} 21685587Sobrien 21785587SobrienNode *linkum(Node *a, Node *b) 21885587Sobrien{ 21985587Sobrien Node *c; 22085587Sobrien 22185587Sobrien if (errorflag) /* don't link things that are wrong */ 22285587Sobrien return a; 22385587Sobrien if (a == NULL) 22485587Sobrien return(b); 22585587Sobrien else if (b == NULL) 22685587Sobrien return(a); 22785587Sobrien for (c = a; c->nnext != NULL; c = c->nnext) 22885587Sobrien ; 22985587Sobrien c->nnext = b; 23085587Sobrien return(a); 23185587Sobrien} 23285587Sobrien 23385587Sobrienvoid defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */ 23485587Sobrien{ /* body of function, arglist */ 23585587Sobrien Node *p; 23685587Sobrien int n; 23785587Sobrien 23885587Sobrien if (isarr(v)) { 23985587Sobrien SYNTAX( "`%s' is an array name and a function name", v->nval ); 24085587Sobrien return; 24185587Sobrien } 24285587Sobrien if (isarg(v->nval) != -1) { 24385587Sobrien SYNTAX( "`%s' is both function name and argument name", v->nval ); 24485587Sobrien return; 24585587Sobrien } 24685587Sobrien 24785587Sobrien v->tval = FCN; 24885587Sobrien v->sval = (char *) st; 24985587Sobrien n = 0; /* count arguments */ 25085587Sobrien for (p = vl; p; p = p->nnext) 25185587Sobrien n++; 25285587Sobrien v->fval = n; 25385587Sobrien dprintf( ("defining func %s (%d args)\n", v->nval, n) ); 25485587Sobrien} 25585587Sobrien 256107806Sobrienint isarg(const char *s) /* is s in argument list for current function? */ 25785587Sobrien{ /* return -1 if not, otherwise arg # */ 25885587Sobrien extern Node *arglist; 25985587Sobrien Node *p = arglist; 26085587Sobrien int n; 26185587Sobrien 262301289Spfg for (n = 0; p != NULL; p = p->nnext, n++) 26385587Sobrien if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0) 26485587Sobrien return n; 26585587Sobrien return -1; 26685587Sobrien} 26785587Sobrien 26885587Sobrienint ptoi(void *p) /* convert pointer to integer */ 26985587Sobrien{ 27085587Sobrien return (int) (long) p; /* swearing that p fits, of course */ 27185587Sobrien} 27285587Sobrien 27385587SobrienNode *itonp(int i) /* and vice versa */ 27485587Sobrien{ 27585587Sobrien return (Node *) (long) i; 27685587Sobrien} 277