xref: /freebsd/contrib/one-true-awk/parse.c (revision f39dd6a9784467f0db5886012b3f4b13899be6b8)
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