1 /***** spin: structs.c *****/
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
12 typedef struct UType {
13 Symbol *nm; /* name of the type */
14 Lextok *cn; /* contents */
15 struct UType *nxt; /* linked list */
19 extern int lineno, depth, Expand_Ok, has_hidden, in_for;
23 static UType *Unames = 0;
24 static UType *Pnames = 0;
26 static Lextok *cpnn(Lextok *, int, int, int);
27 extern void sr_mesg(FILE *, int, int);
34 fatal("illegal reference inside typedef", (char *) 0);
36 for (tmp = Unames; tmp; tmp = tmp->nxt)
37 if (!strcmp(owner->name, tmp->nm->name))
38 { non_fatal("typename %s was defined before",
43 tmp = (UType *) emalloc(sizeof(UType));
51 putUname(FILE *fd, UType *tmp)
55 putUname(fd, tmp->nxt); /* postorder */
56 fprintf(fd, "struct %s { /* user defined type */\n",
58 for (fp = tmp->cn; fp; fp = fp->rgt)
59 for (tl = fp->lft; tl; tl = tl->rgt)
74 for (tmp = Unames; tmp; tmp = tmp->nxt)
75 { if (!strcmp(t, tmp->nm->name))
85 for (tmp = Unames; tmp; tmp = tmp->nxt)
86 { if (!strcmp(t->name, tmp->nm->name))
89 fatal("%s is not a typename", t->name);
94 setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */
100 for (n = p; n; n = n->rgt)
104 fatal("redeclaration of '%s'", n->sym->name);
106 if (n->sym->nbits > 0)
107 non_fatal("(%s) only an unsigned can have width-field",
111 n->sym->hidden |= (4|8|16); /* formal par */
114 { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0)
115 { n->sym->hidden |= 1;
117 } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0)
119 else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0)
120 n->sym->hidden |= 64;
122 n->sym->type = STRUCT; /* classification */
123 n->sym->Slst = m; /* structure itself */
124 n->sym->Snm = t; /* name of typedef */
125 n->sym->Nid = 0; /* this is no chan */
127 if (n->sym->nel <= 0)
128 non_fatal("bad array size for '%s'", n->sym->name);
135 do_same(Lextok *n, Symbol *v, int xinit)
136 { Lextok *tmp, *fp, *tl;
137 int ix = eval(n->lft);
144 /* n->sym->type == STRUCT
147 * structure template: n->sym->Slst
148 * runtime values: n->sym->Sval
150 if (xinit) ini_struct(v); /* once, at top level */
152 if (ix >= v->nel || ix < 0)
153 { printf("spin: indexing %s[%d] - size is %d\n",
154 v->name, ix, v->nel);
155 fatal("indexing error \'%s\'", v->name);
157 if (!n->rgt || !n->rgt->lft)
158 { non_fatal("no subfields %s", v->name); /* i.e., wants all */
159 lineno = oln; Fname = ofn;
163 if (n->rgt->ntyp != '.')
164 { printf("bad subfield type %d\n", n->rgt->ntyp);
169 if (tmp->ntyp != NAME && tmp->ntyp != TYPE)
170 { printf("bad subfield entry %d\n", tmp->ntyp);
173 for (fp = v->Sval[ix]; fp; fp = fp->rgt)
174 for (tl = fp->lft; tl; tl = tl->rgt)
175 if (!strcmp(tl->sym->name, tmp->sym->name))
176 { lineno = oln; Fname = ofn;
179 fatal("cannot locate subfield %s", tmp->sym->name);
184 Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */
189 if (!n || !(tl = do_same(n, v, xinit)))
193 if (tmp->sym->type == STRUCT)
194 { return Rval_struct(tmp, tl, 0);
196 fatal("non-zero 'rgt' on non-structure", 0);
199 /* printf("%d: ix: %d (%d) %d\n", depth, ix, tl->nel, tl->val[ix]); */
200 if (ix >= tl->nel || ix < 0)
201 fatal("indexing error \'%s\'", tl->name);
203 return cast_val(tl->type, tl->val[ix], tl->nbits);
207 Lval_struct(Lextok *n, Symbol *v, int xinit, int a) /* a = assigned value */
212 if (!(tl = do_same(n, v, xinit)))
216 if (tmp->sym->type == STRUCT)
217 return Lval_struct(tmp, tl, 0, a);
219 fatal("non-zero 'rgt' on non-structure", 0);
222 if (ix >= tl->nel || ix < 0)
223 fatal("indexing error \'%s\'", tl->name);
226 a = (a & ((1<<tl->nbits)-1));
228 if (a != tl->val[ix])
237 { Lextok *fp, *tl, *n;
244 if (!m->sym || m->ntyp != STRUCT)
247 n = getuname(m->sym);
249 for (fp = n; fp; fp = fp->rgt)
250 for (tl = fp->lft; tl; tl = tl->rgt)
251 { if (tl->sym->type == STRUCT)
252 { if (tl->sym->nel > 1 || tl->sym->isarray)
253 fatal("array of structures in param list, %s",
255 cnt += Cnt_flds(tl->sym->Slst);
264 { Symbol *s = t->sym;
268 if (s->type != STRUCT)
272 || t->rgt->ntyp != '.' /* gh: had ! in wrong place */
274 return STRUCT; /* not a field reference */
276 return Sym_typ(t->rgt->lft);
280 Width_set(int *wdth, int i, Lextok *n)
284 for (fp = n; fp; fp = fp->rgt)
285 for (tl = fp->lft; tl; tl = tl->rgt)
286 { if (tl->sym->type == STRUCT)
287 j = Width_set(wdth, j, tl->sym->Slst);
289 { for (k = 0; k < tl->sym->nel; k++, j++)
290 wdth[j] = tl->sym->type;
296 ini_struct(Symbol *s)
297 { int i; Lextok *fp, *tl;
299 if (s->type != STRUCT) /* last step */
300 { (void) checkvar(s, 0);
303 if (s->Sval == (Lextok **) 0)
304 { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *));
305 for (i = 0; i < s->nel; i++)
306 { s->Sval[i] = cpnn(s->Slst, 1, 1, 1);
308 for (fp = s->Sval[i]; fp; fp = fp->rgt)
309 for (tl = fp->lft; tl; tl = tl->rgt)
315 cpnn(Lextok *s, int L, int R, int S)
316 { Lextok *d; extern int Nid;
320 d = (Lextok *) emalloc(sizeof(Lextok));
327 if (L) d->lft = cpnn(s->lft, 1, 1, S);
328 if (R) d->rgt = cpnn(s->rgt, 1, 1, S);
331 { d->sym = (Symbol *) emalloc(sizeof(Symbol));
332 memcpy(d->sym, s->sym, sizeof(Symbol));
333 if (d->sym->type == CHAN)
337 fatal("cannot happen cpnn", (char *) 0);
343 full_name(FILE *fd, Lextok *n, Symbol *v, int xinit)
346 int hiddenarrays = 0;
348 fprintf(fd, "%s", v->name);
350 if (!n || !(tl = do_same(n, v, xinit)))
354 if (tmp->sym->type == STRUCT)
356 hiddenarrays = full_name(fd, tmp, tl, 0);
359 fprintf(fd, ".%s", tl->name);
360 out: if (tmp->sym->nel > 1 || tmp->sym->isarray == 1)
361 { fprintf(fd, "[%d]", eval(tmp->lft));
368 validref(Lextok *p, Lextok *c)
372 for (fp = p->sym->Slst; fp; fp = fp->rgt)
373 for (tl = fp->lft; tl; tl = tl->rgt)
374 if (strcmp(tl->sym->name, c->sym->name) == 0)
377 sprintf(lbuf, "no field '%s' defined in structure '%s'\n",
378 c->sym->name, p->sym->name);
379 non_fatal(lbuf, (char *) 0);
383 struct_name(Lextok *n, Symbol *v, int xinit, char *buf)
388 if (!n || !(tl = do_same(n, v, xinit)))
391 if (tmp->sym->type == STRUCT)
393 struct_name(tmp, tl, 0, buf);
396 sprintf(lbuf, ".%s", tl->name);
398 if (tmp->sym->nel > 1 || tmp->sym->isarray == 1)
399 { sprintf(lbuf, "[%d]", eval(tmp->lft));
405 walk2_struct(char *s, Symbol *z)
409 extern void Done_case(char *, Symbol *);
412 if (z->nel == 1 && z->isarray == 0)
413 sprintf(eprefix, "%s%s.", s, z->name);
414 for (ix = 0; ix < z->nel; ix++)
415 { if (z->nel > 1 || z->isarray == 1)
416 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
417 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
418 for (tl = fp->lft; tl; tl = tl->rgt)
419 { if (tl->sym->type == STRUCT)
420 walk2_struct(eprefix, tl->sym);
421 else if (tl->sym->type == CHAN)
422 Done_case(eprefix, tl->sym);
427 walk_struct(FILE *ofd, int dowhat, char *s, Symbol *z, char *a, char *b, char *c)
433 if (z->nel == 1 && z->isarray == 0)
434 sprintf(eprefix, "%s%s.", s, z->name);
435 for (ix = 0; ix < z->nel; ix++)
436 { if (z->nel > 1 || z->isarray == 1)
437 sprintf(eprefix, "%s%s[%d].", s, z->name, ix);
438 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
439 for (tl = fp->lft; tl; tl = tl->rgt)
440 { if (tl->sym->type == STRUCT)
441 walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c);
443 do_var(ofd, dowhat, eprefix, tl->sym, a,b,c);
448 c_struct(FILE *fd, char *ipref, Symbol *z)
450 char pref[256], eprefix[300];
455 for (ix = 0; ix < z->nel; ix++)
456 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
457 for (tl = fp->lft; tl; tl = tl->rgt)
458 { strcpy(eprefix, ipref);
459 if (z->nel > 1 || z->isarray == 1)
460 { /* insert index before last '.' */
461 eprefix[strlen(eprefix)-1] = '\0';
462 sprintf(pref, "[ %d ].", ix);
463 strcat(eprefix, pref);
465 if (tl->sym->type == STRUCT)
466 { strcat(eprefix, tl->sym->name);
467 strcat(eprefix, ".");
468 c_struct(fd, eprefix, tl->sym);
470 c_var(fd, eprefix, tl->sym);
475 dump_struct(Symbol *z, char *prefix, RunList *r)
482 for (ix = 0; ix < z->nel; ix++)
483 { if (z->nel > 1 || z->isarray == 1)
484 sprintf(eprefix, "%s[%d]", prefix, ix);
486 strcpy(eprefix, prefix);
488 for (fp = z->Sval[ix]; fp; fp = fp->rgt)
489 for (tl = fp->lft; tl; tl = tl->rgt)
490 { if (tl->sym->type == STRUCT)
492 strcpy(pref, eprefix);
494 strcat(pref, tl->sym->name);
495 dump_struct(tl->sym, pref, r);
497 for (jx = 0; jx < tl->sym->nel; jx++)
498 { if (tl->sym->type == CHAN)
503 printf("%s(%d):", r->n->name, r->pid);
504 printf("%s.%s", eprefix, tl->sym->name);
505 if (tl->sym->nel > 1 || tl->sym->isarray == 1)
508 sr_mesg(stdout, tl->sym->val[jx],
509 tl->sym->type == MTYPE);
516 retrieve(Lextok **targ, int i, int want, Lextok *n, int Ntyp)
520 for (fp = n; fp; fp = fp->rgt)
521 for (tl = fp->lft; tl; tl = tl->rgt)
522 { if (tl->sym->type == STRUCT)
523 { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp);
525 { Lextok *x = cpnn(tl, 1, 0, 0);
526 x->rgt = nn(ZN, '.', (*targ), ZN);
531 { for (k = 0; k < tl->sym->nel; k++, j++)
533 { *targ = cpnn(tl, 1, 0, 0);
534 (*targ)->lft = nn(ZN, CONST, ZN, ZN);
535 (*targ)->lft->val = k;
537 (*targ)->ntyp = (short) Ntyp;
545 is_explicit(Lextok *n)
548 if (!n->sym) fatal("unexpected - no symbol", 0);
549 if (n->sym->type != STRUCT) return 1;
550 if (!n->rgt) return 0;
551 if (n->rgt->ntyp != '.')
554 printf("ntyp %d\n", n->rgt->ntyp);
555 fatal("unexpected %s, no '.'", n->sym->name);
557 return is_explicit(n->rgt->lft);
561 expand(Lextok *n, int Ok)
562 /* turn rgt-lnked list of struct nms, into ',' list of flds */
563 { Lextok *x = ZN, *y;
568 { y = mk_explicit(n, 1, 0);
570 (void) tail_add(x, y);
580 mk_explicit(Lextok *n, int Ok, int Ntyp)
581 /* produce a single ',' list of fields */
582 { Lextok *bld = ZN, *x;
583 int i, cnt; extern int IArgs;
585 if (n->sym->type != STRUCT
592 && n->rgt->ntyp == '.'
595 && n->rgt->lft->sym->type == STRUCT)
597 bld = mk_explicit(n->rgt->lft, Ok, Ntyp);
598 for (x = bld; x; x = x->rgt)
599 { y = cpnn(n, 1, 0, 0);
600 y->rgt = nn(ZN, '.', x->lft, ZN);
607 if (!Ok || !n->sym->Slst)
608 { if (IArgs) return n;
609 printf("spin: saw '");
610 comment(stdout, n, 0);
612 fatal("incomplete structure ref '%s'", n->sym->name);
615 cnt = Cnt_flds(n->sym->Slst);
616 for (i = cnt-1; i >= 0; i--)
617 { bld = nn(ZN, ',', ZN, bld);
618 if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0)
619 { printf("cannot retrieve field %d\n", i);
620 fatal("bad structure %s", n->sym->name);
622 x = cpnn(n, 1, 0, 0);
623 x->rgt = nn(ZN, '.', bld->lft, ZN);
630 tail_add(Lextok *a, Lextok *b)
633 for (t = a; t->rgt; t = t->rgt)
635 fatal("unexpected type - tail_add", 0);
644 for (tmp = Pnames; tmp; tmp = tmp->nxt)
645 if (!strcmp(n->sym->name, tmp->nm->name))
646 { non_fatal("proctype %s redefined",
650 tmp = (UType *) emalloc(sizeof(UType));
660 for (tmp = Pnames; tmp; tmp = tmp->nxt)
661 { if (!strcmp(t, tmp->nm->name))