xref: /plan9-contrib/sys/src/cmd/awk/parse.c (revision a2c41696452f8a895ad2951a6355034fbc3034ed)
17dd7cddfSDavid du Colombier /****************************************************************
27dd7cddfSDavid du Colombier Copyright (C) Lucent Technologies 1997
33e12c5d1SDavid du Colombier All Rights Reserved
43e12c5d1SDavid du Colombier 
57dd7cddfSDavid du Colombier Permission to use, copy, modify, and distribute this software and
67dd7cddfSDavid du Colombier its documentation for any purpose and without fee is hereby
77dd7cddfSDavid du Colombier granted, provided that the above copyright notice appear in all
87dd7cddfSDavid du Colombier copies and that both that the copyright notice and this
97dd7cddfSDavid du Colombier permission notice and warranty disclaimer appear in supporting
107dd7cddfSDavid du Colombier documentation, and that the name Lucent Technologies or any of
117dd7cddfSDavid du Colombier its entities not be used in advertising or publicity pertaining
127dd7cddfSDavid du Colombier to distribution of the software without specific, written prior
137dd7cddfSDavid du Colombier permission.
143e12c5d1SDavid du Colombier 
157dd7cddfSDavid du Colombier LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
167dd7cddfSDavid du Colombier INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
177dd7cddfSDavid du Colombier IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
187dd7cddfSDavid du Colombier SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
197dd7cddfSDavid du Colombier WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
207dd7cddfSDavid du Colombier IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
217dd7cddfSDavid du Colombier ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
227dd7cddfSDavid du Colombier THIS SOFTWARE.
237dd7cddfSDavid 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)
387dd7cddfSDavid 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)1687dd7cddfSDavid 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 {
1817dd7cddfSDavid du Colombier 	extern Cell *literal0;
1827dd7cddfSDavid 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]);
1917dd7cddfSDavid du Colombier 		if (isfcn(cp))
1927dd7cddfSDavid 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);
1957dd7cddfSDavid 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 
2027dd7cddfSDavid du Colombier #define PA2NUM	50	/* max number of pat,pat patterns allowed */
2037dd7cddfSDavid du Colombier int	paircnt;		/* number of them in use */
2047dd7cddfSDavid du Colombier int	pairstack[PA2NUM];	/* state of each pat,pat */
2057dd7cddfSDavid 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 
2107dd7cddfSDavid du Colombier 	x = node4(PASTAT2, a, b, c, itonp(paircnt));
2117dd7cddfSDavid du Colombier 	if (paircnt++ >= PA2NUM)
2127dd7cddfSDavid 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)) {
2397dd7cddfSDavid du Colombier 		SYNTAX( "`%s' is an array name and a function name", v->nval );
2403e12c5d1SDavid du Colombier 		return;
2413e12c5d1SDavid du Colombier 	}
242*a2c41696SDavid du Colombier 	if (isarg(v->nval) != -1) {
243*a2c41696SDavid du Colombier 		SYNTAX( "`%s' is both function name and argument name", v->nval );
244*a2c41696SDavid du Colombier 		return;
245*a2c41696SDavid du Colombier 	}
246*a2c41696SDavid du Colombier 
2473e12c5d1SDavid du Colombier 	v->tval = FCN;
2487dd7cddfSDavid du Colombier 	v->sval = (char *) st;
2493e12c5d1SDavid du Colombier 	n = 0;	/* count arguments */
2503e12c5d1SDavid du Colombier 	for (p = vl; p; p = p->nnext)
2513e12c5d1SDavid du Colombier 		n++;
2523e12c5d1SDavid du Colombier 	v->fval = n;
2533e12c5d1SDavid du Colombier 	dprintf( ("defining func %s (%d args)\n", v->nval, n) );
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier 
isarg(const char * s)256*a2c41696SDavid du Colombier int isarg(const char *s)		/* is s in argument list for current function? */
257219b2ee8SDavid du Colombier {			/* return -1 if not, otherwise arg # */
2583e12c5d1SDavid du Colombier 	extern Node *arglist;
2593e12c5d1SDavid du Colombier 	Node *p = arglist;
2603e12c5d1SDavid du Colombier 	int n;
2613e12c5d1SDavid du Colombier 
2623e12c5d1SDavid du Colombier 	for (n = 0; p != 0; p = p->nnext, n++)
2633e12c5d1SDavid du Colombier 		if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
2643e12c5d1SDavid du Colombier 			return n;
2653e12c5d1SDavid du Colombier 	return -1;
2663e12c5d1SDavid du Colombier }
2677dd7cddfSDavid du Colombier 
ptoi(void * p)2687dd7cddfSDavid du Colombier int ptoi(void *p)	/* convert pointer to integer */
2697dd7cddfSDavid du Colombier {
2707dd7cddfSDavid du Colombier 	return (int) (long) p;	/* swearing that p fits, of course */
2717dd7cddfSDavid du Colombier }
2727dd7cddfSDavid du Colombier 
itonp(int i)2737dd7cddfSDavid du Colombier Node *itonp(int i)	/* and vice versa */
2747dd7cddfSDavid du Colombier {
2757dd7cddfSDavid du Colombier 	return (Node *) (long) i;
2767dd7cddfSDavid du Colombier }
277