/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ │vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi│ ╚──────────────────────────────────────────────────────────────────────────────╝ │ │ │ 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 "libc/mem/mem.h" #include "libc/str/str.h" #include "third_party/awk/awk.h" #include "third_party/awk/awkgram.tab.h" // clang-format off Node *nodealloc(int n) { Node *x; x = (Node *) malloc(sizeof(*x) + (n-1) * sizeof(x)); 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 != NULL; 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; }