xref: /plan9/sys/src/cmd/awk/parse.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier /****************************************************************
2*7dd7cddfSDavid du Colombier Copyright (C) Lucent Technologies 1997
33e12c5d1SDavid du Colombier All Rights Reserved
43e12c5d1SDavid du Colombier 
5*7dd7cddfSDavid du Colombier Permission to use, copy, modify, and distribute this software and
6*7dd7cddfSDavid du Colombier its documentation for any purpose and without fee is hereby
7*7dd7cddfSDavid du Colombier granted, provided that the above copyright notice appear in all
8*7dd7cddfSDavid du Colombier copies and that both that the copyright notice and this
9*7dd7cddfSDavid du Colombier permission notice and warranty disclaimer appear in supporting
10*7dd7cddfSDavid du Colombier documentation, and that the name Lucent Technologies or any of
11*7dd7cddfSDavid du Colombier its entities not be used in advertising or publicity pertaining
12*7dd7cddfSDavid du Colombier to distribution of the software without specific, written prior
13*7dd7cddfSDavid du Colombier permission.
143e12c5d1SDavid du Colombier 
15*7dd7cddfSDavid du Colombier LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*7dd7cddfSDavid du Colombier INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17*7dd7cddfSDavid du Colombier IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18*7dd7cddfSDavid du Colombier SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*7dd7cddfSDavid du Colombier WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20*7dd7cddfSDavid du Colombier IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21*7dd7cddfSDavid du Colombier ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22*7dd7cddfSDavid du Colombier THIS SOFTWARE.
23*7dd7cddfSDavid du Colombier ****************************************************************/
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier #define DEBUG
263e12c5d1SDavid du Colombier #include <stdio.h>
273e12c5d1SDavid du Colombier #include <string.h>
283e12c5d1SDavid du Colombier #include <stdlib.h>
293e12c5d1SDavid du Colombier #include "awk.h"
303e12c5d1SDavid du Colombier #include "y.tab.h"
313e12c5d1SDavid du Colombier 
nodealloc(int n)323e12c5d1SDavid du Colombier Node *nodealloc(int n)
333e12c5d1SDavid du Colombier {
34219b2ee8SDavid du Colombier 	Node *x;
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *));
373e12c5d1SDavid du Colombier 	if (x == NULL)
38*7dd7cddfSDavid du Colombier 		FATAL("out of space in nodealloc");
393e12c5d1SDavid du Colombier 	x->nnext = NULL;
403e12c5d1SDavid du Colombier 	x->lineno = lineno;
413e12c5d1SDavid du Colombier 	return(x);
423e12c5d1SDavid du Colombier }
433e12c5d1SDavid du Colombier 
exptostat(Node * a)443e12c5d1SDavid du Colombier Node *exptostat(Node *a)
453e12c5d1SDavid du Colombier {
463e12c5d1SDavid du Colombier 	a->ntype = NSTAT;
473e12c5d1SDavid du Colombier 	return(a);
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier 
node1(int a,Node * b)503e12c5d1SDavid du Colombier Node *node1(int a, Node *b)
513e12c5d1SDavid du Colombier {
52219b2ee8SDavid du Colombier 	Node *x;
53219b2ee8SDavid du Colombier 
543e12c5d1SDavid du Colombier 	x = nodealloc(1);
553e12c5d1SDavid du Colombier 	x->nobj = a;
563e12c5d1SDavid du Colombier 	x->narg[0]=b;
573e12c5d1SDavid du Colombier 	return(x);
583e12c5d1SDavid du Colombier }
593e12c5d1SDavid du Colombier 
node2(int a,Node * b,Node * c)603e12c5d1SDavid du Colombier Node *node2(int a, Node *b, Node *c)
613e12c5d1SDavid du Colombier {
62219b2ee8SDavid du Colombier 	Node *x;
63219b2ee8SDavid du Colombier 
643e12c5d1SDavid du Colombier 	x = nodealloc(2);
653e12c5d1SDavid du Colombier 	x->nobj = a;
663e12c5d1SDavid du Colombier 	x->narg[0] = b;
673e12c5d1SDavid du Colombier 	x->narg[1] = c;
683e12c5d1SDavid du Colombier 	return(x);
693e12c5d1SDavid du Colombier }
703e12c5d1SDavid du Colombier 
node3(int a,Node * b,Node * c,Node * d)713e12c5d1SDavid du Colombier Node *node3(int a, Node *b, Node *c, Node *d)
723e12c5d1SDavid du Colombier {
73219b2ee8SDavid du Colombier 	Node *x;
74219b2ee8SDavid du Colombier 
753e12c5d1SDavid du Colombier 	x = nodealloc(3);
763e12c5d1SDavid du Colombier 	x->nobj = a;
773e12c5d1SDavid du Colombier 	x->narg[0] = b;
783e12c5d1SDavid du Colombier 	x->narg[1] = c;
793e12c5d1SDavid du Colombier 	x->narg[2] = d;
803e12c5d1SDavid du Colombier 	return(x);
813e12c5d1SDavid du Colombier }
823e12c5d1SDavid du Colombier 
node4(int a,Node * b,Node * c,Node * d,Node * e)833e12c5d1SDavid du Colombier Node *node4(int a, Node *b, Node *c, Node *d, Node *e)
843e12c5d1SDavid du Colombier {
85219b2ee8SDavid du Colombier 	Node *x;
86219b2ee8SDavid du Colombier 
873e12c5d1SDavid du Colombier 	x = nodealloc(4);
883e12c5d1SDavid du Colombier 	x->nobj = a;
893e12c5d1SDavid du Colombier 	x->narg[0] = b;
903e12c5d1SDavid du Colombier 	x->narg[1] = c;
913e12c5d1SDavid du Colombier 	x->narg[2] = d;
923e12c5d1SDavid du Colombier 	x->narg[3] = e;
933e12c5d1SDavid du Colombier 	return(x);
943e12c5d1SDavid du Colombier }
953e12c5d1SDavid du Colombier 
stat1(int a,Node * b)96219b2ee8SDavid du Colombier Node *stat1(int a, Node *b)
97219b2ee8SDavid du Colombier {
98219b2ee8SDavid du Colombier 	Node *x;
99219b2ee8SDavid du Colombier 
100219b2ee8SDavid du Colombier 	x = node1(a,b);
101219b2ee8SDavid du Colombier 	x->ntype = NSTAT;
102219b2ee8SDavid du Colombier 	return(x);
103219b2ee8SDavid du Colombier }
104219b2ee8SDavid du Colombier 
stat2(int a,Node * b,Node * c)105219b2ee8SDavid du Colombier Node *stat2(int a, Node *b, Node *c)
106219b2ee8SDavid du Colombier {
107219b2ee8SDavid du Colombier 	Node *x;
108219b2ee8SDavid du Colombier 
109219b2ee8SDavid du Colombier 	x = node2(a,b,c);
110219b2ee8SDavid du Colombier 	x->ntype = NSTAT;
111219b2ee8SDavid du Colombier 	return(x);
112219b2ee8SDavid du Colombier }
113219b2ee8SDavid du Colombier 
stat3(int a,Node * b,Node * c,Node * d)1143e12c5d1SDavid du Colombier Node *stat3(int a, Node *b, Node *c, Node *d)
1153e12c5d1SDavid du Colombier {
116219b2ee8SDavid du Colombier 	Node *x;
117219b2ee8SDavid du Colombier 
1183e12c5d1SDavid du Colombier 	x = node3(a,b,c,d);
1193e12c5d1SDavid du Colombier 	x->ntype = NSTAT;
1203e12c5d1SDavid du Colombier 	return(x);
1213e12c5d1SDavid du Colombier }
1223e12c5d1SDavid du Colombier 
stat4(int a,Node * b,Node * c,Node * d,Node * e)123219b2ee8SDavid du Colombier Node *stat4(int a, Node *b, Node *c, Node *d, Node *e)
1243e12c5d1SDavid du Colombier {
125219b2ee8SDavid du Colombier 	Node *x;
126219b2ee8SDavid du Colombier 
127219b2ee8SDavid du Colombier 	x = node4(a,b,c,d,e);
128219b2ee8SDavid du Colombier 	x->ntype = NSTAT;
1293e12c5d1SDavid du Colombier 	return(x);
1303e12c5d1SDavid du Colombier }
1313e12c5d1SDavid du Colombier 
op1(int a,Node * b)1323e12c5d1SDavid du Colombier Node *op1(int a, Node *b)
1333e12c5d1SDavid du Colombier {
134219b2ee8SDavid du Colombier 	Node *x;
135219b2ee8SDavid du Colombier 
1363e12c5d1SDavid du Colombier 	x = node1(a,b);
1373e12c5d1SDavid du Colombier 	x->ntype = NEXPR;
1383e12c5d1SDavid du Colombier 	return(x);
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier 
op2(int a,Node * b,Node * c)141219b2ee8SDavid du Colombier Node *op2(int a, Node *b, Node *c)
1423e12c5d1SDavid du Colombier {
143219b2ee8SDavid du Colombier 	Node *x;
144219b2ee8SDavid du Colombier 
145219b2ee8SDavid du Colombier 	x = node2(a,b,c);
146219b2ee8SDavid du Colombier 	x->ntype = NEXPR;
1473e12c5d1SDavid du Colombier 	return(x);
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier 
op3(int a,Node * b,Node * c,Node * d)1503e12c5d1SDavid du Colombier Node *op3(int a, Node *b, Node *c, Node *d)
1513e12c5d1SDavid du Colombier {
152219b2ee8SDavid du Colombier 	Node *x;
153219b2ee8SDavid du Colombier 
1543e12c5d1SDavid du Colombier 	x = node3(a,b,c,d);
1553e12c5d1SDavid du Colombier 	x->ntype = NEXPR;
1563e12c5d1SDavid du Colombier 	return(x);
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier 
op4(int a,Node * b,Node * c,Node * d,Node * e)1593e12c5d1SDavid du Colombier Node *op4(int a, Node *b, Node *c, Node *d, Node *e)
1603e12c5d1SDavid du Colombier {
161219b2ee8SDavid du Colombier 	Node *x;
162219b2ee8SDavid du Colombier 
1633e12c5d1SDavid du Colombier 	x = node4(a,b,c,d,e);
1643e12c5d1SDavid du Colombier 	x->ntype = NEXPR;
1653e12c5d1SDavid du Colombier 	return(x);
1663e12c5d1SDavid du Colombier }
1673e12c5d1SDavid du Colombier 
celltonode(Cell * a,int b)168*7dd7cddfSDavid du Colombier Node *celltonode(Cell *a, int b)
1693e12c5d1SDavid du Colombier {
170219b2ee8SDavid du Colombier 	Node *x;
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier 	a->ctype = OCELL;
1733e12c5d1SDavid du Colombier 	a->csub = b;
1743e12c5d1SDavid du Colombier 	x = node1(0, (Node *) a);
1753e12c5d1SDavid du Colombier 	x->ntype = NVALUE;
1763e12c5d1SDavid du Colombier 	return(x);
1773e12c5d1SDavid du Colombier }
1783e12c5d1SDavid du Colombier 
rectonode(void)179219b2ee8SDavid du Colombier Node *rectonode(void)	/* make $0 into a Node */
1803e12c5d1SDavid du Colombier {
181*7dd7cddfSDavid du Colombier 	extern Cell *literal0;
182*7dd7cddfSDavid du Colombier 	return op1(INDIRECT, celltonode(literal0, CUNK));
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier 
makearr(Node * p)1853e12c5d1SDavid du Colombier Node *makearr(Node *p)
1863e12c5d1SDavid du Colombier {
1873e12c5d1SDavid du Colombier 	Cell *cp;
1883e12c5d1SDavid du Colombier 
1893e12c5d1SDavid du Colombier 	if (isvalue(p)) {
1903e12c5d1SDavid du Colombier 		cp = (Cell *) (p->narg[0]);
191*7dd7cddfSDavid du Colombier 		if (isfcn(cp))
192*7dd7cddfSDavid du Colombier 			SYNTAX( "%s is a function, not an array", cp->nval );
1933e12c5d1SDavid du Colombier 		else if (!isarr(cp)) {
1943e12c5d1SDavid du Colombier 			xfree(cp->sval);
195*7dd7cddfSDavid du Colombier 			cp->sval = (char *) makesymtab(NSYMTAB);
1963e12c5d1SDavid du Colombier 			cp->tval = ARR;
1973e12c5d1SDavid du Colombier 		}
1983e12c5d1SDavid du Colombier 	}
1993e12c5d1SDavid du Colombier 	return p;
2003e12c5d1SDavid du Colombier }
2013e12c5d1SDavid du Colombier 
202*7dd7cddfSDavid du Colombier #define PA2NUM	50	/* max number of pat,pat patterns allowed */
203*7dd7cddfSDavid du Colombier int	paircnt;		/* number of them in use */
204*7dd7cddfSDavid du Colombier int	pairstack[PA2NUM];	/* state of each pat,pat */
205*7dd7cddfSDavid du Colombier 
pa2stat(Node * a,Node * b,Node * c)206219b2ee8SDavid du Colombier Node *pa2stat(Node *a, Node *b, Node *c)	/* pat, pat {...} */
2073e12c5d1SDavid du Colombier {
208219b2ee8SDavid du Colombier 	Node *x;
209219b2ee8SDavid du Colombier 
210*7dd7cddfSDavid du Colombier 	x = node4(PASTAT2, a, b, c, itonp(paircnt));
211*7dd7cddfSDavid du Colombier 	if (paircnt++ >= PA2NUM)
212*7dd7cddfSDavid du Colombier 		SYNTAX( "limited to %d pat,pat statements", PA2NUM );
2133e12c5d1SDavid du Colombier 	x->ntype = NSTAT;
2143e12c5d1SDavid du Colombier 	return(x);
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier 
linkum(Node * a,Node * b)2173e12c5d1SDavid du Colombier Node *linkum(Node *a, Node *b)
2183e12c5d1SDavid du Colombier {
219219b2ee8SDavid du Colombier 	Node *c;
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 	if (errorflag)	/* don't link things that are wrong */
2223e12c5d1SDavid du Colombier 		return a;
223219b2ee8SDavid du Colombier 	if (a == NULL)
224219b2ee8SDavid du Colombier 		return(b);
225219b2ee8SDavid du Colombier 	else if (b == NULL)
226219b2ee8SDavid du Colombier 		return(a);
2273e12c5d1SDavid du Colombier 	for (c = a; c->nnext != NULL; c = c->nnext)
2283e12c5d1SDavid du Colombier 		;
2293e12c5d1SDavid du Colombier 	c->nnext = b;
2303e12c5d1SDavid du Colombier 	return(a);
2313e12c5d1SDavid du Colombier }
2323e12c5d1SDavid du Colombier 
defn(Cell * v,Node * vl,Node * st)233219b2ee8SDavid du Colombier void defn(Cell *v, Node *vl, Node *st)	/* turn on FCN bit in definition, */
234219b2ee8SDavid du Colombier {					/*   body of function, arglist */
2353e12c5d1SDavid du Colombier 	Node *p;
2363e12c5d1SDavid du Colombier 	int n;
2373e12c5d1SDavid du Colombier 
2383e12c5d1SDavid du Colombier 	if (isarr(v)) {
239*7dd7cddfSDavid du Colombier 		SYNTAX( "`%s' is an array name and a function name", v->nval );
2403e12c5d1SDavid du Colombier 		return;
2413e12c5d1SDavid du Colombier 	}
2423e12c5d1SDavid du Colombier 	v->tval = FCN;
243*7dd7cddfSDavid du Colombier 	v->sval = (char *) st;
2443e12c5d1SDavid du Colombier 	n = 0;	/* count arguments */
2453e12c5d1SDavid du Colombier 	for (p = vl; p; p = p->nnext)
2463e12c5d1SDavid du Colombier 		n++;
2473e12c5d1SDavid du Colombier 	v->fval = n;
2483e12c5d1SDavid du Colombier 	dprintf( ("defining func %s (%d args)\n", v->nval, n) );
2493e12c5d1SDavid du Colombier }
2503e12c5d1SDavid du Colombier 
isarg(char * s)251*7dd7cddfSDavid du Colombier int isarg(char *s)		/* is s in argument list for current function? */
252219b2ee8SDavid du Colombier {			/* return -1 if not, otherwise arg # */
2533e12c5d1SDavid du Colombier 	extern Node *arglist;
2543e12c5d1SDavid du Colombier 	Node *p = arglist;
2553e12c5d1SDavid du Colombier 	int n;
2563e12c5d1SDavid du Colombier 
2573e12c5d1SDavid du Colombier 	for (n = 0; p != 0; p = p->nnext, n++)
2583e12c5d1SDavid du Colombier 		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
2593e12c5d1SDavid du Colombier 			return n;
2603e12c5d1SDavid du Colombier 	return -1;
2613e12c5d1SDavid du Colombier }
262*7dd7cddfSDavid du Colombier 
ptoi(void * p)263*7dd7cddfSDavid du Colombier int ptoi(void *p)	/* convert pointer to integer */
264*7dd7cddfSDavid du Colombier {
265*7dd7cddfSDavid du Colombier 	return (int) (long) p;	/* swearing that p fits, of course */
266*7dd7cddfSDavid du Colombier }
267*7dd7cddfSDavid du Colombier 
itonp(int i)268*7dd7cddfSDavid du Colombier Node *itonp(int i)	/* and vice versa */
269*7dd7cddfSDavid du Colombier {
270*7dd7cddfSDavid du Colombier 	return (Node *) (long) i;
271*7dd7cddfSDavid du Colombier }
272