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