You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
5.1 KiB
276 lines
5.1 KiB
/**************************************************************** |
|
Copyright (C) Lucent Technologies 1997 |
|
All Rights Reserved |
|
|
|
Permission to use, copy, modify, and distribute this software and |
|
its documentation for any purpose and without fee is hereby |
|
granted, provided that the above copyright notice appear in all |
|
copies and that both that the copyright notice and this |
|
permission notice and warranty disclaimer appear in supporting |
|
documentation, and that the name Lucent Technologies or any of |
|
its entities not be used in advertising or publicity pertaining |
|
to distribution of the software without specific, written prior |
|
permission. |
|
|
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. |
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY |
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER |
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, |
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF |
|
THIS SOFTWARE. |
|
****************************************************************/ |
|
|
|
#define DEBUG |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include "awk.h" |
|
#include "ytab.h" |
|
|
|
Node *nodealloc(int n) |
|
{ |
|
Node *x; |
|
|
|
x = (Node *) malloc(sizeof(Node) + (n-1)*sizeof(Node *)); |
|
if (x == NULL) |
|
FATAL("out of space in nodealloc"); |
|
x->nnext = NULL; |
|
x->lineno = lineno; |
|
return(x); |
|
} |
|
|
|
Node *exptostat(Node *a) |
|
{ |
|
a->ntype = NSTAT; |
|
return(a); |
|
} |
|
|
|
Node *node1(int a, Node *b) |
|
{ |
|
Node *x; |
|
|
|
x = nodealloc(1); |
|
x->nobj = a; |
|
x->narg[0]=b; |
|
return(x); |
|
} |
|
|
|
Node *node2(int a, Node *b, Node *c) |
|
{ |
|
Node *x; |
|
|
|
x = nodealloc(2); |
|
x->nobj = a; |
|
x->narg[0] = b; |
|
x->narg[1] = c; |
|
return(x); |
|
} |
|
|
|
Node *node3(int a, Node *b, Node *c, Node *d) |
|
{ |
|
Node *x; |
|
|
|
x = nodealloc(3); |
|
x->nobj = a; |
|
x->narg[0] = b; |
|
x->narg[1] = c; |
|
x->narg[2] = d; |
|
return(x); |
|
} |
|
|
|
Node *node4(int a, Node *b, Node *c, Node *d, Node *e) |
|
{ |
|
Node *x; |
|
|
|
x = nodealloc(4); |
|
x->nobj = a; |
|
x->narg[0] = b; |
|
x->narg[1] = c; |
|
x->narg[2] = d; |
|
x->narg[3] = e; |
|
return(x); |
|
} |
|
|
|
Node *stat1(int a, Node *b) |
|
{ |
|
Node *x; |
|
|
|
x = node1(a,b); |
|
x->ntype = NSTAT; |
|
return(x); |
|
} |
|
|
|
Node *stat2(int a, Node *b, Node *c) |
|
{ |
|
Node *x; |
|
|
|
x = node2(a,b,c); |
|
x->ntype = NSTAT; |
|
return(x); |
|
} |
|
|
|
Node *stat3(int a, Node *b, Node *c, Node *d) |
|
{ |
|
Node *x; |
|
|
|
x = node3(a,b,c,d); |
|
x->ntype = NSTAT; |
|
return(x); |
|
} |
|
|
|
Node *stat4(int a, Node *b, Node *c, Node *d, Node *e) |
|
{ |
|
Node *x; |
|
|
|
x = node4(a,b,c,d,e); |
|
x->ntype = NSTAT; |
|
return(x); |
|
} |
|
|
|
Node *op1(int a, Node *b) |
|
{ |
|
Node *x; |
|
|
|
x = node1(a,b); |
|
x->ntype = NEXPR; |
|
return(x); |
|
} |
|
|
|
Node *op2(int a, Node *b, Node *c) |
|
{ |
|
Node *x; |
|
|
|
x = node2(a,b,c); |
|
x->ntype = NEXPR; |
|
return(x); |
|
} |
|
|
|
Node *op3(int a, Node *b, Node *c, Node *d) |
|
{ |
|
Node *x; |
|
|
|
x = node3(a,b,c,d); |
|
x->ntype = NEXPR; |
|
return(x); |
|
} |
|
|
|
Node *op4(int a, Node *b, Node *c, Node *d, Node *e) |
|
{ |
|
Node *x; |
|
|
|
x = node4(a,b,c,d,e); |
|
x->ntype = NEXPR; |
|
return(x); |
|
} |
|
|
|
Node *celltonode(Cell *a, int b) |
|
{ |
|
Node *x; |
|
|
|
a->ctype = OCELL; |
|
a->csub = b; |
|
x = node1(0, (Node *) a); |
|
x->ntype = NVALUE; |
|
return(x); |
|
} |
|
|
|
Node *rectonode(void) /* make $0 into a Node */ |
|
{ |
|
extern Cell *literal0; |
|
return op1(INDIRECT, celltonode(literal0, CUNK)); |
|
} |
|
|
|
Node *makearr(Node *p) |
|
{ |
|
Cell *cp; |
|
|
|
if (isvalue(p)) { |
|
cp = (Cell *) (p->narg[0]); |
|
if (isfcn(cp)) |
|
SYNTAX( "%s is a function, not an array", cp->nval ); |
|
else if (!isarr(cp)) { |
|
xfree(cp->sval); |
|
cp->sval = (char *) makesymtab(NSYMTAB); |
|
cp->tval = ARR; |
|
} |
|
} |
|
return p; |
|
} |
|
|
|
#define PA2NUM 50 /* max number of pat,pat patterns allowed */ |
|
int paircnt; /* number of them in use */ |
|
int pairstack[PA2NUM]; /* state of each pat,pat */ |
|
|
|
Node *pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */ |
|
{ |
|
Node *x; |
|
|
|
x = node4(PASTAT2, a, b, c, itonp(paircnt)); |
|
if (paircnt++ >= PA2NUM) |
|
SYNTAX( "limited to %d pat,pat statements", PA2NUM ); |
|
x->ntype = NSTAT; |
|
return(x); |
|
} |
|
|
|
Node *linkum(Node *a, Node *b) |
|
{ |
|
Node *c; |
|
|
|
if (errorflag) /* don't link things that are wrong */ |
|
return a; |
|
if (a == NULL) |
|
return(b); |
|
else if (b == NULL) |
|
return(a); |
|
for (c = a; c->nnext != NULL; c = c->nnext) |
|
; |
|
c->nnext = b; |
|
return(a); |
|
} |
|
|
|
void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */ |
|
{ /* body of function, arglist */ |
|
Node *p; |
|
int n; |
|
|
|
if (isarr(v)) { |
|
SYNTAX( "`%s' is an array name and a function name", v->nval ); |
|
return; |
|
} |
|
if (isarg(v->nval) != -1) { |
|
SYNTAX( "`%s' is both function name and argument name", v->nval ); |
|
return; |
|
} |
|
|
|
v->tval = FCN; |
|
v->sval = (char *) st; |
|
n = 0; /* count arguments */ |
|
for (p = vl; p; p = p->nnext) |
|
n++; |
|
v->fval = n; |
|
dprintf( ("defining func %s (%d args)\n", v->nval, n) ); |
|
} |
|
|
|
int isarg(const char *s) /* is s in argument list for current function? */ |
|
{ /* return -1 if not, otherwise arg # */ |
|
extern Node *arglist; |
|
Node *p = arglist; |
|
int n; |
|
|
|
for (n = 0; p != 0; p = p->nnext, n++) |
|
if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0) |
|
return n; |
|
return -1; |
|
} |
|
|
|
int ptoi(void *p) /* convert pointer to integer */ |
|
{ |
|
return (int) (long) p; /* swearing that p fits, of course */ |
|
} |
|
|
|
Node *itonp(int i) /* and vice versa */ |
|
{ |
|
return (Node *) (long) i; |
|
}
|
|
|