1 /* $OpenBSD: parse.c,v 1.12 2020/07/30 17:45:44 millert Exp $ */ 2 /**************************************************************** 3 Copyright (C) Lucent Technologies 1997 4 All Rights Reserved 5 6 Permission to use, copy, modify, and distribute this software and 7 its documentation for any purpose and without fee is hereby 8 granted, provided that the above copyright notice appear in all 9 copies and that both that the copyright notice and this 10 permission notice and warranty disclaimer appear in supporting 11 documentation, and that the name Lucent Technologies or any of 12 its entities not be used in advertising or publicity pertaining 13 to distribution of the software without specific, written prior 14 permission. 15 16 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 18 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 19 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 21 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 22 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 23 THIS SOFTWARE. 24 ****************************************************************/ 25 26 #define DEBUG 27 #include <stdio.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include "awk.h" 31 #include "awkgram.tab.h" 32 33 Node *nodealloc(int n) 34 { 35 Node *x; 36 37 x = malloc(sizeof(*x) + (n-1) * sizeof(x)); 38 if (x == NULL) 39 FATAL("out of space in nodealloc"); 40 x->nnext = NULL; 41 x->lineno = lineno; 42 return(x); 43 } 44 45 Node *exptostat(Node *a) 46 { 47 a->ntype = NSTAT; 48 return(a); 49 } 50 51 Node *node1(int a, Node *b) 52 { 53 Node *x; 54 55 x = nodealloc(1); 56 x->nobj = a; 57 x->narg[0]=b; 58 return(x); 59 } 60 61 Node *node2(int a, Node *b, Node *c) 62 { 63 Node *x; 64 65 x = nodealloc(2); 66 x->nobj = a; 67 x->narg[0] = b; 68 x->narg[1] = c; 69 return(x); 70 } 71 72 Node *node3(int a, Node *b, Node *c, Node *d) 73 { 74 Node *x; 75 76 x = nodealloc(3); 77 x->nobj = a; 78 x->narg[0] = b; 79 x->narg[1] = c; 80 x->narg[2] = d; 81 return(x); 82 } 83 84 Node *node4(int a, Node *b, Node *c, Node *d, Node *e) 85 { 86 Node *x; 87 88 x = nodealloc(4); 89 x->nobj = a; 90 x->narg[0] = b; 91 x->narg[1] = c; 92 x->narg[2] = d; 93 x->narg[3] = e; 94 return(x); 95 } 96 97 Node *node5(int a, Node *b, Node *c, Node *d, Node *e, Node *f) 98 { 99 Node *x; 100 101 x = nodealloc(5); 102 x->nobj = a; 103 x->narg[0] = b; 104 x->narg[1] = c; 105 x->narg[2] = d; 106 x->narg[3] = e; 107 x->narg[4] = f; 108 return(x); 109 } 110 111 Node *stat1(int a, Node *b) 112 { 113 Node *x; 114 115 x = node1(a,b); 116 x->ntype = NSTAT; 117 return(x); 118 } 119 120 Node *stat2(int a, Node *b, Node *c) 121 { 122 Node *x; 123 124 x = node2(a,b,c); 125 x->ntype = NSTAT; 126 return(x); 127 } 128 129 Node *stat3(int a, Node *b, Node *c, Node *d) 130 { 131 Node *x; 132 133 x = node3(a,b,c,d); 134 x->ntype = NSTAT; 135 return(x); 136 } 137 138 Node *stat4(int a, Node *b, Node *c, Node *d, Node *e) 139 { 140 Node *x; 141 142 x = node4(a,b,c,d,e); 143 x->ntype = NSTAT; 144 return(x); 145 } 146 147 Node *op1(int a, Node *b) 148 { 149 Node *x; 150 151 x = node1(a,b); 152 x->ntype = NEXPR; 153 return(x); 154 } 155 156 Node *op2(int a, Node *b, Node *c) 157 { 158 Node *x; 159 160 x = node2(a,b,c); 161 x->ntype = NEXPR; 162 return(x); 163 } 164 165 Node *op3(int a, Node *b, Node *c, Node *d) 166 { 167 Node *x; 168 169 x = node3(a,b,c,d); 170 x->ntype = NEXPR; 171 return(x); 172 } 173 174 Node *op4(int a, Node *b, Node *c, Node *d, Node *e) 175 { 176 Node *x; 177 178 x = node4(a,b,c,d,e); 179 x->ntype = NEXPR; 180 return(x); 181 } 182 183 Node *op5(int a, Node *b, Node *c, Node *d, Node *e, Node *f) 184 { 185 Node *x; 186 187 x = node5(a,b,c,d,e,f); 188 x->ntype = NEXPR; 189 return(x); 190 } 191 192 Node *celltonode(Cell *a, int b) 193 { 194 Node *x; 195 196 a->ctype = OCELL; 197 a->csub = b; 198 x = node1(0, (Node *) a); 199 x->ntype = NVALUE; 200 return(x); 201 } 202 203 Node *rectonode(void) /* make $0 into a Node */ 204 { 205 extern Cell *literal0; 206 return op1(INDIRECT, celltonode(literal0, CUNK)); 207 } 208 209 Node *makearr(Node *p) 210 { 211 Cell *cp; 212 213 if (isvalue(p)) { 214 cp = (Cell *) (p->narg[0]); 215 if (isfcn(cp)) 216 SYNTAX( "%s is a function, not an array", cp->nval ); 217 else if (!isarr(cp)) { 218 xfree(cp->sval); 219 cp->sval = (char *) makesymtab(NSYMTAB); 220 cp->tval = ARR; 221 } 222 } 223 return p; 224 } 225 226 #define PA2NUM 50 /* max number of pat,pat patterns allowed */ 227 int paircnt; /* number of them in use */ 228 int pairstack[PA2NUM]; /* state of each pat,pat */ 229 230 Node *pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */ 231 { 232 Node *x; 233 234 x = node4(PASTAT2, a, b, c, itonp(paircnt)); 235 if (paircnt++ >= PA2NUM) 236 SYNTAX( "limited to %d pat,pat statements", PA2NUM ); 237 x->ntype = NSTAT; 238 return(x); 239 } 240 241 Node *linkum(Node *a, Node *b) 242 { 243 Node *c; 244 245 if (errorflag) /* don't link things that are wrong */ 246 return a; 247 if (a == NULL) 248 return(b); 249 else if (b == NULL) 250 return(a); 251 for (c = a; c->nnext != NULL; c = c->nnext) 252 ; 253 c->nnext = b; 254 return(a); 255 } 256 257 void defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */ 258 { /* body of function, arglist */ 259 Node *p; 260 int n; 261 262 if (isarr(v)) { 263 SYNTAX( "`%s' is an array name and a function name", v->nval ); 264 return; 265 } 266 if (isarg(v->nval) != -1) { 267 SYNTAX( "`%s' is both function name and argument name", v->nval ); 268 return; 269 } 270 271 v->tval = FCN; 272 v->sval = (char *) st; 273 n = 0; /* count arguments */ 274 for (p = vl; p; p = p->nnext) 275 n++; 276 v->fval = n; 277 DPRINTF("defining func %s (%d args)\n", v->nval, n); 278 } 279 280 int isarg(const char *s) /* is s in argument list for current function? */ 281 { /* return -1 if not, otherwise arg # */ 282 extern Node *arglist; 283 Node *p = arglist; 284 int n; 285 286 for (n = 0; p != NULL; p = p->nnext, n++) 287 if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0) 288 return n; 289 return -1; 290 } 291 292 int ptoi(void *p) /* convert pointer to integer */ 293 { 294 return (int) (long) p; /* swearing that p fits, of course */ 295 } 296 297 Node *itonp(int i) /* and vice versa */ 298 { 299 return (Node *) (long) i; 300 } 301