diff --git a/Src/dstep.c b/Src/dstep.c index d823ded..8d12e4f 100644 --- a/Src/dstep.c +++ b/Src/dstep.c @@ -6,419 +6,419 @@ * Tool documentation is available at http://spinroot.com */ +#include "spin.h" /* include this first for strdup & getline */ #include -#include "spin.h" #include "y.tab.h" -#define MAXDSTEP 2048 /* was 512 */ +#define MAXDSTEP 2048 /* was 512 */ -char *NextLab[64]; /* must match value in pangen2.c:41 */ -int Level=0, GenCode=0, IsGuard=0, TestOnly=0; +char *NextLab[64]; /* must match value in pangen2.c:41 */ +int Level=0, GenCode=0, IsGuard=0, TestOnly=0; -static int Tj=0, Jt=0, LastGoto=0; -static int Tojump[MAXDSTEP], Jumpto[MAXDSTEP], Special[MAXDSTEP]; -static void putCode(FILE *, Element *, Element *, Element *, int); +static int Tj=0, Jt=0, LastGoto=0; +static int Tojump[MAXDSTEP], Jumpto[MAXDSTEP], Special[MAXDSTEP]; +static void putCode(FILE *, Element *, Element *, Element *, int); -extern int Pid_nr, separate, OkBreak; +extern int Pid_nr, separate, OkBreak; static void Sourced(int n, int special) -{ int i; - for (i = 0; i < Tj; i++) - if (Tojump[i] == n) - return; - if (Tj >= MAXDSTEP) - fatal("d_step sequence too long", (char *)0); - Special[Tj] = special; - Tojump[Tj++] = n; +{ int i; + for (i = 0; i < Tj; i++) + if (Tojump[i] == n) + return; + if (Tj >= MAXDSTEP) + fatal("d_step sequence too long", (char *)0); + Special[Tj] = special; + Tojump[Tj++] = n; } static void Dested(int n) -{ int i; - for (i = 0; i < Tj; i++) - if (Tojump[i] == n) - return; - for (i = 0; i < Jt; i++) - if (Jumpto[i] == n) - return; - if (Jt >= MAXDSTEP) - fatal("d_step sequence too long", (char *)0); - Jumpto[Jt++] = n; - LastGoto = 1; +{ int i; + for (i = 0; i < Tj; i++) + if (Tojump[i] == n) + return; + for (i = 0; i < Jt; i++) + if (Jumpto[i] == n) + return; + if (Jt >= MAXDSTEP) + fatal("d_step sequence too long", (char *)0); + Jumpto[Jt++] = n; + LastGoto = 1; } static void Mopup(FILE *fd) -{ int i, j; +{ int i, j; - for (i = 0; i < Jt; i++) - { for (j = 0; j < Tj; j++) - if (Tojump[j] == Jumpto[i]) - break; - if (j == Tj) - { char buf[16]; - if (Jumpto[i] == OkBreak) - { if (!LastGoto) - fprintf(fd, "S_%.3d_0: /* break-dest */\n", - OkBreak); - } else { - sprintf(buf, "S_%.3d_0", Jumpto[i]); - non_fatal("goto %s breaks from d_step seq", buf); - } } } - for (j = 0; j < Tj; j++) - { for (i = 0; i < Jt; i++) - if (Tojump[j] == Jumpto[i]) - break; + for (i = 0; i < Jt; i++) + { for (j = 0; j < Tj; j++) + if (Tojump[j] == Jumpto[i]) + break; + if (j == Tj) + { char buf[16]; + if (Jumpto[i] == OkBreak) + { if (!LastGoto) + fprintf(fd, "S_%.3d_0: /* break-dest */\n", + OkBreak); + } else { + sprintf(buf, "S_%.3d_0", Jumpto[i]); + non_fatal("goto %s breaks from d_step seq", buf); + } } } + for (j = 0; j < Tj; j++) + { for (i = 0; i < Jt; i++) + if (Tojump[j] == Jumpto[i]) + break; #ifdef DEBUG - if (i == Jt && !Special[i]) - fprintf(fd, "\t\t/* no goto's to S_%.3d_0 */\n", - Tojump[j]); + if (i == Jt && !Special[i]) + fprintf(fd, "\t\t/* no goto's to S_%.3d_0 */\n", + Tojump[j]); #endif - } - for (j = i = 0; j < Tj; j++) - if (Special[j]) - { if (i >= MAXDSTEP) - { fatal("cannot happen (dstep.c)", (char *)0); - } - Tojump[i] = Tojump[j]; - Special[i] = 2; - i++; - } - Tj = i; /* keep only the global exit-labels */ - Jt = 0; + } + for (j = i = 0; j < Tj; j++) + if (Special[j]) + { if (i >= MAXDSTEP) + { fatal("cannot happen (dstep.c)", (char *)0); + } + Tojump[i] = Tojump[j]; + Special[i] = 2; + i++; + } + Tj = i; /* keep only the global exit-labels */ + Jt = 0; } static int FirstTime(int n) -{ int i; - for (i = 0; i < Tj; i++) - if (Tojump[i] == n) - return (Special[i] <= 1); - return 1; +{ int i; + for (i = 0; i < Tj; i++) + if (Tojump[i] == n) + return (Special[i] <= 1); + return 1; } static void -illegal(Element *e, char *str) +illegal(Element *e, const char *str) { - printf("illegal operator in 'd_step:' '"); - comment(stdout, e->n, 0); - printf("'\n"); - fatal("'%s'", str); + printf("illegal operator in 'd_step:' '"); + comment(stdout, e->n, 0); + printf("'\n"); + fatal("'%s'", str); } static void filterbad(Element *e) { - switch (e->n->ntyp) { - case ASSERT: - case PRINT: - case 'c': - /* run cannot be completely undone - * with sv_save-sv_restor - */ - if (any_oper(e->n->lft, RUN)) - illegal(e, "run operator in d_step"); + switch (e->n->ntyp) { + case ASSERT: + case PRINT: + case 'c': + /* run cannot be completely undone + * with sv_save-sv_restor + */ + if (any_oper(e->n->lft, RUN)) + illegal(e, "run operator in d_step"); - /* remote refs inside d_step sequences - * would be okay, but they cannot always - * be interpreted by the simulator the - * same as by the verifier (e.g., for an - * error trail) - */ - if (any_oper(e->n->lft, 'p')) - illegal(e, "remote reference in d_step"); - break; - case '@': - illegal(e, "process termination"); - break; - case D_STEP: - illegal(e, "nested d_step sequence"); - break; - case ATOMIC: - illegal(e, "nested atomic sequence"); - break; - default: - break; - } + /* remote refs inside d_step sequences + * would be okay, but they cannot always + * be interpreted by the simulator the + * same as by the verifier (e.g., for an + * error trail) + */ + if (any_oper(e->n->lft, 'p')) + illegal(e, "remote reference in d_step"); + break; + case '@': + illegal(e, "process termination"); + break; + case D_STEP: + illegal(e, "nested d_step sequence"); + break; + case ATOMIC: + illegal(e, "nested atomic sequence"); + break; + default: + break; + } } static int CollectGuards(FILE *fd, Element *e, int inh) -{ SeqList *h; Element *ee; +{ SeqList *h; Element *ee; - for (h = e->sub; h; h = h->nxt) - { ee = huntstart(h->this->frst); - filterbad(ee); - switch (ee->n->ntyp) { - case NON_ATOMIC: - inh += CollectGuards(fd, ee->n->sl->this->frst, inh); - break; - case IF: - inh += CollectGuards(fd, ee, inh); - break; - case '.': - if (ee->nxt->n->ntyp == DO) - inh += CollectGuards(fd, ee->nxt, inh); - break; - case ELSE: - if (inh++ > 0) fprintf(fd, " || "); -/* 4.2.5 */ if (!pid_is_claim(Pid_nr)) - fprintf(fd, "(boq == -1 /* else */)"); - else - fprintf(fd, "(1 /* else */)"); - break; - case 'R': - if (inh++ > 0) fprintf(fd, " || "); - fprintf(fd, "("); TestOnly=1; - putstmnt(fd, ee->n, ee->seqno); - fprintf(fd, ")"); TestOnly=0; - break; - case 'r': - if (inh++ > 0) fprintf(fd, " || "); - fprintf(fd, "("); TestOnly=1; - putstmnt(fd, ee->n, ee->seqno); - fprintf(fd, ")"); TestOnly=0; - break; - case 's': - if (inh++ > 0) fprintf(fd, " || "); - fprintf(fd, "("); TestOnly=1; -/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1) && "); - putstmnt(fd, ee->n, ee->seqno); - fprintf(fd, ")"); TestOnly=0; - break; - case 'c': - if (inh++ > 0) fprintf(fd, " || "); - fprintf(fd, "("); TestOnly=1; - if (!pid_is_claim(Pid_nr)) - fprintf(fd, "(boq == -1 && "); - putstmnt(fd, ee->n->lft, e->seqno); - if (!pid_is_claim(Pid_nr)) - fprintf(fd, ")"); - fprintf(fd, ")"); TestOnly=0; - break; - } } - return inh; + for (h = e->sub; h; h = h->nxt) + { ee = huntstart(h->thisS->frst); + filterbad(ee); + switch (ee->n->ntyp) { + case NON_ATOMIC: + inh += CollectGuards(fd, ee->n->sl->thisS->frst, inh); + break; + case IF: + inh += CollectGuards(fd, ee, inh); + break; + case '.': + if (ee->nxt->n->ntyp == DO) + inh += CollectGuards(fd, ee->nxt, inh); + break; + case ELSE: + if (inh++ > 0) fprintf(fd, " || "); +/* 4.2.5 */ if (!pid_is_claim(Pid_nr)) + fprintf(fd, "(boq == -1 /* else */)"); + else + fprintf(fd, "(1 /* else */)"); + break; + case 'R': + if (inh++ > 0) fprintf(fd, " || "); + fprintf(fd, "("); TestOnly=1; + putstmnt(fd, ee->n, ee->seqno); + fprintf(fd, ")"); TestOnly=0; + break; + case 'r': + if (inh++ > 0) fprintf(fd, " || "); + fprintf(fd, "("); TestOnly=1; + putstmnt(fd, ee->n, ee->seqno); + fprintf(fd, ")"); TestOnly=0; + break; + case 's': + if (inh++ > 0) fprintf(fd, " || "); + fprintf(fd, "("); TestOnly=1; +/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq == -1) && "); + putstmnt(fd, ee->n, ee->seqno); + fprintf(fd, ")"); TestOnly=0; + break; + case 'c': + if (inh++ > 0) fprintf(fd, " || "); + fprintf(fd, "("); TestOnly=1; + if (!pid_is_claim(Pid_nr)) + fprintf(fd, "(boq == -1 && "); + putstmnt(fd, ee->n->lft, e->seqno); + if (!pid_is_claim(Pid_nr)) + fprintf(fd, ")"); + fprintf(fd, ")"); TestOnly=0; + break; + } } + return inh; } int putcode(FILE *fd, Sequence *s, Element *nxt, int justguards, int ln, int seqno) -{ int isg=0; - static char buf[64]; +{ int isg=0; + static char buf[64]; - NextLab[0] = "continue"; - filterbad(s->frst); + NextLab[0] = strdup("continue"); + filterbad(s->frst); - switch (s->frst->n->ntyp) { - case UNLESS: - non_fatal("'unless' inside d_step - ignored", (char *) 0); - return putcode(fd, s->frst->n->sl->this, nxt, 0, ln, seqno); - case NON_ATOMIC: - (void) putcode(fd, s->frst->n->sl->this, ZE, 1, ln, seqno); - if (justguards) return 0; /* 6.2.5 */ - break; - case IF: - fprintf(fd, "if (!("); - if (!CollectGuards(fd, s->frst, 0)) /* what about boq? */ - fprintf(fd, "1"); - fprintf(fd, "))\n\t\t\tcontinue;"); - isg = 1; - break; - case '.': - if (s->frst->nxt->n->ntyp == DO) - { fprintf(fd, "if (!("); - if (!CollectGuards(fd, s->frst->nxt, 0)) - fprintf(fd, "1"); - fprintf(fd, "))\n\t\t\tcontinue;"); - isg = 1; - } - break; - case 'R': /* <- can't really happen (it's part of a 'c') */ - fprintf(fd, "if (!("); TestOnly=1; - putstmnt(fd, s->frst->n, s->frst->seqno); - fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; - break; - case 'r': - fprintf(fd, "if (!("); TestOnly=1; - putstmnt(fd, s->frst->n, s->frst->seqno); - fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; - break; - case 's': - fprintf(fd, "if ("); + switch (s->frst->n->ntyp) { + case UNLESS: + non_fatal("'unless' inside d_step - ignored", (char *) 0); + return putcode(fd, s->frst->n->sl->thisS, nxt, 0, ln, seqno); + case NON_ATOMIC: + (void) putcode(fd, s->frst->n->sl->thisS, ZE, 1, ln, seqno); + if (justguards) return 0; /* 6.2.5 */ + break; + case IF: + fprintf(fd, "if (!("); + if (!CollectGuards(fd, s->frst, 0)) /* what about boq? */ + fprintf(fd, "1"); + fprintf(fd, "))\n\t\t\tcontinue;"); + isg = 1; + break; + case '.': + if (s->frst->nxt->n->ntyp == DO) + { fprintf(fd, "if (!("); + if (!CollectGuards(fd, s->frst->nxt, 0)) + fprintf(fd, "1"); + fprintf(fd, "))\n\t\t\tcontinue;"); + isg = 1; + } + break; + case 'R': /* <- can't really happen (it's part of a 'c') */ + fprintf(fd, "if (!("); TestOnly=1; + putstmnt(fd, s->frst->n, s->frst->seqno); + fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; + break; + case 'r': + fprintf(fd, "if (!("); TestOnly=1; + putstmnt(fd, s->frst->n, s->frst->seqno); + fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; + break; + case 's': + fprintf(fd, "if ("); #if 1 -/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq != -1) || "); +/* 4.2.1 */ if (!pid_is_claim(Pid_nr)) fprintf(fd, "(boq != -1) || "); #endif - fprintf(fd, "!("); TestOnly=1; - putstmnt(fd, s->frst->n, s->frst->seqno); - fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; - break; - case 'c': - fprintf(fd, "if (!("); - if (!pid_is_claim(Pid_nr)) fprintf(fd, "boq == -1 && "); - TestOnly=1; - putstmnt(fd, s->frst->n->lft, s->frst->seqno); - fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; - break; - case ELSE: - fprintf(fd, "if (boq != -1 || ("); - if (separate != 2) fprintf(fd, "trpt->"); - fprintf(fd, "o_pm&1))\n\t\t\tcontinue;"); - { extern FILE *fd_th; - fprintf(fd_th, "#ifndef ELSE_IN_GUARD\n"); - fprintf(fd_th, " #define ELSE_IN_GUARD\n"); - fprintf(fd_th, "#endif\n"); - } - break; - case ASGN: /* new 3.0.8 */ - fprintf(fd, "IfNotBlocked"); - break; - default: - fprintf(fd, "/* default %d */\n\t\t", s->frst->n->ntyp); - } + fprintf(fd, "!("); TestOnly=1; + putstmnt(fd, s->frst->n, s->frst->seqno); + fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; + break; + case 'c': + fprintf(fd, "if (!("); + if (!pid_is_claim(Pid_nr)) fprintf(fd, "boq == -1 && "); + TestOnly=1; + putstmnt(fd, s->frst->n->lft, s->frst->seqno); + fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0; + break; + case ELSE: + fprintf(fd, "if (boq != -1 || ("); + if (separate != 2) fprintf(fd, "trpt->"); + fprintf(fd, "o_pm&1))\n\t\t\tcontinue;"); + { extern FILE *fd_th; + fprintf(fd_th, "#ifndef ELSE_IN_GUARD\n"); + fprintf(fd_th, " #define ELSE_IN_GUARD\n"); + fprintf(fd_th, "#endif\n"); + } + break; + case ASGN: /* new 3.0.8 */ + fprintf(fd, "IfNotBlocked"); + break; + default: + fprintf(fd, "/* default %d */\n\t\t", s->frst->n->ntyp); + } - /* 6.2.5 : before TstOnly */ - fprintf(fd, "\n\n\t\treached[%d][%d] = 1;\n\t\t", Pid_nr, seqno); - fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid_nr); /* next state */ - fprintf(fd, "reached[%d][tt] = 1;\n", Pid_nr); /* current state */ + /* 6.2.5 : before TstOnly */ + fprintf(fd, "\n\n\t\treached[%d][%d] = 1;\n\t\t", Pid_nr, seqno); + fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid_nr); /* next state */ + fprintf(fd, "reached[%d][tt] = 1;\n", Pid_nr); /* current state */ - /* 6.2.5 : before sv_save() */ - if (s->frst->n->ntyp != NON_ATOMIC) - fprintf(fd, "\n\t\tif (TstOnly) return 1;\n"); /* if called from enabled() */ + /* 6.2.5 : before sv_save() */ + if (s->frst->n->ntyp != NON_ATOMIC) + fprintf(fd, "\n\t\tif (TstOnly) return 1;\n"); /* if called from enabled() */ - if (justguards) return 0; + if (justguards) return 0; - fprintf(fd, "\n\t\tsv_save();\n\t\t"); - sprintf(buf, "Uerror(\"block in d_step seq, line %d\")", ln); - NextLab[0] = buf; - putCode(fd, s->frst, s->extent, nxt, isg); + fprintf(fd, "\n\t\tsv_save();\n\t\t"); + sprintf(buf, "Uerror(\"block in d_step seq, line %d\")", ln); + NextLab[0] = buf; + putCode(fd, s->frst, s->extent, nxt, isg); - if (nxt) - { extern Symbol *Fname; - extern int lineno; + if (nxt) + { extern Symbol *Fname; + extern int lineno; - if (FirstTime(nxt->Seqno) - && (!(nxt->status & DONE2) || !(nxt->status & D_ATOM))) - { fprintf(fd, "S_%.3d_0: /* 1 */\n", nxt->Seqno); - nxt->status |= DONE2; - LastGoto = 0; - } - Sourced(nxt->Seqno, 1); - lineno = ln; - Fname = nxt->n->fn; - Mopup(fd); - } - unskip(s->frst->seqno); - return LastGoto; + if (FirstTime(nxt->Seqno) + && (!(nxt->status & DONE2) || !(nxt->status & D_ATOM))) + { fprintf(fd, "S_%.3d_0: /* 1 */\n", nxt->Seqno); + nxt->status |= DONE2; + LastGoto = 0; + } + Sourced(nxt->Seqno, 1); + lineno = ln; + Fname = nxt->n->fn; + Mopup(fd); + } + unskip(s->frst->seqno); + return LastGoto; } static void putCode(FILE *fd, Element *f, Element *last, Element *next, int isguard) -{ Element *e, *N; - SeqList *h; int i; - char NextOpt[64]; - static int bno = 0; +{ Element *e, *N; + SeqList *h; int i; + char NextOpt[64]; + static int bno = 0; - for (e = f; e; e = e->nxt) - { if (e->status & DONE2) - continue; - e->status |= DONE2; + for (e = f; e; e = e->nxt) + { if (e->status & DONE2) + continue; + e->status |= DONE2; - if (!(e->status & D_ATOM)) - { if (!LastGoto) - { fprintf(fd, "\t\tgoto S_%.3d_0;\n", - e->Seqno); - Dested(e->Seqno); - } - break; - } - fprintf(fd, "S_%.3d_0: /* 2 */\n", e->Seqno); - LastGoto = 0; - Sourced(e->Seqno, 0); + if (!(e->status & D_ATOM)) + { if (!LastGoto) + { fprintf(fd, "\t\tgoto S_%.3d_0;\n", + e->Seqno); + Dested(e->Seqno); + } + break; + } + fprintf(fd, "S_%.3d_0: /* 2 */\n", e->Seqno); + LastGoto = 0; + Sourced(e->Seqno, 0); - if (!e->sub) - { filterbad(e); - switch (e->n->ntyp) { - case NON_ATOMIC: - h = e->n->sl; - putCode(fd, h->this->frst, - h->this->extent, e->nxt, 0); - break; - case BREAK: - if (LastGoto) break; - if (e->nxt) - { i = target( huntele(e->nxt, - e->status, -1))->Seqno; - fprintf(fd, "\t\tgoto S_%.3d_0; ", i); - fprintf(fd, "/* 'break' */\n"); - Dested(i); - } else - { if (next) - { fprintf(fd, "\t\tgoto S_%.3d_0;", - next->Seqno); - fprintf(fd, " /* NEXT */\n"); - Dested(next->Seqno); - } else - fatal("cannot interpret d_step", 0); - } - break; - case GOTO: - if (LastGoto) break; - i = huntele( get_lab(e->n,1), - e->status, -1)->Seqno; - fprintf(fd, "\t\tgoto S_%.3d_0; ", i); - fprintf(fd, "/* 'goto' */\n"); - Dested(i); - break; - case '.': - if (LastGoto) break; - if (e->nxt && (e->nxt->status & DONE2)) - { i = e->nxt->Seqno; - fprintf(fd, "\t\tgoto S_%.3d_0;", i); - fprintf(fd, " /* '.' */\n"); - Dested(i); - } - break; - default: - putskip(e->seqno); - GenCode = 1; IsGuard = isguard; - fprintf(fd, "\t\t"); - putstmnt(fd, e->n, e->seqno); - fprintf(fd, ";\n"); - GenCode = IsGuard = isguard = LastGoto = 0; - break; - } - i = e->nxt?e->nxt->Seqno:0; - if (e->nxt && (e->nxt->status & DONE2) && !LastGoto) - { fprintf(fd, "\t\tgoto S_%.3d_0; ", i); - fprintf(fd, "/* ';' */\n"); - Dested(i); - break; - } - } else - { for (h = e->sub, i=1; h; h = h->nxt, i++) - { sprintf(NextOpt, "goto S_%.3d_%d", - e->Seqno, i); - NextLab[++Level] = NextOpt; - N = (e->n && e->n->ntyp == DO) ? e : e->nxt; - putCode(fd, h->this->frst, - h->this->extent, N, 1); - Level--; - fprintf(fd, "%s: /* 3 */\n", &NextOpt[5]); - LastGoto = 0; - } - if (!LastGoto) - { fprintf(fd, "\t\tUerror(\"blocking sel "); - fprintf(fd, "in d_step (nr.%d, near line %d)\");\n", - bno++, (e->n)?e->n->ln:0); - LastGoto = 0; - } - } - if (e == last) - { if (!LastGoto && next) - { fprintf(fd, "\t\tgoto S_%.3d_0;\n", - next->Seqno); - Dested(next->Seqno); - } - break; - } } + if (!e->sub) + { filterbad(e); + switch (e->n->ntyp) { + case NON_ATOMIC: + h = e->n->sl; + putCode(fd, h->thisS->frst, + h->thisS->extent, e->nxt, 0); + break; + case BREAK: + if (LastGoto) break; + if (e->nxt) + { i = target( huntele(e->nxt, + e->status, -1))->Seqno; + fprintf(fd, "\t\tgoto S_%.3d_0; ", i); + fprintf(fd, "/* 'break' */\n"); + Dested(i); + } else + { if (next) + { fprintf(fd, "\t\tgoto S_%.3d_0;", + next->Seqno); + fprintf(fd, " /* NEXT */\n"); + Dested(next->Seqno); + } else + fatal("cannot interpret d_step", 0); + } + break; + case GOTO: + if (LastGoto) break; + i = huntele( get_lab(e->n,1), + e->status, -1)->Seqno; + fprintf(fd, "\t\tgoto S_%.3d_0; ", i); + fprintf(fd, "/* 'goto' */\n"); + Dested(i); + break; + case '.': + if (LastGoto) break; + if (e->nxt && (e->nxt->status & DONE2)) + { i = e->nxt->Seqno; + fprintf(fd, "\t\tgoto S_%.3d_0;", i); + fprintf(fd, " /* '.' */\n"); + Dested(i); + } + break; + default: + putskip(e->seqno); + GenCode = 1; IsGuard = isguard; + fprintf(fd, "\t\t"); + putstmnt(fd, e->n, e->seqno); + fprintf(fd, ";\n"); + GenCode = IsGuard = isguard = LastGoto = 0; + break; + } + i = e->nxt?e->nxt->Seqno:0; + if (e->nxt && (e->nxt->status & DONE2) && !LastGoto) + { fprintf(fd, "\t\tgoto S_%.3d_0; ", i); + fprintf(fd, "/* ';' */\n"); + Dested(i); + break; + } + } else + { for (h = e->sub, i=1; h; h = h->nxt, i++) + { sprintf(NextOpt, "goto S_%.3d_%d", + e->Seqno, i); + NextLab[++Level] = NextOpt; + N = (e->n && e->n->ntyp == DO) ? e : e->nxt; + putCode(fd, h->thisS->frst, + h->thisS->extent, N, 1); + Level--; + fprintf(fd, "%s: /* 3 */\n", &NextOpt[5]); + LastGoto = 0; + } + if (!LastGoto) + { fprintf(fd, "\t\tUerror(\"blocking sel "); + fprintf(fd, "in d_step (nr.%d, near line %d)\");\n", + bno++, (e->n)?e->n->ln:0); + LastGoto = 0; + } + } + if (e == last) + { if (!LastGoto && next) + { fprintf(fd, "\t\tgoto S_%.3d_0;\n", + next->Seqno); + Dested(next->Seqno); + } + break; + } } } diff --git a/Src/flow.c b/Src/flow.c index 7176ebc..6cec5e1 100644 --- a/Src/flow.c +++ b/Src/flow.c @@ -76,7 +76,7 @@ Rjumpslocal(Element *q, Element *stop) return 0; } } for (h = f->sub; h; h = h->nxt) - { if (!Rjumpslocal(h->this->frst, h->this->last)) + { if (!Rjumpslocal(h->thisS->frst, h->thisS->last)) return 0; } } @@ -146,12 +146,12 @@ prune_opts(Lextok *n) return; for (l = n->sl; l; l = l->nxt) /* find sequences of unlabeled skips */ - check_sequence(l->this); + check_sequence(l->thisS); } Sequence * close_seq(int nottop) -{ Sequence *s = cur_s->this; +{ Sequence *s = cur_s->thisS; Symbol *z; if (nottop == 0) /* end of proctype body */ @@ -277,7 +277,7 @@ SeqList * seqlist(Sequence *s, SeqList *r) { SeqList *t = (SeqList *) emalloc(sizeof(SeqList)); - t->this = s; + t->thisS = s; t->nxt = r; return t; } @@ -339,18 +339,18 @@ loose_ends(void) /* properly tie-up ends of sub-sequences */ f = f->nxt; if (0) printf("link %d, {%d .. %d} -> %d (ntyp=%d) was %d\n", e->seqno, - e->n->sl->this->frst->seqno, - e->n->sl->this->last->seqno, + e->n->sl->thisS->frst->seqno, + e->n->sl->thisS->last->seqno, f?f->seqno:-1, f?f->n->ntyp:-1, - e->n->sl->this->last->nxt?e->n->sl->this->last->nxt->seqno:-1); - if (!e->n->sl->this->last->nxt) - e->n->sl->this->last->nxt = f; + e->n->sl->thisS->last->nxt?e->n->sl->thisS->last->nxt->seqno:-1); + if (!e->n->sl->thisS->last->nxt) + e->n->sl->thisS->last->nxt = f; else - { if (e->n->sl->this->last->nxt->n->ntyp != GOTO) - { if (!f || e->n->sl->this->last->nxt->seqno != f->seqno) + { if (e->n->sl->thisS->last->nxt->n->ntyp != GOTO) + { if (!f || e->n->sl->thisS->last->nxt->seqno != f->seqno) non_fatal("unexpected: loose ends", (char *)0); } else - e->n->sl->this->last = e->n->sl->this->last->nxt; + e->n->sl->thisS->last = e->n->sl->thisS->last->nxt; /* * fix_dest can push a goto into the nxt position * in that case the goto wins and f is not needed @@ -397,9 +397,9 @@ if_seq(Lextok *n) int ref_chans = 0; for (z = s; z; z = z->nxt) - { if (!z->this->frst) + { if (!z->thisS->frst) continue; - if (z->this->frst->n->ntyp == ELSE) + if (z->thisS->frst->n->ntyp == ELSE) { if (move_else) fatal("duplicate `else'", (char *) 0); if (z->nxt) /* is not already at the end */ @@ -411,7 +411,7 @@ if_seq(Lextok *n) continue; } } else - ref_chans |= has_chanref(z->this->frst->n); + ref_chans |= has_chanref(z->thisS->frst->n); prev_z = z; } if (move_else) @@ -423,8 +423,8 @@ if_seq(Lextok *n) } if (prev_z && ref_chans - && prev_z->this->frst->n->ntyp == ELSE) - { prev_z->this->frst->n->val = 1; + && prev_z->thisS->frst->n->ntyp == ELSE) + { prev_z->thisS->frst->n->val = 1; has_badelse++; if (has_xu) { fatal("invalid use of 'else' combined with i/o and xr/xs assertions,", @@ -440,16 +440,16 @@ if_seq(Lextok *n) e->n->sl = s; /* preserve as info only */ e->sub = s; for (z = s; z; z = z->nxt) - add_el(t, z->this); /* append target */ + add_el(t, z->thisS); /* append target */ if (tok == DO) - { add_el(t, cur_s->this); /* target upfront */ + { add_el(t, cur_s->thisS); /* target upfront */ t = new_el(nn(n, BREAK, ZN, ZN)); /* break target */ set_lab(break_dest(), t); /* new exit */ popbreak(); } - add_el(e, cur_s->this); - add_el(t, cur_s->this); + add_el(e, cur_s->thisS); + add_el(t, cur_s->thisS); return e; /* destination node for label */ } @@ -458,12 +458,12 @@ escape_el(Element *f, Sequence *e) { SeqList *z; for (z = f->esc; z; z = z->nxt) - if (z->this == e) + if (z->thisS == e) return; /* already there */ /* cover the lower-level escapes of this state */ for (z = f->esc; z; z = z->nxt) - attach_escape(z->this, e); + attach_escape(z->thisS, e); /* now attach escape to the state itself */ @@ -477,21 +477,21 @@ escape_el(Element *f, Sequence *e) #endif switch (f->n->ntyp) { case UNLESS: - attach_escape(f->sub->this, e); + attach_escape(f->sub->thisS, e); break; case IF: case DO: for (z = f->sub; z; z = z->nxt) - attach_escape(z->this, e); + attach_escape(z->thisS, e); break; case D_STEP: /* attach only to the guard stmnt */ - escape_el(f->n->sl->this->frst, e); + escape_el(f->n->sl->thisS->frst, e); break; case ATOMIC: case NON_ATOMIC: /* attach to all stmnts */ - attach_escape(f->n->sl->this, e); + attach_escape(f->n->sl->thisS, e); break; } } @@ -524,21 +524,21 @@ unless_seq(Lextok *n) /* append the target state to both */ for (z = s; z; z = z->nxt) - add_el(t, z->this); + add_el(t, z->thisS); /* attach escapes to all states in normal sequence */ - attach_escape(s->this, s->nxt->this); + attach_escape(s->thisS, s->nxt->thisS); - add_el(e, cur_s->this); - add_el(t, cur_s->this); + add_el(e, cur_s->thisS); + add_el(t, cur_s->thisS); #ifdef DEBUG printf("unless element (%d,%d):\n", e->Seqno, t->Seqno); for (z = s; z; z = z->nxt) { Element *x; printf("\t%d,%d,%d :: ", - z->this->frst->Seqno, - z->this->extent->Seqno, - z->this->last->Seqno); - for (x = z->this->frst; x; x = x->nxt) + z->thisS->frst->Seqno, + z->thisS->extent->Seqno, + z->thisS->last->Seqno); + for (x = z->thisS->frst; x; x = x->nxt) printf("(%d)", x->Seqno); printf("\n"); } @@ -601,7 +601,7 @@ add_seq(Lextok *n) if (innermost->ntyp != IF && innermost->ntyp != DO && innermost->ntyp != UNLESS) - add_el(e, cur_s->this); + add_el(e, cur_s->thisS); } void @@ -842,12 +842,12 @@ make_atomic(Sequence *s, int added) case NON_ATOMIC: case ATOMIC: /* redo and search for the last step of that sequence */ - make_atomic(f->n->sl->this, added); + make_atomic(f->n->sl->thisS, added); break; case UNLESS: /* escapes are folded into main sequence */ - make_atomic(f->sub->this, added); + make_atomic(f->sub->thisS, added); break; default: @@ -936,7 +936,7 @@ match_struct(Symbol *s, Symbol *t) } void -valid_name(Lextok *a3, Lextok *a5, Lextok *a8, char *tp) +valid_name(Lextok *a3, Lextok *a5, Lextok *a8, const char *tp) { if (a3->ntyp != NAME) { fatal("%s ( .name : from .. to ) { ... }", tp); @@ -1121,7 +1121,7 @@ walk_atomic(Element *a, Element *b, int added) case NON_ATOMIC: mknonat: f->n->ntyp = NON_ATOMIC; /* can jump here */ h = f->n->sl; - walk_atomic(h->this->frst, h->this->last, added); + walk_atomic(h->thisS->frst, h->thisS->last, added); break; case UNLESS: if (added) @@ -1130,7 +1130,7 @@ mknonat: f->n->ntyp = NON_ATOMIC; /* can jump here */ } } for (h = f->sub; h; h = h->nxt) - walk_atomic(h->this->frst, h->this->last, added); + walk_atomic(h->thisS->frst, h->thisS->last, added); if (f == b) break; } diff --git a/Src/get_strdup.h b/Src/get_strdup.h new file mode 100644 index 0000000..16ab1a4 --- /dev/null +++ b/Src/get_strdup.h @@ -0,0 +1,9 @@ +/* ask for strdup & getline - see https://en.cppreference.com/w/c/experimental/dynamic/getline & https://en.cppreference.com/w/c/experimental/dynamic/strdup */ +#ifdef __STDC_ALLOC_LIB__ + #define __STDC_WANT_LIB_EXT2__ 1 +#else + #define _POSIX_C_SOURCE 200809L +#endif + +#include +#include diff --git a/Src/guided.c b/Src/guided.c index b1f597b..d795728 100644 --- a/Src/guided.c +++ b/Src/guided.c @@ -91,7 +91,7 @@ find_min(Sequence *s) if (e->n->ntyp == ATOMIC || e->n->ntyp == NON_ATOMIC || e->n->ntyp == D_STEP) - { int n = find_min(e->n->sl->this); + { int n = find_min(e->n->sl->thisS); if (n < s->minel) { s->minel = n; } @@ -99,7 +99,7 @@ find_min(Sequence *s) { s->minel = e->Seqno; } for (l = e->sub; l; l = l->nxt) - { int n = find_min(l->this); + { int n = find_min(l->thisS); if (n < s->minel) { s->minel = n; } } } @@ -328,7 +328,7 @@ match_trail(void) { p_talk(og, 1); if (og->n->ntyp == D_STEP) - og = og->n->sl->this->frst; + og = og->n->sl->thisS->frst; printf("\t["); comment(stdout, og->n, 0); @@ -361,7 +361,7 @@ keepgoing: if (dothis->merge_start) { p_talk(dothis, 1); if (dothis->n->ntyp == D_STEP) - dothis = dothis->n->sl->this->frst; + dothis = dothis->n->sl->thisS->frst; printf("\t["); comment(stdout, dothis->n, 0); diff --git a/Src/main.c b/Src/main.c index e307ad0..242130c 100644 --- a/Src/main.c +++ b/Src/main.c @@ -6,9 +6,9 @@ * Tool documentation is available at http://spinroot.com */ +#include "spin.h" #include #include -#include "spin.h" #include "version.h" #include #include @@ -21,1559 +21,1561 @@ #endif #include "y.tab.h" -extern int DstepStart, lineno, tl_terse; -extern FILE *yyin, *yyout, *tl_out; -extern Symbol *context; -extern char *claimproc; -extern void repro_src(void); -extern void qhide(int); -extern char CurScope[MAXSCOPESZ]; -extern short has_provided, has_code, has_ltl, has_accept; -extern int realread, buzzed; -extern void ana_src(int, int); -extern void putprelude(void); - -static void add_comptime(char *); -static void add_runtime(char *); - -Symbol *Fname, *oFname; - -int Etimeouts; /* nr timeouts in program */ -int Ntimeouts; /* nr timeouts in never claim */ -int analyze, columns, dumptab, has_remote, has_remvar; -int interactive, jumpsteps, m_loss, nr_errs, cutoff; -int s_trail, ntrail, verbose, xspin, notabs, rvopt; -int no_print, no_wrapup, Caccess, limited_vis, like_java; -int separate; /* separate compilation */ -int export_ast; /* pangen5.c */ -int norecompile; /* main.c */ -int old_scope_rules; /* use pre 5.3.0 rules */ -int old_priority_rules; /* use pre 6.2.0 rules */ -int product, Strict; -short replay; - -int merger = 1, deadvar = 1, implied_semis = 1; -int ccache = 0; /* oyvind teig: 5.2.0 case caching off by default */ +extern int DstepStart, lineno, tl_terse; +extern FILE *yyin, *yyout, *tl_out; +extern Symbol *context; +extern char *claimproc; +extern void repro_src(void); +extern void qhide(int); +extern char CurScope[MAXSCOPESZ]; +extern short has_provided, has_code, has_ltl, has_accept; +extern int realread, buzzed; +extern void ana_src(int, int); +extern void putprelude(void); + +static void add_comptime(const char *); +static void add_runtime(const char *); + +Symbol *Fname, *oFname; + +int Etimeouts; /* nr timeouts in program */ +int Ntimeouts; /* nr timeouts in never claim */ +int analyze, columns, dumptab, has_remote, has_remvar; +int interactive, jumpsteps, m_loss, nr_errs, cutoff; +int s_trail, ntrail, verbose, xspin, notabs, rvopt; +int no_print, no_wrapup, Caccess, limited_vis, like_java; +int separate; /* separate compilation */ +int export_ast; /* pangen5.c */ +int norecompile; /* main.c */ +int old_scope_rules; /* use pre 5.3.0 rules */ +int old_priority_rules; /* use pre 6.2.0 rules */ +int product, Strict; +short replay; + +int merger = 1, deadvar = 1, implied_semis = 1; +int ccache = 0; /* oyvind teig: 5.2.0 case caching off by default */ static int preprocessonly, SeedUsed, itsr, itsr_n, sw_or_bt; -static int seedy; /* be verbose about chosen seed */ -static int inlineonly; /* show inlined code */ +static int seedy; /* be verbose about chosen seed */ +static int inlineonly; /* show inlined code */ static int dataflow = 1; #if 0 meaning of flags on verbose: - 1 -g global variable values - 2 -l local variable values - 4 -p all process actions - 8 -r receives - 16 -s sends - 32 -v verbose - 64 -w very verbose + 1 -g global variable values + 2 -l local variable values + 4 -p all process actions + 8 -r receives + 16 -s sends + 32 -v verbose + 64 -w very verbose #endif -static char Operator[] = "operator: "; -static char Keyword[] = "keyword: "; -static char Function[] = "function-name: "; -static char **add_ltl = (char **) 0; -static char **ltl_file = (char **) 0; -static char **nvr_file = (char **) 0; -static char *ltl_claims = (char *) 0; -static char *pan_runtime = ""; -static char *pan_comptime = ""; -static char *formula = NULL; -static FILE *fd_ltl = (FILE *) 0; -static char *PreArg[64]; -static int PreCnt = 0; -static char out1[64]; - -char **trailfilename; /* new option 'k' */ - -void explain(int); +static char Operator[] = "operator: "; +static char Keyword[] = "keyword: "; +static char Function[] = "function-name: "; +static char **add_ltl = (char **) 0; +static char **ltl_file = (char **) 0; +static char **nvr_file = (char **) 0; +static const char *ltl_claims = (const char *) 0; +static char empty[] = ""; +static char *pan_runtime = empty; +static char *pan_comptime = empty; +static char *formula = NULL; +static FILE *fd_ltl = (FILE *) 0; +static char *PreArg[64]; +static int PreCnt = 0; +static char out1[64]; + +char **trailfilename; /* new option 'k' */ + +void explain(int); #ifndef CPP - /* to use visual C++: - #define CPP "cl -E/E" - or call spin as: spin -P"CL -E/E" - - on OS2: - #define CPP "icc -E/Pd+ -E/Q+" - or call spin as: spin -P"icc -E/Pd+ -E/Q+" - make sure the -E arg is always at the end, - in each case, because the command line - can later be truncated at that point - */ + /* to use visual C++: + #define CPP "cl -E/E" + or call spin as: spin -P"CL -E/E" + + on OS2: + #define CPP "icc -E/Pd+ -E/Q+" + or call spin as: spin -P"icc -E/Pd+ -E/Q+" + make sure the -E arg is always at the end, + in each case, because the command line + can later be truncated at that point + */ #if 1 - #define CPP "gcc -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c" - /* if gcc-4 is available, this setting is modified below */ + #define CPP "gcc -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c" + /* if gcc-4 is available, this setting is modified below */ #else - #if defined(PC) || defined(MAC) - #define CPP "gcc -std=gnu99 -E -x c" - #else - #ifdef SOLARIS - #define CPP "/usr/ccs/lib/cpp" - #else - #define CPP "cpp" /* sometimes: "/lib/cpp" */ - #endif - #endif + #if defined(PC) || defined(MAC) + #define CPP "gcc -std=gnu99 -E -x c" + #else + #ifdef SOLARIS + #define CPP "/usr/ccs/lib/cpp" + #else + #define CPP "cpp" /* sometimes: "/lib/cpp" */ + #endif + #endif #endif #endif -static char PreProc[512]; -extern int depth; /* at least some steps were made */ +static char PreProc[512]; +extern int depth; /* at least some steps were made */ int WhatSeed(void) { - return SeedUsed; + return SeedUsed; } void final_fiddle(void) -{ char *has_a, *has_l, *has_f; - - /* no -a or -l but has_accept: add -a */ - /* no -a or -l in pan_runtime: add -DSAFETY to pan_comptime */ - /* -a or -l but no -f then add -DNOFAIR */ - - has_a = strstr(pan_runtime, "-a"); - has_l = strstr(pan_runtime, "-l"); - has_f = strstr(pan_runtime, "-f"); - - if (!has_l && !has_a && strstr(pan_comptime, "-DNP")) - { add_runtime("-l"); - has_l = strstr(pan_runtime, "-l"); - } - - if (!has_a && !has_l - && !strstr(pan_comptime, "-DSAFETY")) - { if (has_accept - && !strstr(pan_comptime, "-DBFS") - && !strstr(pan_comptime, "-DNOCLAIM")) - { add_runtime("-a"); - has_a = pan_runtime; - } else - { add_comptime("-DSAFETY"); - } } - - if ((has_a || has_l) && !has_f - && !strstr(pan_comptime, "-DNOFAIR")) - { add_comptime("-DNOFAIR"); - } +{ const char *has_a, *has_l, *has_f; + + /* no -a or -l but has_accept: add -a */ + /* no -a or -l in pan_runtime: add -DSAFETY to pan_comptime */ + /* -a or -l but no -f then add -DNOFAIR */ + + has_a = strstr(pan_runtime, "-a"); + has_l = strstr(pan_runtime, "-l"); + has_f = strstr(pan_runtime, "-f"); + + if (!has_l && !has_a && strstr(pan_comptime, "-DNP")) + { add_runtime("-l"); + has_l = strstr(pan_runtime, "-l"); + } + + if (!has_a && !has_l + && !strstr(pan_comptime, "-DSAFETY")) + { if (has_accept + && !strstr(pan_comptime, "-DBFS") + && !strstr(pan_comptime, "-DNOCLAIM")) + { add_runtime("-a"); + has_a = pan_runtime; + } else + { add_comptime("-DSAFETY"); + } } + + if ((has_a || has_l) && !has_f + && !strstr(pan_comptime, "-DNOFAIR")) + { add_comptime("-DNOFAIR"); + } } static int -change_param(char *t, char *what, int range, int bottom) -{ char *ptr; - int v; - - assert(range < 1000 && range > 0); - if ((ptr = strstr(t, what)) != NULL) - { ptr += strlen(what); - if (!isdigit((int) *ptr)) - { return 0; - } - v = atoi(ptr) + 1; /* was: v = (atoi(ptr)+1)%range */ - if (v >= range) - { v = bottom; - } - if (v >= 100) - { *ptr++ = '0' + (v/100); v %= 100; - *ptr++ = '0' + (v/10); - *ptr = '0' + (v%10); - } else if (v >= 10) - { *ptr++ = '0' + (v/10); - *ptr++ = '0' + (v%10); - *ptr = ' '; - } else - { *ptr++ = '0' + v; - *ptr++ = ' '; - *ptr = ' '; - } } - return 1; +change_param(char *t, const char *what, int range, int bottom) +{ char *ptr; + int v; + + assert(range < 1000 && range > 0); + if ((ptr = strstr(t, what)) != NULL) + { ptr += strlen(what); + if (!isdigit((int) *ptr)) + { return 0; + } + v = atoi(ptr) + 1; /* was: v = (atoi(ptr)+1)%range */ + if (v >= range) + { v = bottom; + } + if (v >= 100) + { *ptr++ = '0' + (v/100); v %= 100; + *ptr++ = '0' + (v/10); + *ptr = '0' + (v%10); + } else if (v >= 10) + { *ptr++ = '0' + (v/10); + *ptr++ = '0' + (v%10); + *ptr = ' '; + } else + { *ptr++ = '0' + v; + *ptr++ = ' '; + *ptr = ' '; + } } + return 1; } static void change_rs(char *t) -{ char *ptr; - int cnt = 0; - long v; - - if ((ptr = strstr(t, "-RS")) != NULL) - { ptr += 3; - /* room for at least 10 digits */ - v = Rand()%1000000000L; - while (v/10 > 0) - { *ptr++ = '0' + v%10; - v /= 10; - cnt++; - } - *ptr++ = '0' + v; - cnt++; - while (cnt++ < 10) - { *ptr++ = ' '; - } } +{ char *ptr; + int cnt = 0; + long v; + + if ((ptr = strstr(t, "-RS")) != NULL) + { ptr += 3; + /* room for at least 10 digits */ + v = Rand()%1000000000L; + while (v/10 > 0) + { *ptr++ = '0' + v%10; + v /= 10; + cnt++; + } + *ptr++ = '0' + v; + cnt++; + while (cnt++ < 10) + { *ptr++ = ' '; + } } } int -omit_str(char *in, char *s) -{ char *ptr = strstr(in, s); - int i, nr = -1; - - if (ptr) - { for (i = 0; i < (int) strlen(s); i++) - { *ptr++ = ' '; - } - if (isdigit((int) *ptr)) - { nr = atoi(ptr); - while (isdigit((int) *ptr)) - { *ptr++ = ' '; - } } } - return nr; +omit_str(char *in, const char *s) +{ char *ptr = (char *) strstr(in, s); + int i, nr = -1; + + if (ptr) + { for (i = 0; i < (int) strlen(s); i++) + { *ptr++ = ' '; + } + if (isdigit((int) *ptr)) + { nr = atoi(ptr); + while (isdigit((int) *ptr)) + { *ptr++ = ' '; + } } } + return nr; } void string_trim(char *t) -{ int n = strlen(t) - 1; +{ int n = strlen(t) - 1; - while (n > 0 && t[n] == ' ') - { t[n--] = '\0'; - } + while (n > 0 && t[n] == ' ') + { t[n--] = '\0'; + } } int e_system(int v, const char *s) -{ static int count = 1; - - /* v == 0 : checks to find non-linked version of gcc */ - /* v == 1 : all other commands */ - /* v == 2 : preprocessing the promela input */ - - if (v == 1) - { if (verbose&(32|64)) /* -v or -w */ - { printf("cmd%02d: %s\n", count++, s); - fflush(stdout); - } - if (verbose&64) /* only -w */ - { return 0; /* suppress the call to system(s) */ - } } - return system(s); +{ static int count = 1; + + /* v == 0 : checks to find non-linked version of gcc */ + /* v == 1 : all other commands */ + /* v == 2 : preprocessing the promela input */ + + if (v == 1) + { if (verbose&(32|64)) /* -v or -w */ + { printf("cmd%02d: %s\n", count++, s); + fflush(stdout); + } + if (verbose&64) /* only -w */ + { return 0; /* suppress the call to system(s) */ + } } + return system(s); } +__attribute__ ((noreturn)) void alldone(int estatus) -{ char *ptr; +{ char *ptr; #if defined(WIN32) || defined(WIN64) - struct _stat x; + struct _stat x; #else - struct stat x; + struct stat x; #endif - if (preprocessonly == 0 && strlen(out1) > 0) - { (void) unlink((const char *) out1); - } - - (void) unlink(TMP_FILE1); - (void) unlink(TMP_FILE2); - - if (!buzzed && seedy && !analyze && !export_ast - && !s_trail && !preprocessonly && depth > 0) - { printf("seed used: %d\n", SeedUsed); - } - - if (!buzzed && xspin && (analyze || s_trail)) - { if (estatus) - { printf("spin: %d error(s) - aborting\n", - estatus); - } else - { printf("Exit-Status 0\n"); - } } - - if (buzzed && replay && !has_code && !estatus) - { extern QH *qh_lst; - QH *j; - int i; - - pan_runtime = (char *) emalloc(2048); /* more than enough */ - sprintf(pan_runtime, "-n%d ", SeedUsed); - if (jumpsteps) - { sprintf(&pan_runtime[strlen(pan_runtime)], "-j%d ", jumpsteps); - } - if (trailfilename) - { sprintf(&pan_runtime[strlen(pan_runtime)], "-k%s ", *trailfilename); - } - if (cutoff) - { sprintf(&pan_runtime[strlen(pan_runtime)], "-u%d ", cutoff); - } - for (i = 1; i <= PreCnt; i++) - { strcat(pan_runtime, PreArg[i]); - strcat(pan_runtime, " "); - } - for (j = qh_lst; j; j = j->nxt) - { sprintf(&pan_runtime[strlen(pan_runtime)], "-q%d ", j->n); - } - if (strcmp(PreProc, CPP) != 0) - { sprintf(&pan_runtime[strlen(pan_runtime)], "\"-P%s\" ", PreProc); - } - /* -oN options 1..5 are ignored in simulations */ - if (old_priority_rules) strcat(pan_runtime, "-o6 "); - if (!implied_semis) strcat(pan_runtime, "-o7 "); - if (no_print) strcat(pan_runtime, "-b "); - if (no_wrapup) strcat(pan_runtime, "-B "); - if (columns == 1) strcat(pan_runtime, "-c "); - if (columns == 2) strcat(pan_runtime, "-M "); - if (seedy == 1) strcat(pan_runtime, "-h "); - if (like_java == 1) strcat(pan_runtime, "-J "); - if (old_scope_rules) strcat(pan_runtime, "-O "); - if (notabs) strcat(pan_runtime, "-T "); - if (verbose&1) strcat(pan_runtime, "-g "); - if (verbose&2) strcat(pan_runtime, "-l "); - if (verbose&4) strcat(pan_runtime, "-p "); - if (verbose&8) strcat(pan_runtime, "-r "); - if (verbose&16) strcat(pan_runtime, "-s "); - if (verbose&32) strcat(pan_runtime, "-v "); - if (verbose&64) strcat(pan_runtime, "-w "); - if (m_loss) strcat(pan_runtime, "-m "); - - char *tmp = (char *) emalloc(strlen("spin -t") + - strlen(pan_runtime) + strlen(Fname->name) + 8); - - sprintf(tmp, "spin -t %s %s", pan_runtime, Fname->name); - estatus = e_system(1, tmp); /* replay */ - exit(estatus); /* replay without c_code */ - } - - if (buzzed && (!replay || has_code) && !estatus) - { char *tmp, *tmp2 = NULL, *P_X; - char *C_X = (buzzed == 2) ? "-O" : ""; - - if (replay && strlen(pan_comptime) == 0) - { + if (preprocessonly == 0 && strlen(out1) > 0) + { (void) unlink((const char *) out1); + } + + (void) unlink(TMP_FILE1); + (void) unlink(TMP_FILE2); + + if (!buzzed && seedy && !analyze && !export_ast + && !s_trail && !preprocessonly && depth > 0) + { printf("seed used: %d\n", SeedUsed); + } + + if (!buzzed && xspin && (analyze || s_trail)) + { if (estatus) + { printf("spin: %d error(s) - aborting\n", + estatus); + } else + { printf("Exit-Status 0\n"); + } } + + if (buzzed && replay && !has_code && !estatus) + { extern QH *qh_lst; + QH *j; + int i; + + pan_runtime = (char *) emalloc(2048); /* more than enough */ + sprintf(pan_runtime, "-n%d ", SeedUsed); + if (jumpsteps) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-j%d ", jumpsteps); + } + if (trailfilename) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-k%s ", *trailfilename); + } + if (cutoff) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-u%d ", cutoff); + } + for (i = 1; i <= PreCnt; i++) + { strcat(pan_runtime, PreArg[i]); + strcat(pan_runtime, " "); + } + for (j = qh_lst; j; j = j->nxt) + { sprintf(&pan_runtime[strlen(pan_runtime)], "-q%d ", j->n); + } + if (strcmp(PreProc, CPP) != 0) + { sprintf(&pan_runtime[strlen(pan_runtime)], "\"-P%s\" ", PreProc); + } + /* -oN options 1..5 are ignored in simulations */ + if (old_priority_rules) strcat(pan_runtime, "-o6 "); + if (!implied_semis) strcat(pan_runtime, "-o7 "); + if (no_print) strcat(pan_runtime, "-b "); + if (no_wrapup) strcat(pan_runtime, "-B "); + if (columns == 1) strcat(pan_runtime, "-c "); + if (columns == 2) strcat(pan_runtime, "-M "); + if (seedy == 1) strcat(pan_runtime, "-h "); + if (like_java == 1) strcat(pan_runtime, "-J "); + if (old_scope_rules) strcat(pan_runtime, "-O "); + if (notabs) strcat(pan_runtime, "-T "); + if (verbose&1) strcat(pan_runtime, "-g "); + if (verbose&2) strcat(pan_runtime, "-l "); + if (verbose&4) strcat(pan_runtime, "-p "); + if (verbose&8) strcat(pan_runtime, "-r "); + if (verbose&16) strcat(pan_runtime, "-s "); + if (verbose&32) strcat(pan_runtime, "-v "); + if (verbose&64) strcat(pan_runtime, "-w "); + if (m_loss) strcat(pan_runtime, "-m "); + + char *tmp = (char *) emalloc(strlen("spin -t") + + strlen(pan_runtime) + strlen(Fname->name) + 8); + + sprintf(tmp, "spin -t %s %s", pan_runtime, Fname->name); + estatus = e_system(1, tmp); /* replay */ + exit(estatus); /* replay without c_code */ + } + + if (buzzed && (!replay || has_code) && !estatus) + { char *tmp, *tmp2 = NULL; const char *P_X; + const char *C_X = (buzzed == 2) ? "-O" : ""; + + if (replay && strlen(pan_comptime) == 0) + { #if defined(WIN32) || defined(WIN64) - P_X = "pan"; + P_X = "pan"; #else - P_X = "./pan"; + P_X = "./pan"; #endif - if (stat(P_X, (struct stat *)&x) < 0) - { goto recompile; /* no executable pan for replay */ - } - tmp = (char *) emalloc(8 + strlen(P_X) + strlen(pan_runtime) +4); - /* the final +4 is too allow adding " &" in some cases */ - sprintf(tmp, "%s %s", P_X, pan_runtime); - goto runit; - } + if (stat(P_X, (struct stat *)&x) < 0) + { goto recompile; /* no executable pan for replay */ + } + tmp = (char *) emalloc(8 + strlen(P_X) + strlen(pan_runtime) +4); + /* the final +4 is too allow adding " &" in some cases */ + sprintf(tmp, "%s %s", P_X, pan_runtime); + goto runit; + } #if defined(WIN32) || defined(WIN64) - P_X = "-o pan pan.c && pan"; + P_X = "-o pan pan.c && pan"; #else - P_X = "-o pan pan.c && ./pan"; + P_X = "-o pan pan.c && ./pan"; #endif - /* swarm and biterate randomization additions */ - if (!replay && itsr) /* iterative search refinement */ - { if (!strstr(pan_comptime, "-DBITSTATE")) - { add_comptime("-DBITSTATE"); - } - if (!strstr(pan_comptime, "-DPUTPID")) - { add_comptime("-DPUTPID"); - } - if (!strstr(pan_comptime, "-DT_RAND") - && !strstr(pan_comptime, "-DT_REVERSE")) - { add_runtime("-T0 "); /* controls t_reverse */ - } - if (!strstr(pan_runtime, "-P") /* runtime flag */ - || pan_runtime[2] < '0' - || pan_runtime[2] > '1') /* no -P0 or -P1 */ - { add_runtime("-P0 "); /* controls p_reverse */ - } - if (!strstr(pan_runtime, "-w")) - { add_runtime("-w18 "); /* -w18 = 256K */ - } else - { char nv[32]; - int x; - x = omit_str(pan_runtime, "-w"); - if (x >= 0) - { sprintf(nv, "-w%d ", x); - add_runtime(nv); /* added spaces */ - } } - if (!strstr(pan_runtime, "-h")) - { add_runtime("-h0 "); /* 0..499 */ - /* leave 2 spaces for increments up to -h499 */ - } else if (!strstr(pan_runtime, "-hash")) - { char nv[32]; - int x; - x = omit_str(pan_runtime, "-h"); - if (x >= 0) - { sprintf(nv, "-h%d ", x%500); - add_runtime(nv); /* added spaces */ - } } - if (!strstr(pan_runtime, "-k")) - { add_runtime("-k1 "); /* 1..3 */ - } else - { char nv[32]; - int x; - x = omit_str(pan_runtime, "-k"); - if (x >= 0) - { sprintf(nv, "-k%d ", x%4); - add_runtime(nv); /* added spaces */ - } } - if (strstr(pan_runtime, "-p_rotate")) - { char nv[32]; - int x; - x = omit_str(pan_runtime, "-p_rotate"); - if (x < 0) - { x = 0; - } - sprintf(nv, "-p_rotate%d ", x%256); - add_runtime(nv); /* added spaces */ - } else if (strstr(pan_runtime, "-p_permute") == 0) - { add_runtime("-p_rotate0 "); - } - if (strstr(pan_runtime, "-RS")) - { (void) omit_str(pan_runtime, "-RS"); - } - /* need room for at least 10 digits */ - add_runtime("-RS1234567890 "); - change_rs(pan_runtime); - } + /* swarm and biterate randomization additions */ + if (!replay && itsr) /* iterative search refinement */ + { if (!strstr(pan_comptime, "-DBITSTATE")) + { add_comptime("-DBITSTATE"); + } + if (!strstr(pan_comptime, "-DPUTPID")) + { add_comptime("-DPUTPID"); + } + if (!strstr(pan_comptime, "-DT_RAND") + && !strstr(pan_comptime, "-DT_REVERSE")) + { add_runtime("-T0 "); /* controls t_reverse */ + } + if (!strstr(pan_runtime, "-P") /* runtime flag */ + || pan_runtime[2] < '0' + || pan_runtime[2] > '1') /* no -P0 or -P1 */ + { add_runtime("-P0 "); /* controls p_reverse */ + } + if (!strstr(pan_runtime, "-w")) + { add_runtime("-w18 "); /* -w18 = 256K */ + } else + { char nv[32]; + int x1; + x1 = omit_str(pan_runtime, "-w"); + if (x1 >= 0) + { sprintf(nv, "-w%d ", x1); + add_runtime(nv); /* added spaces */ + } } + if (!strstr(pan_runtime, "-h")) + { add_runtime("-h0 "); /* 0..499 */ + /* leave 2 spaces for increments up to -h499 */ + } else if (!strstr(pan_runtime, "-hash")) + { char nv[32]; + int x1; + x1 = omit_str(pan_runtime, "-h"); + if (x1 >= 0) + { sprintf(nv, "-h%d ", x1%500); + add_runtime(nv); /* added spaces */ + } } + if (!strstr(pan_runtime, "-k")) + { add_runtime("-k1 "); /* 1..3 */ + } else + { char nv[32]; + int x1; + x1 = omit_str(pan_runtime, "-k"); + if (x1 >= 0) + { sprintf(nv, "-k%d ", x1%4); + add_runtime(nv); /* added spaces */ + } } + if (strstr(pan_runtime, "-p_rotate")) + { char nv[32]; + int x1; + x1 = omit_str(pan_runtime, "-p_rotate"); + if (x1 < 0) + { x1 = 0; + } + sprintf(nv, "-p_rotate%d ", x1%256); + add_runtime(nv); /* added spaces */ + } else if (strstr(pan_runtime, "-p_permute") == 0) + { add_runtime("-p_rotate0 "); + } + if (strstr(pan_runtime, "-RS")) + { (void) omit_str(pan_runtime, "-RS"); + } + /* need room for at least 10 digits */ + add_runtime("-RS1234567890 "); + change_rs(pan_runtime); + } recompile: - if (strstr(PreProc, "cpp")) /* unix/linux */ - { strcpy(PreProc, "gcc"); /* need compiler */ - } else if ((tmp = strstr(PreProc, "-E")) != NULL) - { *tmp = '\0'; /* strip preprocessing flags */ - } - - final_fiddle(); - tmp = (char *) emalloc(8 + /* account for alignment */ - strlen(PreProc) + - strlen(C_X) + - strlen(pan_comptime) + - strlen(P_X) + - strlen(pan_runtime) + - strlen(" -p_reverse & ")); - tmp2 = tmp; - - /* P_X ends with " && ./pan " */ - sprintf(tmp, "%s %s %s %s %s", - PreProc, C_X, pan_comptime, P_X, pan_runtime); - - if (!replay) - { if (itsr < 0) /* swarm only */ - { strcat(tmp, " &"); /* after ./pan */ - itsr = -itsr; /* now same as biterate */ - } - /* do compilation first - * split cc command from run command - * leave cc in tmp, and set tmp2 to run - */ - if ((ptr = strstr(tmp, " && ")) != NULL) - { tmp2 = ptr + 4; /* first run */ - *ptr = '\0'; - } } - - if (has_ltl) - { (void) unlink("_spin_nvr.tmp"); - } - - if (!norecompile) - { /* make sure that if compilation fails we do not continue */ + if (strstr(PreProc, "cpp")) /* unix/linux */ + { strcpy(PreProc, "gcc"); /* need compiler */ + } else if ((tmp = strstr(PreProc, "-E")) != NULL) + { *tmp = '\0'; /* strip preprocessing flags */ + } + + final_fiddle(); + tmp = (char *) emalloc(8 + /* account for alignment */ + strlen(PreProc) + + strlen(C_X) + + strlen(pan_comptime) + + strlen(P_X) + + strlen(pan_runtime) + + strlen(" -p_reverse & ")); + tmp2 = tmp; + + /* P_X ends with " && ./pan " */ + sprintf(tmp, "%s %s %s %s %s", + PreProc, C_X, pan_comptime, P_X, pan_runtime); + + if (!replay) + { if (itsr < 0) /* swarm only */ + { strcat(tmp, " &"); /* after ./pan */ + itsr = -itsr; /* now same as biterate */ + } + /* do compilation first + * split cc command from run command + * leave cc in tmp, and set tmp2 to run + */ + if ((ptr = strstr(tmp, " && ")) != NULL) + { tmp2 = ptr + 4; /* first run */ + *ptr = '\0'; + } } + + if (has_ltl) + { (void) unlink("_spin_nvr.tmp"); + } + + if (!norecompile) + { /* make sure that if compilation fails we do not continue */ #ifdef PC - (void) unlink("./pan.exe"); + (void) unlink("./pan.exe"); #else - (void) unlink("./pan"); + (void) unlink("./pan"); #endif - } + } runit: - if (norecompile && tmp != tmp2) - { estatus = 0; - } else - { estatus = e_system(1, tmp); /* compile or run */ - } - if (replay || estatus < 0) - { goto skipahead; - } - /* !replay */ - if (itsr == 0 && !sw_or_bt) /* single run */ - { estatus = e_system(1, tmp2); - } else if (itsr > 0) /* iterative search refinement */ - { int is_swarm = 0; - if (tmp2 != tmp) /* swarm: did only compilation so far */ - { tmp = tmp2; /* now we point to the run command */ - estatus = e_system(1, tmp); /* first run */ - itsr--; - } - itsr--; /* count down */ - - /* the following are added back randomly later */ - (void) omit_str(tmp, "-p_reverse"); /* replaced by spaces */ - (void) omit_str(tmp, "-p_normal"); - - if (strstr(tmp, " &") != NULL) - { (void) omit_str(tmp, " &"); - is_swarm = 1; - } - - /* increase -w every itsr_n-th run */ - if ((itsr_n > 0 && (itsr == 0 || (itsr%itsr_n) != 0)) - || (change_param(tmp, "-w", 36, 18) >= 0)) /* max 4G bit statespace */ - { (void) change_param(tmp, "-h", 500, 0); /* hash function 0.499 */ - (void) change_param(tmp, "-p_rotate", 256, 0); /* if defined */ - (void) change_param(tmp, "-k", 4, 1); /* nr bits per state 0->1,2,3 */ - (void) change_param(tmp, "-T", 2, 0); /* with or without t_reverse*/ - (void) change_param(tmp, "-P", 2, 0); /* -P 0..1 != p_reverse */ - change_rs(tmp); /* change random seed */ - string_trim(tmp); - if (rand()%5 == 0) /* 20% of all runs */ - { strcat(tmp, " -p_reverse "); - /* at end, so this overrides -p_rotateN, if there */ - /* but -P0..1 disable this in 50% of the cases */ - /* so its really activated in 10% of all runs */ - } else if (rand()%6 == 0) /* override p_rotate and p_reverse */ - { strcat(tmp, " -p_normal "); - } - if (is_swarm) - { strcat(tmp, " &"); - } - goto runit; - } } + if (norecompile && tmp != tmp2) + { estatus = 0; + } else + { estatus = e_system(1, tmp); /* compile or run */ + } + if (replay || estatus < 0) + { goto skipahead; + } + /* !replay */ + if (itsr == 0 && !sw_or_bt) /* single run */ + { estatus = e_system(1, tmp2); + } else if (itsr > 0) /* iterative search refinement */ + { int is_swarm = 0; + if (tmp2 != tmp) /* swarm: did only compilation so far */ + { tmp = tmp2; /* now we point to the run command */ + estatus = e_system(1, tmp); /* first run */ + itsr--; + } + itsr--; /* count down */ + + /* the following are added back randomly later */ + (void) omit_str(tmp, "-p_reverse"); /* replaced by spaces */ + (void) omit_str(tmp, "-p_normal"); + + if (strstr(tmp, " &") != NULL) + { (void) omit_str(tmp, " &"); + is_swarm = 1; + } + + /* increase -w every itsr_n-th run */ + if ((itsr_n > 0 && (itsr == 0 || (itsr%itsr_n) != 0)) + || (change_param(tmp, "-w", 36, 18) >= 0)) /* max 4G bit statespace */ + { (void) change_param(tmp, "-h", 500, 0); /* hash function 0.499 */ + (void) change_param(tmp, "-p_rotate", 256, 0); /* if defined */ + (void) change_param(tmp, "-k", 4, 1); /* nr bits per state 0->1,2,3 */ + (void) change_param(tmp, "-T", 2, 0); /* with or without t_reverse*/ + (void) change_param(tmp, "-P", 2, 0); /* -P 0..1 != p_reverse */ + change_rs(tmp); /* change random seed */ + string_trim(tmp); + if (rand()%5 == 0) /* 20% of all runs */ + { strcat(tmp, " -p_reverse "); + /* at end, so this overrides -p_rotateN, if there */ + /* but -P0..1 disable this in 50% of the cases */ + /* so its really activated in 10% of all runs */ + } else if (rand()%6 == 0) /* override p_rotate and p_reverse */ + { strcat(tmp, " -p_normal "); + } + if (is_swarm) + { strcat(tmp, " &"); + } + goto runit; + } } skipahead: - (void) unlink("pan.b"); - (void) unlink("pan.c"); - (void) unlink("pan.h"); - (void) unlink("pan.m"); - (void) unlink("pan.p"); - (void) unlink("pan.t"); - } - exit(estatus); + (void) unlink("pan.b"); + (void) unlink("pan.c"); + (void) unlink("pan.h"); + (void) unlink("pan.m"); + (void) unlink("pan.p"); + (void) unlink("pan.t"); + } + exit(estatus); } #if 0 - -P0 normal active process creation - -P1 reversed order for *active* process creation != p_reverse + -P0 normal active process creation + -P1 reversed order for *active* process creation != p_reverse - -T0 normal transition exploration - -T1 reversed order of transition exploration + -T0 normal transition exploration + -T1 reversed order of transition exploration - -DP_RAND (random starting point +- -DP_REVERSE) - -DPERMUTED (also enables -p_rotateN and -p_reverse) - -DP_REVERSE (same as -DPERMUTED with -p_reverse, but 7% faster) + -DP_RAND (random starting point +- -DP_REVERSE) + -DPERMUTED (also enables -p_rotateN and -p_reverse) + -DP_REVERSE (same as -DPERMUTED with -p_reverse, but 7% faster) - -DT_RAND (random starting point -- optionally with -T0..1) - -DT_REVERSE (superseded by -T0..1 options) + -DT_RAND (random starting point -- optionally with -T0..1) + -DT_REVERSE (superseded by -T0..1 options) - -hash generates new hash polynomial for -h0 + -hash generates new hash polynomial for -h0 - permutation modes: - -permuted (adds -DPERMUTED) -- this is also the default with -swarm - -t_reverse (same as -T1) - -p_reverse (similar to -P1) - -p_rotateN - -p_normal + permutation modes: + -permuted (adds -DPERMUTED) -- this is also the default with -swarm + -t_reverse (same as -T1) + -p_reverse (similar to -P1) + -p_rotateN + -p_normal - less useful would be (since there is less non-determinism in transitions): - -t_rotateN -- a controlled version of -DT_RAND + less useful would be (since there is less non-determinism in transitions): + -t_rotateN -- a controlled version of -DT_RAND - compiling with -DPERMUTED enables a number of new runtime options, - that -swarmN,M will also exploit: - -p_permute (default) - -p_rotateN - -p_reverse + compiling with -DPERMUTED enables a number of new runtime options, + that -swarmN,M will also exploit: + -p_permute (default) + -p_rotateN + -p_reverse #endif void preprocess(char *a, char *b, int a_tmp) -{ char precmd[1024], cmd[2048]; - int i; +{ char precmd[1024], cmd[2048]; + int i; #ifdef PC - /* gcc is sometimes a symbolic link to gcc-4 - that does not work well in cygwin, so we try - to use the actual executable that is used. - the code below assumes we are on a cygwin-like system - */ - if (strncmp(PreProc, "gcc ", strlen("gcc ")) == 0) - { if (e_system(0, "gcc-4 --version > pan.pre 2>&1") == 0) - { strcpy(PreProc, "gcc-4 -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c"); - } else if (e_system(0, "gcc-3 --version > pan.pre 2>&1") == 0) - { strcpy(PreProc, "gcc-3 -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c"); - } } + /* gcc is sometimes a symbolic link to gcc-4 + that does not work well in cygwin, so we try + to use the actual executable that is used. + the code below assumes we are on a cygwin-like system + */ + if (strncmp(PreProc, "gcc ", strlen("gcc ")) == 0) + { if (e_system(0, "gcc-4 --version > pan.pre 2>&1") == 0) + { strcpy(PreProc, "gcc-4 -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c"); + } else if (e_system(0, "gcc-3 --version > pan.pre 2>&1") == 0) + { strcpy(PreProc, "gcc-3 -std=gnu99 -Wno-unknown-warning-option -Wformat-overflow=0 -E -x c"); + } } #endif - assert(strlen(PreProc) < sizeof(precmd)); - strcpy(precmd, PreProc); - for (i = 1; i <= PreCnt; i++) - { strcat(precmd, " "); - strcat(precmd, PreArg[i]); - } - if (strlen(precmd) > sizeof(precmd)) - { fprintf(stdout, "spin: too many -D args, aborting\n"); - alldone(1); - } - sprintf(cmd, "%s \"%s\" > \"%s\"", precmd, a, b); - if (e_system(2, (const char *)cmd)) /* preprocessing step */ - { (void) unlink((const char *) b); - if (a_tmp) (void) unlink((const char *) a); - fprintf(stdout, "spin: preprocessing failed %s\n", cmd); - alldone(1); /* no return, error exit */ - } - if (a_tmp) (void) unlink((const char *) a); + assert(strlen(PreProc) < sizeof(precmd)); + strcpy(precmd, PreProc); + for (i = 1; i <= PreCnt; i++) + { strcat(precmd, " "); + strcat(precmd, PreArg[i]); + } + if (strlen(precmd) > sizeof(precmd)) + { fprintf(stdout, "spin: too many -D args, aborting\n"); + alldone(1); + } + sprintf(cmd, "%s \"%s\" > \"%s\"", precmd, a, b); + if (e_system(2, (const char *)cmd)) /* preprocessing step */ + { (void) unlink((const char *) b); + if (a_tmp) (void) unlink((const char *) a); + fprintf(stdout, "spin: preprocessing failed %s\n", cmd); + alldone(1); /* no return, error exit */ + } + if (a_tmp) (void) unlink((const char *) a); } void usage(void) { - printf("use: spin [-option] ... [-option] file\n"); - printf("\tNote: file must always be the last argument\n"); - printf("\t-A apply slicing algorithm\n"); - printf("\t-a generate a verifier in pan.c\n"); - printf("\t-B no final state details in simulations\n"); - printf("\t-b don't execute printfs in simulation\n"); - printf("\t-C print channel access info (combine with -g etc.)\n"); - printf("\t-c columnated -s -r simulation output\n"); - printf("\t-d produce symbol-table information\n"); - printf("\t-Dyyy pass -Dyyy to the preprocessor\n"); - printf("\t-Eyyy pass yyy to the preprocessor\n"); - printf("\t-e compute synchronous product of multiple never claims (modified by -L)\n"); - printf("\t-f \"..formula..\" translate LTL "); - printf("into never claim\n"); - printf("\t-F file like -f, but with the LTL formula stored in a 1-line file\n"); - printf("\t-g print all global variables\n"); - printf("\t-h at end of run, print value of seed for random nr generator used\n"); - printf("\t-i interactive (random simulation)\n"); - printf("\t-I show result of inlining and preprocessing\n"); - printf("\t-J reverse eval order of nested unlesses\n"); - printf("\t-jN skip the first N steps "); - printf("in simulation trail\n"); - printf("\t-k fname use the trailfile stored in file fname, see also -t\n"); - printf("\t-L when using -e, use strict language intersection\n"); - printf("\t-l print all local variables\n"); - printf("\t-M generate msc-flow in tcl/tk format\n"); - printf("\t-m lose msgs sent to full queues\n"); - printf("\t-N fname use never claim stored in file fname\n"); - printf("\t-nN seed for random nr generator\n"); - printf("\t-O use old scope rules (pre 5.3.0)\n"); - printf("\t-o1 turn off dataflow-optimizations in verifier\n"); - printf("\t-o2 don't hide write-only variables in verifier\n"); - printf("\t-o3 turn off statement merging in verifier\n"); - printf("\t-o4 turn on rendezvous optiomizations in verifier\n"); - printf("\t-o5 turn on case caching (reduces size of pan.m, but affects reachability reports)\n"); - printf("\t-o6 revert to the old rules for interpreting priority tags (pre version 6.2)\n"); - printf("\t-o7 revert to the old rules for semi-colon usage (pre version 6.3)\n"); - printf("\t-Pxxx use xxx for preprocessing\n"); - printf("\t-p print all statements\n"); - printf("\t-pp pretty-print (reformat) stdin, write stdout\n"); - printf("\t-qN suppress io for queue N in printouts\n"); - printf("\t-r print receive events\n"); - printf("\t-replay replay an error trail-file found earlier\n"); - printf("\t if the model contains embedded c-code, the ./pan executable is used\n"); - printf("\t otherwise spin itself is used to replay the trailfile\n"); - printf("\t note that pan recognizes different runtime options than spin itself\n"); - printf("\t-run (or -search) generate a verifier, and compile and run it\n"); - printf("\t options before -search are interpreted by spin to parse the input\n"); - printf("\t options following a -search are used to compile and run the verifier pan\n"); - printf("\t valid options that can follow a -search argument include:\n"); - printf("\t -bfs perform a breadth-first search\n"); - printf("\t -bfspar perform a parallel breadth-first search\n"); - printf("\t -dfspar perform a parallel depth-first search, same as -DNCORE=4\n"); - printf("\t -bcs use the bounded-context-switching algorithm\n"); - printf("\t -bitstate or -bit, use bitstate storage\n"); - printf("\t -biterateN,M use bitstate with iterative search refinement (-w18..-w35)\n"); - printf("\t perform N randomized runs and increment -w every M runs\n"); - printf("\t default value for N is 10, default for M is 1\n"); - printf("\t (use N,N to keep -w fixed for all runs)\n"); - printf("\t (add -w to see which commands will be executed)\n"); - printf("\t (add -W if ./pan exists and need not be recompiled)\n"); - printf("\t -swarmN,M like -biterate, but running all iterations in parallel\n"); - printf("\t -link file.c link executable pan to file.c\n"); - printf("\t -collapse use collapse state compression\n"); - printf("\t -noreduce do not use partial order reduction\n"); - printf("\t -hc use hash-compact storage\n"); - printf("\t -noclaim ignore all ltl and never claims\n"); - printf("\t -p_permute use process scheduling order random permutation\n"); - printf("\t -p_rotateN use process scheduling order rotation by N\n"); - printf("\t -p_reverse use process scheduling order reversal\n"); - printf("\t -rhash randomly pick one of the -p_... options\n"); - printf("\t -ltl p verify the ltl property named p\n"); - printf("\t -safety compile for safety properties only\n"); - printf("\t -i use the dfs iterative shortening algorithm\n"); - printf("\t -a search for acceptance cycles\n"); - printf("\t -l search for non-progress cycles\n"); - printf("\t similarly, a -D... parameter can be specified to modify the compilation\n"); - printf("\t and any valid runtime pan argument can be specified for the verification\n"); - printf("\t-S1 and -S2 separate pan source for claim and model\n"); - printf("\t-s print send events\n"); - printf("\t-T do not indent printf output\n"); - printf("\t-t[N] follow [Nth] simulation trail, see also -k\n"); - printf("\t-Uyyy pass -Uyyy to the preprocessor\n"); - printf("\t-uN stop a simulation run after N steps\n"); - printf("\t-v verbose, more warnings\n"); - printf("\t-w very verbose (when combined with -l or -g)\n"); - printf("\t-[XYZ] reserved for use by xspin interface\n"); - printf("\t-V print version number and exit\n"); - alldone(1); + printf("use: spin [-option] ... [-option] file\n"); + printf("\tNote: file must always be the last argument\n"); + printf("\t-A apply slicing algorithm\n"); + printf("\t-a generate a verifier in pan.c\n"); + printf("\t-B no final state details in simulations\n"); + printf("\t-b don't execute printfs in simulation\n"); + printf("\t-C print channel access info (combine with -g etc.)\n"); + printf("\t-c columnated -s -r simulation output\n"); + printf("\t-d produce symbol-table information\n"); + printf("\t-Dyyy pass -Dyyy to the preprocessor\n"); + printf("\t-Eyyy pass yyy to the preprocessor\n"); + printf("\t-e compute synchronous product of multiple never claims (modified by -L)\n"); + printf("\t-f \"..formula..\" translate LTL "); + printf("into never claim\n"); + printf("\t-F file like -f, but with the LTL formula stored in a 1-line file\n"); + printf("\t-g print all global variables\n"); + printf("\t-h at end of run, print value of seed for random nr generator used\n"); + printf("\t-i interactive (random simulation)\n"); + printf("\t-I show result of inlining and preprocessing\n"); + printf("\t-J reverse eval order of nested unlesses\n"); + printf("\t-jN skip the first N steps "); + printf("in simulation trail\n"); + printf("\t-k fname use the trailfile stored in file fname, see also -t\n"); + printf("\t-L when using -e, use strict language intersection\n"); + printf("\t-l print all local variables\n"); + printf("\t-M generate msc-flow in tcl/tk format\n"); + printf("\t-m lose msgs sent to full queues\n"); + printf("\t-N fname use never claim stored in file fname\n"); + printf("\t-nN seed for random nr generator\n"); + printf("\t-O use old scope rules (pre 5.3.0)\n"); + printf("\t-o1 turn off dataflow-optimizations in verifier\n"); + printf("\t-o2 don't hide write-only variables in verifier\n"); + printf("\t-o3 turn off statement merging in verifier\n"); + printf("\t-o4 turn on rendezvous optiomizations in verifier\n"); + printf("\t-o5 turn on case caching (reduces size of pan.m, but affects reachability reports)\n"); + printf("\t-o6 revert to the old rules for interpreting priority tags (pre version 6.2)\n"); + printf("\t-o7 revert to the old rules for semi-colon usage (pre version 6.3)\n"); + printf("\t-Pxxx use xxx for preprocessing\n"); + printf("\t-p print all statements\n"); + printf("\t-pp pretty-print (reformat) stdin, write stdout\n"); + printf("\t-qN suppress io for queue N in printouts\n"); + printf("\t-r print receive events\n"); + printf("\t-replay replay an error trail-file found earlier\n"); + printf("\t if the model contains embedded c-code, the ./pan executable is used\n"); + printf("\t otherwise spin itself is used to replay the trailfile\n"); + printf("\t note that pan recognizes different runtime options than spin itself\n"); + printf("\t-run (or -search) generate a verifier, and compile and run it\n"); + printf("\t options before -search are interpreted by spin to parse the input\n"); + printf("\t options following a -search are used to compile and run the verifier pan\n"); + printf("\t valid options that can follow a -search argument include:\n"); + printf("\t -bfs perform a breadth-first search\n"); + printf("\t -bfspar perform a parallel breadth-first search\n"); + printf("\t -dfspar perform a parallel depth-first search, same as -DNCORE=4\n"); + printf("\t -bcs use the bounded-context-switching algorithm\n"); + printf("\t -bitstate or -bit, use bitstate storage\n"); + printf("\t -biterateN,M use bitstate with iterative search refinement (-w18..-w35)\n"); + printf("\t perform N randomized runs and increment -w every M runs\n"); + printf("\t default value for N is 10, default for M is 1\n"); + printf("\t (use N,N to keep -w fixed for all runs)\n"); + printf("\t (add -w to see which commands will be executed)\n"); + printf("\t (add -W if ./pan exists and need not be recompiled)\n"); + printf("\t -swarmN,M like -biterate, but running all iterations in parallel\n"); + printf("\t -link file.c link executable pan to file.c\n"); + printf("\t -collapse use collapse state compression\n"); + printf("\t -noreduce do not use partial order reduction\n"); + printf("\t -hc use hash-compact storage\n"); + printf("\t -noclaim ignore all ltl and never claims\n"); + printf("\t -p_permute use process scheduling order random permutation\n"); + printf("\t -p_rotateN use process scheduling order rotation by N\n"); + printf("\t -p_reverse use process scheduling order reversal\n"); + printf("\t -rhash randomly pick one of the -p_... options\n"); + printf("\t -ltl p verify the ltl property named p\n"); + printf("\t -safety compile for safety properties only\n"); + printf("\t -i use the dfs iterative shortening algorithm\n"); + printf("\t -a search for acceptance cycles\n"); + printf("\t -l search for non-progress cycles\n"); + printf("\t similarly, a -D... parameter can be specified to modify the compilation\n"); + printf("\t and any valid runtime pan argument can be specified for the verification\n"); + printf("\t-S1 and -S2 separate pan source for claim and model\n"); + printf("\t-s print send events\n"); + printf("\t-T do not indent printf output\n"); + printf("\t-t[N] follow [Nth] simulation trail, see also -k\n"); + printf("\t-Uyyy pass -Uyyy to the preprocessor\n"); + printf("\t-uN stop a simulation run after N steps\n"); + printf("\t-v verbose, more warnings\n"); + printf("\t-w very verbose (when combined with -l or -g)\n"); + printf("\t-[XYZ] reserved for use by xspin interface\n"); + printf("\t-V print version number and exit\n"); + alldone(1); } int optimizations(int nr) { - switch (nr) { - case '1': - dataflow = 1 - dataflow; /* dataflow */ - if (verbose&32) - printf("spin: dataflow optimizations turned %s\n", - dataflow?"on":"off"); - break; - case '2': - /* dead variable elimination */ - deadvar = 1 - deadvar; - if (verbose&32) - printf("spin: dead variable elimination turned %s\n", - deadvar?"on":"off"); - break; - case '3': - /* statement merging */ - merger = 1 - merger; - if (verbose&32) - printf("spin: statement merging turned %s\n", - merger?"on":"off"); - break; - - case '4': - /* rv optimization */ - rvopt = 1 - rvopt; - if (verbose&32) - printf("spin: rendezvous optimization turned %s\n", - rvopt?"on":"off"); - break; - case '5': - /* case caching */ - ccache = 1 - ccache; - if (verbose&32) - printf("spin: case caching turned %s\n", - ccache?"on":"off"); - break; - case '6': - old_priority_rules = 1; - if (verbose&32) - printf("spin: using old priority rules (pre version 6.2)\n"); - return 0; /* no break */ - case '7': - implied_semis = 0; - if (verbose&32) - printf("spin: no implied semi-colons (pre version 6.3)\n"); - return 0; /* no break */ - default: - printf("spin: bad or missing parameter on -o\n"); - usage(); - break; - } - return 1; + switch (nr) { + case '1': + dataflow = 1 - dataflow; /* dataflow */ + if (verbose&32) + printf("spin: dataflow optimizations turned %s\n", + dataflow?"on":"off"); + break; + case '2': + /* dead variable elimination */ + deadvar = 1 - deadvar; + if (verbose&32) + printf("spin: dead variable elimination turned %s\n", + deadvar?"on":"off"); + break; + case '3': + /* statement merging */ + merger = 1 - merger; + if (verbose&32) + printf("spin: statement merging turned %s\n", + merger?"on":"off"); + break; + + case '4': + /* rv optimization */ + rvopt = 1 - rvopt; + if (verbose&32) + printf("spin: rendezvous optimization turned %s\n", + rvopt?"on":"off"); + break; + case '5': + /* case caching */ + ccache = 1 - ccache; + if (verbose&32) + printf("spin: case caching turned %s\n", + ccache?"on":"off"); + break; + case '6': + old_priority_rules = 1; + if (verbose&32) + printf("spin: using old priority rules (pre version 6.2)\n"); + return 0; /* no break */ + case '7': + implied_semis = 0; + if (verbose&32) + printf("spin: no implied semi-colons (pre version 6.3)\n"); + return 0; /* no break */ + default: + printf("spin: bad or missing parameter on -o\n"); + usage(); + break; + } + return 1; } static void -add_comptime(char *s) -{ char *tmp; +add_comptime(const char *s) +{ char *tmp; - if (!s || strstr(pan_comptime, s)) - { return; - } + if (!s || strstr(pan_comptime, s)) + { return; + } - tmp = (char *) emalloc(strlen(pan_comptime)+strlen(s)+2); - sprintf(tmp, "%s %s", pan_comptime, s); - pan_comptime = tmp; + tmp = (char *) emalloc(strlen(pan_comptime)+strlen(s)+2); + sprintf(tmp, "%s %s", pan_comptime, s); + pan_comptime = tmp; } static struct { - char *ifsee, *thendo; - int keeparg; + const char *ifsee, *thendo; + int keeparg; } pats[] = { - { "-bfspar", "-DBFS_PAR", 0 }, - { "-bfs", "-DBFS", 0 }, - { "-bcs", "-DBCS", 0 }, - { "-bitstate", "-DBITSTATE", 0 }, - { "-bit", "-DBITSTATE", 0 }, - { "-hc", "-DHC4", 0 }, - { "-collapse", "-DCOLLAPSE", 0 }, - { "-noclaim", "-DNOCLAIM", 0 }, - { "-noreduce", "-DNOREDUCE", 0 }, - { "-np", "-DNP", 0 }, - { "-permuted", "-DPERMUTED", 0 }, - { "-p_permute", "-DPERMUTED", 1 }, - { "-p_rotate", "-DPERMUTED", 1 }, - { "-p_reverse", "-DPERMUTED", 1 }, - { "-rhash", "-DPERMUTED", 1 }, - { "-safety", "-DSAFETY", 0 }, - { "-i", "-DREACH", 1 }, - { "-l", "-DNP", 1 }, - { 0, 0 } + { "-bfspar", "-DBFS_PAR", 0 }, + { "-bfs", "-DBFS", 0 }, + { "-bcs", "-DBCS", 0 }, + { "-bitstate", "-DBITSTATE", 0 }, + { "-bit", "-DBITSTATE", 0 }, + { "-hc", "-DHC4", 0 }, + { "-collapse", "-DCOLLAPSE", 0 }, + { "-noclaim", "-DNOCLAIM", 0 }, + { "-noreduce", "-DNOREDUCE", 0 }, + { "-np", "-DNP", 0 }, + { "-permuted", "-DPERMUTED", 0 }, + { "-p_permute", "-DPERMUTED", 1 }, + { "-p_rotate", "-DPERMUTED", 1 }, + { "-p_reverse", "-DPERMUTED", 1 }, + { "-rhash", "-DPERMUTED", 1 }, + { "-safety", "-DSAFETY", 0 }, + { "-i", "-DREACH", 1 }, + { "-l", "-DNP", 1 }, + { 0, 0, 0 } }; static void -set_itsr_n(char *s) /* e.g., -swarm12,3 */ -{ char *tmp; - - if ((tmp = strchr(s, ',')) != NULL) - { tmp++; - if (*tmp != '\0' && isdigit((int) *tmp)) - { itsr_n = atoi(tmp); - if (itsr_n < 2) - { itsr_n = 0; - } } } +set_itsr_n(const char *s) /* e.g., -swarm12,3 */ +{ const char *tmp; + + if ((tmp = strchr(s, ',')) != NULL) + { tmp++; + if (*tmp != '\0' && isdigit((int) *tmp)) + { itsr_n = atoi(tmp); + if (itsr_n < 2) + { itsr_n = 0; + } } } } static void -add_runtime(char *s) -{ char *tmp; - int i; - - if (strncmp(s, "-biterate", strlen("-biterate")) == 0) - { itsr = 10; /* default nr of sequential iterations */ - sw_or_bt = 1; - if (isdigit((int) s[9])) - { itsr = atoi(&s[9]); - if (itsr < 1) - { itsr = 1; - } - set_itsr_n(s); - } - return; - } - if (strncmp(s, "-swarm", strlen("-swarm")) == 0) - { itsr = -10; /* parallel iterations */ - sw_or_bt = 1; - if (isdigit((int) s[6])) - { itsr = atoi(&s[6]); - if (itsr < 1) - { itsr = 1; - } - itsr = -itsr; - set_itsr_n(s); - } - return; - } - - for (i = 0; pats[i].ifsee; i++) - { if (strncmp(s, pats[i].ifsee, strlen(pats[i].ifsee)) == 0) - { add_comptime(pats[i].thendo); - if (pats[i].keeparg) - { break; - } - return; - } } - if (strncmp(s, "-dfspar", strlen("-dfspar")) == 0) - { add_comptime("-DNCORE=4"); - return; - } - - tmp = (char *) emalloc(strlen(pan_runtime)+strlen(s)+2); - sprintf(tmp, "%s %s", pan_runtime, s); - pan_runtime = tmp; +add_runtime(const char *s) +{ char *tmp; + int i; + + if (strncmp(s, "-biterate", strlen("-biterate")) == 0) + { itsr = 10; /* default nr of sequential iterations */ + sw_or_bt = 1; + if (isdigit((int) s[9])) + { itsr = atoi(&s[9]); + if (itsr < 1) + { itsr = 1; + } + set_itsr_n(s); + } + return; + } + if (strncmp(s, "-swarm", strlen("-swarm")) == 0) + { itsr = -10; /* parallel iterations */ + sw_or_bt = 1; + if (isdigit((int) s[6])) + { itsr = atoi(&s[6]); + if (itsr < 1) + { itsr = 1; + } + itsr = -itsr; + set_itsr_n(s); + } + return; + } + + for (i = 0; pats[i].ifsee; i++) + { if (strncmp(s, pats[i].ifsee, strlen(pats[i].ifsee)) == 0) + { add_comptime(pats[i].thendo); + if (pats[i].keeparg) + { break; + } + return; + } } + if (strncmp(s, "-dfspar", strlen("-dfspar")) == 0) + { add_comptime("-DNCORE=4"); + return; + } + + tmp = (char *) emalloc(strlen(pan_runtime)+strlen(s)+2); + sprintf(tmp, "%s %s", pan_runtime, s); + pan_runtime = tmp; } #ifdef __MINGW32__ - /* mingw on PCs doesn't have a definition of getline - * so we fall back on using a fixed size buffer, to - * avoid having to reimplement getline here·.. - */ + /* mingw on PCs doesn't have a definition of getline + * so we fall back on using a fixed size buffer, to + * avoid having to reimplement getline here·.. + */ ssize_t getline(char **lineptr, size_t *n, FILE *stream) -{ static char buffer[8192]; +{ static char buffer[8192]; - *lineptr = (char *) &buffer; + *lineptr = (char *) &buffer; - if (!fgets(buffer, sizeof(buffer), stream)) - { return 0; - } - return 1; + if (!fgets(buffer, sizeof(buffer), stream)) + { return 0; + } + return 1; } #endif int main(int argc, char *argv[]) -{ Symbol *s; - int T = (int) time((time_t *)0); - int usedopts = 0; - - yyin = stdin; - yyout = stdout; - tl_out = stdout; - strcpy(CurScope, "_"); - - assert(strlen(CPP) < sizeof(PreProc)); - strcpy(PreProc, CPP); - - /* unused flags: y, z, G, L, Q, R, W */ - while (argc > 1 && argv[1][0] == '-') - { switch (argv[1][1]) { - case 'A': export_ast = 1; break; - case 'a': analyze = 1; break; - case 'B': no_wrapup = 1; break; - case 'b': no_print = 1; break; - case 'C': Caccess = 1; break; - case 'c': columns = 1; break; - case 'D': PreArg[++PreCnt] = (char *) &argv[1][0]; - break; /* define */ - case 'd': dumptab = 1; break; - case 'E': PreArg[++PreCnt] = (char *) &argv[1][2]; - break; - case 'e': product++; break; /* see also 'L' */ - case 'F': ltl_file = (char **) (argv+2); - argc--; argv++; break; - case 'f': add_ltl = (char **) argv; - argc--; argv++; break; - case 'g': verbose += 1; break; - case 'h': seedy = 1; break; - case 'i': interactive = 1; break; - case 'I': inlineonly = 1; break; - case 'J': like_java = 1; break; - case 'j': jumpsteps = atoi(&argv[1][2]); break; - case 'k': s_trail = 1; - trailfilename = (char **) (argv+2); - argc--; argv++; break; - case 'L': Strict++; break; /* modified -e */ - case 'l': verbose += 2; break; - case 'M': columns = 2; break; - case 'm': m_loss = 1; break; - case 'N': nvr_file = (char **) (argv+2); - argc--; argv++; break; - case 'n': T = atoi(&argv[1][2]); tl_terse = 1; break; - case 'O': old_scope_rules = 1; break; - case 'o': usedopts += optimizations(argv[1][2]); break; - case 'P': assert(strlen((const char *) &argv[1][2]) < sizeof(PreProc)); - strcpy(PreProc, (const char *) &argv[1][2]); - break; - case 'p': if (argv[1][2] == 'p') - { pretty_print(); - alldone(0); - } - verbose += 4; break; - case 'q': if (isdigit((int) argv[1][2])) - qhide(atoi(&argv[1][2])); - break; - case 'r': - if (strcmp(&argv[1][1], "run") == 0) - { Srand((unsigned int) T); -samecase: if (buzzed != 0) - { fatal("cannot combine -x with -run -replay or -search", (char *)0); - } - buzzed = 2; - analyze = 1; - argc--; argv++; - /* process all remaining arguments, except -w/-W, as relating to pan: */ - while (argc > 1 && argv[1][0] == '-') - { switch (argv[1][1]) { - case 'D': /* eg -DNP */ - /* case 'E': conflicts with runtime arg */ - case 'O': /* eg -O2 */ - case 'U': /* to undefine a macro */ - add_comptime(argv[1]); - break; +{ Symbol *s; + int T = (int) time((time_t *)0); + int usedopts = 0; + + yyin = stdin; + yyout = stdout; + tl_out = stdout; + strcpy(CurScope, "_"); + + assert(strlen(CPP) < sizeof(PreProc)); + strcpy(PreProc, CPP); + + /* unused flags: y, z, G, L, Q, R, W */ + while (argc > 1 && argv[1][0] == '-') + { switch (argv[1][1]) { + case 'A': export_ast = 1; break; + case 'a': analyze = 1; break; + case 'B': no_wrapup = 1; break; + case 'b': no_print = 1; break; + case 'C': Caccess = 1; break; + case 'c': columns = 1; break; + case 'D': PreArg[++PreCnt] = (char *) &argv[1][0]; + break; /* define */ + case 'd': dumptab = 1; break; + case 'E': PreArg[++PreCnt] = (char *) &argv[1][2]; + break; + case 'e': product++; break; /* see also 'L' */ + case 'F': ltl_file = (char **) (argv+2); + argc--; argv++; break; + case 'f': add_ltl = (char **) argv; + argc--; argv++; break; + case 'g': verbose += 1; break; + case 'h': seedy = 1; break; + case 'i': interactive = 1; break; + case 'I': inlineonly = 1; break; + case 'J': like_java = 1; break; + case 'j': jumpsteps = atoi(&argv[1][2]); break; + case 'k': s_trail = 1; + trailfilename = (char **) (argv+2); + argc--; argv++; break; + case 'L': Strict++; break; /* modified -e */ + case 'l': verbose += 2; break; + case 'M': columns = 2; break; + case 'm': m_loss = 1; break; + case 'N': nvr_file = (char **) (argv+2); + argc--; argv++; break; + case 'n': T = atoi(&argv[1][2]); tl_terse = 1; break; + case 'O': old_scope_rules = 1; break; + case 'o': usedopts += optimizations(argv[1][2]); break; + case 'P': assert(strlen((const char *) &argv[1][2]) < sizeof(PreProc)); + strcpy(PreProc, (const char *) &argv[1][2]); + break; + case 'p': if (argv[1][2] == 'p') + { pretty_print(); + alldone(0); + } + verbose += 4; break; + case 'q': if (isdigit((int) argv[1][2])) + qhide(atoi(&argv[1][2])); + break; + case 'r': + if (strcmp(&argv[1][1], "run") == 0) + { Srand((unsigned int) T); +samecase: if (buzzed != 0) + { fatal("cannot combine -x with -run -replay or -search", (char *)0); + } + buzzed = 2; + analyze = 1; + argc--; argv++; + /* process all remaining arguments, except -w/-W, as relating to pan: */ + while (argc > 1 && argv[1][0] == '-') + { switch (argv[1][1]) { + case 'D': /* eg -DNP */ + /* case 'E': conflicts with runtime arg */ + case 'O': /* eg -O2 */ + case 'U': /* to undefine a macro */ + add_comptime(argv[1]); + break; #if 0 - case 'w': /* conflicts with bitstate runtime arg */ - verbose += 64; - break; + case 'w': /* conflicts with bitstate runtime arg */ + verbose += 64; + break; #endif - case 'W': - norecompile = 1; - break; - case 'l': - if (strcmp(&argv[1][1], "ltl") == 0) - { add_runtime("-N"); - argc--; argv++; - add_runtime(argv[1]); /* prop name */ - break; - } - if (strcmp(&argv[1][1], "link") == 0) - { argc--; argv++; - add_comptime(argv[1]); - break; - } - /* else fall through */ - default: - add_runtime(argv[1]); /* -bfs etc. */ - break; - } - argc--; argv++; - } - argc++; argv--; - } else if (strcmp(&argv[1][1], "replay") == 0) - { replay = 1; - add_runtime("-r"); - goto samecase; - } else - { verbose += 8; - } - break; - case 'S': separate = atoi(&argv[1][2]); /* S1 or S2 */ - /* generate code for separate compilation */ - analyze = 1; break; - case 's': - if (strcmp(&argv[1][1], "simulate") == 0) - { break; /* ignore */ - } - if (strcmp(&argv[1][1], "search") == 0) - { goto samecase; - } - verbose += 16; break; - case 'T': notabs = 1; break; - case 't': s_trail = 1; - if (isdigit((int)argv[1][2])) - { ntrail = atoi(&argv[1][2]); - } - break; - case 'U': PreArg[++PreCnt] = (char *) &argv[1][0]; - break; /* undefine */ - case 'u': cutoff = atoi(&argv[1][2]); break; - case 'v': verbose += 32; break; - case 'V': printf("%s\n", SpinVersion); - alldone(0); - break; - case 'w': verbose += 64; break; - case 'W': norecompile = 1; break; /* 6.4.7: for swarm/biterate */ - case 'x': /* internal - reserved use */ - if (buzzed != 0) - { fatal("cannot combine -x with -run -search or -replay", (char *)0); - } - buzzed = 1; /* implies also -a -o3 */ - pan_runtime = "-d"; - analyze = 1; - usedopts += optimizations('3'); - break; - case 'X': xspin = notabs = 1; + case 'W': + norecompile = 1; + break; + case 'l': + if (strcmp(&argv[1][1], "ltl") == 0) + { add_runtime("-N"); + argc--; argv++; + add_runtime(argv[1]); /* prop name */ + break; + } + if (strcmp(&argv[1][1], "link") == 0) + { argc--; argv++; + add_comptime(argv[1]); + break; + } + /* else fall through */ + default: + add_runtime(argv[1]); /* -bfs etc. */ + break; + } + argc--; argv++; + } + argc++; argv--; + } else if (strcmp(&argv[1][1], "replay") == 0) + { replay = 1; + add_runtime("-r"); + goto samecase; + } else + { verbose += 8; + } + break; + case 'S': separate = atoi(&argv[1][2]); /* S1 or S2 */ + /* generate code for separate compilation */ + analyze = 1; break; + case 's': + if (strcmp(&argv[1][1], "simulate") == 0) + { break; /* ignore */ + } + if (strcmp(&argv[1][1], "search") == 0) + { goto samecase; + } + verbose += 16; break; + case 'T': notabs = 1; break; + case 't': s_trail = 1; + if (isdigit((int)argv[1][2])) + { ntrail = atoi(&argv[1][2]); + } + break; + case 'U': PreArg[++PreCnt] = (char *) &argv[1][0]; + break; /* undefine */ + case 'u': cutoff = atoi(&argv[1][2]); break; + case 'v': verbose += 32; break; + case 'V': printf("%s\n", SpinVersion); + alldone(0); + break; + case 'w': verbose += 64; break; + case 'W': norecompile = 1; break; /* 6.4.7: for swarm/biterate */ + case 'x': /* internal - reserved use */ + if (buzzed != 0) + { fatal("cannot combine -x with -run -search or -replay", (char *)0); + } + buzzed = 1; /* implies also -a -o3 */ + pan_runtime = strdup("-d"); + analyze = 1; + usedopts += optimizations('3'); + break; + case 'X': xspin = notabs = 1; #ifndef PC - signal(SIGPIPE, alldone); /* not posix... */ + signal(SIGPIPE, alldone); /* not posix... */ #endif - break; - case 'Y': limited_vis = 1; break; /* used by xspin */ - case 'Z': preprocessonly = 1; break; /* used by xspin */ - - default : usage(); break; - } - argc--; argv++; - } - - if (columns == 2 && !cutoff) - { cutoff = 1024; - } - - if (usedopts && !analyze) - printf("spin: warning -o[1..5] option ignored in simulations\n"); - - if (ltl_file) - { add_ltl = ltl_file-2; add_ltl[1][1] = 'f'; - if (!(tl_out = fopen(*ltl_file, "r"))) - { printf("spin: cannot open %s\n", *ltl_file); - alldone(1); - } - size_t linebuffsize = 0; - ssize_t length = getline(&formula, &linebuffsize, tl_out); - if (!formula || !length) - { printf("spin: cannot read %s\n", *ltl_file); - } - fclose(tl_out); - tl_out = stdout; - *ltl_file = formula; - } - if (argc > 1) - { FILE *fd = stdout; - char cmd[512], out2[512]; - - /* must remain in current dir */ - strcpy(out1, "pan.pre"); - - if (add_ltl || nvr_file) - { assert(strlen(argv[1])+6 < sizeof(out2)); - sprintf(out2, "%s.nvr", argv[1]); - if ((fd = fopen(out2, MFLAGS)) == NULL) - { printf("spin: cannot create tmp file %s\n", - out2); - alldone(1); - } - fprintf(fd, "#include \"%s\"\n", argv[1]); - } - - if (add_ltl) - { tl_out = fd; - nr_errs = tl_main(2, add_ltl); - fclose(fd); - preprocess(out2, out1, 1); - } else if (nvr_file) - { fprintf(fd, "#include \"%s\"\n", *nvr_file); - fclose(fd); - preprocess(out2, out1, 1); - } else - { preprocess(argv[1], out1, 0); - } - - if (preprocessonly) - { alldone(0); - } - - if (!(yyin = fopen(out1, "r"))) - { printf("spin: cannot open %s\n", out1); - alldone(1); - } - - assert(strlen(argv[1])+1 < sizeof(cmd)); - - if (strncmp(argv[1], "progress", (size_t) 8) == 0 - || strncmp(argv[1], "accept", (size_t) 6) == 0) - { sprintf(cmd, "_%s", argv[1]); - } else - { strcpy(cmd, argv[1]); - } - oFname = Fname = lookup(cmd); - if (oFname->name[0] == '\"') - { int i = (int) strlen(oFname->name); - oFname->name[i-1] = '\0'; - oFname = lookup(&oFname->name[1]); - } - } else - { oFname = Fname = lookup(""); - if (add_ltl) - { if (argc > 0) - exit(tl_main(2, add_ltl)); - printf("spin: missing argument to -f\n"); - alldone(1); - } - printf("%s\n", SpinVersion); - fprintf(stderr, "spin: error, no filename specified\n"); - fflush(stdout); - alldone(1); - } - if (columns == 2) - { if (xspin || (verbose & (1|4|8|16|32))) - { printf("spin: -c precludes all flags except -t\n"); - alldone(1); - } - putprelude(); - } - if (columns && !(verbose&8) && !(verbose&16)) - { verbose += (8+16); - } - if (columns == 2 && limited_vis) - { verbose += (1+4); - } - - Srand((unsigned int) T); /* defined in run.c */ - SeedUsed = T; - s = lookup("_"); s->type = PREDEF; /* write-only global var */ - s = lookup("_p"); s->type = PREDEF; - s = lookup("_pid"); s->type = PREDEF; - s = lookup("_last"); s->type = PREDEF; - s = lookup("_nr_pr"); s->type = PREDEF; /* new 3.3.10 */ - s = lookup("_priority"); s->type = PREDEF; /* new 6.2.0 */ - - yyparse(); - fclose(yyin); - - if (ltl_claims) - { Symbol *r; - fclose(fd_ltl); - if (!(yyin = fopen(ltl_claims, "r"))) - { fatal("cannot open %s", ltl_claims); - } - r = oFname; - oFname = Fname = lookup(ltl_claims); - lineno = 0; - yyparse(); - fclose(yyin); - oFname = Fname = r; - if (0) - { (void) unlink(ltl_claims); - } } - - loose_ends(); - - if (inlineonly) - { repro_src(); - return 0; - } - - chanaccess(); - if (!Caccess) - { if (has_provided && merger) - { merger = 0; /* cannot use statement merging in this case */ - } - if (!s_trail && (dataflow || merger) && (!replay || has_code)) - { ana_src(dataflow, merger); - } - sched(); - alldone(nr_errs); - } - - return 0; + break; + case 'Y': limited_vis = 1; break; /* used by xspin */ + case 'Z': preprocessonly = 1; break; /* used by xspin */ + + default : usage(); break; + } + argc--; argv++; + } + + if (columns == 2 && !cutoff) + { cutoff = 1024; + } + + if (usedopts && !analyze) + printf("spin: warning -o[1..5] option ignored in simulations\n"); + + if (ltl_file) + { add_ltl = ltl_file-2; add_ltl[1][1] = 'f'; + if (!(tl_out = fopen(*ltl_file, "r"))) + { printf("spin: cannot open %s\n", *ltl_file); + alldone(1); + } + size_t linebuffsize = 0; + ssize_t length = getline(&formula, &linebuffsize, tl_out); + if (!formula || !length) + { printf("spin: cannot read %s\n", *ltl_file); + } + fclose(tl_out); + tl_out = stdout; + *ltl_file = formula; + } + if (argc > 1) + { FILE *fd = stdout; + char cmd[512], out2[512]; + + /* must remain in current dir */ + strcpy(out1, "pan.pre"); + + if (add_ltl || nvr_file) + { assert(strlen(argv[1])+6 < sizeof(out2)); + sprintf(out2, "%s.nvr", argv[1]); + if ((fd = fopen(out2, MFLAGS)) == NULL) + { printf("spin: cannot create tmp file %s\n", + out2); + alldone(1); + } + fprintf(fd, "#include \"%s\"\n", argv[1]); + } + + if (add_ltl) + { tl_out = fd; + nr_errs = tl_main(2, add_ltl); + fclose(fd); + preprocess(out2, out1, 1); + } else if (nvr_file) + { fprintf(fd, "#include \"%s\"\n", *nvr_file); + fclose(fd); + preprocess(out2, out1, 1); + } else + { preprocess(argv[1], out1, 0); + } + + if (preprocessonly) + { alldone(0); + } + + if (!(yyin = fopen(out1, "r"))) + { printf("spin: cannot open %s\n", out1); + alldone(1); + } + + assert(strlen(argv[1])+1 < sizeof(cmd)); + + if (strncmp(argv[1], "progress", (size_t) 8) == 0 + || strncmp(argv[1], "accept", (size_t) 6) == 0) + { sprintf(cmd, "_%s", argv[1]); + } else + { strcpy(cmd, argv[1]); + } + oFname = Fname = lookup(cmd); + if (oFname->name[0] == '\"') + { int i = (int) strlen(oFname->name); + oFname->name[i-1] = '\0'; + oFname = lookup(&oFname->name[1]); + } + } else + { oFname = Fname = lookup(""); + if (add_ltl) + { if (argc > 0) + exit(tl_main(2, add_ltl)); + printf("spin: missing argument to -f\n"); + alldone(1); + } + printf("%s\n", SpinVersion); + fprintf(stderr, "spin: error, no filename specified\n"); + fflush(stdout); + alldone(1); + } + if (columns == 2) + { if (xspin || (verbose & (1|4|8|16|32))) + { printf("spin: -c precludes all flags except -t\n"); + alldone(1); + } + putprelude(); + } + if (columns && !(verbose&8) && !(verbose&16)) + { verbose += (8+16); + } + if (columns == 2 && limited_vis) + { verbose += (1+4); + } + + Srand((unsigned int) T); /* defined in run.c */ + SeedUsed = T; + s = lookup("_"); s->type = PREDEF; /* write-only global var */ + s = lookup("_p"); s->type = PREDEF; + s = lookup("_pid"); s->type = PREDEF; + s = lookup("_last"); s->type = PREDEF; + s = lookup("_nr_pr"); s->type = PREDEF; /* new 3.3.10 */ + s = lookup("_priority"); s->type = PREDEF; /* new 6.2.0 */ + + yyparse(); + fclose(yyin); + + if (ltl_claims) + { Symbol *r; + fclose(fd_ltl); + if (!(yyin = fopen(ltl_claims, "r"))) + { fatal("cannot open %s", ltl_claims); + } + r = oFname; + oFname = Fname = lookup(ltl_claims); + lineno = 0; + yyparse(); + fclose(yyin); + oFname = Fname = r; + if (0) + { (void) unlink(ltl_claims); + } } + + loose_ends(); + + if (inlineonly) + { repro_src(); + return 0; + } + + chanaccess(); + if (!Caccess) + { if (has_provided && merger) + { merger = 0; /* cannot use statement merging in this case */ + } + if (!s_trail && (dataflow || merger) && (!replay || has_code)) + { ana_src(dataflow, merger); + } + sched(); + alldone(nr_errs); + } + + return 0; } void -ltl_list(char *nm, char *fm) +ltl_list(const char *nm, const char *fm) { - if (s_trail - || analyze - || dumptab) /* when generating pan.c or replaying a trace */ - { if (!ltl_claims) - { ltl_claims = "_spin_nvr.tmp"; - if ((fd_ltl = fopen(ltl_claims, MFLAGS)) == NULL) - { fatal("cannot open tmp file %s", ltl_claims); - } - tl_out = fd_ltl; - } - add_ltl = (char **) emalloc(5 * sizeof(char *)); - add_ltl[1] = "-c"; - add_ltl[2] = nm; - add_ltl[3] = "-f"; - add_ltl[4] = (char *) emalloc(strlen(fm)+4); - strcpy(add_ltl[4], "!("); - strcat(add_ltl[4], fm); - strcat(add_ltl[4], ")"); - /* add_ltl[4] = fm; */ - nr_errs += tl_main(4, add_ltl); - - fflush(tl_out); - /* should read this file after the main file is read */ - } + if (s_trail + || analyze + || dumptab) /* when generating pan.c or replaying a trace */ + { if (!ltl_claims) + { ltl_claims = "_spin_nvr.tmp"; + if ((fd_ltl = fopen(ltl_claims, MFLAGS)) == NULL) + { fatal("cannot open tmp file %s", ltl_claims); + } + tl_out = fd_ltl; + } + add_ltl = (char **) emalloc(5 * sizeof(char *)); + add_ltl[1] = strdup("-c"); + add_ltl[2] = strdup(nm); + add_ltl[3] = strdup("-f"); + add_ltl[4] = (char *) emalloc(strlen(fm)+4); + strcpy(add_ltl[4], "!("); + strcat(add_ltl[4], fm); + strcat(add_ltl[4], ")"); + /* add_ltl[4] = fm; */ + nr_errs += tl_main(4, add_ltl); + + fflush(tl_out); + /* should read this file after the main file is read */ + } } void -non_fatal(char *s1, char *s2) -{ extern int yychar; extern char yytext[]; +non_fatal(const char *s1, const char *s2) +{ extern int yychar; extern char yytext[]; - printf("spin: %s:%d, Error: ", - Fname?Fname->name:(oFname?oFname->name:"nofilename"), lineno); + printf("spin: %s:%d, Error: ", + Fname?Fname->name:(oFname?oFname->name:"nofilename"), lineno); #if 1 - printf(s1, s2); /* avoids a gcc warning */ + printf(s1, s2); /* avoids a gcc warning */ #else - if (s2) - printf(s1, s2); - else - printf(s1); + if (s2) + printf(s1, s2); + else + printf(s1); #endif - if (yychar > 0) - { if (yychar == SEMI) - { printf(" statement separator"); - } else - { printf(" saw '"); - explain(yychar); - printf("'"); - } } - if (strlen(yytext)>1) - printf(" near '%s'", yytext); - printf("\n"); - nr_errs++; + if (yychar > 0) + { if (yychar == SEMI) + { printf(" statement separator"); + } else + { printf(" saw '"); + explain(yychar); + printf("'"); + } } + if (strlen(yytext)>1) + printf(" near '%s'", yytext); + printf("\n"); + nr_errs++; } void -fatal(char *s1, char *s2) +fatal(const char *s1, const char *s2) { - non_fatal(s1, s2); - (void) unlink("pan.b"); - (void) unlink("pan.c"); - (void) unlink("pan.h"); - (void) unlink("pan.m"); - (void) unlink("pan.t"); - (void) unlink("pan.p"); - (void) unlink("pan.pre"); - if (!(verbose&32)) - { (void) unlink("_spin_nvr.tmp"); - } - alldone(1); + non_fatal(s1, s2); + (void) unlink("pan.b"); + (void) unlink("pan.c"); + (void) unlink("pan.h"); + (void) unlink("pan.m"); + (void) unlink("pan.t"); + (void) unlink("pan.p"); + (void) unlink("pan.pre"); + if (!(verbose&32)) + { (void) unlink("_spin_nvr.tmp"); + } + alldone(1); } char * emalloc(size_t n) -{ char *tmp; - static unsigned long cnt = 0; - - if (n == 0) - return NULL; /* robert shelton 10/20/06 */ - - if (!(tmp = (char *) malloc(n))) - { printf("spin: allocated %ld Gb, wanted %d bytes more\n", - cnt/(1024*1024*1024), (int) n); - fatal("not enough memory", (char *)0); - } - cnt += (unsigned long) n; - memset(tmp, 0, n); - return tmp; +{ char *tmp; + static unsigned long cnt = 0; + + if (n == 0) + return NULL; /* robert shelton 10/20/06 */ + + if (!(tmp = (char *) malloc(n))) + { printf("spin: allocated %ld Gb, wanted %d bytes more\n", + cnt/(1024*1024*1024), (int) n); + fatal("not enough memory", (char *)0); + } + cnt += (unsigned long) n; + memset(tmp, 0, n); + return tmp; } void trapwonly(Lextok *n /* , char *unused */) -{ short i; +{ short i; - if (!n) - { fatal("unexpected error,", (char *) 0); - } + if (!n) + { fatal("unexpected error,", (char *) 0); + } - i = (n->sym)?n->sym->type:0; + i = (n->sym)?n->sym->type:0; - /* printf("%s realread %d type %d\n", n->sym?n->sym->name:"--", realread, i); */ + /* printf("%s realread %d type %d\n", n->sym?n->sym->name:"--", realread, i); */ - if (realread - && (i == MTYPE - || i == BIT - || i == BYTE - || i == SHORT - || i == INT - || i == UNSIGNED)) - { n->sym->hidden |= 128; /* var is read at least once */ - } + if (realread + && (i == MTYPE + || i == BIT + || i == BYTE + || i == SHORT + || i == INT + || i == UNSIGNED)) + { n->sym->hidden |= 128; /* var is read at least once */ + } } void setaccess(Symbol *sp, Symbol *what, int cnt, int t) -{ Access *a; - - for (a = sp->access; a; a = a->lnk) - if (a->who == context - && a->what == what - && a->cnt == cnt - && a->typ == t) - return; - - a = (Access *) emalloc(sizeof(Access)); - a->who = context; - a->what = what; - a->cnt = cnt; - a->typ = t; - a->lnk = sp->access; - sp->access = a; +{ Access *a; + + for (a = sp->access; a; a = a->lnk) + if (a->who == context + && a->what == what + && a->cnt == cnt + && a->typ == t) + return; + + a = (Access *) emalloc(sizeof(Access)); + a->who = context; + a->what = what; + a->cnt = cnt; + a->typ = t; + a->lnk = sp->access; + sp->access = a; } Lextok * nn(Lextok *s, int t, Lextok *ll, Lextok *rl) -{ Lextok *n = (Lextok *) emalloc(sizeof(Lextok)); - static int warn_nn = 0; - - n->uiid = is_inline(); /* record origin of the statement */ - n->ntyp = (unsigned short) t; - if (s && s->fn) - { n->ln = s->ln; - n->fn = s->fn; - } else if (rl && rl->fn) - { n->ln = rl->ln; - n->fn = rl->fn; - } else if (ll && ll->fn) - { n->ln = ll->ln; - n->fn = ll->fn; - } else - { n->ln = lineno; - n->fn = Fname; - } - if (s) n->sym = s->sym; - n->lft = ll; - n->rgt = rl; - n->indstep = DstepStart; - - if (t == TIMEOUT) Etimeouts++; - - if (!context) return n; - - if (t == 'r' || t == 's') - setaccess(n->sym, ZS, 0, t); - if (t == 'R') - setaccess(n->sym, ZS, 0, 'P'); - - if (context->name == claimproc) - { int forbidden = separate; - switch (t) { - case ASGN: - printf("spin: Warning, never claim has side-effect\n"); - break; - case 'r': case 's': - non_fatal("never claim contains i/o stmnts",(char *)0); - break; - case TIMEOUT: - /* never claim polls timeout */ - if (Ntimeouts && Etimeouts) - forbidden = 0; - Ntimeouts++; Etimeouts--; - break; - case LEN: case EMPTY: case FULL: - case 'R': case NFULL: case NEMPTY: - /* status becomes non-exclusive */ - if (n->sym && !(n->sym->xu&XX)) - { n->sym->xu |= XX; - if (separate == 2) { - printf("spin: warning, make sure that the S1 model\n"); - printf(" also polls channel '%s' in its claim\n", - n->sym->name); - } } - forbidden = 0; - break; - case 'c': - AST_track(n, 0); /* register as a slice criterion */ - /* fall thru */ - default: - forbidden = 0; - break; - } - if (forbidden) - { printf("spin: never, saw "); explain(t); printf("\n"); - fatal("incompatible with separate compilation",(char *)0); - } - } else if ((t == ENABLED || t == PC_VAL) && !(warn_nn&t)) - { printf("spin: Warning, using %s outside never claim\n", - (t == ENABLED)?"enabled()":"pc_value()"); - warn_nn |= t; - } else if (t == NONPROGRESS) - { fatal("spin: Error, using np_ outside never claim\n", (char *)0); - } - return n; +{ Lextok *n = (Lextok *) emalloc(sizeof(Lextok)); + static int warn_nn = 0; + + n->uiid = is_inline(); /* record origin of the statement */ + n->ntyp = (unsigned short) t; + if (s && s->fn) + { n->ln = s->ln; + n->fn = s->fn; + } else if (rl && rl->fn) + { n->ln = rl->ln; + n->fn = rl->fn; + } else if (ll && ll->fn) + { n->ln = ll->ln; + n->fn = ll->fn; + } else + { n->ln = lineno; + n->fn = Fname; + } + if (s) n->sym = s->sym; + n->lft = ll; + n->rgt = rl; + n->indstep = DstepStart; + + if (t == TIMEOUT) Etimeouts++; + + if (!context) return n; + + if (t == 'r' || t == 's') + setaccess(n->sym, ZS, 0, t); + if (t == 'R') + setaccess(n->sym, ZS, 0, 'P'); + + if (context->name == claimproc) + { int forbidden = separate; + switch (t) { + case ASGN: + printf("spin: Warning, never claim has side-effect\n"); + break; + case 'r': case 's': + non_fatal("never claim contains i/o stmnts",(char *)0); + break; + case TIMEOUT: + /* never claim polls timeout */ + if (Ntimeouts && Etimeouts) + forbidden = 0; + Ntimeouts++; Etimeouts--; + break; + case LEN: case EMPTY: case FULL: + case 'R': case NFULL: case NEMPTY: + /* status becomes non-exclusive */ + if (n->sym && !(n->sym->xu&XX)) + { n->sym->xu |= XX; + if (separate == 2) { + printf("spin: warning, make sure that the S1 model\n"); + printf(" also polls channel '%s' in its claim\n", + n->sym->name); + } } + forbidden = 0; + break; + case 'c': + AST_track(n, 0); /* register as a slice criterion */ + /* fall thru */ + default: + forbidden = 0; + break; + } + if (forbidden) + { printf("spin: never, saw "); explain(t); printf("\n"); + fatal("incompatible with separate compilation",(char *)0); + } + } else if ((t == ENABLED || t == PC_VAL) && !(warn_nn&t)) + { printf("spin: Warning, using %s outside never claim\n", + (t == ENABLED)?"enabled()":"pc_value()"); + warn_nn |= t; + } else if (t == NONPROGRESS) + { fatal("spin: Error, using np_ outside never claim\n", (char *)0); + } + return n; } Lextok * -rem_lab(Symbol *a, Lextok *b, Symbol *c) /* proctype name, pid, label name */ -{ Lextok *tmp1, *tmp2, *tmp3; - - has_remote++; - c->type = LABEL; /* refered to in global context here */ - fix_dest(c, a); /* in case target of rem_lab is jump */ - tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a; - tmp1 = nn(ZN, 'p', tmp1, ZN); - tmp1->sym = lookup("_p"); - tmp2 = nn(ZN, NAME, ZN, ZN); tmp2->sym = a; - tmp3 = nn(ZN, 'q', tmp2, ZN); tmp3->sym = c; - return nn(ZN, EQ, tmp1, tmp3); +rem_lab(Symbol *a, Lextok *b, Symbol *c) /* proctype name, pid, label name */ +{ Lextok *tmp1, *tmp2, *tmp3; + + has_remote++; + c->type = LABEL; /* refered to in global context here */ + fix_dest(c, a); /* in case target of rem_lab is jump */ + tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a; + tmp1 = nn(ZN, 'p', tmp1, ZN); + tmp1->sym = lookup("_p"); + tmp2 = nn(ZN, NAME, ZN, ZN); tmp2->sym = a; + tmp3 = nn(ZN, 'q', tmp2, ZN); tmp3->sym = c; + return nn(ZN, EQ, tmp1, tmp3); #if 0 - .---------------EQ-------. - / \ - 'p' -sym-> _p 'q' -sym-> c (label name) - / / - '?' -sym-> a (proctype) NAME -sym-> a (proctype name) - / - b (pid expr) + .---------------EQ-------. + / \ + 'p' -sym-> _p 'q' -sym-> c (label name) + / / + '?' -sym-> a (proctype) NAME -sym-> a (proctype name) + / + b (pid expr) #endif } Lextok * rem_var(Symbol *a, Lextok *b, Symbol *c, Lextok *ndx) -{ Lextok *tmp1; - - has_remote++; - has_remvar++; - dataflow = 0; /* turn off dead variable resets 4.2.5 */ - merger = 0; /* turn off statement merging for locals 6.4.9 */ - tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a; - tmp1 = nn(ZN, 'p', tmp1, ndx); - tmp1->sym = c; - return tmp1; +{ Lextok *tmp1; + + has_remote++; + has_remvar++; + dataflow = 0; /* turn off dead variable resets 4.2.5 */ + merger = 0; /* turn off statement merging for locals 6.4.9 */ + tmp1 = nn(ZN, '?', b, ZN); tmp1->sym = a; + tmp1 = nn(ZN, 'p', tmp1, ndx); + tmp1->sym = c; + return tmp1; #if 0 - cannot refer to struct elements - only to scalars and arrays - - 'p' -sym-> c (variable name) - / \______ possible arrayindex on c - / - '?' -sym-> a (proctype) - / - b (pid expr) + cannot refer to struct elements + only to scalars and arrays + + 'p' -sym-> c (variable name) + / \______ possible arrayindex on c + / + '?' -sym-> a (proctype) + / + b (pid expr) #endif } void explain(int n) -{ FILE *fd = stdout; - switch (n) { - default: if (n > 0 && n < 256) - fprintf(fd, "'%c' = ", n); - fprintf(fd, "%d", n); - break; - case '\b': fprintf(fd, "\\b"); break; - case '\t': fprintf(fd, "\\t"); break; - case '\f': fprintf(fd, "\\f"); break; - case '\n': fprintf(fd, "\\n"); break; - case '\r': fprintf(fd, "\\r"); break; - case 'c': fprintf(fd, "condition"); break; - case 's': fprintf(fd, "send"); break; - case 'r': fprintf(fd, "recv"); break; - case 'R': fprintf(fd, "recv poll %s", Operator); break; - case '@': fprintf(fd, "@"); break; - case '?': fprintf(fd, "(x->y:z)"); break; +{ FILE *fd = stdout; + switch (n) { + default: if (n > 0 && n < 256) + fprintf(fd, "'%c' = ", n); + fprintf(fd, "%d", n); + break; + case '\b': fprintf(fd, "\\b"); break; + case '\t': fprintf(fd, "\\t"); break; + case '\f': fprintf(fd, "\\f"); break; + case '\n': fprintf(fd, "\\n"); break; + case '\r': fprintf(fd, "\\r"); break; + case 'c': fprintf(fd, "condition"); break; + case 's': fprintf(fd, "send"); break; + case 'r': fprintf(fd, "recv"); break; + case 'R': fprintf(fd, "recv poll %s", Operator); break; + case '@': fprintf(fd, "@"); break; + case '?': fprintf(fd, "(x->y:z)"); break; #if 1 - case NEXT: fprintf(fd, "X"); break; - case ALWAYS: fprintf(fd, "[]"); break; - case EVENTUALLY: fprintf(fd, "<>"); break; - case IMPLIES: fprintf(fd, "->"); break; - case EQUIV: fprintf(fd, "<->"); break; - case UNTIL: fprintf(fd, "U"); break; - case WEAK_UNTIL: fprintf(fd, "W"); break; - case IN: fprintf(fd, "%sin", Keyword); break; + case NEXT: fprintf(fd, "X"); break; + case ALWAYS: fprintf(fd, "[]"); break; + case EVENTUALLY: fprintf(fd, "<>"); break; + case IMPLIES: fprintf(fd, "->"); break; + case EQUIV: fprintf(fd, "<->"); break; + case UNTIL: fprintf(fd, "U"); break; + case WEAK_UNTIL: fprintf(fd, "W"); break; + case IN: fprintf(fd, "%sin", Keyword); break; #endif - case ACTIVE: fprintf(fd, "%sactive", Keyword); break; - case AND: fprintf(fd, "%s&&", Operator); break; - case ASGN: fprintf(fd, "%s=", Operator); break; - case ASSERT: fprintf(fd, "%sassert", Function); break; - case ATOMIC: fprintf(fd, "%satomic", Keyword); break; - case BREAK: fprintf(fd, "%sbreak", Keyword); break; - case C_CODE: fprintf(fd, "%sc_code", Keyword); break; - case C_DECL: fprintf(fd, "%sc_decl", Keyword); break; - case C_EXPR: fprintf(fd, "%sc_expr", Keyword); break; - case C_STATE: fprintf(fd, "%sc_state",Keyword); break; - case C_TRACK: fprintf(fd, "%sc_track",Keyword); break; - case CLAIM: fprintf(fd, "%snever", Keyword); break; - case CONST: fprintf(fd, "a constant"); break; - case DECR: fprintf(fd, "%s--", Operator); break; - case D_STEP: fprintf(fd, "%sd_step", Keyword); break; - case D_PROCTYPE: fprintf(fd, "%sd_proctype", Keyword); break; - case DO: fprintf(fd, "%sdo", Keyword); break; - case DOT: fprintf(fd, "."); break; - case ELSE: fprintf(fd, "%selse", Keyword); break; - case EMPTY: fprintf(fd, "%sempty", Function); break; - case ENABLED: fprintf(fd, "%senabled",Function); break; - case EQ: fprintf(fd, "%s==", Operator); break; - case EVAL: fprintf(fd, "%seval", Function); break; - case FI: fprintf(fd, "%sfi", Keyword); break; - case FULL: fprintf(fd, "%sfull", Function); break; - case GE: fprintf(fd, "%s>=", Operator); break; - case GET_P: fprintf(fd, "%sget_priority",Function); break; - case GOTO: fprintf(fd, "%sgoto", Keyword); break; - case GT: fprintf(fd, "%s>", Operator); break; - case HIDDEN: fprintf(fd, "%shidden", Keyword); break; - case IF: fprintf(fd, "%sif", Keyword); break; - case INCR: fprintf(fd, "%s++", Operator); break; - case INAME: fprintf(fd, "inline name"); break; - case INLINE: fprintf(fd, "%sinline", Keyword); break; - case INIT: fprintf(fd, "%sinit", Keyword); break; - case ISLOCAL: fprintf(fd, "%slocal", Keyword); break; - case LABEL: fprintf(fd, "a label-name"); break; - case LE: fprintf(fd, "%s<=", Operator); break; - case LEN: fprintf(fd, "%slen", Function); break; - case LSHIFT: fprintf(fd, "%s<<", Operator); break; - case LT: fprintf(fd, "%s<", Operator); break; - case MTYPE: fprintf(fd, "%smtype", Keyword); break; - case NAME: fprintf(fd, "an identifier"); break; - case NE: fprintf(fd, "%s!=", Operator); break; - case NEG: fprintf(fd, "%s! (not)",Operator); break; - case NEMPTY: fprintf(fd, "%snempty", Function); break; - case NFULL: fprintf(fd, "%snfull", Function); break; - case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; - case NONPROGRESS: fprintf(fd, "%snp_", Function); break; - case OD: fprintf(fd, "%sod", Keyword); break; - case OF: fprintf(fd, "%sof", Keyword); break; - case OR: fprintf(fd, "%s||", Operator); break; - case O_SND: fprintf(fd, "%s!!", Operator); break; - case PC_VAL: fprintf(fd, "%spc_value",Function); break; - case PNAME: fprintf(fd, "process name"); break; - case PRINT: fprintf(fd, "%sprintf", Function); break; - case PRINTM: fprintf(fd, "%sprintm", Function); break; - case PRIORITY: fprintf(fd, "%spriority", Keyword); break; - case PROCTYPE: fprintf(fd, "%sproctype",Keyword); break; - case PROVIDED: fprintf(fd, "%sprovided",Keyword); break; - case RCV: fprintf(fd, "%s?", Operator); break; - case R_RCV: fprintf(fd, "%s??", Operator); break; - case RSHIFT: fprintf(fd, "%s>>", Operator); break; - case RUN: fprintf(fd, "%srun", Operator); break; - case SEP: fprintf(fd, "token: ::"); break; - case SEMI: fprintf(fd, ";"); break; - case ARROW: fprintf(fd, "->"); break; - case SET_P: fprintf(fd, "%sset_priority",Function); break; - case SHOW: fprintf(fd, "%sshow", Keyword); break; - case SND: fprintf(fd, "%s!", Operator); break; - case STRING: fprintf(fd, "a string"); break; - case TRACE: fprintf(fd, "%strace", Keyword); break; - case TIMEOUT: fprintf(fd, "%stimeout",Keyword); break; - case TYPE: fprintf(fd, "data typename"); break; - case TYPEDEF: fprintf(fd, "%stypedef",Keyword); break; - case XU: fprintf(fd, "%sx[rs]", Keyword); break; - case UMIN: fprintf(fd, "%s- (unary minus)", Operator); break; - case UNAME: fprintf(fd, "a typename"); break; - case UNLESS: fprintf(fd, "%sunless", Keyword); break; - } + case ACTIVE: fprintf(fd, "%sactive", Keyword); break; + case AND: fprintf(fd, "%s&&", Operator); break; + case ASGN: fprintf(fd, "%s=", Operator); break; + case ASSERT: fprintf(fd, "%sassert", Function); break; + case ATOMIC: fprintf(fd, "%satomic", Keyword); break; + case BREAK: fprintf(fd, "%sbreak", Keyword); break; + case C_CODE: fprintf(fd, "%sc_code", Keyword); break; + case C_DECL: fprintf(fd, "%sc_decl", Keyword); break; + case C_EXPR: fprintf(fd, "%sc_expr", Keyword); break; + case C_STATE: fprintf(fd, "%sc_state",Keyword); break; + case C_TRACK: fprintf(fd, "%sc_track",Keyword); break; + case CLAIM: fprintf(fd, "%snever", Keyword); break; + case CONST: fprintf(fd, "a constant"); break; + case DECR: fprintf(fd, "%s--", Operator); break; + case D_STEP: fprintf(fd, "%sd_step", Keyword); break; + case D_PROCTYPE: fprintf(fd, "%sd_proctype", Keyword); break; + case DO: fprintf(fd, "%sdo", Keyword); break; + case DOT: fprintf(fd, "."); break; + case ELSE: fprintf(fd, "%selse", Keyword); break; + case EMPTY: fprintf(fd, "%sempty", Function); break; + case ENABLED: fprintf(fd, "%senabled",Function); break; + case EQ: fprintf(fd, "%s==", Operator); break; + case EVAL: fprintf(fd, "%seval", Function); break; + case FI: fprintf(fd, "%sfi", Keyword); break; + case FULL: fprintf(fd, "%sfull", Function); break; + case GE: fprintf(fd, "%s>=", Operator); break; + case GET_P: fprintf(fd, "%sget_priority",Function); break; + case GOTO: fprintf(fd, "%sgoto", Keyword); break; + case GT: fprintf(fd, "%s>", Operator); break; + case HIDDEN: fprintf(fd, "%shidden", Keyword); break; + case IF: fprintf(fd, "%sif", Keyword); break; + case INCR: fprintf(fd, "%s++", Operator); break; + case INAME: fprintf(fd, "inline name"); break; + case INLINE: fprintf(fd, "%sinline", Keyword); break; + case INIT: fprintf(fd, "%sinit", Keyword); break; + case ISLOCAL: fprintf(fd, "%slocal", Keyword); break; + case LABEL: fprintf(fd, "a label-name"); break; + case LE: fprintf(fd, "%s<=", Operator); break; + case LEN: fprintf(fd, "%slen", Function); break; + case LSHIFT: fprintf(fd, "%s<<", Operator); break; + case LT: fprintf(fd, "%s<", Operator); break; + case MTYPE: fprintf(fd, "%smtype", Keyword); break; + case NAME: fprintf(fd, "an identifier"); break; + case NE: fprintf(fd, "%s!=", Operator); break; + case NEG: fprintf(fd, "%s! (not)",Operator); break; + case NEMPTY: fprintf(fd, "%snempty", Function); break; + case NFULL: fprintf(fd, "%snfull", Function); break; + case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; + case NONPROGRESS: fprintf(fd, "%snp_", Function); break; + case OD: fprintf(fd, "%sod", Keyword); break; + case OF: fprintf(fd, "%sof", Keyword); break; + case OR: fprintf(fd, "%s||", Operator); break; + case O_SND: fprintf(fd, "%s!!", Operator); break; + case PC_VAL: fprintf(fd, "%spc_value",Function); break; + case PNAME: fprintf(fd, "process name"); break; + case PRINT: fprintf(fd, "%sprintf", Function); break; + case PRINTM: fprintf(fd, "%sprintm", Function); break; + case PRIORITY: fprintf(fd, "%spriority", Keyword); break; + case PROCTYPE: fprintf(fd, "%sproctype",Keyword); break; + case PROVIDED: fprintf(fd, "%sprovided",Keyword); break; + case RCV: fprintf(fd, "%s?", Operator); break; + case R_RCV: fprintf(fd, "%s??", Operator); break; + case RSHIFT: fprintf(fd, "%s>>", Operator); break; + case RUN: fprintf(fd, "%srun", Operator); break; + case SEP: fprintf(fd, "token: ::"); break; + case SEMI: fprintf(fd, ";"); break; + case ARROW: fprintf(fd, "->"); break; + case SET_P: fprintf(fd, "%sset_priority",Function); break; + case SHOW: fprintf(fd, "%sshow", Keyword); break; + case SND: fprintf(fd, "%s!", Operator); break; + case STRING: fprintf(fd, "a string"); break; + case TRACE: fprintf(fd, "%strace", Keyword); break; + case TIMEOUT: fprintf(fd, "%stimeout",Keyword); break; + case TYPE: fprintf(fd, "data typename"); break; + case TYPEDEF: fprintf(fd, "%stypedef",Keyword); break; + case XU: fprintf(fd, "%sx[rs]", Keyword); break; + case UMIN: fprintf(fd, "%s- (unary minus)", Operator); break; + case UNAME: fprintf(fd, "a typename"); break; + case UNLESS: fprintf(fd, "%sunless", Keyword); break; + } } diff --git a/Src/makefile b/Src/makefile index 64b33e5..bbd09b9 100644 --- a/Src/makefile +++ b/Src/makefile @@ -4,7 +4,9 @@ # terms in the LICENSE file that is included in this source directory. # Tool documentation is available at http://spinroot.com +CXX?=g++ CC?=gcc +# CC?=$(CXX) CFLAGS?=-O2 -DNXT -Wall -pedantic # on some systems add: -I/usr/include # on a PC: make CFLAGS="-O2 -DNXT -DPC" @@ -15,9 +17,23 @@ CFLAGS?=-O2 -DNXT -Wall -pedantic # or: make CC=clang CFLAGS="-fsanitize=address -g" # for a more picky compilation use gcc-4 and add: -PICKY=-std=c99 -Wstrict-prototypes -pedantic -fno-strength-reduce \ +PICKY=-std=c99 -Wstrict-prototypes \ + -pedantic -fno-strength-reduce \ -fno-builtin -W -Wshadow -Wpointer-arith \ - -Wcast-qual -Winline -Wall + -Wcast-qual -Winline -Wall \ + -Werror + +PICKYXX=-std=c++23 \ + -pedantic -fno-strength-reduce \ + -fno-builtin -W -Wshadow -Wpointer-arith \ + -Wcast-qual -Winline -Wall \ + -Werror + +ifeq ($(CC), $(CXX)) +CFLAGS+=$(PICKYXX) +else +CFLAGS+=$(PICKY) +endif # when running spin with a different compiler: # on OS2: spin -Picc -E/Pd+ -E/Q+ @@ -40,8 +56,8 @@ spin: makefile $(SPIN_OS) $(TL_OS) spin.o $(CC) $(CFLAGS) -o spin spin.o $(SPIN_OS) $(TL_OS) $(LDFLAGS) install: spin - $(INSTALL) spin $(DESTDIR)/bin/spin - $(INSTALL) ../Man/spin.1 $(DESTDIR)/share/man/man1/spin.1 + mkdir -p $(DESTDIR)/bin && $(INSTALL) spin $(DESTDIR)/bin/spin + mkdir -p $(DESTDIR)/share/man/man1 && $(INSTALL) ../Man/spin.1 $(DESTDIR)/share/man/man1/spin.1 spin.o: makefile spin.y $(YACC) $(YFLAGS) spin.y diff --git a/Src/mesg.c b/Src/mesg.c index 662f812..c75fa58 100644 --- a/Src/mesg.c +++ b/Src/mesg.c @@ -6,151 +6,151 @@ * Tool documentation is available at http://spinroot.com */ +#include "spin.h" /* include this first for strdup & getline */ #include #include -#include "spin.h" #include "y.tab.h" #ifndef MAXQ -#define MAXQ 2500 /* default max # queues */ +#define MAXQ 2500 /* default max # queues */ #endif -extern RunList *X_lst; -extern Symbol *Fname; -extern int verbose, TstOnly, s_trail, analyze, columns; -extern int lineno, depth, xspin, m_loss, jumpsteps; -extern int nproc, nstop; -extern short Have_claim; - -QH *qh_lst; -Queue *qtab = (Queue *) 0; /* linked list of queues */ -Queue *ltab[MAXQ]; /* linear list of queues */ -int nrqs = 0, firstrow = 1, has_stdin = 0; -char GBuf[4096]; - -static Lextok *n_rem = (Lextok *) 0; -static Queue *q_rem = (Queue *) 0; - -static int a_rcv(Queue *, Lextok *, int); -static int a_snd(Queue *, Lextok *); -static int sa_snd(Queue *, Lextok *); -static int s_snd(Queue *, Lextok *); -extern Lextok **find_mtype_list(const char *); -extern char *which_mtype(const char *); -extern void sr_buf(int, int, const char *); -extern void sr_mesg(FILE *, int, int, const char *); -extern void putarrow(int, int); -static void sr_talk(Lextok *, int, char *, char *, int, Queue *); +extern RunList *X_lst; +extern Symbol *Fname; +extern int verbose, TstOnly, s_trail, analyze, columns; +extern int lineno, depth, xspin, m_loss, jumpsteps; +extern int nproc, nstop; +extern short Have_claim; + +QH *qh_lst; +Queue *qtab = (Queue *) 0; /* linked list of queues */ +Queue *ltab[MAXQ]; /* linear list of queues */ +int nrqs = 0, firstrow = 1, has_stdin = 0; +char GBuf[4096]; + +static Lextok *n_rem = (Lextok *) 0; +static Queue *q_rem = (Queue *) 0; + +static int a_rcv(Queue *, Lextok *, int); +static int a_snd(Queue *, Lextok *); +static int sa_snd(Queue *, Lextok *); +static int s_snd(Queue *, Lextok *); +extern Lextok **find_mtype_list(const char *); +extern char *which_mtype(const char *); +extern void sr_buf(int, int, const char *); +extern void sr_mesg(FILE *, int, int, const char *); +extern void putarrow(int, int); +static void sr_talk(Lextok *, int, const char *, const char *, int, Queue *); int cnt_mpars(Lextok *n) -{ Lextok *m; - int i=0; +{ Lextok *m; + int i=0; - for (m = n; m; m = m->rgt) - i += Cnt_flds(m); - return i; + for (m = n; m; m = m->rgt) + i += Cnt_flds(m); + return i; } int qmake(Symbol *s) -{ Lextok *m; - Queue *q; - int i, j; - - if (!s->ini) - return 0; - - if (nrqs >= MAXQ) - { lineno = s->ini->ln; - Fname = s->ini->fn; - fatal("too many queues (%s)", s->name); - } - if (analyze && nrqs >= 255) - { fatal("too many channel types", (char *)0); - } - - if (s->ini->ntyp != CHAN) - return eval(s->ini); - - q = (Queue *) emalloc(sizeof(Queue)); - q->qid = (short) ++nrqs; - q->nslots = s->ini->val; - q->nflds = cnt_mpars(s->ini->rgt); - q->setat = depth; - - i = max(1, q->nslots); /* 0-slot qs get 1 slot minimum */ - j = q->nflds * i; - - q->contents = (int *) emalloc(j*sizeof(int)); - q->fld_width = (int *) emalloc(q->nflds*sizeof(int)); - q->mtp = (char **) emalloc(q->nflds*sizeof(char *)); - q->stepnr = (int *) emalloc(i*sizeof(int)); - - for (m = s->ini->rgt, i = 0; m; m = m->rgt) - { if (m->sym && m->ntyp == STRUCT) - { i = Width_set(q->fld_width, i, getuname(m->sym)); - } else - { if (m->sym) - { q->mtp[i] = m->sym->name; - } - q->fld_width[i++] = m->ntyp; - } } - q->nxt = qtab; - qtab = q; - ltab[q->qid-1] = q; - - return q->qid; +{ Lextok *m; + Queue *q; + int i, j; + + if (!s->ini) + return 0; + + if (nrqs >= MAXQ) + { lineno = s->ini->ln; + Fname = s->ini->fn; + fatal("too many queues (%s)", s->name); + } + if (analyze && nrqs >= 255) + { fatal("too many channel types", (char *)0); + } + + if (s->ini->ntyp != CHAN) + return eval(s->ini); + + q = (Queue *) emalloc(sizeof(Queue)); + q->qid = (short) ++nrqs; + q->nslots = s->ini->val; + q->nflds = cnt_mpars(s->ini->rgt); + q->setat = depth; + + i = MaX(1, q->nslots); /* 0-slot qs get 1 slot minimum */ + j = q->nflds * i; + + q->contents = (int *) emalloc(j*sizeof(int)); + q->fld_width = (int *) emalloc(q->nflds*sizeof(int)); + q->mtp = (char **) emalloc(q->nflds*sizeof(char *)); + q->stepnr = (int *) emalloc(i*sizeof(int)); + + for (m = s->ini->rgt, i = 0; m; m = m->rgt) + { if (m->sym && m->ntyp == STRUCT) + { i = Width_set(q->fld_width, i, getuname(m->sym)); + } else + { if (m->sym) + { q->mtp[i] = m->sym->name; + } + q->fld_width[i++] = m->ntyp; + } } + q->nxt = qtab; + qtab = q; + ltab[q->qid-1] = q; + + return q->qid; } int qfull(Lextok *n) -{ int whichq = eval(n->lft)-1; - - if (whichq < MAXQ - && whichq >= 0 // valid qid - && ltab[whichq] // q exists - && ltab[whichq]->nslots > 0) // !q_is_sync added 02/24 - { return (ltab[whichq]->qlen >= ltab[whichq]->nslots); - } - return 0; +{ int whichq = eval(n->lft)-1; + + if (whichq < MAXQ + && whichq >= 0 // valid qid + && ltab[whichq] // q exists + && ltab[whichq]->nslots > 0) // !q_is_sync added 02/24 + { return (ltab[whichq]->qlen >= ltab[whichq]->nslots); + } + return 0; } int qlen(Lextok *n) -{ int whichq = eval(n->lft)-1; +{ int whichq = eval(n->lft)-1; - if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) - return ltab[whichq]->qlen; - return 0; + if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) + return ltab[whichq]->qlen; + return 0; } int q_is_sync(Lextok *n) -{ int whichq = eval(n->lft)-1; +{ int whichq = eval(n->lft)-1; - if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) - return (ltab[whichq]->nslots == 0); - return 0; + if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) + return (ltab[whichq]->nslots == 0); + return 0; } int qsend(Lextok *n) -{ int whichq = eval(n->lft)-1; - - if (whichq == -1) - { printf("Error: sending to an uninitialized chan\n"); - /* whichq = 0; */ - return 0; - } - if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) - { ltab[whichq]->setat = depth; - if (ltab[whichq]->nslots > 0) - { return a_snd(ltab[whichq], n);; - } else - { return s_snd(ltab[whichq], n); - } } - return 0; +{ int whichq = eval(n->lft)-1; + + if (whichq == -1) + { printf("Error: sending to an uninitialized chan\n"); + /* whichq = 0; */ + return 0; + } + if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) + { ltab[whichq]->setat = depth; + if (ltab[whichq]->nslots > 0) + { return a_snd(ltab[whichq], n);; + } else + { return s_snd(ltab[whichq], n); + } } + return 0; } #ifndef PC @@ -160,831 +160,831 @@ qsend(Lextok *n) void peek_ch_init(void) { - tcgetattr(0,&initial_settings); - - new_settings = initial_settings; - new_settings.c_lflag &= ~ICANON; - new_settings.c_lflag &= ~ECHO; - new_settings.c_lflag &= ~ISIG; - new_settings.c_cc[VMIN] = 0; - new_settings.c_cc[VTIME] = 0; + tcgetattr(0,&initial_settings); + + new_settings = initial_settings; + new_settings.c_lflag &= ~ICANON; + new_settings.c_lflag &= ~ECHO; + new_settings.c_lflag &= ~ISIG; + new_settings.c_cc[VMIN] = 0; + new_settings.c_cc[VTIME] = 0; } int peek_ch(void) - { int n; + { int n; - has_stdin = 1; + has_stdin = 1; - tcsetattr(0, TCSANOW, &new_settings); - n = getchar(); - tcsetattr(0, TCSANOW, &initial_settings); + tcsetattr(0, TCSANOW, &new_settings); + n = getchar(); + tcsetattr(0, TCSANOW, &initial_settings); - return n; + return n; } #endif int qrecv(Lextok *n, int full) -{ int whichq = eval(n->lft)-1; +{ int whichq = eval(n->lft)-1; - if (whichq == -1) - { if (n->sym && !strcmp(n->sym->name, "STDIN")) - { Lextok *m; + if (whichq == -1) + { if (n->sym && !strcmp(n->sym->name, "STDIN")) + { Lextok *m; #ifndef PC - static int did_once = 0; - if (!did_once) /* 6.2.4 */ - { peek_ch_init(); - did_once = 1; - } + static int did_once = 0; + if (!did_once) /* 6.2.4 */ + { peek_ch_init(); + did_once = 1; + } #endif - if (TstOnly) return 1; + if (TstOnly) return 1; - for (m = n->rgt; m; m = m->rgt) - if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL) - { + for (m = n->rgt; m; m = m->rgt) + if (m->lft->ntyp != CONST && m->lft->ntyp != EVAL) + { #ifdef PC - int c = getchar(); + int c = getchar(); #else - int c = peek_ch(); /* 6.2.4, was getchar(); */ + int c = peek_ch(); /* 6.2.4, was getchar(); */ #endif - if (c == 27 || c == 3) /* escape or control-c */ - { printf("quit\n"); - exit(0); - } /* else: non-blocking */ - if (c == EOF) return 0; /* no char available */ - (void) setval(m->lft, c); - } else - { fatal("invalid use of STDIN", (char *)0); - } - return 1; - } - printf("Error: receiving from an uninitialized chan %s\n", - n->sym?n->sym->name:""); - /* whichq = 0; */ - return 0; - } - if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) - { ltab[whichq]->setat = depth; - return a_rcv(ltab[whichq], n, full); - } - return 0; + if (c == 27 || c == 3) /* escape or control-c */ + { printf("quit\n"); + exit(0); + } /* else: non-blocking */ + if (c == EOF) return 0; /* no char available */ + (void) setval(m->lft, c); + } else + { fatal("invalid use of STDIN", (char *)0); + } + return 1; + } + printf("Error: receiving from an uninitialized chan %s\n", + n->sym?n->sym->name:""); + /* whichq = 0; */ + return 0; + } + if (whichq < MAXQ && whichq >= 0 && ltab[whichq]) + { ltab[whichq]->setat = depth; + return a_rcv(ltab[whichq], n, full); + } + return 0; } static int -sa_snd(Queue *q, Lextok *n) /* sorted asynchronous */ -{ Lextok *m; - int i, j, k; - int New, Old; - - for (i = 0; i < q->qlen; i++) - for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++) - { New = cast_val(q->fld_width[j], eval(m->lft), 0); - Old = q->contents[i*q->nflds+j]; - if (New == Old) - continue; - if (New > Old) - break; /* inner loop */ - goto found; /* New < Old */ - } +sa_snd(Queue *q, Lextok *n) /* sorted asynchronous */ +{ Lextok *m; + int i, j, k; + int New, Old; + + for (i = 0; i < q->qlen; i++) + for (j = 0, m = n->rgt; m && j < q->nflds; m = m->rgt, j++) + { New = cast_val(q->fld_width[j], eval(m->lft), 0); + Old = q->contents[i*q->nflds+j]; + if (New == Old) + continue; + if (New > Old) + break; /* inner loop */ + goto found; /* New < Old */ + } found: - for (j = q->qlen-1; j >= i; j--) - for (k = 0; k < q->nflds; k++) - { q->contents[(j+1)*q->nflds+k] = - q->contents[j*q->nflds+k]; /* shift up */ - if (k == 0) - q->stepnr[j+1] = q->stepnr[j]; - } - return i*q->nflds; /* new q offset */ + for (j = q->qlen-1; j >= i; j--) + for (k = 0; k < q->nflds; k++) + { q->contents[(j+1)*q->nflds+k] = + q->contents[j*q->nflds+k]; /* shift up */ + if (k == 0) + q->stepnr[j+1] = q->stepnr[j]; + } + return i*q->nflds; /* new q offset */ } void -typ_ck(int ft, int at, char *s) +typ_ck(int ft, int at, const char *s) { - if ((verbose&32) && ft != at - && (ft == CHAN || at == CHAN) - && (at != PREDEF || strcmp(s, "recv") != 0)) - { char buf[256], tag1[64], tag2[64]; - (void) sputtype(tag1, ft); - (void) sputtype(tag2, at); - sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2); - non_fatal("%s", buf); - } + if ((verbose&32) && ft != at + && (ft == CHAN || at == CHAN) + && (at != PREDEF || strcmp(s, "recv") != 0)) + { char buf[256], tag1[64], tag2[64]; + (void) sputtype(tag1, ft); + (void) sputtype(tag2, at); + sprintf(buf, "type-clash in %s, (%s<-> %s)", s, tag1, tag2); + non_fatal("%s", buf); + } } static void mtype_ck(char *p, Lextok *arg) -{ char *t, *s = p?p:"_unnamed_"; - - if (!arg - || !arg->sym) - { return; - } - - switch (arg->ntyp) { - case NAME: - if (arg->sym->mtype_name) - { t = arg->sym->mtype_name->name; - } else - { t = "_unnamed_"; - } - break; - case CONST: - t = which_mtype(arg->sym->name); - break; - default: - t = "expression"; - break; - } - - if (strcmp(s, t) != 0) - { printf("spin: %s:%d, Error: '%s' is type '%s', but ", - arg->fn?arg->fn->name:"", arg->ln, - arg->sym->name, t); - printf("should be type '%s'\n", s); - non_fatal("incorrect type of '%s'", arg->sym->name); - } +{ const char *t, *s = p?p:"_unnamed_"; + + if (!arg + || !arg->sym) + { return; + } + + switch (arg->ntyp) { + case NAME: + if (arg->sym->mtype_name) + { t = arg->sym->mtype_name->name; + } else + { t = "_unnamed_"; + } + break; + case CONST: + t = which_mtype(arg->sym->name); + break; + default: + t = "expression"; + break; + } + + if (strcmp(s, t) != 0) + { printf("spin: %s:%d, Error: '%s' is type '%s', but ", + arg->fn?arg->fn->name:"", arg->ln, + arg->sym->name, t); + printf("should be type '%s'\n", s); + non_fatal("incorrect type of '%s'", arg->sym->name); + } } static int a_snd(Queue *q, Lextok *n) -{ Lextok *m; - int i = q->qlen*q->nflds; /* q offset */ - int j = 0; /* q field# */ - - if (q->nslots > 0 && q->qlen >= q->nslots) - { return m_loss; /* q is full */ - } - - if (TstOnly) - { return 1; - } - if (n->val) i = sa_snd(q, n); /* sorted insert */ - - q->stepnr[i/q->nflds] = depth; - - for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) - { int New = eval(m->lft); - q->contents[i+j] = cast_val(q->fld_width[j], New, 0); - - if (q->fld_width[j] == MTYPE) /* may 30, 2023: i+j -> j */ - { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 - may 30: same change */ - } - if ((verbose&16) && depth >= jumpsteps) - { sr_talk(n, New, "Send ", "->", j, q); /* XXX j was i+j in 6.4.8 */ - } - - /* may 30, 2023: the field types are 0..nflds, not i+0..nflds */ - typ_ck(q->fld_width[j], Sym_typ(m->lft), "send"); - } - - if ((verbose&16) && depth >= jumpsteps) - { for (i = j; i < q->nflds; i++) - { sr_talk(n, 0, "Send ", "->", i, q); - } - if (j < q->nflds) - { printf("%3d: warning: missing params in send\n", - depth); - } - if (m) - { printf("%3d: warning: too many params in send\n", - depth); - } } - q->qlen++; - return 1; +{ Lextok *m; + int i = q->qlen*q->nflds; /* q offset */ + int j = 0; /* q field# */ + + if (q->nslots > 0 && q->qlen >= q->nslots) + { return m_loss; /* q is full */ + } + + if (TstOnly) + { return 1; + } + if (n->val) i = sa_snd(q, n); /* sorted insert */ + + q->stepnr[i/q->nflds] = depth; + + for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) + { int New = eval(m->lft); + q->contents[i+j] = cast_val(q->fld_width[j], New, 0); + + if (q->fld_width[j] == MTYPE) /* may 30, 2023: i+j -> j */ + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 - may 30: same change */ + } + if ((verbose&16) && depth >= jumpsteps) + { sr_talk(n, New, "Send ", "->", j, q); /* XXX j was i+j in 6.4.8 */ + } + + /* may 30, 2023: the field types are 0..nflds, not i+0..nflds */ + typ_ck(q->fld_width[j], Sym_typ(m->lft), "send"); + } + + if ((verbose&16) && depth >= jumpsteps) + { for (i = j; i < q->nflds; i++) + { sr_talk(n, 0, "Send ", "->", i, q); + } + if (j < q->nflds) + { printf("%3d: warning: missing params in send\n", + depth); + } + if (m) + { printf("%3d: warning: too many params in send\n", + depth); + } } + q->qlen++; + return 1; } static int a_rcv(Queue *q, Lextok *n, int full) -{ Lextok *m; - int i=0, oi, j, k; - extern int Rvous; +{ Lextok *m; + int i=0, oi, j, k; + extern int Rvous; - if (q->qlen == 0) - { return 0; /* q is empty */ - } + if (q->qlen == 0) + { return 0; /* q is empty */ + } try_slot: - /* test executability */ - for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++) - { - if (q->fld_width[j] == MTYPE) /* may 30, 2023: i*q->nflds+j -> j */ - { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 -- may 30, same change */ - } - - if (m->lft->ntyp == CONST - && q->contents[i*q->nflds+j] != m->lft->val) - { - if (n->val == 0 /* fifo recv */ - || n->val == 2 /* fifo poll */ - || ++i >= q->qlen) /* last slot */ - { return 0; /* no match */ - } - goto try_slot; /* random recv */ - } - - if (m->lft->ntyp == EVAL) - { Lextok *fix = m->lft->lft; - - if (fix->ntyp == ',') /* new, usertype7 */ - { do { - assert(j < q->nflds); - if (q->contents[i*q->nflds+j] != eval(fix->lft)) - { if (n->val == 0 - || n->val == 2 - || ++i >= q->qlen) - { return 0; - } - goto try_slot; /* random recv */ - } - j++; - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - j--; - } else - { if (q->contents[i*q->nflds+j] != eval(fix)) - { if (n->val == 0 /* fifo recv */ - || n->val == 2 /* fifo poll */ - || ++i >= q->qlen) /* last slot */ - { return 0; /* no match */ - } - goto try_slot; /* random recv */ - } } } - } - - if (TstOnly) return 1; - - if (verbose&8) - { if (j < q->nflds) - { printf("%3d: warning: missing params in next recv\n", - depth); - } else if (m) - { printf("%3d: warning: too many params in next recv\n", - depth); - } } - - /* set the fields */ - if (Rvous) - { n_rem = n; - q_rem = q; - } - - oi = q->stepnr[i]; - for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++) - { if (columns && !full) /* was columns == 1 */ - continue; - if ((verbose&8) && !Rvous && depth >= jumpsteps) - { sr_talk(n, q->contents[i*q->nflds+j], - (full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q); - } - if (!full) - continue; /* test */ - if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL) - { (void) setval(m->lft, q->contents[i*q->nflds+j]); - typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv"); - } - if (n->val < 2) /* not a poll */ - for (k = i; k < q->qlen-1; k++) - { q->contents[k*q->nflds+j] = - q->contents[(k+1)*q->nflds+j]; - if (j == 0) - q->stepnr[k] = q->stepnr[k+1]; - } - } - - if ((!columns || full) - && (verbose&8) && !Rvous && depth >= jumpsteps) - for (i = j; i < q->nflds; i++) - { sr_talk(n, 0, - (full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q); - } - if (columns == 2 && full && !Rvous && depth >= jumpsteps) - putarrow(oi, depth); - - if (full && n->val < 2) - q->qlen--; - return 1; + /* test executability */ + for (m = n->rgt, j=0; m && j < q->nflds; m = m->rgt, j++) + { + if (q->fld_width[j] == MTYPE) /* may 30, 2023: i*q->nflds+j -> j */ + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 -- may 30, same change */ + } + + if (m->lft->ntyp == CONST + && q->contents[i*q->nflds+j] != m->lft->val) + { + if (n->val == 0 /* fifo recv */ + || n->val == 2 /* fifo poll */ + || ++i >= q->qlen) /* last slot */ + { return 0; /* no match */ + } + goto try_slot; /* random recv */ + } + + if (m->lft->ntyp == EVAL) + { Lextok *fix = m->lft->lft; + + if (fix->ntyp == ',') /* new, usertype7 */ + { do { + assert(j < q->nflds); + if (q->contents[i*q->nflds+j] != eval(fix->lft)) + { if (n->val == 0 + || n->val == 2 + || ++i >= q->qlen) + { return 0; + } + goto try_slot; /* random recv */ + } + j++; + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + j--; + } else + { if (q->contents[i*q->nflds+j] != eval(fix)) + { if (n->val == 0 /* fifo recv */ + || n->val == 2 /* fifo poll */ + || ++i >= q->qlen) /* last slot */ + { return 0; /* no match */ + } + goto try_slot; /* random recv */ + } } } + } + + if (TstOnly) return 1; + + if (verbose&8) + { if (j < q->nflds) + { printf("%3d: warning: missing params in next recv\n", + depth); + } else if (m) + { printf("%3d: warning: too many params in next recv\n", + depth); + } } + + /* set the fields */ + if (Rvous) + { n_rem = n; + q_rem = q; + } + + oi = q->stepnr[i]; + for (m = n->rgt, j = 0; m && j < q->nflds; m = m->rgt, j++) + { if (columns && !full) /* was columns == 1 */ + continue; + if ((verbose&8) && !Rvous && depth >= jumpsteps) + { sr_talk(n, q->contents[i*q->nflds+j], + (full && n->val < 2)?"Recv ":"[Recv] ", "<-", j, q); + } + if (!full) + continue; /* test */ + if (m && m->lft->ntyp != CONST && m->lft->ntyp != EVAL) + { (void) setval(m->lft, q->contents[i*q->nflds+j]); + typ_ck(q->fld_width[j], Sym_typ(m->lft), "recv"); + } + if (n->val < 2) /* not a poll */ + for (k = i; k < q->qlen-1; k++) + { q->contents[k*q->nflds+j] = + q->contents[(k+1)*q->nflds+j]; + if (j == 0) + q->stepnr[k] = q->stepnr[k+1]; + } + } + + if ((!columns || full) + && (verbose&8) && !Rvous && depth >= jumpsteps) + for (i = j; i < q->nflds; i++) + { sr_talk(n, 0, + (full && n->val < 2)?"Recv ":"[Recv] ", "<-", i, q); + } + if (columns == 2 && full && !Rvous && depth >= jumpsteps) + putarrow(oi, depth); + + if (full && n->val < 2) + q->qlen--; + return 1; } static int s_snd(Queue *q, Lextok *n) -{ Lextok *m; - RunList *rX, *sX = X_lst; /* rX=recvr, sX=sendr */ - int i, j = 0; /* q field# */ - - for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) - { q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0); - typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send"); - - if (q->fld_width[j] == MTYPE) - { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ - } } - - q->qlen = 1; - if (!complete_rendez()) - { q->qlen = 0; - return 0; - } - if (TstOnly) - { q->qlen = 0; - return 1; - } - q->stepnr[0] = depth; - if ((verbose&16) && depth >= jumpsteps) - { m = n->rgt; - rX = X_lst; X_lst = sX; - - for (j = 0; m && j < q->nflds; m = m->rgt, j++) - { sr_talk(n, eval(m->lft), "Sent ", "->", j, q); - } - - for (i = j; i < q->nflds; i++) - { sr_talk(n, 0, "Sent ", "->", i, q); - } - - if (j < q->nflds) - { printf("%3d: warning: missing params in rv-send\n", - depth); - } else if (m) - { printf("%3d: warning: too many params in rv-send\n", - depth); - } - - X_lst = rX; /* restore receiver's context */ - if (!s_trail) - { if (!n_rem || !q_rem) - fatal("cannot happen, s_snd", (char *) 0); - m = n_rem->rgt; - for (j = 0; m && j < q->nflds; m = m->rgt, j++) - { - if (q->fld_width[j] == MTYPE) - { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ - } - - if (m->lft->ntyp != NAME - || strcmp(m->lft->sym->name, "_") != 0) - { i = eval(m->lft); - } else - { i = 0; - } - if (verbose&8) - sr_talk(n_rem,i,"Recv ","<-",j,q_rem); - } - if (verbose&8) - for (i = j; i < q->nflds; i++) - sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem); - if (columns == 2) - putarrow(depth, depth); - } - n_rem = (Lextok *) 0; - q_rem = (Queue *) 0; - } - return 1; +{ Lextok *m; + RunList *rX, *sX = X_lst; /* rX=recvr, sX=sendr */ + int i, j = 0; /* q field# */ + + for (m = n->rgt; m && j < q->nflds; m = m->rgt, j++) + { q->contents[j] = cast_val(q->fld_width[j], eval(m->lft), 0); + typ_ck(q->fld_width[j], Sym_typ(m->lft), "rv-send"); + + if (q->fld_width[j] == MTYPE) + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ + } } + + q->qlen = 1; + if (!complete_rendez()) + { q->qlen = 0; + return 0; + } + if (TstOnly) + { q->qlen = 0; + return 1; + } + q->stepnr[0] = depth; + if ((verbose&16) && depth >= jumpsteps) + { m = n->rgt; + rX = X_lst; X_lst = sX; + + for (j = 0; m && j < q->nflds; m = m->rgt, j++) + { sr_talk(n, eval(m->lft), "Sent ", "->", j, q); + } + + for (i = j; i < q->nflds; i++) + { sr_talk(n, 0, "Sent ", "->", i, q); + } + + if (j < q->nflds) + { printf("%3d: warning: missing params in rv-send\n", + depth); + } else if (m) + { printf("%3d: warning: too many params in rv-send\n", + depth); + } + + X_lst = rX; /* restore receiver's context */ + if (!s_trail) + { if (!n_rem || !q_rem) + fatal("cannot happen, s_snd", (char *) 0); + m = n_rem->rgt; + for (j = 0; m && j < q->nflds; m = m->rgt, j++) + { + if (q->fld_width[j] == MTYPE) + { mtype_ck(q->mtp[j], m->lft); /* 6.4.8 */ + } + + if (m->lft->ntyp != NAME + || strcmp(m->lft->sym->name, "_") != 0) + { i = eval(m->lft); + } else + { i = 0; + } + if (verbose&8) + sr_talk(n_rem,i,"Recv ","<-",j,q_rem); + } + if (verbose&8) + for (i = j; i < q->nflds; i++) + sr_talk(n_rem, 0, "Recv ", "<-", j, q_rem); + if (columns == 2) + putarrow(depth, depth); + } + n_rem = (Lextok *) 0; + q_rem = (Queue *) 0; + } + return 1; } static void channm(Lextok *n) -{ char lbuf[512]; - - if (n->sym->type == CHAN) - strcat(GBuf, n->sym->name); - else if (n->sym->type == NAME) - strcat(GBuf, lookup(n->sym->name)->name); - else if (n->sym->type == STRUCT) - { Symbol *r = n->sym; - if (r->context) - { r = findloc(r); - if (!r) - { strcat(GBuf, "*?*"); - return; - } } - ini_struct(r); - printf("%s", r->name); - strcpy(lbuf, ""); - struct_name(n->lft, r, 1, lbuf); - strcat(GBuf, lbuf); - } else - strcat(GBuf, "-"); - if (n->lft->lft) - { sprintf(lbuf, "[%d]", eval(n->lft->lft)); - strcat(GBuf, lbuf); - } +{ char lbuf[512]; + + if (n->sym->type == CHAN) + strcat(GBuf, n->sym->name); + else if (n->sym->type == NAME) + strcat(GBuf, lookup(n->sym->name)->name); + else if (n->sym->type == STRUCT) + { Symbol *r = n->sym; + if (r->context) + { r = findloc(r); + if (!r) + { strcat(GBuf, "*?*"); + return; + } } + ini_struct(r); + printf("%s", r->name); + strcpy(lbuf, ""); + struct_name(n->lft, r, 1, lbuf); + strcat(GBuf, lbuf); + } else + strcat(GBuf, "-"); + if (n->lft->lft) + { sprintf(lbuf, "[%d]", eval(n->lft->lft)); + strcat(GBuf, lbuf); + } } static void -difcolumns(Lextok *n, char *tr, int v, int j, Queue *q) -{ extern int prno; - - if (j == 0) - { GBuf[0] = '\0'; - channm(n); - strcat(GBuf, (strncmp(tr, "Sen", 3))?"?":"!"); - } else - strcat(GBuf, ","); - if (tr[0] == '[') strcat(GBuf, "["); - sr_buf(v, q->fld_width[j] == MTYPE, q->mtp[j]); - if (j == q->nflds - 1) - { int cnr; - if (s_trail) - { cnr = prno - Have_claim; - } else - { cnr = X_lst?X_lst->pid - Have_claim:0; - } - if (tr[0] == '[') strcat(GBuf, "]"); - pstext(cnr, GBuf); - } +difcolumns(Lextok *n, const char *tr, int v, int j, Queue *q) +{ extern int prno; + + if (j == 0) + { GBuf[0] = '\0'; + channm(n); + strcat(GBuf, (strncmp(tr, "Sen", 3))?"?":"!"); + } else + strcat(GBuf, ","); + if (tr[0] == '[') strcat(GBuf, "["); + sr_buf(v, q->fld_width[j] == MTYPE, q->mtp[j]); + if (j == q->nflds - 1) + { int cnr; + if (s_trail) + { cnr = prno - Have_claim; + } else + { cnr = X_lst?X_lst->pid - Have_claim:0; + } + if (tr[0] == '[') strcat(GBuf, "]"); + pstext(cnr, GBuf); + } } static void -docolumns(Lextok *n, char *tr, int v, int j, Queue *q) -{ int i; - - if (firstrow) - { printf("q\\p"); - for (i = 0; i < nproc-nstop - Have_claim; i++) - printf(" %3d", i); - printf("\n"); - firstrow = 0; - } - if (j == 0) - { printf("%3d", q->qid); - if (X_lst) - for (i = 0; i < X_lst->pid - Have_claim; i++) - printf(" ."); - printf(" "); - GBuf[0] = '\0'; - channm(n); - printf("%s%c", GBuf, (strncmp(tr, "Sen", 3))?'?':'!'); - } else - printf(","); - if (tr[0] == '[') printf("["); - sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); - if (j == q->nflds - 1) - { if (tr[0] == '[') printf("]"); - printf("\n"); - } +docolumns(Lextok *n, const char *tr, int v, int j, Queue *q) +{ int i; + + if (firstrow) + { printf("q\\p"); + for (i = 0; i < nproc-nstop - Have_claim; i++) + printf(" %3d", i); + printf("\n"); + firstrow = 0; + } + if (j == 0) + { printf("%3d", q->qid); + if (X_lst) + for (i = 0; i < X_lst->pid - Have_claim; i++) + printf(" ."); + printf(" "); + GBuf[0] = '\0'; + channm(n); + printf("%s%c", GBuf, (strncmp(tr, "Sen", 3))?'?':'!'); + } else + printf(","); + if (tr[0] == '[') printf("["); + sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); + if (j == q->nflds - 1) + { if (tr[0] == '[') printf("]"); + printf("\n"); + } } void qhide(int q) -{ QH *p = (QH *) emalloc(sizeof(QH)); - p->n = q; - p->nxt = qh_lst; - qh_lst = p; +{ QH *p = (QH *) emalloc(sizeof(QH)); + p->n = q; + p->nxt = qh_lst; + qh_lst = p; } int qishidden(int q) -{ QH *p; - for (p = qh_lst; p; p = p->nxt) - if (p->n == q) - return 1; - return 0; +{ QH *p; + for (p = qh_lst; p; p = p->nxt) + if (p->n == q) + return 1; + return 0; } static void -sr_talk(Lextok *n, int v, char *tr, char *a, int j, Queue *q) -{ char s[128]; - - if (qishidden(eval(n->lft))) - return; - - if (columns) - { if (columns == 2) - difcolumns(n, tr, v, j, q); - else - docolumns(n, tr, v, j, q); - return; - } - if (xspin) - { if ((verbose&4) && tr[0] != '[') - sprintf(s, "(state -)\t[values: %d", - eval(n->lft)); - else - sprintf(s, "(state -)\t[%d", eval(n->lft)); - if (strncmp(tr, "Sen", 3) == 0) - strcat(s, "!"); - else - strcat(s, "?"); - } else - { strcpy(s, tr); - } - - if (j == 0) - { char snm[128]; - whoruns(1); - { char *ptr = n->fn->name; - char *qtr = snm; - while (*ptr != '\0') - { if (*ptr != '\"') - { *qtr++ = *ptr; - } - ptr++; - } - *qtr = '\0'; - printf("%s:%d %s", - snm, n->ln, s); - } - } else - { printf(","); - } - sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); - - if (j == q->nflds - 1) - { if (xspin) - { printf("]\n"); - if (!(verbose&4)) printf("\n"); - return; - } - printf("\t%s queue %d (", a, eval(n->lft)); - GBuf[0] = '\0'; - channm(n); - printf("%s)\n", GBuf); - } - fflush(stdout); +sr_talk(Lextok *n, int v, const char *tr, const char *a, int j, Queue *q) +{ char s[128]; + + if (qishidden(eval(n->lft))) + return; + + if (columns) + { if (columns == 2) + difcolumns(n, tr, v, j, q); + else + docolumns(n, tr, v, j, q); + return; + } + if (xspin) + { if ((verbose&4) && tr[0] != '[') + sprintf(s, "(state -)\t[values: %d", + eval(n->lft)); + else + sprintf(s, "(state -)\t[%d", eval(n->lft)); + if (strncmp(tr, "Sen", 3) == 0) + strcat(s, "!"); + else + strcat(s, "?"); + } else + { strcpy(s, tr); + } + + if (j == 0) + { char snm[128]; + whoruns(1); + { char *ptr = n->fn->name; + char *qtr = snm; + while (*ptr != '\0') + { if (*ptr != '\"') + { *qtr++ = *ptr; + } + ptr++; + } + *qtr = '\0'; + printf("%s:%d %s", + snm, n->ln, s); + } + } else + { printf(","); + } + sr_mesg(stdout, v, q->fld_width[j] == MTYPE, q->mtp[j]); + + if (j == q->nflds - 1) + { if (xspin) + { printf("]\n"); + if (!(verbose&4)) printf("\n"); + return; + } + printf("\t%s queue %d (", a, eval(n->lft)); + GBuf[0] = '\0'; + channm(n); + printf("%s)\n", GBuf); + } + fflush(stdout); } void sr_buf(int v, int j, const char *s) -{ int cnt = 1; Lextok *n; - char lbuf[512]; - Lextok *Mtype = ZN; - - if (j) - { Mtype = *find_mtype_list(s?s:"_unnamed_"); - } - for (n = Mtype; n && j; n = n->rgt, cnt++) - { if (cnt == v) - { if(strlen(n->lft->sym->name) >= sizeof(lbuf)) - { non_fatal("mtype name %s too long", n->lft->sym->name); - break; - } - sprintf(lbuf, "%s", n->lft->sym->name); - strcat(GBuf, lbuf); - return; - } } - sprintf(lbuf, "%d", v); - strcat(GBuf, lbuf); +{ int cnt = 1; Lextok *n; + char lbuf[512]; + Lextok *Mtype = ZN; + + if (j) + { Mtype = *find_mtype_list(s?s:"_unnamed_"); + } + for (n = Mtype; n && j; n = n->rgt, cnt++) + { if (cnt == v) + { if(strlen(n->lft->sym->name) >= sizeof(lbuf)) + { non_fatal("mtype name %s too long", n->lft->sym->name); + break; + } + sprintf(lbuf, "%s", n->lft->sym->name); + strcat(GBuf, lbuf); + return; + } } + sprintf(lbuf, "%d", v); + strcat(GBuf, lbuf); } void sr_mesg(FILE *fd, int v, int j, const char *s) -{ GBuf[0] ='\0'; +{ GBuf[0] ='\0'; - sr_buf(v, j, s); - fprintf(fd, GBuf, (char *) 0); /* prevent compiler warning */ + sr_buf(v, j, s); + fprintf(fd, GBuf, (char *) 0); /* prevent compiler warning */ } void doq(Symbol *s, int n, RunList *r) -{ Queue *q; - int j, k; - - if (!s->val) /* uninitialized queue */ - return; - for (q = qtab; q; q = q->nxt) - if (q->qid == s->val[n]) - { if (xspin > 0 - && (verbose&4) - && q->setat < depth) - { continue; - } - if (q->nslots == 0) - { continue; /* rv q always empty */ - } - - printf("\t\tqueue %d (", q->qid); - if (r) - { printf("%s(%d):", r->n->name, r->pid - Have_claim); - } - - if (s->nel > 1 || s->isarray) - { printf("%s[%d]): ", s->name, n); - } else - { printf("%s): ", s->name); - } - - for (k = 0; k < q->qlen; k++) - { printf("["); - for (j = 0; j < q->nflds; j++) - { if (j > 0) printf(","); - sr_mesg(stdout, - q->contents[k*q->nflds+j], - q->fld_width[j] == MTYPE, - q->mtp[j]); - } - printf("]"); - } - printf("\n"); - break; - } +{ Queue *q; + int j, k; + + if (!s->val) /* uninitialized queue */ + return; + for (q = qtab; q; q = q->nxt) + if (q->qid == s->val[n]) + { if (xspin > 0 + && (verbose&4) + && q->setat < depth) + { continue; + } + if (q->nslots == 0) + { continue; /* rv q always empty */ + } + + printf("\t\tqueue %d (", q->qid); + if (r) + { printf("%s(%d):", r->n->name, r->pid - Have_claim); + } + + if (s->nel > 1 || s->isarray) + { printf("%s[%d]): ", s->name, n); + } else + { printf("%s): ", s->name); + } + + for (k = 0; k < q->qlen; k++) + { printf("["); + for (j = 0; j < q->nflds; j++) + { if (j > 0) printf(","); + sr_mesg(stdout, + q->contents[k*q->nflds+j], + q->fld_width[j] == MTYPE, + q->mtp[j]); + } + printf("]"); + } + printf("\n"); + break; + } } void -nochan_manip(Lextok *p, Lextok *n, int d) /* p=lhs n=rhs */ -{ int e = 1; - - if (!n - || !p - || !p->sym - || p->sym->type == STRUCT) - { /* if a struct, assignments to structure fields arent checked yet */ - return; - } - - if (d == 0 && p->sym && p->sym->type == CHAN) - { setaccess(p->sym, ZS, 0, 'L'); - - if (n && n->ntyp == CONST) - fatal("invalid asgn to chan", (char *) 0); - - if (n && n->sym && n->sym->type == CHAN) - { setaccess(n->sym, ZS, 0, 'V'); - return; - } - } - - if (!d && n && n->ismtyp) /* rhs is an mtype value (a constant) */ - { char *lhs = "_unnamed_", *rhs = "_unnamed_"; - - if (p->sym) - { lhs = p->sym->mtype_name?p->sym->mtype_name->name:"_unnamed_"; - } - if (n->sym) - { rhs = which_mtype(n->sym->name); /* only for constants */ - } - - if (p->sym && !p->sym->mtype_name && n->sym) - { p->sym->mtype_name = (Symbol *) emalloc(sizeof(Symbol)); - p->sym->mtype_name->name = rhs; - } else if (strcmp(lhs, rhs) != 0) - { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but '%s' is type '%s'\n", - p->fn->name, p->ln, - p->sym?p->sym->name:"?", lhs, - n->sym?n->sym->name:"?", rhs); - non_fatal("type error", (char *) 0); - } } - - /* ok on the rhs of an assignment: */ - if (!n - || n->ntyp == LEN || n->ntyp == RUN - || n->ntyp == FULL || n->ntyp == NFULL - || n->ntyp == EMPTY || n->ntyp == NEMPTY - || n->ntyp == 'R') - return; - - if (n->sym && n->sym->type == CHAN) - { if (d == 1) - fatal("invalid use of chan name", (char *) 0); - else - setaccess(n->sym, ZS, 0, 'V'); - } - - if (n->ntyp == NAME - || n->ntyp == '.') - { e = 0; /* array index or struct element */ - } - - nochan_manip(p, n->lft, e); - nochan_manip(p, n->rgt, 1); +nochan_manip(Lextok *p, Lextok *n, int d) /* p=lhs n=rhs */ +{ int e = 1; + + if (!n + || !p + || !p->sym + || p->sym->type == STRUCT) + { /* if a struct, assignments to structure fields arent checked yet */ + return; + } + + if (d == 0 && p->sym && p->sym->type == CHAN) + { setaccess(p->sym, ZS, 0, 'L'); + + if (n && n->ntyp == CONST) + fatal("invalid asgn to chan", (char *) 0); + + if (n && n->sym && n->sym->type == CHAN) + { setaccess(n->sym, ZS, 0, 'V'); + return; + } + } + + if (!d && n && n->ismtyp) /* rhs is an mtype value (a constant) */ + { const char *lhs = "_unnamed_", *rhs = "_unnamed_"; + + if (p->sym) + { lhs = p->sym->mtype_name?p->sym->mtype_name->name:"_unnamed_"; + } + if (n->sym) + { rhs = which_mtype(n->sym->name); /* only for constants */ + } + + if (p->sym && !p->sym->mtype_name && n->sym) + { p->sym->mtype_name = (Symbol *) emalloc(sizeof(Symbol)); + p->sym->mtype_name->name = strdup(rhs); + } else if (strcmp(lhs, rhs) != 0) + { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but '%s' is type '%s'\n", + p->fn->name, p->ln, + p->sym?p->sym->name:"?", lhs, + n->sym?n->sym->name:"?", rhs); + non_fatal("type error", (char *) 0); + } } + + /* ok on the rhs of an assignment: */ + if (!n + || n->ntyp == LEN || n->ntyp == RUN + || n->ntyp == FULL || n->ntyp == NFULL + || n->ntyp == EMPTY || n->ntyp == NEMPTY + || n->ntyp == 'R') + return; + + if (n->sym && n->sym->type == CHAN) + { if (d == 1) + fatal("invalid use of chan name", (char *) 0); + else + setaccess(n->sym, ZS, 0, 'V'); + } + + if (n->ntyp == NAME + || n->ntyp == '.') + { e = 0; /* array index or struct element */ + } + + nochan_manip(p, n->lft, e); + nochan_manip(p, n->rgt, 1); } typedef struct BaseName { - char *str; - int cnt; - struct BaseName *nxt; + char *str; + int cnt; + struct BaseName *nxt; } BaseName; static BaseName *bsn; static void newbasename(char *s) -{ BaseName *b; - -/* printf("+++++++++%s\n", s); */ - for (b = bsn; b; b = b->nxt) - if (strcmp(b->str, s) == 0) - { b->cnt++; - return; - } - b = (BaseName *) emalloc(sizeof(BaseName)); - b->str = emalloc(strlen(s)+1); - b->cnt = 1; - strcpy(b->str, s); - b->nxt = bsn; - bsn = b; +{ BaseName *b; + +/* printf("+++++++++%s\n", s); */ + for (b = bsn; b; b = b->nxt) + if (strcmp(b->str, s) == 0) + { b->cnt++; + return; + } + b = (BaseName *) emalloc(sizeof(BaseName)); + b->str = emalloc(strlen(s)+1); + b->cnt = 1; + strcpy(b->str, s); + b->nxt = bsn; + bsn = b; } static void delbasename(char *s) -{ BaseName *b, *prv = (BaseName *) 0; - - for (b = bsn; b; prv = b, b = b->nxt) - { if (strcmp(b->str, s) == 0) - { b->cnt--; - if (b->cnt == 0) - { if (prv) - { prv->nxt = b->nxt; - } else - { bsn = b->nxt; - } } -/* printf("---------%s\n", s); */ - break; - } } +{ BaseName *b, *prv = (BaseName *) 0; + + for (b = bsn; b; prv = b, b = b->nxt) + { if (strcmp(b->str, s) == 0) + { b->cnt--; + if (b->cnt == 0) + { if (prv) + { prv->nxt = b->nxt; + } else + { bsn = b->nxt; + } } +/* printf("---------%s\n", s); */ + break; + } } } static void checkindex(char *s, char *t) -{ BaseName *b; - -/* printf("xxx Check %s (%s)\n", s, t); */ - for (b = bsn; b; b = b->nxt) - { -/* printf(" %s\n", b->str); */ - if (strcmp(b->str, s) == 0) - { non_fatal("do not index an array with itself (%s)", t); - break; - } } +{ BaseName *b; + +/* printf("xxx Check %s (%s)\n", s, t); */ + for (b = bsn; b; b = b->nxt) + { +/* printf(" %s\n", b->str); */ + if (strcmp(b->str, s) == 0) + { non_fatal("do not index an array with itself (%s)", t); + break; + } } } static void scan_tree(Lextok *t, char *mn, char *mx) -{ char sv[512]; - char tmp[32]; - int oln = lineno; +{ char sv[512]; + char tmp[32]; + int oln = lineno; - if (!t) return; + if (!t) return; - lineno = t->ln; + lineno = t->ln; - if (t->ntyp == NAME) - { if (strlen(t->sym->name) + strlen(mn) > 512) - { fatal("name too long", t->sym->name); - } + if (t->ntyp == NAME) + { if (strlen(t->sym->name) + strlen(mn) > 512) + { fatal("name too long", t->sym->name); + } - strcat(mn, t->sym->name); + strcat(mn, t->sym->name); - if (t->lft) /* array index */ - { if(strlen(t->sym->name) + strlen("[]") > 512) - { fatal("name too long", t->sym->name); + if (t->lft) /* array index */ + { if(strlen(t->sym->name) + strlen("[]") > 512) + { fatal("name too long", t->sym->name); } strcat(mn, "[]"); - newbasename(mn); - strcpy(sv, mn); /* save */ - strcpy(mn, ""); /* clear */ - strcat(mx, "["); - scan_tree(t->lft, mn, mx); /* index */ - strcat(mx, "]"); - checkindex(mn, mx); /* match against basenames */ - strcpy(mn, sv); /* restore */ - delbasename(mn); - } - if (t->rgt) /* structure element */ - { scan_tree(t->rgt, mn, mx); - } - } else if (t->ntyp == CONST) - { strcat(mn, "1"); /* really: t->val */ - sprintf(tmp, "%d", t->val); - strcat(mx, tmp); - } else if (t->ntyp == '.') - { strcat(mn, "."); - strcat(mx, "."); - scan_tree(t->lft, mn, mx); - } else - { strcat(mn, "??"); - strcat(mx, "??"); - } - lineno = oln; + newbasename(mn); + strcpy(sv, mn); /* save */ + strcpy(mn, ""); /* clear */ + strcat(mx, "["); + scan_tree(t->lft, mn, mx); /* index */ + strcat(mx, "]"); + checkindex(mn, mx); /* match against basenames */ + strcpy(mn, sv); /* restore */ + delbasename(mn); + } + if (t->rgt) /* structure element */ + { scan_tree(t->rgt, mn, mx); + } + } else if (t->ntyp == CONST) + { strcat(mn, "1"); /* really: t->val */ + sprintf(tmp, "%d", t->val); + strcat(mx, tmp); + } else if (t->ntyp == '.') + { strcat(mn, "."); + strcat(mx, "."); + scan_tree(t->lft, mn, mx); + } else + { strcat(mn, "??"); + strcat(mx, "??"); + } + lineno = oln; } static void -no_nested_array_refs(Lextok *n) /* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */ -{ char mn[512]; - char mx[512]; +no_nested_array_refs(Lextok *n) /* a [ a[1] ] with a[1] = 1, causes trouble in pan.b */ +{ char mn[512]; + char mx[512]; -/* printf("==================================ZAP\n"); */ - bsn = (BaseName *) 0; /* start new list */ - strcpy(mn, ""); - strcpy(mx, ""); +/* printf("==================================ZAP\n"); */ + bsn = (BaseName *) 0; /* start new list */ + strcpy(mn, ""); + strcpy(mx, ""); - scan_tree(n, mn, mx); -/* printf("==> %s\n", mn); */ + scan_tree(n, mn, mx); +/* printf("==> %s\n", mn); */ } void no_internals(Lextok *n) -{ char *sp; +{ char *sp; - if (!n->sym - || !n->sym->name) - return; + if (!n->sym + || !n->sym->name) + return; - sp = n->sym->name; + sp = n->sym->name; - if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0) - || (strlen(sp) == strlen("_pid") && strcmp(sp, "_pid") == 0) - || (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0)) - { fatal("invalid assignment to %s", sp); - } + if ((strlen(sp) == strlen("_nr_pr") && strcmp(sp, "_nr_pr") == 0) + || (strlen(sp) == strlen("_pid") && strcmp(sp, "_pid") == 0) + || (strlen(sp) == strlen("_p") && strcmp(sp, "_p") == 0)) + { fatal("invalid assignment to %s", sp); + } - no_nested_array_refs(n); + no_nested_array_refs(n); } diff --git a/Src/msc_tcl.c b/Src/msc_tcl.c index 17004fb..6b6ab5b 100644 --- a/Src/msc_tcl.c +++ b/Src/msc_tcl.c @@ -47,8 +47,8 @@ extern void putpostlude(void); static void putpages(void); static void -psline(int x0, int y0, int x1, int y1, char *color) -{ char *side = "last"; +psline(int x0, int y0, int x1, int y1, const char *color) +{ const char *side = "last"; if (x0 == x1) /* gridline */ { fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags grid -width 1 \n", @@ -85,7 +85,7 @@ psline(int x0, int y0, int x1, int y1, char *color) } static void -colbox(int ix, int iy, int w, int h_unused, char *color) +colbox(int ix, int iy, int w, __attribute__ ((unused)) int h_unused, const char *color) { int x = ix*WW; int y = iy*HH; @@ -150,7 +150,7 @@ spitbox(int ix, int y, char *s) { float bw; /* box width */ char d[256], *t, *z; int a, i, x = ix+1; - char *color = "black"; + const char *color = "black"; if (y > 0) { stepnumber(y); @@ -338,7 +338,7 @@ putarrow(int from, int to) } void -pstext(int x, char *s) +pstext(int x, const char *s) { char *tmp = emalloc((int) strlen(s)+1); strcpy(tmp, s); @@ -359,7 +359,7 @@ pstext(int x, char *s) } void -dotag(FILE *fd, char *s) +dotag(FILE *fd, const char *s) { extern int columns, notabs; extern RunList *X_lst; int i = (!strncmp(s, "MSC: ", 5))?5:0; int pid = s_trail ? (prno - Have_claim) : (X_lst?X_lst->pid:0); diff --git a/Src/pangen1.c b/Src/pangen1.c index 4516cef..f44ce0e 100644 --- a/Src/pangen1.c +++ b/Src/pangen1.c @@ -18,1587 +18,1593 @@ #include #endif -extern FILE *fd_tc, *fd_th, *fd_tt; -extern Label *labtab; -extern Ordered *all_names; -extern ProcList *ready; -extern Queue *qtab; -extern Symbol *Fname; -extern int lineno, verbose, Pid_nr, separate, old_scope_rules, nclaims; -extern int nrRdy, nrqs, mstp, Mpars, claimnr, eventmapnr; -extern short has_sorted, has_random, has_provided, has_priority; -extern Queue *ltab[]; - -int Npars=0, u_sync=0, u_async=0, hastrack = 1; -short has_io = 0; -short has_state=0; /* code contains c_state */ - -extern void c_add_stack(FILE *); -extern void c_stack_size(FILE *); - -static Symbol *LstSet=ZS; -static int acceptors=0, progressors=0, nBits=0; -static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT }; - -static int doglobal(char *, int); -static void dohidden(void); -static void do_init(FILE *, Symbol *); -static void end_labs(Symbol *, int); -static void put_ptype(char *, int, int, int, enum btypes); -static void tc_predef_np(void); -static void put_pinit(ProcList *); -static void multi_init(void); - void walk_struct(FILE *, int, char *, Symbol *, char *, char *, char *); +extern FILE *fd_tc, *fd_th, *fd_tt; +extern Label *labtab; +extern Ordered *all_names; +extern ProcList *ready; +extern Queue *qtab; +extern Symbol *Fname; +extern int lineno, verbose, Pid_nr, separate, old_scope_rules, nclaims; +extern int nrRdy, nrqs, mstp, Mpars, claimnr, eventmapnr; +extern short has_sorted, has_random, has_provided, has_priority; +extern Queue *ltab[]; + +int Npars=0, u_sync=0, u_async=0, hastrack = 1; +short has_io = 0; +short has_state=0; /* code contains c_state */ + +extern void c_add_stack(FILE *); +extern void c_stack_size(FILE *); + +static Symbol *LstSet=ZS; +static int acceptors=0, progressors=0, nBits=0; +static int Types[] = { UNSIGNED, BIT, BYTE, CHAN, MTYPE, SHORT, INT, STRUCT }; + +static int doglobal(const char *, int); +static void dohidden(void); +static void do_init(FILE *, Symbol *); +static void end_labs(Symbol *, int); +static void put_ptype(const char *, int, int, int, enum btypes); +static void tc_predef_np(void); +static void put_pinit(ProcList *); +static void multi_init(void); + void walk_struct(FILE *, int, const char *, Symbol *, const char *, const char *, const char *); static void reverse_names(ProcList *p) { - if (!p) return; - reverse_names(p->nxt); - fprintf(fd_tc, " \"%s\",\n", p->n->name); + if (!p) return; + reverse_names(p->nxt); + fprintf(fd_tc, " \"%s\",\n", p->n->name); } static void reverse_types(ProcList *p) { - if (!p) return; - reverse_types(p->nxt); - fprintf(fd_tc, " %d, /* %s */\n", p->b, p->n->name); + if (!p) return; + reverse_types(p->nxt); + fprintf(fd_tc, " %d, /* %s */\n", p->b, p->n->name); } static int -blog(int n) /* for small log2 without rounding problems */ -{ int m=1, r=2; +blog(int n) /* for small log2 without rounding problems */ +{ int m=1, r=2; - while (r < n) { m++; r *= 2; } - return 1+m; + while (r < n) { m++; r *= 2; } + return 1+m; } void genheader(void) -{ ProcList *p; int i; - - if (separate == 2) - { putunames(fd_th); - goto here; - } - /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */ - fprintf(fd_th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *)); - fprintf(fd_th, "#define SYNC %d\n", u_sync); - fprintf(fd_th, "#define ASYNC %d\n\n", u_async); - fprintf(fd_th, "#ifndef NCORE\n"); - fprintf(fd_th, " #ifdef DUAL_CORE\n"); - fprintf(fd_th, " #define NCORE 2\n"); - fprintf(fd_th, " #elif QUAD_CORE\n"); - fprintf(fd_th, " #define NCORE 4\n"); - fprintf(fd_th, " #else\n"); - fprintf(fd_th, " #define NCORE 1\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n\n"); - - putunames(fd_th); - - fprintf(fd_tc, "\nshort Air[] = { "); - for (p = ready, i=0; p; p = p->nxt, i++) - fprintf(fd_tc, "%s (short) Air%d", (p!=ready)?",":"", i); - fprintf(fd_tc, ", (short) Air%d", i); /* np_ */ - if (nclaims > 1) - { fprintf(fd_tc, "\n#ifndef NOCLAIM\n"); - fprintf(fd_tc, " , (short) Air%d", i+1); /* Multi */ - fprintf(fd_tc, "\n#endif\n\t"); - } - fprintf(fd_tc, " };\n"); - - fprintf(fd_tc, "char *procname[] = {\n"); - reverse_names(ready); - fprintf(fd_tc, " \":np_:\",\n"); - fprintf(fd_tc, " 0\n"); - fprintf(fd_tc, "};\n\n"); - - fprintf(fd_tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM); - fprintf(fd_tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC); - fprintf(fd_tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n", - P_PROC, E_TRACE, N_TRACE); - - fprintf(fd_tc, "int Btypes[] = {\n"); - reverse_types(ready); - fprintf(fd_tc, " 0 /* :np_: */\n"); - fprintf(fd_tc, "};\n\n"); +{ ProcList *p; int i; + + if (separate == 2) + { putunames(fd_th); + goto here; + } + /* 5.2.3: gcc 3 no longer seems to compute sizeof at compile time */ + fprintf(fd_th, "#define WS %d /* word size in bytes */\n", (int) sizeof(void *)); + fprintf(fd_th, "#define SYNC %d\n", u_sync); + fprintf(fd_th, "#define ASYNC %d\n\n", u_async); + fprintf(fd_th, "#ifndef NCORE\n"); + fprintf(fd_th, " #ifdef DUAL_CORE\n"); + fprintf(fd_th, " #define NCORE 2\n"); + fprintf(fd_th, " #elif QUAD_CORE\n"); + fprintf(fd_th, " #define NCORE 4\n"); + fprintf(fd_th, " #else\n"); + fprintf(fd_th, " #define NCORE 1\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n\n"); + + putunames(fd_th); + + fprintf(fd_tc, "\nshort Air[] = { "); + for (p = ready, i=0; p; p = p->nxt, i++) + fprintf(fd_tc, "%s (short) Air%d", (p!=ready)?",":"", i); + fprintf(fd_tc, ", (short) Air%d", i); /* np_ */ + if (nclaims > 1) + { fprintf(fd_tc, "\n#ifndef NOCLAIM\n"); + fprintf(fd_tc, " , (short) Air%d", i+1); /* Multi */ + fprintf(fd_tc, "\n#endif\n\t"); + } + fprintf(fd_tc, " };\n"); + + fprintf(fd_tc, "char *procname[] = {\n"); + reverse_names(ready); + fprintf(fd_tc, " \":np_:\",\n"); + fprintf(fd_tc, " 0\n"); + fprintf(fd_tc, "};\n\n"); + + fprintf(fd_tc, "enum btypes { NONE=%d, N_CLAIM=%d,", NONE, N_CLAIM); + fprintf(fd_tc, " I_PROC=%d, A_PROC=%d,", I_PROC, A_PROC); + fprintf(fd_tc, " P_PROC=%d, E_TRACE=%d, N_TRACE=%d };\n\n", + P_PROC, E_TRACE, N_TRACE); + + fprintf(fd_tc, "int Btypes[] = {\n"); + reverse_types(ready); + fprintf(fd_tc, " 0 /* :np_: */\n"); + fprintf(fd_tc, "};\n\n"); here: - for (p = ready; p; p = p->nxt) - put_ptype(p->n->name, p->tn, mstp, nrRdy+1, p->b); - /* +1 for np_ */ - put_ptype("np_", nrRdy, mstp, nrRdy+1, 0); - - if (nclaims > 1) - { /* this is the structure that goes into the state-vector - * instead of the actual never claims - * this assumes that the claims do not have any local variables - * this claim records the types and states of all subclaims in an array - * NB: not sure if we need the first 3 fields in this structure - * it's here for now to avoid breaking some possible dependence - * in the calculations above, we were already taking into account - * that there is one never-claim, which will now be this one - */ - - i = blog(mstp); - fprintf(fd_th, "\n"); - - fprintf(fd_th, "#ifndef NOCLAIM\n"); - fprintf(fd_th, " #ifndef NP\n"); - fprintf(fd_th, " #undef VERI\n"); - fprintf(fd_th, " #define VERI %d\n", nrRdy+1); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, " #define Pclaim P%d\n\n", nrRdy+1); - fprintf(fd_th, "typedef struct P%d {\n", nrRdy+1); - fprintf(fd_th, " unsigned _pid : 8; /* always zero */\n"); - fprintf(fd_th, " unsigned _t : %d; /* active-claim type */\n", - blog(nrRdy+1)); - fprintf(fd_th, " unsigned _p : %d; /* active-claim state */\n", - i); - fprintf(fd_th, " unsigned _n : %d; /* active-claim index */\n", - blog(nclaims)); - if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */ - { fprintf(fd_th, " uchar c_cur[NCLAIMS]; /* claim-states */\n"); - } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */ - { fprintf(fd_th, " ushort c_cur[NCLAIMS]; /* claim-states */\n"); - } else /* the most unlikely case */ - { fprintf(fd_th, " uint c_cur[NCLAIMS]; /* claim-states */\n"); - } - fprintf(fd_th, "} P%d;\n", nrRdy+1); - - fprintf(fd_tc, "#ifndef NOCLAIM\n"); - fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); - fprintf(fd_tc, "#endif\n"); - - fprintf(fd_th, " #define Air%d (0)\n\n", nrRdy+1); - fprintf(fd_th, "#endif\n"); - /* - * find special states as: - * stopstate [ claimnr ][ curstate ] == 1 - * accpstate [ claimnr ][ curstate ] - * progstate [ claimnr ][ curstate ] - * reached [ claimnr ][ curstate ] - * visstate [ claimnr ][ curstate ] - * loopstate [ claimnr ][ curstate ] - * mapstate [ claimnr ][ curstate ] - */ - } else - { fprintf(fd_th, "#define Pclaim P0\n"); - fprintf(fd_th, "#ifndef NCLAIMS\n"); - fprintf(fd_th, " #define NCLAIMS 1\n"); - fprintf(fd_th, "#endif\n"); - fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); - } - - ntimes(fd_th, 0, 1, Head0); - - if (separate != 2) - { - ntimes(fd_th, 0, 1, Header); - fprintf(fd_th, "#define StackSize ("); - c_stack_size(fd_th); - fprintf(fd_th, ")\n"); - - c_add_stack(fd_th); - ntimes(fd_th, 0, 1, Header0); - } else - { fprintf(fd_th, "extern char *emalloc(unsigned long);\n"); - } - ntimes(fd_th, 0, 1, Head1); - - LstSet = ZS; - (void) doglobal("", PUTV); - - hastrack = c_add_sv(fd_th); - - fprintf(fd_th, "#ifdef TRIX\n"); - fprintf(fd_th, " /* room for 512 proc+chan ptrs, + safety margin */\n"); - fprintf(fd_th, " char *_ids_[MAXPROC+MAXQ+4];\n"); - fprintf(fd_th, "#else\n"); - fprintf(fd_th, " uchar sv[VECTORSZ];\n"); - fprintf(fd_th, "#endif\n"); - - fprintf(fd_th, "} State"); + for (p = ready; p; p = p->nxt) + put_ptype(p->n->name, p->tn, mstp, nrRdy+1, p->b); + /* +1 for np_ */ + put_ptype("np_", nrRdy, mstp, nrRdy+1, NONE); + + if (nclaims > 1) + { /* this is the structure that goes into the state-vector + * instead of the actual never claims + * this assumes that the claims do not have any local variables + * this claim records the types and states of all subclaims in an array + * NB: not sure if we need the first 3 fields in this structure + * it's here for now to avoid breaking some possible dependence + * in the calculations above, we were already taking into account + * that there is one never-claim, which will now be this one + */ + + i = blog(mstp); + fprintf(fd_th, "\n"); + + fprintf(fd_th, "#ifndef NOCLAIM\n"); + fprintf(fd_th, " #ifndef NP\n"); + fprintf(fd_th, " #undef VERI\n"); + fprintf(fd_th, " #define VERI %d\n", nrRdy+1); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #define Pclaim P%d\n\n", nrRdy+1); + fprintf(fd_th, "typedef struct P%d {\n", nrRdy+1); + fprintf(fd_th, " unsigned _pid : 8; /* always zero */\n"); + fprintf(fd_th, " unsigned _t : %d; /* active-claim type */\n", + blog(nrRdy+1)); + fprintf(fd_th, " unsigned _p : %d; /* active-claim state */\n", + i); + fprintf(fd_th, " unsigned _n : %d; /* active-claim index */\n", + blog(nclaims)); + if (i <= UINT8_MAX) /* in stdint.h = UCHAR_MAX from limits.h */ + { fprintf(fd_th, " uchar c_cur[NCLAIMS]; /* claim-states */\n"); + } else if (i <= UINT16_MAX) /* really USHRT_MAX from limits.h */ + { fprintf(fd_th, " ushort c_cur[NCLAIMS]; /* claim-states */\n"); + } else /* the most unlikely case */ + { fprintf(fd_th, " uint c_cur[NCLAIMS]; /* claim-states */\n"); + } + fprintf(fd_th, "} P%d;\n", nrRdy+1); + + fprintf(fd_tc, "#ifndef NOCLAIM\n"); + fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_th, " #define Air%d (0)\n\n", nrRdy+1); + fprintf(fd_th, "#endif\n"); + /* + * find special states as: + * stopstate [ claimnr ][ curstate ] == 1 + * accpstate [ claimnr ][ curstate ] + * progstate [ claimnr ][ curstate ] + * reached [ claimnr ][ curstate ] + * visstate [ claimnr ][ curstate ] + * loopstate [ claimnr ][ curstate ] + * mapstate [ claimnr ][ curstate ] + */ + } else + { fprintf(fd_th, "#define Pclaim P0\n"); + fprintf(fd_th, "#ifndef NCLAIMS\n"); + fprintf(fd_th, " #define NCLAIMS 1\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_tc, "uchar spin_c_typ[NCLAIMS]; /* claim-types */\n"); + } + + ntimes(fd_th, 0, 1, Head0); + + if (separate != 2) + { + ntimes(fd_th, 0, 1, Header); + fprintf(fd_th, "#define StackSize ("); + c_stack_size(fd_th); + fprintf(fd_th, ")\n"); + + c_add_stack(fd_th); + ntimes(fd_th, 0, 1, Header0); + } else + { fprintf(fd_th, "extern char *emalloc(unsigned long);\n"); + } + ntimes(fd_th, 0, 1, Head1); + + LstSet = ZS; + (void) doglobal("", PUTV); + + hastrack = c_add_sv(fd_th); + + fprintf(fd_th, "#ifdef TRIX\n"); + fprintf(fd_th, " /* room for 512 proc+chan ptrs, + safety margin */\n"); + fprintf(fd_th, " char *_ids_[MAXPROC+MAXQ+4];\n"); + fprintf(fd_th, "#else\n"); + fprintf(fd_th, " uchar sv[VECTORSZ];\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "} State"); #ifdef SOLARIS - fprintf(fd_th,"\n#ifdef GCC\n"); - fprintf(fd_th, "\t__attribute__ ((aligned(8)))"); - fprintf(fd_th, "\n#endif\n\t"); + fprintf(fd_th,"\n#ifdef GCC\n"); + fprintf(fd_th, "\t__attribute__ ((aligned(8)))"); + fprintf(fd_th, "\n#endif\n\t"); #endif - fprintf(fd_th, ";\n\n"); - - fprintf(fd_th, "#ifdef TRIX\n"); - fprintf(fd_th, "typedef struct TRIX_v6 {\n"); - fprintf(fd_th, " uchar *body; /* aligned */\n"); - fprintf(fd_th, "#ifndef BFS\n"); - fprintf(fd_th, " short modified;\n"); - fprintf(fd_th, "#endif\n"); - fprintf(fd_th, " short psize;\n"); - fprintf(fd_th, " short parent_pid;\n"); - fprintf(fd_th, " struct TRIX_v6 *nxt;\n"); - fprintf(fd_th, "} TRIX_v6;\n"); - fprintf(fd_th, "#endif\n\n"); - - fprintf(fd_th, "#define HAS_TRACK %d\n", hastrack); - if (0 && hastrack) /* not really a problem */ - { fprintf(fd_th, "#ifdef BFS_PAR\n"); - fprintf(fd_th, " #error cannot use BFS_PAR on models with c_track stmnts\n"); - fprintf(fd_th, "#endif\n"); - } - if (separate != 2) - dohidden(); + fprintf(fd_th, ";\n\n"); + + fprintf(fd_th, "#ifdef TRIX\n"); + fprintf(fd_th, "typedef struct TRIX_v6 {\n"); + fprintf(fd_th, " uchar *body; /* aligned */\n"); + fprintf(fd_th, "#ifndef BFS\n"); + fprintf(fd_th, " short modified;\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, " short psize;\n"); + fprintf(fd_th, " short parent_pid;\n"); + fprintf(fd_th, " struct TRIX_v6 *nxt;\n"); + fprintf(fd_th, "} TRIX_v6;\n"); + fprintf(fd_th, "#endif\n\n"); + + fprintf(fd_th, "#define HAS_TRACK %d\n", hastrack); + if (0 && hastrack) /* not really a problem */ + { fprintf(fd_th, "#ifdef BFS_PAR\n"); + fprintf(fd_th, " #error cannot use BFS_PAR on models with c_track stmnts\n"); + fprintf(fd_th, "#endif\n"); + } + if (separate != 2) + dohidden(); } void genaddproc(void) -{ ProcList *p; - int i = 0; +{ ProcList *p; + int i = 0; - if (separate == 2) goto shortcut; + if (separate == 2) goto shortcut; - ntimes(fd_tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */ + ntimes(fd_tc, nrRdy+1, nrRdy+2, R2); /* +1 for np_ -- was th */ - fprintf(fd_tc, "#ifdef TRIX\n"); - fprintf(fd_tc, "int what_p_size(int);\n"); - fprintf(fd_tc, "int what_q_size(int);\n\n"); + fprintf(fd_tc, "#ifdef TRIX\n"); + fprintf(fd_tc, "int what_p_size(int);\n"); + fprintf(fd_tc, "int what_q_size(int);\n\n"); - /* the number of processes just changed by 1 (up or down) */ - /* this means that the channel indices move up or down by one slot */ - /* not all new channels may have a valid index yet, but we move */ - /* all of them anyway, as if they existed */ - ntimes(fd_tc, 0, 1, R7a); - fprintf(fd_tc, "#endif\n\n"); + /* the number of processes just changed by 1 (up or down) */ + /* this means that the channel indices move up or down by one slot */ + /* not all new channels may have a valid index yet, but we move */ + /* all of them anyway, as if they existed */ + ntimes(fd_tc, 0, 1, R7a); + fprintf(fd_tc, "#endif\n\n"); - ntimes(fd_tc, 0, 1, R7b); + ntimes(fd_tc, 0, 1, R7b); - fprintf(fd_tc, "int\naddproc(int calling_pid, int priority, int n"); - for (/* i = 0 */; i < Npars; i++) - fprintf(fd_tc, ", int par%d", i); + fprintf(fd_tc, "int\naddproc(int calling_pid, int priority, int n"); + for (/* i = 0 */; i < Npars; i++) + fprintf(fd_tc, ", int par%d", i); - ntimes(fd_tc, 0, 1, Addp0); - ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ + ntimes(fd_tc, 0, 1, Addp0); + ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ - if (nclaims > 1) - { fprintf(fd_tc, "#ifndef NOCLAIM\n"); - ntimes(fd_tc, nrRdy+1, nrRdy+2, R5); - fprintf(fd_tc, "#endif\n"); - } + if (nclaims > 1) + { fprintf(fd_tc, "#ifndef NOCLAIM\n"); + ntimes(fd_tc, nrRdy+1, nrRdy+2, R5); + fprintf(fd_tc, "#endif\n"); + } - ntimes(fd_tc, 0, 1, Addp1); + ntimes(fd_tc, 0, 1, Addp1); - if (has_provided) - { fprintf(fd_tt, "\nint\nprovided(int II, unsigned char ot, "); - fprintf(fd_tt, "int tt, Trans *t)\n"); - fprintf(fd_tt, "{\n\tswitch(ot) {\n"); - } + if (has_provided) + { fprintf(fd_tt, "\nint\nprovided(int II, unsigned char ot, "); + fprintf(fd_tt, "int tt, Trans *t)\n"); + fprintf(fd_tt, "{\n\tswitch(ot) {\n"); + } shortcut: - if (nclaims > 1) - { multi_init(); - } - tc_predef_np(); - for (p = ready; p; p = p->nxt) - { Pid_nr = p->tn; - put_pinit(p); - } - if (separate == 2) return; - - Pid_nr = 0; - if (has_provided) - { fprintf(fd_tt, "\tdefault: return 1; /* e.g., a claim */\n"); - fprintf(fd_tt, "\t}\n\treturn 0;\n}\n"); - } - - ntimes(fd_tc, i, i+1, R6); - if (separate == 0) - ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ - else - ntimes(fd_tc, 1, nrRdy, R5); - ntimes(fd_tc, 0, 1, R8a); + if (nclaims > 1) + { multi_init(); + } + tc_predef_np(); + for (p = ready; p; p = p->nxt) + { Pid_nr = p->tn; + put_pinit(p); + } + if (separate == 2) return; + + Pid_nr = 0; + if (has_provided) + { fprintf(fd_tt, "\tdefault: return 1; /* e.g., a claim */\n"); + fprintf(fd_tt, "\t}\n\treturn 0;\n}\n"); + } + + ntimes(fd_tc, i, i+1, R6); + if (separate == 0) + ntimes(fd_tc, 1, nrRdy+1, R5); /* +1 for np_ */ + else + ntimes(fd_tc, 1, nrRdy, R5); + ntimes(fd_tc, 0, 1, R8a); } void do_locinits(FILE *fd) -{ ProcList *p; - - /* the locinit functions may refer to pptr or qptr */ - fprintf(fd, "#if VECTORSZ>32000\n"); - fprintf(fd, " extern int \n"); - fprintf(fd, "#else\n"); - fprintf(fd, " extern short \n"); - fprintf(fd, "#endif\n"); - fprintf(fd, " *proc_offset, *q_offset;\n"); - - for (p = ready; p; p = p->nxt) - { c_add_locinit(fd, p->tn, p->n->name); - } +{ ProcList *p; + + /* the locinit functions may refer to pptr or qptr */ + fprintf(fd, "#if VECTORSZ>32000\n"); + fprintf(fd, " extern int \n"); + fprintf(fd, "#else\n"); + fprintf(fd, " extern short \n"); + fprintf(fd, "#endif\n"); + fprintf(fd, " *proc_offset, *q_offset;\n"); + + for (p = ready; p; p = p->nxt) + { c_add_locinit(fd, p->tn, p->n->name); + } } void genother(void) -{ ProcList *p; - - switch (separate) { - case 2: - if (nclaims > 0) - { for (p = ready; p; p = p->nxt) - { if (p->b == N_CLAIM) - { ntimes(fd_tc, p->tn, p->tn+1, R0); /* claims only */ - fprintf(fd_tc, "#ifdef HAS_CODE\n"); - ntimes(fd_tc, p->tn, p->tn+1, R00); - fprintf(fd_tc, "#endif\n"); - } } } - break; - case 1: - ntimes(fd_tc, 0, 1, Code0); - for (p = ready; p; p = p->nxt) - { if (p->b != N_CLAIM) - { ntimes(fd_tc, p->tn, p->tn+1, R0); /* all except claims */ - fprintf(fd_tc, "#ifdef HAS_CODE\n"); - ntimes(fd_tc, p->tn, p->tn+1, R00); - fprintf(fd_tc, "#endif\n"); - } } - break; - case 0: - ntimes(fd_tc, 0, 1, Code0); - ntimes(fd_tc, 0, nrRdy+1, R0); /* +1 for np_ */ - fprintf(fd_tc, "#ifdef HAS_CODE\n"); - ntimes(fd_tc, 0, nrRdy+1, R00); /* +1 for np_ */ - fprintf(fd_tc, "#endif\n"); - break; - } - /* new place, make sure Maxbody is set to its final value here */ - fprintf(fd_tc, "\n"); - - if (separate != 2) - { ntimes(fd_tc, 1, u_sync+u_async+1, R3); /* nrqs is still 0 */ - fprintf(fd_tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n"); - fprintf(fd_tc, "\tif ((Maxbody %% WS) != 0)\n"); - fprintf(fd_tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n"); - } - - for (p = ready; p; p = p->nxt) - end_labs(p->n, p->tn); - - switch (separate) { - case 2: - if (nclaims > 0) - { for (p = ready; p; p = p->nxt) - { if (p->b == N_CLAIM) - { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* claims only */ - } } } - return; - case 1: - for (p = ready; p; p = p->nxt) - { if (p->b != N_CLAIM) - { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* all except claims */ - } } - fprintf(fd_tc, " if (state_tables)\n"); - fprintf(fd_tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */ - if (acceptors == 0) - { acceptors = 1; /* assume at least 1 acceptstate */ - } - break; - case 0: - ntimes(fd_tc, 0, nrRdy, R0a); /* all */ - break; - } - - ntimes(fd_th, acceptors, acceptors+1, Code1); - ntimes(fd_th, progressors, progressors+1, Code3); - - ntimes(fd_tc, 0, 1, Code2a); /* dfs, bfs */ - ntimes(fd_tc, 0, 1, Code2e); /* multicore */ - ntimes(fd_tc, 0, 1, Code2c); /* multicore */ - ntimes(fd_tc, 0, 1, Code2d); - - fprintf(fd_tc, "void\ndo_reach(void)\n{\n"); - ntimes(fd_tc, 0, nrRdy, R4); - fprintf(fd_tc, "}\n\n"); - - fprintf(fd_tc, "void\niniglobals(int calling_pid)\n{\n"); - if (doglobal("", INIV) > 0) - { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); - (void) doglobal("logval(\"", LOGV); - fprintf(fd_tc, "#endif\n"); - } - fprintf(fd_tc, "}\n\n"); +{ ProcList *p; + + switch (separate) { + case 2: + if (nclaims > 0) + { for (p = ready; p; p = p->nxt) + { if (p->b == N_CLAIM) + { ntimes(fd_tc, p->tn, p->tn+1, R0); /* claims only */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, p->tn, p->tn+1, R00); + fprintf(fd_tc, "#endif\n"); + } } } + break; + case 1: + ntimes(fd_tc, 0, 1, Code0); + for (p = ready; p; p = p->nxt) + { if (p->b != N_CLAIM) + { ntimes(fd_tc, p->tn, p->tn+1, R0); /* all except claims */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, p->tn, p->tn+1, R00); + fprintf(fd_tc, "#endif\n"); + } } + break; + case 0: + ntimes(fd_tc, 0, 1, Code0); + ntimes(fd_tc, 0, nrRdy+1, R0); /* +1 for np_ */ + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + ntimes(fd_tc, 0, nrRdy+1, R00); /* +1 for np_ */ + fprintf(fd_tc, "#endif\n"); + break; + } + /* new place, make sure Maxbody is set to its final value here */ + fprintf(fd_tc, "\n"); + + if (separate != 2) + { ntimes(fd_tc, 1, u_sync+u_async+1, R3); /* nrqs is still 0 */ + fprintf(fd_tc, "\tMaxbody = max(Maxbody, sizeof(State)-VECTORSZ);\n"); + fprintf(fd_tc, "\tif ((Maxbody %% WS) != 0)\n"); + fprintf(fd_tc, "\t Maxbody += WS - (Maxbody %% WS);\n\n"); + } + + for (p = ready; p; p = p->nxt) + end_labs(p->n, p->tn); + + switch (separate) { + case 2: + if (nclaims > 0) + { for (p = ready; p; p = p->nxt) + { if (p->b == N_CLAIM) + { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* claims only */ + } } } + return; + case 1: + for (p = ready; p; p = p->nxt) + { if (p->b != N_CLAIM) + { ntimes(fd_tc, p->tn, p->tn+1, R0a); /* all except claims */ + } } + fprintf(fd_tc, " if (state_tables)\n"); + fprintf(fd_tc, " ini_claim(%d, 0);\n", claimnr); /* the default claim */ + if (acceptors == 0) + { acceptors = 1; /* assume at least 1 acceptstate */ + } + break; + case 0: + ntimes(fd_tc, 0, nrRdy, R0a); /* all */ + break; + } + + ntimes(fd_th, acceptors, acceptors+1, Code1); + ntimes(fd_th, progressors, progressors+1, Code3); + + ntimes(fd_tc, 0, 1, Code2a); /* dfs, bfs */ + ntimes(fd_tc, 0, 1, Code2e); /* multicore */ + ntimes(fd_tc, 0, 1, Code2c); /* multicore */ + ntimes(fd_tc, 0, 1, Code2d); + + fprintf(fd_tc, "void\ndo_reach(void)\n{\n"); + ntimes(fd_tc, 0, nrRdy, R4); + fprintf(fd_tc, "}\n\n"); + + fprintf(fd_tc, "void\niniglobals(int calling_pid)\n{\n"); + if (doglobal("", INIV) > 0) + { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); + (void) doglobal("logval(\"", LOGV); + fprintf(fd_tc, "#endif\n"); + } + fprintf(fd_tc, "}\n\n"); } void gensvmap(void) { - ntimes(fd_tc, 0, 1, SvMap); + ntimes(fd_tc, 0, 1, SvMap); } static struct { - char *s, *t; int n, m, p; + const char *s, *t; int n, m, p; } ln[] = { - {"end", "stopstate", 3, 0, 0}, - {"progress", "progstate", 8, 0, 1}, - {"accept", "accpstate", 6, 1, 0}, - {0, 0, 0, 0, 0}, + {"end", "stopstate", 3, 0, 0}, + {"progress", "progstate", 8, 0, 1}, + {"accept", "accpstate", 6, 1, 0}, + {0, 0, 0, 0, 0}, }; static void end_labs(Symbol *s, int i) -{ int oln = lineno; - Symbol *ofn = Fname; - Label *l; - int j; char foo[128]; - - if ((pid_is_claim(i) && separate == 1) - || (!pid_is_claim(i) && separate == 2)) - return; - - for (l = labtab; l; l = l->nxt) - for (j = 0; ln[j].n; j++) - { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0 - && strcmp(l->c->name, s->name) == 0) - { fprintf(fd_tc, "\t%s[%d][%d] = 1;\n", - ln[j].t, i, l->e->seqno); - acceptors += ln[j].m; - progressors += ln[j].p; - if (l->e->status & D_ATOM) - { sprintf(foo, "%s label inside d_step", - ln[j].s); - goto complain; - } - if (j > 0 && (l->e->status & ATOM)) - { sprintf(foo, "%s label inside atomic", - ln[j].s); - complain: lineno = l->e->n->ln; - Fname = l->e->n->fn; - printf("spin: %3d:%s, warning, %s - is invisible\n", - lineno, Fname?Fname->name:"-", foo); - } } } - /* visible states -- through remote refs: */ - for (l = labtab; l; l = l->nxt) - if (l->visible - && strcmp(l->s->context->name, s->name) == 0) - fprintf(fd_tc, "\tvisstate[%d][%d] = 1;\n", - i, l->e->seqno); - - lineno = oln; - Fname = ofn; +{ int oln = lineno; + Symbol *ofn = Fname; + Label *l; + int j; char foo[128]; + + if ((pid_is_claim(i) && separate == 1) + || (!pid_is_claim(i) && separate == 2)) + return; + + for (l = labtab; l; l = l->nxt) + for (j = 0; ln[j].n; j++) + { if (strncmp(l->s->name, ln[j].s, ln[j].n) == 0 + && strcmp(l->c->name, s->name) == 0) + { fprintf(fd_tc, "\t%s[%d][%d] = 1;\n", + ln[j].t, i, l->e->seqno); + acceptors += ln[j].m; + progressors += ln[j].p; + if (l->e->status & D_ATOM) + { sprintf(foo, "%s label inside d_step", + ln[j].s); + goto complain; + } + if (j > 0 && (l->e->status & ATOM)) + { sprintf(foo, "%s label inside atomic", + ln[j].s); + complain: lineno = l->e->n->ln; + Fname = l->e->n->fn; + printf("spin: %3d:%s, warning, %s - is invisible\n", + lineno, Fname?Fname->name:"-", foo); + } } } + /* visible states -- through remote refs: */ + for (l = labtab; l; l = l->nxt) + if (l->visible + && strcmp(l->s->context->name, s->name) == 0) + fprintf(fd_tc, "\tvisstate[%d][%d] = 1;\n", + i, l->e->seqno); + + lineno = oln; + Fname = ofn; } void ntimes(FILE *fd, int n, int m, const char *c[]) { - int i, j; - for (j = 0; c[j]; j++) - for (i = n; i < m; i++) - { fprintf(fd, c[j], i, i, i, i, i, i); - fprintf(fd, "\n"); - } + int i, j; + for (j = 0; c[j]; j++) + for (i = n; i < m; i++) + { fprintf(fd, c[j], i, i, i, i, i, i); + fprintf(fd, "\n"); + } } void prehint(Symbol *s) -{ Lextok *n; +{ Lextok *n; - printf("spin: warning, "); - if (!s) return; + printf("spin: warning, "); + if (!s) return; - n = (s->context != ZS)?s->context->ini:s->ini; - if (n) - printf("line %s:%d, ", n->fn->name, n->ln); + n = (s->context != ZS)?s->context->ini:s->ini; + if (n) + printf("line %s:%d, ", n->fn->name, n->ln); } void -checktype(Symbol *sp, char *s) -{ char buf[128]; int i; - - if (!s - || (sp->type != BYTE - && sp->type != SHORT - && sp->type != INT)) - return; - - if (sp->hidden&16) /* formal parameter */ - { ProcList *p; Lextok *f, *t; - int posnr = 0; - for (p = ready; p; p = p->nxt) - if (p->n->name - && strcmp(s, p->n->name) == 0) - break; - if (p) - for (f = p->p; f; f = f->rgt) /* list of types */ - for (t = f->lft; t; t = t->rgt, posnr++) - if (t->sym - && strcmp(t->sym->name, sp->name) == 0) - { checkrun(sp, posnr); - return; - } - - } else if (!(sp->hidden&4)) - { if (!(verbose&32)) return; - sputtype(buf, sp->type); - i = (int) strlen(buf); - while (i > 0 && buf[--i] == ' ') buf[i] = '\0'; - prehint(sp); - if (sp->context) - printf("proctype %s:", s); - else - printf("global"); - printf(" '%s %s' could be declared 'bit %s'\n", - buf, sp->name, sp->name); - } else if (sp->type != BYTE && !(sp->hidden&8)) - { if (!(verbose&32)) return; - sputtype(buf, sp->type); - i = (int) strlen(buf); - while (buf[--i] == ' ') buf[i] = '\0'; - prehint(sp); - if (sp->context) - printf("proctype %s:", s); - else - printf("global"); - printf(" '%s %s' could be declared 'byte %s'\n", - buf, sp->name, sp->name); - } +checktype(Symbol *sp, const char *s) +{ char buf[128]; int i; + + if (!s + || (sp->type != BYTE + && sp->type != SHORT + && sp->type != INT)) + return; + + if (sp->hidden&16) /* formal parameter */ + { ProcList *p; Lextok *f, *t; + int posnr = 0; + for (p = ready; p; p = p->nxt) + if (p->n->name + && strcmp(s, p->n->name) == 0) + break; + if (p) + for (f = p->p; f; f = f->rgt) /* list of types */ + for (t = f->lft; t; t = t->rgt, posnr++) + if (t->sym + && strcmp(t->sym->name, sp->name) == 0) + { checkrun(sp, posnr); + return; + } + + } else if (!(sp->hidden&4)) + { if (!(verbose&32)) return; + sputtype(buf, sp->type); + i = (int) strlen(buf); + while (i > 0 && buf[--i] == ' ') buf[i] = '\0'; + prehint(sp); + if (sp->context) + printf("proctype %s:", s); + else + printf("global"); + printf(" '%s %s' could be declared 'bit %s'\n", + buf, sp->name, sp->name); + } else if (sp->type != BYTE && !(sp->hidden&8)) + { if (!(verbose&32)) return; + sputtype(buf, sp->type); + i = (int) strlen(buf); + while (buf[--i] == ' ') buf[i] = '\0'; + prehint(sp); + if (sp->context) + printf("proctype %s:", s); + else + printf("global"); + printf(" '%s %s' could be declared 'byte %s'\n", + buf, sp->name, sp->name); + } } static int -dolocal(FILE *ofd, char *pre, int dowhat, int p, char *s, enum btypes b) -{ int h, j, k=0; extern int nr_errs; - Ordered *walk; - Symbol *sp; - char buf[128], buf2[128], buf3[128]; - - if (dowhat == INIV) - { /* initialize in order of declaration */ - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp->context - && !sp->owner - && strcmp(s, sp->context->name) == 0) - { checktype(sp, s); /* fall through */ - if (!(sp->hidden&16)) - { sprintf(buf, "((P%d *)pptr(h))->", p); - do_var(ofd, dowhat, buf, sp, "", " = ", ";\n"); - } - k++; - } } - } else - { for (j = 0; j < 8; j++) - for (h = 0; h <= 1; h++) - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp->context - && !sp->owner - && sp->type == Types[j] - && ((h == 0 && (sp->nel == 1 && sp->isarray == 0)) - || (h == 1 && (sp->nel > 1 || sp->isarray == 1))) - && strcmp(s, sp->context->name) == 0) - { switch (dowhat) { - case LOGV: - if (sp->type == CHAN - && verbose == 0) - break; - sprintf(buf, "%s%s:", pre, s); - { sprintf(buf2, "\", ((P%d *)pptr(h))->", p); - sprintf(buf3, ");\n"); - } - do_var(ofd, dowhat, "", sp, buf, buf2, buf3); - break; - case PUTV: - sprintf(buf, "((P%d *)pptr(h))->", p); - do_var(ofd, dowhat, buf, sp, "", " = ", ";\n"); - k++; - break; - } - if (b == N_CLAIM) - { printf("error: %s defines local %s\n", - s, sp->name); - nr_errs++; - } } } } - - return k; +dolocal(FILE *ofd, const char *pre, int dowhat, int p, const char *s, enum btypes b) +{ int h, j, k=0; extern int nr_errs; + Ordered *walk; + Symbol *sp; + char buf[128], buf2[128], buf3[128]; + + if (dowhat == INIV) + { /* initialize in order of declaration */ + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp->context + && !sp->owner + && strcmp(s, sp->context->name) == 0) + { checktype(sp, s); /* fall through */ + if (!(sp->hidden&16)) + { sprintf(buf, "((P%d *)pptr(h))->", p); + do_var(ofd, dowhat, buf, sp, "", " = ", ";\n"); + } + k++; + } } + } else + { for (j = 0; j < 8; j++) + for (h = 0; h <= 1; h++) + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp->context + && !sp->owner + && sp->type == Types[j] + && ((h == 0 && (sp->nel == 1 && sp->isarray == 0)) + || (h == 1 && (sp->nel > 1 || sp->isarray == 1))) + && strcmp(s, sp->context->name) == 0) + { switch (dowhat) { + case LOGV: + if (sp->type == CHAN + && verbose == 0) + break; + sprintf(buf, "%s%s:", pre, s); + { sprintf(buf2, "\", ((P%d *)pptr(h))->", p); + sprintf(buf3, ");\n"); + } + do_var(ofd, dowhat, "", sp, buf, buf2, buf3); + break; + case PUTV: + sprintf(buf, "((P%d *)pptr(h))->", p); + do_var(ofd, dowhat, buf, sp, "", " = ", ";\n"); + k++; + break; + } +if (b == N_CLAIM) + { printf("error: %s defines local %s\n", + s, sp->name); + nr_errs++; + } } } } + + return k; } void c_chandump(FILE *fd) -{ Queue *q; - char buf[256]; - int i; - - if (!qtab) - { fprintf(fd, "void\nc_chandump(int unused)\n"); - fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n"); - return; - } - - fprintf(fd, "void\nc_chandump(int from)\n"); - fprintf(fd, "{ uchar *z; int slot;\n"); - - fprintf(fd, " from--;\n"); - fprintf(fd, " if (from >= (int) now._nr_qs || from < 0)\n"); - fprintf(fd, " { printf(\"pan: bad qid %%d\\n\", from+1);\n"); - fprintf(fd, " return;\n"); - fprintf(fd, " }\n"); - fprintf(fd, " z = qptr(from);\n"); - fprintf(fd, " switch (((Q0 *)z)->_t) {\n"); - - for (q = qtab; q; q = q->nxt) - { fprintf(fd, " case %d:\n\t\t", q->qid); - sprintf(buf, "((Q%d *)z)->", q->qid); - - fprintf(fd, "for (slot = 0; slot < %sQlen; slot++)\n\t\t", buf); - fprintf(fd, "{ printf(\" [\");\n\t\t"); - for (i = 0; i < q->nflds; i++) - { if (q->fld_width[i] == MTYPE) - { fprintf(fd, "\tprintm(%scontents[slot].fld%d", - buf, i); - if (q->mtp[i]) - { fprintf(fd, ", \"%s\"", q->mtp[i]); - } else - { fprintf(fd, ", 0"); - } - } else - { fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d", - buf, i); - } - fprintf(fd, ");\n\t\t"); - } - fprintf(fd, " printf(\"],\");\n\t\t"); - fprintf(fd, "}\n\t\t"); - fprintf(fd, "break;\n"); - } - fprintf(fd, " }\n"); - fprintf(fd, " printf(\"\\n\");\n}\n"); +{ Queue *q; + char buf[256]; + int i; + + if (!qtab) + { fprintf(fd, "void\nc_chandump(int unused)\n"); + fprintf(fd, "{\tunused++; /* avoid complaints */\n}\n"); + return; + } + + fprintf(fd, "void\nc_chandump(int from)\n"); + fprintf(fd, "{ uchar *z; int slot;\n"); + + fprintf(fd, " from--;\n"); + fprintf(fd, " if (from >= (int) now._nr_qs || from < 0)\n"); + fprintf(fd, " { printf(\"pan: bad qid %%d\\n\", from+1);\n"); + fprintf(fd, " return;\n"); + fprintf(fd, " }\n"); + fprintf(fd, " z = qptr(from);\n"); + fprintf(fd, " switch (((Q0 *)z)->_t) {\n"); + + for (q = qtab; q; q = q->nxt) + { fprintf(fd, " case %d:\n\t\t", q->qid); + sprintf(buf, "((Q%d *)z)->", q->qid); + + fprintf(fd, "for (slot = 0; slot < %sQlen; slot++)\n\t\t", buf); + fprintf(fd, "{ printf(\" [\");\n\t\t"); + for (i = 0; i < q->nflds; i++) + { if (q->fld_width[i] == MTYPE) + { fprintf(fd, "\tprintm(%scontents[slot].fld%d", + buf, i); + if (q->mtp[i]) + { fprintf(fd, ", \"%s\"", q->mtp[i]); + } else + { fprintf(fd, ", 0"); + } + } else + { fprintf(fd, "\tprintf(\"%%d,\", %scontents[slot].fld%d", + buf, i); + } + fprintf(fd, ");\n\t\t"); + } + fprintf(fd, " printf(\"],\");\n\t\t"); + fprintf(fd, "}\n\t\t"); + fprintf(fd, "break;\n"); + } + fprintf(fd, " }\n"); + fprintf(fd, " printf(\"\\n\");\n}\n"); } void -c_var(FILE *fd, char *pref, Symbol *sp) -{ char *ptr, buf[256]; - int i; - - if (!sp) - { fatal("cannot happen - c_var", 0); - } - - ptr = sp->name; - if (!old_scope_rules) - { while (*ptr == '_' || isdigit((int)*ptr)) - { ptr++; - } } - - switch (sp->type) { - case STRUCT: - /* c_struct(fd, pref, sp); */ - fprintf(fd, "\t\tprintf(\"\t(struct %s)\\n\");\n", - sp->name); - sprintf(buf, "%s%s.", pref, sp->name); - c_struct(fd, buf, sp); - break; - case MTYPE: - case BIT: case BYTE: - case SHORT: case INT: - case UNSIGNED: - sputtype(buf, sp->type); - if (sp->nel == 1 && sp->isarray == 0) - { - if (sp->type == MTYPE && ismtype(sp->name)) - { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n", - buf, ptr, ismtype(sp->name)); - } else - { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n", - buf, ptr, pref, sp->name); - } - } else - { fprintf(fd, "\t{\tint l_in; /* 1 */\n"); - fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel); - fprintf(fd, "\t\t{\n"); - fprintf(fd, "\t\t\tprintf(\"\t%s %s[%%d]:\t%%d\\n\", l_in, %s%s[l_in]);\n", - buf, ptr, pref, sp->name); - fprintf(fd, "\t\t}\n"); - fprintf(fd, "\t}\n"); - } - break; - case CHAN: - if (sp->nel == 1 && sp->isarray == 0) - { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ", ptr); - fprintf(fd, "%s%s, q_len(%s%s));\n", - pref, sp->name, pref, sp->name); - fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name); - } else - for (i = 0; i < sp->nel; i++) - { fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ", - ptr, i); - fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n", - pref, sp->name, i, pref, sp->name, i); - fprintf(fd, "\tc_chandump(%s%s[%d]);\n", - pref, sp->name, i); - } - break; - } +c_var(FILE *fd, const char *pref, Symbol *sp) +{ char *ptr, buf[256]; + int i; + + if (!sp) + { fatal("cannot happen - c_var", 0); + } + + ptr = sp->name; + if (!old_scope_rules) + { while (*ptr == '_' || isdigit((int)*ptr)) + { ptr++; + } } + + switch (sp->type) { + case STRUCT: + /* c_struct(fd, pref, sp); */ + fprintf(fd, "\t\tprintf(\"\t(struct %s)\\n\");\n", + sp->name); + sprintf(buf, "%s%s.", pref, sp->name); + c_struct(fd, buf, sp); + break; + case MTYPE: + case BIT: case BYTE: + case SHORT: case INT: + case UNSIGNED: + sputtype(buf, sp->type); + if (sp->nel == 1 && sp->isarray == 0) + { + if (sp->type == MTYPE && ismtype(sp->name)) + { fprintf(fd, "\tprintf(\"\t%s %s:\t%d\\n\");\n", + buf, ptr, ismtype(sp->name)); + } else + { fprintf(fd, "\tprintf(\"\t%s %s:\t%%d\\n\", %s%s);\n", + buf, ptr, pref, sp->name); + } + } else + { fprintf(fd, "\t{\tint l_in; /* 1 */\n"); + fprintf(fd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", sp->nel); + fprintf(fd, "\t\t{\n"); + fprintf(fd, "\t\t\tprintf(\"\t%s %s[%%d]:\t%%d\\n\", l_in, %s%s[l_in]);\n", + buf, ptr, pref, sp->name); + fprintf(fd, "\t\t}\n"); + fprintf(fd, "\t}\n"); + } + break; + case CHAN: + if (sp->nel == 1 && sp->isarray == 0) + { fprintf(fd, "\tprintf(\"\tchan %s (=%%d):\tlen %%d:\\t\", ", ptr); + fprintf(fd, "%s%s, q_len(%s%s));\n", + pref, sp->name, pref, sp->name); + fprintf(fd, "\tc_chandump(%s%s);\n", pref, sp->name); + } else + for (i = 0; i < sp->nel; i++) + { fprintf(fd, "\tprintf(\"\tchan %s[%d] (=%%d):\tlen %%d:\\t\", ", + ptr, i); + fprintf(fd, "%s%s[%d], q_len(%s%s[%d]));\n", + pref, sp->name, i, pref, sp->name, i); + fprintf(fd, "\tc_chandump(%s%s[%d]);\n", + pref, sp->name, i); + } + break; + } } int c_splurge_any(ProcList *p) -{ Ordered *walk; - Symbol *sp; - - if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (!sp->context - || sp->type == 0 - || strcmp(sp->context->name, p->n->name) != 0 - || sp->owner || (sp->hidden&1) - || (sp->type == MTYPE && ismtype(sp->name))) - continue; - - return 1; - } - return 0; +{ Ordered *walk; + Symbol *sp; + + if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (!sp->context + || sp->type == 0 + || strcmp(sp->context->name, p->n->name) != 0 + || sp->owner || (sp->hidden&1) + || (sp->type == MTYPE && ismtype(sp->name))) + continue; + + return 1; + } + return 0; } void c_splurge(FILE *fd, ProcList *p) -{ Ordered *walk; - Symbol *sp; - char pref[64]; - - if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (!sp->context - || sp->type == 0 - || strcmp(sp->context->name, p->n->name) != 0 - || sp->owner || (sp->hidden&1) - || (sp->type == MTYPE && ismtype(sp->name))) - continue; - - sprintf(pref, "((P%d *)pptr(pid))->", p->tn); - c_var(fd, pref, sp); - } +{ Ordered *walk; + Symbol *sp; + char pref[64]; + + if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (!sp->context + || sp->type == 0 + || strcmp(sp->context->name, p->n->name) != 0 + || sp->owner || (sp->hidden&1) + || (sp->type == MTYPE && ismtype(sp->name))) + continue; + + sprintf(pref, "((P%d *)pptr(pid))->", p->tn); + c_var(fd, pref, sp); + } } void -c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */ -{ Ordered *walk; - ProcList *p; - Symbol *sp; - Mtypes_t *lst; - Lextok *n; - int j; - extern Mtypes_t *Mtypes; - - fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n"); - fprintf(fd, " printf(\"global vars:\\n\");\n"); - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp->context || sp->owner || (sp->hidden&1)) - continue; - c_var(fd, "now.", sp); - } - fprintf(fd, "}\n"); - - fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n"); - fprintf(fd, " switch(tp) {\n"); - for (p = ready; p; p = p->nxt) - { fprintf(fd, " case %d:\n", p->tn); - if (c_splurge_any(p)) - { fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n", - p->n->name); - c_splurge(fd, p); - } else - { fprintf(fd, " \t/* none */\n"); - } - fprintf(fd, " \tbreak;\n"); - } - fprintf(fd, " }\n}\n"); - - fprintf(fd, "void\nprintm(int x, char *s)\n{\n"); - fprintf(fd, " if (!s) { s = \"_unnamed_\"; }\n"); - for (lst = Mtypes; lst; lst = lst->nxt) - { fprintf(fd, " if (strcmp(s, \"%s\") == 0)\n", lst->nm); - fprintf(fd, " switch (x) {\n"); - for (n = lst->mt, j = 1; n && j; n = n->rgt, j++) - fprintf(fd, "\tcase %d: Printf(\"%s\"); return;\n", - j, n->lft->sym->name); - fprintf(fd, " default: Printf(\"%%d\", x); return;\n"); - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); +c_wrapper(FILE *fd) /* allow pan.c to print out global sv entries */ +{ Ordered *walk; + ProcList *p; + Symbol *sp; + Mtypes_t *lst; + Lextok *n; + int j; + extern Mtypes_t *Mtypes; + + fprintf(fd, "void\nc_globals(void)\n{\t/* int i; */\n"); + fprintf(fd, " printf(\"global vars:\\n\");\n"); + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp->context || sp->owner || (sp->hidden&1)) + continue; + c_var(fd, "now.", sp); + } + fprintf(fd, "}\n"); + + fprintf(fd, "void\nc_locals(int pid, int tp)\n{\t/* int i; */\n"); + fprintf(fd, " switch(tp) {\n"); + for (p = ready; p; p = p->nxt) + { fprintf(fd, " case %d:\n", p->tn); + if (c_splurge_any(p)) + { fprintf(fd, " \tprintf(\"local vars proc %%d (%s):\\n\", pid);\n", + p->n->name); + c_splurge(fd, p); + } else + { fprintf(fd, " \t/* none */\n"); + } + fprintf(fd, " \tbreak;\n"); + } + fprintf(fd, " }\n}\n"); + + fprintf(fd, "void\nprintm(int x, char *s)\n{\n"); + fprintf(fd, " if (!s) { s = \"_unnamed_\"; }\n"); + for (lst = Mtypes; lst; lst = lst->nxt) + { fprintf(fd, " if (strcmp(s, \"%s\") == 0)\n", lst->nm); + fprintf(fd, " switch (x) {\n"); + for (n = lst->mt, j = 1; n && j; n = n->rgt, j++) + fprintf(fd, "\tcase %d: Printf(\"%s\"); return;\n", + j, n->lft->sym->name); + fprintf(fd, " default: Printf(\"%%d\", x); return;\n"); + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); } static int -doglobal(char *pre, int dowhat) -{ Ordered *walk; - Symbol *sp; - int j, cnt = 0; - - for (j = 0; j < 8; j++) - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (!sp->context - && !sp->owner - && sp->type == Types[j]) - { if (Types[j] != MTYPE || !ismtype(sp->name)) - switch (dowhat) { - case LOGV: - if (sp->type == CHAN - && verbose == 0) - break; - if (sp->hidden&1) - break; - do_var(fd_tc, dowhat, "", sp, - pre, "\", now.", ");\n"); - break; - case INIV: - checktype(sp, (char *) 0); - cnt++; /* fall through */ - case PUTV: - do_var(fd_tc, dowhat, - (sp->hidden&1)?"":"now.", sp, - "", " = ", ";\n"); - break; - } } } - return cnt; +doglobal(const char *pre, int dowhat) +{ Ordered *walk; + Symbol *sp; + int j, cnt = 0; + + for (j = 0; j < 8; j++) + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (!sp->context + && !sp->owner + && sp->type == Types[j]) + { if (Types[j] != MTYPE || !ismtype(sp->name)) + switch (dowhat) { + case LOGV: + if (sp->type == CHAN + && verbose == 0) + break; + if (sp->hidden&1) + break; + do_var(fd_tc, dowhat, "", sp, + pre, "\", now.", ");\n"); + break; + case INIV: + checktype(sp, (char *) 0); + cnt++; /* fall through */ + case PUTV: + do_var(fd_tc, dowhat, + (sp->hidden&1)?"":"now.", sp, + "", " = ", ";\n"); + break; + } } } + return cnt; } static void dohidden(void) -{ Ordered *walk; - Symbol *sp; - int j; - - for (j = 0; j < 8; j++) - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if ((sp->hidden&1) - && sp->type == Types[j]) - { if (sp->context || sp->owner) - fatal("cannot hide non-globals (%s)", sp->name); - if (sp->type == CHAN) - fatal("cannot hide channels (%s)", sp->name); - fprintf(fd_th, "/* hidden variable: */"); - typ2c(sp); - } } +{ Ordered *walk; + Symbol *sp; + int j; + + for (j = 0; j < 8; j++) + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if ((sp->hidden&1) + && sp->type == Types[j]) + { if (sp->context || sp->owner) + fatal("cannot hide non-globals (%s)", sp->name); + if (sp->type == CHAN) + fatal("cannot hide channels (%s)", sp->name); + fprintf(fd_th, "/* hidden variable: */"); + typ2c(sp); + } } } void -do_var(FILE *ofd, int dowhat, char *s, Symbol *sp, - char *pre, char *sep, char *ter) -{ int i; - char *ptr = sp?sp->name:""; - - if (!sp) - { fatal("cannot happen - do_var", 0); - } - - switch(dowhat) { - case PUTV: - if (sp->hidden&1) break; - typ2c(sp); - break; - - case LOGV: - if (!old_scope_rules) - { while (*ptr == '_' || isdigit((int)*ptr)) - { ptr++; - } } - /* fall thru */ - case INIV: - if (sp->type == STRUCT) - { /* struct may contain a chan */ - walk_struct(ofd, dowhat, s, sp, pre, sep, ter); - break; - } - if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */ - break; - if (sp->nel == 1 && sp->isarray == 0) - { if (dowhat == LOGV) - { fprintf(ofd, "\t\t%s%s%s%s", - pre, s, ptr, sep); - fprintf(ofd, "%s%s", s, sp->name); - } else - { fprintf(ofd, "\t\t%s%s%s%s", - pre, s, sp->name, sep); - do_init(ofd, sp); - } - fprintf(ofd, "%s", ter); - } else - { if (sp->ini && sp->ini->ntyp == CHAN) - { for (i = 0; i < sp->nel; i++) - { fprintf(ofd, "\t\t%s%s%s[%d]%s", - pre, s, sp->name, i, sep); - if (dowhat == LOGV) - fprintf(ofd, "%s%s[%d]", - s, sp->name, i); - else - do_init(ofd, sp); - fprintf(ofd, "%s", ter); - } - } else if (sp->ini) - { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',') - { Lextok *z, *y; - z = sp->ini; - for (i = 0; i < sp->nel; i++) - { if (z && z->ntyp == ',') - { y = z->lft; - z = z->rgt; - } else - { y = z; - } - fprintf(ofd, "\t\t%s%s%s[%d]%s", - pre, s, sp->name, i, sep); - putstmnt(ofd, y, 0); - fprintf(ofd, "%s", ter); - } - } else - { fprintf(ofd, "\t{\tint l_in; /* 2 */\n"); - fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", - sp->nel); - fprintf(ofd, "\t\t{\n"); - fprintf(ofd, "\t\t\t%s%s%s[l_in]%s", - pre, s, sp->name, sep); - if (dowhat == LOGV) - { fprintf(ofd, "%s%s[l_in]", s, sp->name); - } else - { putstmnt(ofd, sp->ini, 0); - } - fprintf(ofd, "%s", ter); - fprintf(ofd, "\t\t}\n"); - fprintf(ofd, "\t}\n"); - } } } - break; - } +do_var(FILE *ofd, int dowhat, const char *s, Symbol *sp, + const char *pre, const char *sep, const char *ter) +{ int i; + const char *ptr = sp?sp->name:""; + + if (!sp) + { fatal("cannot happen - do_var", 0); + } + + switch(dowhat) { + case PUTV: + if (sp->hidden&1) break; + typ2c(sp); + break; + + case LOGV: + if (!old_scope_rules) + { while (*ptr == '_' || isdigit((int)*ptr)) + { ptr++; + } } + /* fall thru */ + case INIV: + if (sp->type == STRUCT) + { /* struct may contain a chan */ + walk_struct(ofd, dowhat, s, sp, pre, sep, ter); + break; + } + if (!sp->ini && dowhat != LOGV) /* it defaults to 0 */ + break; + if (sp->nel == 1 && sp->isarray == 0) + { if (dowhat == LOGV) + { fprintf(ofd, "\t\t%s%s%s%s", + pre, s, ptr, sep); + fprintf(ofd, "%s%s", s, sp->name); + } else + { fprintf(ofd, "\t\t%s%s%s%s", + pre, s, sp->name, sep); + do_init(ofd, sp); + } + fprintf(ofd, "%s", ter); + } else + { if (sp->ini && sp->ini->ntyp == CHAN) + { for (i = 0; i < sp->nel; i++) + { fprintf(ofd, "\t\t%s%s%s[%d]%s", + pre, s, sp->name, i, sep); + if (dowhat == LOGV) + fprintf(ofd, "%s%s[%d]", + s, sp->name, i); + else + do_init(ofd, sp); + fprintf(ofd, "%s", ter); + } + } else if (sp->ini) + { if (dowhat != LOGV && sp->isarray && sp->ini->ntyp == ',') + { Lextok *z, *y; + z = sp->ini; + for (i = 0; i < sp->nel; i++) + { if (z && z->ntyp == ',') + { y = z->lft; + z = z->rgt; + } else + { y = z; + } + fprintf(ofd, "\t\t%s%s%s[%d]%s", + pre, s, sp->name, i, sep); + putstmnt(ofd, y, 0); + fprintf(ofd, "%s", ter); + } + } else + { fprintf(ofd, "\t{\tint l_in; /* 2 */\n"); + fprintf(ofd, "\t\tfor (l_in = 0; l_in < %d; l_in++)\n", + sp->nel); + fprintf(ofd, "\t\t{\n"); + fprintf(ofd, "\t\t\t%s%s%s[l_in]%s", + pre, s, sp->name, sep); + if (dowhat == LOGV) + { fprintf(ofd, "%s%s[l_in]", s, sp->name); + } else + { putstmnt(ofd, sp->ini, 0); + } + fprintf(ofd, "%s", ter); + fprintf(ofd, "\t\t}\n"); + fprintf(ofd, "\t}\n"); + } } } + break; + } } static void do_init(FILE *ofd, Symbol *sp) -{ int i; - - if (sp->ini - && sp->type == CHAN - && ((i = qmake(sp)) > 0)) - { if (sp->ini->ntyp == CHAN) - { fprintf(ofd, "addqueue(calling_pid, %d, %d)", - i, ltab[i-1]->nslots == 0); - } else - { fprintf(ofd, "%d", i); - } - } else - { putstmnt(ofd, sp->ini, 0); - } +{ int i; + + if (sp->ini + && sp->type == CHAN + && ((i = qmake(sp)) > 0)) + { if (sp->ini->ntyp == CHAN) + { fprintf(ofd, "addqueue(calling_pid, %d, %d)", + i, ltab[i-1]->nslots == 0); + } else + { fprintf(ofd, "%d", i); + } + } else + { putstmnt(ofd, sp->ini, 0); + } } static void -put_ptype(char *s, int i, int m0, int m1, enum btypes b) -{ int k; - - if (b == I_PROC) - { fprintf(fd_th, "#define Pinit ((P%d *)_this)\n", i); - } else if (b == P_PROC || b == A_PROC) - { fprintf(fd_th, "#define P%s ((P%d *)_this)\n", s, i); - } - - fprintf(fd_th, "typedef struct P%d { /* %s */\n", i, s); - fprintf(fd_th, " unsigned _pid : 8; /* 0..255 */\n"); - fprintf(fd_th, " unsigned _t : %d; /* proctype */\n", blog(m1)); - fprintf(fd_th, " unsigned _p : %d; /* state */\n", blog(m0)); - fprintf(fd_th, "#ifdef HAS_PRIORITY\n"); - fprintf(fd_th, " unsigned _priority : 8; /* 0..255 */\n"); - fprintf(fd_th, "#endif\n"); - LstSet = ZS; - nBits = 8 + blog(m1) + blog(m0); - k = dolocal(fd_tc, "", PUTV, i, s, b); /* includes pars */ - c_add_loc(fd_th, s); - - fprintf(fd_th, "} P%d;\n", i); - if ((!LstSet && k > 0) || has_state) - fprintf(fd_th, "#define Air%d 0\n\n", i); - else if (LstSet || k == 0) /* 5.0, added condition */ - { fprintf(fd_th, "#define Air%d (sizeof(P%d) - ", i, i); - if (k == 0) - { fprintf(fd_th, "%d", (nBits+7)/8); - goto done; - } - if ((LstSet->type != BIT && LstSet->type != UNSIGNED) - || LstSet->nel != 1) - { fprintf(fd_th, "Offsetof(P%d, %s) - %d*sizeof(", - i, LstSet->name, LstSet->nel); - } - switch(LstSet->type) { - case UNSIGNED: - fprintf(fd_th, "%d", (nBits+7)/8); - break; - case BIT: - if (LstSet->nel == 1) - { fprintf(fd_th, "%d", (nBits+7)/8); - break; - } /* else fall through */ - case MTYPE: case BYTE: case CHAN: - fprintf(fd_th, "uchar)"); break; - case SHORT: - fprintf(fd_th, "short)"); break; - case INT: - fprintf(fd_th, "int)"); break; - default: - fatal("cannot happen Air %s", - LstSet->name); - } -done: fprintf(fd_th, ")\n\n"); - } +put_ptype(const char *s, int i, int m0, int m1, enum btypes b) +{ int k; + + if (b == I_PROC) + { fprintf(fd_th, "#define Pinit ((P%d *)_this)\n", i); + } else if (b == P_PROC || b == A_PROC) + { fprintf(fd_th, "#define P%s ((P%d *)_this)\n", s, i); + } + + fprintf(fd_th, "typedef struct P%d { /* %s */\n", i, s); + fprintf(fd_th, " unsigned _pid : 8; /* 0..255 */\n"); + fprintf(fd_th, " unsigned _t : %d; /* proctype */\n", blog(m1)); + fprintf(fd_th, " unsigned _p : %d; /* state */\n", blog(m0)); + fprintf(fd_th, "#ifdef HAS_PRIORITY\n"); + fprintf(fd_th, " unsigned _priority : 8; /* 0..255 */\n"); + fprintf(fd_th, "#endif\n"); + LstSet = ZS; + nBits = 8 + blog(m1) + blog(m0); + k = dolocal(fd_tc, "", PUTV, i, s, b); /* includes pars */ + c_add_loc(fd_th, s); + + fprintf(fd_th, "} P%d;\n", i); + if ((!LstSet && k > 0) || has_state) + fprintf(fd_th, "#define Air%d 0\n\n", i); + else if (LstSet || k == 0) /* 5.0, added condition */ + { fprintf(fd_th, "#define Air%d (sizeof(P%d) - ", i, i); + if (k == 0) + { fprintf(fd_th, "%d", (nBits+7)/8); + goto done; + } + if ((LstSet->type != BIT && LstSet->type != UNSIGNED) + || LstSet->nel != 1) + { fprintf(fd_th, "Offsetof(P%d, %s) - %d*sizeof(", + i, LstSet->name, LstSet->nel); + } + switch(LstSet->type) { + case UNSIGNED: + fprintf(fd_th, "%d", (nBits+7)/8); + break; + case BIT: + if (LstSet->nel == 1) + { fprintf(fd_th, "%d", (nBits+7)/8); + break; + } /* else fall through */ + case MTYPE: case BYTE: case CHAN: + fprintf(fd_th, "uchar)"); break; + case SHORT: + fprintf(fd_th, "short)"); break; + case INT: + fprintf(fd_th, "int)"); break; + default: + fatal("cannot happen Air %s", + LstSet->name); + } +done: fprintf(fd_th, ")\n\n"); + } } static void tc_predef_np(void) { - fprintf(fd_th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */ - - fprintf(fd_th, "#define _nstates%d 3 /* np_ */\n", nrRdy); - fprintf(fd_th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy); - fprintf(fd_th, "#define _start%d 0 /* np_ */\n", nrRdy); - - fprintf(fd_tc, "\tcase %d: /* np_ */\n", nrRdy); - if (separate == 1) - { fprintf(fd_tc, "\t\tini_claim(%d, h);\n", nrRdy); - } else - { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy); - - fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy); - fprintf(fd_tc, "#endif\n"); - - fprintf(fd_tc, "\t\treached%d[0] = 1;\n", nrRdy); - fprintf(fd_tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy); - } - fprintf(fd_tc, "\t\tbreak;\n"); + fprintf(fd_th, "#define _NP_ %d\n", nrRdy); /* 1+ highest proctype nr */ + + fprintf(fd_th, "#define _nstates%d 3 /* np_ */\n", nrRdy); + fprintf(fd_th, "#define _endstate%d 2 /* np_ */\n\n", nrRdy); + fprintf(fd_th, "#define _start%d 0 /* np_ */\n", nrRdy); + + fprintf(fd_tc, "\tcase %d: /* np_ */\n", nrRdy); + if (separate == 1) + { fprintf(fd_tc, "\t\tini_claim(%d, h);\n", nrRdy); + } else + { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", nrRdy, nrRdy); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = 0;\n", nrRdy); + + fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority;\n", nrRdy); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "\t\treached%d[0] = 1;\n", nrRdy); + fprintf(fd_tc, "\t\taccpstate[%d][1] = 1;\n", nrRdy); + } + fprintf(fd_tc, "\t\tbreak;\n"); } static void multi_init(void) -{ ProcList *p; - Element *e; - int i = nrRdy+1; - int ini, j; - int nrc = nclaims; - - fprintf(fd_tc, "#ifndef NOCLAIM\n"); - fprintf(fd_tc, "\tcase %d: /* claim select */\n", i); - for (p = ready, j = 0; p; p = p->nxt, j++) - { if (p->b == N_CLAIM) - { e = p->s->frst; - ini = huntele(e, e->status, -1)->seqno; - - fprintf(fd_tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n", - j, p->tn, p->n->name); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n", - i, j, ini); - fprintf(fd_tc, "\t\treached%d[%d]=1;\n", p->tn, ini); - - /* the default initial claim is first one in model */ - if (--nrc == 0) - { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n", - i, j, p->n->name); - fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", p->tn); - fprintf(fd_tc, "#ifndef BFS\n"); - fprintf(fd_tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n"); - fprintf(fd_tc, "\t\t\tprintf(\"pan: ltl formula %s\\n\");\n", - p->n->name); - fprintf(fd_tc, "#endif\n"); - } - } } - fprintf(fd_tc, "\t\tif (whichclaim != -1)\n"); - fprintf(fd_tc, "\t\t{ select_claim(whichclaim);\n"); - fprintf(fd_tc, "\t\t}\n"); - fprintf(fd_tc, "\t\tbreak;\n\n"); - fprintf(fd_tc, "#endif\n"); +{ ProcList *p; + Element *e; + int i = nrRdy+1; + int ini, j; + int nrc = nclaims; + + fprintf(fd_tc, "#ifndef NOCLAIM\n"); + fprintf(fd_tc, "\tcase %d: /* claim select */\n", i); + for (p = ready, j = 0; p; p = p->nxt, j++) + { if (p->b == N_CLAIM) + { e = p->s->frst; + ini = huntele(e, e->status, -1)->seqno; + + fprintf(fd_tc, "\t\tspin_c_typ[%d] = %d; /* %s */\n", + j, p->tn, p->n->name); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->c_cur[%d] = %d;\n", + i, j, ini); + fprintf(fd_tc, "\t\treached%d[%d]=1;\n", p->tn, ini); + + /* the default initial claim is first one in model */ + if (--nrc == 0) + { fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, p->tn); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_n = %d; /* %s */\n", + i, j, p->n->name); + fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", p->tn); + fprintf(fd_tc, "#ifndef BFS\n"); + fprintf(fd_tc, "\t\tif (whichclaim == -1 && claimname == NULL)\n"); + fprintf(fd_tc, "\t\t\tprintf(\"pan: ltl formula %s\\n\");\n", + p->n->name); + fprintf(fd_tc, "#endif\n"); + } + } } + fprintf(fd_tc, "\t\tif (whichclaim != -1)\n"); + fprintf(fd_tc, "\t\t{ select_claim(whichclaim);\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n\n"); + fprintf(fd_tc, "#endif\n"); } static void put_pinit(ProcList *P) -{ Lextok *fp, *fpt, *t; - Element *e = P->s->frst; - Symbol *s = P->n; - Lextok *p = P->p; - int i = P->tn; - int ini, j, k; - - if (pid_is_claim(i) - && separate == 1) - { fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); - fprintf(fd_tc, "\t\tini_claim(%d, h);\n", i); - fprintf(fd_tc, "\t\tbreak;\n"); - return; - } - if (!pid_is_claim(i) - && separate == 2) - return; - - ini = huntele(e, e->status, -1)->seqno; - fprintf(fd_th, "#define _start%d %d\n", i, ini); - if (i == eventmapnr) - fprintf(fd_th, "#define start_event %d\n", ini); - - fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); - - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i); - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); - fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); - - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n", - i, (P->priority<1)? 1 : P->priority); - - fprintf(fd_tc, "#endif\n"); - fprintf(fd_tc, "\t\treached%d[%d]=1;\n", i, ini); - if (P->b == N_CLAIM) - { fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", i); - } - - if (has_provided) - { fprintf(fd_tt, "\tcase %d: /* %s */\n\t\t", i, s->name); - if (P->prov) - { fprintf(fd_tt, "if ("); - putstmnt(fd_tt, P->prov, 0); - fprintf(fd_tt, ")\n\t\t\t"); - } - fprintf(fd_tt, "return 1;\n"); - if (P->prov) - fprintf(fd_tt, "\t\tbreak;\n"); - } - - fprintf(fd_tc, "\t\t/* params: */\n"); - for (fp = p, j=0; fp; fp = fp->rgt) - for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++) - { t = (fpt->ntyp == ',') ? fpt->lft : fpt; - if (t->sym->nel > 1 || t->sym->isarray) - { lineno = t->ln; - Fname = t->fn; - fatal("array in parameter list, %s", - t->sym->name); - } - fprintf(fd_tc, "\t\t((P%d *)pptr(h))->", i); - if (t->sym->type == STRUCT) - { if (full_name(fd_tc, t, t->sym, 1)) - { lineno = t->ln; - Fname = t->fn; - fatal("hidden array in parameter %s", - t->sym->name); - } - } else - fprintf(fd_tc, "%s", t->sym->name); - fprintf(fd_tc, " = par%d;\n", j); - } - fprintf(fd_tc, "\t\t/* locals: */\n"); - k = dolocal(fd_tc, "", INIV, i, s->name, P->b); - if (k > 0) - { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); - (void) dolocal(fd_tc, "logval(\"", LOGV, i, s->name, P->b); - fprintf(fd_tc, "#endif\n"); - } - - fprintf(fd_tc, "#ifdef HAS_CODE\n"); - fprintf(fd_tc, "\t\tlocinit%d(h);\n", i); - fprintf(fd_tc, "#endif\n"); - - dumpclaims(fd_tc, i, s->name); - fprintf(fd_tc, "\t break;\n"); +{ Lextok *fp, *fpt, *t; + Element *e = P->s->frst; + Symbol *s = P->n; + Lextok *p = P->p; + int i = P->tn; + int ini, j, k; + + if (pid_is_claim(i) + && separate == 1) + { fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); + fprintf(fd_tc, "\t\tini_claim(%d, h);\n", i); + fprintf(fd_tc, "\t\tbreak;\n"); + return; + } + if (!pid_is_claim(i) + && separate == 2) + return; + + ini = huntele(e, e->status, -1)->seqno; + fprintf(fd_th, "#define _start%d %d\n", i, ini); + if (i == eventmapnr) + fprintf(fd_th, "#define start_event %d\n", ini); + + fprintf(fd_tc, "\tcase %d: /* %s */\n", i, s->name); + + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_t = %d;\n", i, i); + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_p = %d;\n", i, ini); + fprintf(fd_tc, "#ifdef HAS_PRIORITY\n"); + + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->_priority = priority; /* was: %d */\n", + i, (P->priority<1)? 1 : P->priority); + + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\t\treached%d[%d]=1;\n", i, ini); + if (P->b == N_CLAIM) + { fprintf(fd_tc, "\t\tsrc_claim = src_ln%d;\n", i); + } + + if (has_provided) + { fprintf(fd_tt, "\tcase %d: /* %s */\n\t\t", i, s->name); + if (P->prov) + { fprintf(fd_tt, "if ("); + putstmnt(fd_tt, P->prov, 0); + fprintf(fd_tt, ")\n\t\t\t"); + } + fprintf(fd_tt, "return 1;\n"); + if (P->prov) + fprintf(fd_tt, "\t\tbreak;\n"); + } + + fprintf(fd_tc, "\t\t/* params: */\n"); + for (fp = p, j=0; fp; fp = fp->rgt) + for (fpt = fp->lft; fpt; fpt = fpt->rgt, j++) + { t = (fpt->ntyp == ',') ? fpt->lft : fpt; + if (t->sym->nel > 1 || t->sym->isarray) + { lineno = t->ln; + Fname = t->fn; + fatal("array in parameter list, %s", + t->sym->name); + } + fprintf(fd_tc, "\t\t((P%d *)pptr(h))->", i); + if (t->sym->type == STRUCT) + { if (full_name(fd_tc, t, t->sym, 1)) + { lineno = t->ln; + Fname = t->fn; + fatal("hidden array in parameter %s", + t->sym->name); + } + } else + fprintf(fd_tc, "%s", t->sym->name); + fprintf(fd_tc, " = par%d;\n", j); + } + fprintf(fd_tc, "\t\t/* locals: */\n"); + k = dolocal(fd_tc, "", INIV, i, s->name, P->b); + if (k > 0) + { fprintf(fd_tc, "#ifdef VAR_RANGES\n"); + (void) dolocal(fd_tc, "logval(\"", LOGV, i, s->name, P->b); + fprintf(fd_tc, "#endif\n"); + } + + fprintf(fd_tc, "#ifdef HAS_CODE\n"); + fprintf(fd_tc, "\t\tlocinit%d(h);\n", i); + fprintf(fd_tc, "#endif\n"); + + dumpclaims(fd_tc, i, s->name); + fprintf(fd_tc, "\t break;\n"); } Element * huntstart(Element *f) -{ Element *e = f; - Element *elast = (Element *) 0; - int cnt = 0; - - while (elast != e && cnt++ < 200) /* new 4.0.8 */ - { elast = e; - if (e->n) - { if (e->n->ntyp == '.' && e->nxt) - e = e->nxt; - else if (e->n->ntyp == UNLESS) - e = e->sub->this->frst; - } } - - if (cnt >= 200 || !e) - { lineno = (f && f->n)?f->n->ln:lineno; - fatal("confusing control. structure", (char *) 0); - } - return e; +{ Element *e = f; + Element *elast = (Element *) 0; + int cnt = 0; + + while (elast != e && cnt++ < 200) /* new 4.0.8 */ + { elast = e; + if (e->n) + { if (e->n->ntyp == '.' && e->nxt) + e = e->nxt; + else if (e->n->ntyp == UNLESS) + e = e->sub->thisS->frst; + } } + + if (cnt >= 200 || !e) + { lineno = (f && f->n)?f->n->ln:lineno; + fatal("confusing control. structure", (char *) 0); + } + return e; } Element * huntele(Element *f, unsigned int o, int stopat) -{ Element *g, *e = f; - int cnt=0; /* a precaution against loops */ - - if (e) - for ( ; cnt < 500 && e->n; cnt++) - { - if (e->seqno == stopat) - break; - - switch (e->n->ntyp) { - case GOTO: - g = get_lab(e->n,1); - if (e == g) - { lineno = (f && f->n)?f->n->ln:lineno; - fatal("infinite goto loop", (char *) 0); - } - cross_dsteps(e->n, g->n); - break; - case '.': - case BREAK: - if (!e->nxt) - return e; - g = e->nxt; - break; - case UNLESS: - g = huntele(e->sub->this->frst, o, stopat); - if (!g) - { fatal("unexpected error 1", (char *) 0); - } - break; - case D_STEP: - case ATOMIC: - case NON_ATOMIC: - default: - return e; - } - if ((o & ATOM) && !(g->status & ATOM)) - return e; - e = g; - } - if (cnt >= 500 || !e) - { lineno = (f && f->n)?f->n->ln:lineno; - fatal("confusing control structure", (char *) 0); - } - return e; +{ Element *g, *e = f; + int cnt=0; /* a precaution against loops */ + + if (e) + for ( ; cnt < 500 && e->n; cnt++) + { + if (e->seqno == stopat) + break; + + switch (e->n->ntyp) { + case GOTO: + g = get_lab(e->n,1); + if (e == g) + { lineno = (f && f->n)?f->n->ln:lineno; + fatal("infinite goto loop", (char *) 0); + } + cross_dsteps(e->n, g->n); + break; + case '.': + case BREAK: + if (!e->nxt) + return e; + g = e->nxt; + break; + case UNLESS: + g = huntele(e->sub->thisS->frst, o, stopat); + if (!g) + { fatal("unexpected error 1", (char *) 0); + } + break; + case D_STEP: + case ATOMIC: + case NON_ATOMIC: + default: + return e; + } + if ((o & ATOM) && !(g->status & ATOM)) + return e; + e = g; + } + if (cnt >= 500 || !e) + { lineno = (f && f->n)?f->n->ln:lineno; + fatal("confusing control structure", (char *) 0); + } + return e; } void typ2c(Symbol *sp) -{ int wsbits = sizeof(long)*8; /* wordsize in bits */ - switch (sp->type) { - case UNSIGNED: - if (sp->hidden&1) - fprintf(fd_th, "\tuchar %s;", sp->name); - else - fprintf(fd_th, "\tunsigned %s : %d", - sp->name, sp->nbits); - LstSet = sp; - if (nBits%wsbits > 0 - && wsbits - nBits%wsbits < sp->nbits) - { /* must padd to a word-boundary */ - nBits += wsbits - nBits%wsbits; - } - nBits += sp->nbits; - break; - case BIT: - if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1)) - { fprintf(fd_th, "\tunsigned %s : 1", sp->name); - LstSet = sp; - nBits++; - break; - } /* else fall through */ - if (!(sp->hidden&1) && (verbose&32)) - printf("spin: warning: bit-array %s[%d] mapped to byte-array\n", - sp->name, sp->nel); - nBits += 8*sp->nel; /* mapped onto array of uchars */ - case MTYPE: - case BYTE: - case CHAN: /* good for up to 255 channels */ - fprintf(fd_th, "\tuchar %s", sp->name); - LstSet = sp; - break; - case SHORT: - fprintf(fd_th, "\tshort %s", sp->name); - LstSet = sp; - break; - case INT: - fprintf(fd_th, "\tint %s", sp->name); - LstSet = sp; - break; - case STRUCT: - if (!sp->Snm) - fatal("undeclared structure element %s", sp->name); - fprintf(fd_th, "\tstruct %s %s", - sp->Snm->name, - sp->name); - LstSet = ZS; - break; - case CODE_FRAG: - case PREDEF: - return; - default: - fatal("variable %s undeclared", sp->name); - } - - if (sp->nel > 1 || sp->isarray) - fprintf(fd_th, "[%d]", sp->nel); - fprintf(fd_th, ";\n"); +{ int wsbits = sizeof(long)*8; /* wordsize in bits */ + switch (sp->type) { + case UNSIGNED: + if (sp->hidden&1) + fprintf(fd_th, "\tuchar %s;", sp->name); + else + fprintf(fd_th, "\tunsigned %s : %d", + sp->name, sp->nbits); + LstSet = sp; + if (nBits%wsbits > 0 + && wsbits - nBits%wsbits < sp->nbits) + { /* must padd to a word-boundary */ + nBits += wsbits - nBits%wsbits; + } + nBits += sp->nbits; + break; + case BIT: + if (sp->nel == 1 && sp->isarray == 0 && !(sp->hidden&1)) + { fprintf(fd_th, "\tunsigned %s : 1", sp->name); + LstSet = sp; + nBits++; + break; + } /* else fall through */ + if (!(sp->hidden&1) && (verbose&32)) + printf("spin: warning: bit-array %s[%d] mapped to byte-array\n", + sp->name, sp->nel); + nBits += 8*sp->nel; /* mapped onto array of uchars */ + /*fallthrough*/ + case MTYPE: + /*fallthrough*/ + case BYTE: + /*fallthrough*/ + case CHAN: /* good for up to 255 channels */ + fprintf(fd_th, "\tuchar %s", sp->name); + LstSet = sp; + break; + case SHORT: + fprintf(fd_th, "\tshort %s", sp->name); + LstSet = sp; + break; + case INT: + fprintf(fd_th, "\tint %s", sp->name); + LstSet = sp; + break; + case STRUCT: + if (!sp->Snm) + fatal("undeclared structure element %s", sp->name); + fprintf(fd_th, "\tstruct %s %s", + sp->Snm->name, + sp->name); + LstSet = ZS; + break; + case CODE_FRAG: + case PREDEF: + return; + default: + fatal("variable %s undeclared", sp->name); + } + + if (sp->nel > 1 || sp->isarray) + fprintf(fd_th, "[%d]", sp->nel); + fprintf(fd_th, ";\n"); } static void ncases(FILE *fd, int p, int n, int m, const char *c[]) -{ int i, j; +{ int i, j; - for (j = 0; c[j]; j++) - for (i = n; i < m; i++) - { fprintf(fd, c[j], i, p, i); - fprintf(fd, "\n"); - } + for (j = 0; c[j]; j++) + for (i = n; i < m; i++) + { fprintf(fd, c[j], i, p, i); + fprintf(fd, "\n"); + } } void qlen_type(int qmax) { - fprintf(fd_th, "\t"); - if (qmax < 256) - fprintf(fd_th, "uchar"); - else if (qmax < 65535) - fprintf(fd_th, "ushort"); - else - fprintf(fd_th, "uint"); - fprintf(fd_th, " Qlen; /* q_size */\n"); + fprintf(fd_th, "\t"); + if (qmax < 256) + fprintf(fd_th, "uchar"); + else if (qmax < 65535) + fprintf(fd_th, "ushort"); + else + fprintf(fd_th, "uint"); + fprintf(fd_th, " Qlen; /* q_size */\n"); } void genaddqueue(void) -{ char buf0[256]; - int j, qmax = 0; - Queue *q; - - ntimes(fd_tc, 0, 1, Addq0); - - if (has_io && !nrqs) - fprintf(fd_th, "#define NQS 1 /* nrqs=%d, but has_io */\n", nrqs); - else - fprintf(fd_th, "#define NQS %d\n", nrqs); - - for (q = qtab; q; q = q->nxt) - if (q->nslots > qmax) - qmax = q->nslots; - - for (q = qtab; q; q = q->nxt) - { j = q->qid; - fprintf(fd_tc, "\tcase %d: j = sizeof(Q%d);", j, j); - fprintf(fd_tc, " q_flds[%d] = %d;", j, q->nflds); - fprintf(fd_tc, " q_max[%d] = %d;", j, max(1,q->nslots)); - fprintf(fd_tc, " break;\n"); - - fprintf(fd_th, "typedef struct Q%d {\n", j); - qlen_type(qmax); /* 4.2.2 */ - fprintf(fd_th, " uchar _t; /* q_type */\n"); - fprintf(fd_th, " struct {\n"); - - for (j = 0; j < q->nflds; j++) - { switch (q->fld_width[j]) { - case BIT: - if (q->nflds != 1) - { fprintf(fd_th, "\t\tunsigned"); - fprintf(fd_th, " fld%d : 1;\n", j); - break; - } /* else fall through: smaller struct */ - case MTYPE: - case CHAN: - case BYTE: - fprintf(fd_th, "\t\tuchar fld%d;\n", j); - break; - case SHORT: - fprintf(fd_th, "\t\tshort fld%d;\n", j); - break; - case INT: - fprintf(fd_th, "\t\tint fld%d;\n", j); - break; - default: - fatal("bad channel spec", ""); - } - } - fprintf(fd_th, " } contents[%d];\n", max(1, q->nslots)); - fprintf(fd_th, "} Q%d;\n", q->qid); - } - - fprintf(fd_th, "typedef struct Q0 {\t/* generic q */\n"); - qlen_type(qmax); /* 4.2.2 */ - fprintf(fd_th, " uchar _t;\n"); - fprintf(fd_th, "} Q0;\n"); - - ntimes(fd_tc, 0, 1, Addq1); - - fprintf(fd_tc, "#ifdef TRIX\n"); - fprintf(fd_tc, "int\nwhat_p_size(int t)\n{\tint j;\n"); - fprintf(fd_tc, " switch (t) {\n"); - ntimes(fd_tc, 0, nrRdy+1, R5); /* +1 for np_ */ - fprintf(fd_tc, " default: Uerror(\"bad proctype\");\n"); - fprintf(fd_tc, " }\n return j;\n}\n\n"); - - fprintf(fd_tc, "int\nwhat_q_size(int t)\n{\tint j;\n"); - fprintf(fd_tc, " switch (t) {\n"); - for (j = 0; j < nrqs+1; j++) - { fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", j, j); - } - fprintf(fd_tc, " default: Uerror(\"bad qtype\");\n"); - fprintf(fd_tc, " }\n return j;\n}\n"); - fprintf(fd_tc, "#endif\n\n"); - - if (has_random) - { fprintf(fd_th, "int Q_has(int"); - for (j = 0; j < Mpars; j++) - fprintf(fd_th, ", int, int"); - fprintf(fd_th, ");\n"); - - fprintf(fd_tc, "int\nQ_has(int into"); - for (j = 0; j < Mpars; j++) - fprintf(fd_tc, ", int want%d, int fld%d", j, j); - fprintf(fd_tc, ")\n"); - fprintf(fd_tc, "{ int i;\n\n"); - fprintf(fd_tc, " if (!into--)\n"); - fprintf(fd_tc, " uerror(\"ref to unknown chan "); - fprintf(fd_tc, "(recv-poll)\");\n\n"); - fprintf(fd_tc, " if (into >= now._nr_qs || into < 0)\n"); - fprintf(fd_tc, " Uerror(\"qrecv bad queue#\");\n\n"); - fprintf(fd_tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;"); - fprintf(fd_tc, " i++)\n"); - fprintf(fd_tc, " {\n"); - for (j = 0; j < Mpars; j++) - { fprintf(fd_tc, " if (want%d && ", j); - fprintf(fd_tc, "qrecv(into+1, i, %d, 0) != fld%d)\n", - j, j); - fprintf(fd_tc, " continue;\n"); - } - fprintf(fd_tc, " return i+1;\n"); - fprintf(fd_tc, " }\n"); - fprintf(fd_tc, " return 0;\n"); - fprintf(fd_tc, "}\n"); - } - - fprintf(fd_tc, "#if NQS>0\n"); - fprintf(fd_tc, "void\nqsend(int into, int sorted"); - for (j = 0; j < Mpars; j++) - fprintf(fd_tc, ", int fld%d", j); - fprintf(fd_tc, ", int args_given)\n"); - ntimes(fd_tc, 0, 1, Addq11); - - for (q = qtab; q; q = q->nxt) - { sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(fd_tc, "\tcase %d:%s\n", q->qid, - (q->nslots)?"":" /* =rv= */"); - if (q->nslots == 0) /* reset handshake point */ - fprintf(fd_tc, "\t\t(trpt+2)->o_m = 0;\n"); - - if (has_sorted) - { fprintf(fd_tc, "\t\tif (!sorted) goto append%d;\n", q->qid); - fprintf(fd_tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0); - fprintf(fd_tc, "\t\t{\t/* find insertion point */\n"); - sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); - for (j = 0; j < q->nflds; j++) - { fprintf(fd_tc, "\t\t\tif (fld%d > %s%d) continue;\n", - j, buf0, j); - fprintf(fd_tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j); - fprintf(fd_tc, "goto found%d;\n\n", q->qid); - } - fprintf(fd_tc, "\t\t}\n"); - fprintf(fd_tc, "\tfound%d:\n", q->qid); - sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(fd_tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0); - fprintf(fd_tc, "\t\t{\t/* shift up */\n"); - for (j = 0; j < q->nflds; j++) - { fprintf(fd_tc, "\t\t\t%scontents[k+1].fld%d = ", - buf0, j); - fprintf(fd_tc, "%scontents[k].fld%d;\n", - buf0, j); - } - fprintf(fd_tc, "\t\t}\n"); - fprintf(fd_tc, "\tappend%d:\t/* insert in slot j */\n", q->qid); - } - - fprintf(fd_tc, "#ifdef HAS_SORTED\n"); - fprintf(fd_tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */ - fprintf(fd_tc, "#endif\n"); - fprintf(fd_tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0); - sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); - for (j = 0; j < q->nflds; j++) - { fprintf(fd_tc, "\t\t%s%d = fld%d;", buf0, j, j); - if (q->fld_width[j] == MTYPE) - { fprintf(fd_tc, "\t/* mtype %s */", - q->mtp[j]?q->mtp[j]:"_unnamed_"); - } - fprintf(fd_tc, "\n"); - } - fprintf(fd_tc, "\t\tif (args_given != %d)\n", q->nflds); - fprintf(fd_tc, "\t\t{ if (args_given > %d)\n", q->nflds); - fprintf(fd_tc, "\t\t uerror(\"too many parameters in send stmnt\");\n"); - fprintf(fd_tc, "\t\t else\n"); - fprintf(fd_tc, "\t\t uerror(\"too few parameters in send stmnt\");\n"); - fprintf(fd_tc, "\t\t}\n"); - fprintf(fd_tc, "\t\tbreak;\n"); - } - ntimes(fd_tc, 0, 1, Addq2); - - for (q = qtab; q; q = q->nxt) - fprintf(fd_tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots)); - - ntimes(fd_tc, 0, 1, Addq3); - - for (q = qtab; q; q = q->nxt) - fprintf(fd_tc, "\tcase %d: return (q_sz(from) == %d);\n", - q->qid, max(1, q->nslots)); - - ntimes(fd_tc, 0, 1, Addq4); - for (q = qtab; q; q = q->nxt) - { sprintf(buf0, "((Q%d *)z)->", q->qid); - fprintf(fd_tc, " case %d:%s\n\t\t", - q->qid, (q->nslots)?"":" /* =rv= */"); - if (q->nflds == 1) - { fprintf(fd_tc, "if (fld == 0) r = %s", buf0); - fprintf(fd_tc, "contents[slot].fld0;\n"); - } else - { fprintf(fd_tc, "switch (fld) {\n"); - ncases(fd_tc, q->qid, 0, q->nflds, R12); - fprintf(fd_tc, "\t\tdefault: Uerror"); - fprintf(fd_tc, "(\"too many fields in recv\");\n"); - fprintf(fd_tc, "\t\t}\n"); - } - fprintf(fd_tc, "\t\tif (done)\n"); - if (q->nslots == 0) - { fprintf(fd_tc, "\t\t{ j = %sQlen - 1;\n", buf0); - fprintf(fd_tc, "\t\t %sQlen = 0;\n", buf0); - sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid); - } else - { fprintf(fd_tc, "\t\t{ j = %sQlen;\n", buf0); - fprintf(fd_tc, "\t\t %sQlen = --j;\n", buf0); - fprintf(fd_tc, "\t\t for (k=slot; kcontents", q->qid); - for (j = 0; j < q->nflds; j++) - { fprintf(fd_tc, "\t%s[k].fld%d = \n", buf0, j); - fprintf(fd_tc, "\t\t%s[k+1].fld%d;\n", buf0, j); - } - fprintf(fd_tc, "\t\t }\n"); - } - - for (j = 0; j < q->nflds; j++) - fprintf(fd_tc, "%s[j].fld%d = 0;\n", buf0, j); - fprintf(fd_tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds); - fprintf(fd_tc, "\tuerror(\"missing pars in receive\");\n"); - /* incompletely received msgs cannot be unrecv'ed */ - fprintf(fd_tc, "\t\t}\n"); - fprintf(fd_tc, "\t\tbreak;\n"); - } - ntimes(fd_tc, 0, 1, Addq5); - for (q = qtab; q; q = q->nxt) - fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", - q->qid, q->qid); - ntimes(fd_tc, 0, 1, R8b); - ntimes(fd_th, 0, 1, Proto); /* function prototypes */ - - fprintf(fd_th, "void qsend(int, int"); - for (j = 0; j < Mpars; j++) - fprintf(fd_th, ", int"); - fprintf(fd_th, ", int);\n\n"); - - fprintf(fd_th, "#define Addproc(x,y) addproc(256, y, x"); - /* 256 is param outside the range of valid pids */ - for (j = 0; j < Npars; j++) - fprintf(fd_th, ", 0"); - fprintf(fd_th, ")\n"); +{ char buf0[256]; + int j, qmax = 0; + Queue *q; + + ntimes(fd_tc, 0, 1, Addq0); + + if (has_io && !nrqs) + fprintf(fd_th, "#define NQS 1 /* nrqs=%d, but has_io */\n", nrqs); + else + fprintf(fd_th, "#define NQS %d\n", nrqs); + + for (q = qtab; q; q = q->nxt) + if (q->nslots > qmax) + qmax = q->nslots; + + for (q = qtab; q; q = q->nxt) + { j = q->qid; + fprintf(fd_tc, "\tcase %d: j = sizeof(Q%d);", j, j); + fprintf(fd_tc, " q_flds[%d] = %d;", j, q->nflds); + fprintf(fd_tc, " q_max[%d] = %d;", j, MaX(1,q->nslots)); + fprintf(fd_tc, " break;\n"); + + fprintf(fd_th, "typedef struct Q%d {\n", j); + qlen_type(qmax); /* 4.2.2 */ + fprintf(fd_th, " uchar _t; /* q_type */\n"); + fprintf(fd_th, " struct {\n"); + + for (j = 0; j < q->nflds; j++) + { switch (q->fld_width[j]) { + case BIT: + if (q->nflds != 1) + { fprintf(fd_th, "\t\tunsigned"); + fprintf(fd_th, " fld%d : 1;\n", j); + break; + } /* else fall through: smaller struct */ + /*fallthrough*/ + case MTYPE: + /*fallthrough*/ + case CHAN: + /*fallthrough*/ + case BYTE: + fprintf(fd_th, "\t\tuchar fld%d;\n", j); + break; + case SHORT: + fprintf(fd_th, "\t\tshort fld%d;\n", j); + break; + case INT: + fprintf(fd_th, "\t\tint fld%d;\n", j); + break; + default: + fatal("bad channel spec", ""); + } + } + fprintf(fd_th, " } contents[%d];\n", MaX(1, q->nslots)); + fprintf(fd_th, "} Q%d;\n", q->qid); + } + + fprintf(fd_th, "typedef struct Q0 {\t/* generic q */\n"); + qlen_type(qmax); /* 4.2.2 */ + fprintf(fd_th, " uchar _t;\n"); + fprintf(fd_th, "} Q0;\n"); + + ntimes(fd_tc, 0, 1, Addq1); + + fprintf(fd_tc, "#ifdef TRIX\n"); + fprintf(fd_tc, "int\nwhat_p_size(int t)\n{\tint j;\n"); + fprintf(fd_tc, " switch (t) {\n"); + ntimes(fd_tc, 0, nrRdy+1, R5); /* +1 for np_ */ + fprintf(fd_tc, " default: Uerror(\"bad proctype\");\n"); + fprintf(fd_tc, " }\n return j;\n}\n\n"); + + fprintf(fd_tc, "int\nwhat_q_size(int t)\n{\tint j;\n"); + fprintf(fd_tc, " switch (t) {\n"); + for (j = 0; j < nrqs+1; j++) + { fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", j, j); + } + fprintf(fd_tc, " default: Uerror(\"bad qtype\");\n"); + fprintf(fd_tc, " }\n return j;\n}\n"); + fprintf(fd_tc, "#endif\n\n"); + + if (has_random) + { fprintf(fd_th, "int Q_has(int"); + for (j = 0; j < Mpars; j++) + fprintf(fd_th, ", int, int"); + fprintf(fd_th, ");\n"); + + fprintf(fd_tc, "int\nQ_has(int into"); + for (j = 0; j < Mpars; j++) + fprintf(fd_tc, ", int want%d, int fld%d", j, j); + fprintf(fd_tc, ")\n"); + fprintf(fd_tc, "{ int i;\n\n"); + fprintf(fd_tc, " if (!into--)\n"); + fprintf(fd_tc, " uerror(\"ref to unknown chan "); + fprintf(fd_tc, "(recv-poll)\");\n\n"); + fprintf(fd_tc, " if (into >= now._nr_qs || into < 0)\n"); + fprintf(fd_tc, " Uerror(\"qrecv bad queue#\");\n\n"); + fprintf(fd_tc, " for (i = 0; i < ((Q0 *)qptr(into))->Qlen;"); + fprintf(fd_tc, " i++)\n"); + fprintf(fd_tc, " {\n"); + for (j = 0; j < Mpars; j++) + { fprintf(fd_tc, " if (want%d && ", j); + fprintf(fd_tc, "qrecv(into+1, i, %d, 0) != fld%d)\n", + j, j); + fprintf(fd_tc, " continue;\n"); + } + fprintf(fd_tc, " return i+1;\n"); + fprintf(fd_tc, " }\n"); + fprintf(fd_tc, " return 0;\n"); + fprintf(fd_tc, "}\n"); + } + + fprintf(fd_tc, "#if NQS>0\n"); + fprintf(fd_tc, "void\nqsend(int into, int sorted"); + for (j = 0; j < Mpars; j++) + fprintf(fd_tc, ", int fld%d", j); + fprintf(fd_tc, ", int args_given)\n"); + ntimes(fd_tc, 0, 1, Addq11); + + for (q = qtab; q; q = q->nxt) + { sprintf(buf0, "((Q%d *)z)->", q->qid); + fprintf(fd_tc, "\tcase %d:%s\n", q->qid, + (q->nslots)?"":" /* =rv= */"); + if (q->nslots == 0) /* reset handshake point */ + fprintf(fd_tc, "\t\t(trpt+2)->o_m = 0;\n"); + + if (has_sorted) + { fprintf(fd_tc, "\t\tif (!sorted) goto append%d;\n", q->qid); + fprintf(fd_tc, "\t\tfor (j = 0; j < %sQlen; j++)\n", buf0); + fprintf(fd_tc, "\t\t{\t/* find insertion point */\n"); + sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); + for (j = 0; j < q->nflds; j++) + { fprintf(fd_tc, "\t\t\tif (fld%d > %s%d) continue;\n", + j, buf0, j); + fprintf(fd_tc, "\t\t\tif (fld%d < %s%d) ", j, buf0, j); + fprintf(fd_tc, "goto found%d;\n\n", q->qid); + } + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\tfound%d:\n", q->qid); + sprintf(buf0, "((Q%d *)z)->", q->qid); + fprintf(fd_tc, "\t\tfor (k = %sQlen - 1; k >= j; k--)\n", buf0); + fprintf(fd_tc, "\t\t{\t/* shift up */\n"); + for (j = 0; j < q->nflds; j++) + { fprintf(fd_tc, "\t\t\t%scontents[k+1].fld%d = ", + buf0, j); + fprintf(fd_tc, "%scontents[k].fld%d;\n", + buf0, j); + } + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\tappend%d:\t/* insert in slot j */\n", q->qid); + } + + fprintf(fd_tc, "#ifdef HAS_SORTED\n"); + fprintf(fd_tc, "\t\t(trpt+1)->ipt = j;\n"); /* ipt was bup.oval */ + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\t\t%sQlen = %sQlen + 1;\n", buf0, buf0); + sprintf(buf0, "((Q%d *)z)->contents[j].fld", q->qid); + for (j = 0; j < q->nflds; j++) + { fprintf(fd_tc, "\t\t%s%d = fld%d;", buf0, j, j); + if (q->fld_width[j] == MTYPE) + { fprintf(fd_tc, "\t/* mtype %s */", + q->mtp[j]?q->mtp[j]:"_unnamed_"); + } + fprintf(fd_tc, "\n"); + } + fprintf(fd_tc, "\t\tif (args_given != %d)\n", q->nflds); + fprintf(fd_tc, "\t\t{ if (args_given > %d)\n", q->nflds); + fprintf(fd_tc, "\t\t uerror(\"too many parameters in send stmnt\");\n"); + fprintf(fd_tc, "\t\t else\n"); + fprintf(fd_tc, "\t\t uerror(\"too few parameters in send stmnt\");\n"); + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n"); + } + ntimes(fd_tc, 0, 1, Addq2); + + for (q = qtab; q; q = q->nxt) + fprintf(fd_tc, "\tcase %d: return %d;\n", q->qid, (!q->nslots)); + + ntimes(fd_tc, 0, 1, Addq3); + + for (q = qtab; q; q = q->nxt) + fprintf(fd_tc, "\tcase %d: return (q_sz(from) == %d);\n", + q->qid, MaX(1, q->nslots)); + + ntimes(fd_tc, 0, 1, Addq4); + for (q = qtab; q; q = q->nxt) + { sprintf(buf0, "((Q%d *)z)->", q->qid); + fprintf(fd_tc, " case %d:%s\n\t\t", + q->qid, (q->nslots)?"":" /* =rv= */"); + if (q->nflds == 1) + { fprintf(fd_tc, "if (fld == 0) r = %s", buf0); + fprintf(fd_tc, "contents[slot].fld0;\n"); + } else + { fprintf(fd_tc, "switch (fld) {\n"); + ncases(fd_tc, q->qid, 0, q->nflds, R12); + fprintf(fd_tc, "\t\tdefault: Uerror"); + fprintf(fd_tc, "(\"too many fields in recv\");\n"); + fprintf(fd_tc, "\t\t}\n"); + } + fprintf(fd_tc, "\t\tif (done)\n"); + if (q->nslots == 0) + { fprintf(fd_tc, "\t\t{ j = %sQlen - 1;\n", buf0); + fprintf(fd_tc, "\t\t %sQlen = 0;\n", buf0); + sprintf(buf0, "\t\t\t((Q%d *)z)->contents", q->qid); + } else + { fprintf(fd_tc, "\t\t{ j = %sQlen;\n", buf0); + fprintf(fd_tc, "\t\t %sQlen = --j;\n", buf0); + fprintf(fd_tc, "\t\t for (k=slot; kcontents", q->qid); + for (j = 0; j < q->nflds; j++) + { fprintf(fd_tc, "\t%s[k].fld%d = \n", buf0, j); + fprintf(fd_tc, "\t\t%s[k+1].fld%d;\n", buf0, j); + } + fprintf(fd_tc, "\t\t }\n"); + } + + for (j = 0; j < q->nflds; j++) + fprintf(fd_tc, "%s[j].fld%d = 0;\n", buf0, j); + fprintf(fd_tc, "\t\t\tif (fld+1 != %d)\n\t\t\t", q->nflds); + fprintf(fd_tc, "\tuerror(\"missing pars in receive\");\n"); + /* incompletely received msgs cannot be unrecv'ed */ + fprintf(fd_tc, "\t\t}\n"); + fprintf(fd_tc, "\t\tbreak;\n"); + } + ntimes(fd_tc, 0, 1, Addq5); + for (q = qtab; q; q = q->nxt) + fprintf(fd_tc, " case %d: j = sizeof(Q%d); break;\n", + q->qid, q->qid); + ntimes(fd_tc, 0, 1, R8b); + ntimes(fd_th, 0, 1, Proto); /* function prototypes */ + + fprintf(fd_th, "void qsend(int, int"); + for (j = 0; j < Mpars; j++) + fprintf(fd_th, ", int"); + fprintf(fd_th, ", int);\n\n"); + + fprintf(fd_th, "#define Addproc(x,y) addproc(256, y, x"); + /* 256 is param outside the range of valid pids */ + for (j = 0; j < Npars; j++) + fprintf(fd_th, ", 0"); + fprintf(fd_th, ")\n"); } diff --git a/Src/pangen2.c b/Src/pangen2.c index c8b7e8f..a490a3d 100644 --- a/Src/pangen2.c +++ b/Src/pangen2.c @@ -14,1280 +14,1285 @@ #include "pangen5.h" #include "pangen7.h" -#define DELTA 500 /* sets an upperbound on nr of chan names */ - -#define blurb(fd, e) { fprintf(fd, "\n"); if (!merger) fprintf(fd, "\t\t/* %s:%d */\n", \ - e->n->fn->name, e->n->ln); } -#define tr_map(m, e) { if (!merger) fprintf(fd_tt, "\t\ttr_2_src(%d, \"%s\", %d);\n", \ - m, e->n->fn->name, e->n->ln); } - -extern ProcList *ready; -extern RunList *run_lst; -extern Lextok *runstmnts; -extern Symbol *Fname, *oFname, *context; -extern char *claimproc, *eventmap; -extern int lineno, verbose, Npars, Mpars, nclaims; -extern int m_loss, has_remote, has_remvar, merger, rvopt, separate; -extern int Ntimeouts, Etimeouts, deadvar, old_scope_rules, old_priority_rules; -extern int u_sync, u_async, nrRdy, Unique; -extern int GenCode, IsGuard, Level, TestOnly; -extern int globmin, globmax, ltl_mode, dont_simplify; - -extern short has_stack; -extern char *NextLab[64]; /* must match value in dstep.c:18 */ - -int buzzed; -FILE *fd_tc, *fd_th, *fd_tt, *fd_tb; -static FILE *fd_tm; - -int OkBreak = -1, has_hidden = 0; /* has_hidden set in sym.c and structs.c */ -short nocast=0; /* to turn off casts in lvalues */ -short terse=0; /* terse printing of varnames */ -short no_arrays=0; -short has_last=0; /* spec refers to _last */ -short has_priority=0; /* spec refers to _priority */ -short has_badelse=0; /* spec contains else combined with chan refs */ -short has_enabled=0; /* spec contains enabled() */ -short has_pcvalue=0; /* spec contains pc_value() */ -short has_np=0; /* spec contains np_ */ -short has_sorted=0; /* spec contains `!!' (sorted-send) operator */ -short has_random=0; /* spec contains `??' (random-recv) operator */ -short has_xu=0; /* spec contains xr or xs assertions */ -short has_unless=0; /* spec contains unless statements */ -short has_provided=0; /* spec contains PROVIDED clauses on procs */ -short has_code=0; /* spec contains c_code, c_expr, c_state */ -short has_ltl=0; /* has inline ltl formulae */ -int mstp=0; /* max nr of state/process */ -int claimnr = -1; /* claim process, if any */ -int eventmapnr = -1; /* event trace, if any */ -int Pid_nr; /* proc currently processed */ -int multi_oval; /* set in merges, used also in pangen4.c */ -int in_settr; /* avoid quotes inside quotes */ - -#define MAXMERGE 256 /* max nr of bups per merge sequence */ - -static short CnT[MAXMERGE]; -static Lextok XZ, YZ[MAXMERGE]; -static int didcase, YZmax, YZcnt; - -static Lextok *Nn[2]; -static int Det; /* set if deterministic */ -static int T_sum, T_mus, t_cyc; -static int TPE[2], EPT[2]; -static int uniq=1; -static int multi_needed, multi_undo; -static short AllGlobal=0; /* set if process has provided clause */ -static short withprocname=0; /* prefix local varnames with procname */ -static short _isok=0; /* checks usage of predefined variable _ */ -static short evalindex=0; /* evaluate index of var names */ - -extern int has_global(Lextok *); -extern void check_mtypes(Lextok *, Lextok *); -extern void walk2_struct(char *, Symbol *); -extern int find_min(Sequence *); -extern int find_max(Sequence *); - -static int getweight(Lextok *); -static int scan_seq(Sequence *); -static void genconditionals(void); -static void mark_seq(Sequence *); -static void patch_atomic(Sequence *); -static void put_seq(Sequence *, int, int); -static void putproc(ProcList *); -static void Tpe(Lextok *); -extern void spit_recvs(FILE *, FILE*); +#define DELTA 500 /* sets an upperbound on nr of chan names */ + +#define blurb(fd, e) { fprintf(fd, "\n"); if (!merger) fprintf(fd, "\t\t/* %s:%d */\n", \ + e->n->fn->name, e->n->ln); } +#define tr_map(m, e) { if (!merger) fprintf(fd_tt, "\t\ttr_2_src(%d, \"%s\", %d);\n", \ + m, e->n->fn->name, e->n->ln); } + +extern ProcList *ready; +extern RunList *run_lst; +extern Lextok *runstmnts; +extern Symbol *Fname, *oFname, *context; +extern char *claimproc, *eventmap; +extern int lineno, verbose, Npars, Mpars, nclaims; +extern int m_loss, has_remote, has_remvar, merger, rvopt, separate; +extern int Ntimeouts, Etimeouts, deadvar, old_scope_rules, old_priority_rules; +extern int u_sync, u_async, nrRdy, Unique; +extern int GenCode, IsGuard, Level, TestOnly; +extern int globmin, globmax, ltl_mode, dont_simplify; + +extern short has_stack; +extern char *NextLab[64]; /* must match value in dstep.c:18 */ + +int buzzed; +FILE *fd_tc, *fd_th, *fd_tt, *fd_tb; +static FILE *fd_tm; + +int OkBreak = -1, has_hidden = 0; /* has_hidden set in sym.c and structs.c */ +short nocast=0; /* to turn off casts in lvalues */ +short terse=0; /* terse printing of varnames */ +short no_arrays=0; +short has_last=0; /* spec refers to _last */ +short has_priority=0; /* spec refers to _priority */ +short has_badelse=0; /* spec contains else combined with chan refs */ +short has_enabled=0; /* spec contains enabled() */ +short has_pcvalue=0; /* spec contains pc_value() */ +short has_np=0; /* spec contains np_ */ +short has_sorted=0; /* spec contains `!!' (sorted-send) operator */ +short has_random=0; /* spec contains `??' (random-recv) operator */ +short has_xu=0; /* spec contains xr or xs assertions */ +short has_unless=0; /* spec contains unless statements */ +short has_provided=0; /* spec contains PROVIDED clauses on procs */ +short has_code=0; /* spec contains c_code, c_expr, c_state */ +short has_ltl=0; /* has inline ltl formulae */ +int mstp=0; /* max nr of state/process */ +int claimnr = -1; /* claim process, if any */ +int eventmapnr = -1; /* event trace, if any */ +int Pid_nr; /* proc currently processed */ +int multi_oval; /* set in merges, used also in pangen4.c */ +int in_settr; /* avoid quotes inside quotes */ + +#define MAXMERGE 256 /* max nr of bups per merge sequence */ + +static short CnT[MAXMERGE]; +static Lextok XZ, YZ[MAXMERGE]; +static int didcase, YZmax, YZcnt; + +static Lextok *Nn[2]; +static int Det; /* set if deterministic */ +static int T_sum, T_mus, t_cyc; +static int TPE[2], EPT[2]; +static int uniq=1; +static int multi_needed, multi_undo; +static short AllGlobal=0; /* set if process has provided clause */ +static short withprocname=0; /* prefix local varnames with procname */ +static short _isok=0; /* checks usage of predefined variable _ */ +static short evalindex=0; /* evaluate index of var names */ + +extern int has_global(Lextok *); +extern void check_mtypes(Lextok *, Lextok *); +extern void walk2_struct(char *, Symbol *); +extern int find_min(Sequence *); +extern int find_max(Sequence *); + +static int getweight(Lextok *); +static int scan_seq(Sequence *); +static void genconditionals(void); +static void mark_seq(Sequence *); +static void patch_atomic(Sequence *); +static void put_seq(Sequence *, int, int); +static void putproc(ProcList *); +static void Tpe(Lextok *); +extern void spit_recvs(FILE *, FILE*); static L_List *keep_track; void keep_track_off(Lextok *n) -{ L_List *p; +{ L_List *p; - p = (L_List *) emalloc(sizeof(L_List)); - p->n = n; - p->nxt = keep_track; - keep_track = p; + p = (L_List *) emalloc(sizeof(L_List)); + p->n = n; + p->nxt = keep_track; + keep_track = p; } int check_track(Lextok *n) -{ L_List *p; +{ L_List *p; - for (p = keep_track; p; p = p->nxt) - { if (p->n == n) - { return n->sym?n->sym->type:0; - } } - return 0; + for (p = keep_track; p; p = p->nxt) + { if (p->n == n) + { return n->sym?n->sym->type:0; + } } + return 0; } static int fproc(char *s) -{ ProcList *p; +{ ProcList *p; - for (p = ready; p; p = p->nxt) - if (strcmp(p->n->name, s) == 0) - return p->tn; + for (p = ready; p; p = p->nxt) + if (strcmp(p->n->name, s) == 0) + return p->tn; - fatal("proctype %s not found", s); - return -1; + fatal("proctype %s not found", s); + return -1; } int -pid_is_claim(int p) /* Pid_nr (p->tn) to type (p->b) */ -{ ProcList *r; - - for (r = ready; r; r = r->nxt) - { if (r->tn == p) return (r->b == N_CLAIM); - } - printf("spin: error, cannot find pid %d\n", p); - return 0; +pid_is_claim(int p) /* Pid_nr (p->tn) to type (p->b) */ +{ ProcList *r; + + for (r = ready; r; r = r->nxt) + { if (r->tn == p) return (r->b == N_CLAIM); + } + printf("spin: error, cannot find pid %d\n", p); + return 0; } static void reverse_procs(RunList *q) { - if (!q) return; - reverse_procs(q->nxt); - fprintf(fd_tc, " Addproc(%d, %d);\n", - q->tn, q->priority < 1 ? 1 : q->priority); + if (!q) return; + reverse_procs(q->nxt); + fprintf(fd_tc, " Addproc(%d, %d);\n", + q->tn, q->priority < 1 ? 1 : q->priority); } static void forward_procs(RunList *q) { - if (!q) return; - fprintf(fd_tc, " Addproc(%d, %d);\n", - q->tn, q->priority < 1 ? 1 : q->priority); - forward_procs(q->nxt); + if (!q) return; + fprintf(fd_tc, " Addproc(%d, %d);\n", + q->tn, q->priority < 1 ? 1 : q->priority); + forward_procs(q->nxt); } static void tm_predef_np(void) { - fprintf(fd_th, "#define _T5 %d\n", uniq++); - fprintf(fd_th, "#define _T2 %d\n", uniq++); - - fprintf(fd_tm, "\tcase _T5:\t/* np_ */\n"); - - if (separate == 2) - { fprintf(fd_tm, "\t\tif (!((!(o_pm&4) && !(tau&128))))\n"); - } else - { fprintf(fd_tm, "\t\tif (!((!(trpt->o_pm&4) && !(trpt->tau&128))))\n"); - } - fprintf(fd_tm, "\t\t\tcontinue;\n"); - fprintf(fd_tm, "\t\t/* else fall through */\n"); - fprintf(fd_tm, "\tcase _T2:\t/* true */\n"); - fprintf(fd_tm, "\t\t_m = 3; goto P999;\n"); + fprintf(fd_th, "#define _T5 %d\n", uniq++); + fprintf(fd_th, "#define _T2 %d\n", uniq++); + + fprintf(fd_tm, "\tcase _T5:\t/* np_ */\n"); + + if (separate == 2) + { fprintf(fd_tm, "\t\tif (!((!(o_pm&4) && !(tau&128))))\n"); + } else + { fprintf(fd_tm, "\t\tif (!((!(trpt->o_pm&4) && !(trpt->tau&128))))\n"); + } + fprintf(fd_tm, "\t\t\tcontinue;\n"); + fprintf(fd_tm, "\t\t/* else fall through */\n"); + fprintf(fd_tm, "\tcase _T2:\t/* true */\n"); + fprintf(fd_tm, "\t\t_m = 3; goto P999;\n"); } static void tt_predef_np(void) { - fprintf(fd_tt, "\t/* np_ demon: */\n"); - fprintf(fd_tt, "\ttrans[_NP_] = "); - fprintf(fd_tt, "(Trans **) emalloc(3*sizeof(Trans *));\n"); - fprintf(fd_tt, "\tT = trans[_NP_][0] = "); - fprintf(fd_tt, "settr(9997,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); - fprintf(fd_tt, "\t T->nxt = "); - fprintf(fd_tt, "settr(9998,0,0,_T2,0,\"(1)\", 0,2,0);\n"); - fprintf(fd_tt, "\tT = trans[_NP_][1] = "); - fprintf(fd_tt, "settr(9999,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); + fprintf(fd_tt, "\t/* np_ demon: */\n"); + fprintf(fd_tt, "\ttrans[_NP_] = "); + fprintf(fd_tt, "(Trans **) emalloc(3*sizeof(Trans *));\n"); + fprintf(fd_tt, "\tT = trans[_NP_][0] = "); + fprintf(fd_tt, "settr(9997,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); + fprintf(fd_tt, "\t T->nxt = "); + fprintf(fd_tt, "settr(9998,0,0,_T2,0,\"(1)\", 0,2,0);\n"); + fprintf(fd_tt, "\tT = trans[_NP_][1] = "); + fprintf(fd_tt, "settr(9999,0,1,_T5,0,\"(np_)\", 1,2,0);\n"); } static struct { - char *nm[3]; + const char *nm[3]; } Cfile[] = { - { { "pan.c", "pan_s.c", "pan_t.c" } }, - { { "pan.h", "pan_s.h", "pan_t.h" } }, - { { "pan.t", "pan_s.t", "pan_t.t" } }, - { { "pan.m", "pan_s.m", "pan_t.m" } }, - { { "pan.b", "pan_s.b", "pan_t.b" } } + { { "pan.c", "pan_s.c", "pan_t.c" } }, + { { "pan.h", "pan_s.h", "pan_t.h" } }, + { { "pan.t", "pan_s.t", "pan_t.t" } }, + { { "pan.m", "pan_s.m", "pan_t.m" } }, + { { "pan.b", "pan_s.b", "pan_t.b" } } }; void gensrc(void) -{ ProcList *p; - int i; - - disambiguate(); /* avoid name-clashes between scopes */ - - if (!(fd_tc = fopen(Cfile[0].nm[separate], MFLAGS)) /* main routines */ - || !(fd_th = fopen(Cfile[1].nm[separate], MFLAGS)) /* header file */ - || !(fd_tt = fopen(Cfile[2].nm[separate], MFLAGS)) /* transition matrix */ - || !(fd_tm = fopen(Cfile[3].nm[separate], MFLAGS)) /* forward moves */ - || !(fd_tb = fopen(Cfile[4].nm[separate], MFLAGS))) /* backward moves */ - { printf("spin: cannot create pan.[chtmfb]\n"); - alldone(1); - } - - fprintf(fd_th, "#ifndef PAN_H\n"); - fprintf(fd_th, "#define PAN_H\n\n"); - - fprintf(fd_th, "#define SpinVersion \"%s\"\n", SpinVersion); - fprintf(fd_th, "#define PanSource \""); - for (i = 0; oFname->name[i] != '\0'; i++) - { char c = oFname->name[i]; - if (c == '\\') /* Windows path */ - { fprintf(fd_th, "\\"); - } - fprintf(fd_th, "%c", c); - } - fprintf(fd_th, "\"\n\n"); - - fprintf(fd_th, "#define G_long %d\n", (int) sizeof(long)); - fprintf(fd_th, "#define G_int %d\n\n", (int) sizeof(int)); - fprintf(fd_th, "#define ulong unsigned long\n"); - fprintf(fd_th, "#define ushort unsigned short\n"); - - fprintf(fd_th, "#ifdef WIN64\n"); - fprintf(fd_th, " #define ONE_L (1L)\n"); - fprintf(fd_th, "/* #define long long long */\n"); - fprintf(fd_th, "#else\n"); - fprintf(fd_th, " #define ONE_L (1L)\n"); - fprintf(fd_th, "#endif\n\n"); - - fprintf(fd_th, "#ifdef BFS_PAR\n"); - fprintf(fd_th, " #define NRUNS %d\n", (runstmnts)?1:0); - fprintf(fd_th, " #ifndef BFS\n"); - fprintf(fd_th, " #define BFS\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, " #ifndef PUTPID\n"); - fprintf(fd_th, " #define PUTPID\n"); - fprintf(fd_th, " #endif\n\n"); - fprintf(fd_th, " #if !defined(USE_TDH) && !defined(NO_TDH)\n"); - fprintf(fd_th, " #define USE_TDH\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, " #if defined(USE_TDH) && !defined(NO_HC)\n"); - fprintf(fd_th, " #define HC /* default for USE_TDH */\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, " #ifndef BFS_MAXPROCS\n"); - fprintf(fd_th, " #define BFS_MAXPROCS 64 /* max nr of cores to use */\n"); - fprintf(fd_th, " #endif\n"); - - fprintf(fd_th, " #define BFS_GLOB 0 /* global lock */\n"); - fprintf(fd_th, " #define BFS_ORD 1 /* used with -DCOLLAPSE */\n"); - fprintf(fd_th, " #define BFS_MEM 2 /* malloc from shared heap */\n"); - fprintf(fd_th, " #define BFS_PRINT 3 /* protect printfs */\n"); - fprintf(fd_th, " #define BFS_STATE 4 /* hashtable */\n\n"); - fprintf(fd_th, " #define BFS_INQ 2 /* state is in q */\n\n"); - - fprintf(fd_th, " #ifdef BFS_FIFO\n"); /* queue access */ - fprintf(fd_th, " #define BFS_ID(a,b) (BFS_STATE + (int) ((a)*BFS_MAXPROCS+(b)))\n"); - fprintf(fd_th, " #define BFS_MAXLOCKS (BFS_STATE + (BFS_MAXPROCS*BFS_MAXPROCS))\n"); - fprintf(fd_th, " #else\n"); /* h_store access (not needed for o_store) */ - fprintf(fd_th, " #ifndef BFS_W\n"); - fprintf(fd_th, " #define BFS_W 10\n"); /* 1<minel = -1; - claimproc = n->name = "_:never_template:_"; - mk_rdy(n, ZN, s, 0, ZN, N_CLAIM); - } - if (separate == 2) - { if (has_remote) - { printf("spin: warning, make sure that the S1 model\n"); - printf(" includes the same remote references\n"); - } - fprintf(fd_th, "#ifndef NFAIR\n"); - fprintf(fd_th, "#define NFAIR 2 /* must be >= 2 */\n"); - fprintf(fd_th, "#endif\n"); - if (has_last) - fprintf(fd_th, "#define HAS_LAST %d\n", has_last); - if (has_priority && !old_priority_rules) - fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); - goto doless; - } - - fprintf(fd_th, "#define DELTA %d\n", DELTA); - fprintf(fd_th, "#ifdef MA\n"); - fprintf(fd_th, " #if NCORE>1 && !defined(SEP_STATE)\n"); - fprintf(fd_th, " #define SEP_STATE\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, " #if MA==1\n"); /* user typed -DMA without size */ - fprintf(fd_th, " #undef MA\n"); - fprintf(fd_th, " #define MA 100\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - fprintf(fd_th, "#ifdef W_XPT\n"); - fprintf(fd_th, " #if W_XPT==1\n"); /* user typed -DW_XPT without size */ - fprintf(fd_th, " #undef W_XPT\n"); - fprintf(fd_th, " #define W_XPT 1000000\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - fprintf(fd_th, "#ifndef NFAIR\n"); - fprintf(fd_th, " #define NFAIR 2 /* must be >= 2 */\n"); - fprintf(fd_th, "#endif\n"); - if (Ntimeouts) - fprintf(fd_th, "#define NTIM %d\n", Ntimeouts); - if (Etimeouts) - fprintf(fd_th, "#define ETIM %d\n", Etimeouts); - if (has_remvar) - fprintf(fd_th, "#define REM_VARS 1\n"); - if (has_remote) - fprintf(fd_th, "#define REM_REFS %d\n", has_remote); /* not yet used */ - if (has_hidden) - { fprintf(fd_th, "#define HAS_HIDDEN %d\n", has_hidden); - fprintf(fd_th, "#if defined(BFS_PAR) || defined(BFS)\n"); - fprintf(fd_th, " #error cannot use BFS on models with variables declared hidden\n"); - fprintf(fd_th, "#endif\n"); - } - if (has_last) - fprintf(fd_th, "#define HAS_LAST %d\n", has_last); - if (has_priority && !old_priority_rules) - fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); - if (has_sorted) - fprintf(fd_th, "#define HAS_SORTED %d\n", has_sorted); - if (m_loss) - fprintf(fd_th, "#define M_LOSS\n"); - if (has_random) - fprintf(fd_th, "#define HAS_RANDOM %d\n", has_random); - if (has_ltl) - fprintf(fd_th, "#define HAS_LTL 1\n"); - fprintf(fd_th, "#define HAS_CODE 1\n"); /* could also be set to has_code */ - /* always defining it doesn't seem to cause measurable overhead though */ - /* and allows for pan -r etc to work for non-embedded code as well */ - fprintf(fd_th, "#if defined(RANDSTORE) && !defined(RANDSTOR)\n"); - fprintf(fd_th, " #define RANDSTOR RANDSTORE\n"); /* xspin uses RANDSTORE... */ - fprintf(fd_th, "#endif\n"); - if (has_stack) - fprintf(fd_th, "#define HAS_STACK %d\n", has_stack); - if (has_enabled || (has_priority && !old_priority_rules)) - fprintf(fd_th, "#define HAS_ENABLED 1\n"); - if (has_unless) - fprintf(fd_th, "#define HAS_UNLESS %d\n", has_unless); - if (has_provided) - fprintf(fd_th, "#define HAS_PROVIDED %d\n", has_provided); - if (has_pcvalue) - fprintf(fd_th, "#define HAS_PCVALUE %d\n", has_pcvalue); - if (has_badelse) - fprintf(fd_th, "#define HAS_BADELSE %d\n", has_badelse); - if (has_enabled - || (has_priority && !old_priority_rules) - || has_pcvalue - || has_badelse - || has_last) - { fprintf(fd_th, "#ifndef NOREDUCE\n"); - fprintf(fd_th, " #define NOREDUCE 1\n"); - fprintf(fd_th, "#endif\n"); - } - if (has_np) - fprintf(fd_th, "#define HAS_NP %d\n", has_np); - if (merger) - fprintf(fd_th, "#define MERGED 1\n"); +{ ProcList *p; + int i; + + disambiguate(); /* avoid name-clashes between scopes */ + + if (!(fd_tc = fopen(Cfile[0].nm[separate], MFLAGS)) /* main routines */ + || !(fd_th = fopen(Cfile[1].nm[separate], MFLAGS)) /* header file */ + || !(fd_tt = fopen(Cfile[2].nm[separate], MFLAGS)) /* transition matrix */ + || !(fd_tm = fopen(Cfile[3].nm[separate], MFLAGS)) /* forward moves */ + || !(fd_tb = fopen(Cfile[4].nm[separate], MFLAGS))) /* backward moves */ + { printf("spin: cannot create pan.[chtmfb]\n"); + alldone(1); + } + + fprintf(fd_th, "#ifndef PAN_H\n"); + fprintf(fd_th, "#define PAN_H\n\n"); + + fprintf(fd_th, "#define SpinVersion \"%s\"\n", SpinVersion); + fprintf(fd_th, "#define PanSource \""); + for (i = 0; oFname->name[i] != '\0'; i++) + { char c = oFname->name[i]; + if (c == '\\') /* Windows path */ + { fprintf(fd_th, "\\"); + } + fprintf(fd_th, "%c", c); + } + fprintf(fd_th, "\"\n\n"); + + fprintf(fd_th, "#define G_long %d\n", (int) sizeof(long)); + fprintf(fd_th, "#define G_int %d\n\n", (int) sizeof(int)); + fprintf(fd_th, "#define ulong unsigned long\n"); + fprintf(fd_th, "#define ushort unsigned short\n"); + + fprintf(fd_th, "#ifdef WIN64\n"); + fprintf(fd_th, " #define ONE_L (1L)\n"); + fprintf(fd_th, "/* #define long long long */\n"); + fprintf(fd_th, "#else\n"); + fprintf(fd_th, " #define ONE_L (1L)\n"); + fprintf(fd_th, "#endif\n\n"); + + fprintf(fd_th, "#ifdef BFS_PAR\n"); + fprintf(fd_th, " #define NRUNS %d\n", (runstmnts)?1:0); + fprintf(fd_th, " #ifndef BFS\n"); + fprintf(fd_th, " #define BFS\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #ifndef PUTPID\n"); + fprintf(fd_th, " #define PUTPID\n"); + fprintf(fd_th, " #endif\n\n"); + fprintf(fd_th, " #if !defined(USE_TDH) && !defined(NO_TDH)\n"); + fprintf(fd_th, " #define USE_TDH\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #if defined(USE_TDH) && !defined(NO_HC)\n"); + fprintf(fd_th, " #define HC /* default for USE_TDH */\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #ifndef BFS_MAXPROCS\n"); + fprintf(fd_th, " #define BFS_MAXPROCS 64 /* max nr of cores to use */\n"); + fprintf(fd_th, " #endif\n"); + + fprintf(fd_th, " #define BFS_GLOB 0 /* global lock */\n"); + fprintf(fd_th, " #define BFS_ORD 1 /* used with -DCOLLAPSE */\n"); + fprintf(fd_th, " #define BFS_MEM 2 /* malloc from shared heap */\n"); + fprintf(fd_th, " #define BFS_PRINT 3 /* protect printfs */\n"); + fprintf(fd_th, " #define BFS_STATE 4 /* hashtable */\n\n"); + fprintf(fd_th, " #define BFS_INQ 2 /* state is in q */\n\n"); + + fprintf(fd_th, " #ifdef BFS_FIFO\n"); /* queue access */ + fprintf(fd_th, " #define BFS_ID(a,b) (BFS_STATE + (int) ((a)*BFS_MAXPROCS+(b)))\n"); + fprintf(fd_th, " #define BFS_MAXLOCKS (BFS_STATE + (BFS_MAXPROCS*BFS_MAXPROCS))\n"); + fprintf(fd_th, " #else\n"); /* h_store access (not needed for o_store) */ + fprintf(fd_th, " #ifndef BFS_W\n"); + fprintf(fd_th, " #define BFS_W 10\n"); /* 1<minel = -1; + claimproc = n->name = strdup("_:never_template:_"); + mk_rdy(n, ZN, s, 0, ZN, N_CLAIM); + } + if (separate == 2) + { if (has_remote) + { printf("spin: warning, make sure that the S1 model\n"); + printf(" includes the same remote references\n"); + } + fprintf(fd_th, "#ifndef NFAIR\n"); + fprintf(fd_th, "#define NFAIR 2 /* must be >= 2 */\n"); + fprintf(fd_th, "#endif\n"); + if (has_last) + fprintf(fd_th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); + goto doless; + } + + fprintf(fd_th, "#define DELTA %d\n", DELTA); + fprintf(fd_th, "#ifdef MA\n"); + fprintf(fd_th, " #if NCORE>1 && !defined(SEP_STATE)\n"); + fprintf(fd_th, " #define SEP_STATE\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, " #if MA==1\n"); /* user typed -DMA without size */ + fprintf(fd_th, " #undef MA\n"); + fprintf(fd_th, " #define MA 100\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, "#ifdef W_XPT\n"); + fprintf(fd_th, " #if W_XPT==1\n"); /* user typed -DW_XPT without size */ + fprintf(fd_th, " #undef W_XPT\n"); + fprintf(fd_th, " #define W_XPT 1000000\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + fprintf(fd_th, "#ifndef NFAIR\n"); + fprintf(fd_th, " #define NFAIR 2 /* must be >= 2 */\n"); + fprintf(fd_th, "#endif\n"); + if (Ntimeouts) + fprintf(fd_th, "#define NTIM %d\n", Ntimeouts); + if (Etimeouts) + fprintf(fd_th, "#define ETIM %d\n", Etimeouts); + if (has_remvar) + fprintf(fd_th, "#define REM_VARS 1\n"); + if (has_remote) + fprintf(fd_th, "#define REM_REFS %d\n", has_remote); /* not yet used */ + if (has_hidden) + { fprintf(fd_th, "#define HAS_HIDDEN %d\n", has_hidden); + fprintf(fd_th, "#if defined(BFS_PAR) || defined(BFS)\n"); + fprintf(fd_th, " #error cannot use BFS on models with variables declared hidden\n"); + fprintf(fd_th, "#endif\n"); + } + if (has_last) + fprintf(fd_th, "#define HAS_LAST %d\n", has_last); + if (has_priority && !old_priority_rules) + fprintf(fd_th, "#define HAS_PRIORITY %d\n", has_priority); + if (has_sorted) + fprintf(fd_th, "#define HAS_SORTED %d\n", has_sorted); + if (m_loss) + fprintf(fd_th, "#define M_LOSS\n"); + if (has_random) + fprintf(fd_th, "#define HAS_RANDOM %d\n", has_random); + if (has_ltl) + fprintf(fd_th, "#define HAS_LTL 1\n"); + fprintf(fd_th, "#define HAS_CODE 1\n"); /* could also be set to has_code */ + /* always defining it doesn't seem to cause measurable overhead though */ + /* and allows for pan -r etc to work for non-embedded code as well */ + fprintf(fd_th, "#if defined(RANDSTORE) && !defined(RANDSTOR)\n"); + fprintf(fd_th, " #define RANDSTOR RANDSTORE\n"); /* xspin uses RANDSTORE... */ + fprintf(fd_th, "#endif\n"); + if (has_stack) + fprintf(fd_th, "#define HAS_STACK %d\n", has_stack); + if (has_enabled || (has_priority && !old_priority_rules)) + fprintf(fd_th, "#define HAS_ENABLED 1\n"); + if (has_unless) + fprintf(fd_th, "#define HAS_UNLESS %d\n", has_unless); + if (has_provided) + fprintf(fd_th, "#define HAS_PROVIDED %d\n", has_provided); + if (has_pcvalue) + fprintf(fd_th, "#define HAS_PCVALUE %d\n", has_pcvalue); + if (has_badelse) + fprintf(fd_th, "#define HAS_BADELSE %d\n", has_badelse); + if (has_enabled + || (has_priority && !old_priority_rules) + || has_pcvalue + || has_badelse + || has_last) + { fprintf(fd_th, "#ifndef NOREDUCE\n"); + fprintf(fd_th, " #define NOREDUCE 1\n"); + fprintf(fd_th, "#endif\n"); + } + if (has_np) + fprintf(fd_th, "#define HAS_NP %d\n", has_np); + if (merger) + fprintf(fd_th, "#define MERGED 1\n"); doless: - fprintf(fd_th, "#if !defined(HAS_LAST) && defined(BCS)\n"); - fprintf(fd_th, " #define HAS_LAST 1 /* use it, but */\n"); - fprintf(fd_th, " #ifndef STORE_LAST\n"); /* unless the user insists */ - fprintf(fd_th, " #define NO_LAST 1 /* don't store it */\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - - fprintf(fd_th, "#if defined(BCS) && defined(BITSTATE)\n"); - fprintf(fd_th, " #ifndef NO_CTX\n"); - fprintf(fd_th, " #define STORE_CTX 1\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - - fprintf(fd_th, "#ifdef NP\n"); - if (!has_np) - fprintf(fd_th, " #define HAS_NP 2\n"); - fprintf(fd_th, " #define VERI %d /* np_ */\n", nrRdy); - fprintf(fd_th, "#endif\n"); - - fprintf(fd_th, "#if defined(NOCLAIM) && defined(NP)\n"); - fprintf(fd_th, " #undef NOCLAIM\n"); - fprintf(fd_th, "#endif\n"); - if (claimproc) - { claimnr = fproc(claimproc); /* the default claim */ - fprintf(fd_th, "#ifndef NOCLAIM\n"); - fprintf(fd_th, " #define NCLAIMS %d\n", nclaims); - fprintf(fd_th, " #ifndef NP\n"); - fprintf(fd_th, " #define VERI %d\n", claimnr); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - } - if (eventmap) - { eventmapnr = fproc(eventmap); - fprintf(fd_th, "#define EVENT_TRACE %d\n", eventmapnr); - fprintf(fd_th, "#define endevent _endstate%d\n", eventmapnr); - if (eventmap[2] == 'o') /* ":notrace:" */ - fprintf(fd_th, "#define NEGATED_TRACE 1\n"); - } - - fprintf(fd_th, "\ntypedef struct S_F_MAP {\n"); - fprintf(fd_th, " char *fnm;\n\tint from;\n\tint upto;\n"); - fprintf(fd_th, "} S_F_MAP;\n"); - - fprintf(fd_tc, "/*** Generated by %s ***/\n", SpinVersion); - fprintf(fd_tc, "/*** From source: %s ***/\n\n", oFname->name); - - ntimes(fd_tc, 0, 1, Pre0); - - plunk_c_decls(fd_tc); /* types can be refered to in State */ - - switch (separate) { - case 0: fprintf(fd_tc, "#include \"pan.h\"\n"); break; - case 1: fprintf(fd_tc, "#include \"pan_s.h\"\n"); break; - case 2: fprintf(fd_tc, "#include \"pan_t.h\"\n"); break; - } - - if (separate != 2) - { fprintf(fd_tc, "char *TrailFile = PanSource; /* default */\n"); - fprintf(fd_tc, "char *trailfilename;\n"); - } - - fprintf(fd_tc, "#ifdef LOOPSTATE\n"); - fprintf(fd_tc, "double cnt_loops;\n"); - fprintf(fd_tc, "#endif\n"); - - fprintf(fd_tc, "State A_Root; /* seed-state for cycles */\n"); - fprintf(fd_tc, "State now; /* the full state-vector */\n"); - fprintf(fd_tc, "#if NQS > 0\n"); - fprintf(fd_tc, "short q_flds[NQS+1];\n"); - fprintf(fd_tc, "short q_max[NQS+1];\n"); - fprintf(fd_tc, "#endif\n"); - - fprintf(fd_tc, "#ifndef XUSAFE\n"); - fprintf(fd_tc, " uchar q_claim[MAXQ+1];\n"); - fprintf(fd_tc, " char *q_name[MAXQ+1];\n"); - fprintf(fd_tc, " char *p_name[MAXPROC+1];\n"); - fprintf(fd_tc, "#endif\n"); - - plunk_c_fcts(fd_tc); /* State can be used in fcts */ - - if (separate != 2) - { ntimes(fd_tc, 0, 1, Preamble); - ntimes(fd_tc, 0, 1, Separate); /* things that moved out of pan.h */ - } else - { fprintf(fd_tc, "extern int verbose;\n"); - fprintf(fd_tc, "extern long depth, depthfound;\n"); - } - - fprintf(fd_tc, "#ifndef NOBOUNDCHECK\n"); - fprintf(fd_tc, " #define Index(x, y)\tBoundcheck(x, y, II, tt, t)\n"); - fprintf(fd_tc, "#else\n"); - fprintf(fd_tc, " #define Index(x, y)\tx\n"); - fprintf(fd_tc, "#endif\n"); - - c_preview(); /* sets hastrack */ - - for (p = ready; p; p = p->nxt) - mstp = max(p->s->maxel, mstp); - - if (separate != 2) - { fprintf(fd_tt, "#ifdef PEG\n"); - fprintf(fd_tt, "struct T_SRC {\n"); - fprintf(fd_tt, " char *fl; int ln;\n"); - fprintf(fd_tt, "} T_SRC[NTRANS];\n\n"); - fprintf(fd_tt, "void\ntr_2_src(int m, char *file, int ln)\n"); - fprintf(fd_tt, "{ T_SRC[m].fl = file;\n"); - fprintf(fd_tt, " T_SRC[m].ln = ln;\n"); - fprintf(fd_tt, "}\n\n"); - fprintf(fd_tt, "void\nputpeg(int n, int m)\n"); - fprintf(fd_tt, "{ printf(\"%%5d\ttrans %%4d \", m, n);\n"); - fprintf(fd_tt, " printf(\"%%s:%%d\\n\",\n"); - fprintf(fd_tt, " T_SRC[n].fl, T_SRC[n].ln);\n"); - fprintf(fd_tt, "}\n"); - if (!merger) - { fprintf(fd_tt, "#else\n"); - fprintf(fd_tt, "#define tr_2_src(m,f,l)\n"); - } - fprintf(fd_tt, "#endif\n\n"); - fprintf(fd_tt, "void\nsettable(void)\n{\tTrans *T;\n"); - fprintf(fd_tt, "\tTrans *settr(int, int, int, int, int,"); - fprintf(fd_tt, " char *, int, int, int);\n\n"); - fprintf(fd_tt, "\ttrans = (Trans ***) "); - fprintf(fd_tt, "emalloc(%d*sizeof(Trans **));\n", nrRdy+1); - /* +1 for np_ automaton */ - - if (separate == 1) - { - fprintf(fd_tm, " if (II == 0)\n"); - fprintf(fd_tm, " { _m = step_claim(trpt->o_pm, trpt->tau, tt, ot, t);\n"); - fprintf(fd_tm, " if (_m) goto P999; else continue;\n"); - fprintf(fd_tm, " } else\n"); - } - - fprintf(fd_tm, "#define rand pan_rand\n"); - fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); - fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); - fprintf(fd_tm, " #ifdef BFS_PAR\n"); - fprintf(fd_tm, " bfs_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); - fprintf(fd_tm, " #else\n"); - fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); - fprintf(fd_tm, " #endif\n"); - fprintf(fd_tm, "#endif\n"); - fprintf(fd_tm, " switch (t->forw) {\n"); - } else - { fprintf(fd_tt, "#ifndef PEG\n"); - fprintf(fd_tt, " #define tr_2_src(m,f,l)\n"); - fprintf(fd_tt, "#endif\n"); - fprintf(fd_tt, "void\nset_claim(void)\n{\tTrans *T;\n"); - fprintf(fd_tt, "\textern Trans ***trans;\n"); - fprintf(fd_tt, "\textern Trans *settr(int, int, int, int, int,"); - fprintf(fd_tt, " char *, int, int, int);\n\n"); - - fprintf(fd_tm, "#define rand pan_rand\n"); - fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); - fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); - fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, forw);\n"); - fprintf(fd_tm, "#endif\n"); - fprintf(fd_tm, " switch (forw) {\n"); - } - - fprintf(fd_tm, " default: Uerror(\"bad forward move\");\n"); - fprintf(fd_tm, " case 0: /* if without executable clauses */\n"); - fprintf(fd_tm, " continue;\n"); - fprintf(fd_tm, " case 1: /* generic 'goto' or 'skip' */\n"); - if (separate != 2) - fprintf(fd_tm, " IfNotBlocked\n"); - fprintf(fd_tm, " _m = 3; goto P999;\n"); - fprintf(fd_tm, " case 2: /* generic 'else' */\n"); - if (separate == 2) - fprintf(fd_tm, " if (o_pm&1) continue;\n"); - else - { fprintf(fd_tm, " IfNotBlocked\n"); - fprintf(fd_tm, " if (trpt->o_pm&1) continue;\n"); - } - fprintf(fd_tm, " _m = 3; goto P999;\n"); - uniq = 3; - - if (separate == 1) - fprintf(fd_tb, " if (II == 0) goto R999;\n"); - - fprintf(fd_tb, " switch (t->back) {\n"); - fprintf(fd_tb, " default: Uerror(\"bad return move\");\n"); - fprintf(fd_tb, " case 0: goto R999; /* nothing to undo */\n"); - - for (p = ready; p; p = p->nxt) - { putproc(p); - } - - if (separate != 2) - { fprintf(fd_th, "\n"); - for (p = ready; p; p = p->nxt) - fprintf(fd_th, "extern short src_ln%d[];\n", p->tn); - for (p = ready; p; p = p->nxt) - fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", p->tn); - fprintf(fd_th, "\n"); - - fprintf(fd_tc, "uchar reached%d[3]; /* np_ */\n", nrRdy); - fprintf(fd_tc, "uchar *loopstate%d; /* np_ */\n", nrRdy); - - fprintf(fd_tc, "struct {\n"); - fprintf(fd_tc, " int tp; short *src;\n"); - fprintf(fd_tc, "} src_all[] = {\n"); - for (p = ready; p; p = p->nxt) - fprintf(fd_tc, " { %d, &src_ln%d[0] },\n", - p->tn, p->tn); - fprintf(fd_tc, " { 0, (short *) 0 }\n"); - fprintf(fd_tc, "};\n"); - - fprintf(fd_tc, "S_F_MAP *flref[] = {\n"); /* 5.3.0 */ - for (p = ready; p; p = p->nxt) - { fprintf(fd_tc, " src_file%d%c\n", p->tn, p->nxt?',':' '); - } - fprintf(fd_tc, "};\n\n"); - } else - { fprintf(fd_tc, "extern uchar reached%d[3]; /* np_ */\n", nrRdy); - } - - gencodetable(fd_tc); /* was th */ - - if (Unique < (1 << (8*sizeof(unsigned char)) )) /* was uniq before */ - { fprintf(fd_th, "#define T_ID unsigned char\n"); - } else if (Unique < (1 << (8*sizeof(unsigned short)) )) - { fprintf(fd_th, "#define T_ID unsigned short\n"); - } else - { fprintf(fd_th, "#define T_ID unsigned int\n"); - } - - if (separate != 1) - { tm_predef_np(); - tt_predef_np(); - } - fprintf(fd_tt, "}\n\n"); /* end of settable() */ - - fprintf(fd_tm, "#undef rand\n"); - fprintf(fd_tm, " }\n\n"); - fprintf(fd_tb, " }\n\n"); - - if (separate != 2) - { ntimes(fd_tt, 0, 1, Tail); - genheader(); - if (separate == 1) - { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_s.m\"\n"); - fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_s.b\"\n"); - fprintf(fd_th, "#define SEPARATE\n"); - fprintf(fd_th, "#define TRANSITIONS\t\"pan_s.t\"\n"); - fprintf(fd_th, "extern void ini_claim(int, int);\n"); - } else - { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan.m\"\n"); - fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan.b\"\n"); - fprintf(fd_th, "#define TRANSITIONS\t\"pan.t\"\n"); - } - genaddproc(); - genother(); - genaddqueue(); - genunio(); - genconditionals(); - gensvmap(); - if (!run_lst) fatal("no runable process", (char *)0); - fprintf(fd_tc, "void\n"); - fprintf(fd_tc, "active_procs(void)\n{\n"); - - fprintf(fd_tc, " if (reversing == 0) {\n"); - reverse_procs(run_lst); - fprintf(fd_tc, " } else {\n"); - forward_procs(run_lst); - fprintf(fd_tc, " }\n"); - - fprintf(fd_tc, "}\n"); - ntimes(fd_tc, 0, 1, Dfa); - ntimes(fd_tc, 0, 1, Xpt); - - fprintf(fd_th, "#define NTRANS %d\n", uniq); - if (u_sync && !u_async) - { spit_recvs(fd_th, fd_tc); - } - } else - { genheader(); - fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_t.m\"\n"); - fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_t.b\"\n"); - fprintf(fd_th, "#define TRANSITIONS\t\"pan_t.t\"\n"); - fprintf(fd_tc, "extern int Maxbody;\n"); - fprintf(fd_tc, "#if VECTORSZ>32000\n"); - fprintf(fd_tc, " extern int *proc_offset;\n"); - fprintf(fd_tc, "#else\n"); - fprintf(fd_tc, " extern short *proc_offset;\n"); - fprintf(fd_tc, "#endif\n"); - fprintf(fd_tc, "extern uchar *proc_skip;\n"); - fprintf(fd_tc, "extern uchar *reached[];\n"); - fprintf(fd_tc, "extern uchar *accpstate[];\n"); - fprintf(fd_tc, "extern uchar *progstate[];\n"); - fprintf(fd_tc, "extern uchar *loopstate[];\n"); - fprintf(fd_tc, "extern uchar *stopstate[];\n"); - fprintf(fd_tc, "extern uchar *visstate[];\n\n"); - fprintf(fd_tc, "extern short *mapstate[];\n"); - - fprintf(fd_tc, "void\nini_claim(int n, int h)\n{"); - fprintf(fd_tc, "\textern State now;\n"); - fprintf(fd_tc, "\textern void set_claim(void);\n\n"); - fprintf(fd_tc, "#ifdef PROV\n"); - fprintf(fd_tc, " #include PROV\n"); - fprintf(fd_tc, "#endif\n"); - fprintf(fd_tc, "\tset_claim();\n"); - genother(); - fprintf(fd_tc, "\n\tswitch (n) {\n"); - genaddproc(); - fprintf(fd_tc, "\t}\n"); - fprintf(fd_tc, "\n}\n"); - fprintf(fd_tc, "int\nstep_claim(int o_pm, int tau, int tt, int ot, Trans *t)\n"); - fprintf(fd_tc, "{ int forw = t->forw; int _m = 0; extern char *noptr; int II=0;\n"); - fprintf(fd_tc, " extern State now;\n"); - fprintf(fd_tc, "#define continue return 0\n"); - fprintf(fd_tc, "#include \"pan_t.m\"\n"); - fprintf(fd_tc, "P999:\n\treturn _m;\n}\n"); - fprintf(fd_tc, "#undef continue\n"); - fprintf(fd_tc, "int\nrev_claim(int backw)\n{ return 0; }\n"); - fprintf(fd_tc, "#include TRANSITIONS\n"); - } - - if (separate != 2) - { c_wrapper(fd_tc); - c_chandump(fd_tc); - } - - fprintf(fd_th, "#if defined(BFS_PAR) || NCORE>1\n"); - fprintf(fd_th, " void e_critical(int);\n"); - fprintf(fd_th, " void x_critical(int);\n"); - fprintf(fd_th, " #ifdef BFS_PAR\n"); - fprintf(fd_th, " void bfs_main(int, int);\n"); - fprintf(fd_th, " void bfs_report_mem(void);\n"); - fprintf(fd_th, " #endif\n"); - fprintf(fd_th, "#endif\n"); - - fprintf(fd_th, "\n\n/* end of PAN_H */\n#endif\n"); - fclose(fd_th); - fclose(fd_tt); - fclose(fd_tm); - fclose(fd_tb); - - if (!(fd_th = fopen("pan.p", MFLAGS))) - { printf("spin: cannot create pan.p for -DBFS_PAR\n"); - return; /* we're done anyway */ - } - - ntimes(fd_th, 0, 1, pan_par); /* BFS_PAR */ - fclose(fd_th); - - fprintf(fd_tc, "\nTrans *t_id_lkup[%d];\n\n", globmax+1); - - if (separate != 2) - { fprintf(fd_tc, "\n#ifdef BFS_PAR\n\t#include \"pan.p\"\n#endif\n"); - } - fprintf(fd_tc, "\n/* end of pan.c */\n"); - fclose(fd_tc); + fprintf(fd_th, "#if !defined(HAS_LAST) && defined(BCS)\n"); + fprintf(fd_th, " #define HAS_LAST 1 /* use it, but */\n"); + fprintf(fd_th, " #ifndef STORE_LAST\n"); /* unless the user insists */ + fprintf(fd_th, " #define NO_LAST 1 /* don't store it */\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "#if defined(BCS) && defined(BITSTATE)\n"); + fprintf(fd_th, " #ifndef NO_CTX\n"); + fprintf(fd_th, " #define STORE_CTX 1\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "#ifdef NP\n"); + if (!has_np) + fprintf(fd_th, " #define HAS_NP 2\n"); + fprintf(fd_th, " #define VERI %d /* np_ */\n", nrRdy); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "#if defined(NOCLAIM) && defined(NP)\n"); + fprintf(fd_th, " #undef NOCLAIM\n"); + fprintf(fd_th, "#endif\n"); + if (claimproc) + { claimnr = fproc(claimproc); /* the default claim */ + fprintf(fd_th, "#ifndef NOCLAIM\n"); + fprintf(fd_th, " #define NCLAIMS %d\n", nclaims); + fprintf(fd_th, " #ifndef NP\n"); + fprintf(fd_th, " #define VERI %d\n", claimnr); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + } + if (eventmap) + { eventmapnr = fproc(eventmap); + fprintf(fd_th, "#define EVENT_TRACE %d\n", eventmapnr); + fprintf(fd_th, "#define endevent _endstate%d\n", eventmapnr); + if (eventmap[2] == 'o') /* ":notrace:" */ + fprintf(fd_th, "#define NEGATED_TRACE 1\n"); + } + + fprintf(fd_th, "\ntypedef struct S_F_MAP {\n"); + fprintf(fd_th, " char *fnm;\n\tint from;\n\tint upto;\n"); + fprintf(fd_th, "} S_F_MAP;\n"); + + fprintf(fd_tc, "/*** Generated by %s ***/\n", SpinVersion); + fprintf(fd_tc, "/*** From source: %s ***/\n\n", oFname->name); + + ntimes(fd_tc, 0, 1, Pre0); + + plunk_c_decls(fd_tc); /* types can be refered to in State */ + + switch (separate) { + case 0: fprintf(fd_tc, "#include \"pan.h\"\n"); break; + case 1: fprintf(fd_tc, "#include \"pan_s.h\"\n"); break; + case 2: fprintf(fd_tc, "#include \"pan_t.h\"\n"); break; + } + + if (separate != 2) + { fprintf(fd_tc, "char *TrailFile = PanSource; /* default */\n"); + fprintf(fd_tc, "char *trailfilename;\n"); + } + + fprintf(fd_tc, "#ifdef LOOPSTATE\n"); + fprintf(fd_tc, "double cnt_loops;\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "State A_Root; /* seed-state for cycles */\n"); + fprintf(fd_tc, "State now; /* the full state-vector */\n"); + fprintf(fd_tc, "#if NQS > 0\n"); + fprintf(fd_tc, "short q_flds[NQS+1];\n"); + fprintf(fd_tc, "short q_max[NQS+1];\n"); + fprintf(fd_tc, "#endif\n"); + + fprintf(fd_tc, "#ifndef XUSAFE\n"); + fprintf(fd_tc, " uchar q_claim[MAXQ+1];\n"); + fprintf(fd_tc, " char *q_name[MAXQ+1];\n"); + fprintf(fd_tc, " char *p_name[MAXPROC+1];\n"); + fprintf(fd_tc, "#endif\n"); + + plunk_c_fcts(fd_tc); /* State can be used in fcts */ + + if (separate != 2) + { ntimes(fd_tc, 0, 1, Preamble); + ntimes(fd_tc, 0, 1, Separate); /* things that moved out of pan.h */ + } else + { fprintf(fd_tc, "extern int verbose;\n"); + fprintf(fd_tc, "extern long depth, depthfound;\n"); + } + + fprintf(fd_tc, "#ifndef NOBOUNDCHECK\n"); + fprintf(fd_tc, " #define Index(x, y)\tBoundcheck(x, y, II, tt, t)\n"); + fprintf(fd_tc, "#else\n"); + fprintf(fd_tc, " #define Index(x, y)\tx\n"); + fprintf(fd_tc, "#endif\n"); + + c_preview(); /* sets hastrack */ + + for (p = ready; p; p = p->nxt) + mstp = MaX(p->s->maxel, mstp); + + if (separate != 2) + { fprintf(fd_tt, "#ifdef PEG\n"); + fprintf(fd_tt, "struct T_SRC {\n"); + fprintf(fd_tt, " char *fl; int ln;\n"); + fprintf(fd_tt, "} T_SRC[NTRANS];\n\n"); + fprintf(fd_tt, "void\ntr_2_src(int m, char *file, int ln)\n"); + fprintf(fd_tt, "{ T_SRC[m].fl = file;\n"); + fprintf(fd_tt, " T_SRC[m].ln = ln;\n"); + fprintf(fd_tt, "}\n\n"); + fprintf(fd_tt, "void\nputpeg(int n, int m)\n"); + fprintf(fd_tt, "{ printf(\"%%5d\ttrans %%4d \", m, n);\n"); + fprintf(fd_tt, " printf(\"%%s:%%d\\n\",\n"); + fprintf(fd_tt, " T_SRC[n].fl, T_SRC[n].ln);\n"); + fprintf(fd_tt, "}\n"); + if (!merger) + { fprintf(fd_tt, "#else\n"); + fprintf(fd_tt, "#define tr_2_src(m,f,l)\n"); + } + fprintf(fd_tt, "#endif\n\n"); + fprintf(fd_tt, "void\nsettable(void)\n{\tTrans *T;\n"); + fprintf(fd_tt, "\tTrans *settr(int, int, int, int, int,"); + fprintf(fd_tt, " char *, int, int, int);\n\n"); + fprintf(fd_tt, "\ttrans = (Trans ***) "); + fprintf(fd_tt, "emalloc(%d*sizeof(Trans **));\n", nrRdy+1); + /* +1 for np_ automaton */ + + if (separate == 1) + { + fprintf(fd_tm, " if (II == 0)\n"); + fprintf(fd_tm, " { _m = step_claim(trpt->o_pm, trpt->tau, tt, ot, t);\n"); + fprintf(fd_tm, " if (_m) goto P999; else continue;\n"); + fprintf(fd_tm, " } else\n"); + } + + fprintf(fd_tm, "#define rand pan_rand\n"); + fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); + fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); + fprintf(fd_tm, " #ifdef BFS_PAR\n"); + fprintf(fd_tm, " bfs_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(fd_tm, " #else\n"); + fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, t->forw);\n"); + fprintf(fd_tm, " #endif\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, " switch (t->forw) {\n"); + } else + { fprintf(fd_tt, "#ifndef PEG\n"); + fprintf(fd_tt, " #define tr_2_src(m,f,l)\n"); + fprintf(fd_tt, "#endif\n"); + fprintf(fd_tt, "void\nset_claim(void)\n{\tTrans *T;\n"); + fprintf(fd_tt, "\textern Trans ***trans;\n"); + fprintf(fd_tt, "\textern Trans *settr(int, int, int, int, int,"); + fprintf(fd_tt, " char *, int, int, int);\n\n"); + + fprintf(fd_tm, "#define rand pan_rand\n"); + fprintf(fd_tm, "#define pthread_equal(a,b) ((a)==(b))\n"); + fprintf(fd_tm, "#if defined(HAS_CODE) && defined(VERBOSE)\n"); + fprintf(fd_tm, " cpu_printf(\"Pr: %%d Tr: %%d\\n\", II, forw);\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, " switch (forw) {\n"); + } + + fprintf(fd_tm, " default: Uerror(\"bad forward move\");\n"); + fprintf(fd_tm, " case 0: /* if without executable clauses */\n"); + fprintf(fd_tm, " continue;\n"); + fprintf(fd_tm, " case 1: /* generic 'goto' or 'skip' */\n"); + if (separate != 2) + fprintf(fd_tm, " IfNotBlocked\n"); + fprintf(fd_tm, " _m = 3; goto P999;\n"); + fprintf(fd_tm, " case 2: /* generic 'else' */\n"); + if (separate == 2) + fprintf(fd_tm, " if (o_pm&1) continue;\n"); + else + { fprintf(fd_tm, " IfNotBlocked\n"); + fprintf(fd_tm, " if (trpt->o_pm&1) continue;\n"); + } + fprintf(fd_tm, " _m = 3; goto P999;\n"); + uniq = 3; + + if (separate == 1) + fprintf(fd_tb, " if (II == 0) goto R999;\n"); + + fprintf(fd_tb, " switch (t->back) {\n"); + fprintf(fd_tb, " default: Uerror(\"bad return move\");\n"); + fprintf(fd_tb, " case 0: goto R999; /* nothing to undo */\n"); + + for (p = ready; p; p = p->nxt) + { putproc(p); + } + + if (separate != 2) + { fprintf(fd_th, "\n"); + for (p = ready; p; p = p->nxt) + fprintf(fd_th, "extern short src_ln%d[];\n", p->tn); + for (p = ready; p; p = p->nxt) + fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", p->tn); + fprintf(fd_th, "\n"); + + fprintf(fd_tc, "uchar reached%d[3]; /* np_ */\n", nrRdy); + fprintf(fd_tc, "uchar *loopstate%d; /* np_ */\n", nrRdy); + + fprintf(fd_tc, "struct {\n"); + fprintf(fd_tc, " int tp; short *src;\n"); + fprintf(fd_tc, "} src_all[] = {\n"); + for (p = ready; p; p = p->nxt) + fprintf(fd_tc, " { %d, &src_ln%d[0] },\n", + p->tn, p->tn); + fprintf(fd_tc, " { 0, (short *) 0 }\n"); + fprintf(fd_tc, "};\n"); + + fprintf(fd_tc, "S_F_MAP *flref[] = {\n"); /* 5.3.0 */ + for (p = ready; p; p = p->nxt) + { fprintf(fd_tc, " src_file%d%c\n", p->tn, p->nxt?',':' '); + } + fprintf(fd_tc, "};\n\n"); + } else + { fprintf(fd_tc, "extern uchar reached%d[3]; /* np_ */\n", nrRdy); + } + + gencodetable(fd_tc); /* was th */ + + if (Unique < (1 << (8*sizeof(unsigned char)) )) /* was uniq before */ + { fprintf(fd_th, "#define T_ID unsigned char\n"); + } else if (Unique < (1 << (8*sizeof(unsigned short)) )) + { fprintf(fd_th, "#define T_ID unsigned short\n"); + } else + { fprintf(fd_th, "#define T_ID unsigned int\n"); + } + + if (separate != 1) + { tm_predef_np(); + tt_predef_np(); + } + fprintf(fd_tt, "}\n\n"); /* end of settable() */ + + fprintf(fd_tm, "#undef rand\n"); + fprintf(fd_tm, " }\n\n"); + fprintf(fd_tb, " }\n\n"); + + if (separate != 2) + { ntimes(fd_tt, 0, 1, Tail); + genheader(); + if (separate == 1) + { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_s.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_s.b\"\n"); + fprintf(fd_th, "#define SEPARATE\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan_s.t\"\n"); + fprintf(fd_th, "extern void ini_claim(int, int);\n"); + } else + { fprintf(fd_th, "#define FORWARD_MOVES\t\"pan.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan.b\"\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan.t\"\n"); + } + genaddproc(); + genother(); + genaddqueue(); + genunio(); + genconditionals(); + gensvmap(); + if (!run_lst) fatal("no runable process", (char *)0); + fprintf(fd_tc, "void\n"); + fprintf(fd_tc, "active_procs(void)\n{\n"); + + fprintf(fd_tc, " if (reversing == 0) {\n"); + reverse_procs(run_lst); + fprintf(fd_tc, " } else {\n"); + forward_procs(run_lst); + fprintf(fd_tc, " }\n"); + + fprintf(fd_tc, "}\n"); + ntimes(fd_tc, 0, 1, Dfa); + ntimes(fd_tc, 0, 1, Xpt); + + fprintf(fd_th, "#define NTRANS %d\n", uniq); + if (u_sync && !u_async) + { spit_recvs(fd_th, fd_tc); + } + } else + { genheader(); + fprintf(fd_th, "#define FORWARD_MOVES\t\"pan_t.m\"\n"); + fprintf(fd_th, "#define BACKWARD_MOVES\t\"pan_t.b\"\n"); + fprintf(fd_th, "#define TRANSITIONS\t\"pan_t.t\"\n"); + fprintf(fd_tc, "extern int Maxbody;\n"); + fprintf(fd_tc, "#if VECTORSZ>32000\n"); + fprintf(fd_tc, " extern int *proc_offset;\n"); + fprintf(fd_tc, "#else\n"); + fprintf(fd_tc, " extern short *proc_offset;\n"); + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "extern uchar *proc_skip;\n"); + fprintf(fd_tc, "extern uchar *reached[];\n"); + fprintf(fd_tc, "extern uchar *accpstate[];\n"); + fprintf(fd_tc, "extern uchar *progstate[];\n"); + fprintf(fd_tc, "extern uchar *loopstate[];\n"); + fprintf(fd_tc, "extern uchar *stopstate[];\n"); + fprintf(fd_tc, "extern uchar *visstate[];\n\n"); + fprintf(fd_tc, "extern short *mapstate[];\n"); + + fprintf(fd_tc, "void\nini_claim(int n, int h)\n{"); + fprintf(fd_tc, "\textern State now;\n"); + fprintf(fd_tc, "\textern void set_claim(void);\n\n"); + fprintf(fd_tc, "#ifdef PROV\n"); + fprintf(fd_tc, " #include PROV\n"); + fprintf(fd_tc, "#endif\n"); + fprintf(fd_tc, "\tset_claim();\n"); + genother(); + fprintf(fd_tc, "\n\tswitch (n) {\n"); + genaddproc(); + fprintf(fd_tc, "\t}\n"); + fprintf(fd_tc, "\n}\n"); + fprintf(fd_tc, "int\nstep_claim(int o_pm, int tau, int tt, int ot, Trans *t)\n"); + fprintf(fd_tc, "{ int forw = t->forw; int _m = 0; extern char *noptr; int II=0;\n"); + fprintf(fd_tc, " extern State now;\n"); + fprintf(fd_tc, "#define continue return 0\n"); + fprintf(fd_tc, "#include \"pan_t.m\"\n"); + fprintf(fd_tc, "P999:\n\treturn _m;\n}\n"); + fprintf(fd_tc, "#undef continue\n"); + fprintf(fd_tc, "int\nrev_claim(int backw)\n{ return 0; }\n"); + fprintf(fd_tc, "#include TRANSITIONS\n"); + } + + if (separate != 2) + { c_wrapper(fd_tc); + c_chandump(fd_tc); + } + + fprintf(fd_th, "#if defined(BFS_PAR) || NCORE>1\n"); + fprintf(fd_th, " void e_critical(int);\n"); + fprintf(fd_th, " void x_critical(int);\n"); + fprintf(fd_th, " #ifdef BFS_PAR\n"); + fprintf(fd_th, " void bfs_main(int, int);\n"); + fprintf(fd_th, " void bfs_report_mem(void);\n"); + fprintf(fd_th, " #endif\n"); + fprintf(fd_th, "#endif\n"); + + fprintf(fd_th, "\n\n/* end of PAN_H */\n#endif\n"); + fclose(fd_th); + fclose(fd_tt); + fclose(fd_tm); + fclose(fd_tb); + + if (!(fd_th = fopen("pan.p", MFLAGS))) + { printf("spin: cannot create pan.p for -DBFS_PAR\n"); + return; /* we're done anyway */ + } + + ntimes(fd_th, 0, 1, pan_par); /* BFS_PAR */ + fclose(fd_th); + + fprintf(fd_tc, "\nTrans *t_id_lkup[%d];\n\n", globmax+1); + + if (separate != 2) + { fprintf(fd_tc, "\n#ifdef BFS_PAR\n\t#include \"pan.p\"\n#endif\n"); + } + fprintf(fd_tc, "\n/* end of pan.c */\n"); + fclose(fd_tc); } static int find_id(Symbol *s) -{ ProcList *p; +{ ProcList *p; - if (s) - for (p = ready; p; p = p->nxt) - if (s == p->n) - return p->tn; - return 0; + if (s) + for (p = ready; p; p = p->nxt) + if (s == p->n) + return p->tn; + return 0; } static void dolen(Symbol *s, char *pre, int pid, int ai, int qln) { - if (ai > 0) - fprintf(fd_tc, "\n\t\t\t || "); - fprintf(fd_tc, "%s(", pre); - if (!(s->hidden&1)) - { if (s->context) - fprintf(fd_tc, "(int) ( ((P%d *)_this)->", pid); - else - fprintf(fd_tc, "(int) ( now."); - } - fprintf(fd_tc, "%s", s->name); - if (qln > 1 || s->isarray) fprintf(fd_tc, "[%d]", ai); - fprintf(fd_tc, ") )"); + if (ai > 0) + fprintf(fd_tc, "\n\t\t\t || "); + fprintf(fd_tc, "%s(", pre); + if (!(s->hidden&1)) + { if (s->context) + fprintf(fd_tc, "(int) ( ((P%d *)_this)->", pid); + else + fprintf(fd_tc, "(int) ( now."); + } + fprintf(fd_tc, "%s", s->name); + if (qln > 1 || s->isarray) fprintf(fd_tc, "[%d]", ai); + fprintf(fd_tc, ") )"); } -struct AA { char TT[9]; char CC[8]; }; +struct AA { char TT[9]; char CC[8]; }; static struct AA BB[4] = { - { "Q_FULL_F", " q_full" }, - { "Q_FULL_T", "!q_full" }, - { "Q_EMPT_F", " !q_len" }, - { "Q_EMPT_T", " q_len" } - }; + { "Q_FULL_F", " q_full" }, + { "Q_FULL_T", "!q_full" }, + { "Q_EMPT_F", " !q_len" }, + { "Q_EMPT_T", " q_len" } + }; static struct AA DD[4] = { - { "Q_FULL_F", " q_e_f" }, /* empty or full */ - { "Q_FULL_T", "!q_full" }, - { "Q_EMPT_F", " q_e_f" }, - { "Q_EMPT_T", " q_len" } - }; - /* this reduces the number of cases where 's' and 'r' - are considered conditionally safe under the - partial order reduction rules; as a price for - this simple implementation, it also affects the - cases where nfull and nempty can be considered - safe -- since these are labeled the same way as - 's' and 'r' respectively - it only affects reduction, not functionality - */ + { "Q_FULL_F", " q_e_f" }, /* empty or full */ + { "Q_FULL_T", "!q_full" }, + { "Q_EMPT_F", " q_e_f" }, + { "Q_EMPT_T", " q_len" } + }; + /* this reduces the number of cases where 's' and 'r' + are considered conditionally safe under the + partial order reduction rules; as a price for + this simple implementation, it also affects the + cases where nfull and nempty can be considered + safe -- since these are labeled the same way as + 's' and 'r' respectively + it only affects reduction, not functionality + */ void bb_or_dd(int j, int which) { - if (which) - { if (has_unless) - fprintf(fd_tc, "%s", DD[j].CC); - else - fprintf(fd_tc, "%s", BB[j].CC); - } else - { if (has_unless) - fprintf(fd_tc, "%s", DD[j].TT); - else - fprintf(fd_tc, "%s", BB[j].TT); - } + if (which) + { if (has_unless) + fprintf(fd_tc, "%s", DD[j].CC); + else + fprintf(fd_tc, "%s", BB[j].CC); + } else + { if (has_unless) + fprintf(fd_tc, "%s", DD[j].TT); + else + fprintf(fd_tc, "%s", BB[j].TT); + } } void Done_case(char *nm, Symbol *z) -{ int j, k; - int nid = z->Nid; - int qln = z->nel; - - fprintf(fd_tc, "\t\tcase %d: if (", nid); - for (j = 0; j < 4; j++) - { fprintf(fd_tc, "\t(t->ty[i] == "); - bb_or_dd(j, 0); - fprintf(fd_tc, " && ("); - for (k = 0; k < qln; k++) - { if (k > 0) - fprintf(fd_tc, "\n\t\t\t || "); - bb_or_dd(j, 1); - fprintf(fd_tc, "(%s%s", nm, z->name); - if (qln > 1) - fprintf(fd_tc, "[%d]", k); - fprintf(fd_tc, ")"); - } - fprintf(fd_tc, "))\n\t\t\t "); - if (j < 3) - fprintf(fd_tc, "|| "); - else - fprintf(fd_tc, " "); - } - fprintf(fd_tc, ") return 0; break;\n"); +{ int j, k; + int nid = z->Nid; + int qln = z->nel; + + fprintf(fd_tc, "\t\tcase %d: if (", nid); + for (j = 0; j < 4; j++) + { fprintf(fd_tc, "\t(t->ty[i] == "); + bb_or_dd(j, 0); + fprintf(fd_tc, " && ("); + for (k = 0; k < qln; k++) + { if (k > 0) + fprintf(fd_tc, "\n\t\t\t || "); + bb_or_dd(j, 1); + fprintf(fd_tc, "(%s%s", nm, z->name); + if (qln > 1) + fprintf(fd_tc, "[%d]", k); + fprintf(fd_tc, ")"); + } + fprintf(fd_tc, "))\n\t\t\t "); + if (j < 3) + fprintf(fd_tc, "|| "); + else + fprintf(fd_tc, " "); + } + fprintf(fd_tc, ") return 0; break;\n"); } static void Docase(Symbol *s, int pid, int nid) -{ int i, j; - - fprintf(fd_tc, "\t\tcase %d: if (", nid); - for (j = 0; j < 4; j++) - { fprintf(fd_tc, "\t(t->ty[i] == "); - bb_or_dd(j, 0); - fprintf(fd_tc, " && ("); - if (has_unless) - { for (i = 0; i < s->nel; i++) - dolen(s, DD[j].CC, pid, i, s->nel); - } else - { for (i = 0; i < s->nel; i++) - dolen(s, BB[j].CC, pid, i, s->nel); - } - fprintf(fd_tc, "))\n\t\t\t "); - if (j < 3) - fprintf(fd_tc, "|| "); - else - fprintf(fd_tc, " "); - } - fprintf(fd_tc, ") return 0; break;\n"); +{ int i, j; + + fprintf(fd_tc, "\t\tcase %d: if (", nid); + for (j = 0; j < 4; j++) + { fprintf(fd_tc, "\t(t->ty[i] == "); + bb_or_dd(j, 0); + fprintf(fd_tc, " && ("); + if (has_unless) + { for (i = 0; i < s->nel; i++) + dolen(s, DD[j].CC, pid, i, s->nel); + } else + { for (i = 0; i < s->nel; i++) + dolen(s, BB[j].CC, pid, i, s->nel); + } + fprintf(fd_tc, "))\n\t\t\t "); + if (j < 3) + fprintf(fd_tc, "|| "); + else + fprintf(fd_tc, " "); + } + fprintf(fd_tc, ") return 0; break;\n"); } static void genconditionals(void) -{ Symbol *s; - int last=0, j; - extern Ordered *all_names; - Ordered *walk; - - fprintf(fd_th, "#define LOCAL 1\n"); - fprintf(fd_th, "#define Q_FULL_F 2\n"); - fprintf(fd_th, "#define Q_EMPT_F 3\n"); - fprintf(fd_th, "#define Q_EMPT_T 4\n"); - fprintf(fd_th, "#define Q_FULL_T 5\n"); - fprintf(fd_th, "#define TIMEOUT_F 6\n"); - fprintf(fd_th, "#define GLOBAL 7\n"); - fprintf(fd_th, "#define BAD 8\n"); - fprintf(fd_th, "#define ALPHA_F 9\n"); - - fprintf(fd_tc, "int\n"); - fprintf(fd_tc, "q_cond(short II, Trans *t)\n"); - fprintf(fd_tc, "{ int i = 0;\n"); - fprintf(fd_tc, " for (i = 0; i < 6; i++)\n"); - fprintf(fd_tc, " { if (t->ty[i] == TIMEOUT_F) return %s;\n", - (Etimeouts)?"(!(trpt->tau&1))":"1"); - fprintf(fd_tc, " if (t->ty[i] == ALPHA_F)\n"); - fprintf(fd_tc, "#ifdef GLOB_ALPHA\n"); - fprintf(fd_tc, " return 0;\n"); - fprintf(fd_tc, "#else\n\t\t\treturn "); - fprintf(fd_tc, "(II+1 == (short) now._nr_pr && II+1 < MAXPROC);\n"); - fprintf(fd_tc, "#endif\n"); - - /* we switch on the chan name from the spec (as identified by - * the corresponding Nid number) rather than the actual qid - * because we cannot predict at compile time which specific qid - * will be accessed by the statement at runtime. that is: - * we do not know which qid to pass to q_cond at runtime - * but we do know which name is used. if it's a chan array, we - * must check all elements of the array for compliance (bummer) - */ - fprintf(fd_tc, " switch (t->qu[i]) {\n"); - fprintf(fd_tc, " case 0: break;\n"); - - for (walk = all_names; walk; walk = walk->next) - { s = walk->entry; - if (s->owner) continue; - j = find_id(s->context); - if (s->type == CHAN) - { if (last == s->Nid) continue; /* chan array */ - last = s->Nid; - Docase(s, j, last); - } else if (s->type == STRUCT) - { /* struct may contain a chan */ - char pregat[128]; - strcpy(pregat, ""); - if (!(s->hidden&1)) - { if (s->context) - sprintf(pregat, "((P%d *)_this)->",j); - else - sprintf(pregat, "now."); - } - walk2_struct(pregat, s); - } - } - fprintf(fd_tc, " \tdefault: Uerror(\"unknown qid - q_cond\");\n"); - fprintf(fd_tc, " \t\t\treturn 0;\n"); - fprintf(fd_tc, " \t}\n"); - fprintf(fd_tc, " }\n"); - fprintf(fd_tc, " return 1;\n"); - fprintf(fd_tc, "}\n"); +{ Symbol *s; + int last=0, j; + extern Ordered *all_names; + Ordered *walk; + + fprintf(fd_th, "#define LOCAL 1\n"); + fprintf(fd_th, "#define Q_FULL_F 2\n"); + fprintf(fd_th, "#define Q_EMPT_F 3\n"); + fprintf(fd_th, "#define Q_EMPT_T 4\n"); + fprintf(fd_th, "#define Q_FULL_T 5\n"); + fprintf(fd_th, "#define TIMEOUT_F 6\n"); + fprintf(fd_th, "#define GLOBAL 7\n"); + fprintf(fd_th, "#define BAD 8\n"); + fprintf(fd_th, "#define ALPHA_F 9\n"); + + fprintf(fd_tc, "int\n"); + fprintf(fd_tc, "q_cond(short II, Trans *t)\n"); + fprintf(fd_tc, "{ int i = 0;\n"); + fprintf(fd_tc, " for (i = 0; i < 6; i++)\n"); + fprintf(fd_tc, " { if (t->ty[i] == TIMEOUT_F) return %s;\n", + (Etimeouts)?"(!(trpt->tau&1))":"1"); + fprintf(fd_tc, " if (t->ty[i] == ALPHA_F)\n"); + fprintf(fd_tc, "#ifdef GLOB_ALPHA\n"); + fprintf(fd_tc, " return 0;\n"); + fprintf(fd_tc, "#else\n\t\t\treturn "); + fprintf(fd_tc, "(II+1 == (short) now._nr_pr && II+1 < MAXPROC);\n"); + fprintf(fd_tc, "#endif\n"); + + /* we switch on the chan name from the spec (as identified by + * the corresponding Nid number) rather than the actual qid + * because we cannot predict at compile time which specific qid + * will be accessed by the statement at runtime. that is: + * we do not know which qid to pass to q_cond at runtime + * but we do know which name is used. if it's a chan array, we + * must check all elements of the array for compliance (bummer) + */ + fprintf(fd_tc, " switch (t->qu[i]) {\n"); + fprintf(fd_tc, " case 0: break;\n"); + + for (walk = all_names; walk; walk = walk->next) + { s = walk->entry; + if (s->owner) continue; + j = find_id(s->context); + if (s->type == CHAN) + { if (last == s->Nid) continue; /* chan array */ + last = s->Nid; + Docase(s, j, last); + } else if (s->type == STRUCT) + { /* struct may contain a chan */ + char pregat[128]; + strcpy(pregat, ""); + if (!(s->hidden&1)) + { if (s->context) + sprintf(pregat, "((P%d *)_this)->",j); + else + sprintf(pregat, "now."); + } + walk2_struct(pregat, s); + } + } + fprintf(fd_tc, " \tdefault: Uerror(\"unknown qid - q_cond\");\n"); + fprintf(fd_tc, " \t\t\treturn 0;\n"); + fprintf(fd_tc, " \t}\n"); + fprintf(fd_tc, " }\n"); + fprintf(fd_tc, " return 1;\n"); + fprintf(fd_tc, "}\n"); } static void putproc(ProcList *p) -{ Pid_nr = p->tn; - Det = p->det; +{ Pid_nr = p->tn; + Det = p->det; - if (pid_is_claim(Pid_nr) - && separate == 1) - { fprintf(fd_th, "extern uchar reached%d[];\n", Pid_nr); + if (pid_is_claim(Pid_nr) + && separate == 1) + { fprintf(fd_th, "extern uchar reached%d[];\n", Pid_nr); #if 0 - fprintf(fd_th, "extern short _nstates%d;\n", Pid_nr); + fprintf(fd_th, "extern short _nstates%d;\n", Pid_nr); #else - fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", - Pid_nr, p->s->maxel, p->n->name); + fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", + Pid_nr, p->s->maxel, p->n->name); #endif - fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); - fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); - fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", Pid_nr); - fprintf(fd_th, "#define _endstate%d %d\n", - Pid_nr, p->s->last?p->s->last->seqno:0); - return; - } - if (!pid_is_claim(Pid_nr) - && separate == 2) - { fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); - fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); - return; - } - - AllGlobal = (p->prov)?1:0; /* process has provided clause */ - - fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", - Pid_nr, p->s->maxel, p->n->name); + fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); + fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); + fprintf(fd_th, "extern S_F_MAP src_file%d[];\n", Pid_nr); + fprintf(fd_th, "#define _endstate%d %d\n", + Pid_nr, p->s->last?p->s->last->seqno:0); + return; + } + if (!pid_is_claim(Pid_nr) + && separate == 2) + { fprintf(fd_th, "extern short src_ln%d[];\n", Pid_nr); + fprintf(fd_th, "extern uchar *loopstate%d;\n", Pid_nr); + return; + } + + AllGlobal = (p->prov)?1:0; /* process has provided clause */ + + fprintf(fd_th, "\n#define _nstates%d %d\t/* %s */\n", + Pid_nr, p->s->maxel, p->n->name); /* new */ - fprintf(fd_th, "#define minseq%d %d\n", Pid_nr, find_min(p->s)); - fprintf(fd_th, "#define maxseq%d %d\n", Pid_nr, find_max(p->s)); + fprintf(fd_th, "#define minseq%d %d\n", Pid_nr, find_min(p->s)); + fprintf(fd_th, "#define maxseq%d %d\n", Pid_nr, find_max(p->s)); /* end */ - if (Pid_nr == eventmapnr) - fprintf(fd_th, "#define nstates_event _nstates%d\n", Pid_nr); - - fprintf(fd_th, "#define _endstate%d %d\n", Pid_nr, p->s->last?p->s->last->seqno:0); - - if (p->b == N_CLAIM || p->b == E_TRACE || p->b == N_TRACE) - { fprintf(fd_tm, "\n /* CLAIM %s */\n", p->n->name); - fprintf(fd_tb, "\n /* CLAIM %s */\n", p->n->name); - } - else - { fprintf(fd_tm, "\n /* PROC %s */\n", p->n->name); - fprintf(fd_tb, "\n /* PROC %s */\n", p->n->name); - } - fprintf(fd_tt, "\n /* proctype %d: %s */\n", Pid_nr, p->n->name); - fprintf(fd_tt, "\n trans[%d] = (Trans **)", Pid_nr); - fprintf(fd_tt, " emalloc(%d*sizeof(Trans *));\n\n", p->s->maxel); - - if (Pid_nr == eventmapnr) - { fprintf(fd_th, "\n#define in_s_scope(x_y3_) 0"); - fprintf(fd_tc, "\n#define in_r_scope(x_y3_) 0"); - } - put_seq(p->s, 2, 0); - if (Pid_nr == eventmapnr) - { fprintf(fd_th, "\n\n"); - fprintf(fd_tc, "\n\n"); - } - dumpsrc(p->s->maxel, Pid_nr); + if (Pid_nr == eventmapnr) + fprintf(fd_th, "#define nstates_event _nstates%d\n", Pid_nr); + + fprintf(fd_th, "#define _endstate%d %d\n", Pid_nr, p->s->last?p->s->last->seqno:0); + + if (p->b == N_CLAIM || p->b == E_TRACE || p->b == N_TRACE) + { fprintf(fd_tm, "\n /* CLAIM %s */\n", p->n->name); + fprintf(fd_tb, "\n /* CLAIM %s */\n", p->n->name); + } + else + { fprintf(fd_tm, "\n /* PROC %s */\n", p->n->name); + fprintf(fd_tb, "\n /* PROC %s */\n", p->n->name); + } + fprintf(fd_tt, "\n /* proctype %d: %s */\n", Pid_nr, p->n->name); + fprintf(fd_tt, "\n trans[%d] = (Trans **)", Pid_nr); + fprintf(fd_tt, " emalloc(%d*sizeof(Trans *));\n\n", p->s->maxel); + + if (Pid_nr == eventmapnr) + { fprintf(fd_th, "\n#define in_s_scope(x_y3_) 0"); + fprintf(fd_tc, "\n#define in_r_scope(x_y3_) 0"); + } + put_seq(p->s, 2, 0); + if (Pid_nr == eventmapnr) + { fprintf(fd_th, "\n\n"); + fprintf(fd_tc, "\n\n"); + } + dumpsrc(p->s->maxel, Pid_nr); } static void addTpe(int x) -{ int i; +{ int i; - if (x <= 2) return; + if (x <= 2) return; - for (i = 0; i < T_sum; i++) - if (TPE[i] == x) - return; - TPE[(T_sum++)%2] = x; + for (i = 0; i < T_sum; i++) + if (TPE[i] == x) + return; + TPE[(T_sum++)%2] = x; } static void cnt_seq(Sequence *s) -{ Element *f; - SeqList *h; - - if (s) - for (f = s->frst; f; f = f->nxt) - { Tpe(f->n); /* sets EPT */ - addTpe(EPT[0]); - addTpe(EPT[1]); - for (h = f->sub; h; h = h->nxt) - cnt_seq(h->this); - if (f == s->last) - break; - } +{ Element *f; + SeqList *h; + + if (s) + for (f = s->frst; f; f = f->nxt) + { Tpe(f->n); /* sets EPT */ + addTpe(EPT[0]); + addTpe(EPT[1]); + for (h = f->sub; h; h = h->nxt) + cnt_seq(h->thisS); + if (f == s->last) + break; + } } static void typ_seq(Sequence *s) { - T_sum = 0; - TPE[0] = 2; TPE[1] = 0; - cnt_seq(s); - if (T_sum > 2) /* more than one type */ - { TPE[0] = 5*DELTA; /* non-mixing */ - TPE[1] = 0; - } + T_sum = 0; + TPE[0] = 2; TPE[1] = 0; + cnt_seq(s); + if (T_sum > 2) /* more than one type */ + { TPE[0] = 5*DELTA; /* non-mixing */ + TPE[1] = 0; + } } static int hidden(Lextok *n) { - if (n) - switch (n->ntyp) { - case FULL: case EMPTY: - case NFULL: case NEMPTY: case TIMEOUT: - Nn[(T_mus++)%2] = n; - break; - case '!': case UMIN: case '~': case ASSERT: case 'c': - (void) hidden(n->lft); - break; - case '/': case '*': case '-': case '+': - case '%': case LT: case GT: case '&': case '^': - case '|': case LE: case GE: case NE: case '?': - case EQ: case OR: case AND: case LSHIFT: case RSHIFT: - (void) hidden(n->lft); - (void) hidden(n->rgt); - break; - } - return T_mus; + if (n) + switch (n->ntyp) { + case FULL: case EMPTY: + case NFULL: case NEMPTY: case TIMEOUT: + Nn[(T_mus++)%2] = n; + break; + case '!': case UMIN: case '~': case ASSERT: case 'c': + (void) hidden(n->lft); + break; + case '/': case '*': case '-': case '+': + case '%': case LT: case GT: case '&': case '^': + case '|': case LE: case GE: case NE: case '?': + case EQ: case OR: case AND: case LSHIFT: case RSHIFT: + (void) hidden(n->lft); + (void) hidden(n->rgt); + break; + } + return T_mus; } static int getNid(Lextok *n) { - if (n->sym - && n->sym->type == STRUCT - && n->rgt && n->rgt->lft) - return getNid(n->rgt->lft); - - if (!n->sym || n->sym->Nid == 0) - { fatal("bad channel name '%s'", - (n->sym)?n->sym->name:"no name"); - } - return n->sym->Nid; + if (n->sym + && n->sym->type == STRUCT + && n->rgt && n->rgt->lft) + return getNid(n->rgt->lft); + + if (!n->sym || n->sym->Nid == 0) + { fatal("bad channel name '%s'", + (n->sym)?n->sym->name:"no name"); + } + return n->sym->Nid; } static int valTpe(Lextok *n) -{ int res = 2; - /* - 2 = local - 2+1 .. 2+1*DELTA = nfull, 's' - require q_full==false - 2+1+1*DELTA .. 2+2*DELTA = nempty, 'r' - require q_len!=0 - 2+1+2*DELTA .. 2+3*DELTA = empty - require q_len==0 - 2+1+3*DELTA .. 2+4*DELTA = full - require q_full==true - 5*DELTA = non-mixing (i.e., always makes the selection global) - 6*DELTA = timeout (conditionally safe) - 7*DELTA = @, process deletion (conditionally safe) - */ - switch (n->ntyp) { /* a series of fall-thru cases: */ - case FULL: res += DELTA; /* add 3*DELTA + chan nr */ - case EMPTY: res += DELTA; /* add 2*DELTA + chan nr */ - case 'r': - case NEMPTY: res += DELTA; /* add 1*DELTA + chan nr */ - case 's': - case NFULL: res += getNid(n->lft); /* add channel nr */ - break; - - case TIMEOUT: res = 6*DELTA; break; - case '@': res = 7*DELTA; break; - default: break; - } - return res; +{ int res = 2; + /* + 2 = local + 2+1 .. 2+1*DELTA = nfull, 's' - require q_full==false + 2+1+1*DELTA .. 2+2*DELTA = nempty, 'r' - require q_len!=0 + 2+1+2*DELTA .. 2+3*DELTA = empty - require q_len==0 + 2+1+3*DELTA .. 2+4*DELTA = full - require q_full==true + 5*DELTA = non-mixing (i.e., always makes the selection global) + 6*DELTA = timeout (conditionally safe) + 7*DELTA = @, process deletion (conditionally safe) + */ + switch (n->ntyp) { /* a series of fall-thru cases: */ + case FULL: res += DELTA; /* add 3*DELTA + chan nr */ + /*fallthrough*/ + case EMPTY: res += DELTA; /* add 2*DELTA + chan nr */ + /*fallthrough*/ + case 'r': + /*fallthrough*/ + case NEMPTY: res += DELTA; /* add 1*DELTA + chan nr */ + /*fallthrough*/ + case 's': + /*fallthrough*/ + case NFULL: res += getNid(n->lft); /* add channel nr */ + break; + + case TIMEOUT: res = 6*DELTA; break; + case '@': res = 7*DELTA; break; + default: break; + } + return res; } static void -Tpe(Lextok *n) /* mixing in selections */ +Tpe(Lextok *n) /* mixing in selections */ { - EPT[0] = 2; EPT[1] = 0; + EPT[0] = 2; EPT[1] = 0; - if (!n) return; + if (!n) return; - T_mus = 0; - Nn[0] = Nn[1] = ZN; + T_mus = 0; + Nn[0] = Nn[1] = ZN; - if (n->ntyp == 'c') - { if (hidden(n->lft) > 2) - { EPT[0] = 5*DELTA; /* non-mixing */ - EPT[1] = 0; - return; - } - } else - Nn[0] = n; + if (n->ntyp == 'c') + { if (hidden(n->lft) > 2) + { EPT[0] = 5*DELTA; /* non-mixing */ + EPT[1] = 0; + return; + } + } else + Nn[0] = n; - if (Nn[0]) EPT[0] = valTpe(Nn[0]); - if (Nn[1]) EPT[1] = valTpe(Nn[1]); + if (Nn[0]) EPT[0] = valTpe(Nn[0]); + if (Nn[1]) EPT[1] = valTpe(Nn[1]); } static void put_escp(Element *e) -{ int n; - SeqList *x; - - if (e->esc /* && e->n->ntyp != GOTO */ && e->n->ntyp != '.') - { for (x = e->esc, n = 0; x; x = x->nxt, n++) - { int i = huntele(x->this->frst, e->status, -1)->seqno; - fprintf(fd_tt, "\ttrans[%d][%d]->escp[%d] = %d;\n", - Pid_nr, e->seqno, n, i); - fprintf(fd_tt, "\treached%d[%d] = 1;\n", - Pid_nr, i); - } - for (x = e->esc, n=0; x; x = x->nxt, n++) - { fprintf(fd_tt, " /* escape #%d: %d */\n", n, - huntele(x->this->frst, e->status, -1)->seqno); - put_seq(x->this, 2, 0); /* args?? */ - } - fprintf(fd_tt, " /* end-escapes */\n"); - } +{ int n; + SeqList *x; + + if (e->esc /* && e->n->ntyp != GOTO */ && e->n->ntyp != '.') + { for (x = e->esc, n = 0; x; x = x->nxt, n++) + { int i = huntele(x->thisS->frst, e->status, -1)->seqno; + fprintf(fd_tt, "\ttrans[%d][%d]->escp[%d] = %d;\n", + Pid_nr, e->seqno, n, i); + fprintf(fd_tt, "\treached%d[%d] = 1;\n", + Pid_nr, i); + } + for (x = e->esc, n=0; x; x = x->nxt, n++) + { fprintf(fd_tt, " /* escape #%d: %d */\n", n, + huntele(x->thisS->frst, e->status, -1)->seqno); + put_seq(x->thisS, 2, 0); /* args?? */ + } + fprintf(fd_tt, " /* end-escapes */\n"); + } } static void put_sub(Element *e, int Tt0, int Tt1) -{ Sequence *s = e->n->sl->this; - Element *g = ZE; - int a; - - patch_atomic(s); - putskip(s->frst->seqno); - g = huntstart(s->frst); - a = g->seqno; - - if (0) printf("put_sub %d -> %d -> %d\n", e->seqno, s->frst->seqno, a); - - if ((e->n->ntyp == ATOMIC - || e->n->ntyp == D_STEP) - && scan_seq(s)) - mark_seq(s); - s->last->nxt = e->nxt; - - typ_seq(s); /* sets TPE */ - - if (e->n->ntyp == D_STEP) - { int inherit = (e->status&(ATOM|L_ATOM)); - fprintf(fd_tm, "\tcase %d: ", uniq++); - fprintf(fd_tm, "// STATE %d - %s:%d - [", - e->seqno, e->n->fn->name, e->n->ln); - comment(fd_tm, e->n, 0); - fprintf(fd_tm, "]\n\t\t"); - - if (s->last->n->ntyp == BREAK) - OkBreak = target(huntele(s->last->nxt, - s->last->status, -1))->Seqno; - else - OkBreak = -1; - - if (!putcode(fd_tm, s, e->nxt, 0, e->n->ln, e->seqno)) - { - fprintf(fd_tm, "\n#if defined(C_States) && (HAS_TRACK==1)\n"); - fprintf(fd_tm, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); - fprintf(fd_tm, "#endif\n"); - - fprintf(fd_tm, "\t\t_m = %d", getweight(s->frst->n)); - if (m_loss && s->frst->n->ntyp == 's') - fprintf(fd_tm, "+delta_m; delta_m = 0"); - fprintf(fd_tm, "; goto P999;\n\n"); - } - - fprintf(fd_tb, "\tcase %d: ", uniq-1); - fprintf(fd_tb, "// STATE %d\n", e->seqno); - fprintf(fd_tb, "\t\tsv_restor();\n"); - fprintf(fd_tb, "\t\tgoto R999;\n"); - if (e->nxt) - a = huntele(e->nxt, e->status, -1)->seqno; - else - a = 0; - tr_map(uniq-1, e); - fprintf(fd_tt, "/*->*/\ttrans[%d][%d]\t= ", - Pid_nr, e->seqno); - fprintf(fd_tt, "settr(%d,%d,%d,%d,%d,\"", - e->Seqno, D_ATOM|inherit, a, uniq-1, uniq-1); +{ Sequence *s = e->n->sl->thisS; + Element *g = ZE; + int a; + + patch_atomic(s); + putskip(s->frst->seqno); + g = huntstart(s->frst); + a = g->seqno; + + if (0) printf("put_sub %d -> %d -> %d\n", e->seqno, s->frst->seqno, a); + + if ((e->n->ntyp == ATOMIC + || e->n->ntyp == D_STEP) + && scan_seq(s)) + mark_seq(s); + s->last->nxt = e->nxt; + + typ_seq(s); /* sets TPE */ + + if (e->n->ntyp == D_STEP) + { int inherit = (e->status&(ATOM|L_ATOM)); + fprintf(fd_tm, "\tcase %d: ", uniq++); + fprintf(fd_tm, "// STATE %d - %s:%d - [", + e->seqno, e->n->fn->name, e->n->ln); + comment(fd_tm, e->n, 0); + fprintf(fd_tm, "]\n\t\t"); + + if (s->last->n->ntyp == BREAK) + OkBreak = target(huntele(s->last->nxt, + s->last->status, -1))->Seqno; + else + OkBreak = -1; + + if (!putcode(fd_tm, s, e->nxt, 0, e->n->ln, e->seqno)) + { + fprintf(fd_tm, "\n#if defined(C_States) && (HAS_TRACK==1)\n"); + fprintf(fd_tm, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); + fprintf(fd_tm, "#endif\n"); + + fprintf(fd_tm, "\t\t_m = %d", getweight(s->frst->n)); + if (m_loss && s->frst->n->ntyp == 's') + fprintf(fd_tm, "+delta_m; delta_m = 0"); + fprintf(fd_tm, "; goto P999;\n\n"); + } + + fprintf(fd_tb, "\tcase %d: ", uniq-1); + fprintf(fd_tb, "// STATE %d\n", e->seqno); + fprintf(fd_tb, "\t\tsv_restor();\n"); + fprintf(fd_tb, "\t\tgoto R999;\n"); + if (e->nxt) + a = huntele(e->nxt, e->status, -1)->seqno; + else + a = 0; + tr_map(uniq-1, e); + fprintf(fd_tt, "/*->*/\ttrans[%d][%d]\t= ", + Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,%d,%d,%d,\"", + e->Seqno, D_ATOM|inherit, a, uniq-1, uniq-1); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); - fprintf(fd_tt, "%d, %d);\n", TPE[0], TPE[1]); - put_escp(e); - } else - { /* ATOMIC or NON_ATOMIC */ - fprintf(fd_tt, "\tT = trans[ %d][%d] = ", Pid_nr, e->seqno); - fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", - e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0); + fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); + fprintf(fd_tt, "%d, %d);\n", TPE[0], TPE[1]); + put_escp(e); + } else + { /* ATOMIC or NON_ATOMIC */ + fprintf(fd_tt, "\tT = trans[ %d][%d] = ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", + e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - if ((e->status&CHECK2) - || (g->status&CHECK2)) - s->frst->status |= I_GLOB; - fprintf(fd_tt, "\", %d, %d, %d);", - (s->frst->status&I_GLOB)?1:0, Tt0, Tt1); - blurb(fd_tt, e); - fprintf(fd_tt, "\tT->nxt\t= "); - fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", - e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0, a); + if ((e->status&CHECK2) + || (g->status&CHECK2)) + s->frst->status |= I_GLOB; + fprintf(fd_tt, "\", %d, %d, %d);", + (s->frst->status&I_GLOB)?1:0, Tt0, Tt1); + blurb(fd_tt, e); + fprintf(fd_tt, "\tT->nxt\t= "); + fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", + e->Seqno, (e->n->ntyp == ATOMIC)?ATOM:0, a); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); - if (e->n->ntyp == NON_ATOMIC) - { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); - blurb(fd_tt, e); - put_seq(s, Tt0, Tt1); - } else - { fprintf(fd_tt, "%d, %d);", TPE[0], TPE[1]); - blurb(fd_tt, e); - put_seq(s, TPE[0], TPE[1]); - } - } + fprintf(fd_tt, "\", %d, ", (s->frst->status&I_GLOB)?1:0); + if (e->n->ntyp == NON_ATOMIC) + { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); + blurb(fd_tt, e); + put_seq(s, Tt0, Tt1); + } else + { fprintf(fd_tt, "%d, %d);", TPE[0], TPE[1]); + blurb(fd_tt, e); + put_seq(s, TPE[0], TPE[1]); + } + } } typedef struct CaseCache { - int m, b, owner; - Element *e; - Lextok *n; - FSM_use *u; - struct CaseCache *nxt; + int m, b, owner; + Element *e; + Lextok *n; + FSM_use *u; + struct CaseCache *nxt; } CaseCache; static CaseCache *casing[6]; @@ -1295,2230 +1300,2230 @@ static CaseCache *casing[6]; static int identical(Lextok *p, Lextok *q) { - if ((!p && q) || (p && !q)) - return 0; - if (!p) - return 1; - - if (p->ntyp != q->ntyp - || p->ismtyp != q->ismtyp - || p->val != q->val - || p->indstep != q->indstep - || p->sym != q->sym - || p->sq != q->sq - || p->sl != q->sl) - return 0; - - return identical(p->lft, q->lft) - && identical(p->rgt, q->rgt); + if ((!p && q) || (p && !q)) + return 0; + if (!p) + return 1; + + if (p->ntyp != q->ntyp + || p->ismtyp != q->ismtyp + || p->val != q->val + || p->indstep != q->indstep + || p->sym != q->sym + || p->sq != q->sq + || p->sl != q->sl) + return 0; + + return identical(p->lft, q->lft) + && identical(p->rgt, q->rgt); } static int samedeads(FSM_use *a, FSM_use *b) -{ FSM_use *p, *q; +{ FSM_use *p, *q; - for (p = a, q = b; p && q; p = p->nxt, q = q->nxt) - if (p->var != q->var - || p->special != q->special) - return 0; - return (!p && !q); + for (p = a, q = b; p && q; p = p->nxt, q = q->nxt) + if (p->var != q->var + || p->special != q->special) + return 0; + return (!p && !q); } static Element * findnext(Element *f) -{ Element *g; +{ Element *g; - if (f->n->ntyp == GOTO) - { g = get_lab(f->n, 1); - return huntele(g, f->status, -1); - } - return f->nxt; + if (f->n->ntyp == GOTO) + { g = get_lab(f->n, 1); + return huntele(g, f->status, -1); + } + return f->nxt; } static Element * advance(Element *e, int stopat) -{ Element *f = e; - - if (stopat) - while (f && f->seqno != stopat) - { f = findnext(f); - if (!f) - { break; - } - switch (f->n->ntyp) { - case GOTO: - case '.': - case PRINT: - case PRINTM: - break; - default: - return f; - } } - return (Element *) 0; +{ Element *f = e; + + if (stopat) + while (f && f->seqno != stopat) + { f = findnext(f); + if (!f) + { break; + } + switch (f->n->ntyp) { + case GOTO: + case '.': + case PRINT: + case PRINTM: + break; + default: + return f; + } } + return (Element *) 0; } static int equiv_merges(Element *a, Element *b) -{ Element *f, *g; - int stopat_a, stopat_b; +{ Element *f, *g; + int stopat_a, stopat_b; - if (a->merge_start) - stopat_a = a->merge_start; - else - stopat_a = a->merge; + if (a->merge_start) + stopat_a = a->merge_start; + else + stopat_a = a->merge; - if (b->merge_start) - stopat_b = b->merge_start; - else - stopat_b = b->merge; + if (b->merge_start) + stopat_b = b->merge_start; + else + stopat_b = b->merge; - if (!stopat_a && !stopat_b) - return 1; + if (!stopat_a && !stopat_b) + return 1; - f = advance(a, stopat_a); - g = advance(b, stopat_b); + f = advance(a, stopat_a); + g = advance(b, stopat_b); - if (!f && !g) - return 1; + if (!f && !g) + return 1; - if (f && g) - return identical(f->n, g->n); + if (f && g) + return identical(f->n, g->n); - return 0; + return 0; } static CaseCache * prev_case(Element *e, int owner) -{ int j; CaseCache *nc; - - switch (e->n->ntyp) { - case 'r': j = 0; break; - case 's': j = 1; break; - case 'c': j = 2; break; - case ASGN: j = 3; break; - case ASSERT: j = 4; break; - default: j = 5; break; - } - for (nc = casing[j]; nc; nc = nc->nxt) - if (identical(nc->n, e->n) - && samedeads(nc->u, e->dead) - && equiv_merges(nc->e, e) - && nc->owner == owner) - return nc; - - return (CaseCache *) 0; +{ int j; CaseCache *nc; + + switch (e->n->ntyp) { + case 'r': j = 0; break; + case 's': j = 1; break; + case 'c': j = 2; break; + case ASGN: j = 3; break; + case ASSERT: j = 4; break; + default: j = 5; break; + } + for (nc = casing[j]; nc; nc = nc->nxt) + if (identical(nc->n, e->n) + && samedeads(nc->u, e->dead) + && equiv_merges(nc->e, e) + && nc->owner == owner) + return nc; + + return (CaseCache *) 0; } static void new_case(Element *e, int m, int b, int owner) -{ int j; CaseCache *nc; - - switch (e->n->ntyp) { - case 'r': j = 0; break; - case 's': j = 1; break; - case 'c': j = 2; break; - case ASGN: j = 3; break; - case ASSERT: j = 4; break; - default: j = 5; break; - } - nc = (CaseCache *) emalloc(sizeof(CaseCache)); - nc->owner = owner; - nc->m = m; - nc->b = b; - nc->e = e; - nc->n = e->n; - nc->u = e->dead; - nc->nxt = casing[j]; - casing[j] = nc; +{ int j; CaseCache *nc; + + switch (e->n->ntyp) { + case 'r': j = 0; break; + case 's': j = 1; break; + case 'c': j = 2; break; + case ASGN: j = 3; break; + case ASSERT: j = 4; break; + default: j = 5; break; + } + nc = (CaseCache *) emalloc(sizeof(CaseCache)); + nc->owner = owner; + nc->m = m; + nc->b = b; + nc->e = e; + nc->n = e->n; + nc->u = e->dead; + nc->nxt = casing[j]; + casing[j] = nc; } static int nr_bup(Element *e) -{ FSM_use *u; - Lextok *v; - int nr = 0; - - switch (e->n->ntyp) { - case ASGN: - if (check_track(e->n) == STRUCT) { break; } - nr++; - break; - case 'r': - if (e->n->val >= 1) - nr++; /* random recv */ - for (v = e->n->rgt; v; v = v->rgt) - { if ((v->lft->ntyp == CONST - || v->lft->ntyp == EVAL)) - continue; - nr++; - } - break; - default: - break; - } - for (u = e->dead; u; u = u->nxt) - { switch (u->special) { - case 2: /* dead after write */ - if (e->n->ntyp == ASGN - && e->n->rgt->ntyp == CONST - && e->n->rgt->val == 0) - break; - nr++; - break; - case 1: /* dead after read */ - nr++; - break; - } } - return nr; +{ FSM_use *u; + Lextok *v; + int nr = 0; + + switch (e->n->ntyp) { + case ASGN: + if (check_track(e->n) == STRUCT) { break; } + nr++; + break; + case 'r': + if (e->n->val >= 1) + nr++; /* random recv */ + for (v = e->n->rgt; v; v = v->rgt) + { if ((v->lft->ntyp == CONST + || v->lft->ntyp == EVAL)) + continue; + nr++; + } + break; + default: + break; + } + for (u = e->dead; u; u = u->nxt) + { switch (u->special) { + case 2: /* dead after write */ + if (e->n->ntyp == ASGN + && e->n->rgt->ntyp == CONST + && e->n->rgt->val == 0) + break; + nr++; + break; + case 1: /* dead after read */ + nr++; + break; + } } + return nr; } static int nrhops(Element *e) -{ Element *f = e, *g; - int cnt = 0; - int stopat; - - if (e->merge_start) - stopat = e->merge_start; - else - stopat = e->merge; +{ Element *f = e, *g; + int cnt = 0; + int stopat; + + if (e->merge_start) + stopat = e->merge_start; + else + stopat = e->merge; #if 0 - printf("merge: %d merge_start %d - seqno %d\n", - e->merge, e->merge_start, e->seqno); + printf("merge: %d merge_start %d - seqno %d\n", + e->merge, e->merge_start, e->seqno); #endif - do { - cnt += nr_bup(f); - - if (f->n->ntyp == GOTO) - { g = get_lab(f->n, 1); - if (g->seqno == stopat) - f = g; - else - f = huntele(g, f->status, stopat); - } else - { - f = f->nxt; - } - - if (f && !f->merge && !f->merge_single && f->seqno != stopat) - { fprintf(fd_tm, "\n\t\t// bad hop %s:%d -- at %d, <", - f->n->fn->name,f->n->ln, f->seqno); - comment(fd_tm, f->n, 0); - fprintf(fd_tm, "> looking for %d -- merge %d:%d:%d ", - stopat, f->merge, f->merge_start, f->merge_single); - break; - } - } while (f && f->seqno != stopat); - - return cnt; + do { + cnt += nr_bup(f); + + if (f->n->ntyp == GOTO) + { g = get_lab(f->n, 1); + if (g->seqno == stopat) + f = g; + else + f = huntele(g, f->status, stopat); + } else + { + f = f->nxt; + } + + if (f && !f->merge && !f->merge_single && f->seqno != stopat) + { fprintf(fd_tm, "\n\t\t// bad hop %s:%d -- at %d, <", + f->n->fn->name,f->n->ln, f->seqno); + comment(fd_tm, f->n, 0); + fprintf(fd_tm, "> looking for %d -- merge %d:%d:%d ", + stopat, f->merge, f->merge_start, f->merge_single); + break; + } + } while (f && f->seqno != stopat); + + return cnt; } static void check_needed(void) { - if (multi_needed) - { fprintf(fd_tm, "(trpt+1)->bup.ovals = grab_ints(%d);\n\t\t", - multi_needed); - multi_undo = multi_needed; - multi_needed = 0; - } + if (multi_needed) + { fprintf(fd_tm, "(trpt+1)->bup.ovals = grab_ints(%d);\n\t\t", + multi_needed); + multi_undo = multi_needed; + multi_needed = 0; + } } static void doforward(FILE *tm_fd, Element *e) -{ FSM_use *u; - - putstmnt(tm_fd, e->n, e->seqno); - - if (e->n->ntyp != ELSE && Det) - { fprintf(tm_fd, ";\n\t\tif (trpt->o_pm&1)\n\t\t"); - fprintf(tm_fd, "\tuerror(\"non-determinism in D_proctype\")"); - } - if (deadvar && !has_code) - for (u = e->dead; u; u = u->nxt) - { fprintf(tm_fd, ";\n\t\t"); - fprintf(tm_fd, "if (TstOnly) return 1; /* TT */\n"); - fprintf(tm_fd, "\t\t/* dead %d: %s */ ", - u->special, u->var->name); - - switch (u->special) { - case 2: /* dead after write -- lval already bupped */ - if (e->n->ntyp == ASGN) /* could be recv or asgn */ - { if (e->n->rgt->ntyp == CONST - && e->n->rgt->val == 0) - continue; /* already set to 0 */ - } - if (e->n->ntyp != 'r') - { XZ.sym = u->var; - fprintf(tm_fd, "\n#ifdef HAS_CODE\n"); - fprintf(tm_fd, "\t\tif (!readtrail)\n"); - fprintf(tm_fd, "#endif\n\t\t\t"); - putname(tm_fd, "", &XZ, 0, " = 0"); - break; - } /* else fall through */ - case 1: /* dead after read -- add asgn of rval -- needs bup */ - YZ[YZmax].sym = u->var; /* store for pan.b */ - CnT[YZcnt]++; /* this step added bups */ - if (multi_oval) - { check_needed(); - fprintf(tm_fd, "(trpt+1)->bup.ovals[%d] = ", - multi_oval-1); - multi_oval++; - } else - fprintf(tm_fd, "(trpt+1)->bup.oval = "); - putname(tm_fd, "", &YZ[YZmax], 0, ";\n"); - fprintf(tm_fd, "#ifdef HAS_CODE\n"); - fprintf(tm_fd, "\t\tif (!readtrail)\n"); - fprintf(tm_fd, "#endif\n\t\t\t"); - putname(tm_fd, "", &YZ[YZmax], 0, " = 0"); - YZmax++; - break; - } } - fprintf(tm_fd, ";\n\t\t"); +{ FSM_use *u; + + putstmnt(tm_fd, e->n, e->seqno); + + if (e->n->ntyp != ELSE && Det) + { fprintf(tm_fd, ";\n\t\tif (trpt->o_pm&1)\n\t\t"); + fprintf(tm_fd, "\tuerror(\"non-determinism in D_proctype\")"); + } + if (deadvar && !has_code) + for (u = e->dead; u; u = u->nxt) + { fprintf(tm_fd, ";\n\t\t"); + fprintf(tm_fd, "if (TstOnly) return 1; /* TT */\n"); + fprintf(tm_fd, "\t\t/* dead %d: %s */ ", + u->special, u->var->name); + + switch (u->special) { + case 2: /* dead after write -- lval already bupped */ + if (e->n->ntyp == ASGN) /* could be recv or asgn */ + { if (e->n->rgt->ntyp == CONST + && e->n->rgt->val == 0) + continue; /* already set to 0 */ + } + if (e->n->ntyp != 'r') + { XZ.sym = u->var; + fprintf(tm_fd, "\n#ifdef HAS_CODE\n"); + fprintf(tm_fd, "\t\tif (!readtrail)\n"); + fprintf(tm_fd, "#endif\n\t\t\t"); + putname(tm_fd, "", &XZ, 0, " = 0"); + break; + } /* else fall through */ + case 1: /* dead after read -- add asgn of rval -- needs bup */ + YZ[YZmax].sym = u->var; /* store for pan.b */ + CnT[YZcnt]++; /* this step added bups */ + if (multi_oval) + { check_needed(); + fprintf(tm_fd, "(trpt+1)->bup.ovals[%d] = ", + multi_oval-1); + multi_oval++; + } else + fprintf(tm_fd, "(trpt+1)->bup.oval = "); + putname(tm_fd, "", &YZ[YZmax], 0, ";\n"); + fprintf(tm_fd, "#ifdef HAS_CODE\n"); + fprintf(tm_fd, "\t\tif (!readtrail)\n"); + fprintf(tm_fd, "#endif\n\t\t\t"); + putname(tm_fd, "", &YZ[YZmax], 0, " = 0"); + YZmax++; + break; + } } + fprintf(tm_fd, ";\n\t\t"); } static int dobackward(Element *e, int casenr) { - if (!any_undo(e->n) && CnT[YZcnt] == 0) - { YZcnt--; - return 0; - } - - if (!didcase) - { fprintf(fd_tb, "\n\tcase %d: ", casenr); - fprintf(fd_tb, "// STATE %d\n\t\t", e->seqno); - didcase++; - } - - _isok++; - while (CnT[YZcnt] > 0) /* undo dead variable resets */ - { CnT[YZcnt]--; - YZmax--; - if (YZmax < 0) - fatal("cannot happen, dobackward", (char *)0); - fprintf(fd_tb, ";\n\t/* %d */\t", YZmax); - putname(fd_tb, "", &YZ[YZmax], 0, " = trpt->bup.oval"); - if (multi_oval > 0) - { multi_oval--; - fprintf(fd_tb, "s[%d]", multi_oval-1); - } - } - - if (e->n->ntyp != '.') - { fprintf(fd_tb, ";\n\t\t"); - undostmnt(e->n, e->seqno); - } - _isok--; - - YZcnt--; - return 1; + if (!any_undo(e->n) && CnT[YZcnt] == 0) + { YZcnt--; + return 0; + } + + if (!didcase) + { fprintf(fd_tb, "\n\tcase %d: ", casenr); + fprintf(fd_tb, "// STATE %d\n\t\t", e->seqno); + didcase++; + } + + _isok++; + while (CnT[YZcnt] > 0) /* undo dead variable resets */ + { CnT[YZcnt]--; + YZmax--; + if (YZmax < 0) + fatal("cannot happen, dobackward", (char *)0); + fprintf(fd_tb, ";\n\t/* %d */\t", YZmax); + putname(fd_tb, "", &YZ[YZmax], 0, " = trpt->bup.oval"); + if (multi_oval > 0) + { multi_oval--; + fprintf(fd_tb, "s[%d]", multi_oval-1); + } + } + + if (e->n->ntyp != '.') + { fprintf(fd_tb, ";\n\t\t"); + undostmnt(e->n, e->seqno); + } + _isok--; + + YZcnt--; + return 1; } static void lastfirst(int stopat, Element *fin, int casenr) -{ Element *f = fin, *g; - - if (f->n->ntyp == GOTO) - { g = get_lab(f->n, 1); - if (g->seqno == stopat) - f = g; - else - f = huntele(g, f->status, stopat); - } else - f = f->nxt; - - if (!f || f->seqno == stopat - || (!f->merge && !f->merge_single)) - return; - lastfirst(stopat, f, casenr); +{ Element *f = fin, *g; + + if (f->n->ntyp == GOTO) + { g = get_lab(f->n, 1); + if (g->seqno == stopat) + f = g; + else + f = huntele(g, f->status, stopat); + } else + f = f->nxt; + + if (!f || f->seqno == stopat + || (!f->merge && !f->merge_single)) + return; + lastfirst(stopat, f, casenr); #if 0 - fprintf(fd_tb, "\n\t/* merge %d -- %d:%d %d:%d:%d (casenr %d) ", - YZcnt, - f->merge_start, f->merge, - f->seqno, f?f->seqno:-1, stopat, - casenr); - comment(fd_tb, f->n, 0); - fprintf(fd_tb, " */\n"); - fflush(fd_tb); + fprintf(fd_tb, "\n\t/* merge %d -- %d:%d %d:%d:%d (casenr %d) ", + YZcnt, + f->merge_start, f->merge, + f->seqno, f?f->seqno:-1, stopat, + casenr); + comment(fd_tb, f->n, 0); + fprintf(fd_tb, " */\n"); + fflush(fd_tb); #endif - dobackward(f, casenr); + dobackward(f, casenr); } static int modifier; static void lab_transfer(Element *to, Element *from) -{ Symbol *ns, *s = has_lab(from, (1|2|4)); - Symbol *oc; - int ltp, usedit=0; - - if (!s) return; - - /* "from" could have all three labels -- rename - * to prevent jumps to the transfered copies - */ - oc = context; /* remember */ - for (ltp = 1; ltp < 8; ltp *= 2) /* 1, 2, and 4 */ - if ((s = has_lab(from, ltp)) != (Symbol *) 0) - { ns = (Symbol *) emalloc(sizeof(Symbol)); - ns->name = (char *) emalloc((int) strlen(s->name) + 4); - sprintf(ns->name, "%s%d", s->name, modifier); - - context = s->context; - set_lab(ns, to); - usedit++; - } - context = oc; /* restore */ - if (usedit) - { if (modifier++ > 990) - fatal("modifier overflow error", (char *) 0); - } +{ Symbol *ns, *s = has_lab(from, (1|2|4)); + Symbol *oc; + int ltp, usedit=0; + + if (!s) return; + + /* "from" could have all three labels -- rename + * to prevent jumps to the transfered copies + */ + oc = context; /* remember */ + for (ltp = 1; ltp < 8; ltp *= 2) /* 1, 2, and 4 */ + if ((s = has_lab(from, ltp)) != (Symbol *) 0) + { ns = (Symbol *) emalloc(sizeof(Symbol)); + ns->name = (char *) emalloc((int) strlen(s->name) + 4); + sprintf(ns->name, "%s%d", s->name, modifier); + + context = s->context; + set_lab(ns, to); + usedit++; + } + context = oc; /* restore */ + if (usedit) + { if (modifier++ > 990) + fatal("modifier overflow error", (char *) 0); + } } static int case_cache(Element *e, int a) -{ int bupcase = 0, casenr = uniq, fromcache = 0; - CaseCache *Cached = (CaseCache *) 0; - Element *f, *g; - int j, nrbups, mark, ntarget; - extern int ccache; - - mark = (e->status&ATOM); /* could lose atomicity in a merge chain */ - - if (e->merge_mark > 0 - || (merger && e->merge_in == 0)) - { /* state nominally unreachable (part of merge chains) */ - if (e->n->ntyp != '.' - && e->n->ntyp != GOTO) - { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); - fprintf(fd_tt, "settr(0,0,0,0,0,\""); +{ int bupcase = 0, casenr = uniq, fromcache = 0; + CaseCache *Cached = (CaseCache *) 0; + Element *f, *g; + int j, nrbups, mark, ntarget; + extern int ccache; + + mark = (e->status&ATOM); /* could lose atomicity in a merge chain */ + + if (e->merge_mark > 0 + || (merger && e->merge_in == 0)) + { /* state nominally unreachable (part of merge chains) */ + if (e->n->ntyp != '.' + && e->n->ntyp != GOTO) + { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(0,0,0,0,0,\""); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - fprintf(fd_tt, "\",0,0,0);\n"); - } else - { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); - casenr = 1; /* mhs example */ - j = a; - goto haveit; /* pakula's example */ - } - - return -1; - } - - fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); - - if (ccache - && !pid_is_claim(Pid_nr) - && Pid_nr != eventmapnr - && (Cached = prev_case(e, Pid_nr))) - { bupcase = Cached->b; - casenr = Cached->m; - fromcache = 1; - - fprintf(fd_tm, "// STATE %d - %s:%d - [", - e->seqno, e->n->fn->name, e->n->ln); - comment(fd_tm, e->n, 0); - fprintf(fd_tm, "] (%d:%d - %d) same as %d (%d:%d - %d)\n", - e->merge_start, e->merge, e->merge_in, - casenr, - Cached->e->merge_start, Cached->e->merge, Cached->e->merge_in); - - goto gotit; - } - - fprintf(fd_tm, "\tcase %d: // STATE %d - %s:%d - [", - uniq++, e->seqno, e->n->fn->name, e->n->ln); - comment(fd_tm, e->n, 0); - nrbups = (e->merge || e->merge_start) ? nrhops(e) : nr_bup(e); - fprintf(fd_tm, "] (%d:%d:%d - %d)\n\t\t", - e->merge_start, e->merge, nrbups, e->merge_in); - - if (nrbups > MAXMERGE-1) - fatal("merge requires more than 256 bups", (char *)0); - - if (e->n->ntyp != 'r' && !pid_is_claim(Pid_nr) && Pid_nr != eventmapnr) - fprintf(fd_tm, "IfNotBlocked\n\t\t"); - - if (multi_needed != 0 || multi_undo != 0) - fatal("cannot happen, case_cache", (char *) 0); - - if (nrbups > 1) - { multi_oval = 1; - multi_needed = nrbups; /* allocated after edge condition */ - } else - multi_oval = 0; - - memset(CnT, 0, sizeof(CnT)); - YZmax = YZcnt = 0; + fprintf(fd_tt, "\",0,0,0);\n"); + } else + { fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + casenr = 1; /* mhs example */ + j = a; + goto haveit; /* pakula's example */ + } + + return -1; + } + + fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + + if (ccache + && !pid_is_claim(Pid_nr) + && Pid_nr != eventmapnr + && (Cached = prev_case(e, Pid_nr))) + { bupcase = Cached->b; + casenr = Cached->m; + fromcache = 1; + + fprintf(fd_tm, "// STATE %d - %s:%d - [", + e->seqno, e->n->fn->name, e->n->ln); + comment(fd_tm, e->n, 0); + fprintf(fd_tm, "] (%d:%d - %d) same as %d (%d:%d - %d)\n", + e->merge_start, e->merge, e->merge_in, + casenr, + Cached->e->merge_start, Cached->e->merge, Cached->e->merge_in); + + goto gotit; + } + + fprintf(fd_tm, "\tcase %d: // STATE %d - %s:%d - [", + uniq++, e->seqno, e->n->fn->name, e->n->ln); + comment(fd_tm, e->n, 0); + nrbups = (e->merge || e->merge_start) ? nrhops(e) : nr_bup(e); + fprintf(fd_tm, "] (%d:%d:%d - %d)\n\t\t", + e->merge_start, e->merge, nrbups, e->merge_in); + + if (nrbups > MAXMERGE-1) + fatal("merge requires more than 256 bups", (char *)0); + + if (e->n->ntyp != 'r' && !pid_is_claim(Pid_nr) && Pid_nr != eventmapnr) + fprintf(fd_tm, "IfNotBlocked\n\t\t"); + + if (multi_needed != 0 || multi_undo != 0) + fatal("cannot happen, case_cache", (char *) 0); + + if (nrbups > 1) + { multi_oval = 1; + multi_needed = nrbups; /* allocated after edge condition */ + } else + multi_oval = 0; + + memset(CnT, 0, sizeof(CnT)); + YZmax = YZcnt = 0; /* new 4.2.6, revised 6.0.0 */ - if (pid_is_claim(Pid_nr)) - { fprintf(fd_tm, "\n#if defined(VERI) && !defined(NP)\n"); - fprintf(fd_tm, "#if NCLAIMS>1\n\t\t"); - fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); - fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); - fprintf(fd_tm, " { int nn = (int) ((Pclaim *)pptr(0))->_n;\n\t\t"); - fprintf(fd_tm, " printf(\"depth %%ld: Claim %%s (%%d), state %%d (line %%d)\\n\",\n\t\t"); - fprintf(fd_tm, " depth, procname[spin_c_typ[nn]], nn, "); - fprintf(fd_tm, "(int) ((Pclaim *)pptr(0))->_p, src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); - fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); - fprintf(fd_tm, " fflush(stdout);\n\t\t"); - fprintf(fd_tm, "} }\n"); - fprintf(fd_tm, "#else\n\t\t"); - fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); - fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); - fprintf(fd_tm, " { printf(\"depth %%d: Claim, state %%d (line %%d)\\n\",\n\t\t"); - fprintf(fd_tm, " (int) depth, (int) ((Pclaim *)pptr(0))->_p, "); - fprintf(fd_tm, "src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); - fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); - fprintf(fd_tm, " fflush(stdout);\n\t\t"); - fprintf(fd_tm, "} }\n"); - fprintf(fd_tm, "#endif\n"); - fprintf(fd_tm, "#endif\n\t\t"); - } + if (pid_is_claim(Pid_nr)) + { fprintf(fd_tm, "\n#if defined(VERI) && !defined(NP)\n"); + fprintf(fd_tm, "#if NCLAIMS>1\n\t\t"); + fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); + fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); + fprintf(fd_tm, " { int nn = (int) ((Pclaim *)pptr(0))->_n;\n\t\t"); + fprintf(fd_tm, " printf(\"depth %%ld: Claim %%s (%%d), state %%d (line %%d)\\n\",\n\t\t"); + fprintf(fd_tm, " depth, procname[spin_c_typ[nn]], nn, "); + fprintf(fd_tm, "(int) ((Pclaim *)pptr(0))->_p, src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); + fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); + fprintf(fd_tm, " fflush(stdout);\n\t\t"); + fprintf(fd_tm, "} }\n"); + fprintf(fd_tm, "#else\n\t\t"); + fprintf(fd_tm, "{ static int reported%d = 0;\n\t\t", e->seqno); + fprintf(fd_tm, " if (verbose && !reported%d)\n\t\t", e->seqno); + fprintf(fd_tm, " { printf(\"depth %%d: Claim, state %%d (line %%d)\\n\",\n\t\t"); + fprintf(fd_tm, " (int) depth, (int) ((Pclaim *)pptr(0))->_p, "); + fprintf(fd_tm, "src_claim[ (int) ((Pclaim *)pptr(0))->_p ]);\n\t\t"); + fprintf(fd_tm, " reported%d = 1;\n\t\t", e->seqno); + fprintf(fd_tm, " fflush(stdout);\n\t\t"); + fprintf(fd_tm, "} }\n"); + fprintf(fd_tm, "#endif\n"); + fprintf(fd_tm, "#endif\n\t\t"); + } /* end */ - /* the src xrefs have the numbers in e->seqno builtin */ - fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, e->seqno); - - doforward(fd_tm, e); - - if (e->merge_start) - ntarget = e->merge_start; - else - ntarget = e->merge; - - if (ntarget) - { f = e; - -more: if (f->n->ntyp == GOTO) - { g = get_lab(f->n, 1); - if (g->seqno == ntarget) - f = g; - else - f = huntele(g, f->status, ntarget); - } else - f = f->nxt; - - - if (f && f->seqno != ntarget) - { if (!f->merge && !f->merge_single) - { fprintf(fd_tm, "/* stop at bad hop %d, %d */\n\t\t", - f->seqno, ntarget); - goto out; - } - fprintf(fd_tm, "/* merge: "); - comment(fd_tm, f->n, 0); - fprintf(fd_tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, ntarget); - fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, f->seqno); - YZcnt++; - lab_transfer(e, f); - mark = f->status&(ATOM|L_ATOM); /* last step wins */ - doforward(fd_tm, f); - if (f->merge_in == 1) f->merge_mark++; - - goto more; - } } + /* the src xrefs have the numbers in e->seqno builtin */ + fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, e->seqno); + + doforward(fd_tm, e); + + if (e->merge_start) + ntarget = e->merge_start; + else + ntarget = e->merge; + + if (ntarget) + { f = e; + +more: if (f->n->ntyp == GOTO) + { g = get_lab(f->n, 1); + if (g->seqno == ntarget) + f = g; + else + f = huntele(g, f->status, ntarget); + } else + f = f->nxt; + + + if (f && f->seqno != ntarget) + { if (!f->merge && !f->merge_single) + { fprintf(fd_tm, "/* stop at bad hop %d, %d */\n\t\t", + f->seqno, ntarget); + goto out; + } + fprintf(fd_tm, "/* merge: "); + comment(fd_tm, f->n, 0); + fprintf(fd_tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, ntarget); + fprintf(fd_tm, "reached[%d][%d] = 1;\n\t\t", Pid_nr, f->seqno); + YZcnt++; + lab_transfer(e, f); + mark = f->status&(ATOM|L_ATOM); /* last step wins */ + doforward(fd_tm, f); + if (f->merge_in == 1) f->merge_mark++; + + goto more; + } } out: - fprintf(fd_tm, "_m = %d", getweight(e->n)); - if (m_loss && e->n->ntyp == 's') fprintf(fd_tm, "+delta_m; delta_m = 0"); - fprintf(fd_tm, "; goto P999; /* %d */\n", YZcnt); - - multi_needed = 0; - didcase = 0; - - if (ntarget) - lastfirst(ntarget, e, casenr); /* mergesteps only */ - - dobackward(e, casenr); /* the original step */ - - fprintf(fd_tb, ";\n\t\t"); - - if (e->merge || e->merge_start) - { if (!didcase) - { fprintf(fd_tb, "\n\tcase %d: ", casenr); - fprintf(fd_tb, "// STATE %d", e->seqno); - didcase++; - } else - fprintf(fd_tb, ";"); - } else - fprintf(fd_tb, ";"); - fprintf(fd_tb, "\n\t\t"); - - if (multi_undo) - { fprintf(fd_tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t", - multi_undo); - multi_undo = 0; - } - if (didcase) - { fprintf(fd_tb, "goto R999;\n"); - bupcase = casenr; - } - - if (!e->merge && !e->merge_start) - new_case(e, casenr, bupcase, Pid_nr); + fprintf(fd_tm, "_m = %d", getweight(e->n)); + if (m_loss && e->n->ntyp == 's') fprintf(fd_tm, "+delta_m; delta_m = 0"); + fprintf(fd_tm, "; goto P999; /* %d */\n", YZcnt); + + multi_needed = 0; + didcase = 0; + + if (ntarget) + lastfirst(ntarget, e, casenr); /* mergesteps only */ + + dobackward(e, casenr); /* the original step */ + + fprintf(fd_tb, ";\n\t\t"); + + if (e->merge || e->merge_start) + { if (!didcase) + { fprintf(fd_tb, "\n\tcase %d: ", casenr); + fprintf(fd_tb, "// STATE %d", e->seqno); + didcase++; + } else + fprintf(fd_tb, ";"); + } else + fprintf(fd_tb, ";"); + fprintf(fd_tb, "\n\t\t"); + + if (multi_undo) + { fprintf(fd_tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t", + multi_undo); + multi_undo = 0; + } + if (didcase) + { fprintf(fd_tb, "goto R999;\n"); + bupcase = casenr; + } + + if (!e->merge && !e->merge_start) + new_case(e, casenr, bupcase, Pid_nr); gotit: - j = a; - if (e->merge_start) - j = e->merge_start; - else if (e->merge) - j = e->merge; + j = a; + if (e->merge_start) + j = e->merge_start; + else if (e->merge) + j = e->merge; haveit: - fprintf(fd_tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"", - e->Seqno, mark, j, casenr, bupcase); + fprintf(fd_tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"", + e->Seqno, mark, j, casenr, bupcase); - return (fromcache)?0:casenr; + return (fromcache)?0:casenr; } static void put_el(Element *e, int Tt0, int Tt1) -{ int a, casenr, Global_ref; - Element *g = ZE; - - if (e->n->ntyp == GOTO) - { g = get_lab(e->n, 1); - g = huntele(g, e->status, -1); - cross_dsteps(e->n, g->n); - a = g->seqno; - } else if (e->nxt) - { g = huntele(e->nxt, e->status, -1); - a = g->seqno; - } else - a = 0; - if (g - && ((g->status&CHECK2) /* entering remotely ref'd state */ - || (e->status&CHECK2))) /* leaving remotely ref'd state */ - e->status |= I_GLOB; - - /* don't remove dead edges in here, to preserve structure of fsm */ - if (e->merge_start || e->merge) - goto non_generic; - - /*** avoid duplicate or redundant cases in pan.m ***/ - switch (e->n->ntyp) { - case ELSE: - casenr = 2; /* standard else */ - putskip(e->seqno); - goto generic_case; - /* break; */ - case '.': - case GOTO: - case BREAK: - putskip(e->seqno); - casenr = 1; /* standard goto */ -generic_case: fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); - fprintf(fd_tt, "settr(%d,%d,%d,%d,0,\"", - e->Seqno, e->status&ATOM, a, casenr); - break; +{ int a, casenr, Global_ref; + Element *g = ZE; + + if (e->n->ntyp == GOTO) + { g = get_lab(e->n, 1); + g = huntele(g, e->status, -1); + cross_dsteps(e->n, g->n); + a = g->seqno; + } else if (e->nxt) + { g = huntele(e->nxt, e->status, -1); + a = g->seqno; + } else + a = 0; + if (g + && ((g->status&CHECK2) /* entering remotely ref'd state */ + || (e->status&CHECK2))) /* leaving remotely ref'd state */ + e->status |= I_GLOB; + + /* don't remove dead edges in here, to preserve structure of fsm */ + if (e->merge_start || e->merge) + goto non_generic; + + /*** avoid duplicate or redundant cases in pan.m ***/ + switch (e->n->ntyp) { + case ELSE: + casenr = 2; /* standard else */ + putskip(e->seqno); + goto generic_case; + /* break; */ + case '.': + case GOTO: + case BREAK: + putskip(e->seqno); + casenr = 1; /* standard goto */ +generic_case: fprintf(fd_tt, "\ttrans[%d][%d]\t= ", Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,%d,%d,0,\"", + e->Seqno, e->status&ATOM, a, casenr); + break; #ifndef PRINTF - case PRINT: - goto non_generic; - case PRINTM: - goto non_generic; + case PRINT: + goto non_generic; + case PRINTM: + goto non_generic; #endif - case 'c': - if (e->n->lft->ntyp == CONST - && e->n->lft->val == 1) /* skip or true */ - { casenr = 1; - putskip(e->seqno); - goto generic_case; - } - goto non_generic; - - default: + case 'c': + if (e->n->lft->ntyp == CONST + && e->n->lft->val == 1) /* skip or true */ + { casenr = 1; + putskip(e->seqno); + goto generic_case; + } + goto non_generic; + + default: non_generic: - casenr = case_cache(e, a); - if (casenr < 0) return; /* unreachable state */ - break; - } - /* tailend of settr(...); */ - Global_ref = (e->status&I_GLOB)?1:has_global(e->n); + casenr = case_cache(e, a); + if (casenr < 0) return; /* unreachable state */ + break; + } + /* tailend of settr(...); */ + Global_ref = (e->status&I_GLOB)?1:has_global(e->n); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - fprintf(fd_tt, "\", %d, ", Global_ref); - if (Tt0 != 2) - { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); - } else - { Tpe(e->n); /* sets EPT */ - fprintf(fd_tt, "%d, %d);", EPT[0], EPT[1]); - } - if ((e->merge_start && e->merge_start != a) - || (e->merge && e->merge != a)) - { fprintf(fd_tt, " /* m: %d -> %d,%d */\n", - a, e->merge_start, e->merge); - fprintf(fd_tt, " reached%d[%d] = 1;", - Pid_nr, a); /* Sheinman's example */ - } - fprintf(fd_tt, "\n"); - - if (casenr > 2) - tr_map(casenr, e); - put_escp(e); + fprintf(fd_tt, "\", %d, ", Global_ref); + if (Tt0 != 2) + { fprintf(fd_tt, "%d, %d);", Tt0, Tt1); + } else + { Tpe(e->n); /* sets EPT */ + fprintf(fd_tt, "%d, %d);", EPT[0], EPT[1]); + } + if ((e->merge_start && e->merge_start != a) + || (e->merge && e->merge != a)) + { fprintf(fd_tt, " /* m: %d -> %d,%d */\n", + a, e->merge_start, e->merge); + fprintf(fd_tt, " reached%d[%d] = 1;", + Pid_nr, a); /* Sheinman's example */ + } + fprintf(fd_tt, "\n"); + + if (casenr > 2) + tr_map(casenr, e); + put_escp(e); } static void nested_unless(Element *e, Element *g) -{ struct SeqList *y = e->esc, *z = g->esc; - - for ( ; y && z; y = y->nxt, z = z->nxt) - if (z->this != y->this) - break; - if (!y && !z) - return; - - if (g->n->ntyp != GOTO - && g->n->ntyp != '.' - && e->sub->nxt) - { printf("error: (%s:%d) saw 'unless' on a guard:\n", - (e->n)?e->n->fn->name:"-", - (e->n)?e->n->ln:0); - printf("=====>instead of\n"); - printf(" do (or if)\n"); - printf(" :: ...\n"); - printf(" :: stmnt1 unless stmnt2\n"); - printf(" od (of fi)\n"); - printf("=====>use\n"); - printf(" do (or if)\n"); - printf(" :: ...\n"); - printf(" :: stmnt1\n"); - printf(" od (or fi) unless stmnt2\n"); - printf("=====>or rewrite\n"); - } +{ struct SeqList *y = e->esc, *z = g->esc; + + for ( ; y && z; y = y->nxt, z = z->nxt) + if (z->thisS != y->thisS) + break; + if (!y && !z) + return; + + if (g->n->ntyp != GOTO + && g->n->ntyp != '.' + && e->sub->nxt) + { printf("error: (%s:%d) saw 'unless' on a guard:\n", + (e->n)?e->n->fn->name:"-", + (e->n)?e->n->ln:0); + printf("=====>instead of\n"); + printf(" do (or if)\n"); + printf(" :: ...\n"); + printf(" :: stmnt1 unless stmnt2\n"); + printf(" od (of fi)\n"); + printf("=====>use\n"); + printf(" do (or if)\n"); + printf(" :: ...\n"); + printf(" :: stmnt1\n"); + printf(" od (or fi) unless stmnt2\n"); + printf("=====>or rewrite\n"); + } } static void put_seq(Sequence *s, int Tt0, int Tt1) -{ SeqList *h; - Element *e, *g; - int a, deadlink; - - if (0) printf("put_seq %d\n", s->frst->seqno); - - for (e = s->frst; e; e = e->nxt) - { - if (0) printf(" step %d\n", e->seqno); - if (e->status & DONE) - { - if (0) printf(" done before\n"); - goto checklast; - } - e->status |= DONE; - - if (e->n->ln) - putsrc(e); - - if (e->n->ntyp == UNLESS) - { - if (0) printf(" an unless\n"); - put_seq(e->sub->this, Tt0, Tt1); - } else if (e->sub) - { - if (0) printf(" has sub\n"); - fprintf(fd_tt, "\tT = trans[%d][%d] = ", - Pid_nr, e->seqno); - fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", - e->Seqno, e->status&ATOM); +{ SeqList *h; + Element *e, *g; + int a, deadlink; + + if (0) printf("put_seq %d\n", s->frst->seqno); + + for (e = s->frst; e; e = e->nxt) + { + if (0) printf(" step %d\n", e->seqno); + if (e->status & DONE) + { + if (0) printf(" done before\n"); + goto checklast; + } + e->status |= DONE; + + if (e->n->ln) + putsrc(e); + + if (e->n->ntyp == UNLESS) + { + if (0) printf(" an unless\n"); + put_seq(e->sub->thisS, Tt0, Tt1); + } else if (e->sub) + { + if (0) printf(" has sub\n"); + fprintf(fd_tt, "\tT = trans[%d][%d] = ", + Pid_nr, e->seqno); + fprintf(fd_tt, "settr(%d,%d,0,0,0,\"", + e->Seqno, e->status&ATOM); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - if (e->status&CHECK2) - e->status |= I_GLOB; - fprintf(fd_tt, "\", %d, %d, %d);", - (e->status&I_GLOB)?1:0, Tt0, Tt1); - blurb(fd_tt, e); - for (h = e->sub; h; h = h->nxt) - { putskip(h->this->frst->seqno); - g = huntstart(h->this->frst); - if (g->esc) - nested_unless(e, g); - a = g->seqno; - - if (g->n->ntyp == 'c' - && g->n->lft->ntyp == CONST - && g->n->lft->val == 0 /* 0 or false */ - && !g->esc) - { fprintf(fd_tt, "#if 0\n\t/* dead link: */\n"); - deadlink = 1; - if (verbose&32) - printf("spin: %s:%d, warning, condition is always false\n", - g->n->fn?g->n->fn->name:"", g->n->ln); - } else - deadlink = 0; - if (0) printf(" settr %d %d\n", a, 0); - if (h->nxt) - fprintf(fd_tt, "\tT = T->nxt\t= "); - else - fprintf(fd_tt, "\t T->nxt\t= "); - fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", - e->Seqno, e->status&ATOM, a); + if (e->status&CHECK2) + e->status |= I_GLOB; + fprintf(fd_tt, "\", %d, %d, %d);", + (e->status&I_GLOB)?1:0, Tt0, Tt1); + blurb(fd_tt, e); + for (h = e->sub; h; h = h->nxt) + { putskip(h->thisS->frst->seqno); + g = huntstart(h->thisS->frst); + if (g->esc) + nested_unless(e, g); + a = g->seqno; + + if (g->n->ntyp == 'c' + && g->n->lft->ntyp == CONST + && g->n->lft->val == 0 /* 0 or false */ + && !g->esc) + { fprintf(fd_tt, "#if 0\n\t/* dead link: */\n"); + deadlink = 1; + if (verbose&32) + printf("spin: %s:%d, warning, condition is always false\n", + g->n->fn?g->n->fn->name:"", g->n->ln); + } else + deadlink = 0; + if (0) printf(" settr %d %d\n", a, 0); + if (h->nxt) + fprintf(fd_tt, "\tT = T->nxt\t= "); + else + fprintf(fd_tt, "\t T->nxt\t= "); + fprintf(fd_tt, "settr(%d,%d,%d,0,0,\"", + e->Seqno, e->status&ATOM, a); in_settr++; - comment(fd_tt, e->n, e->seqno); + comment(fd_tt, e->n, e->seqno); in_settr--; - if (g->status&CHECK2) - h->this->frst->status |= I_GLOB; - fprintf(fd_tt, "\", %d, %d, %d);", - (h->this->frst->status&I_GLOB)?1:0, - Tt0, Tt1); - blurb(fd_tt, e); - if (deadlink) - fprintf(fd_tt, "#endif\n"); - } - for (h = e->sub; h; h = h->nxt) - put_seq(h->this, Tt0, Tt1); - } else - { - if (0) printf(" [non]atomic %d\n", e->n->ntyp); - if (e->n->ntyp == ATOMIC - || e->n->ntyp == D_STEP - || e->n->ntyp == NON_ATOMIC) - put_sub(e, Tt0, Tt1); - else - { - if (0) printf(" put_el %d\n", e->seqno); - put_el(e, Tt0, Tt1); - } - } -checklast: if (e == s->last) - break; - } - if (0) printf("put_seq done\n"); + if (g->status&CHECK2) + h->thisS->frst->status |= I_GLOB; + fprintf(fd_tt, "\", %d, %d, %d);", + (h->thisS->frst->status&I_GLOB)?1:0, + Tt0, Tt1); + blurb(fd_tt, e); + if (deadlink) + fprintf(fd_tt, "#endif\n"); + } + for (h = e->sub; h; h = h->nxt) + put_seq(h->thisS, Tt0, Tt1); + } else + { + if (0) printf(" [non]atomic %d\n", e->n->ntyp); + if (e->n->ntyp == ATOMIC + || e->n->ntyp == D_STEP + || e->n->ntyp == NON_ATOMIC) + put_sub(e, Tt0, Tt1); + else + { + if (0) printf(" put_el %d\n", e->seqno); + put_el(e, Tt0, Tt1); + } + } +checklast: if (e == s->last) + break; + } + if (0) printf("put_seq done\n"); } static void -patch_atomic(Sequence *s) /* catch goto's that break the chain */ -{ Element *f, *g; - SeqList *h; - - for (f = s->frst; f ; f = f->nxt) - { - if (f->n && f->n->ntyp == GOTO) - { g = get_lab(f->n,1); - cross_dsteps(f->n, g->n); - if ((f->status & (ATOM|L_ATOM)) - && !(g->status & (ATOM|L_ATOM))) - { f->status &= ~ATOM; - f->status |= L_ATOM; - } - /* bridge atomics */ - if ((f->status & L_ATOM) - && (g->status & (ATOM|L_ATOM))) - { f->status &= ~L_ATOM; - f->status |= ATOM; - } - } else - for (h = f->sub; h; h = h->nxt) - patch_atomic(h->this); - if (f == s->extent) - break; - } +patch_atomic(Sequence *s) /* catch goto's that break the chain */ +{ Element *f, *g; + SeqList *h; + + for (f = s->frst; f ; f = f->nxt) + { + if (f->n && f->n->ntyp == GOTO) + { g = get_lab(f->n,1); + cross_dsteps(f->n, g->n); + if ((f->status & (ATOM|L_ATOM)) + && !(g->status & (ATOM|L_ATOM))) + { f->status &= ~ATOM; + f->status |= L_ATOM; + } + /* bridge atomics */ + if ((f->status & L_ATOM) + && (g->status & (ATOM|L_ATOM))) + { f->status &= ~L_ATOM; + f->status |= ATOM; + } + } else + for (h = f->sub; h; h = h->nxt) + patch_atomic(h->thisS); + if (f == s->extent) + break; + } } static void mark_seq(Sequence *s) -{ Element *f; - SeqList *h; - - for (f = s->frst; f; f = f->nxt) - { f->status |= I_GLOB; - - if (f->n->ntyp == ATOMIC - || f->n->ntyp == NON_ATOMIC - || f->n->ntyp == D_STEP) - mark_seq(f->n->sl->this); - - for (h = f->sub; h; h = h->nxt) - mark_seq(h->this); - if (f == s->last) - return; - } +{ Element *f; + SeqList *h; + + for (f = s->frst; f; f = f->nxt) + { f->status |= I_GLOB; + + if (f->n->ntyp == ATOMIC + || f->n->ntyp == NON_ATOMIC + || f->n->ntyp == D_STEP) + mark_seq(f->n->sl->thisS); + + for (h = f->sub; h; h = h->nxt) + mark_seq(h->thisS); + if (f == s->last) + return; + } } static Element * find_target(Element *e) -{ Element *f; - - if (!e) return e; - - if (t_cyc++ > 32) - { fatal("cycle of goto jumps", (char *) 0); - } - switch (e->n->ntyp) { - case GOTO: - f = get_lab(e->n,1); - cross_dsteps(e->n, f->n); - f = find_target(f); - break; - case BREAK: - if (e->nxt) - { f = find_target(huntele(e->nxt, e->status, -1)); - break; /* new 5.0 -- was missing */ - } - /* else fall through */ - default: - f = e; - break; - } - return f; +{ Element *f; + + if (!e) return e; + + if (t_cyc++ > 32) + { fatal("cycle of goto jumps", (char *) 0); + } + switch (e->n->ntyp) { + case GOTO: + f = get_lab(e->n,1); + cross_dsteps(e->n, f->n); + f = find_target(f); + break; + case BREAK: + if (e->nxt) + { f = find_target(huntele(e->nxt, e->status, -1)); + break; /* new 5.0 -- was missing */ + } + /* else fall through */ + default: + f = e; + break; + } + return f; } Element * target(Element *e) { - if (!e) return e; - lineno = e->n->ln; - Fname = e->n->fn; - t_cyc = 0; - return find_target(e); + if (!e) return e; + lineno = e->n->ln; + Fname = e->n->fn; + t_cyc = 0; + return find_target(e); } static int -seq_has_el(Sequence *s, Element *g) /* new to version 5.0 */ -{ Element *f; - SeqList *h; - - for (f = s->frst; f; f = f->nxt) /* g in same atomic? */ - { if (f == g) - { return 1; - } - if (f->status & CHECK3) - { continue; - } - f->status |= CHECK3; /* protect against cycles */ - for (h = f->sub; h; h = h->nxt) - { if (h->this && seq_has_el(h->this, g)) - { return 1; - } } } - return 0; +seq_has_el(Sequence *s, Element *g) /* new to version 5.0 */ +{ Element *f; + SeqList *h; + + for (f = s->frst; f; f = f->nxt) /* g in same atomic? */ + { if (f == g) + { return 1; + } + if (f->status & CHECK3) + { continue; + } + f->status |= CHECK3; /* protect against cycles */ + for (h = f->sub; h; h = h->nxt) + { if (h->thisS && seq_has_el(h->thisS, g)) + { return 1; + } } } + return 0; } static int scan_seq(Sequence *s) -{ Element *f, *g; - SeqList *h; - - for (f = s->frst; f; f = f->nxt) - { if ((f->status&CHECK2) - || has_global(f->n)) - return 1; - if (f->n->ntyp == GOTO /* may exit or reach other atomic */ - && !(f->status & D_ATOM)) /* cannot jump from d_step */ - { /* consider jump from an atomic without globals into - * an atomic with globals - * example by Claus Traulsen, 22 June 2007 - */ - g = target(f); +{ Element *f, *g; + SeqList *h; + + for (f = s->frst; f; f = f->nxt) + { if ((f->status&CHECK2) + || has_global(f->n)) + return 1; + if (f->n->ntyp == GOTO /* may exit or reach other atomic */ + && !(f->status & D_ATOM)) /* cannot jump from d_step */ + { /* consider jump from an atomic without globals into + * an atomic with globals + * example by Claus Traulsen, 22 June 2007 + */ + g = target(f); #if 1 - if (g && !seq_has_el(s, g)) /* not internal to this atomic/dstep */ + if (g && !seq_has_el(s, g)) /* not internal to this atomic/dstep */ #else - if (g - && !(f->status & L_ATOM) - && !(g->status & (ATOM|L_ATOM))) + if (g + && !(f->status & L_ATOM) + && !(g->status & (ATOM|L_ATOM))) #endif - { fprintf(fd_tt, "\t/* mark-down line %d status %d = %d */\n", f->n->ln, f->status, (f->status & D_ATOM)); - return 1; /* assume worst case */ - } } - for (h = f->sub; h; h = h->nxt) - if (scan_seq(h->this)) - return 1; - if (f == s->last) - break; - } - return 0; + { fprintf(fd_tt, "\t/* mark-down line %d status %d = %d */\n", f->n->ln, f->status, (f->status & D_ATOM)); + return 1; /* assume worst case */ + } } + for (h = f->sub; h; h = h->nxt) + if (scan_seq(h->thisS)) + return 1; + if (f == s->last) + break; + } + return 0; } static int glob_args(Lextok *n) -{ int result = 0; - Lextok *v; - - for (v = n->rgt; v; v = v->rgt) - { if (v->lft->ntyp == CONST) - continue; - if (v->lft->ntyp == EVAL) - result += has_global(v->lft->lft); - else - result += has_global(v->lft); - } - return result; +{ int result = 0; + Lextok *v; + + for (v = n->rgt; v; v = v->rgt) + { if (v->lft->ntyp == CONST) + continue; + if (v->lft->ntyp == EVAL) + result += has_global(v->lft->lft); + else + result += has_global(v->lft); + } + return result; } static int proc_is_safe(const Lextok *n) -{ ProcList *p; - /* not safe unless no local var inits are used */ - /* note that a local variable init could refer to a global */ - - for (p = ready; p; p = p->nxt) - { if (strcmp(n->sym->name, p->n->name) == 0) - { /* printf("proc %s safety: %d\n", p->n->name, p->unsafe); */ - return (p->unsafe != 0); - } } -/* non_fatal("bad call to proc_is_safe", (char *) 0); */ - /* cannot happen */ - return 0; +{ ProcList *p; + /* not safe unless no local var inits are used */ + /* note that a local variable init could refer to a global */ + + for (p = ready; p; p = p->nxt) + { if (strcmp(n->sym->name, p->n->name) == 0) + { /* printf("proc %s safety: %d\n", p->n->name, p->unsafe); */ + return (p->unsafe != 0); + } } +/* non_fatal("bad call to proc_is_safe", (char *) 0); */ + /* cannot happen */ + return 0; } int has_global(Lextok *n) -{ Lextok *v; - static Symbol *n_seen = (Symbol *) 0; - - if (!n) return 0; - if (AllGlobal) return 1; /* global provided clause */ - - switch (n->ntyp) { - case ATOMIC: - case D_STEP: - case NON_ATOMIC: - return scan_seq(n->sl->this); - - case '.': - case BREAK: - case GOTO: - case CONST: - return 0; - - case ELSE: return n->val; /* true if combined with chan refs */ - - case 's': return glob_args(n)!=0 || ((n->sym->xu&(XS|XX)) != XS); - case 'r': return glob_args(n)!=0 || ((n->sym->xu&(XR|XX)) != XR); - case 'R': return glob_args(n)!=0 || (((n->sym->xu)&(XR|XS|XX)) != (XR|XS)); - case NEMPTY: return ((n->sym->xu&(XR|XX)) != XR); - case NFULL: return ((n->sym->xu&(XS|XX)) != XS); - case FULL: return ((n->sym->xu&(XR|XX)) != XR); - case EMPTY: return ((n->sym->xu&(XS|XX)) != XS); - case LEN: return (((n->sym->xu)&(XR|XS|XX)) != (XR|XS)); - - case NAME: - if (strcmp(n->sym->name, "_priority") == 0) - { if (old_priority_rules) - { if (n_seen != n->sym) - fatal("cannot refer to _priority with -o6", (char *) 0); - n_seen = n->sym; - } - return 0; - } - if (n->sym->context - || (n->sym->hidden&64) - || strcmp(n->sym->name, "_pid") == 0 - || strcmp(n->sym->name, "_") == 0) - return 0; - return 1; - - case RUN: - return proc_is_safe(n); - - case C_CODE: case C_EXPR: - return glob_inline(n->sym->name); - - case ENABLED: case PC_VAL: case NONPROGRESS: - case 'p': case 'q': - case TIMEOUT: case SET_P: case GET_P: - return 1; - - /* @ was 1 (global) since 2.8.5 - in 3.0 it is considered local and - conditionally safe, provided: - II is the youngest process - and nrprocs < MAXPROCS - */ - case '@': return 0; - - case '!': case UMIN: case '~': case ASSERT: - return has_global(n->lft); - - case '/': case '*': case '-': case '+': - case '%': case LT: case GT: case '&': case '^': - case '|': case LE: case GE: case NE: case '?': - case EQ: case OR: case AND: case LSHIFT: - case RSHIFT: case 'c': case ASGN: - return has_global(n->lft) || has_global(n->rgt); - - case PRINT: - for (v = n->lft; v; v = v->rgt) - if (has_global(v->lft)) return 1; - return 0; - case PRINTM: - return has_global(n->lft); - } - return 0; +{ Lextok *v; + static Symbol *n_seen = (Symbol *) 0; + + if (!n) return 0; + if (AllGlobal) return 1; /* global provided clause */ + + switch (n->ntyp) { + case ATOMIC: + case D_STEP: + case NON_ATOMIC: + return scan_seq(n->sl->thisS); + + case '.': + case BREAK: + case GOTO: + case CONST: + return 0; + + case ELSE: return n->val; /* true if combined with chan refs */ + + case 's': return glob_args(n)!=0 || ((n->sym->xu&(XS|XX)) != XS); + case 'r': return glob_args(n)!=0 || ((n->sym->xu&(XR|XX)) != XR); + case 'R': return glob_args(n)!=0 || (((n->sym->xu)&(XR|XS|XX)) != (XR|XS)); + case NEMPTY: return ((n->sym->xu&(XR|XX)) != XR); + case NFULL: return ((n->sym->xu&(XS|XX)) != XS); + case FULL: return ((n->sym->xu&(XR|XX)) != XR); + case EMPTY: return ((n->sym->xu&(XS|XX)) != XS); + case LEN: return (((n->sym->xu)&(XR|XS|XX)) != (XR|XS)); + + case NAME: + if (strcmp(n->sym->name, "_priority") == 0) + { if (old_priority_rules) + { if (n_seen != n->sym) + fatal("cannot refer to _priority with -o6", (char *) 0); + n_seen = n->sym; + } + return 0; + } + if (n->sym->context + || (n->sym->hidden&64) + || strcmp(n->sym->name, "_pid") == 0 + || strcmp(n->sym->name, "_") == 0) + return 0; + return 1; + + case RUN: + return proc_is_safe(n); + + case C_CODE: case C_EXPR: + return glob_inline(n->sym->name); + + case ENABLED: case PC_VAL: case NONPROGRESS: + case 'p': case 'q': + case TIMEOUT: case SET_P: case GET_P: + return 1; + + /* @ was 1 (global) since 2.8.5 + in 3.0 it is considered local and + conditionally safe, provided: + II is the youngest process + and nrprocs < MAXPROCS + */ + case '@': return 0; + + case '!': case UMIN: case '~': case ASSERT: + return has_global(n->lft); + + case '/': case '*': case '-': case '+': + case '%': case LT: case GT: case '&': case '^': + case '|': case LE: case GE: case NE: case '?': + case EQ: case OR: case AND: case LSHIFT: + case RSHIFT: case 'c': case ASGN: + return has_global(n->lft) || has_global(n->rgt); + + case PRINT: + for (v = n->lft; v; v = v->rgt) + if (has_global(v->lft)) return 1; + return 0; + case PRINTM: + return has_global(n->lft); + } + return 0; } static void -Bailout(FILE *fd, char *str) +Bailout(FILE *fd, const char *str) { - if (!GenCode) - { fprintf(fd, "continue%s", str); - } else if (IsGuard) - { fprintf(fd, "%s%s", NextLab[Level], str); - } else - { fprintf(fd, "Uerror(\"block in d_step seq\")%s", str); - } + if (!GenCode) + { fprintf(fd, "continue%s", str); + } else if (IsGuard) + { fprintf(fd, "%s%s", NextLab[Level], str); + } else + { fprintf(fd, "Uerror(\"block in d_step seq\")%s", str); + } } -#define cat0(x) putstmnt(fd,now->lft,m); fprintf(fd, x); \ - putstmnt(fd,now->rgt,m) -#define cat1(x) fprintf(fd,"("); cat0(x); fprintf(fd,")") -#define cat2(x,y) fprintf(fd,x); putstmnt(fd,y,m) -#define cat3(x,y,z) fprintf(fd,x); putstmnt(fd,y,m); fprintf(fd,z) -#define cat30(x,y,z) fprintf(fd,x,0); putstmnt(fd,y,m); fprintf(fd,z) +#define cat0(x) putstmnt(fd,now->lft,m); fprintf(fd, x); \ + putstmnt(fd,now->rgt,m) +#define cat1(x) fprintf(fd,"("); cat0(x); fprintf(fd,")") +#define cat2(x,y) fprintf(fd,x); putstmnt(fd,y,m) +#define cat3(x,y,z) fprintf(fd,x); putstmnt(fd,y,m); fprintf(fd,z) +#define cat30(x,y,z) fprintf(fd,x,0); putstmnt(fd,y,m); fprintf(fd,z) extern void explain(int); void dump_tree(const char *s, Lextok *p) -{ char z[64]; +{ char z[64]; - if (!p) return; + if (!p) return; - printf("\n%s:\t%2d:\t%3d (", s, p->ln, p->ntyp); - explain(p->ntyp); - if (p->ntyp == 315) printf(": %s", p->sym->name); - if (p->ntyp == 312) printf(": %d", p->val); - printf(")"); + printf("\n%s:\t%2d:\t%3d (", s, p->ln, p->ntyp); + explain(p->ntyp); + if (p->ntyp == 315) printf(": %s", p->sym->name); + if (p->ntyp == 312) printf(": %d", p->val); + printf(")"); - if (p->lft) { sprintf(z, "%sL", s); dump_tree(z, p->lft); } - if (p->rgt) { sprintf(z, "%sR", s); dump_tree(z, p->rgt); } + if (p->lft) { sprintf(z, "%sL", s); dump_tree(z, p->lft); } + if (p->rgt) { sprintf(z, "%sR", s); dump_tree(z, p->rgt); } } void putstmnt(FILE *fd, Lextok *now, int m) -{ Lextok *v; - int i, j; - - if (!now) { fprintf(fd, "0"); return; } - lineno = now->ln; - Fname = now->fn; - - switch (now->ntyp) { - case CONST: fprintf(fd, "%d", now->val); break; - case '!': cat3(" !(", now->lft, ")"); break; - case UMIN: cat3(" -(", now->lft, ")"); break; - case '~': cat3(" ~(", now->lft, ")"); break; - - case '/': cat1("/"); break; - case '*': cat1("*"); break; - case '-': cat1("-"); break; - case '+': cat1("+"); break; - case '%': cat1("%%"); break; - case '&': cat1("&"); break; - case '^': cat1("^"); break; - case '|': cat1("|"); break; - case LT: cat1("<"); break; - case GT: cat1(">"); break; - case LE: cat1("<="); break; - case GE: cat1(">="); break; - case NE: cat1("!="); break; - case EQ: cat1("=="); break; - case OR: cat1("||"); break; - case AND: cat1("&&"); break; - case LSHIFT: cat1("<<"); break; - case RSHIFT: cat1(">>"); break; - - case TIMEOUT: - if (separate == 2) - fprintf(fd, "((tau)&1)"); - else - fprintf(fd, "((trpt->tau)&1)"); - if (GenCode) - printf("spin: %s:%d, warning, 'timeout' in d_step sequence\n", - Fname->name, lineno); - /* is okay as a guard */ - break; - - case RUN: - if (now->sym == NULL) - fatal("internal error pangen2.c", (char *) 0); - if (claimproc - && strcmp(now->sym->name, claimproc) == 0) - fatal("claim %s, (not runnable)", claimproc); - if (eventmap - && strcmp(now->sym->name, eventmap) == 0) - fatal("eventmap %s, (not runnable)", eventmap); - - if (GenCode) - fatal("'run' in d_step sequence (use atomic)", (char *)0); - - fprintf(fd,"addproc(II, %d, %d", - (now->val > 0 && !old_priority_rules) ? now->val : 1, - fproc(now->sym->name)); - for (v = now->lft, i = 0; v; v = v->rgt, i++) - { cat2(", ", v->lft); - } - check_param_count(i, now); - - if (i > Npars) - { /* printf("\t%d parameters used, max %d expected\n", i, Npars); */ - fatal("too many parameters in run %s(...)", now->sym->name); - } - for ( ; i < Npars; i++) - fprintf(fd, ", 0"); - fprintf(fd, ")"); - check_mtypes(now, now->lft); +{ Lextok *v; + int i, j; + + if (!now) { fprintf(fd, "0"); return; } + lineno = now->ln; + Fname = now->fn; + + switch (now->ntyp) { + case CONST: fprintf(fd, "%d", now->val); break; + case '!': cat3(" !(", now->lft, ")"); break; + case UMIN: cat3(" -(", now->lft, ")"); break; + case '~': cat3(" ~(", now->lft, ")"); break; + + case '/': cat1("/"); break; + case '*': cat1("*"); break; + case '-': cat1("-"); break; + case '+': cat1("+"); break; + case '%': cat1("%%"); break; + case '&': cat1("&"); break; + case '^': cat1("^"); break; + case '|': cat1("|"); break; + case LT: cat1("<"); break; + case GT: cat1(">"); break; + case LE: cat1("<="); break; + case GE: cat1(">="); break; + case NE: cat1("!="); break; + case EQ: cat1("=="); break; + case OR: cat1("||"); break; + case AND: cat1("&&"); break; + case LSHIFT: cat1("<<"); break; + case RSHIFT: cat1(">>"); break; + + case TIMEOUT: + if (separate == 2) + fprintf(fd, "((tau)&1)"); + else + fprintf(fd, "((trpt->tau)&1)"); + if (GenCode) + printf("spin: %s:%d, warning, 'timeout' in d_step sequence\n", + Fname->name, lineno); + /* is okay as a guard */ + break; + + case RUN: + if (now->sym == NULL) + fatal("internal error pangen2.c", (char *) 0); + if (claimproc + && strcmp(now->sym->name, claimproc) == 0) + fatal("claim %s, (not runnable)", claimproc); + if (eventmap + && strcmp(now->sym->name, eventmap) == 0) + fatal("eventmap %s, (not runnable)", eventmap); + + if (GenCode) + fatal("'run' in d_step sequence (use atomic)", (char *)0); + + fprintf(fd,"addproc(II, %d, %d", + (now->val > 0 && !old_priority_rules) ? now->val : 1, + fproc(now->sym->name)); + for (v = now->lft, i = 0; v; v = v->rgt, i++) + { cat2(", ", v->lft); + } + check_param_count(i, now); + + if (i > Npars) + { /* printf("\t%d parameters used, max %d expected\n", i, Npars); */ + fatal("too many parameters in run %s(...)", now->sym->name); + } + for ( ; i < Npars; i++) + fprintf(fd, ", 0"); + fprintf(fd, ")"); + check_mtypes(now, now->lft); #if 0 - /* process now->sym->name has run priority now->val */ - if (now->val > 0 && now->val < 256 && !old_priority_rules) - { fprintf(fd, " && (((P0 *)pptr(now._nr_pr - 1))->_priority = %d)", now->val); - } + /* process now->sym->name has run priority now->val */ + if (now->val > 0 && now->val < 256 && !old_priority_rules) + { fprintf(fd, " && (((P0 *)pptr(now._nr_pr - 1))->_priority = %d)", now->val); + } #endif - if (now->val < 0 || now->val > 255) /* 0 itself is allowed */ - { fatal("bad process in run %s, valid range: 1..255", now->sym->name); - } - break; - - case ENABLED: - cat3("enabled(II, ", now->lft, ")"); - break; - - case GET_P: - if (old_priority_rules) - { fprintf(fd, "1"); - } else - { cat3("get_priority(", now->lft, ")"); - } - break; - - case SET_P: - if (!old_priority_rules) - { fprintf(fd, "if (TstOnly) return 1; /* T30 */\n\t\t"); - fprintf(fd, "set_priority("); - putstmnt(fd, now->lft->lft, m); - fprintf(fd, ", "); - putstmnt(fd, now->lft->rgt, m); - fprintf(fd, ")"); - } - break; - - case NONPROGRESS: - /* o_pm&4=progress, tau&128=claim stutter */ - if (separate == 2) - fprintf(fd, "(!(o_pm&4) && !(tau&128))"); - else - fprintf(fd, "(!(trpt->o_pm&4) && !(trpt->tau&128))"); - break; - - case PC_VAL: - cat3("((P0 *) Pptr(", now->lft, "+BASE))->_p"); - break; - - case LEN: - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); - putname(fd, "q_R_check(", now->lft, m, ""); - fprintf(fd, ", II)) &&\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); - putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - putname(fd, "q_len(", now->lft, m, ")"); - break; - - case FULL: - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); - putname(fd, "q_R_check(", now->lft, m, ""); - fprintf(fd, ", II)) &&\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); - putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - putname(fd, "q_full(", now->lft, m, ")"); - break; - - case EMPTY: - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); - putname(fd, "q_R_check(", now->lft, m, ""); - fprintf(fd, ", II)) &&\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); - putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - putname(fd, "(q_len(", now->lft, m, ")==0)"); - break; - - case NFULL: - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); - putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - putname(fd, "(!q_full(", now->lft, m, "))"); - break; - - case NEMPTY: - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); - putname(fd, "q_R_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - putname(fd, "(q_len(", now->lft, m, ")>0)"); - break; - - case 's': - if (Pid_nr == eventmapnr) - { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 's') "); - putname(fd, "|| _qid+1 != ", now->lft, m, ""); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL) - continue; - fprintf(fd, " \\\n\t\t|| qrecv("); - putname(fd, "", now->lft, m, ", "); - putname(fd, "q_len(", now->lft, m, ")-1, "); - fprintf(fd, "%d, 0) != ", i); - if (v->lft->ntyp == CONST) - putstmnt(fd, v->lft, m); - else /* EVAL */ - putstmnt(fd, v->lft->lft, m); - } - fprintf(fd, ")\n"); - fprintf(fd, "\t\t continue"); - putname(fd_th, " || (x_y3_ == ", now->lft, m, ")"); - break; - } - if (TestOnly) - { if (m_loss) - fprintf(fd, "1"); - else - putname(fd, "!q_full(", now->lft, m, ")"); - break; - } - if (has_xu) - { fprintf(fd, "\n#if !defined(XUSAFE) && !defined(NOREDUCE)\n\t\t"); - putname(fd, "if (q_claim[", now->lft, m, "]&2)\n\t\t"); - putname(fd, "{ q_S_check(", now->lft, m, ", II);\n\t\t"); - fprintf(fd, "}\n"); - if (has_sorted && now->val == 1) - { putname(fd, "\t\tif (q_claim[", now->lft, m, "]&1)\n\t\t"); /* &1 iso &2 */ - fprintf(fd, "{ uerror(\"sorted send on xr channel violates po reduction\");\n\t\t"); - fprintf(fd, "}\n"); - } - fprintf(fd, "#endif\n\t\t"); - } - fprintf(fd, "if (q_%s", - (u_sync > 0 && u_async == 0)?"len":"full"); - putname(fd, "(", now->lft, m, "))\n"); - - if (m_loss) - { fprintf(fd, "\t\t{ nlost++; delta_m = 1; } else {"); - } else - { fprintf(fd, "\t\t\t"); - Bailout(fd, ";"); - } - - if (has_enabled || has_priority) - fprintf(fd, "\n\t\tif (TstOnly) return 1; /* T1 */"); - - if (u_sync && !u_async && rvopt) - fprintf(fd, "\n\n\t\tif (no_recvs(II)) continue;\n"); - - fprintf(fd, "\n#ifdef HAS_CODE\n"); - fprintf(fd, "\t\tif (readtrail && gui) {\n"); - fprintf(fd, "\t\t\tchar simtmp[64];\n"); - putname(fd, "\t\t\tsprintf(simvals, \"%%d!\", ", now->lft, m, ");\n"); - _isok++; - for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { cat3("\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); - if (v->rgt) - fprintf(fd, "\t\tstrcat(simvals, \",\");\n"); - } - _isok--; - fprintf(fd, "\t\t}\n"); - fprintf(fd, "#endif\n\t\t"); - - putname(fd, "\n\t\tqsend(", now->lft, m, ""); - fprintf(fd, ", %d", now->val); - for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { cat2(", ", v->lft); - } - if (i > Mpars) - { terse++; - putname(stdout, "channel name: ", now->lft, m, "\n"); - terse--; - printf(" %d msg parameters sent, %d expected\n", i, Mpars); - fatal("too many pars in send", ""); - } - for (j = i; i < Mpars; i++) - { fprintf(fd, ", 0"); - } - fprintf(fd, ", %d)", j); - if (u_sync) - { fprintf(fd, ";\n\t\t"); - if (u_async) - { putname(fd, "if (q_zero(", now->lft, m, ")) "); - } - putname(fd, "{ boq = ", now->lft, m, ""); - if (GenCode) - { fprintf(fd, "; Uerror(\"rv-attempt in d_step\")"); - } - fprintf(fd, "; }"); - } - if (m_loss) - { fprintf(fd, ";\n\t\t}\n\t\t"); /* end of m_loss else */ - } - break; - - case 'r': - if (Pid_nr == eventmapnr) - { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 'r') "); - putname(fd, "|| _qid+1 != ", now->lft, m, ""); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL) - continue; - fprintf(fd, " \\\n\t\t|| qrecv("); - putname(fd, "", now->lft, m, ", "); - fprintf(fd, "0, %d, 0) != ", i); - if (v->lft->ntyp == CONST) - putstmnt(fd, v->lft, m); - else /* EVAL */ - putstmnt(fd, v->lft->lft, m); - } - fprintf(fd, ")\n"); - fprintf(fd, "\t\t continue"); - - putname(fd_tc, " || (x_y3_ == ", now->lft, m, ")"); - - break; - } - if (TestOnly) - { fprintf(fd, "(("); - if (u_sync) fprintf(fd, "(boq == -1 && "); - - putname(fd, "q_len(", now->lft, m, ")"); - - if (u_sync && now->val <= 1) - { putname(fd, ") || (boq == ", now->lft,m," && "); - putname(fd, "q_zero(", now->lft,m,"))"); - } - - fprintf(fd, ")"); - if (now->val == 0 || now->val == 2) - { for (v = now->rgt, i=j=0; v; v = v->rgt, i++) - { if (v->lft->ntyp == CONST) - { cat3("\n\t\t&& (", v->lft, " == "); - putname(fd, "qrecv(", now->lft, m, ", "); - fprintf(fd, "0, %d, 0))", i); - } else if (v->lft->ntyp == EVAL) - { cat3("\n\t\t&& (", v->lft->lft, " == "); - putname(fd, "qrecv(", now->lft, m, ", "); - fprintf(fd, "0, %d, 0))", i); - } else - { j++; continue; - } - } - } else - { fprintf(fd, "\n\t\t&& Q_has("); - putname(fd, "", now->lft, m, ""); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp == CONST) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft, m); - } else if (v->lft->ntyp == EVAL) - { if (v->lft->lft->ntyp == ',') /* usertype1 */ - { if (0) { dump_tree("1", v->lft->lft); } - Lextok *fix = v->lft->lft; - do { i++; - fprintf(fd, ", 1, "); - putstmnt(fd, fix->lft, m); - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - } else - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); - } - } else - { fprintf(fd, ", 0, 0"); - } } - for ( ; i < Mpars; i++) - { fprintf(fd, ", 0, 0"); - } - fprintf(fd, ")"); - } - fprintf(fd, ")"); - break; - } - if (has_xu) - { fprintf(fd, "\n#if !defined(XUSAFE) && !defined(NOREDUCE)\n\t\t"); - putname(fd, "if (q_claim[", now->lft, m, "]&1)\n\t\t"); - putname(fd, "{ q_R_check(", now->lft, m, ", II);\n\t\t"); - if (has_random && now->val != 0) - fprintf(fd, " uerror(\"rand receive on xr channel violates po reduction\");\n\t\t"); - fprintf(fd, "}\n"); - fprintf(fd, "#endif\n\t\t"); - } - if (u_sync) - { if (now->val >= 2) - { if (u_async) - { fprintf(fd, "if ("); - putname(fd, "q_zero(", now->lft,m,"))"); - fprintf(fd, "\n\t\t{\t"); - } - fprintf(fd, "uerror(\"polling "); - fprintf(fd, "rv chan\");\n\t\t"); - if (u_async) - fprintf(fd, " continue;\n\t\t}\n\t\t"); - fprintf(fd, "IfNotBlocked\n\t\t"); - } else - { fprintf(fd, "if ("); - if (u_async == 0) - putname(fd, "boq != ", now->lft,m,") "); - else - { putname(fd, "q_zero(", now->lft,m,"))"); - fprintf(fd, "\n\t\t{\tif (boq != "); - putname(fd, "", now->lft,m,") "); - Bailout(fd, ";\n\t\t} else\n\t\t"); - fprintf(fd, "{\tif (boq != -1) "); - } - Bailout(fd, ";\n\t\t"); - if (u_async) - fprintf(fd, "}\n\t\t"); - } } - putname(fd, "if (q_len(", now->lft, m, ") == 0) "); - Bailout(fd, ""); - - for (v = now->rgt, j=0; v; v = v->rgt) - { if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL) - { j++; /* count settables */ - } } - - fprintf(fd, ";\n\n\t\tXX=1"); -/* test */ if (now->val == 0 || now->val == 2) - { for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp == CONST) - { fprintf(fd, ";\n\t\t"); - cat3("if (", v->lft, " != "); - putname(fd, "qrecv(", now->lft, m, ", "); - fprintf(fd, "0, %d, 0)) ", i); - Bailout(fd, ""); - } else if (v->lft->ntyp == EVAL) - { fprintf(fd, ";\n\t\t"); - cat3("if (", v->lft->lft, " != "); - putname(fd, "qrecv(", now->lft, m, ", "); - fprintf(fd, "0, %d, 0)) ", i); - Bailout(fd, ""); - } } - if (has_enabled || has_priority) - fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); - } else /* random receive: val 1 or 3 */ - { fprintf(fd, ";\n\t\tif (!(XX = Q_has("); - putname(fd, "", now->lft, m, ""); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp == CONST) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft, m); - } else if (v->lft->ntyp == EVAL) - { if (v->lft->lft->ntyp == ',') /* usertype2 */ - { if (0) { dump_tree("2", v->lft->lft); } - Lextok *fix = v->lft->lft; - do { i++; - fprintf(fd, ", 1, "); - putstmnt(fd, fix->lft, m); - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - } else - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); - } - } else - { fprintf(fd, ", 0, 0"); - } } - for ( ; i < Mpars; i++) - { fprintf(fd, ", 0, 0"); - } - fprintf(fd, "))) "); - Bailout(fd, ""); - - if (has_enabled || has_priority) - { fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); - } - if (!GenCode) - { fprintf(fd, ";\n\t\t"); - if (multi_oval) - { check_needed(); - fprintf(fd, "(trpt+1)->bup.ovals[%d] = ", - multi_oval-1); - multi_oval++; - } else - { fprintf(fd, "(trpt+1)->bup.oval = "); - } - fprintf(fd, "XX"); - } } - - if (j == 0 && now->val >= 2) - { fprintf(fd, ";\n\t\t"); - break; /* poll without side-effect */ - } - - if (!GenCode) - { int jj = 0; - fprintf(fd, ";\n\t\t"); - /* no variables modified */ - if (j == 0 && now->val == 0) - { fprintf(fd, "\n#ifndef BFS_PAR\n\t\t"); - /* q_flds values are not shared among cores */ - fprintf(fd, "if (q_flds[((Q0 *)qptr("); - putname(fd, "", now->lft, m, "-1))->_t]"); - fprintf(fd, " != %d)\n\t\t\t", i); - fprintf(fd, "Uerror(\"wrong nr of msg fields in rcv\");\n"); - fprintf(fd, "#endif\n\t\t"); - } - - for (v = now->rgt; v; v = v->rgt) - { if ((v->lft->ntyp != CONST - && v->lft->ntyp != EVAL)) - { jj++; /* nr of vars needing bup */ - } } - - if (jj) - for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { char tempbuf[64]; - - if ((v->lft->ntyp == CONST - || v->lft->ntyp == EVAL)) - continue; - - if (multi_oval) - { check_needed(); - sprintf(tempbuf, "(trpt+1)->bup.ovals[%d] = ", - multi_oval-1); - multi_oval++; - } else - sprintf(tempbuf, "(trpt+1)->bup.oval = "); - - if (v->lft->sym && !strcmp(v->lft->sym->name, "_")) - { fprintf(fd, tempbuf, (char *) 0); - putname(fd, "qrecv(", now->lft, m, ""); - fprintf(fd, ", XX-1, %d, 0);\n\t\t", i); - } else - { _isok++; - cat30(tempbuf, v->lft, ";\n\t\t"); - _isok--; - } - } - - if (jj) /* check for double entries q?x,x */ - { Lextok *w; - - for (v = now->rgt; v; v = v->rgt) - { if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL - && v->lft->sym - && v->lft->sym->type != STRUCT /* not a struct */ - && (v->lft->sym->nel == 1 && v->lft->sym->isarray == 0) /* not array */ - && strcmp(v->lft->sym->name, "_") != 0) - for (w = v->rgt; w; w = w->rgt) - if (v->lft->sym == w->lft->sym) - { fatal("cannot use var ('%s') in multiple msg fields", - v->lft->sym->name); - } } } - } -/* set */ for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { - if (v->lft->ntyp == CONST && v->rgt) - { continue; - } - - if (v->lft->ntyp == EVAL) - { Lextok *fix = v->lft->lft; - int old_i = i; - while (fix && fix->ntyp == ',') /* usertype9 */ - { i++; - fix = fix->rgt; - } - if (i > old_i) - { i--; /* next increment handles it */ - } - if (v->rgt) - { continue; - } - } - fprintf(fd, ";\n\t\t"); - - if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL - && v->lft->sym != NULL - && strcmp(v->lft->sym->name, "_") != 0) - { nocast=1; - _isok++; - putstmnt(fd, v->lft, m); - _isok--; - nocast=0; - fprintf(fd, " = "); - } - - putname(fd, "qrecv(", now->lft, m, ", "); - fprintf(fd, "XX-1, %d, ", i); - fprintf(fd, "%d)", (v->rgt || now->val >= 2)?0:1); - - if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL - && v->lft->sym != NULL - && strcmp(v->lft->sym->name, "_") != 0 - && (v->lft->ntyp != NAME - || v->lft->sym->type != CHAN)) - { fprintf(fd, ";\n#ifdef VAR_RANGES"); - fprintf(fd, "\n\t\tlogval(\""); - withprocname = terse = nocast = 1; - _isok++; - putstmnt(fd,v->lft,m); - withprocname = terse = nocast = 0; - fprintf(fd, "\", "); - putstmnt(fd,v->lft,m); - _isok--; - fprintf(fd, ");\n#endif\n"); - fprintf(fd, "\t\t"); - } - } - fprintf(fd, ";\n\t\t"); - - fprintf(fd, "\n#ifdef HAS_CODE\n"); - fprintf(fd, "\t\tif (readtrail && gui) {\n"); - fprintf(fd, "\t\t\tchar simtmp[32];\n"); - putname(fd, "\t\t\tsprintf(simvals, \"%%d?\", ", now->lft, m, ");\n"); - _isok++; - for (v = now->rgt, i = 0; v; v = v->rgt, i++) - { if (v->lft->ntyp != EVAL) - { cat3("\t\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); - } else - { if (v->lft->lft->ntyp == ',') /* usertype4 */ - { if (0) { dump_tree("4", v->lft->lft); } - Lextok *fix = v->lft->lft; - do { i++; - cat3("\n\t\t\tsprintf(simtmp, \"%%d,\", ", fix->lft, "); strcat(simvals, simtmp);"); - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - } else - { cat3("\n\t\t\tsprintf(simtmp, \"%%d\", ", v->lft->lft, "); strcat(simvals, simtmp);"); - } } - if (v->rgt) - { fprintf(fd, "\n\t\t\tstrcat(simvals, \",\");\n"); - } } - _isok--; - fprintf(fd, "\n\t\t}\n"); - fprintf(fd, "#endif\n\t\t"); - - if (u_sync) - { putname(fd, "if (q_zero(", now->lft, m, "))"); - fprintf(fd, "\n\t\t{ boq = -1;\n"); - - fprintf(fd, "#ifndef NOFAIR\n"); /* NEW 3.0.8 */ - fprintf(fd, "\t\t\tif (fairness\n"); - fprintf(fd, "\t\t\t&& !(trpt->o_pm&32)\n"); - fprintf(fd, "\t\t\t&& (now._a_t&2)\n"); - fprintf(fd, "\t\t\t&& now._cnt[now._a_t&1] == II+2)\n"); - fprintf(fd, "\t\t\t{ now._cnt[now._a_t&1] -= 1;\n"); - fprintf(fd, "#ifdef VERI\n"); - fprintf(fd, "\t\t\t if (II == 1)\n"); - fprintf(fd, "\t\t\t now._cnt[now._a_t&1] = 1;\n"); - fprintf(fd, "#endif\n"); - fprintf(fd, "#ifdef DEBUG\n"); - fprintf(fd, "\t\t\tprintf(\"%%3ld: proc %%d fairness \", depth, II);\n"); - fprintf(fd, "\t\t\tprintf(\"Rule 2: --cnt to %%d (%%d)\\n\",\n"); - fprintf(fd, "\t\t\t now._cnt[now._a_t&1], now._a_t);\n"); - fprintf(fd, "#endif\n"); - fprintf(fd, "\t\t\t trpt->o_pm |= (32|64);\n"); - fprintf(fd, "\t\t\t}\n"); - fprintf(fd, "#endif\n"); - - fprintf(fd, "\n\t\t}"); - } - break; - - case 'R': - if (!terse && !TestOnly && has_xu) - { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); - fprintf(fd, "q_R_check("); - putname(fd, "", now->lft, m, ", II)) &&\n\t\t"); - putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); - putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); - fprintf(fd, "\n#endif\n\t\t"); - } - if (u_sync>0) - putname(fd, "not_RV(", now->lft, m, ") && \\\n\t\t"); - - for (v = now->rgt, i=j=0; v; v = v->rgt, i++) - if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL) - { j++; continue; - } - if (now->val == 0 || i == j) - { putname(fd, "(q_len(", now->lft, m, ") > 0"); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp != CONST - && v->lft->ntyp != EVAL) - continue; - fprintf(fd, " \\\n\t\t&& qrecv("); - putname(fd, "", now->lft, m, ", "); - fprintf(fd, "0, %d, 0) == ", i); - if (v->lft->ntyp == CONST) - { putstmnt(fd, v->lft, m); - } else /* EVAL */ - { if (v->lft->lft->ntyp == ',') /* usertype2 */ - { if (0) { dump_tree("8", v->lft->lft); } - Lextok *fix = v->lft->lft; - do { i++; - putstmnt(fd, fix->lft, m); - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - } else - { putstmnt(fd, v->lft->lft, m); - } - } - } - fprintf(fd, ")"); - } else - { putname(fd, "Q_has(", now->lft, m, ""); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v->lft->ntyp == CONST) - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft, m); - } else if (v->lft->ntyp == EVAL) - { if (v->lft->lft->ntyp == ',') /* usertype3 */ - { if (0) { dump_tree("3", v->lft->lft); } - Lextok *fix = v->lft->lft; - do { i++; - fprintf(fd, ", 1, "); - putstmnt(fd, fix->lft, m); - fix = fix->rgt; - } while (fix && fix->ntyp == ','); - } else - { fprintf(fd, ", 1, "); - putstmnt(fd, v->lft->lft, m); - } - } else - fprintf(fd, ", 0, 0"); - } - for ( ; i < Mpars; i++) - { fprintf(fd, ", 0, 0"); - } - fprintf(fd, ")"); - } - break; - - case 'c': - preruse(fd, now->lft); /* preconditions */ - cat3("if (!(", now->lft, "))\n\t\t\t"); - Bailout(fd, ""); - break; - - case ELSE: - if (!GenCode) - { if (separate == 2) - fprintf(fd, "if (o_pm&1)\n\t\t\t"); - else - fprintf(fd, "if (trpt->o_pm&1)\n\t\t\t"); - Bailout(fd, ""); - } else - { fprintf(fd, "/* else */"); - } - break; - - case '?': - if (now->lft) - { cat3("( (", now->lft, ") ? "); - } - if (now->rgt) - { cat3("(", now->rgt->lft, ") : "); - cat3("(", now->rgt->rgt, ") )"); - } - break; - - case ASGN: - if (check_track(now) == STRUCT) { break; } - - if (has_enabled || has_priority) - fprintf(fd, "if (TstOnly) return 1; /* T3 */\n\t\t"); - _isok++; - - if (!GenCode) - { if (multi_oval) - { char tempbuf[64]; - check_needed(); - sprintf(tempbuf, "(trpt+1)->bup.ovals[%d] = ", - multi_oval-1); - multi_oval++; - cat30(tempbuf, now->lft, ";\n\t\t"); - } else - { cat3("(trpt+1)->bup.oval = ", now->lft, ";\n\t\t"); - } } - if (now->lft->sym - && now->lft->sym->type == PREDEF - && strcmp(now->lft->sym->name, "_") != 0 - && strcmp(now->lft->sym->name, "_priority") != 0) - { fatal("invalid assignment to %s", now->lft->sym->name); - } - - nocast = 1; putstmnt(fd,now->lft,m); nocast = 0; - fprintf(fd," = "); - _isok--; - if (now->lft->sym->isarray - && now->rgt->ntyp == ',') /* array initializer */ - { putstmnt(fd, now->rgt->lft, m); - non_fatal("cannot use an array list initializer here", (char *) 0); - } else - { putstmnt(fd, now->rgt, m); - } - - if (now->sym->type != CHAN - || verbose > 0) - { fprintf(fd, ";\n#ifdef VAR_RANGES"); - fprintf(fd, "\n\t\tlogval(\""); - withprocname = terse = nocast = 1; - _isok++; - putstmnt(fd,now->lft,m); - withprocname = terse = nocast = 0; - fprintf(fd, "\", "); - putstmnt(fd,now->lft,m); - _isok--; - fprintf(fd, ");\n#endif\n"); - fprintf(fd, "\t\t"); - } - break; - - case PRINT: - if (has_enabled || has_priority) - fprintf(fd, "if (TstOnly) return 1; /* T4 */\n\t\t"); + if (now->val < 0 || now->val > 255) /* 0 itself is allowed */ + { fatal("bad process in run %s, valid range: 1..255", now->sym->name); + } + break; + + case ENABLED: + cat3("enabled(II, ", now->lft, ")"); + break; + + case GET_P: + if (old_priority_rules) + { fprintf(fd, "1"); + } else + { cat3("get_priority(", now->lft, ")"); + } + break; + + case SET_P: + if (!old_priority_rules) + { fprintf(fd, "if (TstOnly) return 1; /* T30 */\n\t\t"); + fprintf(fd, "set_priority("); + putstmnt(fd, now->lft->lft, m); + fprintf(fd, ", "); + putstmnt(fd, now->lft->rgt, m); + fprintf(fd, ")"); + } + break; + + case NONPROGRESS: + /* o_pm&4=progress, tau&128=claim stutter */ + if (separate == 2) + fprintf(fd, "(!(o_pm&4) && !(tau&128))"); + else + fprintf(fd, "(!(trpt->o_pm&4) && !(trpt->tau&128))"); + break; + + case PC_VAL: + cat3("((P0 *) Pptr(", now->lft, "+BASE))->_p"); + break; + + case LEN: + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); + putname(fd, "q_R_check(", now->lft, m, ""); + fprintf(fd, ", II)) &&\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); + putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + putname(fd, "q_len(", now->lft, m, ")"); + break; + + case FULL: + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); + putname(fd, "q_R_check(", now->lft, m, ""); + fprintf(fd, ", II)) &&\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); + putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + putname(fd, "q_full(", now->lft, m, ")"); + break; + + case EMPTY: + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); + putname(fd, "q_R_check(", now->lft, m, ""); + fprintf(fd, ", II)) &&\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); + putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + putname(fd, "(q_len(", now->lft, m, ")==0)"); + break; + + case NFULL: + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); + putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + putname(fd, "(!q_full(", now->lft, m, "))"); + break; + + case NEMPTY: + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); + putname(fd, "q_R_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + putname(fd, "(q_len(", now->lft, m, ")>0)"); + break; + + case 's': + if (Pid_nr == eventmapnr) + { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 's') "); + putname(fd, "|| _qid+1 != ", now->lft, m, ""); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL) + continue; + fprintf(fd, " \\\n\t\t|| qrecv("); + putname(fd, "", now->lft, m, ", "); + putname(fd, "q_len(", now->lft, m, ")-1, "); + fprintf(fd, "%d, 0) != ", i); + if (v->lft->ntyp == CONST) + putstmnt(fd, v->lft, m); + else /* EVAL */ + putstmnt(fd, v->lft->lft, m); + } + fprintf(fd, ")\n"); + fprintf(fd, "\t\t continue"); + putname(fd_th, " || (x_y3_ == ", now->lft, m, ")"); + break; + } + if (TestOnly) + { if (m_loss) + fprintf(fd, "1"); + else + putname(fd, "!q_full(", now->lft, m, ")"); + break; + } + if (has_xu) + { fprintf(fd, "\n#if !defined(XUSAFE) && !defined(NOREDUCE)\n\t\t"); + putname(fd, "if (q_claim[", now->lft, m, "]&2)\n\t\t"); + putname(fd, "{ q_S_check(", now->lft, m, ", II);\n\t\t"); + fprintf(fd, "}\n"); + if (has_sorted && now->val == 1) + { putname(fd, "\t\tif (q_claim[", now->lft, m, "]&1)\n\t\t"); /* &1 iso &2 */ + fprintf(fd, "{ uerror(\"sorted send on xr channel violates po reduction\");\n\t\t"); + fprintf(fd, "}\n"); + } + fprintf(fd, "#endif\n\t\t"); + } + fprintf(fd, "if (q_%s", + (u_sync > 0 && u_async == 0)?"len":"full"); + putname(fd, "(", now->lft, m, "))\n"); + + if (m_loss) + { fprintf(fd, "\t\t{ nlost++; delta_m = 1; } else {"); + } else + { fprintf(fd, "\t\t\t"); + Bailout(fd, ";"); + } + + if (has_enabled || has_priority) + fprintf(fd, "\n\t\tif (TstOnly) return 1; /* T1 */"); + + if (u_sync && !u_async && rvopt) + fprintf(fd, "\n\n\t\tif (no_recvs(II)) continue;\n"); + + fprintf(fd, "\n#ifdef HAS_CODE\n"); + fprintf(fd, "\t\tif (readtrail && gui) {\n"); + fprintf(fd, "\t\t\tchar simtmp[64];\n"); + putname(fd, "\t\t\tsprintf(simvals, \"%%d!\", ", now->lft, m, ");\n"); + _isok++; + for (v = now->rgt, i = 0; v; v = v->rgt, i++) + { cat3("\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); + if (v->rgt) + fprintf(fd, "\t\tstrcat(simvals, \",\");\n"); + } + _isok--; + fprintf(fd, "\t\t}\n"); + fprintf(fd, "#endif\n\t\t"); + + putname(fd, "\n\t\tqsend(", now->lft, m, ""); + fprintf(fd, ", %d", now->val); + for (v = now->rgt, i = 0; v; v = v->rgt, i++) + { cat2(", ", v->lft); + } + if (i > Mpars) + { terse++; + putname(stdout, "channel name: ", now->lft, m, "\n"); + terse--; + printf(" %d msg parameters sent, %d expected\n", i, Mpars); + fatal("too many pars in send", ""); + } + for (j = i; i < Mpars; i++) + { fprintf(fd, ", 0"); + } + fprintf(fd, ", %d)", j); + if (u_sync) + { fprintf(fd, ";\n\t\t"); + if (u_async) + { putname(fd, "if (q_zero(", now->lft, m, ")) "); + } + putname(fd, "{ boq = ", now->lft, m, ""); + if (GenCode) + { fprintf(fd, "; Uerror(\"rv-attempt in d_step\")"); + } + fprintf(fd, "; }"); + } + if (m_loss) + { fprintf(fd, ";\n\t\t}\n\t\t"); /* end of m_loss else */ + } + break; + + case 'r': + if (Pid_nr == eventmapnr) + { fprintf(fd, "if ((II == -EVENT_TRACE && _tp != 'r') "); + putname(fd, "|| _qid+1 != ", now->lft, m, ""); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL) + continue; + fprintf(fd, " \\\n\t\t|| qrecv("); + putname(fd, "", now->lft, m, ", "); + fprintf(fd, "0, %d, 0) != ", i); + if (v->lft->ntyp == CONST) + putstmnt(fd, v->lft, m); + else /* EVAL */ + putstmnt(fd, v->lft->lft, m); + } + fprintf(fd, ")\n"); + fprintf(fd, "\t\t continue"); + + putname(fd_tc, " || (x_y3_ == ", now->lft, m, ")"); + + break; + } + if (TestOnly) + { fprintf(fd, "(("); + if (u_sync) fprintf(fd, "(boq == -1 && "); + + putname(fd, "q_len(", now->lft, m, ")"); + + if (u_sync && now->val <= 1) + { putname(fd, ") || (boq == ", now->lft,m," && "); + putname(fd, "q_zero(", now->lft,m,"))"); + } + + fprintf(fd, ")"); + if (now->val == 0 || now->val == 2) + { for (v = now->rgt, i=j=0; v; v = v->rgt, i++) + { if (v->lft->ntyp == CONST) + { cat3("\n\t\t&& (", v->lft, " == "); + putname(fd, "qrecv(", now->lft, m, ", "); + fprintf(fd, "0, %d, 0))", i); + } else if (v->lft->ntyp == EVAL) + { cat3("\n\t\t&& (", v->lft->lft, " == "); + putname(fd, "qrecv(", now->lft, m, ", "); + fprintf(fd, "0, %d, 0))", i); + } else + { j++; continue; + } + } + } else + { fprintf(fd, "\n\t\t&& Q_has("); + putname(fd, "", now->lft, m, ""); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp == CONST) + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft, m); + } else if (v->lft->ntyp == EVAL) + { if (v->lft->lft->ntyp == ',') /* usertype1 */ + { if (0) { dump_tree("1", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } + } else + { fprintf(fd, ", 0, 0"); + } } + for ( ; i < Mpars; i++) + { fprintf(fd, ", 0, 0"); + } + fprintf(fd, ")"); + } + fprintf(fd, ")"); + break; + } + if (has_xu) + { fprintf(fd, "\n#if !defined(XUSAFE) && !defined(NOREDUCE)\n\t\t"); + putname(fd, "if (q_claim[", now->lft, m, "]&1)\n\t\t"); + putname(fd, "{ q_R_check(", now->lft, m, ", II);\n\t\t"); + if (has_random && now->val != 0) + fprintf(fd, " uerror(\"rand receive on xr channel violates po reduction\");\n\t\t"); + fprintf(fd, "}\n"); + fprintf(fd, "#endif\n\t\t"); + } + if (u_sync) + { if (now->val >= 2) + { if (u_async) + { fprintf(fd, "if ("); + putname(fd, "q_zero(", now->lft,m,"))"); + fprintf(fd, "\n\t\t{\t"); + } + fprintf(fd, "uerror(\"polling "); + fprintf(fd, "rv chan\");\n\t\t"); + if (u_async) + fprintf(fd, " continue;\n\t\t}\n\t\t"); + fprintf(fd, "IfNotBlocked\n\t\t"); + } else + { fprintf(fd, "if ("); + if (u_async == 0) + putname(fd, "boq != ", now->lft,m,") "); + else + { putname(fd, "q_zero(", now->lft,m,"))"); + fprintf(fd, "\n\t\t{\tif (boq != "); + putname(fd, "", now->lft,m,") "); + Bailout(fd, ";\n\t\t} else\n\t\t"); + fprintf(fd, "{\tif (boq != -1) "); + } + Bailout(fd, ";\n\t\t"); + if (u_async) + fprintf(fd, "}\n\t\t"); + } } + putname(fd, "if (q_len(", now->lft, m, ") == 0) "); + Bailout(fd, ""); + + for (v = now->rgt, j=0; v; v = v->rgt) + { if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL) + { j++; /* count settables */ + } } + + fprintf(fd, ";\n\n\t\tXX=1"); +/* test */ if (now->val == 0 || now->val == 2) + { for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp == CONST) + { fprintf(fd, ";\n\t\t"); + cat3("if (", v->lft, " != "); + putname(fd, "qrecv(", now->lft, m, ", "); + fprintf(fd, "0, %d, 0)) ", i); + Bailout(fd, ""); + } else if (v->lft->ntyp == EVAL) + { fprintf(fd, ";\n\t\t"); + cat3("if (", v->lft->lft, " != "); + putname(fd, "qrecv(", now->lft, m, ", "); + fprintf(fd, "0, %d, 0)) ", i); + Bailout(fd, ""); + } } + if (has_enabled || has_priority) + fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); + } else /* random receive: val 1 or 3 */ + { fprintf(fd, ";\n\t\tif (!(XX = Q_has("); + putname(fd, "", now->lft, m, ""); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp == CONST) + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft, m); + } else if (v->lft->ntyp == EVAL) + { if (v->lft->lft->ntyp == ',') /* usertype2 */ + { if (0) { dump_tree("2", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } + } else + { fprintf(fd, ", 0, 0"); + } } + for ( ; i < Mpars; i++) + { fprintf(fd, ", 0, 0"); + } + fprintf(fd, "))) "); + Bailout(fd, ""); + + if (has_enabled || has_priority) + { fprintf(fd, ";\n\t\tif (TstOnly) return 1 /* T2 */"); + } + if (!GenCode) + { fprintf(fd, ";\n\t\t"); + if (multi_oval) + { check_needed(); + fprintf(fd, "(trpt+1)->bup.ovals[%d] = ", + multi_oval-1); + multi_oval++; + } else + { fprintf(fd, "(trpt+1)->bup.oval = "); + } + fprintf(fd, "XX"); + } } + + if (j == 0 && now->val >= 2) + { fprintf(fd, ";\n\t\t"); + break; /* poll without side-effect */ + } + + if (!GenCode) + { int jj = 0; + fprintf(fd, ";\n\t\t"); + /* no variables modified */ + if (j == 0 && now->val == 0) + { fprintf(fd, "\n#ifndef BFS_PAR\n\t\t"); + /* q_flds values are not shared among cores */ + fprintf(fd, "if (q_flds[((Q0 *)qptr("); + putname(fd, "", now->lft, m, "-1))->_t]"); + fprintf(fd, " != %d)\n\t\t\t", i); + fprintf(fd, "Uerror(\"wrong nr of msg fields in rcv\");\n"); + fprintf(fd, "#endif\n\t\t"); + } + + for (v = now->rgt; v; v = v->rgt) + { if ((v->lft->ntyp != CONST + && v->lft->ntyp != EVAL)) + { jj++; /* nr of vars needing bup */ + } } + + if (jj) + for (v = now->rgt, i = 0; v; v = v->rgt, i++) + { char tempbuf[64]; + + if ((v->lft->ntyp == CONST + || v->lft->ntyp == EVAL)) + continue; + + if (multi_oval) + { check_needed(); + sprintf(tempbuf, "(trpt+1)->bup.ovals[%d] = ", + multi_oval-1); + multi_oval++; + } else + sprintf(tempbuf, "(trpt+1)->bup.oval = "); + + if (v->lft->sym && !strcmp(v->lft->sym->name, "_")) + { fprintf(fd, tempbuf, (char *) 0); + putname(fd, "qrecv(", now->lft, m, ""); + fprintf(fd, ", XX-1, %d, 0);\n\t\t", i); + } else + { _isok++; + cat30(tempbuf, v->lft, ";\n\t\t"); + _isok--; + } + } + + if (jj) /* check for double entries q?x,x */ + { Lextok *w; + + for (v = now->rgt; v; v = v->rgt) + { if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL + && v->lft->sym + && v->lft->sym->type != STRUCT /* not a struct */ + && (v->lft->sym->nel == 1 && v->lft->sym->isarray == 0) /* not array */ + && strcmp(v->lft->sym->name, "_") != 0) + for (w = v->rgt; w; w = w->rgt) + if (v->lft->sym == w->lft->sym) + { fatal("cannot use var ('%s') in multiple msg fields", + v->lft->sym->name); + } } } + } +/* set */ for (v = now->rgt, i = 0; v; v = v->rgt, i++) + { + if (v->lft->ntyp == CONST && v->rgt) + { continue; + } + + if (v->lft->ntyp == EVAL) + { Lextok *fix = v->lft->lft; + int old_i = i; + while (fix && fix->ntyp == ',') /* usertype9 */ + { i++; + fix = fix->rgt; + } + if (i > old_i) + { i--; /* next increment handles it */ + } + if (v->rgt) + { continue; + } + } + fprintf(fd, ";\n\t\t"); + + if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL + && v->lft->sym != NULL + && strcmp(v->lft->sym->name, "_") != 0) + { nocast=1; + _isok++; + putstmnt(fd, v->lft, m); + _isok--; + nocast=0; + fprintf(fd, " = "); + } + + putname(fd, "qrecv(", now->lft, m, ", "); + fprintf(fd, "XX-1, %d, ", i); + fprintf(fd, "%d)", (v->rgt || now->val >= 2)?0:1); + + if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL + && v->lft->sym != NULL + && strcmp(v->lft->sym->name, "_") != 0 + && (v->lft->ntyp != NAME + || v->lft->sym->type != CHAN)) + { fprintf(fd, ";\n#ifdef VAR_RANGES"); + fprintf(fd, "\n\t\tlogval(\""); + withprocname = terse = nocast = 1; + _isok++; + putstmnt(fd,v->lft,m); + withprocname = terse = nocast = 0; + fprintf(fd, "\", "); + putstmnt(fd,v->lft,m); + _isok--; + fprintf(fd, ");\n#endif\n"); + fprintf(fd, "\t\t"); + } + } + fprintf(fd, ";\n\t\t"); + + fprintf(fd, "\n#ifdef HAS_CODE\n"); + fprintf(fd, "\t\tif (readtrail && gui) {\n"); + fprintf(fd, "\t\t\tchar simtmp[32];\n"); + putname(fd, "\t\t\tsprintf(simvals, \"%%d?\", ", now->lft, m, ");\n"); + _isok++; + for (v = now->rgt, i = 0; v; v = v->rgt, i++) + { if (v->lft->ntyp != EVAL) + { cat3("\t\t\tsprintf(simtmp, \"%%d\", ", v->lft, "); strcat(simvals, simtmp);"); + } else + { if (v->lft->lft->ntyp == ',') /* usertype4 */ + { if (0) { dump_tree("4", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + cat3("\n\t\t\tsprintf(simtmp, \"%%d,\", ", fix->lft, "); strcat(simvals, simtmp);"); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { cat3("\n\t\t\tsprintf(simtmp, \"%%d\", ", v->lft->lft, "); strcat(simvals, simtmp);"); + } } + if (v->rgt) + { fprintf(fd, "\n\t\t\tstrcat(simvals, \",\");\n"); + } } + _isok--; + fprintf(fd, "\n\t\t}\n"); + fprintf(fd, "#endif\n\t\t"); + + if (u_sync) + { putname(fd, "if (q_zero(", now->lft, m, "))"); + fprintf(fd, "\n\t\t{ boq = -1;\n"); + + fprintf(fd, "#ifndef NOFAIR\n"); /* NEW 3.0.8 */ + fprintf(fd, "\t\t\tif (fairness\n"); + fprintf(fd, "\t\t\t&& !(trpt->o_pm&32)\n"); + fprintf(fd, "\t\t\t&& (now._a_t&2)\n"); + fprintf(fd, "\t\t\t&& now._cnt[now._a_t&1] == II+2)\n"); + fprintf(fd, "\t\t\t{ now._cnt[now._a_t&1] -= 1;\n"); + fprintf(fd, "#ifdef VERI\n"); + fprintf(fd, "\t\t\t if (II == 1)\n"); + fprintf(fd, "\t\t\t now._cnt[now._a_t&1] = 1;\n"); + fprintf(fd, "#endif\n"); + fprintf(fd, "#ifdef DEBUG\n"); + fprintf(fd, "\t\t\tprintf(\"%%3ld: proc %%d fairness \", depth, II);\n"); + fprintf(fd, "\t\t\tprintf(\"Rule 2: --cnt to %%d (%%d)\\n\",\n"); + fprintf(fd, "\t\t\t now._cnt[now._a_t&1], now._a_t);\n"); + fprintf(fd, "#endif\n"); + fprintf(fd, "\t\t\t trpt->o_pm |= (32|64);\n"); + fprintf(fd, "\t\t\t}\n"); + fprintf(fd, "#endif\n"); + + fprintf(fd, "\n\t\t}"); + } + break; + + case 'R': + if (!terse && !TestOnly && has_xu) + { fprintf(fd, "\n#ifndef XUSAFE\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&1) || "); + fprintf(fd, "q_R_check("); + putname(fd, "", now->lft, m, ", II)) &&\n\t\t"); + putname(fd, "(!(q_claim[", now->lft, m, "]&2) || "); + putname(fd, "q_S_check(", now->lft, m, ", II)) &&"); + fprintf(fd, "\n#endif\n\t\t"); + } + if (u_sync>0) + putname(fd, "not_RV(", now->lft, m, ") && \\\n\t\t"); + + for (v = now->rgt, i=j=0; v; v = v->rgt, i++) + if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL) + { j++; continue; + } + if (now->val == 0 || i == j) + { putname(fd, "(q_len(", now->lft, m, ") > 0"); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp != CONST + && v->lft->ntyp != EVAL) + continue; + fprintf(fd, " \\\n\t\t&& qrecv("); + putname(fd, "", now->lft, m, ", "); + fprintf(fd, "0, %d, 0) == ", i); + if (v->lft->ntyp == CONST) + { putstmnt(fd, v->lft, m); + } else /* EVAL */ + { if (v->lft->lft->ntyp == ',') /* usertype2 */ + { if (0) { dump_tree("8", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { putstmnt(fd, v->lft->lft, m); + } + } + } + fprintf(fd, ")"); + } else + { putname(fd, "Q_has(", now->lft, m, ""); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v->lft->ntyp == CONST) + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft, m); + } else if (v->lft->ntyp == EVAL) + { if (v->lft->lft->ntyp == ',') /* usertype3 */ + { if (0) { dump_tree("3", v->lft->lft); } + Lextok *fix = v->lft->lft; + do { i++; + fprintf(fd, ", 1, "); + putstmnt(fd, fix->lft, m); + fix = fix->rgt; + } while (fix && fix->ntyp == ','); + } else + { fprintf(fd, ", 1, "); + putstmnt(fd, v->lft->lft, m); + } + } else + fprintf(fd, ", 0, 0"); + } + for ( ; i < Mpars; i++) + { fprintf(fd, ", 0, 0"); + } + fprintf(fd, ")"); + } + break; + + case 'c': + preruse(fd, now->lft); /* preconditions */ + cat3("if (!(", now->lft, "))\n\t\t\t"); + Bailout(fd, ""); + break; + + case ELSE: + if (!GenCode) + { if (separate == 2) + fprintf(fd, "if (o_pm&1)\n\t\t\t"); + else + fprintf(fd, "if (trpt->o_pm&1)\n\t\t\t"); + Bailout(fd, ""); + } else + { fprintf(fd, "/* else */"); + } + break; + + case '?': + if (now->lft) + { cat3("( (", now->lft, ") ? "); + } + if (now->rgt) + { cat3("(", now->rgt->lft, ") : "); + cat3("(", now->rgt->rgt, ") )"); + } + break; + + case ASGN: + if (check_track(now) == STRUCT) { break; } + + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T3 */\n\t\t"); + _isok++; + + if (!GenCode) + { if (multi_oval) + { char tempbuf[64]; + check_needed(); + sprintf(tempbuf, "(trpt+1)->bup.ovals[%d] = ", + multi_oval-1); + multi_oval++; + cat30(tempbuf, now->lft, ";\n\t\t"); + } else + { cat3("(trpt+1)->bup.oval = ", now->lft, ";\n\t\t"); + } } + if (now->lft->sym + && now->lft->sym->type == PREDEF + && strcmp(now->lft->sym->name, "_") != 0 + && strcmp(now->lft->sym->name, "_priority") != 0) + { fatal("invalid assignment to %s", now->lft->sym->name); + } + + nocast = 1; putstmnt(fd,now->lft,m); nocast = 0; + fprintf(fd," = "); + _isok--; + if (now->lft->sym->isarray + && now->rgt->ntyp == ',') /* array initializer */ + { putstmnt(fd, now->rgt->lft, m); + non_fatal("cannot use an array list initializer here", (char *) 0); + } else + { putstmnt(fd, now->rgt, m); + } + + if (now->sym->type != CHAN + || verbose > 0) + { fprintf(fd, ";\n#ifdef VAR_RANGES"); + fprintf(fd, "\n\t\tlogval(\""); + withprocname = terse = nocast = 1; + _isok++; + putstmnt(fd,now->lft,m); + withprocname = terse = nocast = 0; + fprintf(fd, "\", "); + putstmnt(fd,now->lft,m); + _isok--; + fprintf(fd, ");\n#endif\n"); + fprintf(fd, "\t\t"); + } + break; + + case PRINT: + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T4 */\n\t\t"); #ifdef PRINTF - fprintf(fd, "printf(%s", now->sym->name); + fprintf(fd, "printf(%s", now->sym->name); #else - fprintf(fd, "Printf(%s", now->sym->name); + fprintf(fd, "Printf(%s", now->sym->name); #endif - for (v = now->lft; v; v = v->rgt) - { cat2(", ", v->lft); - } - fprintf(fd, ")"); - break; - - case PRINTM: - { char *s = 0; - if (now->lft->sym - && now->lft->sym->mtype_name) - { s = now->lft->sym->mtype_name->name; - } - - if (has_enabled || has_priority) - { fprintf(fd, "if (TstOnly) return 1; /* T5 */\n\t\t"); - } - fprintf(fd, "/* YY */ printm("); - if (now->lft - && now->lft->ismtyp) - { fprintf(fd, "%d", now->lft->val); - } else - { putstmnt(fd, now->lft, m); - } - if (s) - { fprintf(fd, ", \"%s\"", s); - } else - { fprintf(fd, ", 0"); - } - fprintf(fd, ")"); - } - break; - - case NAME: - if (!nocast && now->sym && Sym_typ(now) < SHORT) - putname(fd, "((int)", now, m, ")"); - else - putname(fd, "", now, m, ""); - break; - - case 'p': - putremote(fd, now, m); - break; - - case 'q': - if (terse) - fprintf(fd, "%s", now->sym?now->sym->name:"?"); - else - fprintf(fd, "%d", remotelab(now)); - break; - - case C_EXPR: - fprintf(fd, "("); - plunk_expr(fd, now->sym->name); + for (v = now->lft; v; v = v->rgt) + { cat2(", ", v->lft); + } + fprintf(fd, ")"); + break; + + case PRINTM: + { char *s = 0; + if (now->lft->sym + && now->lft->sym->mtype_name) + { s = now->lft->sym->mtype_name->name; + } + + if (has_enabled || has_priority) + { fprintf(fd, "if (TstOnly) return 1; /* T5 */\n\t\t"); + } + fprintf(fd, "/* YY */ printm("); + if (now->lft + && now->lft->ismtyp) + { fprintf(fd, "%d", now->lft->val); + } else + { putstmnt(fd, now->lft, m); + } + if (s) + { fprintf(fd, ", \"%s\"", s); + } else + { fprintf(fd, ", 0"); + } + fprintf(fd, ")"); + } + break; + + case NAME: + if (!nocast && now->sym && Sym_typ(now) < SHORT) + putname(fd, "((int)", now, m, ")"); + else + putname(fd, "", now, m, ""); + break; + + case 'p': + putremote(fd, now, m); + break; + + case 'q': + if (terse) + fprintf(fd, "%s", now->sym?now->sym->name:"?"); + else + fprintf(fd, "%d", remotelab(now)); + break; + + case C_EXPR: + fprintf(fd, "("); + plunk_expr(fd, now->sym->name); #if 1 - fprintf(fd, ")"); + fprintf(fd, ")"); #else - fprintf(fd, ") /* %s */ ", now->sym->name); + fprintf(fd, ") /* %s */ ", now->sym->name); #endif - break; - - case C_CODE: - if (now->sym) - fprintf(fd, "/* %s */\n\t\t", now->sym->name); - if (has_enabled || has_priority) - fprintf(fd, "if (TstOnly) return 1; /* T6 */\n\t\t"); - - if (now->sym) - plunk_inline(fd, now->sym->name, 1, GenCode); - else - fatal("internal error pangen2.c", (char *) 0); - - if (!GenCode) - { fprintf(fd, "\n"); /* state changed, capture it */ - fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n"); - fprintf(fd, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); - fprintf(fd, "#endif\n"); - } - break; - - case ASSERT: - if (has_enabled || has_priority) - fprintf(fd, "if (TstOnly) return 1; /* T7 */\n\t\t"); - - cat3("spin_assert(", now->lft, ", "); - terse = nocast = 1; - cat3("\"", now->lft, "\", II, tt, t)"); - terse = nocast = 0; - break; - - case '.': - case BREAK: - case GOTO: - if (Pid_nr == eventmapnr) - fprintf(fd, "Uerror(\"cannot get here\")"); - putskip(m); - break; - - case '@': - if (Pid_nr == eventmapnr) - { fprintf(fd, "return 0"); - break; - } - - if (has_enabled || has_priority) - { fprintf(fd, "if (TstOnly)\n\t\t\t"); - fprintf(fd, "return (II+1 == now._nr_pr);\n\t\t"); - } - fprintf(fd, "if (!delproc(1, II)) "); - Bailout(fd, ""); - break; - - default: - printf("spin: error, %s:%d, bad node type %d (.m)\n", - now->fn->name, now->ln, now->ntyp); - fflush(fd); - alldone(1); - } + break; + + case C_CODE: + if (now->sym) + fprintf(fd, "/* %s */\n\t\t", now->sym->name); + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T6 */\n\t\t"); + + if (now->sym) + plunk_inline(fd, now->sym->name, 1, GenCode); + else + fatal("internal error pangen2.c", (char *) 0); + + if (!GenCode) + { fprintf(fd, "\n"); /* state changed, capture it */ + fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n"); + fprintf(fd, "\t\tc_update((uchar *) &(now.c_state[0]));\n"); + fprintf(fd, "#endif\n"); + } + break; + + case ASSERT: + if (has_enabled || has_priority) + fprintf(fd, "if (TstOnly) return 1; /* T7 */\n\t\t"); + + cat3("spin_assert(", now->lft, ", "); + terse = nocast = 1; + cat3("\"", now->lft, "\", II, tt, t)"); + terse = nocast = 0; + break; + + case '.': + case BREAK: + case GOTO: + if (Pid_nr == eventmapnr) + fprintf(fd, "Uerror(\"cannot get here\")"); + putskip(m); + break; + + case '@': + if (Pid_nr == eventmapnr) + { fprintf(fd, "return 0"); + break; + } + + if (has_enabled || has_priority) + { fprintf(fd, "if (TstOnly)\n\t\t\t"); + fprintf(fd, "return (II+1 == now._nr_pr);\n\t\t"); + } + fprintf(fd, "if (!delproc(1, II)) "); + Bailout(fd, ""); + break; + + default: + printf("spin: error, %s:%d, bad node type %d (.m)\n", + now->fn->name, now->ln, now->ntyp); + fflush(fd); + alldone(1); + } } char * simplify_name(char *s) -{ char *t = s; +{ char *t = s; - if (!old_scope_rules) - { while (*t == '_' || isdigit((int)*t)) - { t++; - } } + if (!old_scope_rules) + { while (*t == '_' || isdigit((int)*t)) + { t++; + } } - return t; + return t; } void -putname(FILE *fd, char *pre, Lextok *n, int m, char *suff) /* varref */ -{ Symbol *s = n->sym; - char *ptr; - - lineno = n->ln; Fname = n->fn; - - if (!s) - fatal("no name - putname", (char *) 0); - - if (s->context && context && s->type) - s = findloc(s); /* it's a local var */ - - if (!s) - { fprintf(fd, "%s%s%s", pre, n->sym->name, suff); - return; - } - - if (!s->type) /* not a local name */ - s = lookup(s->name); /* must be a global */ - - if (!s->type) - { if (strcmp(pre, ".") != 0) - fatal("undeclared variable '%s'", s->name); - s->type = INT; - } - - if (s->type == PROCTYPE) - fatal("proctype-name '%s' used as array-name", s->name); - - fprintf(fd, pre, 0); - if (!terse && !s->owner && evalindex != 1) - { if (old_priority_rules - && strcmp(s->name, "_priority") == 0) - { fprintf(fd, "1"); - goto shortcut; - } else - { if (s->context - || strcmp(s->name, "_p") == 0 - || strcmp(s->name, "_pid") == 0 - || strcmp(s->name, "_priority") == 0) - { fprintf(fd, "((P%d *)_this)->", Pid_nr); - } else - { int x = strcmp(s->name, "_"); - if (!(s->hidden&1) && x != 0) - fprintf(fd, "now."); - if (x == 0 && _isok == 0) - fatal("attempt to read value of '_'", 0); - } } } - - if (terse && buzzed == 1) - { fprintf(fd, "B_state.%s", (s->context)?"local[B_pid].":""); - } - - ptr = s->name; - - if (!dont_simplify /* new 6.4.3 */ - && s->type != PREDEF) /* new 6.0.2 */ - { if (withprocname - && s->context - && strcmp(pre, ".")) - { fprintf(fd, "%s:", s->context->name); - ptr = simplify_name(ptr); - } else - { if (terse) - { ptr = simplify_name(ptr); - } } } - - if (evalindex != 1) - fprintf(fd, "%s", ptr); - - if (s->nel > 1 || s->isarray == 1) - { if (no_arrays) - { non_fatal("ref to array element invalid in this context", - (char *)0); - printf("\thint: instead of, e.g., x[rs] qu[3], use\n"); - printf("\tchan nm_3 = qu[3]; x[rs] nm_3;\n"); - printf("\tand use nm_3 in sends/recvs instead of qu[3]\n"); - } - /* an xr or xs reference to an array element - * becomes an exclusion tag on the array itself - - * which could result in invalidly labeling - * operations on other elements of this array to - * be also safe under the partial order reduction - * (see procedure has_global()) - */ - - if (evalindex == 2) - { fprintf(fd, "[%%d]"); - } else if (evalindex == 1) - { evalindex = 0; /* no good if index is indexed array */ - fprintf(fd, ", "); - putstmnt(fd, n->lft, m); - evalindex = 1; - } else - { if (terse - || (n->lft - && n->lft->ntyp == CONST - && n->lft->val < s->nel) - || (!n->lft && s->nel > 0)) - { cat3("[", n->lft, "]"); - } else - { /* attempt to catch arrays that are indexed with an array element in the same array - * this causes trouble in the verifier in the backtracking - * e.g., restoring a[?] in the assignment: a [a[1]] = x where a[1] == 1 - * but it is hard when the array is inside a structure, so the names don't match - */ +putname(FILE *fd, const char *pre, const Lextok *n, int m, const char *suff) /* varref */ +{ Symbol *s = n->sym; + char *ptr; + + lineno = n->ln; Fname = n->fn; + + if (!s) + fatal("no name - putname", (char *) 0); + + if (s->context && context && s->type) + s = findloc(s); /* it's a local var */ + + if (!s) + { fprintf(fd, "%s%s%s", pre, n->sym->name, suff); + return; + } + + if (!s->type) /* not a local name */ + s = lookup(s->name); /* must be a global */ + + if (!s->type) + { if (strcmp(pre, ".") != 0) + fatal("undeclared variable '%s'", s->name); + s->type = INT; + } + + if (s->type == PROCTYPE) + fatal("proctype-name '%s' used as array-name", s->name); + + fprintf(fd, pre, 0); + if (!terse && !s->owner && evalindex != 1) + { if (old_priority_rules + && strcmp(s->name, "_priority") == 0) + { fprintf(fd, "1"); + goto shortcut; + } else + { if (s->context + || strcmp(s->name, "_p") == 0 + || strcmp(s->name, "_pid") == 0 + || strcmp(s->name, "_priority") == 0) + { fprintf(fd, "((P%d *)_this)->", Pid_nr); + } else + { int x = strcmp(s->name, "_"); + if (!(s->hidden&1) && x != 0) + fprintf(fd, "now."); + if (x == 0 && _isok == 0) + fatal("attempt to read value of '_'", 0); + } } } + + if (terse && buzzed == 1) + { fprintf(fd, "B_state.%s", (s->context)?"local[B_pid].":""); + } + + ptr = s->name; + + if (!dont_simplify /* new 6.4.3 */ + && s->type != PREDEF) /* new 6.0.2 */ + { if (withprocname + && s->context + && strcmp(pre, ".")) + { fprintf(fd, "%s:", s->context->name); + ptr = simplify_name(ptr); + } else + { if (terse) + { ptr = simplify_name(ptr); + } } } + + if (evalindex != 1) + fprintf(fd, "%s", ptr); + + if (s->nel > 1 || s->isarray == 1) + { if (no_arrays) + { non_fatal("ref to array element invalid in this context", + (char *)0); + printf("\thint: instead of, e.g., x[rs] qu[3], use\n"); + printf("\tchan nm_3 = qu[3]; x[rs] nm_3;\n"); + printf("\tand use nm_3 in sends/recvs instead of qu[3]\n"); + } + /* an xr or xs reference to an array element + * becomes an exclusion tag on the array itself - + * which could result in invalidly labeling + * operations on other elements of this array to + * be also safe under the partial order reduction + * (see procedure has_global()) + */ + + if (evalindex == 2) + { fprintf(fd, "[%%d]"); + } else if (evalindex == 1) + { evalindex = 0; /* no good if index is indexed array */ + fprintf(fd, ", "); + putstmnt(fd, n->lft, m); + evalindex = 1; + } else + { if (terse + || (n->lft + && n->lft->ntyp == CONST + && n->lft->val < s->nel) + || (!n->lft && s->nel > 0)) + { cat3("[", n->lft, "]"); + } else + { /* attempt to catch arrays that are indexed with an array element in the same array + * this causes trouble in the verifier in the backtracking + * e.g., restoring a[?] in the assignment: a [a[1]] = x where a[1] == 1 + * but it is hard when the array is inside a structure, so the names don't match + */ #if 0 - if (n->lft->ntyp == NAME) - { printf("%4d: Basename %s index %s\n", - n->lft->ln, s->name, n->lft->sym->name); - } + if (n->lft->ntyp == NAME) + { printf("%4d: Basename %s index %s\n", + n->lft->ln, s->name, n->lft->sym->name); + } #endif - cat3("[ Index(", n->lft, ", "); - fprintf(fd, "%d) ]", s->nel); - } } - } else - { if (n->lft /* effectively a scalar, but with an index */ - && (n->lft->ntyp != CONST - || n->lft->val != 0)) - { fatal("ref to scalar '%s' using array index", (char *) ptr); - } } - - if (s->type == STRUCT && n->rgt && n->rgt->lft) - { putname(fd, ".", n->rgt->lft, m, ""); - } + cat3("[ Index(", n->lft, ", "); + fprintf(fd, "%d) ]", s->nel); + } } + } else + { if (n->lft /* effectively a scalar, but with an index */ + && (n->lft->ntyp != CONST + || n->lft->val != 0)) + { fatal("ref to scalar '%s' using array index", (char *) ptr); + } } + + if (s->type == STRUCT && n->rgt && n->rgt->lft) + { putname(fd, ".", n->rgt->lft, m, ""); + } shortcut: - fprintf(fd, suff, 0); + fprintf(fd, suff, 0); } void -putremote(FILE *fd, Lextok *n, int m) /* remote reference */ -{ int promoted = 0; - int pt; - - if (terse) - { fprintf(fd, "%s", n->lft->sym->name); /* proctype name */ - if (n->lft->lft) - { fprintf(fd, "["); - putstmnt(fd, n->lft->lft, m); /* pid */ - fprintf(fd, "]"); - } - if (ltl_mode) - { fprintf(fd, ":%s", n->sym->name); - } else - { fprintf(fd, ".%s", n->sym->name); - } - } else - { if (Sym_typ(n) < SHORT) - { promoted = 1; - fprintf(fd, "((int)"); - } - - pt = fproc(n->lft->sym->name); - fprintf(fd, "((P%d *)Pptr(", pt); - if (n->lft->lft) - { fprintf(fd, "BASE+"); - putstmnt(fd, n->lft->lft, m); - } else - fprintf(fd, "f_pid(%d)", pt); - fprintf(fd, "))->%s", n->sym->name); - } - if (n->rgt) - { fprintf(fd, "["); - putstmnt(fd, n->rgt, m); /* array var ref */ - fprintf(fd, "]"); - } - if (promoted) fprintf(fd, ")"); +putremote(FILE *fd, Lextok *n, int m) /* remote reference */ +{ int promoted = 0; + int pt; + + if (terse) + { fprintf(fd, "%s", n->lft->sym->name); /* proctype name */ + if (n->lft->lft) + { fprintf(fd, "["); + putstmnt(fd, n->lft->lft, m); /* pid */ + fprintf(fd, "]"); + } + if (ltl_mode) + { fprintf(fd, ":%s", n->sym->name); + } else + { fprintf(fd, ".%s", n->sym->name); + } + } else + { if (Sym_typ(n) < SHORT) + { promoted = 1; + fprintf(fd, "((int)"); + } + + pt = fproc(n->lft->sym->name); + fprintf(fd, "((P%d *)Pptr(", pt); + if (n->lft->lft) + { fprintf(fd, "BASE+"); + putstmnt(fd, n->lft->lft, m); + } else + fprintf(fd, "f_pid(%d)", pt); + fprintf(fd, "))->%s", n->sym->name); + } + if (n->rgt) + { fprintf(fd, "["); + putstmnt(fd, n->rgt, m); /* array var ref */ + fprintf(fd, "]"); + } + if (promoted) fprintf(fd, ")"); } static int getweight(Lextok *n) -{ /* this piece of code is a remnant of early versions - * of the verifier -- in the current version of Spin - * only non-zero values matter - so this could probably - * simply return 1 in all cases. - */ - switch (n->ntyp) { - case 'r': return 4; - case 's': return 2; - case TIMEOUT: return 1; - case 'c': if (has_typ(n->lft, TIMEOUT)) return 1; - } - return 3; +{ /* this piece of code is a remnant of early versions + * of the verifier -- in the current version of Spin + * only non-zero values matter - so this could probably + * simply return 1 in all cases. + */ + switch (n->ntyp) { + case 'r': return 4; + case 's': return 2; + case TIMEOUT: return 1; + case 'c': if (has_typ(n->lft, TIMEOUT)) return 1; + } + return 3; } int has_typ(Lextok *n, int m) { - if (!n) return 0; - if (n->ntyp == m) return 1; - return (has_typ(n->lft, m) || has_typ(n->rgt, m)); + if (!n) return 0; + if (n->ntyp == m) return 1; + return (has_typ(n->lft, m) || has_typ(n->rgt, m)); } static int runcount, opcount; @@ -3526,36 +3531,36 @@ static int runcount, opcount; static void do_count(Lextok *n, int checkop) { - if (!n) return; - - switch (n->ntyp) { - case RUN: - runcount++; - break; - default: - if (checkop) opcount++; - break; - } - do_count(n->lft, checkop && (n->ntyp != RUN)); - do_count(n->rgt, checkop); + if (!n) return; + + switch (n->ntyp) { + case RUN: + runcount++; + break; + default: + if (checkop) opcount++; + break; + } + do_count(n->lft, checkop && (n->ntyp != RUN)); + do_count(n->rgt, checkop); } void count_runs(Lextok *n) { - runcount = opcount = 0; - do_count(n, 1); - if (runcount > 1) - fatal("more than one run operator in expression", ""); - if (runcount == 1 && opcount > 1) - fatal("use of run operator in compound expression", ""); + runcount = opcount = 0; + do_count(n, 1); + if (runcount > 1) + fatal("more than one run operator in expression", ""); + if (runcount == 1 && opcount > 1) + fatal("use of run operator in compound expression", ""); } void any_runs(Lextok *n) { - runcount = opcount = 0; - do_count(n, 0); - if (runcount >= 1) - fatal("run operator used in invalid context", ""); + runcount = opcount = 0; + do_count(n, 0); + if (runcount >= 1) + fatal("run operator used in invalid context", ""); } diff --git a/Src/pangen3.c b/Src/pangen3.c index 9e2a33e..57b5f13 100644 --- a/Src/pangen3.c +++ b/Src/pangen3.c @@ -10,536 +10,536 @@ #include "y.tab.h" #include -extern FILE *fd_th, *fd_tc; -extern int eventmapnr, old_priority_rules, in_settr; +extern FILE *fd_th, *fd_tc; +extern int eventmapnr, old_priority_rules, in_settr; typedef struct SRC { - int ln, st; /* linenr, statenr */ - Symbol *fn; /* filename */ - struct SRC *nxt; + int ln, st; /* linenr, statenr */ + Symbol *fn; /* filename */ + struct SRC *nxt; } SRC; -static int col; -static Symbol *lastfnm; -static Symbol lastdef; -static int lastfrom; -static SRC *frst = (SRC *) 0; -static SRC *skip = (SRC *) 0; +static int col; +static Symbol *lastfnm; +static Symbol lastdef; +static int lastfrom; +static SRC *frst = (SRC *) 0; +static SRC *skip = (SRC *) 0; -extern int ltl_mode; +extern int ltl_mode; -extern void sr_mesg(FILE *, int, int, const char *); -extern Lextok **find_mtype_list(const char *); +extern void sr_mesg(FILE *, int, int, const char *); +extern Lextok **find_mtype_list(const char *); static void putnr(int n) { - if (col++ == 8) - { fprintf(fd_tc, "\n\t"); /* was th */ - col = 1; - } - fprintf(fd_tc, "%3d, ", n); /* was th */ + if (col++ == 8) + { fprintf(fd_tc, "\n\t"); /* was th */ + col = 1; + } + fprintf(fd_tc, "%3d, ", n); /* was th */ } static void putfnm(int j, Symbol *s) { - if (lastfnm && lastfnm == s && j != -1) - return; - - if (lastfnm) - fprintf(fd_tc, "{ \"%s\", %d, %d },\n\t", /* was th */ - lastfnm->name, - lastfrom, - j-1); - lastfnm = s; - lastfrom = j; + if (lastfnm && lastfnm == s && j != -1) + return; + + if (lastfnm) + fprintf(fd_tc, "{ \"%s\", %d, %d },\n\t", /* was th */ + lastfnm->name, + lastfrom, + j-1); + lastfnm = s; + lastfrom = j; } static void putfnm_flush(int j) { - if (lastfnm) - fprintf(fd_tc, "{ \"%s\", %d, %d }\n", /* was th */ - lastfnm->name, - lastfrom, j); + if (lastfnm) + fprintf(fd_tc, "{ \"%s\", %d, %d }\n", /* was th */ + lastfnm->name, + lastfrom, j); } static SRC * newsrc(int m, SRC *n) -{ SRC *tmp; - tmp = (SRC *) emalloc(sizeof(SRC)); - tmp->st = m; - tmp->nxt = n; - return tmp; +{ SRC *tmp; + tmp = (SRC *) emalloc(sizeof(SRC)); + tmp->st = m; + tmp->nxt = n; + return tmp; } void -putskip(int m) /* states that need not be reached */ -{ SRC *tmp, *lst = (SRC *)0; - /* 6.4.0: now an ordered list */ - for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) - { if (tmp->st == m) - { return; - } - if (tmp->st > m) /* insert before */ - { if (tmp == skip) - { tmp = newsrc(m, skip); - skip = tmp; - } else - { assert(lst); - tmp = newsrc(m, lst->nxt); - lst->nxt = tmp; - } - return; - } } - /* insert at the end */ - if (lst) - { lst->nxt = newsrc(m, 0); - } else /* empty list */ - { skip = newsrc(m, 0); - } +putskip(int m) /* states that need not be reached */ +{ SRC *tmp, *lst = (SRC *)0; + /* 6.4.0: now an ordered list */ + for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == m) + { return; + } + if (tmp->st > m) /* insert before */ + { if (tmp == skip) + { tmp = newsrc(m, skip); + skip = tmp; + } else + { assert(lst); + tmp = newsrc(m, lst->nxt); + lst->nxt = tmp; + } + return; + } } + /* insert at the end */ + if (lst) + { lst->nxt = newsrc(m, 0); + } else /* empty list */ + { skip = newsrc(m, 0); + } } void -unskip(int m) /* a state that needs to be reached after all */ -{ SRC *tmp, *lst = (SRC *)0; - - for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) - { if (tmp->st == m) - { if (tmp == skip) - skip = skip->nxt; - else if (lst) /* always true, but helps coverity */ - lst->nxt = tmp->nxt; - break; - } - if (tmp->st > m) - { break; /* m is not in list */ - } } +unskip(int m) /* a state that needs to be reached after all */ +{ SRC *tmp, *lst = (SRC *)0; + + for (tmp = skip; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == m) + { if (tmp == skip) + skip = skip->nxt; + else if (lst) /* always true, but helps coverity */ + lst->nxt = tmp->nxt; + break; + } + if (tmp->st > m) + { break; /* m is not in list */ + } } } void -putsrc(Element *e) /* match states to source lines */ -{ SRC *tmp, *lst = (SRC *)0; - int n, m; - - if (!e || !e->n) return; - - n = e->n->ln; - m = e->seqno; - /* 6.4.0: now an ordered list */ - for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) - { if (tmp->st == m) - { if (tmp->ln != n || tmp->fn != e->n->fn) - printf("putsrc mismatch seqno %d, line %d - %d, file %s\n", m, n, - tmp->ln, tmp->fn->name); - return; - } - if (tmp->st > m) /* insert before */ - { if (tmp == frst) - { tmp = newsrc(m, frst); - frst = tmp; - } else - { assert(lst); - tmp = newsrc(m, lst->nxt); - lst->nxt = tmp; - } - tmp->ln = n; - tmp->fn = e->n->fn; - return; - } } - /* insert at the end */ - tmp = newsrc(m, lst?lst->nxt:0); - tmp->ln = n; - tmp->fn = e->n->fn; - if (lst) - { lst->nxt = tmp; - } else - { frst = tmp; - } +putsrc(Element *e) /* match states to source lines */ +{ SRC *tmp, *lst = (SRC *)0; + int n, m; + + if (!e || !e->n) return; + + n = e->n->ln; + m = e->seqno; + /* 6.4.0: now an ordered list */ + for (tmp = frst; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == m) + { if (tmp->ln != n || tmp->fn != e->n->fn) + printf("putsrc mismatch seqno %d, line %d - %d, file %s\n", m, n, + tmp->ln, tmp->fn->name); + return; + } + if (tmp->st > m) /* insert before */ + { if (tmp == frst) + { tmp = newsrc(m, frst); + frst = tmp; + } else + { assert(lst); + tmp = newsrc(m, lst->nxt); + lst->nxt = tmp; + } + tmp->ln = n; + tmp->fn = e->n->fn; + return; + } } + /* insert at the end */ + tmp = newsrc(m, lst?lst->nxt:0); + tmp->ln = n; + tmp->fn = e->n->fn; + if (lst) + { lst->nxt = tmp; + } else + { frst = tmp; + } } static void dumpskip(int n, int m) -{ SRC *tmp, *lst; - FILE *tz = fd_tc; /* was fd_th */ - int j; - - fprintf(tz, "uchar reached%d [] = {\n\t", m); - tmp = skip; - lst = (SRC *) 0; - for (j = 0, col = 0; j <= n; j++) - { /* find j in the sorted list */ - for ( ; tmp; lst = tmp, tmp = tmp->nxt) - { if (tmp->st == j) - { putnr(1); - if (lst) - lst->nxt = tmp->nxt; - else - skip = tmp->nxt; - break; - } - if (tmp->st > j) - { putnr(0); - break; /* j is not in the list */ - } } - - if (!tmp) - { putnr(0); - } } - fprintf(tz, "};\n"); - fprintf(tz, "uchar *loopstate%d;\n", m); - - if (m == eventmapnr) - fprintf(fd_th, "#define reached_event reached%d\n", m); - - skip = (SRC *) 0; +{ SRC *tmp, *lst; + FILE *tz = fd_tc; /* was fd_th */ + int j; + + fprintf(tz, "uchar reached%d [] = {\n\t", m); + tmp = skip; + lst = (SRC *) 0; + for (j = 0, col = 0; j <= n; j++) + { /* find j in the sorted list */ + for ( ; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == j) + { putnr(1); + if (lst) + lst->nxt = tmp->nxt; + else + skip = tmp->nxt; + break; + } + if (tmp->st > j) + { putnr(0); + break; /* j is not in the list */ + } } + + if (!tmp) + { putnr(0); + } } + fprintf(tz, "};\n"); + fprintf(tz, "uchar *loopstate%d;\n", m); + + if (m == eventmapnr) + fprintf(fd_th, "#define reached_event reached%d\n", m); + + skip = (SRC *) 0; } void dumpsrc(int n, int m) -{ SRC *tmp, *lst; - int j; - static int did_claim = 0; - FILE *tz = fd_tc; /* was fd_th */ - - fprintf(tz, "\nshort src_ln%d [] = {\n\t", m); - tmp = frst; - for (j = 0, col = 0; j <= n; j++) - { for ( ; tmp; tmp = tmp->nxt) - { if (tmp->st == j) - { putnr(tmp->ln); - break; - } - if (tmp->st > j) - { putnr(0); - break; - } } - if (!tmp) - { putnr(0); - } } - fprintf(tz, "};\n"); - - lastfnm = (Symbol *) 0; - lastdef.name = "-"; - fprintf(tz, "S_F_MAP src_file%d [] = {\n\t", m); - tmp = frst; - lst = (SRC *) 0; - for (j = 0, col = 0; j <= n; j++) - { for ( ; tmp; lst = tmp, tmp = tmp->nxt) - { if (tmp->st == j) - { putfnm(j, tmp->fn); - if (lst) - lst->nxt = tmp->nxt; - else - frst = tmp->nxt; - break; - } - if (tmp->st > j) - { putfnm(j, &lastdef); - break; - } } - if (!tmp) - { putfnm(j, &lastdef); - } } - putfnm_flush(j); - fprintf(tz, "};\n"); - - if (pid_is_claim(m) && !did_claim) - { fprintf(tz, "short *src_claim;\n"); - did_claim++; - } - if (m == eventmapnr) - fprintf(fd_th, "#define src_event src_ln%d\n", m); - - frst = (SRC *) 0; - dumpskip(n, m); +{ SRC *tmp, *lst; + int j; + static int did_claim = 0; + FILE *tz = fd_tc; /* was fd_th */ + + fprintf(tz, "\nshort src_ln%d [] = {\n\t", m); + tmp = frst; + for (j = 0, col = 0; j <= n; j++) + { for ( ; tmp; tmp = tmp->nxt) + { if (tmp->st == j) + { putnr(tmp->ln); + break; + } + if (tmp->st > j) + { putnr(0); + break; + } } + if (!tmp) + { putnr(0); + } } + fprintf(tz, "};\n"); + + lastfnm = (Symbol *) 0; + lastdef.name = strdup("-"); + fprintf(tz, "S_F_MAP src_file%d [] = {\n\t", m); + tmp = frst; + lst = (SRC *) 0; + for (j = 0, col = 0; j <= n; j++) + { for ( ; tmp; lst = tmp, tmp = tmp->nxt) + { if (tmp->st == j) + { putfnm(j, tmp->fn); + if (lst) + lst->nxt = tmp->nxt; + else + frst = tmp->nxt; + break; + } + if (tmp->st > j) + { putfnm(j, &lastdef); + break; + } } + if (!tmp) + { putfnm(j, &lastdef); + } } + putfnm_flush(j); + fprintf(tz, "};\n"); + + if (pid_is_claim(m) && !did_claim) + { fprintf(tz, "short *src_claim;\n"); + did_claim++; + } + if (m == eventmapnr) + fprintf(fd_th, "#define src_event src_ln%d\n", m); + + frst = (SRC *) 0; + dumpskip(n, m); } -#define Cat0(x) comwork(fd,now->lft,m); fprintf(fd, x); \ - comwork(fd,now->rgt,m) -#define Cat1(x) fprintf(fd,"("); Cat0(x); fprintf(fd,")") -#define Cat2(x,y) fprintf(fd,x); comwork(fd,y,m) -#define Cat3(x,y,z) fprintf(fd,x); comwork(fd,y,m); fprintf(fd,z) +#define Cat0(x) comwork(fd,now->lft,m); fprintf(fd, x); \ + comwork(fd,now->rgt,m) +#define Cat1(x) fprintf(fd,"("); Cat0(x); fprintf(fd,")") +#define Cat2(x,y) fprintf(fd,x); comwork(fd,y,m) +#define Cat3(x,y,z) fprintf(fd,x); comwork(fd,y,m); fprintf(fd,z) static int symbolic(FILE *fd, Lextok *tv) -{ Lextok *n, *Mtype; - int cnt = 1; - - if (tv->ismtyp) - { char *s = "_unnamed_"; - if (tv->sym && tv->sym->mtype_name) - { s = tv->sym->mtype_name->name; - } - Mtype = *find_mtype_list(s); - for (n = Mtype; n; n = n->rgt, cnt++) - { if (cnt == tv->val) - { fprintf(fd, "%s", n->lft->sym->name); - return 1; - } } } - - return 0; +{ Lextok *n, *Mtype; + int cnt = 1; + + if (tv->ismtyp) + { const char *s = "_unnamed_"; + if (tv->sym && tv->sym->mtype_name) + { s = tv->sym->mtype_name->name; + } + Mtype = *find_mtype_list(s); + for (n = Mtype; n; n = n->rgt, cnt++) + { if (cnt == tv->val) + { fprintf(fd, "%s", n->lft->sym->name); + return 1; + } } } + + return 0; } static void comwork(FILE *fd, Lextok *now, int m) -{ Lextok *v; - char *s = 0; - int i, j; - - if (!now) { fprintf(fd, "0"); return; } - switch (now->ntyp) { - case CONST: if (now->ismtyp - && now->sym - && now->sym->mtype_name) - { s = now->sym->mtype_name->name; - } - sr_mesg(fd, now->val, now->ismtyp, s); - break; - - case '!': Cat3("!(", now->lft, ")"); break; - case UMIN: Cat3("-(", now->lft, ")"); break; - case '~': Cat3("~(", now->lft, ")"); break; - - case '/': Cat1("/"); break; - case '*': Cat1("*"); break; - case '-': Cat1("-"); break; - case '+': Cat1("+"); break; - case '%': Cat1("%%"); break; - case '&': Cat1("&"); break; - case '^': Cat1("^"); break; - case '|': Cat1("|"); break; - case LE: Cat1("<="); break; - case GE: Cat1(">="); break; - case GT: Cat1(">"); break; - case LT: Cat1("<"); break; - case NE: Cat1("!="); break; - case EQ: - if (ltl_mode - && now->lft->ntyp == 'p' - && now->rgt->ntyp == 'q') /* remote ref */ - { Lextok *p = now->lft->lft; - - fprintf(fd, "("); - fprintf(fd, "%s", p->sym->name); - if (p->lft) - { fprintf(fd, "["); - putstmnt(fd, p->lft, 0); /* pid */ - fprintf(fd, "]"); - } - fprintf(fd, "@"); - fprintf(fd, "%s", now->rgt->sym->name); - fprintf(fd, ")"); - break; - } - Cat1("=="); - break; - - case OR: Cat1("||"); break; - case AND: Cat1("&&"); break; - case LSHIFT: Cat1("<<"); break; - case RSHIFT: Cat1(">>"); break; - - case RUN: fprintf(fd, "run %s(", now->sym->name); - for (v = now->lft; v; v = v->rgt) - if (v == now->lft) - { comwork(fd, v->lft, m); - } else - { Cat2(",", v->lft); - } - fprintf(fd, ")"); - break; - - case LEN: putname(fd, "len(", now->lft, m, ")"); - break; - case FULL: putname(fd, "full(", now->lft, m, ")"); - break; - case EMPTY: putname(fd, "empty(", now->lft, m, ")"); - break; - case NFULL: putname(fd, "nfull(", now->lft, m, ")"); - break; - case NEMPTY: putname(fd, "nempty(", now->lft, m, ")"); - break; - - case 's': putname(fd, "", now->lft, m, now->val?"!!":"!"); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v != now->rgt) fprintf(fd,","); - if (!symbolic(fd, v->lft)) - comwork(fd,v->lft,m); - } - break; - case 'r': putname(fd, "", now->lft, m, "?"); - switch (now->val) { - case 0: break; - case 1: fprintf(fd, "?"); break; - case 2: fprintf(fd, "<"); break; - case 3: fprintf(fd, "?<"); break; - } - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v != now->rgt) fprintf(fd,","); - if (!symbolic(fd, v->lft)) - comwork(fd,v->lft,m); - } - if (now->val >= 2) - fprintf(fd, ">"); - break; - case 'R': putname(fd, "", now->lft, m, now->val?"??[":"?["); - for (v = now->rgt, i=0; v; v = v->rgt, i++) - { if (v != now->rgt) fprintf(fd,","); - if (!symbolic(fd, v->lft)) - comwork(fd,v->lft,m); - } - fprintf(fd, "]"); - break; - - case ENABLED: Cat3("enabled(", now->lft, ")"); - break; - - case GET_P: if (old_priority_rules) - { fprintf(fd, "1"); - } else - { Cat3("get_priority(", now->lft, ")"); - } - break; - - case SET_P: if (!old_priority_rules) - { fprintf(fd, "set_priority("); - comwork(fd, now->lft->lft, m); - fprintf(fd, ", "); - comwork(fd, now->lft->rgt, m); - fprintf(fd, ")"); - } - break; - - case EVAL: if (now->lft->ntyp == ',') - { Cat3("eval(", now->lft->lft, ")"); - } else - { Cat3("eval(", now->lft, ")"); - } - break; - - case NONPROGRESS: - fprintf(fd, "np_"); - break; - - case PC_VAL: Cat3("pc_value(", now->lft, ")"); - break; - - case 'c': Cat3("(", now->lft, ")"); - break; - - case '?': if (now->lft) - { Cat3("( (", now->lft, ") -> "); - } - if (now->rgt) - { Cat3("(", now->rgt->lft, ") : "); - Cat3("(", now->rgt->rgt, ") )"); - } - break; - - case ASGN: - if (check_track(now) == STRUCT) { break; } - comwork(fd,now->lft,m); - fprintf(fd," = "); - comwork(fd,now->rgt,m); - break; - - case PRINT: { char c, buf[1024]; - strncpy(buf, now->sym->name, 510); - for (i = j = 0; i < 510; i++, j++) - { c = now->sym->name[i]; - buf[j] = c; - if (c == '\\') buf[++j] = c; - if (c == '\"') buf[j] = '\''; - if (c == '\0') break; - } - if (now->ntyp == PRINT) - fprintf(fd, "printf"); - else - fprintf(fd, "annotate"); - fprintf(fd, "(%s", buf); - } - for (v = now->lft; v; v = v->rgt) - { Cat2(",", v->lft); - } - fprintf(fd, ")"); - break; - case PRINTM: fprintf(fd, "printm("); - { char *s = 0; - if (now->lft->sym - && now->lft->sym->mtype_name) - { s = now->lft->sym->mtype_name->name; - } - - if (now->lft && now->lft->ismtyp) - { fprintf(fd, "%d", now->lft->val); - } else - { comwork(fd, now->lft, m); - } - - if (s) - { if (in_settr) - { fprintf(fd, ", '%s')", s); - } else - { fprintf(fd, ", \"%s\")", s); - } - } else - { fprintf(fd, ", 0)"); - } - } - break; - case NAME: - putname(fd, "", now, m, ""); - break; - - case 'p': - if (ltl_mode) - { fprintf(fd, "%s", now->lft->sym->name); /* proctype */ - if (now->lft->lft) - { fprintf(fd, "["); - putstmnt(fd, now->lft->lft, 0); /* pid */ - fprintf(fd, "]"); - } - fprintf(fd, ":"); /* remote varref */ - fprintf(fd, "%s", now->sym->name); /* varname */ - break; - } - putremote(fd, now, m); - break; - case 'q': fprintf(fd, "%s", now->sym->name); - break; - case C_EXPR: - case C_CODE: fprintf(fd, "{%s}", now->sym->name); - break; - case ASSERT: Cat3("assert(", now->lft, ")"); - break; - case '.': fprintf(fd, ".(goto)"); break; - case GOTO: fprintf(fd, "goto %s", now->sym->name); break; - case BREAK: fprintf(fd, "break"); break; - case ELSE: fprintf(fd, "else"); break; - case '@': fprintf(fd, "-end-"); break; - - case D_STEP: fprintf(fd, "D_STEP%d", now->ln); break; - case ATOMIC: fprintf(fd, "ATOMIC"); break; - case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; - case IF: fprintf(fd, "IF"); break; - case DO: fprintf(fd, "DO"); break; - case UNLESS: fprintf(fd, "unless"); break; - case TIMEOUT: fprintf(fd, "timeout"); break; - default: if (isprint(now->ntyp)) - fprintf(fd, "'%c'", now->ntyp); - else - fprintf(fd, "%d", now->ntyp); - break; - } +{ Lextok *v; + char *s = 0; + int i, j; + + if (!now) { fprintf(fd, "0"); return; } + switch (now->ntyp) { + case CONST: if (now->ismtyp + && now->sym + && now->sym->mtype_name) + { s = now->sym->mtype_name->name; + } + sr_mesg(fd, now->val, now->ismtyp, s); + break; + + case '!': Cat3("!(", now->lft, ")"); break; + case UMIN: Cat3("-(", now->lft, ")"); break; + case '~': Cat3("~(", now->lft, ")"); break; + + case '/': Cat1("/"); break; + case '*': Cat1("*"); break; + case '-': Cat1("-"); break; + case '+': Cat1("+"); break; + case '%': Cat1("%%"); break; + case '&': Cat1("&"); break; + case '^': Cat1("^"); break; + case '|': Cat1("|"); break; + case LE: Cat1("<="); break; + case GE: Cat1(">="); break; + case GT: Cat1(">"); break; + case LT: Cat1("<"); break; + case NE: Cat1("!="); break; + case EQ: + if (ltl_mode + && now->lft->ntyp == 'p' + && now->rgt->ntyp == 'q') /* remote ref */ + { Lextok *p = now->lft->lft; + + fprintf(fd, "("); + fprintf(fd, "%s", p->sym->name); + if (p->lft) + { fprintf(fd, "["); + putstmnt(fd, p->lft, 0); /* pid */ + fprintf(fd, "]"); + } + fprintf(fd, "@"); + fprintf(fd, "%s", now->rgt->sym->name); + fprintf(fd, ")"); + break; + } + Cat1("=="); + break; + + case OR: Cat1("||"); break; + case AND: Cat1("&&"); break; + case LSHIFT: Cat1("<<"); break; + case RSHIFT: Cat1(">>"); break; + + case RUN: fprintf(fd, "run %s(", now->sym->name); + for (v = now->lft; v; v = v->rgt) + if (v == now->lft) + { comwork(fd, v->lft, m); + } else + { Cat2(",", v->lft); + } + fprintf(fd, ")"); + break; + + case LEN: putname(fd, "len(", now->lft, m, ")"); + break; + case FULL: putname(fd, "full(", now->lft, m, ")"); + break; + case EMPTY: putname(fd, "empty(", now->lft, m, ")"); + break; + case NFULL: putname(fd, "nfull(", now->lft, m, ")"); + break; + case NEMPTY: putname(fd, "nempty(", now->lft, m, ")"); + break; + + case 's': putname(fd, "", now->lft, m, now->val?"!!":"!"); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v != now->rgt) fprintf(fd,","); + if (!symbolic(fd, v->lft)) + comwork(fd,v->lft,m); + } + break; + case 'r': putname(fd, "", now->lft, m, "?"); + switch (now->val) { + case 0: break; + case 1: fprintf(fd, "?"); break; + case 2: fprintf(fd, "<"); break; + case 3: fprintf(fd, "?<"); break; + } + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v != now->rgt) fprintf(fd,","); + if (!symbolic(fd, v->lft)) + comwork(fd,v->lft,m); + } + if (now->val >= 2) + fprintf(fd, ">"); + break; + case 'R': putname(fd, "", now->lft, m, now->val?"??[":"?["); + for (v = now->rgt, i=0; v; v = v->rgt, i++) + { if (v != now->rgt) fprintf(fd,","); + if (!symbolic(fd, v->lft)) + comwork(fd,v->lft,m); + } + fprintf(fd, "]"); + break; + + case ENABLED: Cat3("enabled(", now->lft, ")"); + break; + + case GET_P: if (old_priority_rules) + { fprintf(fd, "1"); + } else + { Cat3("get_priority(", now->lft, ")"); + } + break; + + case SET_P: if (!old_priority_rules) + { fprintf(fd, "set_priority("); + comwork(fd, now->lft->lft, m); + fprintf(fd, ", "); + comwork(fd, now->lft->rgt, m); + fprintf(fd, ")"); + } + break; + + case EVAL: if (now->lft->ntyp == ',') + { Cat3("eval(", now->lft->lft, ")"); + } else + { Cat3("eval(", now->lft, ")"); + } + break; + + case NONPROGRESS: + fprintf(fd, "np_"); + break; + + case PC_VAL: Cat3("pc_value(", now->lft, ")"); + break; + + case 'c': Cat3("(", now->lft, ")"); + break; + + case '?': if (now->lft) + { Cat3("( (", now->lft, ") -> "); + } + if (now->rgt) + { Cat3("(", now->rgt->lft, ") : "); + Cat3("(", now->rgt->rgt, ") )"); + } + break; + + case ASGN: + if (check_track(now) == STRUCT) { break; } + comwork(fd,now->lft,m); + fprintf(fd," = "); + comwork(fd,now->rgt,m); + break; + + case PRINT: { char c, buf[1024]; + strncpy(buf, now->sym->name, 510); + for (i = j = 0; i < 510; i++, j++) + { c = now->sym->name[i]; + buf[j] = c; + if (c == '\\') buf[++j] = c; + if (c == '\"') buf[j] = '\''; + if (c == '\0') break; + } + if (now->ntyp == PRINT) + fprintf(fd, "printf"); + else + fprintf(fd, "annotate"); + fprintf(fd, "(%s", buf); + } + for (v = now->lft; v; v = v->rgt) + { Cat2(",", v->lft); + } + fprintf(fd, ")"); + break; + case PRINTM: fprintf(fd, "printm("); + { char *s1 = 0; + if (now->lft->sym + && now->lft->sym->mtype_name) + { s1 = now->lft->sym->mtype_name->name; + } + + if (now->lft && now->lft->ismtyp) + { fprintf(fd, "%d", now->lft->val); + } else + { comwork(fd, now->lft, m); + } + + if (s1) + { if (in_settr) + { fprintf(fd, ", '%s')", s1); + } else + { fprintf(fd, ", \"%s\")", s1); + } + } else + { fprintf(fd, ", 0)"); + } + } + break; + case NAME: + putname(fd, "", now, m, ""); + break; + + case 'p': + if (ltl_mode) + { fprintf(fd, "%s", now->lft->sym->name); /* proctype */ + if (now->lft->lft) + { fprintf(fd, "["); + putstmnt(fd, now->lft->lft, 0); /* pid */ + fprintf(fd, "]"); + } + fprintf(fd, ":"); /* remote varref */ + fprintf(fd, "%s", now->sym->name); /* varname */ + break; + } + putremote(fd, now, m); + break; + case 'q': fprintf(fd, "%s", now->sym->name); + break; + case C_EXPR: + case C_CODE: fprintf(fd, "{%s}", now->sym->name); + break; + case ASSERT: Cat3("assert(", now->lft, ")"); + break; + case '.': fprintf(fd, ".(goto)"); break; + case GOTO: fprintf(fd, "goto %s", now->sym->name); break; + case BREAK: fprintf(fd, "break"); break; + case ELSE: fprintf(fd, "else"); break; + case '@': fprintf(fd, "-end-"); break; + + case D_STEP: fprintf(fd, "D_STEP%d", now->ln); break; + case ATOMIC: fprintf(fd, "ATOMIC"); break; + case NON_ATOMIC: fprintf(fd, "sub-sequence"); break; + case IF: fprintf(fd, "IF"); break; + case DO: fprintf(fd, "DO"); break; + case UNLESS: fprintf(fd, "unless"); break; + case TIMEOUT: fprintf(fd, "timeout"); break; + default: if (isprint(now->ntyp)) + fprintf(fd, "'%c'", now->ntyp); + else + fprintf(fd, "%d", now->ntyp); + break; + } } void comment(FILE *fd, Lextok *now, int m) -{ extern short terse, nocast; +{ extern short terse, nocast; - terse=nocast=1; - comwork(fd, now, m); - terse=nocast=0; + terse=nocast=1; + comwork(fd, now, m); + terse=nocast=0; } diff --git a/Src/pangen5.c b/Src/pangen5.c index 4fd49a1..1043124 100644 --- a/Src/pangen5.c +++ b/Src/pangen5.c @@ -777,7 +777,7 @@ spit_recvs(FILE *f1, FILE *f2) /* called from pangen2.c */ markit: fprintf(f2, "\tIs_Recv[%d] = 1;\n", e->Seqno); break; case D_STEP: - s = e->n->sl->this; + s = e->n->sl->thisS; switch (s->frst->n->ntyp) { case DO: fatal("unexpected: do at start of d_step", (char *) 0); @@ -822,10 +822,10 @@ ana_seq(Sequence *s) From = e->seqno; if (e->n->ntyp == UNLESS) - ana_seq(e->sub->this); + ana_seq(e->sub->thisS); else if (e->sub) { for (h = e->sub; h; h = h->nxt) - { g = huntstart(h->this->frst); + { g = huntstart(h->thisS->frst); To = g->seqno; if (g->n->ntyp != 'c' @@ -836,12 +836,12 @@ ana_seq(Sequence *s) /* else it's a dead link */ } for (h = e->sub; h; h = h->nxt) - ana_seq(h->this); + ana_seq(h->thisS); } else if (e->n->ntyp == ATOMIC || e->n->ntyp == D_STEP || e->n->ntyp == NON_ATOMIC) { - t = e->n->sl->this; + t = e->n->sl->thisS; g = huntstart(t->frst); t->last->nxt = e->nxt; To = g->seqno; @@ -871,10 +871,10 @@ ana_seq(Sequence *s) && e->n->ntyp != GOTO && e->n->ntyp != '.') for (h = e->esc; h; h = h->nxt) - { g = huntstart(h->this->frst); + { g = huntstart(h->thisS->frst); To = g->seqno; FSM_EDGE(From, To, ZE); - ana_seq(h->this); + ana_seq(h->thisS); } } diff --git a/Src/pangen6.c b/Src/pangen6.c index df8e08d..eec9c60 100644 --- a/Src/pangen6.c +++ b/Src/pangen6.c @@ -9,2347 +9,2347 @@ #include "spin.h" #include "y.tab.h" -extern Ordered *all_names; +extern Ordered *all_names; extern FSM_use *use_free; extern FSM_state **fsm_tbl; extern FSM_state *fsmx; -extern int verbose, o_max; +extern int verbose, o_max; static FSM_trans *cur_t; static FSM_trans *expl_par; static FSM_trans *expl_var; -static FSM_trans *explicit; +static FSM_trans *explicit_ptr; extern void rel_use(FSM_use *); -#define ulong unsigned long +#define ulong unsigned long typedef struct Pair { - FSM_state *h; - int b; - struct Pair *nxt; + FSM_state *h; + int b; + struct Pair *nxt; } Pair; typedef struct AST { - ProcList *p; /* proctype decl */ - int i_st; /* start state */ - int nstates, nwords; - int relevant; - Pair *pairs; /* entry and exit nodes of proper subgraphs */ - FSM_state *fsm; /* proctype body */ - struct AST *nxt; /* linked list */ + ProcList *p; /* proctype decl */ + int i_st; /* start state */ + int nstates, nwords; + int relevant; + Pair *pairs; /* entry and exit nodes of proper subgraphs */ + FSM_state *fsm; /* proctype body */ + struct AST *nxt; /* linked list */ } AST; -typedef struct RPN { /* relevant proctype names */ - Symbol *rn; - struct RPN *nxt; +typedef struct RPN { /* relevant proctype names */ + Symbol *rn; + struct RPN *nxt; } RPN; -typedef struct ALIAS { /* channel aliasing info */ - Lextok *cnm; /* this chan */ - int origin; /* debugging - origin of the alias */ - struct ALIAS *alias; /* can be an alias for these other chans */ - struct ALIAS *nxt; /* linked list */ +typedef struct ALIAS { /* channel aliasing info */ + Lextok *cnm; /* this chan */ + int origin; /* debugging - origin of the alias */ + struct ALIAS *alias; /* can be an alias for these other chans */ + struct ALIAS *nxt; /* linked list */ } ALIAS; typedef struct ChanList { - Lextok *s; /* containing stmnt */ - Lextok *n; /* point of reference - could be struct */ - struct ChanList *nxt; /* linked list */ + Lextok *s; /* containing stmnt */ + Lextok *n; /* point of reference - could be struct */ + struct ChanList *nxt; /* linked list */ } ChanList; /* a chan alias can be created in one of three ways: - assignement to chan name - a = b -- a is now an alias for b - passing chan name as parameter in run - run x(b) -- proctype x(chan a) - passing chan name through channel - x!b -- x?a + assignement to chan name + a = b -- a is now an alias for b + passing chan name as parameter in run + run x(b) -- proctype x(chan a) + passing chan name through channel + x!b -- x?a */ -#define USE 1 -#define DEF 2 -#define DEREF_DEF 4 -#define DEREF_USE 8 - -static AST *ast; -static ALIAS *chalcur; -static ALIAS *chalias; -static ChanList *chanlist; -static Slicer *slicer; -static Slicer *rel_vars; /* all relevant variables */ -static int AST_Changes; -static int AST_Round; -static RPN *rpn; -static int in_recv = 0; - -static int AST_mutual(Lextok *, Lextok *, int); -static void AST_dominant(void); -static void AST_hidden(void); -static void AST_setcur(Lextok *); -static void check_slice(Lextok *, int); -static void curtail(AST *); -static void def_use(Lextok *, int); -static void name_AST_track(Lextok *, int); -static void show_expl(void); +#define USE 1 +#define DEF 2 +#define DEREF_DEF 4 +#define DEREF_USE 8 + +static AST *ast; +static ALIAS *chalcur; +static ALIAS *chalias; +static ChanList *chanlist; +static Slicer *slicer; +static Slicer *rel_vars; /* all relevant variables */ +static int AST_Changes; +static int AST_Round; +static RPN *rpn; +static int in_recv = 0; + +static int AST_mutual(Lextok *, Lextok *, int); +static void AST_dominant(void); +static void AST_hidden(void); +static void AST_setcur(Lextok *); +static void check_slice(Lextok *, int); +static void curtail(AST *); +static void def_use(Lextok *, int); +static void name_AST_track(Lextok *, int); +static void show_expl(void); static int -AST_isini(Lextok *n) /* is this an initialized channel */ -{ Symbol *s; +AST_isini(Lextok *n) /* is this an initialized channel */ +{ Symbol *s; - if (!n || !n->sym) return 0; + if (!n || !n->sym) return 0; - s = n->sym; + s = n->sym; - if (s->type == CHAN) - return (s->ini->ntyp == CHAN); /* freshly instantiated */ + if (s->type == CHAN) + return (s->ini->ntyp == CHAN); /* freshly instantiated */ - if (s->type == STRUCT && n->rgt) - return AST_isini(n->rgt->lft); + if (s->type == STRUCT && n->rgt) + return AST_isini(n->rgt->lft); - return 0; + return 0; } static void AST_var(Lextok *n, Symbol *s, int toplevel) { - if (!s) return; + if (!s) return; - if (toplevel) - { if (s->context && s->type) - printf(":%s:L:", s->context->name); - else - printf("G:"); - } - printf("%s", s->name); /* array indices ignored */ + if (toplevel) + { if (s->context && s->type) + printf(":%s:L:", s->context->name); + else + printf("G:"); + } + printf("%s", s->name); /* array indices ignored */ - if (s->type == STRUCT && n && n->rgt && n->rgt->lft) - { printf(":"); - AST_var(n->rgt->lft, n->rgt->lft->sym, 0); - } + if (s->type == STRUCT && n && n->rgt && n->rgt->lft) + { printf(":"); + AST_var(n->rgt->lft, n->rgt->lft->sym, 0); + } } static void name_def_indices(Lextok *n, int code) { - if (!n || !n->sym) return; + if (!n || !n->sym) return; - if (n->sym->nel > 1 || n->sym->isarray) - def_use(n->lft, code); /* process the index */ + if (n->sym->nel > 1 || n->sym->isarray) + def_use(n->lft, code); /* process the index */ - if (n->sym->type == STRUCT /* and possible deeper ones */ - && n->rgt) - name_def_indices(n->rgt->lft, code); + if (n->sym->type == STRUCT /* and possible deeper ones */ + && n->rgt) + name_def_indices(n->rgt->lft, code); } static void name_def_use(Lextok *n, int code) -{ FSM_use *u; - - if (!n) return; - - if ((code&USE) - && cur_t->step - && cur_t->step->n) - { switch (cur_t->step->n->ntyp) { - case 'c': /* possible predicate abstraction? */ - n->sym->colnr |= 2; /* yes */ - break; - default: - n->sym->colnr |= 1; /* no */ - break; - } - } - - for (u = cur_t->Val[0]; u; u = u->nxt) - if (AST_mutual(n, u->n, 1) - && u->special == code) - return; - - if (use_free) - { u = use_free; - use_free = use_free->nxt; - } else - u = (FSM_use *) emalloc(sizeof(FSM_use)); - - u->n = n; - u->special = code; - u->nxt = cur_t->Val[0]; - cur_t->Val[0] = u; - - name_def_indices(n, USE|(code&(~DEF))); /* not def, but perhaps deref */ +{ FSM_use *u; + + if (!n) return; + + if ((code&USE) + && cur_t->step + && cur_t->step->n) + { switch (cur_t->step->n->ntyp) { + case 'c': /* possible predicate abstraction? */ + n->sym->colnr |= 2; /* yes */ + break; + default: + n->sym->colnr |= 1; /* no */ + break; + } + } + + for (u = cur_t->Val[0]; u; u = u->nxt) + if (AST_mutual(n, u->n, 1) + && u->special == code) + return; + + if (use_free) + { u = use_free; + use_free = use_free->nxt; + } else + u = (FSM_use *) emalloc(sizeof(FSM_use)); + + u->n = n; + u->special = code; + u->nxt = cur_t->Val[0]; + cur_t->Val[0] = u; + + name_def_indices(n, USE|(code&(~DEF))); /* not def, but perhaps deref */ } static void def_use(Lextok *now, int code) -{ Lextok *v; - - if (now) - switch (now->ntyp) { - case '!': - case UMIN: - case '~': - case 'c': - case ENABLED: - case SET_P: - case GET_P: - case ASSERT: - def_use(now->lft, USE|code); - break; - - case EVAL: - if (now->lft->ntyp == ',') - { def_use(now->lft->lft, USE|code); - } else - { def_use(now->lft, USE|code); - } - break; - - case LEN: - case FULL: - case EMPTY: - case NFULL: - case NEMPTY: - def_use(now->lft, DEREF_USE|USE|code); - break; - - case '/': - case '*': - case '-': - case '+': - case '%': - case '&': - case '^': - case '|': - case LE: - case GE: - case GT: - case LT: - case NE: - case EQ: - case OR: - case AND: - case LSHIFT: - case RSHIFT: - def_use(now->lft, USE|code); - def_use(now->rgt, USE|code); - break; - - case ASGN: - def_use(now->lft, DEF|code); - def_use(now->rgt, USE|code); - break; - - case TYPE: /* name in parameter list */ - name_def_use(now, code); - break; - - case NAME: - name_def_use(now, code); - break; - - case RUN: - name_def_use(now, USE); /* procname - not really needed */ - for (v = now->lft; v; v = v->rgt) - def_use(v->lft, USE); /* params */ - break; - - case 's': - def_use(now->lft, DEREF_DEF|DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - def_use(v->lft, USE|code); - break; - - case 'r': - def_use(now->lft, DEREF_DEF|DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - { if (v->lft->ntyp == EVAL) - { if (v->lft->ntyp == ',') - { def_use(v->lft->lft, code); /* will add USE */ - } else - { def_use(v->lft, code); /* will add USE */ - } - } else if (v->lft->ntyp != CONST) - { def_use(v->lft, DEF|code); - } } - break; - - case 'R': - def_use(now->lft, DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - { if (v->lft->ntyp == EVAL) - { if (v->lft->ntyp == ',') - { def_use(v->lft->lft, code); /* will add USE */ - } else - { def_use(v->lft, code); /* will add USE */ - } } } - break; - - case '?': - def_use(now->lft, USE|code); - if (now->rgt) - { def_use(now->rgt->lft, code); - def_use(now->rgt->rgt, code); - } - break; - - case PRINT: - for (v = now->lft; v; v = v->rgt) - def_use(v->lft, USE|code); - break; - - case PRINTM: - def_use(now->lft, USE); - break; - - case CONST: - case ELSE: /* ? */ - case NONPROGRESS: - case PC_VAL: - case 'p': - case 'q': - break; - - case '.': - case GOTO: - case BREAK: - case '@': - case D_STEP: - case ATOMIC: - case NON_ATOMIC: - case IF: - case DO: - case UNLESS: - case TIMEOUT: - case C_CODE: - case C_EXPR: - default: - break; - } +{ Lextok *v; + + if (now) + switch (now->ntyp) { + case '!': + case UMIN: + case '~': + case 'c': + case ENABLED: + case SET_P: + case GET_P: + case ASSERT: + def_use(now->lft, USE|code); + break; + + case EVAL: + if (now->lft->ntyp == ',') + { def_use(now->lft->lft, USE|code); + } else + { def_use(now->lft, USE|code); + } + break; + + case LEN: + case FULL: + case EMPTY: + case NFULL: + case NEMPTY: + def_use(now->lft, DEREF_USE|USE|code); + break; + + case '/': + case '*': + case '-': + case '+': + case '%': + case '&': + case '^': + case '|': + case LE: + case GE: + case GT: + case LT: + case NE: + case EQ: + case OR: + case AND: + case LSHIFT: + case RSHIFT: + def_use(now->lft, USE|code); + def_use(now->rgt, USE|code); + break; + + case ASGN: + def_use(now->lft, DEF|code); + def_use(now->rgt, USE|code); + break; + + case TYPE: /* name in parameter list */ + name_def_use(now, code); + break; + + case NAME: + name_def_use(now, code); + break; + + case RUN: + name_def_use(now, USE); /* procname - not really needed */ + for (v = now->lft; v; v = v->rgt) + def_use(v->lft, USE); /* params */ + break; + + case 's': + def_use(now->lft, DEREF_DEF|DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + def_use(v->lft, USE|code); + break; + + case 'r': + def_use(now->lft, DEREF_DEF|DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + { if (v->lft->ntyp == EVAL) + { if (v->lft->ntyp == ',') + { def_use(v->lft->lft, code); /* will add USE */ + } else + { def_use(v->lft, code); /* will add USE */ + } + } else if (v->lft->ntyp != CONST) + { def_use(v->lft, DEF|code); + } } + break; + + case 'R': + def_use(now->lft, DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + { if (v->lft->ntyp == EVAL) + { if (v->lft->ntyp == ',') + { def_use(v->lft->lft, code); /* will add USE */ + } else + { def_use(v->lft, code); /* will add USE */ + } } } + break; + + case '?': + def_use(now->lft, USE|code); + if (now->rgt) + { def_use(now->rgt->lft, code); + def_use(now->rgt->rgt, code); + } + break; + + case PRINT: + for (v = now->lft; v; v = v->rgt) + def_use(v->lft, USE|code); + break; + + case PRINTM: + def_use(now->lft, USE); + break; + + case CONST: + case ELSE: /* ? */ + case NONPROGRESS: + case PC_VAL: + case 'p': + case 'q': + break; + + case '.': + case GOTO: + case BREAK: + case '@': + case D_STEP: + case ATOMIC: + case NON_ATOMIC: + case IF: + case DO: + case UNLESS: + case TIMEOUT: + case C_CODE: + case C_EXPR: + default: + break; + } } static int AST_add_alias(Lextok *n, int nr) -{ ALIAS *ca; - int res; +{ ALIAS *ca; + int res; - for (ca = chalcur->alias; ca; ca = ca->nxt) - if (AST_mutual(ca->cnm, n, 1)) - { res = (ca->origin&nr); - ca->origin |= nr; /* 1, 2, or 4 - run, asgn, or rcv */ - return (res == 0); /* 0 if already there with same origin */ - } + for (ca = chalcur->alias; ca; ca = ca->nxt) + if (AST_mutual(ca->cnm, n, 1)) + { res = (ca->origin&nr); + ca->origin |= nr; /* 1, 2, or 4 - run, asgn, or rcv */ + return (res == 0); /* 0 if already there with same origin */ + } - ca = (ALIAS *) emalloc(sizeof(ALIAS)); - ca->cnm = n; - ca->origin = nr; - ca->nxt = chalcur->alias; - chalcur->alias = ca; - return 1; + ca = (ALIAS *) emalloc(sizeof(ALIAS)); + ca->cnm = n; + ca->origin = nr; + ca->nxt = chalcur->alias; + chalcur->alias = ca; + return 1; } static void AST_run_alias(char *pn, char *s, Lextok *t, int parno) -{ Lextok *v; - int cnt; +{ Lextok *v; + int cnt; - if (!t) return; + if (!t) return; - if (t->ntyp == RUN) - { if (strcmp(t->sym->name, s) == 0) - for (v = t->lft, cnt = 1; v; v = v->rgt, cnt++) - if (cnt == parno) - { AST_add_alias(v->lft, 1); /* RUN */ - break; - } - } else - { AST_run_alias(pn, s, t->lft, parno); - AST_run_alias(pn, s, t->rgt, parno); - } + if (t->ntyp == RUN) + { if (strcmp(t->sym->name, s) == 0) + for (v = t->lft, cnt = 1; v; v = v->rgt, cnt++) + if (cnt == parno) + { AST_add_alias(v->lft, 1); /* RUN */ + break; + } + } else + { AST_run_alias(pn, s, t->lft, parno); + AST_run_alias(pn, s, t->rgt, parno); + } } static void AST_findrun(char *s, int parno) -{ FSM_state *f; - FSM_trans *t; - AST *a; +{ FSM_state *f; + FSM_trans *t; + AST *a; - for (a = ast; a; a = a->nxt) /* automata */ - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* transitions */ - { if (t->step) - AST_run_alias(a->p->n->name, s, t->step->n, parno); - } + for (a = ast; a; a = a->nxt) /* automata */ + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* transitions */ + { if (t->step) + AST_run_alias(a->p->n->name, s, t->step->n, parno); + } } static void -AST_par_chans(ProcList *p) /* find local chan's init'd to chan passed as param */ -{ Ordered *walk; - Symbol *sp; - - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp - && sp->context - && strcmp(sp->context->name, p->n->name) == 0 - && sp->Nid >= 0 /* not itself a param */ - && sp->type == CHAN - && sp->ini->ntyp == NAME) /* != CONST and != CHAN */ - { Lextok *x = nn(ZN, 0, ZN, ZN); - x->sym = sp; - AST_setcur(x); - AST_add_alias(sp->ini, 2); /* ASGN */ - } } +AST_par_chans(ProcList *p) /* find local chan's init'd to chan passed as param */ +{ Ordered *walk; + Symbol *sp; + + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp + && sp->context + && strcmp(sp->context->name, p->n->name) == 0 + && sp->Nid >= 0 /* not itself a param */ + && sp->type == CHAN + && sp->ini->ntyp == NAME) /* != CONST and != CHAN */ + { Lextok *x = nn(ZN, 0, ZN, ZN); + x->sym = sp; + AST_setcur(x); + AST_add_alias(sp->ini, 2); /* ASGN */ + } } } static void AST_para(ProcList *p) -{ Lextok *f, *t, *c; - int cnt = 0; +{ Lextok *f, *t, *c; + int cnt = 0; - AST_par_chans(p); + AST_par_chans(p); - for (f = p->p; f; f = f->rgt) /* list of types */ - for (t = f->lft; t; t = t->rgt) - { if (t->ntyp != ',') - c = t; - else - c = t->lft; /* expanded struct */ + for (f = p->p; f; f = f->rgt) /* list of types */ + for (t = f->lft; t; t = t->rgt) + { if (t->ntyp != ',') + c = t; + else + c = t->lft; /* expanded struct */ - cnt++; - if (Sym_typ(c) == CHAN) - { ALIAS *na = (ALIAS *) emalloc(sizeof(ALIAS)); + cnt++; + if (Sym_typ(c) == CHAN) + { ALIAS *na = (ALIAS *) emalloc(sizeof(ALIAS)); - na->cnm = c; - na->nxt = chalias; - chalcur = chalias = na; + na->cnm = c; + na->nxt = chalias; + chalcur = chalias = na; #if 0 - printf("%s -- (par) -- ", p->n->name); - AST_var(c, c->sym, 1); - printf(" => <<"); + printf("%s -- (par) -- ", p->n->name); + AST_var(c, c->sym, 1); + printf(" => <<"); #endif - AST_findrun(p->n->name, cnt); + AST_findrun(p->n->name, cnt); #if 0 - printf(">>\n"); + printf(">>\n"); #endif - } - } + } + } } static void AST_haschan(Lextok *c) { - if (!c) return; - if (Sym_typ(c) == CHAN) - { AST_add_alias(c, 2); /* ASGN */ + if (!c) return; + if (Sym_typ(c) == CHAN) + { AST_add_alias(c, 2); /* ASGN */ #if 0 - printf("<<"); - AST_var(c, c->sym, 1); - printf(">>\n"); + printf("<<"); + AST_var(c, c->sym, 1); + printf(">>\n"); #endif - } else - { AST_haschan(c->rgt); - AST_haschan(c->lft); - } + } else + { AST_haschan(c->rgt); + AST_haschan(c->lft); + } } static int AST_nrpar(Lextok *n) /* 's' or 'r' */ -{ Lextok *m; - int j = 0; +{ Lextok *m; + int j = 0; - for (m = n->rgt; m; m = m->rgt) - j++; - return j; + for (m = n->rgt; m; m = m->rgt) + j++; + return j; } static int AST_ord(Lextok *n, Lextok *s) -{ Lextok *m; - int j = 0; +{ Lextok *m; + int j = 0; - for (m = n->rgt; m; m = m->rgt) - { j++; - if (s->sym == m->lft->sym) - return j; - } - return 0; + for (m = n->rgt; m; m = m->rgt) + { j++; + if (s->sym == m->lft->sym) + return j; + } + return 0; } #if 0 static void AST_ownership(Symbol *s) { - if (!s) return; - printf("%s:", s->name); - AST_ownership(s->owner); + if (!s) return; + printf("%s:", s->name); + AST_ownership(s->owner); } #endif static int AST_mutual(Lextok *a, Lextok *b, int toplevel) -{ Symbol *as, *bs; +{ Symbol *as, *bs; - if (!a && !b) return 1; + if (!a && !b) return 1; - if (!a || !b) return 0; + if (!a || !b) return 0; - as = a->sym; - bs = b->sym; + as = a->sym; + bs = b->sym; - if (!as || !bs) return 0; + if (!as || !bs) return 0; - if (toplevel && as->context != bs->context) - return 0; + if (toplevel && as->context != bs->context) + return 0; - if (as->type != bs->type) - return 0; + if (as->type != bs->type) + return 0; - if (strcmp(as->name, bs->name) != 0) - return 0; + if (strcmp(as->name, bs->name) != 0) + return 0; - if (as->type == STRUCT && a->rgt && b->rgt) /* we know that a and b are not null */ - return AST_mutual(a->rgt->lft, b->rgt->lft, 0); + if (as->type == STRUCT && a->rgt && b->rgt) /* we know that a and b are not null */ + return AST_mutual(a->rgt->lft, b->rgt->lft, 0); - return 1; + return 1; } static void -AST_setcur(Lextok *n) /* set chalcur */ -{ ALIAS *ca; +AST_setcur(Lextok *n) /* set chalcur */ +{ ALIAS *ca; - for (ca = chalias; ca; ca = ca->nxt) - if (AST_mutual(ca->cnm, n, 1)) /* if same chan */ - { chalcur = ca; - return; - } + for (ca = chalias; ca; ca = ca->nxt) + if (AST_mutual(ca->cnm, n, 1)) /* if same chan */ + { chalcur = ca; + return; + } - ca = (ALIAS *) emalloc(sizeof(ALIAS)); - ca->cnm = n; - ca->nxt = chalias; - chalcur = chalias = ca; + ca = (ALIAS *) emalloc(sizeof(ALIAS)); + ca->cnm = n; + ca->nxt = chalias; + chalcur = chalias = ca; } static void -AST_other(AST *a) /* check chan params in asgns and recvs */ -{ FSM_state *f; - FSM_trans *t; - FSM_use *u; - ChanList *cl; - - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* transitions */ - for (u = t->Val[0]; u; u = u->nxt) /* def/use info */ - if (Sym_typ(u->n) == CHAN - && (u->special&DEF)) /* def of chan-name */ - { AST_setcur(u->n); - switch (t->step->n->ntyp) { - case ASGN: - AST_haschan(t->step->n->rgt); - break; - case 'r': - /* guess sends where name may originate */ - for (cl = chanlist; cl; cl = cl->nxt) /* all sends */ - { int aa = AST_nrpar(cl->s); - int bb = AST_nrpar(t->step->n); - if (aa != bb) /* matching nrs of params */ - continue; - - aa = AST_ord(cl->s, cl->n); - bb = AST_ord(t->step->n, u->n); - if (aa != bb) /* same position in parlist */ - continue; - - AST_add_alias(cl->n, 4); /* RCV assume possible match */ - } - break; - default: - printf("type = %d\n", t->step->n->ntyp); - non_fatal("unexpected chan def type", (char *) 0); - break; - } } +AST_other(AST *a) /* check chan params in asgns and recvs */ +{ FSM_state *f; + FSM_trans *t; + FSM_use *u; + ChanList *cl; + + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* transitions */ + for (u = t->Val[0]; u; u = u->nxt) /* def/use info */ + if (Sym_typ(u->n) == CHAN + && (u->special&DEF)) /* def of chan-name */ + { AST_setcur(u->n); + switch (t->step->n->ntyp) { + case ASGN: + AST_haschan(t->step->n->rgt); + break; + case 'r': + /* guess sends where name may originate */ + for (cl = chanlist; cl; cl = cl->nxt) /* all sends */ + { int aa = AST_nrpar(cl->s); + int bb = AST_nrpar(t->step->n); + if (aa != bb) /* matching nrs of params */ + continue; + + aa = AST_ord(cl->s, cl->n); + bb = AST_ord(t->step->n, u->n); + if (aa != bb) /* same position in parlist */ + continue; + + AST_add_alias(cl->n, 4); /* RCV assume possible match */ + } + break; + default: + printf("type = %d\n", t->step->n->ntyp); + non_fatal("unexpected chan def type", (char *) 0); + break; + } } } static void AST_aliases(void) -{ ALIAS *na, *ca; - - for (na = chalias; na; na = na->nxt) - { printf("\npossible aliases of "); - AST_var(na->cnm, na->cnm->sym, 1); - printf("\n\t"); - for (ca = na->alias; ca; ca = ca->nxt) - { if (!ca->cnm->sym) - printf("no valid name "); - else - AST_var(ca->cnm, ca->cnm->sym, 1); - printf("<"); - if (ca->origin & 1) printf("RUN "); - if (ca->origin & 2) printf("ASGN "); - if (ca->origin & 4) printf("RCV "); - printf("[%s]", AST_isini(ca->cnm)?"Initzd":"Name"); - printf(">"); - if (ca->nxt) printf(", "); - } - printf("\n"); - } - printf("\n"); +{ ALIAS *na, *ca; + + for (na = chalias; na; na = na->nxt) + { printf("\npossible aliases of "); + AST_var(na->cnm, na->cnm->sym, 1); + printf("\n\t"); + for (ca = na->alias; ca; ca = ca->nxt) + { if (!ca->cnm->sym) + printf("no valid name "); + else + AST_var(ca->cnm, ca->cnm->sym, 1); + printf("<"); + if (ca->origin & 1) printf("RUN "); + if (ca->origin & 2) printf("ASGN "); + if (ca->origin & 4) printf("RCV "); + printf("[%s]", AST_isini(ca->cnm)?"Initzd":"Name"); + printf(">"); + if (ca->nxt) printf(", "); + } + printf("\n"); + } + printf("\n"); } static void -AST_indirect(FSM_use *uin, FSM_trans *t, char *cause, char *pn) -{ FSM_use *u; - - /* this is a newly discovered relevant statement */ - /* all vars it uses to contribute to its DEF are new criteria */ - - if (!(t->relevant&1)) AST_Changes++; - - t->round = AST_Round; - t->relevant = 1; - - if ((verbose&32) && t->step) - { printf("\tDR %s [[ ", pn); - comment(stdout, t->step->n, 0); - printf("]]\n\t\tfully relevant %s", cause); - if (uin) { printf(" due to "); AST_var(uin->n, uin->n->sym, 1); } - printf("\n"); - } - for (u = t->Val[0]; u; u = u->nxt) - if (u != uin - && (u->special&(USE|DEREF_USE))) - { if (verbose&32) - { printf("\t\t\tuses(%d): ", u->special); - AST_var(u->n, u->n->sym, 1); - printf("\n"); - } - name_AST_track(u->n, u->special); /* add to slice criteria */ - } +AST_indirect(FSM_use *uin, FSM_trans *t, const char *cause, const char *pn) +{ FSM_use *u; + + /* this is a newly discovered relevant statement */ + /* all vars it uses to contribute to its DEF are new criteria */ + + if (!(t->relevant&1)) AST_Changes++; + + t->round = AST_Round; + t->relevant = 1; + + if ((verbose&32) && t->step) + { printf("\tDR %s [[ ", pn); + comment(stdout, t->step->n, 0); + printf("]]\n\t\tfully relevant %s", cause); + if (uin) { printf(" due to "); AST_var(uin->n, uin->n->sym, 1); } + printf("\n"); + } + for (u = t->Val[0]; u; u = u->nxt) + if (u != uin + && (u->special&(USE|DEREF_USE))) + { if (verbose&32) + { printf("\t\t\tuses(%d): ", u->special); + AST_var(u->n, u->n->sym, 1); + printf("\n"); + } + name_AST_track(u->n, u->special); /* add to slice criteria */ + } } static void -def_relevant(char *pn, FSM_trans *t, Lextok *n, int ischan) -{ FSM_use *u; - ALIAS *na, *ca; - int chanref; - - /* look for all DEF's of n - * mark those stmnts relevant - * mark all var USEs in those stmnts as criteria - */ - - if (n->ntyp != ELSE) - for (u = t->Val[0]; u; u = u->nxt) - { chanref = (Sym_typ(u->n) == CHAN); - - if (ischan != chanref /* no possible match */ - || !(u->special&(DEF|DEREF_DEF))) /* not a def */ - continue; - - if (AST_mutual(u->n, n, 1)) - { AST_indirect(u, t, "(exact match)", pn); - continue; - } - - if (chanref) - for (na = chalias; na; na = na->nxt) - { if (!AST_mutual(u->n, na->cnm, 1)) - continue; - for (ca = na->alias; ca; ca = ca->nxt) - if (AST_mutual(ca->cnm, n, 1) - && AST_isini(ca->cnm)) - { AST_indirect(u, t, "(alias match)", pn); - break; - } - if (ca) break; - } } +def_relevant(const char *pn, FSM_trans *t, Lextok *n, int ischan) +{ FSM_use *u; + ALIAS *na, *ca; + int chanref; + + /* look for all DEF's of n + * mark those stmnts relevant + * mark all var USEs in those stmnts as criteria + */ + + if (n->ntyp != ELSE) + for (u = t->Val[0]; u; u = u->nxt) + { chanref = (Sym_typ(u->n) == CHAN); + + if (ischan != chanref /* no possible match */ + || !(u->special&(DEF|DEREF_DEF))) /* not a def */ + continue; + + if (AST_mutual(u->n, n, 1)) + { AST_indirect(u, t, "(exact match)", pn); + continue; + } + + if (chanref) + for (na = chalias; na; na = na->nxt) + { if (!AST_mutual(u->n, na->cnm, 1)) + continue; + for (ca = na->alias; ca; ca = ca->nxt) + if (AST_mutual(ca->cnm, n, 1) + && AST_isini(ca->cnm)) + { AST_indirect(u, t, "(alias match)", pn); + break; + } + if (ca) break; + } } } static void AST_relevant(Lextok *n) -{ AST *a; - FSM_state *f; - FSM_trans *t; - int ischan; - - /* look for all DEF's of n - * mark those stmnts relevant - * mark all var USEs in those stmnts as criteria - */ - - if (!n) return; - ischan = (Sym_typ(n) == CHAN); - - if (verbose&32) - { printf("<ntyp); - AST_var(n, n->sym, 1); - printf(">>\n"); - } - - for (t = expl_par; t; t = t->nxt) /* param assignments */ - { if (!(t->relevant&1)) - def_relevant(":params:", t, n, ischan); - } - - for (t = expl_var; t; t = t->nxt) - { if (!(t->relevant&1)) /* var inits */ - def_relevant(":vars:", t, n, ischan); - } - - for (a = ast; a; a = a->nxt) /* all other stmnts */ - { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) - for (f = a->fsm; f; f = f->nxt) - for (t = f->t; t; t = t->nxt) - { if (!(t->relevant&1)) - def_relevant(a->p->n->name, t, n, ischan); - } } +{ AST *a; + FSM_state *f; + FSM_trans *t; + int ischan; + + /* look for all DEF's of n + * mark those stmnts relevant + * mark all var USEs in those stmnts as criteria + */ + + if (!n) return; + ischan = (Sym_typ(n) == CHAN); + + if (verbose&32) + { printf("<ntyp); + AST_var(n, n->sym, 1); + printf(">>\n"); + } + + for (t = expl_par; t; t = t->nxt) /* param assignments */ + { if (!(t->relevant&1)) + def_relevant(":params:", t, n, ischan); + } + + for (t = expl_var; t; t = t->nxt) + { if (!(t->relevant&1)) /* var inits */ + def_relevant(":vars:", t, n, ischan); + } + + for (a = ast; a; a = a->nxt) /* all other stmnts */ + { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) + for (f = a->fsm; f; f = f->nxt) + for (t = f->t; t; t = t->nxt) + { if (!(t->relevant&1)) + def_relevant(a->p->n->name, t, n, ischan); + } } } static int AST_relpar(char *s) -{ FSM_trans *t, *T; - FSM_use *u; - - for (T = expl_par; T; T = (T == expl_par)?expl_var: (FSM_trans *) 0) - for (t = T; t; t = t->nxt) - { if (t->relevant&1) - for (u = t->Val[0]; u; u = u->nxt) - { if (u->n->sym->type - && u->n->sym->context - && strcmp(u->n->sym->context->name, s) == 0) - { - if (verbose&32) - { printf("proctype %s relevant, due to symbol ", s); - AST_var(u->n, u->n->sym, 1); - printf("\n"); - } - return 1; - } } } - return 0; +{ FSM_trans *t, *T; + FSM_use *u; + + for (T = expl_par; T; T = (T == expl_par)?expl_var: (FSM_trans *) 0) + for (t = T; t; t = t->nxt) + { if (t->relevant&1) + for (u = t->Val[0]; u; u = u->nxt) + { if (u->n->sym->type + && u->n->sym->context + && strcmp(u->n->sym->context->name, s) == 0) + { + if (verbose&32) + { printf("proctype %s relevant, due to symbol ", s); + AST_var(u->n, u->n->sym, 1); + printf("\n"); + } + return 1; + } } } + return 0; } static void AST_dorelevant(void) -{ AST *a; - RPN *r; +{ AST *a; + RPN *r; - for (r = rpn; r; r = r->nxt) - { for (a = ast; a; a = a->nxt) - if (strcmp(a->p->n->name, r->rn->name) == 0) - { a->relevant |= 1; - break; - } - if (!a) - fatal("cannot find proctype %s", r->rn->name); - } + for (r = rpn; r; r = r->nxt) + { for (a = ast; a; a = a->nxt) + if (strcmp(a->p->n->name, r->rn->name) == 0) + { a->relevant |= 1; + break; + } + if (!a) + fatal("cannot find proctype %s", r->rn->name); + } } static void AST_procisrelevant(Symbol *s) -{ RPN *r; - for (r = rpn; r; r = r->nxt) - if (strcmp(r->rn->name, s->name) == 0) - return; - r = (RPN *) emalloc(sizeof(RPN)); - r->rn = s; - r->nxt = rpn; - rpn = r; +{ RPN *r; + for (r = rpn; r; r = r->nxt) + if (strcmp(r->rn->name, s->name) == 0) + return; + r = (RPN *) emalloc(sizeof(RPN)); + r->rn = s; + r->nxt = rpn; + rpn = r; } static int AST_proc_isrel(char *s) -{ AST *a; +{ AST *a; - for (a = ast; a; a = a->nxt) - if (strcmp(a->p->n->name, s) == 0) - return (a->relevant&1); - non_fatal("cannot happen, missing proc in ast", (char *) 0); - return 0; + for (a = ast; a; a = a->nxt) + if (strcmp(a->p->n->name, s) == 0) + return (a->relevant&1); + non_fatal("cannot happen, missing proc in ast", (char *) 0); + return 0; } static int AST_scoutrun(Lextok *t) { - if (!t) return 0; + if (!t) return 0; - if (t->ntyp == RUN) - return AST_proc_isrel(t->sym->name); - return (AST_scoutrun(t->lft) || AST_scoutrun(t->rgt)); + if (t->ntyp == RUN) + return AST_proc_isrel(t->sym->name); + return (AST_scoutrun(t->lft) || AST_scoutrun(t->rgt)); } static void AST_tagruns(void) -{ AST *a; - FSM_state *f; - FSM_trans *t; - - /* if any stmnt inside a proctype is relevant - * or any parameter passed in a run - * then so are all the run statements on that proctype - */ - - for (a = ast; a; a = a->nxt) - { if (a->p->b == N_CLAIM || a->p->b == I_PROC - || a->p->b == E_TRACE || a->p->b == N_TRACE) - { a->relevant |= 1; /* the proctype is relevant */ - continue; - } - if (AST_relpar(a->p->n->name)) - a->relevant |= 1; - else - { for (f = a->fsm; f; f = f->nxt) - for (t = f->t; t; t = t->nxt) - if (t->relevant) - goto yes; -yes: if (f) - a->relevant |= 1; - } - } - - for (a = ast; a; a = a->nxt) - for (f = a->fsm; f; f = f->nxt) - for (t = f->t; t; t = t->nxt) - if (t->step - && AST_scoutrun(t->step->n)) - { AST_indirect((FSM_use *)0, t, ":run:", a->p->n->name); - /* BUT, not all actual params are relevant */ - } +{ AST *a; + FSM_state *f; + FSM_trans *t; + + /* if any stmnt inside a proctype is relevant + * or any parameter passed in a run + * then so are all the run statements on that proctype + */ + + for (a = ast; a; a = a->nxt) + { if (a->p->b == N_CLAIM || a->p->b == I_PROC + || a->p->b == E_TRACE || a->p->b == N_TRACE) + { a->relevant |= 1; /* the proctype is relevant */ + continue; + } + if (AST_relpar(a->p->n->name)) + a->relevant |= 1; + else + { for (f = a->fsm; f; f = f->nxt) + for (t = f->t; t; t = t->nxt) + if (t->relevant) + goto yes; +yes: if (f) + a->relevant |= 1; + } + } + + for (a = ast; a; a = a->nxt) + for (f = a->fsm; f; f = f->nxt) + for (t = f->t; t; t = t->nxt) + if (t->step + && AST_scoutrun(t->step->n)) + { AST_indirect((FSM_use *)0, t, ":run:", a->p->n->name); + /* BUT, not all actual params are relevant */ + } } static void -AST_report(AST *a, Element *e) /* ALSO deduce irrelevant vars */ +AST_report(AST *a, Element *e) /* ALSO deduce irrelevant vars */ { - if (!(a->relevant&2)) - { a->relevant |= 2; - printf("spin: redundant in proctype %s (for given property):\n", - a->p->n->name); - } - printf(" %s:%d (state %d)", - e->n?e->n->fn->name:"-", - e->n?e->n->ln:-1, - e->seqno); - printf(" ["); - comment(stdout, e->n, 0); - printf("]\n"); + if (!(a->relevant&2)) + { a->relevant |= 2; + printf("spin: redundant in proctype %s (for given property):\n", + a->p->n->name); + } + printf(" %s:%d (state %d)", + e->n?e->n->fn->name:"-", + e->n?e->n->ln:-1, + e->seqno); + printf(" ["); + comment(stdout, e->n, 0); + printf("]\n"); } static int AST_always(Lextok *n) { - if (!n) return 0; + if (!n) return 0; - if (n->ntyp == '@' /* -end */ - || n->ntyp == 'p') /* remote reference */ - return 1; - return AST_always(n->lft) || AST_always(n->rgt); + if (n->ntyp == '@' /* -end */ + || n->ntyp == 'p') /* remote reference */ + return 1; + return AST_always(n->lft) || AST_always(n->rgt); } static void AST_edge_dump(AST *a, FSM_state *f) -{ FSM_trans *t; - FSM_use *u; - - for (t = f->t; t; t = t->nxt) /* edges */ - { - if (t->step && AST_always(t->step->n)) - t->relevant |= 1; /* always relevant */ - - if (verbose&32) - { switch (t->relevant) { - case 0: printf(" "); break; - case 1: printf("*%3d ", t->round); break; - case 2: printf("+%3d ", t->round); break; - case 3: printf("#%3d ", t->round); break; - default: printf("? "); break; - } - - printf("%d\t->\t%d\t", f->from, t->to); - if (t->step) - comment(stdout, t->step->n, 0); - else - printf("Unless"); - - for (u = t->Val[0]; u; u = u->nxt) - { printf(" <"); - AST_var(u->n, u->n->sym, 1); - printf(":%d>", u->special); - } - printf("\n"); - } else - { if (t->relevant) - continue; - - if (t->step) - switch(t->step->n->ntyp) { - case ASGN: - case 's': - case 'r': - case 'c': - if (t->step->n->lft->ntyp != CONST) - AST_report(a, t->step); - break; - - case PRINT: /* don't report */ - case PRINTM: - case ASSERT: - case C_CODE: - case C_EXPR: - default: - break; - } } } +{ FSM_trans *t; + FSM_use *u; + + for (t = f->t; t; t = t->nxt) /* edges */ + { + if (t->step && AST_always(t->step->n)) + t->relevant |= 1; /* always relevant */ + + if (verbose&32) + { switch (t->relevant) { + case 0: printf(" "); break; + case 1: printf("*%3d ", t->round); break; + case 2: printf("+%3d ", t->round); break; + case 3: printf("#%3d ", t->round); break; + default: printf("? "); break; + } + + printf("%d\t->\t%d\t", f->from, t->to); + if (t->step) + comment(stdout, t->step->n, 0); + else + printf("Unless"); + + for (u = t->Val[0]; u; u = u->nxt) + { printf(" <"); + AST_var(u->n, u->n->sym, 1); + printf(":%d>", u->special); + } + printf("\n"); + } else + { if (t->relevant) + continue; + + if (t->step) + switch(t->step->n->ntyp) { + case ASGN: + case 's': + case 'r': + case 'c': + if (t->step->n->lft->ntyp != CONST) + AST_report(a, t->step); + break; + + case PRINT: /* don't report */ + case PRINTM: + case ASSERT: + case C_CODE: + case C_EXPR: + default: + break; + } } } } static void AST_dfs(AST *a, int s, int vis) -{ FSM_state *f; - FSM_trans *t; +{ FSM_state *f; + FSM_trans *t; - f = fsm_tbl[s]; - if (f->seen) return; + f = fsm_tbl[s]; + if (f->seen) return; - f->seen = 1; - if (vis) AST_edge_dump(a, f); + f->seen = 1; + if (vis) AST_edge_dump(a, f); - for (t = f->t; t; t = t->nxt) - AST_dfs(a, t->to, vis); + for (t = f->t; t; t = t->nxt) + AST_dfs(a, t->to, vis); } static void AST_dump(AST *a) -{ FSM_state *f; +{ FSM_state *f; - for (f = a->fsm; f; f = f->nxt) - { f->seen = 0; - fsm_tbl[f->from] = f; - } + for (f = a->fsm; f; f = f->nxt) + { f->seen = 0; + fsm_tbl[f->from] = f; + } - if (verbose&32) - printf("AST_START %s from %d\n", a->p->n->name, a->i_st); + if (verbose&32) + printf("AST_START %s from %d\n", a->p->n->name, a->i_st); - AST_dfs(a, a->i_st, 1); + AST_dfs(a, a->i_st, 1); } static void AST_sends(AST *a) -{ FSM_state *f; - FSM_trans *t; - FSM_use *u; - ChanList *cl; - - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* transitions */ - { if (t->step - && t->step->n - && t->step->n->ntyp == 's') - for (u = t->Val[0]; u; u = u->nxt) - { if (Sym_typ(u->n) == CHAN - && ((u->special&USE) && !(u->special&DEREF_USE))) - { +{ FSM_state *f; + FSM_trans *t; + FSM_use *u; + ChanList *cl; + + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* transitions */ + { if (t->step + && t->step->n + && t->step->n->ntyp == 's') + for (u = t->Val[0]; u; u = u->nxt) + { if (Sym_typ(u->n) == CHAN + && ((u->special&USE) && !(u->special&DEREF_USE))) + { #if 0 - printf("%s -- (%d->%d) -- ", - a->p->n->name, f->from, t->to); - AST_var(u->n, u->n->sym, 1); - printf(" -> chanlist\n"); + printf("%s -- (%d->%d) -- ", + a->p->n->name, f->from, t->to); + AST_var(u->n, u->n->sym, 1); + printf(" -> chanlist\n"); #endif - cl = (ChanList *) emalloc(sizeof(ChanList)); - cl->s = t->step->n; - cl->n = u->n; - cl->nxt = chanlist; - chanlist = cl; -} } } } + cl = (ChanList *) emalloc(sizeof(ChanList)); + cl->s = t->step->n; + cl->n = u->n; + cl->nxt = chanlist; + chanlist = cl; +} } } } static ALIAS * AST_alfind(Lextok *n) -{ ALIAS *na; +{ ALIAS *na; - for (na = chalias; na; na = na->nxt) - if (AST_mutual(na->cnm, n, 1)) - return na; - return (ALIAS *) 0; + for (na = chalias; na; na = na->nxt) + if (AST_mutual(na->cnm, n, 1)) + return na; + return (ALIAS *) 0; } static void AST_trans(void) -{ ALIAS *na, *ca, *da, *ea; - int nchanges; +{ ALIAS *na, *ca, *da, *ea; + int nchanges; - do { - nchanges = 0; - for (na = chalias; na; na = na->nxt) - { chalcur = na; - for (ca = na->alias; ca; ca = ca->nxt) - { da = AST_alfind(ca->cnm); - if (da) - for (ea = da->alias; ea; ea = ea->nxt) - { nchanges += AST_add_alias(ea->cnm, - ea->origin|ca->origin); - } } } - } while (nchanges > 0); + do { + nchanges = 0; + for (na = chalias; na; na = na->nxt) + { chalcur = na; + for (ca = na->alias; ca; ca = ca->nxt) + { da = AST_alfind(ca->cnm); + if (da) + for (ea = da->alias; ea; ea = ea->nxt) + { nchanges += AST_add_alias(ea->cnm, + ea->origin|ca->origin); + } } } + } while (nchanges > 0); - chalcur = (ALIAS *) 0; + chalcur = (ALIAS *) 0; } static void AST_def_use(AST *a) -{ FSM_state *f; - FSM_trans *t; +{ FSM_state *f; + FSM_trans *t; - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* all edges */ - { cur_t = t; - rel_use(t->Val[0]); /* redo Val; doesn't cover structs */ - rel_use(t->Val[1]); - t->Val[0] = t->Val[1] = (FSM_use *) 0; + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* all edges */ + { cur_t = t; + rel_use(t->Val[0]); /* redo Val; doesn't cover structs */ + rel_use(t->Val[1]); + t->Val[0] = t->Val[1] = (FSM_use *) 0; - if (!t->step) continue; + if (!t->step) continue; - def_use(t->step->n, 0); /* def/use info, including structs */ - } - cur_t = (FSM_trans *) 0; + def_use(t->step->n, 0); /* def/use info, including structs */ + } + cur_t = (FSM_trans *) 0; } static void name_AST_track(Lextok *n, int code) -{ extern int nr_errs; +{ extern int nr_errs; #if 0 - printf("AST_name: "); - AST_var(n, n->sym, 1); - printf(" -- %d\n", code); + printf("AST_name: "); + AST_var(n, n->sym, 1); + printf(" -- %d\n", code); #endif - if (in_recv && (code&DEF) && (code&USE)) - { printf("spin: %s:%d, error: DEF and USE of same var in rcv stmnt: ", - n->fn->name, n->ln); - AST_var(n, n->sym, 1); - printf(" -- %d\n", code); - nr_errs++; - } - check_slice(n, code); + if (in_recv && (code&DEF) && (code&USE)) + { printf("spin: %s:%d, error: DEF and USE of same var in rcv stmnt: ", + n->fn->name, n->ln); + AST_var(n, n->sym, 1); + printf(" -- %d\n", code); + nr_errs++; + } + check_slice(n, code); } void -AST_track(Lextok *now, int code) /* called from main.c */ -{ Lextok *v; extern int export_ast; - - if (!export_ast) return; - - if (now) - switch (now->ntyp) { - case LEN: - case FULL: - case EMPTY: - case NFULL: - case NEMPTY: - AST_track(now->lft, DEREF_USE|USE|code); - break; - - case '/': - case '*': - case '-': - case '+': - case '%': - case '&': - case '^': - case '|': - case LE: - case GE: - case GT: - case LT: - case NE: - case EQ: - case OR: - case AND: - case LSHIFT: - case RSHIFT: - AST_track(now->rgt, USE|code); - /* fall through */ - case '!': - case UMIN: - case '~': - case 'c': - case ENABLED: - case SET_P: - case GET_P: - case ASSERT: - AST_track(now->lft, USE|code); - break; - - case EVAL: - if (now->lft->ntyp == ',') - { AST_track(now->lft->lft, USE|(code&(~DEF))); - } else - { AST_track(now->lft, USE|(code&(~DEF))); - } - break; - - case NAME: - name_AST_track(now, code); - if (now->sym->nel > 1 || now->sym->isarray) - AST_track(now->lft, USE); /* index, was USE|code */ - break; - - case 'R': - AST_track(now->lft, DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - AST_track(v->lft, code); /* a deeper eval can add USE */ - break; - - case '?': - AST_track(now->lft, USE|code); - if (now->rgt) - { AST_track(now->rgt->lft, code); - AST_track(now->rgt->rgt, code); - } - break; +AST_track(Lextok *now, int code) /* called from main.c */ +{ Lextok *v; extern int export_ast; + + if (!export_ast) return; + + if (now) + switch (now->ntyp) { + case LEN: + case FULL: + case EMPTY: + case NFULL: + case NEMPTY: + AST_track(now->lft, DEREF_USE|USE|code); + break; + + case '/': + case '*': + case '-': + case '+': + case '%': + case '&': + case '^': + case '|': + case LE: + case GE: + case GT: + case LT: + case NE: + case EQ: + case OR: + case AND: + case LSHIFT: + case RSHIFT: + AST_track(now->rgt, USE|code); + /* fall through */ + case '!': + case UMIN: + case '~': + case 'c': + case ENABLED: + case SET_P: + case GET_P: + case ASSERT: + AST_track(now->lft, USE|code); + break; + + case EVAL: + if (now->lft->ntyp == ',') + { AST_track(now->lft->lft, USE|(code&(~DEF))); + } else + { AST_track(now->lft, USE|(code&(~DEF))); + } + break; + + case NAME: + name_AST_track(now, code); + if (now->sym->nel > 1 || now->sym->isarray) + AST_track(now->lft, USE); /* index, was USE|code */ + break; + + case 'R': + AST_track(now->lft, DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + AST_track(v->lft, code); /* a deeper eval can add USE */ + break; + + case '?': + AST_track(now->lft, USE|code); + if (now->rgt) + { AST_track(now->rgt->lft, code); + AST_track(now->rgt->rgt, code); + } + break; /* added for control deps: */ - case TYPE: - name_AST_track(now, code); - break; - case ASGN: - AST_track(now->lft, DEF|code); - AST_track(now->rgt, USE|code); - break; - case RUN: - name_AST_track(now, USE); - for (v = now->lft; v; v = v->rgt) - AST_track(v->lft, USE|code); - break; - case 's': - AST_track(now->lft, DEREF_DEF|DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - AST_track(v->lft, USE|code); - break; - case 'r': - AST_track(now->lft, DEREF_DEF|DEREF_USE|USE|code); - for (v = now->rgt; v; v = v->rgt) - { in_recv++; - AST_track(v->lft, DEF|code); - in_recv--; - } - break; - case PRINT: - for (v = now->lft; v; v = v->rgt) - AST_track(v->lft, USE|code); - break; - case PRINTM: - AST_track(now->lft, USE); - break; + case TYPE: + name_AST_track(now, code); + break; + case ASGN: + AST_track(now->lft, DEF|code); + AST_track(now->rgt, USE|code); + break; + case RUN: + name_AST_track(now, USE); + for (v = now->lft; v; v = v->rgt) + AST_track(v->lft, USE|code); + break; + case 's': + AST_track(now->lft, DEREF_DEF|DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + AST_track(v->lft, USE|code); + break; + case 'r': + AST_track(now->lft, DEREF_DEF|DEREF_USE|USE|code); + for (v = now->rgt; v; v = v->rgt) + { in_recv++; + AST_track(v->lft, DEF|code); + in_recv--; + } + break; + case PRINT: + for (v = now->lft; v; v = v->rgt) + AST_track(v->lft, USE|code); + break; + case PRINTM: + AST_track(now->lft, USE); + break; /* end add */ - case 'p': + case 'p': #if 0 - 'p' -sym-> _p - / - '?' -sym-> a (proctype) - / - b (pid expr) + 'p' -sym-> _p + / + '?' -sym-> a (proctype) + / + b (pid expr) #endif - AST_track(now->lft->lft, USE|code); - AST_procisrelevant(now->lft->sym); - break; - - case CONST: - case ELSE: - case NONPROGRESS: - case PC_VAL: - case 'q': - break; - - case '.': - case GOTO: - case BREAK: - case '@': - case D_STEP: - case ATOMIC: - case NON_ATOMIC: - case IF: - case DO: - case UNLESS: - case TIMEOUT: - case C_CODE: - case C_EXPR: - break; - - default: - printf("AST_track, NOT EXPECTED ntyp: %d\n", now->ntyp); - break; - } + AST_track(now->lft->lft, USE|code); + AST_procisrelevant(now->lft->sym); + break; + + case CONST: + case ELSE: + case NONPROGRESS: + case PC_VAL: + case 'q': + break; + + case '.': + case GOTO: + case BREAK: + case '@': + case D_STEP: + case ATOMIC: + case NON_ATOMIC: + case IF: + case DO: + case UNLESS: + case TIMEOUT: + case C_CODE: + case C_EXPR: + break; + + default: + printf("AST_track, NOT EXPECTED ntyp: %d\n", now->ntyp); + break; + } } static int AST_dump_rel(void) -{ Slicer *rv; - Ordered *walk; - char buf[64]; - int banner=0; - - if (verbose&32) - { printf("Relevant variables:\n"); - for (rv = rel_vars; rv; rv = rv->nxt) - { printf("\t"); - AST_var(rv->n, rv->n->sym, 1); - printf("\n"); - } - return 1; - } - for (rv = rel_vars; rv; rv = rv->nxt) - rv->n->sym->setat = 1; /* mark it */ - - for (walk = all_names; walk; walk = walk->next) - { Symbol *s; - s = walk->entry; - if (!s->setat - && (s->type != MTYPE || s->ini->ntyp != CONST) - && s->type != STRUCT /* report only fields */ - && s->type != PROCTYPE - && !s->owner - && sputtype(buf, s->type)) - { if (!banner) - { banner = 1; - printf("spin: redundant vars (for given property):\n"); - } - printf("\t"); - symvar(s); - } } - return banner; +{ Slicer *rv; + Ordered *walk; + char buf[64]; + int banner=0; + + if (verbose&32) + { printf("Relevant variables:\n"); + for (rv = rel_vars; rv; rv = rv->nxt) + { printf("\t"); + AST_var(rv->n, rv->n->sym, 1); + printf("\n"); + } + return 1; + } + for (rv = rel_vars; rv; rv = rv->nxt) + rv->n->sym->setat = 1; /* mark it */ + + for (walk = all_names; walk; walk = walk->next) + { Symbol *s; + s = walk->entry; + if (!s->setat + && (s->type != MTYPE || s->ini->ntyp != CONST) + && s->type != STRUCT /* report only fields */ + && s->type != PROCTYPE + && !s->owner + && sputtype(buf, s->type)) + { if (!banner) + { banner = 1; + printf("spin: redundant vars (for given property):\n"); + } + printf("\t"); + symvar(s); + } } + return banner; } static void AST_suggestions(void) -{ Symbol *s; - Ordered *walk; - FSM_state *f; - FSM_trans *t; - AST *a; - int banner=0; - int talked=0; - - for (walk = all_names; walk; walk = walk->next) - { s = walk->entry; - if (s->colnr == 2 /* only used in conditionals */ - && (s->type == BYTE - || s->type == SHORT - || s->type == INT - || s->type == MTYPE)) - { if (!banner) - { banner = 1; - printf("spin: consider using predicate"); - printf(" abstraction to replace:\n"); - } - printf("\t"); - symvar(s); - } } - - /* look for source and sink processes */ - - for (a = ast; a; a = a->nxt) /* automata */ - { banner = 0; - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* transitions */ - { if (t->step) - switch (t->step->n->ntyp) { - case 's': - banner |= 1; - break; - case 'r': - banner |= 2; - break; - case '.': - case D_STEP: - case ATOMIC: - case NON_ATOMIC: - case IF: - case DO: - case UNLESS: - case '@': - case GOTO: - case BREAK: - case PRINT: - case PRINTM: - case ASSERT: - case C_CODE: - case C_EXPR: - break; - default: - banner |= 4; - goto no_good; - } - } -no_good: if (banner == 1 || banner == 2) - { printf("spin: proctype %s defines a %s process\n", - a->p->n->name, - banner==1?"source":"sink"); - talked |= banner; - } else if (banner == 3) - { printf("spin: proctype %s mimics a buffer\n", - a->p->n->name); - talked |= 4; - } - } - if (talked&1) - { printf("\tto reduce complexity, consider merging the code of\n"); - printf("\teach source process into the code of its target\n"); - } - if (talked&2) - { printf("\tto reduce complexity, consider merging the code of\n"); - printf("\teach sink process into the code of its source\n"); - } - if (talked&4) - printf("\tto reduce complexity, avoid buffer processes\n"); +{ Symbol *s; + Ordered *walk; + FSM_state *f; + FSM_trans *t; + AST *a; + int banner=0; + int talked=0; + + for (walk = all_names; walk; walk = walk->next) + { s = walk->entry; + if (s->colnr == 2 /* only used in conditionals */ + && (s->type == BYTE + || s->type == SHORT + || s->type == INT + || s->type == MTYPE)) + { if (!banner) + { banner = 1; + printf("spin: consider using predicate"); + printf(" abstraction to replace:\n"); + } + printf("\t"); + symvar(s); + } } + + /* look for source and sink processes */ + + for (a = ast; a; a = a->nxt) /* automata */ + { banner = 0; + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* transitions */ + { if (t->step) + switch (t->step->n->ntyp) { + case 's': + banner |= 1; + break; + case 'r': + banner |= 2; + break; + case '.': + case D_STEP: + case ATOMIC: + case NON_ATOMIC: + case IF: + case DO: + case UNLESS: + case '@': + case GOTO: + case BREAK: + case PRINT: + case PRINTM: + case ASSERT: + case C_CODE: + case C_EXPR: + break; + default: + banner |= 4; + goto no_good; + } + } +no_good: if (banner == 1 || banner == 2) + { printf("spin: proctype %s defines a %s process\n", + a->p->n->name, + banner==1?"source":"sink"); + talked |= banner; + } else if (banner == 3) + { printf("spin: proctype %s mimics a buffer\n", + a->p->n->name); + talked |= 4; + } + } + if (talked&1) + { printf("\tto reduce complexity, consider merging the code of\n"); + printf("\teach source process into the code of its target\n"); + } + if (talked&2) + { printf("\tto reduce complexity, consider merging the code of\n"); + printf("\teach sink process into the code of its source\n"); + } + if (talked&4) + printf("\tto reduce complexity, avoid buffer processes\n"); } static void AST_preserve(void) -{ Slicer *sc, *nx, *rv; +{ Slicer *sc, *nx, *rv; - for (sc = slicer; sc; sc = nx) - { if (!sc->used) - break; /* done */ + for (sc = slicer; sc; sc = nx) + { if (!sc->used) + break; /* done */ - nx = sc->nxt; + nx = sc->nxt; - for (rv = rel_vars; rv; rv = rv->nxt) - if (AST_mutual(sc->n, rv->n, 1)) - break; + for (rv = rel_vars; rv; rv = rv->nxt) + if (AST_mutual(sc->n, rv->n, 1)) + break; - if (!rv) /* not already there */ - { sc->nxt = rel_vars; - rel_vars = sc; - } } - slicer = sc; + if (!rv) /* not already there */ + { sc->nxt = rel_vars; + rel_vars = sc; + } } + slicer = sc; } static void check_slice(Lextok *n, int code) -{ Slicer *sc; +{ Slicer *sc; - for (sc = slicer; sc; sc = sc->nxt) - if (AST_mutual(sc->n, n, 1) - && sc->code == code) - return; /* already there */ + for (sc = slicer; sc; sc = sc->nxt) + if (AST_mutual(sc->n, n, 1) + && sc->code == code) + return; /* already there */ - sc = (Slicer *) emalloc(sizeof(Slicer)); - sc->n = n; + sc = (Slicer *) emalloc(sizeof(Slicer)); + sc->n = n; - sc->code = code; - sc->used = 0; - sc->nxt = slicer; - slicer = sc; + sc->code = code; + sc->used = 0; + sc->nxt = slicer; + slicer = sc; } static void AST_data_dep(void) -{ Slicer *sc; +{ Slicer *sc; - /* mark all def-relevant transitions */ - for (sc = slicer; sc; sc = sc->nxt) - { sc->used = 1; - if (verbose&32) - { printf("spin: slice criterion "); - AST_var(sc->n, sc->n->sym, 1); - printf(" type=%d\n", Sym_typ(sc->n)); - } - AST_relevant(sc->n); - } - AST_tagruns(); /* mark 'run's relevant if target proctype is relevant */ + /* mark all def-relevant transitions */ + for (sc = slicer; sc; sc = sc->nxt) + { sc->used = 1; + if (verbose&32) + { printf("spin: slice criterion "); + AST_var(sc->n, sc->n->sym, 1); + printf(" type=%d\n", Sym_typ(sc->n)); + } + AST_relevant(sc->n); + } + AST_tagruns(); /* mark 'run's relevant if target proctype is relevant */ } static int AST_blockable(AST *a, int s) -{ FSM_state *f; - FSM_trans *t; - - f = fsm_tbl[s]; - - for (t = f->t; t; t = t->nxt) - { if (t->relevant&2) - return 1; - - if (t->step && t->step->n) - switch (t->step->n->ntyp) { - case IF: - case DO: - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - if (AST_blockable(a, t->to)) - { t->round = AST_Round; - t->relevant |= 2; - return 1; - } - /* else fall through */ - default: - break; - } - else if (AST_blockable(a, t->to)) /* Unless */ - { t->round = AST_Round; - t->relevant |= 2; - return 1; - } - } - return 0; +{ FSM_state *f; + FSM_trans *t; + + f = fsm_tbl[s]; + + for (t = f->t; t; t = t->nxt) + { if (t->relevant&2) + return 1; + + if (t->step && t->step->n) + switch (t->step->n->ntyp) { + case IF: + case DO: + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + if (AST_blockable(a, t->to)) + { t->round = AST_Round; + t->relevant |= 2; + return 1; + } + /* else fall through */ + default: + break; + } + else if (AST_blockable(a, t->to)) /* Unless */ + { t->round = AST_Round; + t->relevant |= 2; + return 1; + } + } + return 0; } static void AST_spread(AST *a, int s) -{ FSM_state *f; - FSM_trans *t; - - f = fsm_tbl[s]; - - for (t = f->t; t; t = t->nxt) - { if (t->relevant&2) - continue; - - if (t->step && t->step->n) - switch (t->step->n->ntyp) { - case IF: - case DO: - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - AST_spread(a, t->to); - /* fall thru */ - default: - t->round = AST_Round; - t->relevant |= 2; - break; - } - else /* Unless */ - { AST_spread(a, t->to); - t->round = AST_Round; - t->relevant |= 2; - } - } +{ FSM_state *f; + FSM_trans *t; + + f = fsm_tbl[s]; + + for (t = f->t; t; t = t->nxt) + { if (t->relevant&2) + continue; + + if (t->step && t->step->n) + switch (t->step->n->ntyp) { + case IF: + case DO: + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + AST_spread(a, t->to); + /* fall thru */ + default: + t->round = AST_Round; + t->relevant |= 2; + break; + } + else /* Unless */ + { AST_spread(a, t->to); + t->round = AST_Round; + t->relevant |= 2; + } + } } static int AST_notrelevant(Lextok *n) -{ Slicer *s; +{ Slicer *s; - for (s = rel_vars; s; s = s->nxt) - if (AST_mutual(s->n, n, 1)) - return 0; - for (s = slicer; s; s = s->nxt) - if (AST_mutual(s->n, n, 1)) - return 0; - return 1; + for (s = rel_vars; s; s = s->nxt) + if (AST_mutual(s->n, n, 1)) + return 0; + for (s = slicer; s; s = s->nxt) + if (AST_mutual(s->n, n, 1)) + return 0; + return 1; } static int AST_withchan(Lextok *n) { - if (!n) return 0; - if (Sym_typ(n) == CHAN) - return 1; - return AST_withchan(n->lft) || AST_withchan(n->rgt); + if (!n) return 0; + if (Sym_typ(n) == CHAN) + return 1; + return AST_withchan(n->lft) || AST_withchan(n->rgt); } static int AST_suspect(FSM_trans *t) -{ FSM_use *u; - /* check for possible overkill */ - if (!t || !t->step || !AST_withchan(t->step->n)) - return 0; - for (u = t->Val[0]; u; u = u->nxt) - if (AST_notrelevant(u->n)) - return 1; - return 0; +{ FSM_use *u; + /* check for possible overkill */ + if (!t || !t->step || !AST_withchan(t->step->n)) + return 0; + for (u = t->Val[0]; u; u = u->nxt) + if (AST_notrelevant(u->n)) + return 1; + return 0; } static void AST_shouldconsider(AST *a, int s) -{ FSM_state *f; - FSM_trans *t; - - f = fsm_tbl[s]; - for (t = f->t; t; t = t->nxt) - { if (t->step && t->step->n) - switch (t->step->n->ntyp) { - case IF: - case DO: - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - AST_shouldconsider(a, t->to); - break; - default: - AST_track(t->step->n, 0); +{ FSM_state *f; + FSM_trans *t; + + f = fsm_tbl[s]; + for (t = f->t; t; t = t->nxt) + { if (t->step && t->step->n) + switch (t->step->n->ntyp) { + case IF: + case DO: + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + AST_shouldconsider(a, t->to); + break; + default: + AST_track(t->step->n, 0); /* - AST_track is called here for a blockable stmnt from which - a relevant stmnmt was shown to be reachable - for a condition this makes all USEs relevant - but for a channel operation it only makes the executability - relevant -- in those cases, parameters that aren't already - relevant may be replaceable with arbitrary tokens + AST_track is called here for a blockable stmnt from which + a relevant stmnmt was shown to be reachable + for a condition this makes all USEs relevant + but for a channel operation it only makes the executability + relevant -- in those cases, parameters that aren't already + relevant may be replaceable with arbitrary tokens */ - if (AST_suspect(t)) - { printf("spin: possibly redundant parameters in: "); - comment(stdout, t->step->n, 0); - printf("\n"); - } - break; - } - else /* an Unless */ - AST_shouldconsider(a, t->to); - } + if (AST_suspect(t)) + { printf("spin: possibly redundant parameters in: "); + comment(stdout, t->step->n, 0); + printf("\n"); + } + break; + } + else /* an Unless */ + AST_shouldconsider(a, t->to); + } } static int FSM_critical(AST *a, int s) -{ FSM_state *f; - FSM_trans *t; - - /* is a 1-relevant stmnt reachable from this state? */ - - f = fsm_tbl[s]; - if (f->seen) - goto done; - f->seen = 1; - f->cr = 0; - for (t = f->t; t; t = t->nxt) - if ((t->relevant&1) - || FSM_critical(a, t->to)) - { f->cr = 1; - - if (verbose&32) - { printf("\t\t\t\tcritical(%d) ", t->relevant); - comment(stdout, t->step->n, 0); - printf("\n"); - } - break; - } +{ FSM_state *f; + FSM_trans *t; + + /* is a 1-relevant stmnt reachable from this state? */ + + f = fsm_tbl[s]; + if (f->seen) + goto done; + f->seen = 1; + f->cr = 0; + for (t = f->t; t; t = t->nxt) + if ((t->relevant&1) + || FSM_critical(a, t->to)) + { f->cr = 1; + + if (verbose&32) + { printf("\t\t\t\tcritical(%d) ", t->relevant); + comment(stdout, t->step->n, 0); + printf("\n"); + } + break; + } #if 0 - else { - if (verbose&32) - { printf("\t\t\t\tnot-crit "); - comment(stdout, t->step->n, 0); - printf("\n"); - } - } + else { + if (verbose&32) + { printf("\t\t\t\tnot-crit "); + comment(stdout, t->step->n, 0); + printf("\n"); + } + } #endif done: - return f->cr; + return f->cr; } static void AST_ctrl(AST *a) -{ FSM_state *f; - FSM_trans *t; - int hit; - - /* add all blockable transitions - * from which relevant transitions can be reached - */ - if (verbose&32) - printf("CTL -- %s\n", a->p->n->name); - - /* 1 : mark all blockable edges */ - for (f = a->fsm; f; f = f->nxt) - { if (!(f->scratch&2)) /* not part of irrelevant subgraph */ - for (t = f->t; t; t = t->nxt) - { if (t->step && t->step->n) - switch (t->step->n->ntyp) { - case 'r': - case 's': - case 'c': - case ELSE: - t->round = AST_Round; - t->relevant |= 2; /* mark for next phases */ - if (verbose&32) - { printf("\tpremark "); - comment(stdout, t->step->n, 0); - printf("\n"); - } - break; - default: - break; - } } } - - /* 2: keep only 2-marked stmnts from which 1-marked stmnts can be reached */ - for (f = a->fsm; f; f = f->nxt) - { fsm_tbl[f->from] = f; - f->seen = 0; /* used in dfs from FSM_critical */ - } - for (f = a->fsm; f; f = f->nxt) - { if (!FSM_critical(a, f->from)) - for (t = f->t; t; t = t->nxt) - if (t->relevant&2) - { t->relevant &= ~2; /* clear mark */ - if (verbose&32) - { printf("\t\tnomark "); - if (t->step && t->step->n) - comment(stdout, t->step->n, 0); - printf("\n"); - } } } - - /* 3 : lift marks across IF/DO etc. */ - for (f = a->fsm; f; f = f->nxt) - { hit = 0; - for (t = f->t; t; t = t->nxt) - { if (t->step && t->step->n) - switch (t->step->n->ntyp) { - case IF: - case DO: - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - if (AST_blockable(a, t->to)) - hit = 1; - break; - default: - break; - } - else if (AST_blockable(a, t->to)) /* Unless */ - hit = 1; - - if (hit) break; - } - if (hit) /* at least one outgoing trans can block */ - for (t = f->t; t; t = t->nxt) - { t->round = AST_Round; - t->relevant |= 2; /* lift */ - if (verbose&32) - { printf("\t\t\tliftmark "); - if (t->step && t->step->n) - comment(stdout, t->step->n, 0); - printf("\n"); - } - AST_spread(a, t->to); /* and spread to all guards */ - } } - - /* 4: nodes with 2-marked out-edges contribute new slice criteria */ - for (f = a->fsm; f; f = f->nxt) - for (t = f->t; t; t = t->nxt) - if (t->relevant&2) - { AST_shouldconsider(a, f->from); - break; /* inner loop */ - } +{ FSM_state *f; + FSM_trans *t; + int hit; + + /* add all blockable transitions + * from which relevant transitions can be reached + */ + if (verbose&32) + printf("CTL -- %s\n", a->p->n->name); + + /* 1 : mark all blockable edges */ + for (f = a->fsm; f; f = f->nxt) + { if (!(f->scratch&2)) /* not part of irrelevant subgraph */ + for (t = f->t; t; t = t->nxt) + { if (t->step && t->step->n) + switch (t->step->n->ntyp) { + case 'r': + case 's': + case 'c': + case ELSE: + t->round = AST_Round; + t->relevant |= 2; /* mark for next phases */ + if (verbose&32) + { printf("\tpremark "); + comment(stdout, t->step->n, 0); + printf("\n"); + } + break; + default: + break; + } } } + + /* 2: keep only 2-marked stmnts from which 1-marked stmnts can be reached */ + for (f = a->fsm; f; f = f->nxt) + { fsm_tbl[f->from] = f; + f->seen = 0; /* used in dfs from FSM_critical */ + } + for (f = a->fsm; f; f = f->nxt) + { if (!FSM_critical(a, f->from)) + for (t = f->t; t; t = t->nxt) + if (t->relevant&2) + { t->relevant &= ~2; /* clear mark */ + if (verbose&32) + { printf("\t\tnomark "); + if (t->step && t->step->n) + comment(stdout, t->step->n, 0); + printf("\n"); + } } } + + /* 3 : lift marks across IF/DO etc. */ + for (f = a->fsm; f; f = f->nxt) + { hit = 0; + for (t = f->t; t; t = t->nxt) + { if (t->step && t->step->n) + switch (t->step->n->ntyp) { + case IF: + case DO: + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + if (AST_blockable(a, t->to)) + hit = 1; + break; + default: + break; + } + else if (AST_blockable(a, t->to)) /* Unless */ + hit = 1; + + if (hit) break; + } + if (hit) /* at least one outgoing trans can block */ + for (t = f->t; t; t = t->nxt) + { t->round = AST_Round; + t->relevant |= 2; /* lift */ + if (verbose&32) + { printf("\t\t\tliftmark "); + if (t->step && t->step->n) + comment(stdout, t->step->n, 0); + printf("\n"); + } + AST_spread(a, t->to); /* and spread to all guards */ + } } + + /* 4: nodes with 2-marked out-edges contribute new slice criteria */ + for (f = a->fsm; f; f = f->nxt) + for (t = f->t; t; t = t->nxt) + if (t->relevant&2) + { AST_shouldconsider(a, f->from); + break; /* inner loop */ + } } static void AST_control_dep(void) -{ AST *a; +{ AST *a; - for (a = ast; a; a = a->nxt) - { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) - { AST_ctrl(a); - } } + for (a = ast; a; a = a->nxt) + { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) + { AST_ctrl(a); + } } } static void AST_prelabel(void) -{ AST *a; - FSM_state *f; - FSM_trans *t; - - for (a = ast; a; a = a->nxt) - { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) - for (f = a->fsm; f; f = f->nxt) - for (t = f->t; t; t = t->nxt) - { if (t->step - && t->step->n - && t->step->n->ntyp == ASSERT - ) - { t->relevant |= 1; - } } } +{ AST *a; + FSM_state *f; + FSM_trans *t; + + for (a = ast; a; a = a->nxt) + { if (a->p->b != N_CLAIM && a->p->b != E_TRACE && a->p->b != N_TRACE) + for (f = a->fsm; f; f = f->nxt) + for (t = f->t; t; t = t->nxt) + { if (t->step + && t->step->n + && t->step->n->ntyp == ASSERT + ) + { t->relevant |= 1; + } } } } static void AST_criteria(void) -{ /* - * remote labels are handled separately -- by making - * sure they are not pruned away during optimization - */ - AST_Changes = 1; /* to get started */ - for (AST_Round = 1; slicer && AST_Changes; AST_Round++) - { AST_Changes = 0; - AST_data_dep(); - AST_preserve(); /* moves processed vars from slicer to rel_vars */ - AST_dominant(); /* mark data-irrelevant subgraphs */ - AST_control_dep(); /* can add data deps, which add control deps */ - - if (verbose&32) - printf("\n\nROUND %d -- changes %d\n", - AST_Round, AST_Changes); - } +{ /* + * remote labels are handled separately -- by making + * sure they are not pruned away during optimization + */ + AST_Changes = 1; /* to get started */ + for (AST_Round = 1; slicer && AST_Changes; AST_Round++) + { AST_Changes = 0; + AST_data_dep(); + AST_preserve(); /* moves processed vars from slicer to rel_vars */ + AST_dominant(); /* mark data-irrelevant subgraphs */ + AST_control_dep(); /* can add data deps, which add control deps */ + + if (verbose&32) + printf("\n\nROUND %d -- changes %d\n", + AST_Round, AST_Changes); + } } static void -AST_alias_analysis(void) /* aliasing of promela channels */ -{ AST *a; +AST_alias_analysis(void) /* aliasing of promela channels */ +{ AST *a; - for (a = ast; a; a = a->nxt) - AST_sends(a); /* collect chan-names that are send across chans */ + for (a = ast; a; a = a->nxt) + AST_sends(a); /* collect chan-names that are send across chans */ - for (a = ast; a; a = a->nxt) - AST_para(a->p); /* aliasing of chans thru proctype parameters */ + for (a = ast; a; a = a->nxt) + AST_para(a->p); /* aliasing of chans thru proctype parameters */ - for (a = ast; a; a = a->nxt) - AST_other(a); /* chan params in asgns and recvs */ + for (a = ast; a; a = a->nxt) + AST_other(a); /* chan params in asgns and recvs */ - AST_trans(); /* transitive closure of alias table */ + AST_trans(); /* transitive closure of alias table */ - if (verbose&32) - AST_aliases(); /* show channel aliasing info */ + if (verbose&32) + AST_aliases(); /* show channel aliasing info */ } void AST_slice(void) -{ AST *a; - int spurious = 0; - - if (!slicer) - { printf("spin: warning: no slice criteria found (no assertions and no claim)\n"); - spurious = 1; - } - AST_dorelevant(); /* mark procs refered to in remote refs */ - - for (a = ast; a; a = a->nxt) - AST_def_use(a); /* compute standard def/use information */ - - AST_hidden(); /* parameter passing and local var inits */ - - AST_alias_analysis(); /* channel alias analysis */ - - AST_prelabel(); /* mark all 'assert(...)' stmnts as relevant */ - AST_criteria(); /* process the slice criteria from - * asserts and from the never claim - */ - if (!spurious || (verbose&32)) - { spurious = 1; - for (a = ast; a; a = a->nxt) - { AST_dump(a); /* marked up result */ - if (a->relevant&2) /* it printed something */ - spurious = 0; - } - if (!AST_dump_rel() /* relevant variables */ - && spurious) - printf("spin: no redundancies found (for given property)\n"); - } - AST_suggestions(); - - if (verbose&32) - show_expl(); +{ AST *a; + int spurious = 0; + + if (!slicer) + { printf("spin: warning: no slice criteria found (no assertions and no claim)\n"); + spurious = 1; + } + AST_dorelevant(); /* mark procs refered to in remote refs */ + + for (a = ast; a; a = a->nxt) + AST_def_use(a); /* compute standard def/use information */ + + AST_hidden(); /* parameter passing and local var inits */ + + AST_alias_analysis(); /* channel alias analysis */ + + AST_prelabel(); /* mark all 'assert(...)' stmnts as relevant */ + AST_criteria(); /* process the slice criteria from + * asserts and from the never claim + */ + if (!spurious || (verbose&32)) + { spurious = 1; + for (a = ast; a; a = a->nxt) + { AST_dump(a); /* marked up result */ + if (a->relevant&2) /* it printed something */ + spurious = 0; + } + if (!AST_dump_rel() /* relevant variables */ + && spurious) + printf("spin: no redundancies found (for given property)\n"); + } + AST_suggestions(); + + if (verbose&32) + show_expl(); } void AST_store(ProcList *p, int start_state) -{ AST *n_ast; +{ AST *n_ast; - if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) - { n_ast = (AST *) emalloc(sizeof(AST)); - n_ast->p = p; - n_ast->i_st = start_state; - n_ast->relevant = 0; - n_ast->fsm = fsmx; - n_ast->nxt = ast; - ast = n_ast; - } - fsmx = (FSM_state *) 0; /* hide it from FSM_DEL */ + if (p->b != N_CLAIM && p->b != E_TRACE && p->b != N_TRACE) + { n_ast = (AST *) emalloc(sizeof(AST)); + n_ast->p = p; + n_ast->i_st = start_state; + n_ast->relevant = 0; + n_ast->fsm = fsmx; + n_ast->nxt = ast; + ast = n_ast; + } + fsmx = (FSM_state *) 0; /* hide it from FSM_DEL */ } static void AST_add_explicit(Lextok *d, Lextok *u) -{ FSM_trans *e = (FSM_trans *) emalloc(sizeof(FSM_trans)); +{ FSM_trans *e = (FSM_trans *) emalloc(sizeof(FSM_trans)); - e->to = 0; /* or start_state ? */ - e->relevant = 0; /* to be determined */ - e->step = (Element *) 0; /* left blank */ - e->Val[0] = e->Val[1] = (FSM_use *) 0; + e->to = 0; /* or start_state ? */ + e->relevant = 0; /* to be determined */ + e->step = (Element *) 0; /* left blank */ + e->Val[0] = e->Val[1] = (FSM_use *) 0; - cur_t = e; + cur_t = e; - def_use(u, USE); - def_use(d, DEF); + def_use(u, USE); + def_use(d, DEF); - cur_t = (FSM_trans *) 0; + cur_t = (FSM_trans *) 0; - e->nxt = explicit; - explicit = e; + e->nxt = explicit_ptr; + explicit_ptr = e; } static void AST_fp1(char *s, Lextok *t, Lextok *f, int parno) -{ Lextok *v; - int cnt; +{ Lextok *v; + int cnt; - if (!t) return; + if (!t) return; - if (t->ntyp == RUN) - { if (strcmp(t->sym->name, s) == 0) - for (v = t->lft, cnt = 1; v; v = v->rgt, cnt++) - if (cnt == parno) - { AST_add_explicit(f, v->lft); - break; - } - } else - { AST_fp1(s, t->lft, f, parno); - AST_fp1(s, t->rgt, f, parno); - } + if (t->ntyp == RUN) + { if (strcmp(t->sym->name, s) == 0) + for (v = t->lft, cnt = 1; v; v = v->rgt, cnt++) + if (cnt == parno) + { AST_add_explicit(f, v->lft); + break; + } + } else + { AST_fp1(s, t->lft, f, parno); + AST_fp1(s, t->rgt, f, parno); + } } static void AST_mk1(char *s, Lextok *c, int parno) -{ AST *a; - FSM_state *f; - FSM_trans *t; +{ AST *a; + FSM_state *f; + FSM_trans *t; - /* concoct an extra FSM_trans *t with the asgn of - * formal par c to matching actual pars made explicit - */ + /* concoct an extra FSM_trans *t with the asgn of + * formal par c to matching actual pars made explicit + */ - for (a = ast; a; a = a->nxt) /* automata */ - for (f = a->fsm; f; f = f->nxt) /* control states */ - for (t = f->t; t; t = t->nxt) /* transitions */ - { if (t->step) - AST_fp1(s, t->step->n, c, parno); - } + for (a = ast; a; a = a->nxt) /* automata */ + for (f = a->fsm; f; f = f->nxt) /* control states */ + for (t = f->t; t; t = t->nxt) /* transitions */ + { if (t->step) + AST_fp1(s, t->step->n, c, parno); + } } static void -AST_par_init(void) /* parameter passing -- hidden assignments */ -{ AST *a; - Lextok *f, *t, *c; - int cnt; - - for (a = ast; a; a = a->nxt) - { if (a->p->b == N_CLAIM || a->p->b == I_PROC - || a->p->b == E_TRACE || a->p->b == N_TRACE) - { continue; /* has no params */ - } - cnt = 0; - for (f = a->p->p; f; f = f->rgt) /* types */ - for (t = f->lft; t; t = t->rgt) /* formals */ - { cnt++; /* formal par count */ - c = (t->ntyp != ',')? t : t->lft; /* the formal parameter */ - AST_mk1(a->p->n->name, c, cnt); /* all matching run statements */ - } } +AST_par_init(void) /* parameter passing -- hidden assignments */ +{ AST *a; + Lextok *f, *t, *c; + int cnt; + + for (a = ast; a; a = a->nxt) + { if (a->p->b == N_CLAIM || a->p->b == I_PROC + || a->p->b == E_TRACE || a->p->b == N_TRACE) + { continue; /* has no params */ + } + cnt = 0; + for (f = a->p->p; f; f = f->rgt) /* types */ + for (t = f->lft; t; t = t->rgt) /* formals */ + { cnt++; /* formal par count */ + c = (t->ntyp != ',')? t : t->lft; /* the formal parameter */ + AST_mk1(a->p->n->name, c, cnt); /* all matching run statements */ + } } } static void -AST_var_init(void) /* initialized vars (not chans) - hidden assignments */ -{ Ordered *walk; - Lextok *x; - Symbol *sp; - AST *a; - - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp - && !sp->context /* globals */ - && sp->type != PROCTYPE - && sp->ini - && (sp->type != MTYPE || sp->ini->ntyp != CONST) /* not mtype defs */ - && sp->ini->ntyp != CHAN) - { x = nn(ZN, TYPE, ZN, ZN); - x->sym = sp; - AST_add_explicit(x, sp->ini); - } } - - for (a = ast; a; a = a->nxt) - { if (a->p->b != N_CLAIM - && a->p->b != E_TRACE && a->p->b != N_TRACE) /* has no locals */ - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp - && sp->context - && strcmp(sp->context->name, a->p->n->name) == 0 - && sp->Nid >= 0 /* not a param */ - && sp->type != LABEL - && sp->ini - && sp->ini->ntyp != CHAN) - { x = nn(ZN, TYPE, ZN, ZN); - x->sym = sp; - AST_add_explicit(x, sp->ini); - } } } +AST_var_init(void) /* initialized vars (not chans) - hidden assignments */ +{ Ordered *walk; + Lextok *x; + Symbol *sp; + AST *a; + + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp + && !sp->context /* globals */ + && sp->type != PROCTYPE + && sp->ini + && (sp->type != MTYPE || sp->ini->ntyp != CONST) /* not mtype defs */ + && sp->ini->ntyp != CHAN) + { x = nn(ZN, TYPE, ZN, ZN); + x->sym = sp; + AST_add_explicit(x, sp->ini); + } } + + for (a = ast; a; a = a->nxt) + { if (a->p->b != N_CLAIM + && a->p->b != E_TRACE && a->p->b != N_TRACE) /* has no locals */ + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp + && sp->context + && strcmp(sp->context->name, a->p->n->name) == 0 + && sp->Nid >= 0 /* not a param */ + && sp->type != LABEL + && sp->ini + && sp->ini->ntyp != CHAN) + { x = nn(ZN, TYPE, ZN, ZN); + x->sym = sp; + AST_add_explicit(x, sp->ini); + } } } } static void show_expl(void) -{ FSM_trans *t, *T; - FSM_use *u; - - printf("\nExplicit List:\n"); - for (T = expl_par; T; T = (T == expl_par)?expl_var: (FSM_trans *) 0) - { for (t = T; t; t = t->nxt) - { if (!t->Val[0]) continue; - printf("%s", t->relevant?"*":" "); - printf("%3d", t->round); - for (u = t->Val[0]; u; u = u->nxt) - { printf("\t<"); - AST_var(u->n, u->n->sym, 1); - printf(":%d>, ", u->special); - } - printf("\n"); - } - printf("==\n"); - } - printf("End\n"); +{ FSM_trans *t, *T; + FSM_use *u; + + printf("\nExplicit List:\n"); + for (T = expl_par; T; T = (T == expl_par)?expl_var: (FSM_trans *) 0) + { for (t = T; t; t = t->nxt) + { if (!t->Val[0]) continue; + printf("%s", t->relevant?"*":" "); + printf("%3d", t->round); + for (u = t->Val[0]; u; u = u->nxt) + { printf("\t<"); + AST_var(u->n, u->n->sym, 1); + printf(":%d>, ", u->special); + } + printf("\n"); + } + printf("==\n"); + } + printf("End\n"); } static void -AST_hidden(void) /* reveal all hidden assignments */ +AST_hidden(void) /* reveal all hidden assignments */ { - AST_par_init(); - expl_par = explicit; - explicit = (FSM_trans *) 0; + AST_par_init(); + expl_par = explicit_ptr; + explicit_ptr = (FSM_trans *) 0; - AST_var_init(); - expl_var = explicit; - explicit = (FSM_trans *) 0; + AST_var_init(); + expl_var = explicit_ptr; + explicit_ptr = (FSM_trans *) 0; } -#define BPW (8*sizeof(ulong)) /* bits per word */ +#define BPW (8*sizeof(ulong)) /* bits per word */ static int bad_scratch(FSM_state *f, int upto) -{ FSM_trans *t; +{ FSM_trans *t; #if 0 - 1. all internal branch-points have else-s - 2. all non-branchpoints have non-blocking out-edge - 3. all internal edges are non-relevant - subgraphs like this need NOT contribute control-dependencies + 1. all internal branch-points have else-s + 2. all non-branchpoints have non-blocking out-edge + 3. all internal edges are non-relevant + subgraphs like this need NOT contribute control-dependencies #endif - if (!f->seen - || (f->scratch&4)) - return 0; + if (!f->seen + || (f->scratch&4)) + return 0; - if (f->scratch&8) - return 1; + if (f->scratch&8) + return 1; - f->scratch |= 4; + f->scratch |= 4; - if (verbose&32) printf("X[%d:%d:%d] ", f->from, upto, f->scratch); + if (verbose&32) printf("X[%d:%d:%d] ", f->from, upto, f->scratch); - if (f->scratch&1) - { if (verbose&32) - printf("\tbad scratch: %d\n", f->from); -bad: f->scratch &= ~4; - /* f->scratch |= 8; wrong */ - return 1; - } + if (f->scratch&1) + { if (verbose&32) + printf("\tbad scratch: %d\n", f->from); +bad: f->scratch &= ~4; + /* f->scratch |= 8; wrong */ + return 1; + } - if (f->from != upto) - for (t = f->t; t; t = t->nxt) - if (bad_scratch(fsm_tbl[t->to], upto)) - goto bad; + if (f->from != upto) + for (t = f->t; t; t = t->nxt) + if (bad_scratch(fsm_tbl[t->to], upto)) + goto bad; - return 0; + return 0; } static void mark_subgraph(FSM_state *f, int upto) -{ FSM_trans *t; +{ FSM_trans *t; - if (f->from == upto - || !f->seen - || (f->scratch&2)) - return; + if (f->from == upto + || !f->seen + || (f->scratch&2)) + return; - f->scratch |= 2; + f->scratch |= 2; - for (t = f->t; t; t = t->nxt) - mark_subgraph(fsm_tbl[t->to], upto); + for (t = f->t; t; t = t->nxt) + mark_subgraph(fsm_tbl[t->to], upto); } static void AST_pair(AST *a, FSM_state *h, int y) -{ Pair *p; +{ Pair *p; - for (p = a->pairs; p; p = p->nxt) - if (p->h == h - && p->b == y) - return; + for (p = a->pairs; p; p = p->nxt) + if (p->h == h + && p->b == y) + return; - p = (Pair *) emalloc(sizeof(Pair)); - p->h = h; - p->b = y; - p->nxt = a->pairs; - a->pairs = p; + p = (Pair *) emalloc(sizeof(Pair)); + p->h = h; + p->b = y; + p->nxt = a->pairs; + a->pairs = p; } static void AST_checkpairs(AST *a) -{ Pair *p; +{ Pair *p; - for (p = a->pairs; p; p = p->nxt) - { if (verbose&32) - printf(" inspect pair %d %d\n", p->b, p->h->from); - if (!bad_scratch(p->h, p->b)) /* subgraph is clean */ - { if (verbose&32) - printf("subgraph: %d .. %d\n", p->b, p->h->from); - mark_subgraph(p->h, p->b); - } - } + for (p = a->pairs; p; p = p->nxt) + { if (verbose&32) + printf(" inspect pair %d %d\n", p->b, p->h->from); + if (!bad_scratch(p->h, p->b)) /* subgraph is clean */ + { if (verbose&32) + printf("subgraph: %d .. %d\n", p->b, p->h->from); + mark_subgraph(p->h, p->b); + } + } } static void subgraph(AST *a, FSM_state *f, int out) -{ FSM_state *h; - int i, j; - ulong *g; +{ FSM_state *h; + int i, j; + ulong *g; #if 0 - reverse dominance suggests that this is a possible - entry and exit node for a proper subgraph + reverse dominance suggests that this is a possible + entry and exit node for a proper subgraph #endif - h = fsm_tbl[out]; + h = fsm_tbl[out]; - i = f->from / BPW; - j = f->from % BPW; /* assert(j <= 32); else lshift undefined? */ - g = h->mod; + i = f->from / BPW; + j = f->from % BPW; /* assert(j <= 32); else lshift undefined? */ + g = h->mod; - if (verbose&32) - printf("possible pair %d %d -- %d\n", - f->from, h->from, (g[i]&(1<from); /* record this pair */ + if (verbose&32) + printf("possible pair %d %d -- %d\n", + f->from, h->from, (g[i]&(1<from); /* record this pair */ } static void act_dom(AST *a) -{ FSM_state *f; - FSM_trans *t; - int i, j, cnt; +{ FSM_state *f; + FSM_trans *t; + int i, j, cnt; - for (f = a->fsm; f; f = f->nxt) - { if (!f->seen) continue; + for (f = a->fsm; f; f = f->nxt) + { if (!f->seen) continue; #if 0 - f->from is the exit-node of a proper subgraph, with - the dominator its entry-node, if: - a. this node has more than 1 reachable predecessor - b. the dominator has more than 1 reachable successor - (need reachability - in case of reverse dominance) - d. the dominator is reachable, and not equal to this node + f->from is the exit-node of a proper subgraph, with + the dominator its entry-node, if: + a. this node has more than 1 reachable predecessor + b. the dominator has more than 1 reachable successor + (need reachability - in case of reverse dominance) + d. the dominator is reachable, and not equal to this node #endif - for (t = f->p, i = 0; t; t = t->nxt) - { i += fsm_tbl[t->to]->seen; - } - if (i <= 1) - { continue; /* a. */ - } - for (cnt = 1; cnt < a->nstates; cnt++) /* 0 is endstate */ - { if (cnt == f->from - || !fsm_tbl[cnt]->seen) - { continue; /* c. */ - } - i = cnt / BPW; - j = cnt % BPW; /* assert(j <= 32); */ - if (!(f->dom[i]&(1<t, i = 0; t; t = t->nxt) - { i += fsm_tbl[t->to]->seen; - } - if (i <= 1) - { continue; /* b. */ - } - if (f->mod) /* final check in 2nd phase */ - { subgraph(a, f, cnt); /* possible entry-exit pair */ - } } } + for (t = f->p, i = 0; t; t = t->nxt) + { i += fsm_tbl[t->to]->seen; + } + if (i <= 1) + { continue; /* a. */ + } + for (cnt = 1; cnt < a->nstates; cnt++) /* 0 is endstate */ + { if (cnt == f->from + || !fsm_tbl[cnt]->seen) + { continue; /* c. */ + } + i = cnt / BPW; + j = cnt % BPW; /* assert(j <= 32); */ + if (!(f->dom[i]&(1<t, i = 0; t; t = t->nxt) + { i += fsm_tbl[t->to]->seen; + } + if (i <= 1) + { continue; /* b. */ + } + if (f->mod) /* final check in 2nd phase */ + { subgraph(a, f, cnt); /* possible entry-exit pair */ + } } } } static void reachability(AST *a) -{ FSM_state *f; +{ FSM_state *f; - for (f = a->fsm; f; f = f->nxt) - f->seen = 0; /* clear */ - AST_dfs(a, a->i_st, 0); /* mark 'seen' */ + for (f = a->fsm; f; f = f->nxt) + f->seen = 0; /* clear */ + AST_dfs(a, a->i_st, 0); /* mark 'seen' */ } static int see_else(FSM_state *f) -{ FSM_trans *t; - - for (t = f->t; t; t = t->nxt) - { if (t->step - && t->step->n) - switch (t->step->n->ntyp) { - case ELSE: - return 1; - case IF: - case DO: - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - if (see_else(fsm_tbl[t->to])) - return 1; - default: - break; - } - } - return 0; +{ FSM_trans *t; + + for (t = f->t; t; t = t->nxt) + { if (t->step + && t->step->n) + switch (t->step->n->ntyp) { + case ELSE: + return 1; + case IF: + case DO: + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + if (see_else(fsm_tbl[t->to])) + return 1; + default: + break; + } + } + return 0; } static int is_guard(FSM_state *f) -{ FSM_state *g; - FSM_trans *t; - - for (t = f->p; t; t = t->nxt) - { g = fsm_tbl[t->to]; - if (!g->seen) - continue; - - if (t->step - && t->step->n) - switch(t->step->n->ntyp) { - case IF: - case DO: - return 1; - case ATOMIC: - case NON_ATOMIC: - case D_STEP: - if (is_guard(g)) - return 1; - default: - break; - } - } - return 0; +{ FSM_state *g; + FSM_trans *t; + + for (t = f->p; t; t = t->nxt) + { g = fsm_tbl[t->to]; + if (!g->seen) + continue; + + if (t->step + && t->step->n) + switch(t->step->n->ntyp) { + case IF: + case DO: + return 1; + case ATOMIC: + case NON_ATOMIC: + case D_STEP: + if (is_guard(g)) + return 1; + default: + break; + } + } + return 0; } static void curtail(AST *a) -{ FSM_state *f, *g; - FSM_trans *t; - int i, haselse, isrel, blocking; +{ FSM_state *f, *g; + FSM_trans *t; + int i, haselse, isrel, blocking; #if 0 - mark nodes that do not satisfy these requirements: - 1. all internal branch-points have else-s - 2. all non-branchpoints have non-blocking out-edge - 3. all internal edges are non-data-relevant + mark nodes that do not satisfy these requirements: + 1. all internal branch-points have else-s + 2. all non-branchpoints have non-blocking out-edge + 3. all internal edges are non-data-relevant #endif - if (verbose&32) - printf("Curtail %s:\n", a->p->n->name); - - for (f = a->fsm; f; f = f->nxt) - { if (!f->seen - || (f->scratch&(1|2))) - continue; - - isrel = haselse = i = blocking = 0; - - for (t = f->t; t; t = t->nxt) - { g = fsm_tbl[t->to]; - - isrel |= (t->relevant&1); /* data relevant */ - i += g->seen; - - if (t->step - && t->step->n) - { switch (t->step->n->ntyp) { - case IF: - case DO: - haselse |= see_else(g); - break; - case 'c': - case 's': - case 'r': - blocking = 1; - break; - } } } + if (verbose&32) + printf("Curtail %s:\n", a->p->n->name); + + for (f = a->fsm; f; f = f->nxt) + { if (!f->seen + || (f->scratch&(1|2))) + continue; + + isrel = haselse = i = blocking = 0; + + for (t = f->t; t; t = t->nxt) + { g = fsm_tbl[t->to]; + + isrel |= (t->relevant&1); /* data relevant */ + i += g->seen; + + if (t->step + && t->step->n) + { switch (t->step->n->ntyp) { + case IF: + case DO: + haselse |= see_else(g); + break; + case 'c': + case 's': + case 'r': + blocking = 1; + break; + } } } #if 0 - if (verbose&32) - printf("prescratch %d -- %d %d %d %d -- %d\n", - f->from, i, isrel, blocking, haselse, is_guard(f)); + if (verbose&32) + printf("prescratch %d -- %d %d %d %d -- %d\n", + f->from, i, isrel, blocking, haselse, is_guard(f)); #endif - if (isrel /* 3. */ - || (i == 1 && blocking) /* 2. */ - || (i > 1 && !haselse)) /* 1. */ - { if (!is_guard(f)) - { f->scratch |= 1; - if (verbose&32) - printf("scratch %d -- %d %d %d %d\n", - f->from, i, isrel, blocking, haselse); - } - } - } + if (isrel /* 3. */ + || (i == 1 && blocking) /* 2. */ + || (i > 1 && !haselse)) /* 1. */ + { if (!is_guard(f)) + { f->scratch |= 1; + if (verbose&32) + printf("scratch %d -- %d %d %d %d\n", + f->from, i, isrel, blocking, haselse); + } + } + } } static void init_dom(AST *a) -{ FSM_state *f; - int i, j, cnt; +{ FSM_state *f; + int i, j, cnt; #if 0 - (1) D(s0) = {s0} - (2) for s in S - {s0} do D(s) = S + (1) D(s0) = {s0} + (2) for s in S - {s0} do D(s) = S #endif - for (f = a->fsm; f; f = f->nxt) - { if (!f->seen) continue; - - f->dom = (ulong *) emalloc(a->nwords * sizeof(ulong)); - - if (f->from == a->i_st) - { i = a->i_st / BPW; - j = a->i_st % BPW; /* assert(j <= 32); */ - f->dom[i] = (1<nwords; i++) - { f->dom[i] = (ulong) ~0; /* all 1's */ - } - if (a->nstates % BPW) - for (i = (a->nstates % BPW); i < (int) BPW; i++) - { f->dom[a->nwords-1] &= ~(1<< ((ulong) i)); /* clear tail */ - } - for (cnt = 0; cnt < a->nstates; cnt++) - { if (!fsm_tbl[cnt]->seen) - { i = cnt / BPW; - j = cnt % BPW; /* assert(j <= 32); */ - f->dom[i] &= ~(1<< ((ulong) j)); - } } } } + for (f = a->fsm; f; f = f->nxt) + { if (!f->seen) continue; + + f->dom = (ulong *) emalloc(a->nwords * sizeof(ulong)); + + if (f->from == a->i_st) + { i = a->i_st / BPW; + j = a->i_st % BPW; /* assert(j <= 32); */ + f->dom[i] = (1<nwords; i++) + { f->dom[i] = (ulong) ~0; /* all 1's */ + } + if (a->nstates % BPW) + for (i = (a->nstates % BPW); i < (int) BPW; i++) + { f->dom[a->nwords-1] &= ~(1<< ((ulong) i)); /* clear tail */ + } + for (cnt = 0; cnt < a->nstates; cnt++) + { if (!fsm_tbl[cnt]->seen) + { i = cnt / BPW; + j = cnt % BPW; /* assert(j <= 32); */ + f->dom[i] &= ~(1<< ((ulong) j)); + } } } } } static int dom_perculate(AST *a, FSM_state *f) -{ static ulong *ndom = (ulong *) 0; - static int on = 0; - int i, j, cnt = 0; - FSM_state *g; - FSM_trans *t; +{ static ulong *ndom = (ulong *) 0; + static int on = 0; + int i, j, cnt = 0; + FSM_state *g; + FSM_trans *t; - if (on < a->nwords) - { on = a->nwords; - ndom = (ulong *) - emalloc(on * sizeof(ulong)); - } + if (on < a->nwords) + { on = a->nwords; + ndom = (ulong *) + emalloc(on * sizeof(ulong)); + } - for (i = 0; i < a->nwords; i++) - ndom[i] = (ulong) ~0; + for (i = 0; i < a->nwords; i++) + ndom[i] = (ulong) ~0; - for (t = f->p; t; t = t->nxt) /* all reachable predecessors */ - { g = fsm_tbl[t->to]; - if (g->seen) - for (i = 0; i < a->nwords; i++) - ndom[i] &= g->dom[i]; /* (5b) */ - } + for (t = f->p; t; t = t->nxt) /* all reachable predecessors */ + { g = fsm_tbl[t->to]; + if (g->seen) + for (i = 0; i < a->nwords; i++) + ndom[i] &= g->dom[i]; /* (5b) */ + } - i = f->from / BPW; - j = f->from % BPW; /* assert(j <= 32); */ - ndom[i] |= (1<from / BPW; + j = f->from % BPW; /* assert(j <= 32); */ + ndom[i] |= (1<nwords; i++) - if (f->dom[i] != ndom[i]) - { cnt++; - f->dom[i] = ndom[i]; - } + for (i = 0; i < a->nwords; i++) + if (f->dom[i] != ndom[i]) + { cnt++; + f->dom[i] = ndom[i]; + } - return cnt; + return cnt; } static void dom_forward(AST *a) -{ FSM_state *f; - int cnt; +{ FSM_state *f; + int cnt; - init_dom(a); /* (1,2) */ - do { - cnt = 0; - for (f = a->fsm; f; f = f->nxt) - { if (f->seen - && f->from != a->i_st) /* (4) */ - cnt += dom_perculate(a, f); /* (5) */ - } - } while (cnt); /* (3) */ - dom_perculate(a, fsm_tbl[a->i_st]); + init_dom(a); /* (1,2) */ + do { + cnt = 0; + for (f = a->fsm; f; f = f->nxt) + { if (f->seen + && f->from != a->i_st) /* (4) */ + cnt += dom_perculate(a, f); /* (5) */ + } + } while (cnt); /* (3) */ + dom_perculate(a, fsm_tbl[a->i_st]); } static void AST_dominant(void) -{ FSM_state *f; - FSM_trans *t; - AST *a; - int oi; - static FSM_state no_state; +{ FSM_state *f; + FSM_trans *t; + AST *a; + int oi; + static FSM_state no_state; #if 0 - find dominators - Aho, Sethi, & Ullman, Compilers - principles, techniques, and tools - Addison-Wesley, 1986, p.671. + find dominators + Aho, Sethi, & Ullman, Compilers - principles, techniques, and tools + Addison-Wesley, 1986, p.671. - (1) D(s0) = {s0} - (2) for s in S - {s0} do D(s) = S + (1) D(s0) = {s0} + (2) for s in S - {s0} do D(s) = S - (3) while any D(s) changes do - (4) for s in S - {s0} do - (5) D(s) = {s} union with intersection of all D(p) - where p are the immediate predecessors of s + (3) while any D(s) changes do + (4) for s in S - {s0} do + (5) D(s) = {s} union with intersection of all D(p) + where p are the immediate predecessors of s - the purpose is to find proper subgraphs - (one entry node, one exit node) + the purpose is to find proper subgraphs + (one entry node, one exit node) #endif - if (AST_Round == 1) /* computed once, reused in every round */ - for (a = ast; a; a = a->nxt) - { a->nstates = 0; - for (f = a->fsm; f; f = f->nxt) - { a->nstates++; /* count */ - fsm_tbl[f->from] = f; /* fast lookup */ - f->scratch = 0; /* clear scratch marks */ - } - for (oi = 0; oi < a->nstates; oi++) - if (!fsm_tbl[oi]) - fsm_tbl[oi] = &no_state; - - a->nwords = (a->nstates + BPW - 1) / BPW; /* round up */ - - if (verbose&32) - { printf("%s (%d): ", a->p->n->name, a->i_st); - printf("states=%d (max %d), words = %d, bpw %d, overflow %d\n", - a->nstates, o_max, a->nwords, - (int) BPW, (int) (a->nstates % BPW)); - } - - reachability(a); - dom_forward(a); /* forward dominance relation */ - - curtail(a); /* mark ineligible edges */ - for (f = a->fsm; f; f = f->nxt) - { t = f->p; - f->p = f->t; - f->t = t; /* invert edges */ - - f->mod = f->dom; - f->dom = (ulong *) 0; - } - oi = a->i_st; - if (fsm_tbl[0]->seen) /* end-state reachable - else leave it */ - a->i_st = 0; /* becomes initial state */ - - dom_forward(a); /* reverse dominance -- don't redo reachability! */ - act_dom(a); /* mark proper subgraphs, if any */ - AST_checkpairs(a); /* selectively place 2 scratch-marks */ - - for (f = a->fsm; f; f = f->nxt) - { t = f->p; - f->p = f->t; - f->t = t; /* restore */ - } - a->i_st = oi; /* restore */ - } else - for (a = ast; a; a = a->nxt) - { for (f = a->fsm; f; f = f->nxt) - { fsm_tbl[f->from] = f; - f->scratch &= 1; /* preserve 1-marks */ - } - for (oi = 0; oi < a->nstates; oi++) - if (!fsm_tbl[oi]) - fsm_tbl[oi] = &no_state; - - curtail(a); /* mark ineligible edges */ - - for (f = a->fsm; f; f = f->nxt) - { t = f->p; - f->p = f->t; - f->t = t; /* invert edges */ - } - - AST_checkpairs(a); /* recompute 2-marks */ - - for (f = a->fsm; f; f = f->nxt) - { t = f->p; - f->p = f->t; - f->t = t; /* restore */ - } } + if (AST_Round == 1) /* computed once, reused in every round */ + for (a = ast; a; a = a->nxt) + { a->nstates = 0; + for (f = a->fsm; f; f = f->nxt) + { a->nstates++; /* count */ + fsm_tbl[f->from] = f; /* fast lookup */ + f->scratch = 0; /* clear scratch marks */ + } + for (oi = 0; oi < a->nstates; oi++) + if (!fsm_tbl[oi]) + fsm_tbl[oi] = &no_state; + + a->nwords = (a->nstates + BPW - 1) / BPW; /* round up */ + + if (verbose&32) + { printf("%s (%d): ", a->p->n->name, a->i_st); + printf("states=%d (max %d), words = %d, bpw %d, overflow %d\n", + a->nstates, o_max, a->nwords, + (int) BPW, (int) (a->nstates % BPW)); + } + + reachability(a); + dom_forward(a); /* forward dominance relation */ + + curtail(a); /* mark ineligible edges */ + for (f = a->fsm; f; f = f->nxt) + { t = f->p; + f->p = f->t; + f->t = t; /* invert edges */ + + f->mod = f->dom; + f->dom = (ulong *) 0; + } + oi = a->i_st; + if (fsm_tbl[0]->seen) /* end-state reachable - else leave it */ + a->i_st = 0; /* becomes initial state */ + + dom_forward(a); /* reverse dominance -- don't redo reachability! */ + act_dom(a); /* mark proper subgraphs, if any */ + AST_checkpairs(a); /* selectively place 2 scratch-marks */ + + for (f = a->fsm; f; f = f->nxt) + { t = f->p; + f->p = f->t; + f->t = t; /* restore */ + } + a->i_st = oi; /* restore */ + } else + for (a = ast; a; a = a->nxt) + { for (f = a->fsm; f; f = f->nxt) + { fsm_tbl[f->from] = f; + f->scratch &= 1; /* preserve 1-marks */ + } + for (oi = 0; oi < a->nstates; oi++) + if (!fsm_tbl[oi]) + fsm_tbl[oi] = &no_state; + + curtail(a); /* mark ineligible edges */ + + for (f = a->fsm; f; f = f->nxt) + { t = f->p; + f->p = f->t; + f->t = t; /* invert edges */ + } + + AST_checkpairs(a); /* recompute 2-marks */ + + for (f = a->fsm; f; f = f->nxt) + { t = f->p; + f->p = f->t; + f->t = t; /* restore */ + } } } diff --git a/Src/pangen7.c b/Src/pangen7.c index b6b492e..d35a63c 100644 --- a/Src/pangen7.c +++ b/Src/pangen7.c @@ -6,16 +6,16 @@ * Tool documentation is available at http://spinroot.com */ +#include "spin.h" /* include this first for strdup & getline */ #include #include -#include "spin.h" #include "y.tab.h" #include #ifndef PC #include #endif -extern ProcList *ready; +extern ProcList *ready; extern Element *Al_El; extern int nclaims, verbose, Strict; extern short has_accept; @@ -27,253 +27,253 @@ typedef struct State_Stack State_Stack; typedef struct Guard Guard; struct Succ_List { - SQueue *s; - Succ_List *nxt; + SQueue *s; + Succ_List *nxt; }; struct OneState { - int *combo; /* the combination of claim states */ - Succ_List *succ; /* list of ptrs to immediate successor states */ + int *combo; /* the combination of claim states */ + Succ_List *succ; /* list of ptrs to immediate successor states */ }; struct SQueue { - OneState state; - SQueue *nxt; + OneState state; + SQueue *nxt; }; struct State_Stack { - int *n; - State_Stack *nxt; + int *n; + State_Stack *nxt; }; struct Guard { - Lextok *t; - Guard *nxt; + Lextok *t; + Guard *nxt; }; -static SQueue *sq, *sd, *render; /* states move from sq to sd to render to holding */ -static SQueue *holding, *lasthold; +static SQueue *sq, *sd, *render; /* states move from sq to sd to render to holding */ +static SQueue *holding, *lasthold; static State_Stack *dsts; -static int nst; /* max nr of states in claims */ -static int *Ist; /* initial states */ -static int *Nacc; /* number of accept states in claim */ -static int *Nst; /* next states */ -static int **reached; /* n claims x states */ -static int unfolding; /* to make sure all accept states are reached */ -static int is_accept; /* remember if the current state is accepting in any claim */ +static int nst; /* max nr of states in claims */ +static int *Ist; /* initial states */ +static int *Nacc; /* number of accept states in claim */ +static int *Nst; /* next states */ +static int **reached; /* n claims x states */ +static int unfolding; /* to make sure all accept states are reached */ +static int is_accept; /* remember if the current state is accepting in any claim */ static int not_printing; /* set during explore_product */ -static Element ****matrix; /* n x two-dimensional arrays state x state */ -static Element **Selfs; /* self-loop states at end of claims */ +static Element ****matrix; /* n x two-dimensional arrays state x state */ +static Element **Selfs; /* self-loop states at end of claims */ static void get_seq(int, Sequence *); static void set_el(int n, Element *e); static void gen_product(void); -static void print_state_nm(char *, int *, char *); +static void print_state_nm(const char *, const int *, const char *); static SQueue *find_state(int *); static SQueue *retrieve_state(int *); static int same_state(int *a, int *b) -{ int i; +{ int i; - for (i = 0; i < nclaims; i++) - { if (a[i] != b[i]) - { return 0; - } } - return 1; + for (i = 0; i < nclaims; i++) + { if (a[i] != b[i]) + { return 0; + } } + return 1; } static int in_stack(SQueue *s, SQueue *in) -{ SQueue *q; +{ SQueue *q; - for (q = in; q; q = q->nxt) - { if (same_state(q->state.combo, s->state.combo)) - { return 1; - } } - return 0; + for (q = in; q; q = q->nxt) + { if (same_state(q->state.combo, s->state.combo)) + { return 1; + } } + return 0; } static void to_render(SQueue *s) -{ SQueue *a, *q, *last; /* find in sd/sq and move to render, if not already there */ - int n; - - for (n = 0; n < nclaims; n++) - { reached[n][ s->state.combo[n] ] |= 2; - } - - for (q = render; q; q = q->nxt) - { if (same_state(q->state.combo, s->state.combo)) - { return; - } } - for (q = holding; q; q = q->nxt) - { if (same_state(q->state.combo, s->state.combo)) - { return; - } } - - a = sd; +{ SQueue *a, *q, *last; /* find in sd/sq and move to render, if not already there */ + int n; + + for (n = 0; n < nclaims; n++) + { reached[n][ s->state.combo[n] ] |= 2; + } + + for (q = render; q; q = q->nxt) + { if (same_state(q->state.combo, s->state.combo)) + { return; + } } + for (q = holding; q; q = q->nxt) + { if (same_state(q->state.combo, s->state.combo)) + { return; + } } + + a = sd; more: - for (q = a, last = 0; q; last = q, q = q->nxt) - { if (same_state(q->state.combo, s->state.combo)) - { if (!last) - { if (a == sd) - { sd = q->nxt; - } else if (a == sq) - { sq = q->nxt; - } else - { holding = q->nxt; - } - } else - { last->nxt = q->nxt; - } - q->nxt = render; - render = q; - return; - } } - if (verbose) - { print_state_nm("looking for: ", s->state.combo, "\n"); - } - (void) find_state(s->state.combo); /* creates it in sq */ - if (a != sq) - { a = sq; - goto more; - } - fatal("cannot happen, to_render", 0); + for (q = a, last = 0; q; last = q, q = q->nxt) + { if (same_state(q->state.combo, s->state.combo)) + { if (!last) + { if (a == sd) + { sd = q->nxt; + } else if (a == sq) + { sq = q->nxt; + } else + { holding = q->nxt; + } + } else + { last->nxt = q->nxt; + } + q->nxt = render; + render = q; + return; + } } + if (verbose) + { print_state_nm("looking for: ", s->state.combo, "\n"); + } + (void) find_state(s->state.combo); /* creates it in sq */ + if (a != sq) + { a = sq; + goto more; + } + fatal("cannot happen, to_render", 0); } static void -wrap_text(char *pre, Lextok *t, char *post) +wrap_text(const char *pre, Lextok *t, const char *post) { - printf(pre, (char *) 0); - comment(stdout, t, 0); - printf(post, (char *) 0); + printf(pre, (char *) 0); + comment(stdout, t, 0); + printf(post, (char *) 0); } static State_Stack * push_dsts(int *n) -{ State_Stack *s; - int i; - - for (s = dsts; s; s = s->nxt) - { if (same_state(s->n, n)) - { if (verbose&64) - { printf("\n"); - for (s = dsts; s; s = s->nxt) - { print_state_nm("\t", s->n, "\n"); - } - print_state_nm("\t", n, "\n"); - } - return s; - } } - - s = (State_Stack *) emalloc(sizeof(State_Stack)); - s->n = (int *) emalloc(nclaims * sizeof(int)); - for (i = 0; i < nclaims; i++) - s->n[i] = n[i]; - s->nxt = dsts; - dsts = s; - return 0; +{ State_Stack *s; + int i; + + for (s = dsts; s; s = s->nxt) + { if (same_state(s->n, n)) + { if (verbose&64) + { printf("\n"); + for (s = dsts; s; s = s->nxt) + { print_state_nm("\t", s->n, "\n"); + } + print_state_nm("\t", n, "\n"); + } + return s; + } } + + s = (State_Stack *) emalloc(sizeof(State_Stack)); + s->n = (int *) emalloc(nclaims * sizeof(int)); + for (i = 0; i < nclaims; i++) + s->n[i] = n[i]; + s->nxt = dsts; + dsts = s; + return 0; } static void pop_dsts(void) { - assert(dsts != NULL); - dsts = dsts->nxt; + assert(dsts != NULL); + dsts = dsts->nxt; } static void complete_transition(Succ_List *sl, Guard *g) -{ Guard *w; - int cnt = 0; - - printf(" :: "); - for (w = g; w; w = w->nxt) - { if (w->t->ntyp == CONST - && w->t->val == 1) - { continue; - } else if (w->t->ntyp == 'c' - && w->t->lft->ntyp == CONST - && w->t->lft->val == 1) - { continue; /* 'true' */ - } - - if (cnt > 0) - { printf(" && "); - } - wrap_text("", w->t, ""); - cnt++; - } - if (cnt == 0) - { printf("true"); - } - print_state_nm(" -> goto ", sl->s->state.combo, ""); - - if (is_accept > 0) - { printf("_U%d\n", (unfolding+1)%nclaims); - } else - { printf("_U%d\n", unfolding); - } +{ Guard *w; + int cnt = 0; + + printf(" :: "); + for (w = g; w; w = w->nxt) + { if (w->t->ntyp == CONST + && w->t->val == 1) + { continue; + } else if (w->t->ntyp == 'c' + && w->t->lft->ntyp == CONST + && w->t->lft->val == 1) + { continue; /* 'true' */ + } + + if (cnt > 0) + { printf(" && "); + } + wrap_text("", w->t, ""); + cnt++; + } + if (cnt == 0) + { printf("true"); + } + print_state_nm(" -> goto ", sl->s->state.combo, ""); + + if (is_accept > 0) + { printf("_U%d\n", (unfolding+1)%nclaims); + } else + { printf("_U%d\n", unfolding); + } } static void state_body(OneState *s, Guard *guard) -{ Succ_List *sl; - State_Stack *y; - Guard *g; - int i, once; - - for (sl = s->succ; sl; sl = sl->nxt) - { once = 0; - - for (i = 0; i < nclaims; i++) - { Element *e; - e = matrix[i][s->combo[i]][sl->s->state.combo[i]]; - - /* if one of the claims has a DO or IF move - then pull its target state forward, once - */ - - if (!e - || e->n->ntyp == NON_ATOMIC - || e->n->ntyp == DO - || e->n->ntyp == IF) - { s = &(sl->s->state); - y = push_dsts(s->combo); - if (!y) - { if (once++ == 0) - { assert(s->succ != NULL); - state_body(s, guard); - } - pop_dsts(); - } else if (!y->nxt) /* self-loop transition */ - { if (!not_printing) printf(" /* self-loop */\n"); - } else - { /* non_fatal("loop in state body", 0); ** maybe ok */ - } - continue; - } else - { g = (Guard *) emalloc(sizeof(Guard)); - g->t = e->n; - g->nxt = guard; - guard = g; - } } - - if (guard && !once) - { if (!not_printing) complete_transition(sl, guard); - to_render(sl->s); - } } +{ Succ_List *sl; + State_Stack *y; + Guard *g; + int i, once; + + for (sl = s->succ; sl; sl = sl->nxt) + { once = 0; + + for (i = 0; i < nclaims; i++) + { Element *e; + e = matrix[i][s->combo[i]][sl->s->state.combo[i]]; + + /* if one of the claims has a DO or IF move + then pull its target state forward, once + */ + + if (!e + || e->n->ntyp == NON_ATOMIC + || e->n->ntyp == DO + || e->n->ntyp == IF) + { s = &(sl->s->state); + y = push_dsts(s->combo); + if (!y) + { if (once++ == 0) + { assert(s->succ != NULL); + state_body(s, guard); + } + pop_dsts(); + } else if (!y->nxt) /* self-loop transition */ + { if (!not_printing) printf(" /* self-loop */\n"); + } else + { /* non_fatal("loop in state body", 0); ** maybe ok */ + } + continue; + } else + { g = (Guard *) emalloc(sizeof(Guard)); + g->t = e->n; + g->nxt = guard; + guard = g; + } } + + if (guard && !once) + { if (!not_printing) complete_transition(sl, guard); + to_render(sl->s); + } } } static struct X_tbl { - char *s; int n; + const char *s; int n; } spl[] = { - {"end", 3 }, - {"accept", 6 }, - {0, 0 }, + {"end", 3 }, + {"accept", 6 }, + {0, 0 }, }; static int slcnt; @@ -281,643 +281,643 @@ extern Label *labtab; static ProcList * locate_claim(int n) -{ ProcList *p; - int i; +{ ProcList *p; + int i; - for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ - { if (i == n) - { break; - } } - assert(p && p->b == N_CLAIM); + for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ + { if (i == n) + { break; + } } + assert(p && p->b == N_CLAIM); - return p; + return p; } static void elim_lab(Element *e) -{ Label *l, *lst; - - for (l = labtab, lst = NULL; l; lst = l, l = l->nxt) - { if (l->e == e) - { if (lst) - { lst->nxt = l->nxt; - } else - { labtab = l->nxt; - } - break; - } } +{ Label *l, *lst; + + for (l = labtab, lst = NULL; l; lst = l, l = l->nxt) + { if (l->e == e) + { if (lst) + { lst->nxt = l->nxt; + } else + { labtab = l->nxt; + } + break; + } } } static int claim_has_accept(ProcList *p) -{ Label *l; - - for (l = labtab; l; l = l->nxt) - { if (strcmp(l->c->name, p->n->name) == 0 - && strncmp(l->s->name, "accept", 6) == 0) - { return 1; - } } - return 0; +{ Label *l; + + for (l = labtab; l; l = l->nxt) + { if (strcmp(l->c->name, p->n->name) == 0 + && strncmp(l->s->name, "accept", 6) == 0) + { return 1; + } } + return 0; } static void prune_accept(void) -{ int n; - - for (n = 0; n < nclaims; n++) - { if ((reached[n][Selfs[n]->seqno] & 2) == 0) - { if (verbose) - { printf("claim %d: selfloop not reachable\n", n); - } - elim_lab(Selfs[n]); - Nacc[n] = claim_has_accept(locate_claim(n)); - } } +{ int n; + + for (n = 0; n < nclaims; n++) + { if ((reached[n][Selfs[n]->seqno] & 2) == 0) + { if (verbose) + { printf("claim %d: selfloop not reachable\n", n); + } + elim_lab(Selfs[n]); + Nacc[n] = claim_has_accept(locate_claim(n)); + } } } static void mk_accepting(int n, Element *e) -{ ProcList *p; - Label *l; - int i; - - assert(!Selfs[n]); - Selfs[n] = e; - - l = (Label *) emalloc(sizeof(Label)); - l->s = (Symbol *) emalloc(sizeof(Symbol)); - l->s->name = "accept00"; - l->c = (Symbol *) emalloc(sizeof(Symbol)); - l->uiid = 0; /* this is not in an inline */ - - for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ - { if (i == n) - { l->c->name = p->n->name; - break; - } } - assert(p && p->b == N_CLAIM); - Nacc[n] = 1; - has_accept = 1; - - l->e = e; - l->nxt = labtab; - labtab = l; +{ ProcList *p; + Label *l; + int i; + + assert(!Selfs[n]); + Selfs[n] = e; + + l = (Label *) emalloc(sizeof(Label)); + l->s = (Symbol *) emalloc(sizeof(Symbol)); + l->s->name = strdup("accept00"); + l->c = (Symbol *) emalloc(sizeof(Symbol)); + l->uiid = 0; /* this is not in an inline */ + + for (p = ready, i = 0; p; p = p->nxt, i++) /* find claim name */ + { if (i == n) + { l->c->name = p->n->name; + break; + } } + assert(p && p->b == N_CLAIM); + Nacc[n] = 1; + has_accept = 1; + + l->e = e; + l->nxt = labtab; + labtab = l; } static void check_special(int *nrs) -{ ProcList *p; - Label *l; - int i, j, nmatches; - int any_accepts = 0; - - for (i = 0; i < nclaims; i++) - { any_accepts += Nacc[i]; - } - - is_accept = 0; - for (j = 0; spl[j].n; j++) /* 2 special label prefixes */ - { nmatches = 0; - for (p = ready, i = 0; p; p = p->nxt, i++) /* check each claim */ - { if (p->b != N_CLAIM) - { continue; - } - /* claim i in state nrs[i], type p->tn, name p->n->name - * either the state has an accept label, or the claim has none, - * so that all its states should be considered accepting - * --- but only if other claims do have accept states! - */ - if (Strict == 0 && j == 1 && Nacc[i] == 0 && any_accepts > 0) - { if ((verbose&32) && i == unfolding) - { printf(" /* claim %d pseudo-accept */\n", i); - } - goto is_accepting; - } - for (l = labtab; l; l = l->nxt) /* check its labels */ - { if (strcmp(l->c->name, p->n->name) == 0 /* right claim */ - && l->e->seqno == nrs[i] /* right state */ - && strncmp(l->s->name, spl[j].s, spl[j].n) == 0) - { if (j == 1) /* accept state */ - { char buf[32]; -is_accepting: if (strchr(p->n->name, ':')) - { sprintf(buf, "N%d", i); - } else - { assert(strlen(p->n->name) < sizeof(buf)); - strcpy(buf, p->n->name); - } - if (unfolding == 0 && i == 0) - { if (!not_printing) - printf("%s_%s_%d:\n", /* true accept */ - spl[j].s, buf, slcnt++); - } else if (verbose&32) - { if (!not_printing) - printf("%s_%s%d:\n", - buf, spl[j].s, slcnt++); - } - if (i == unfolding) - { is_accept++; /* move to next unfolding */ - } - } else - { nmatches++; - } - break; - } } } - if (j == 0 && nmatches == nclaims) /* end-state */ - { if (!not_printing) - { printf("%s%d:\n", spl[j].s, slcnt++); - } } } +{ ProcList *p; + Label *l; + int i, j, nmatches; + int any_accepts = 0; + + for (i = 0; i < nclaims; i++) + { any_accepts += Nacc[i]; + } + + is_accept = 0; + for (j = 0; spl[j].n; j++) /* 2 special label prefixes */ + { nmatches = 0; + for (p = ready, i = 0; p; p = p->nxt, i++) /* check each claim */ + { if (p->b != N_CLAIM) + { continue; + } + /* claim i in state nrs[i], type p->tn, name p->n->name + * either the state has an accept label, or the claim has none, + * so that all its states should be considered accepting + * --- but only if other claims do have accept states! + */ + if (Strict == 0 && j == 1 && Nacc[i] == 0 && any_accepts > 0) + { if ((verbose&32) && i == unfolding) + { printf(" /* claim %d pseudo-accept */\n", i); + } + goto is_accepting; + } + for (l = labtab; l; l = l->nxt) /* check its labels */ + { if (strcmp(l->c->name, p->n->name) == 0 /* right claim */ + && l->e->seqno == nrs[i] /* right state */ + && strncmp(l->s->name, spl[j].s, spl[j].n) == 0) + { if (j == 1) /* accept state */ + { char buf[32]; +is_accepting: if (strchr(p->n->name, ':')) + { sprintf(buf, "N%d", i); + } else + { assert(strlen(p->n->name) < sizeof(buf)); + strcpy(buf, p->n->name); + } + if (unfolding == 0 && i == 0) + { if (!not_printing) + printf("%s_%s_%d:\n", /* true accept */ + spl[j].s, buf, slcnt++); + } else if (verbose&32) + { if (!not_printing) + printf("%s_%s%d:\n", + buf, spl[j].s, slcnt++); + } + if (i == unfolding) + { is_accept++; /* move to next unfolding */ + } + } else + { nmatches++; + } + break; + } } } + if (j == 0 && nmatches == nclaims) /* end-state */ + { if (!not_printing) + { printf("%s%d:\n", spl[j].s, slcnt++); + } } } } static int render_state(SQueue *q) { - if (!q || !q->state.succ) - { if (verbose&64) - { printf(" no exit\n"); - } - return 0; - } - - check_special(q->state.combo); /* accept or end-state labels */ - - dsts = (State_Stack *) 0; - push_dsts(q->state.combo); /* to detect loops */ - - if (!not_printing) - { print_state_nm("", q->state.combo, ""); /* the name */ - printf("_U%d:\n\tdo\n", unfolding); - } - - state_body(&(q->state), (Guard *) 0); - - if (!not_printing) - { printf("\tod;\n"); - } - pop_dsts(); - return 1; + if (!q || !q->state.succ) + { if (verbose&64) + { printf(" no exit\n"); + } + return 0; + } + + check_special(q->state.combo); /* accept or end-state labels */ + + dsts = (State_Stack *) 0; + push_dsts(q->state.combo); /* to detect loops */ + + if (!not_printing) + { print_state_nm("", q->state.combo, ""); /* the name */ + printf("_U%d:\n\tdo\n", unfolding); + } + + state_body(&(q->state), (Guard *) 0); + + if (!not_printing) + { printf("\tod;\n"); + } + pop_dsts(); + return 1; } static void explore_product(void) -{ SQueue *q; - - /* all states are in the sd queue */ - - q = retrieve_state(Ist); /* retrieve from the sd q */ - q->nxt = render; /* put in render q */ - render = q; - do { - q = render; - render = render->nxt; - q->nxt = 0; /* remove from render q */ - - if (verbose&64) - { print_state_nm("explore: ", q->state.combo, "\n"); - } - - not_printing = 1; - render_state(q); /* may add new states */ - not_printing = 0; - - if (lasthold) - { lasthold->nxt = q; - lasthold = q; - } else - { holding = lasthold = q; - } - } while (render); - assert(!dsts); - +{ SQueue *q; + + /* all states are in the sd queue */ + + q = retrieve_state(Ist); /* retrieve from the sd q */ + q->nxt = render; /* put in render q */ + render = q; + do { + q = render; + render = render->nxt; + q->nxt = 0; /* remove from render q */ + + if (verbose&64) + { print_state_nm("explore: ", q->state.combo, "\n"); + } + + not_printing = 1; + render_state(q); /* may add new states */ + not_printing = 0; + + if (lasthold) + { lasthold->nxt = q; + lasthold = q; + } else + { holding = lasthold = q; + } + } while (render); + assert(!dsts); + } static void print_product(void) -{ SQueue *q; - int cnt; - - if (unfolding == 0) - { printf("never Product {\n"); /* name expected by iSpin */ - q = find_state(Ist); /* should find it in the holding q */ - assert(q != NULL); - q->nxt = holding; /* put it at the front */ - holding = q; - } - render = holding; - holding = lasthold = 0; - - printf("/* ============= U%d ============= */\n", unfolding); - cnt = 0; - do { - q = render; - render = render->nxt; - q->nxt = 0; - if (verbose&64) - { print_state_nm("print: ", q->state.combo, "\n"); - } - cnt += render_state(q); - - if (lasthold) - { lasthold->nxt = q; - lasthold = q; - } else - { holding = lasthold = q; - } - } while (render); - assert(!dsts); - - if (cnt == 0) - { printf(" 0;\n"); - } - - if (unfolding == nclaims-1) - { printf("}\n"); - } +{ SQueue *q; + int cnt; + + if (unfolding == 0) + { printf("never Product {\n"); /* name expected by iSpin */ + q = find_state(Ist); /* should find it in the holding q */ + assert(q != NULL); + q->nxt = holding; /* put it at the front */ + holding = q; + } + render = holding; + holding = lasthold = 0; + + printf("/* ============= U%d ============= */\n", unfolding); + cnt = 0; + do { + q = render; + render = render->nxt; + q->nxt = 0; + if (verbose&64) + { print_state_nm("print: ", q->state.combo, "\n"); + } + cnt += render_state(q); + + if (lasthold) + { lasthold->nxt = q; + lasthold = q; + } else + { holding = lasthold = q; + } + } while (render); + assert(!dsts); + + if (cnt == 0) + { printf(" 0;\n"); + } + + if (unfolding == nclaims-1) + { printf("}\n"); + } } static void prune_dead(void) -{ Succ_List *sl, *last; - SQueue *q; - int cnt; - - do { cnt = 0; - for (q = sd; q; q = q->nxt) - { /* if successor is deadend, remove it - * unless it's a move to the end-state of the claim - */ - last = (Succ_List *) 0; - for (sl = q->state.succ; sl; last = sl, sl = sl->nxt) - { if (!sl->s->state.succ) /* no successor */ - { if (!last) - { q->state.succ = sl->nxt; - } else - { last->nxt = sl->nxt; - } - cnt++; - } } } - } while (cnt > 0); +{ Succ_List *sl, *last; + SQueue *q; + int cnt; + + do { cnt = 0; + for (q = sd; q; q = q->nxt) + { /* if successor is deadend, remove it + * unless it's a move to the end-state of the claim + */ + last = (Succ_List *) 0; + for (sl = q->state.succ; sl; last = sl, sl = sl->nxt) + { if (!sl->s->state.succ) /* no successor */ + { if (!last) + { q->state.succ = sl->nxt; + } else + { last->nxt = sl->nxt; + } + cnt++; + } } } + } while (cnt > 0); } static void print_raw(void) -{ int i, j, n; - - printf("#if 0\n"); - for (n = 0; n < nclaims; n++) - { printf("C%d:\n", n); - for (i = 0; i < nst; i++) - { if (reached[n][i]) - for (j = 0; j < nst; j++) - { if (matrix[n][i][j]) - { if (reached[n][i] & 2) printf("+"); - if (i == Ist[n]) printf("*"); - printf("\t%d", i); - wrap_text(" -[", matrix[n][i][j]->n, "]->\t"); - printf("%d\n", j); - } } } } - printf("#endif\n\n"); - fflush(stdout); +{ int i, j, n; + + printf("#if 0\n"); + for (n = 0; n < nclaims; n++) + { printf("C%d:\n", n); + for (i = 0; i < nst; i++) + { if (reached[n][i]) + for (j = 0; j < nst; j++) + { if (matrix[n][i][j]) + { if (reached[n][i] & 2) printf("+"); + if (i == Ist[n]) printf("*"); + printf("\t%d", i); + wrap_text(" -[", matrix[n][i][j]->n, "]->\t"); + printf("%d\n", j); + } } } } + printf("#endif\n\n"); + fflush(stdout); } void sync_product(void) -{ ProcList *p; - Element *e; - int n, i; - - if (nclaims <= 1) return; - - (void) unlink("pan.pre"); - - Ist = (int *) emalloc(sizeof(int) * nclaims); - Nacc = (int *) emalloc(sizeof(int) * nclaims); - Nst = (int *) emalloc(sizeof(int) * nclaims); - reached = (int **) emalloc(sizeof(int *) * nclaims); - Selfs = (Element **) emalloc(sizeof(Element *) * nclaims); - matrix = (Element ****) emalloc(sizeof(Element ***) * nclaims); /* claims */ - - for (p = ready, i = 0; p; p = p->nxt, i++) - { if (p->b == N_CLAIM) - { nst = max(p->s->maxel, nst); - Nacc[i] = claim_has_accept(p); - } } - - for (n = 0; n < nclaims; n++) - { reached[n] = (int *) emalloc(sizeof(int) * nst); - matrix[n] = (Element ***) emalloc(sizeof(Element **) * nst); /* rows */ - for (i = 0; i < nst; i++) /* cols */ - { matrix[n][i] = (Element **) emalloc(sizeof(Element *) * nst); - } } - - for (e = Al_El; e; e = e->Nxt) - { e->status &= ~DONE; - } - - for (p = ready, n=0; p; p = p->nxt, n++) - { if (p->b == N_CLAIM) - { /* fill in matrix[n] */ - e = p->s->frst; - Ist[n] = huntele(e, e->status, -1)->seqno; - - reached[n][Ist[n]] = 1|2; - get_seq(n, p->s); - } } - - if (verbose) /* show only the input automata */ - { print_raw(); - } - - gen_product(); /* create product automaton */ +{ ProcList *p; + Element *e; + int n, i; + + if (nclaims <= 1) return; + + (void) unlink("pan.pre"); + + Ist = (int *) emalloc(sizeof(int) * nclaims); + Nacc = (int *) emalloc(sizeof(int) * nclaims); + Nst = (int *) emalloc(sizeof(int) * nclaims); + reached = (int **) emalloc(sizeof(int *) * nclaims); + Selfs = (Element **) emalloc(sizeof(Element *) * nclaims); + matrix = (Element ****) emalloc(sizeof(Element ***) * nclaims); /* claims */ + + for (p = ready, i = 0; p; p = p->nxt, i++) + { if (p->b == N_CLAIM) + { nst = MaX(p->s->maxel, nst); + Nacc[i] = claim_has_accept(p); + } } + + for (n = 0; n < nclaims; n++) + { reached[n] = (int *) emalloc(sizeof(int) * nst); + matrix[n] = (Element ***) emalloc(sizeof(Element **) * nst); /* rows */ + for (i = 0; i < nst; i++) /* cols */ + { matrix[n][i] = (Element **) emalloc(sizeof(Element *) * nst); + } } + + for (e = Al_El; e; e = e->Nxt) + { e->status &= ~DONE; + } + + for (p = ready, n=0; p; p = p->nxt, n++) + { if (p->b == N_CLAIM) + { /* fill in matrix[n] */ + e = p->s->frst; + Ist[n] = huntele(e, e->status, -1)->seqno; + + reached[n][Ist[n]] = 1|2; + get_seq(n, p->s); + } } + + if (verbose) /* show only the input automata */ + { print_raw(); + } + + gen_product(); /* create product automaton */ } static int nxt_trans(int n, int cs, int frst) -{ int j; - - for (j = frst; j < nst; j++) - { if (reached[n][cs] - && matrix[n][cs][j]) - { return j; - } } - return -1; +{ int j; + + for (j = frst; j < nst; j++) + { if (reached[n][cs] + && matrix[n][cs][j]) + { return j; + } } + return -1; } static void -print_state_nm(char *p, int *s, char *a) -{ int i; - printf("%sP", p); - for (i = 0; i < nclaims; i++) - { printf("_%d", s[i]); - } - printf("%s", a); +print_state_nm(const char *p, const int *s, const char *a) +{ int i; + printf("%sP", p); + for (i = 0; i < nclaims; i++) + { printf("_%d", s[i]); + } + printf("%s", a); } static void create_transition(OneState *s, SQueue *it) -{ int n, from, upto; - int *F = s->combo; - int *T = it->state.combo; - Succ_List *sl; - Lextok *t; - - if (verbose&64) - { print_state_nm("", F, " "); - print_state_nm("-> ", T, "\t"); - } - - /* check if any of the claims is blocked */ - /* which makes the state a dead-end */ - for (n = 0; n < nclaims; n++) - { from = F[n]; - upto = T[n]; - t = matrix[n][from][upto]->n; - if (verbose&64) - { wrap_text("", t, " "); - } - if (t->ntyp == 'c' - && t->lft->ntyp == CONST) - { if (t->lft->val == 0) /* i.e., false */ - { goto done; - } } } - - sl = (Succ_List *) emalloc(sizeof(Succ_List)); - sl->s = it; - sl->nxt = s->succ; - s->succ = sl; +{ int n, from, upto; + int *F = s->combo; + int *T = it->state.combo; + Succ_List *sl; + Lextok *t; + + if (verbose&64) + { print_state_nm("", F, " "); + print_state_nm("-> ", T, "\t"); + } + + /* check if any of the claims is blocked */ + /* which makes the state a dead-end */ + for (n = 0; n < nclaims; n++) + { from = F[n]; + upto = T[n]; + t = matrix[n][from][upto]->n; + if (verbose&64) + { wrap_text("", t, " "); + } + if (t->ntyp == 'c' + && t->lft->ntyp == CONST) + { if (t->lft->val == 0) /* i.e., false */ + { goto done; + } } } + + sl = (Succ_List *) emalloc(sizeof(Succ_List)); + sl->s = it; + sl->nxt = s->succ; + s->succ = sl; done: - if (verbose&64) - { printf("\n"); - } + if (verbose&64) + { printf("\n"); + } } static SQueue * find_state(int *cs) -{ SQueue *nq, *a = sq; - int i; - -again: /* check in nq, sq, and then in the render q */ - for (nq = a; nq; nq = nq->nxt) - { if (same_state(nq->state.combo, cs)) - { return nq; /* found */ - } } - if (a == sq && sd) - { a = sd; - goto again; /* check the other stack too */ - } else if (a == sd && render) - { a = render; - goto again; - } - - nq = (SQueue *) emalloc(sizeof(SQueue)); - nq->state.combo = (int *) emalloc(nclaims * sizeof(int)); - for (i = 0; i < nclaims; i++) - { nq->state.combo[i] = cs[i]; - } - nq->nxt = sq; /* add to sq stack */ - sq = nq; - - return nq; +{ SQueue *nq, *a = sq; + int i; + +again: /* check in nq, sq, and then in the render q */ + for (nq = a; nq; nq = nq->nxt) + { if (same_state(nq->state.combo, cs)) + { return nq; /* found */ + } } + if (a == sq && sd) + { a = sd; + goto again; /* check the other stack too */ + } else if (a == sd && render) + { a = render; + goto again; + } + + nq = (SQueue *) emalloc(sizeof(SQueue)); + nq->state.combo = (int *) emalloc(nclaims * sizeof(int)); + for (i = 0; i < nclaims; i++) + { nq->state.combo[i] = cs[i]; + } + nq->nxt = sq; /* add to sq stack */ + sq = nq; + + return nq; } static SQueue * retrieve_state(int *s) -{ SQueue *nq, *last = NULL; - - for (nq = sd; nq; last = nq, nq = nq->nxt) - { if (same_state(nq->state.combo, s)) - { if (last) - { last->nxt = nq->nxt; - } else - { sd = nq->nxt; /* 6.4.0: was sd = nq */ - } - return nq; /* found */ - } } - - fatal("cannot happen: retrieve_state", 0); - return (SQueue *) 0; +{ SQueue *nq, *last = NULL; + + for (nq = sd; nq; last = nq, nq = nq->nxt) + { if (same_state(nq->state.combo, s)) + { if (last) + { last->nxt = nq->nxt; + } else + { sd = nq->nxt; /* 6.4.0: was sd = nq */ + } + return nq; /* found */ + } } + + fatal("cannot happen: retrieve_state", 0); + return (SQueue *) 0; } static void all_successors(int n, OneState *cur) -{ int i, j = 0; - - if (n >= nclaims) - { create_transition(cur, find_state(Nst)); - } else - { i = cur->combo[n]; - for (;;) - { j = nxt_trans(n, i, j); - if (j < 0) break; - Nst[n] = j; - all_successors(n+1, cur); - j++; - } } +{ int i, j = 0; + + if (n >= nclaims) + { create_transition(cur, find_state(Nst)); + } else + { i = cur->combo[n]; + for (;;) + { j = nxt_trans(n, i, j); + if (j < 0) break; + Nst[n] = j; + all_successors(n+1, cur); + j++; + } } } static void gen_product(void) -{ OneState *cur_st; - SQueue *q; - - find_state(Ist); /* create initial state */ - - while (sq) - { if (in_stack(sq, sd)) - { sq = sq->nxt; - continue; - } - cur_st = &(sq->state); - - q = sq; - sq = sq->nxt; /* delete from sq stack */ - q->nxt = sd; /* and move to done stack */ - sd = q; - - all_successors(0, cur_st); - } - /* all states are in the sd queue now */ - prune_dead(); - explore_product(); /* check if added accept-self-loops are reachable */ - prune_accept(); - - if (verbose) - { print_raw(); - } - - /* PM: merge states with identical successor lists */ - - /* all outgoing transitions from accept-states - from claim n in copy n connect to states in copy (n+1)%nclaims - only accept states from claim 0 in copy 0 are true accept states - in the product - - PM: what about claims that have no accept states (e.g., restrictions) - */ - - for (unfolding = 0; unfolding < nclaims; unfolding++) - { print_product(); - } +{ OneState *cur_st; + SQueue *q; + + find_state(Ist); /* create initial state */ + + while (sq) + { if (in_stack(sq, sd)) + { sq = sq->nxt; + continue; + } + cur_st = &(sq->state); + + q = sq; + sq = sq->nxt; /* delete from sq stack */ + q->nxt = sd; /* and move to done stack */ + sd = q; + + all_successors(0, cur_st); + } + /* all states are in the sd queue now */ + prune_dead(); + explore_product(); /* check if added accept-self-loops are reachable */ + prune_accept(); + + if (verbose) + { print_raw(); + } + + /* PM: merge states with identical successor lists */ + + /* all outgoing transitions from accept-states + from claim n in copy n connect to states in copy (n+1)%nclaims + only accept states from claim 0 in copy 0 are true accept states + in the product + + PM: what about claims that have no accept states (e.g., restrictions) + */ + + for (unfolding = 0; unfolding < nclaims; unfolding++) + { print_product(); + } } static void t_record(int n, Element *e, Element *g) -{ int from = e->seqno, upto = g?g->seqno:0; +{ int from = e->seqno, upto = g?g->seqno:0; - assert(from >= 0 && from < nst); - assert(upto >= 0 && upto < nst); + assert(from >= 0 && from < nst); + assert(upto >= 0 && upto < nst); - matrix[n][from][upto] = e; - reached[n][upto] |= 1; + matrix[n][from][upto] = e; + reached[n][upto] |= 1; } static void get_sub(int n, Element *e) { - if (e->n->ntyp == D_STEP - || e->n->ntyp == ATOMIC) - { fatal("atomic or d_step in never claim product", 0); - } - /* NON_ATOMIC */ - e->n->sl->this->last->nxt = e->nxt; - get_seq(n, e->n->sl->this); + if (e->n->ntyp == D_STEP + || e->n->ntyp == ATOMIC) + { fatal("atomic or d_step in never claim product", 0); + } + /* NON_ATOMIC */ + e->n->sl->thisS->last->nxt = e->nxt; + get_seq(n, e->n->sl->thisS); - t_record(n, e, e->n->sl->this->frst); + t_record(n, e, e->n->sl->thisS->frst); } static void set_el(int n, Element *e) -{ Element *g; - - if (e->n->ntyp == '@') /* change to self-loop */ - { e->n->ntyp = CONST; - e->n->val = 1; /* true */ - e->nxt = e; - g = e; - mk_accepting(n, e); - } else - - if (e->n->ntyp == GOTO) - { g = get_lab(e->n, 1); - g = huntele(g, e->status, -1); - } else if (e->nxt) - { g = huntele(e->nxt, e->status, -1); - } else - { g = NULL; - } - - t_record(n, e, g); +{ Element *g; + + if (e->n->ntyp == '@') /* change to self-loop */ + { e->n->ntyp = CONST; + e->n->val = 1; /* true */ + e->nxt = e; + g = e; + mk_accepting(n, e); + } else + + if (e->n->ntyp == GOTO) + { g = get_lab(e->n, 1); + g = huntele(g, e->status, -1); + } else if (e->nxt) + { g = huntele(e->nxt, e->status, -1); + } else + { g = NULL; + } + + t_record(n, e, g); } static void get_seq(int n, Sequence *s) -{ SeqList *h; - Element *e; - - e = huntele(s->frst, s->frst->status, -1); - for ( ; e; e = e->nxt) - { if (e->status & DONE) - { goto checklast; - } - e->status |= DONE; - - if (e->n->ntyp == UNLESS) - { fatal("unless stmnt in never claim product", 0); - } - - if (e->sub) /* IF or DO */ - { Lextok *x = NULL; - Lextok *y = NULL; - Lextok *haselse = NULL; - - for (h = e->sub; h; h = h->nxt) - { Lextok *t = h->this->frst->n; - if (t->ntyp == ELSE) - { if (verbose&64) printf("else at line %d\n", t->ln); - haselse = t; - continue; - } - if (t->ntyp != 'c') - { fatal("product, 'else' combined with non-condition", 0); - } - - if (t->lft->ntyp == CONST /* true */ - && t->lft->val == 1 - && y == NULL) - { y = nn(ZN, CONST, ZN, ZN); - y->val = 0; - } else - { if (!x) - x = t; - else - x = nn(ZN, OR, x, t); - if (verbose&64) - { wrap_text(" [", x, "]\n"); - } } } - if (haselse) - { if (!y) - { y = nn(ZN, '!', x, ZN); - } - if (verbose&64) - { wrap_text(" [else: ", y, "]\n"); - } - haselse->ntyp = 'c'; /* replace else */ - haselse->lft = y; - } - - for (h = e->sub; h; h = h->nxt) - { t_record(n, e, h->this->frst); - get_seq(n, h->this); - } - } else - { if (e->n->ntyp == ATOMIC - || e->n->ntyp == D_STEP - || e->n->ntyp == NON_ATOMIC) - { get_sub(n, e); - } else - { set_el(n, e); - } - } -checklast: if (e == s->last) - break; - } +{ SeqList *h; + Element *e; + + e = huntele(s->frst, s->frst->status, -1); + for ( ; e; e = e->nxt) + { if (e->status & DONE) + { goto checklast; + } + e->status |= DONE; + + if (e->n->ntyp == UNLESS) + { fatal("unless stmnt in never claim product", 0); + } + + if (e->sub) /* IF or DO */ + { Lextok *x = NULL; + Lextok *y = NULL; + Lextok *haselse = NULL; + + for (h = e->sub; h; h = h->nxt) + { Lextok *t = h->thisS->frst->n; + if (t->ntyp == ELSE) + { if (verbose&64) printf("else at line %d\n", t->ln); + haselse = t; + continue; + } + if (t->ntyp != 'c') + { fatal("product, 'else' combined with non-condition", 0); + } + + if (t->lft->ntyp == CONST /* true */ + && t->lft->val == 1 + && y == NULL) + { y = nn(ZN, CONST, ZN, ZN); + y->val = 0; + } else + { if (!x) + x = t; + else + x = nn(ZN, OR, x, t); + if (verbose&64) + { wrap_text(" [", x, "]\n"); + } } } + if (haselse) + { if (!y) + { y = nn(ZN, '!', x, ZN); + } + if (verbose&64) + { wrap_text(" [else: ", y, "]\n"); + } + haselse->ntyp = 'c'; /* replace else */ + haselse->lft = y; + } + + for (h = e->sub; h; h = h->nxt) + { t_record(n, e, h->thisS->frst); + get_seq(n, h->thisS); + } + } else + { if (e->n->ntyp == ATOMIC + || e->n->ntyp == D_STEP + || e->n->ntyp == NON_ATOMIC) + { get_sub(n, e); + } else + { set_el(n, e); + } + } +checklast: if (e == s->last) + break; + } } diff --git a/Src/reprosrc.c b/Src/reprosrc.c index ee2b0d9..a3a5dff 100644 --- a/Src/reprosrc.c +++ b/Src/reprosrc.c @@ -40,7 +40,7 @@ repro_sub(Element *e) break; } indent++; - repro_seq(e->n->sl->this); + repro_seq(e->n->sl->thisS); indent--; doindent(); @@ -60,10 +60,10 @@ repro_seq(Sequence *s) if (e->n->ntyp == UNLESS) { printf("/* normal */ {\n"); - repro_seq(e->n->sl->this); + repro_seq(e->n->sl->thisS); doindent(); printf("} unless {\n"); - repro_seq(e->n->sl->nxt->this); + repro_seq(e->n->sl->nxt->thisS); doindent(); printf("}; /* end unless */\n"); } else if (e->sub) @@ -75,7 +75,7 @@ repro_seq(Sequence *s) for (h = e->sub; h; h = h->nxt) { indent--; doindent(); indent++; printf("::\n"); - repro_seq(h->this); + repro_seq(h->thisS); printf("\n"); } diff --git a/Src/run.c b/Src/run.c index ad7c8a4..8b30c16 100644 --- a/Src/run.c +++ b/Src/run.c @@ -48,7 +48,7 @@ rev_escape(SeqList *e) if (e) { if ((r = rev_escape(e->nxt)) == ZE) /* reversed order */ - { r = eval_sub(e->this->frst); + { r = eval_sub(e->thisS->frst); } } return r; @@ -81,7 +81,7 @@ eval_sub(Element *e) } if (e->n->ntyp == UNLESS) { /* escapes were distributed into sequence */ - return eval_sub(e->sub->this->frst); + return eval_sub(e->sub->thisS->frst); } else if (e->sub) /* true for IF, DO, and UNLESS */ { Element *has_else = ZE; Element *bas_else = ZE; @@ -107,25 +107,25 @@ eval_sub(Element *e) && !Escape_Check && !(e->status&(D_ATOM)) && depth >= jumpsteps - && z->this->frst - && (xspin || (verbose&32) || Enabled0(z->this->frst))) - { if (z->this->frst->n->ntyp == ELSE) - { has_else = (Rvous)?ZE:z->this->frst->nxt; + && z->thisS->frst + && (xspin || (verbose&32) || Enabled0(z->thisS->frst))) + { if (z->thisS->frst->n->ntyp == ELSE) + { has_else = (Rvous)?ZE:z->thisS->frst->nxt; nr_else = j; continue; } printf("\tchoice %d: ", j); #if 0 - if (z->this->frst->n) - printf("line %d, ", z->this->frst->n->ln); + if (z->thisS->frst->n) + printf("line %d, ", z->thisS->frst->n->ln); #endif - if (!Enabled0(z->this->frst)) + if (!Enabled0(z->thisS->frst)) printf("unexecutable, "); else { nr_choices++; only_pos = j; } - comment(stdout, z->this->frst->n, 0); + comment(stdout, z->thisS->frst->n, 0); printf("\n"); } } @@ -179,9 +179,9 @@ eval_sub(Element *e) has_else = ZE; bas_else = ZE; for (i = 0, z = e->sub; i < j+k; i++) - { if (z->this->frst - && z->this->frst->n->ntyp == ELSE) - { bas_else = z->this->frst; + { if (z->thisS->frst + && z->thisS->frst->n->ntyp == ELSE) + { bas_else = z->thisS->frst; has_else = (Rvous)?ZE:bas_else->nxt; if (!interactive || depth < jumpsteps || Escape_Check @@ -190,11 +190,11 @@ eval_sub(Element *e) continue; } } - if (z->this->frst - && ((z->this->frst->n->ntyp == ATOMIC - || z->this->frst->n->ntyp == D_STEP) - && z->this->frst->n->sl->this->frst->n->ntyp == ELSE)) - { bas_else = z->this->frst->n->sl->this->frst; + if (z->thisS->frst + && ((z->thisS->frst->n->ntyp == ATOMIC + || z->thisS->frst->n->ntyp == D_STEP) + && z->thisS->frst->n->sl->thisS->frst->n->ntyp == ELSE)) + { bas_else = z->thisS->frst->n->sl->thisS->frst; has_else = (Rvous)?ZE:bas_else->nxt; if (!interactive || depth < jumpsteps || Escape_Check @@ -204,7 +204,7 @@ eval_sub(Element *e) } } if (i >= k) - { if ((f = eval_sub(z->this->frst)) != ZE) + { if ((f = eval_sub(z->thisS->frst)) != ZE) return f; else if (interactive && depth >= jumpsteps && !(e->status&(D_ATOM))) @@ -219,15 +219,15 @@ eval_sub(Element *e) } else { if (e->n->ntyp == ATOMIC || e->n->ntyp == D_STEP) - { f = e->n->sl->this->frst; - g = e->n->sl->this->last; + { f = e->n->sl->thisS->frst; + g = e->n->sl->thisS->last; g->nxt = e->nxt; if (!(g = eval_sub(f))) /* atomic guard */ return ZE; return g; } else if (e->n->ntyp == NON_ATOMIC) - { f = e->n->sl->this->frst; - g = e->n->sl->this->last; + { f = e->n->sl->thisS->frst; + g = e->n->sl->thisS->last; g->nxt = e->nxt; /* close it */ return eval_sub(f); } else if (e->n->ntyp == '.') @@ -242,10 +242,10 @@ eval_sub(Element *e) printf("] has escape(s): "); for (x = e->esc; x; x = x->nxt) { printf("["); - g = x->this->frst; + g = x->thisS->frst; if (g->n->ntyp == ATOMIC || g->n->ntyp == NON_ATOMIC) - g = g->n->sl->this->frst; + g = g->n->sl->thisS->frst; comment(stdout, g->n, 0); printf("] "); } @@ -272,7 +272,7 @@ eval_sub(Element *e) } } else { for (x = e->esc; x; x = x->nxt) - { if ((g = eval_sub(x->this->frst)) != ZE) + { if ((g = eval_sub(x->thisS->frst)) != ZE) { if (verbose&4) { printf("\tEscape taken "); if (g->n && g->n->fn) @@ -466,9 +466,9 @@ eval(Lextok *now) comment(stdout, now->lft, 0); printf(")\n"); if (s_trail && !xspin) return 1; - wrapup(1); /* doesn't return */ + wrapup(1); /* doesn't return */ /*fallthrough*/ - case IF: case DO: case BREAK: case UNLESS: /* compound */ + case IF: /*fallthrough*/ case DO: /*fallthrough*/ case BREAK: /*fallthrough*/ case UNLESS: /*fallthrough*/ /* compound */ case '.': return 1; /* return label for compound */ case '@': return 0; /* stop state */ case ELSE: return 1; /* only hit here in guided trails */ @@ -646,20 +646,20 @@ Enabled0(Element *e) if (Rvous) return 0; return 1; case UNLESS: - return Enabled0(e->sub->this->frst); + return Enabled0(e->sub->thisS->frst); case ATOMIC: case D_STEP: case NON_ATOMIC: - return Enabled0(e->n->sl->this->frst); + return Enabled0(e->n->sl->thisS->frst); } if (e->sub) /* true for IF, DO, and UNLESS */ { for (z = e->sub; z; z = z->nxt) - if (Enabled0(z->this->frst)) + if (Enabled0(z->thisS->frst)) return 1; return 0; } for (z = e->esc; z; z = z->nxt) - { if (Enabled0(z->this->frst)) + { if (Enabled0(z->thisS->frst)) return 1; } #if 0 diff --git a/Src/sched.c b/Src/sched.c index 69ba521..a9e1ab7 100644 --- a/Src/sched.c +++ b/Src/sched.c @@ -102,7 +102,7 @@ mk_rdy(Symbol *n, Lextok *p, Sequence *s, int det, Lextok *prov, enum btypes b) for (fpt = fp->lft; fpt; fpt = fpt->rgt) { j++; /* count # of parameters */ } - Npars = max(Npars, j); + Npars = MaX(Npars, j); return ready; } @@ -111,7 +111,7 @@ void check_mtypes(Lextok *pnm, Lextok *args) /* proctype name, actual params */ { ProcList *p = NULL; Lextok *fp, *fpt, *at; - char *s, *t; + const char *s, *t; if (pnm && pnm->sym) { for (p = ready; p; p = p->nxt) @@ -186,7 +186,7 @@ formdump(void) } void -announce(char *w) +announce(const char *w) { if (columns) { extern char GBuf[]; @@ -396,12 +396,12 @@ silent_moves(Element *e) cross_dsteps(e->n, f->n); return f; /* guard against goto cycles */ case UNLESS: - return silent_moves(e->sub->this->frst); + return silent_moves(e->sub->thisS->frst); case NON_ATOMIC: case ATOMIC: case D_STEP: - e->n->sl->this->last->nxt = e->nxt; - return silent_moves(e->n->sl->this->frst); + e->n->sl->thisS->last->nxt = e->nxt; + return silent_moves(e->n->sl->thisS->frst); case '.': return silent_moves(e->nxt); } @@ -508,7 +508,7 @@ try_more: for (X_lst = run_lst, k = 1; X_lst; X_lst = X_lst->nxt) proc_no_ch = no_choice; proc_k = k; for (z = X_lst->pc->sub, j=0; z; z = z->nxt) - { Element *y = silent_moves(z->this->frst); + { Element *y = silent_moves(z->thisS->frst); int unex; if (!y) continue; diff --git a/Src/spin.h b/Src/spin.h index 5fb4aac..5136bfa 100644 --- a/Src/spin.h +++ b/Src/spin.h @@ -9,6 +9,8 @@ #ifndef SEEN_SPIN_H #define SEEN_SPIN_H +#include "get_strdup.h" /* include this first for strdup & getline */ + #include #include #include @@ -19,433 +21,441 @@ #include #endif -enum { INIV, PUTV, LOGV }; /* used in pangen1.c */ +enum { INIV, PUTV, LOGV }; /* used in pangen1.c */ enum btypes { NONE, N_CLAIM, I_PROC, A_PROC, P_PROC, E_TRACE, N_TRACE }; typedef struct Lextok { - unsigned short ntyp; /* node type */ - short ismtyp; /* CONST derived from MTYP */ - int val; /* value attribute */ - int ln; /* line number */ - int indstep; /* part of d_step sequence */ - int uiid; /* inline id, if non-zero */ - struct Symbol *fn; /* file name */ - struct Symbol *sym; /* symbol reference */ - struct Sequence *sq; /* sequence */ - struct SeqList *sl; /* sequence list */ - struct Lextok *lft, *rgt; /* children in parse tree */ + unsigned short ntyp; /* node type */ + short ismtyp; /* CONST derived from MTYP */ + int val; /* value attribute */ + int ln; /* line number */ + int indstep; /* part of d_step sequence */ + int uiid; /* inline id, if non-zero */ + struct Symbol *fn; /* file name */ + struct Symbol *sym; /* symbol reference */ + struct Sequence *sq; /* sequence */ + struct SeqList *sl; /* sequence list */ + struct Lextok *lft, *rgt; /* children in parse tree */ } Lextok; typedef struct Slicer { - Lextok *n; /* global var, usable as slice criterion */ - short code; /* type of use: DEREF_USE or normal USE */ - short used; /* set when handled */ - struct Slicer *nxt; /* linked list */ + Lextok *n; /* global var, usable as slice criterion */ + short code; /* type of use: DEREF_USE or normal USE */ + short used; /* set when handled */ + struct Slicer *nxt; /* linked list */ } Slicer; typedef struct Access { - struct Symbol *who; /* proctype name of accessor */ - struct Symbol *what; /* proctype name of accessed */ - int cnt, typ; /* parameter nr and, e.g., 's' or 'r' */ - struct Access *lnk; /* linked list */ + struct Symbol *who; /* proctype name of accessor */ + struct Symbol *what; /* proctype name of accessed */ + int cnt, typ; /* parameter nr and, e.g., 's' or 'r' */ + struct Access *lnk; /* linked list */ } Access; typedef struct Symbol { - char *name; - int Nid; /* unique number for the name */ - unsigned short type; /* bit,short,.., chan,struct */ - unsigned char hidden; /* bit-flags: - 1=hide, 2=show, - 4=bit-equiv, 8=byte-equiv, - 16=formal par, 32=inline par, - 64=treat as if local; 128=read at least once - */ - unsigned char colnr; /* for use with xspin during simulation */ - unsigned char isarray; /* set if decl specifies array bound */ - unsigned char *bscp; /* block scope */ - int sc; /* scope seq no -- set only for proctypes */ - int nbits; /* optional width specifier */ - int nel; /* 1 if scalar, >1 if array */ - int setat; /* last depth value changed */ - int *val; /* runtime value(s), initl 0 */ - Lextok **Sval; /* values for structures */ - - int xu; /* exclusive r or w by 1 pid */ - struct Symbol *xup[2]; /* xr or xs proctype */ - struct Access *access;/* e.g., senders and receives of chan */ - Lextok *ini; /* initial value, or chan-def */ - Lextok *Slst; /* template for structure if struct */ - struct Symbol *mtype_name; /* if type == MTYPE else nil */ - struct Symbol *Snm; /* name of the defining struct */ - struct Symbol *owner; /* set for names of subfields in typedefs */ - struct Symbol *context; /* 0 if global, or procname */ - struct Symbol *next; /* linked list */ + char *name; + int Nid; /* unique number for the name */ + unsigned short type; /* bit,short,.., chan,struct */ + unsigned char hidden; /* bit-flags: + 1=hide, 2=show, + 4=bit-equiv, 8=byte-equiv, + 16=formal par, 32=inline par, + 64=treat as if local; 128=read at least once + */ + unsigned char colnr; /* for use with xspin during simulation */ + unsigned char isarray; /* set if decl specifies array bound */ + unsigned char *bscp; /* block scope */ + int sc; /* scope seq no -- set only for proctypes */ + int nbits; /* optional width specifier */ + int nel; /* 1 if scalar, >1 if array */ + int setat; /* last depth value changed */ + int *val; /* runtime value(s), initl 0 */ + Lextok **Sval; /* values for structures */ + + int xu; /* exclusive r or w by 1 pid */ + struct Symbol *xup[2]; /* xr or xs proctype */ + struct Access *access;/* e.g., senders and receives of chan */ + Lextok *ini; /* initial value, or chan-def */ + Lextok *Slst; /* template for structure if struct */ + struct Symbol *mtype_name; /* if type == MTYPE else nil */ + struct Symbol *Snm; /* name of the defining struct */ + struct Symbol *owner; /* set for names of subfields in typedefs */ + struct Symbol *context; /* 0 if global, or procname */ + struct Symbol *next; /* linked list */ } Symbol; -typedef struct Ordered { /* links all names in Symbol table */ - struct Symbol *entry; - struct Ordered *next; +typedef struct Ordered { /* links all names in Symbol table */ + struct Symbol *entry; + struct Ordered *next; } Ordered; typedef struct Mtypes_t { - char *nm; /* name of mtype, or "_unnamed_" */ - Lextok *mt; /* the linked list of names */ - struct Mtypes_t *nxt; /* linked list of mtypes */ + char *nm; /* name of mtype, or "_unnamed_" */ + Lextok *mt; /* the linked list of names */ + struct Mtypes_t *nxt; /* linked list of mtypes */ } Mtypes_t; typedef struct Queue { - short qid; /* runtime q index */ - int qlen; /* nr messages stored */ - int nslots, nflds; /* capacity, flds/slot */ - int setat; /* last depth value changed */ - int *fld_width; /* type of each field */ - int *contents; /* the values stored */ - int *stepnr; /* depth when each msg was sent */ - char **mtp; /* if mtype, name of list, else 0 */ - struct Queue *nxt; /* linked list */ + short qid; /* runtime q index */ + int qlen; /* nr messages stored */ + int nslots, nflds; /* capacity, flds/slot */ + int setat; /* last depth value changed */ + int *fld_width; /* type of each field */ + int *contents; /* the values stored */ + int *stepnr; /* depth when each msg was sent */ + char **mtp; /* if mtype, name of list, else 0 */ + struct Queue *nxt; /* linked list */ } Queue; -typedef struct FSM_state { /* used in pangen5.c - dataflow */ - int from; /* state number */ - int seen; /* used for dfs */ - int in; /* nr of incoming edges */ - int cr; /* has reachable 1-relevant successor */ - int scratch; - unsigned long *dom, *mod; /* to mark dominant nodes */ - struct FSM_trans *t; /* outgoing edges */ - struct FSM_trans *p; /* incoming edges, predecessors */ - struct FSM_state *nxt; /* linked list of all states */ +typedef struct FSM_state { /* used in pangen5.c - dataflow */ + int from; /* state number */ + int seen; /* used for dfs */ + int in; /* nr of incoming edges */ + int cr; /* has reachable 1-relevant successor */ + int scratch; + unsigned long *dom, *mod; /* to mark dominant nodes */ + struct FSM_trans *t; /* outgoing edges */ + struct FSM_trans *p; /* incoming edges, predecessors */ + struct FSM_state *nxt; /* linked list of all states */ } FSM_state; -typedef struct FSM_trans { /* used in pangen5.c - dataflow */ - int to; - short relevant; /* when sliced */ - short round; /* ditto: iteration when marked */ - struct FSM_use *Val[2]; /* 0=reads, 1=writes */ - struct Element *step; - struct FSM_trans *nxt; +typedef struct FSM_trans { /* used in pangen5.c - dataflow */ + int to; + short relevant; /* when sliced */ + short round; /* ditto: iteration when marked */ + struct FSM_use *Val[2]; /* 0=reads, 1=writes */ + struct Element *step; + struct FSM_trans *nxt; } FSM_trans; -typedef struct FSM_use { /* used in pangen5.c - dataflow */ - Lextok *n; - Symbol *var; - int special; - struct FSM_use *nxt; +typedef struct FSM_use { /* used in pangen5.c - dataflow */ + Lextok *n; + Symbol *var; + int special; + struct FSM_use *nxt; } FSM_use; typedef struct Element { - Lextok *n; /* defines the type & contents */ - int Seqno; /* identifies this el within system */ - int seqno; /* identifies this el within a proc */ - int merge; /* set by -O if step can be merged */ - int merge_start; - int merge_single; - short merge_in; /* nr of incoming edges */ - short merge_mark; /* state was generated in merge sequence */ - unsigned int status; /* used by analyzer generator */ - struct FSM_use *dead; /* optional dead variable list */ - struct SeqList *sub; /* subsequences, for compounds */ - struct SeqList *esc; /* zero or more escape sequences */ - struct Element *Nxt; /* linked list - for global lookup */ - struct Element *nxt; /* linked list - program structure */ + Lextok *n; /* defines the type & contents */ + int Seqno; /* identifies this el within system */ + int seqno; /* identifies this el within a proc */ + int merge; /* set by -O if step can be merged */ + int merge_start; + int merge_single; + short merge_in; /* nr of incoming edges */ + short merge_mark; /* state was generated in merge sequence */ + unsigned int status; /* used by analyzer generator */ + struct FSM_use *dead; /* optional dead variable list */ + struct SeqList *sub; /* subsequences, for compounds */ + struct SeqList *esc; /* zero or more escape sequences */ + struct Element *Nxt; /* linked list - for global lookup */ + struct Element *nxt; /* linked list - program structure */ } Element; typedef struct Sequence { - Element *frst; - Element *last; /* links onto continuations */ - Element *extent; /* last element in original */ - int minel; /* minimum Seqno, set and used only in guided.c */ - int maxel; /* 1+largest id in sequence */ + Element *frst; + Element *last; /* links onto continuations */ + Element *extent; /* last element in original */ + int minel; /* minimum Seqno, set and used only in guided.c */ + int maxel; /* 1+largest id in sequence */ } Sequence; typedef struct SeqList { - Sequence *this; /* one sequence */ - struct SeqList *nxt; /* linked list */ + Sequence *thisS; /* one sequence */ + struct SeqList *nxt; /* linked list */ } SeqList; typedef struct Label { - Symbol *s; - Symbol *c; - Element *e; - int uiid; /* non-zero if label appears in an inline */ - int visible; /* label referenced in claim (slice relevant) */ - struct Label *nxt; + Symbol *s; + Symbol *c; + Element *e; + int uiid; /* non-zero if label appears in an inline */ + int visible; /* label referenced in claim (slice relevant) */ + struct Label *nxt; } Label; typedef struct Lbreak { - Symbol *l; - struct Lbreak *nxt; + Symbol *l; + struct Lbreak *nxt; } Lbreak; typedef struct L_List { - Lextok *n; - struct L_List *nxt; + Lextok *n; + struct L_List *nxt; } L_List; typedef struct RunList { - Symbol *n; /* name */ - int tn; /* ordinal of type */ - int pid; /* process id */ - int priority; /* for simulations only */ - enum btypes b; /* the type of process */ - Element *pc; /* current stmnt */ - Sequence *ps; /* used by analyzer generator */ - Lextok *prov; /* provided clause */ - Symbol *symtab; /* local variables */ - struct RunList *nxt; /* linked list */ + Symbol *n; /* name */ + int tn; /* ordinal of type */ + int pid; /* process id */ + int priority; /* for simulations only */ + enum btypes b; /* the type of process */ + Element *pc; /* current stmnt */ + Sequence *ps; /* used by analyzer generator */ + Lextok *prov; /* provided clause */ + Symbol *symtab; /* local variables */ + struct RunList *nxt; /* linked list */ } RunList; typedef struct ProcList { - Symbol *n; /* name */ - Lextok *p; /* parameters */ - Sequence *s; /* body */ - Lextok *prov; /* provided clause */ - enum btypes b; /* e.g., claim, trace, proc */ - short tn; /* ordinal number */ - unsigned char det; /* deterministic */ - unsigned char unsafe; /* contains global var inits */ - unsigned char priority; /* process priority, if any */ - struct ProcList *nxt; /* linked list */ + Symbol *n; /* name */ + Lextok *p; /* parameters */ + Sequence *s; /* body */ + Lextok *prov; /* provided clause */ + enum btypes b; /* e.g., claim, trace, proc */ + short tn; /* ordinal number */ + unsigned char det; /* deterministic */ + unsigned char unsafe; /* contains global var inits */ + unsigned char priority; /* process priority, if any */ + struct ProcList *nxt; /* linked list */ } ProcList; typedef struct QH { - int n; - struct QH *nxt; + int n; + struct QH *nxt; } QH; -typedef Lextok *Lexptr; +typedef Lextok *Lexptr; -#define YYSTYPE Lexptr +#define YYSTYPE Lexptr -#define ZN (Lextok *)0 -#define ZS (Symbol *)0 -#define ZE (Element *)0 +#define ZN (Lextok *)0 +#define ZS (Symbol *)0 +#define ZE (Element *)0 -#define DONE 1 /* status bits of elements */ -#define ATOM 2 /* part of an atomic chain */ -#define L_ATOM 4 /* last element in a chain */ -#define I_GLOB 8 /* inherited global ref */ -#define DONE2 16 /* used in putcode and main*/ -#define D_ATOM 32 /* deterministic atomic */ -#define ENDSTATE 64 /* normal endstate */ -#define CHECK2 128 /* status bits for remote ref check */ -#define CHECK3 256 /* status bits for atomic jump check */ +#define DONE 1 /* status bits of elements */ +#define ATOM 2 /* part of an atomic chain */ +#define L_ATOM 4 /* last element in a chain */ +#define I_GLOB 8 /* inherited global ref */ +#define DONE2 16 /* used in putcode and main*/ +#define D_ATOM 32 /* deterministic atomic */ +#define ENDSTATE 64 /* normal endstate */ +#define CHECK2 128 /* status bits for remote ref check */ +#define CHECK3 256 /* status bits for atomic jump check */ -#define Nhash 255 /* slots in symbol hash-table */ +#define Nhash 255 /* slots in symbol hash-table */ -#define XR 1 /* non-shared receive-only */ -#define XS 2 /* non-shared send-only */ -#define XX 4 /* overrides XR or XS tag */ +#define XR 1 /* non-shared receive-only */ +#define XS 2 /* non-shared send-only */ +#define XX 4 /* overrides XR or XS tag */ -#define CODE_FRAG 2 /* auto-numbered code-fragment */ -#define CODE_DECL 4 /* auto-numbered c_decl */ -#define PREDEF 3 /* predefined name: _p, _last */ +#define CODE_FRAG 2 /* auto-numbered code-fragment */ +#define CODE_DECL 4 /* auto-numbered c_decl */ +#define PREDEF 3 /* predefined name: _p, _last */ -#define UNSIGNED 5 /* val defines width in bits */ -#define BIT 1 /* also equal to width in bits */ -#define BYTE 8 /* ditto */ -#define SHORT 16 /* ditto */ -#define INT 32 /* ditto */ -#define CHAN 64 /* not */ -#define STRUCT 128 /* user defined structure name */ +#define UNSIGNED 5 /* val defines width in bits */ +#define BIT 1 /* also equal to width in bits */ +#define BYTE 8 /* ditto */ +#define SHORT 16 /* ditto */ +#define INT 32 /* ditto */ +#define CHAN 64 /* not */ +#define STRUCT 128 /* user defined structure name */ -#define SOMETHINGBIG 65536 -#define RATHERSMALL 512 -#define MAXSCOPESZ 1024 +#define SOMETHINGBIG 65536 +#define RATHERSMALL 512 +#define MAXSCOPESZ 1024 -#ifndef max - #define max(a,b) (((a)<(b)) ? (b) : (a)) +#ifdef max + #error Your C compiler is broken - it defines max +#else + #ifdef __cplusplus + #include + #define MaX std::max + #else + inline int MaX(int a, int b) {return a #include -#define YYMAXDEPTH 20000 /* default is 10000 */ -#define YYDEBUG 0 -#define Stop nn(ZN,'@',ZN,ZN) -#define PART0 "place initialized declaration of " -#define PART1 "place initialized chan decl of " -#define PART2 " at start of proctype " - -static Lextok *ltl_to_string(Lextok *); - -extern Symbol *context, *owner; -extern Lextok *for_body(Lextok *, int); -extern void for_setup(Lextok *, Lextok *, Lextok *); -extern Lextok *for_index(Lextok *, Lextok *); -extern Lextok *sel_index(Lextok *, Lextok *, Lextok *); +#define YYMAXDEPTH 20000 /* default is 10000 */ +#define YYDEBUG 0 +#define Stop nn(ZN,'@',ZN,ZN) +#define PART0 "place initialized declaration of " +#define PART1 "place initialized chan decl of " +#define PART2 " at start of proctype " + +static Lextok *ltl_to_string(Lextok *); + +extern Symbol *context, *owner; +extern Lextok *for_body(Lextok *, int); +extern void for_setup(Lextok *, Lextok *, Lextok *); +extern Lextok *for_index(Lextok *, Lextok *); +extern Lextok *sel_index(Lextok *, Lextok *, Lextok *); extern void keep_track_off(Lextok *); -extern void safe_break(void); -extern void restore_break(void); -extern int u_sync, u_async, dumptab, scope_level; -extern int initialization_ok; -extern short has_sorted, has_random, has_enabled, has_pcvalue, has_np, has_priority; -extern short has_code, has_state, has_ltl, has_io; -extern void check_mtypes(Lextok *, Lextok *); -extern void count_runs(Lextok *); -extern void no_internals(Lextok *); -extern void any_runs(Lextok *); -extern void explain(int); -extern void ltl_list(char *, char *); -extern void validref(Lextok *, Lextok *); -extern void sanity_check(Lextok *); -extern char yytext[]; - -int Mpars = 0; /* max nr of message parameters */ -int nclaims = 0; /* nr of never claims */ -int ltl_mode = 0; /* set when parsing an ltl formula */ -int Expand_Ok = 0, realread = 1, IArgs = 0, NamesNotAdded = 0; -int in_for = 0, in_seq = 0, par_cnt = 0; -int dont_simplify = 0; -char *claimproc = (char *) 0; -char *eventmap = (char *) 0; - -static char *ltl_name; -static int Embedded = 0, inEventMap = 0, has_ini = 0; +extern void safe_break(void); +extern void restore_break(void); +extern int u_sync, u_async, dumptab, scope_level; +extern int initialization_ok; +extern short has_sorted, has_random, has_enabled, has_pcvalue, has_np, has_priority; +extern short has_code, has_state, has_ltl, has_io; +extern void check_mtypes(Lextok *, Lextok *); +extern void count_runs(Lextok *); +extern void no_internals(Lextok *); +extern void any_runs(Lextok *); +extern void explain(int); +extern void ltl_list(const char *, const char *); +extern void validref(Lextok *, Lextok *); +extern void sanity_check(Lextok *); +extern char yytext[]; + +int Mpars = 0; /* max nr of message parameters */ +int nclaims = 0; /* nr of never claims */ +int ltl_mode = 0; /* set when parsing an ltl formula */ +int Expand_Ok = 0, realread = 1, IArgs = 0, NamesNotAdded = 0; +int in_for = 0, in_seq = 0, par_cnt = 0; +int dont_simplify = 0; +const char *claimproc = (char *) 0; +const char *eventmap = (char *) 0; + +static const char *ltl_name; +static int Embedded = 0, inEventMap = 0, has_ini = 0; %} -%token ASSERT PRINT PRINTM PREPROC -%token C_CODE C_DECL C_EXPR C_STATE C_TRACK -%token RUN LEN ENABLED SET_P GET_P EVAL PC_VAL -%token TYPEDEF MTYPE INLINE RETURN LABEL OF -%token GOTO BREAK ELSE SEMI ARROW -%token IF FI DO OD FOR SELECT IN SEP DOTDOT -%token ATOMIC NON_ATOMIC D_STEP UNLESS +%token ASSERT PRINT PRINTM PREPROC +%token C_CODE C_DECL C_EXPR C_STATE C_TRACK +%token RUN LEN ENABLED SET_P GET_P EVAL PC_VAL +%token TYPEDEF MTYPE INLINE RETURN LABEL OF +%token GOTO BREAK ELSE SEMI ARROW +%token IF FI DO OD FOR SELECT IN SEP DOTDOT +%token ATOMIC NON_ATOMIC D_STEP UNLESS %token TIMEOUT NONPROGRESS -%token ACTIVE PROCTYPE D_PROCTYPE -%token HIDDEN SHOW ISLOCAL -%token PRIORITY PROVIDED -%token FULL EMPTY NFULL NEMPTY -%token CONST TYPE XU /* val */ -%token NAME UNAME PNAME INAME /* sym */ -%token STRING CLAIM TRACE INIT LTL /* sym */ - -%right ASGN -%left SND O_SND RCV R_RCV /* SND doubles as boolean negation */ -%left IMPLIES EQUIV /* ltl */ -%left OR -%left AND -%left ALWAYS EVENTUALLY /* ltl */ -%left UNTIL WEAK_UNTIL RELEASE /* ltl */ -%right NEXT /* ltl */ -%left '|' -%left '^' -%left '&' -%left EQ NE -%left GT LT GE LE -%left LSHIFT RSHIFT -%left '+' '-' -%left '*' '/' '%' -%left INCR DECR -%right '~' UMIN NEG -%left DOT +%token ACTIVE PROCTYPE D_PROCTYPE +%token HIDDEN SHOW ISLOCAL +%token PRIORITY PROVIDED +%token FULL EMPTY NFULL NEMPTY +%token CONST TYPE XU /* val */ +%token NAME UNAME PNAME INAME /* sym */ +%token STRING CLAIM TRACE INIT LTL /* sym */ + +%right ASGN +%left SND O_SND RCV R_RCV /* SND doubles as boolean negation */ +%left IMPLIES EQUIV /* ltl */ +%left OR +%left AND +%left ALWAYS EVENTUALLY /* ltl */ +%left UNTIL WEAK_UNTIL RELEASE /* ltl */ +%right NEXT /* ltl */ +%left '|' +%left '^' +%left '&' +%left EQ NE +%left GT LT GE LE +%left LSHIFT RSHIFT +%left '+' '-' +%left '*' '/' '%' +%left INCR DECR +%right '~' UMIN NEG +%left DOT %% /** PROMELA Grammar Rules **/ -program : units { yytext[0] = '\0'; } - ; - -units : unit - | units unit - ; - -unit : proc /* proctype { } */ - | init /* init { } */ - | claim /* never claim */ - | ltl /* ltl formula */ - | events /* event assertions */ - | one_decl /* variables, chans */ - | utype /* user defined types */ - | c_fcts /* c functions etc. */ - | ns /* named sequence */ - | semi /* optional separator */ - | error - ; - -l_par : '(' { par_cnt++; } - ; - -r_par : ')' { par_cnt--; } - ; - - -proc : inst /* optional instantiator */ - proctype NAME { - setptype(ZN, $3, PROCTYPE, ZN); - setpname($3); - context = $3->sym; - context->ini = $2; /* linenr and file */ - Expand_Ok++; /* expand struct names in decl */ - has_ini = 0; - } - l_par decl r_par { Expand_Ok--; - if (has_ini) - fatal("initializer in parameter list", (char *) 0); - } - Opt_priority - Opt_enabler - body { ProcList *rl; - if ($1 != ZN && $1->val > 0) - { int j; - rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, A_PROC); - for (j = 0; j < $1->val; j++) - { runnable(rl, $9?$9->val:1, 1); - announce(":root:"); - } - if (dumptab) $3->sym->ini = $1; - } else - { rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, P_PROC); - } - if (rl && has_ini == 1) /* global initializations, unsafe */ - { /* printf("proctype %s has initialized data\n", - $3->sym->name); - */ - rl->unsafe = 1; - } - context = ZS; - } - ; - -proctype: PROCTYPE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 0; } - | D_PROCTYPE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 1; } - ; - -inst : /* empty */ { $$ = ZN; } - | ACTIVE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 1; } - | ACTIVE '[' const_expr ']' { - $$ = nn(ZN,CONST,ZN,ZN); $$->val = $3->val; - if ($3->val > 255) - non_fatal("max nr of processes is 255\n", ""); - } - | ACTIVE '[' NAME ']' { - $$ = nn(ZN,CONST,ZN,ZN); - $$->val = 0; - if (!$3->sym->type) - fatal("undeclared variable %s", - $3->sym->name); - else if ($3->sym->ini->ntyp != CONST) - fatal("need constant initializer for %s\n", - $3->sym->name); - else - $$->val = $3->sym->ini->val; - } - ; - -init : INIT { context = $1->sym; } - Opt_priority - body { ProcList *rl; - rl = mk_rdy(context, ZN, $4->sq, 0, ZN, I_PROC); - runnable(rl, $3?$3->val:1, 1); - announce(":root:"); - context = ZS; - } - ; - -ltl : LTL optname2 { ltl_mode = 1; ltl_name = $2->sym->name; } - ltl_body { if ($4) ltl_list($2->sym->name, $4->sym->name); - ltl_mode = 0; has_ltl = 1; - } - ; +program : units { yytext[0] = '\0'; } + ; + +units : unit + | units unit + ; + +unit : proc /* proctype { } */ + | init /* init { } */ + | claim /* never claim */ + | ltl /* ltl formula */ + | events /* event assertions */ + | one_decl /* variables, chans */ + | utype /* user defined types */ + | c_fcts /* c functions etc. */ + | ns /* named sequence */ + | semi /* optional separator */ + | error + ; + +l_par : '(' { par_cnt++; } + ; + +r_par : ')' { par_cnt--; } + ; + + +proc : inst /* optional instantiator */ + proctype NAME { + setptype(ZN, $3, PROCTYPE, ZN); + setpname($3); + context = $3->sym; + context->ini = $2; /* linenr and file */ + Expand_Ok++; /* expand struct names in decl */ + has_ini = 0; + } + l_par decl r_par { Expand_Ok--; + if (has_ini) + fatal("initializer in parameter list", (char *) 0); + } + Opt_priority + Opt_enabler + body { ProcList *rl; + if ($1 != ZN && $1->val > 0) + { int j; + rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, A_PROC); + for (j = 0; j < $1->val; j++) + { runnable(rl, $9?$9->val:1, 1); + announce(":root:"); + } + if (dumptab) $3->sym->ini = $1; + } else + { rl = mk_rdy($3->sym, $6, $11->sq, $2->val, $10, P_PROC); + } + if (rl && has_ini == 1) /* global initializations, unsafe */ + { /* printf("proctype %s has initialized data\n", + $3->sym->name); + */ + rl->unsafe = 1; + } + context = ZS; + } + ; + +proctype: PROCTYPE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 0; } + | D_PROCTYPE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 1; } + ; + +inst : /* empty */ { $$ = ZN; } + | ACTIVE { $$ = nn(ZN,CONST,ZN,ZN); $$->val = 1; } + | ACTIVE '[' const_expr ']' { + $$ = nn(ZN,CONST,ZN,ZN); $$->val = $3->val; + if ($3->val > 255) + non_fatal("max nr of processes is 255\n", ""); + } + | ACTIVE '[' NAME ']' { + $$ = nn(ZN,CONST,ZN,ZN); + $$->val = 0; + if (!$3->sym->type) + fatal("undeclared variable %s", + $3->sym->name); + else if ($3->sym->ini->ntyp != CONST) + fatal("need constant initializer for %s\n", + $3->sym->name); + else + $$->val = $3->sym->ini->val; + } + ; + +init : INIT { context = $1->sym; } + Opt_priority + body { ProcList *rl; + rl = mk_rdy(context, ZN, $4->sq, 0, ZN, I_PROC); + runnable(rl, $3?$3->val:1, 1); + announce(":root:"); + context = ZS; + } + ; + +ltl : LTL optname2 { ltl_mode = 1; ltl_name = $2->sym->name; } + ltl_body { if ($4) ltl_list($2->sym->name, $4->sym->name); + ltl_mode = 0; has_ltl = 1; + } + ; ltl_body: '{' full_expr OS '}' { $$ = ltl_to_string($2); } - | error { $$ = NULL; } - ; - -claim : CLAIM optname { if ($2 != ZN) - { $1->sym = $2->sym; /* new 5.3.0 */ - } - nclaims++; - context = $1->sym; - if (claimproc && !strcmp(claimproc, $1->sym->name)) - { fatal("claim %s redefined", claimproc); - } - claimproc = $1->sym->name; - } - body { (void) mk_rdy($1->sym, ZN, $4->sq, 0, ZN, N_CLAIM); - context = ZS; - } - ; - -optname : /* empty */ { char tb[32]; - memset(tb, 0, 32); - sprintf(tb, "never_%d", nclaims); - $$ = nn(ZN, NAME, ZN, ZN); - $$->sym = lookup(tb); - } - | NAME { $$ = $1; } - ; + | error { $$ = NULL; } + ; + +claim : CLAIM optname { if ($2 != ZN) + { $1->sym = $2->sym; /* new 5.3.0 */ + } + nclaims++; + context = $1->sym; + if (claimproc && !strcmp(claimproc, $1->sym->name)) + { fatal("claim %s redefined", claimproc); + } + claimproc = $1->sym->name; + } + body { (void) mk_rdy($1->sym, ZN, $4->sq, 0, ZN, N_CLAIM); + context = ZS; + } + ; + +optname : /* empty */ { char tb[32]; + memset(tb, 0, 32); + sprintf(tb, "never_%d", nclaims); + $$ = nn(ZN, NAME, ZN, ZN); + $$->sym = lookup(tb); + } + | NAME { $$ = $1; } + ; optname2 : /* empty */ { char tb[32]; static int nltl = 0; - memset(tb, 0, 32); - sprintf(tb, "ltl_%d", nltl++); - $$ = nn(ZN, NAME, ZN, ZN); - $$->sym = lookup(tb); - } - | NAME { $$ = $1; } - ; - -events : TRACE { context = $1->sym; - if (eventmap) - non_fatal("trace %s redefined", eventmap); - eventmap = $1->sym->name; - inEventMap++; - } - body { - if (strcmp($1->sym->name, ":trace:") == 0) - { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, E_TRACE); - } else - { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, N_TRACE); - } - context = ZS; - inEventMap--; - } - ; - -utype : TYPEDEF NAME '{' { if (context) - { fatal("typedef %s must be global", - $2->sym->name); - } - owner = $2->sym; - in_seq = $1->ln; - } - decl_lst '}' { setuname($5); - owner = ZS; - in_seq = 0; - } - ; - -nm : NAME { $$ = $1; } - | INAME { $$ = $1; - if (IArgs) - fatal("invalid use of '%s'", $1->sym->name); - } - ; - -ns : INLINE nm l_par { NamesNotAdded++; } - args r_par { prep_inline($2->sym, $5); - NamesNotAdded--; - } - ; - -c_fcts : ccode { /* leaves pseudo-inlines with sym of - * type CODE_FRAG or CODE_DECL in global context - */ - } - | cstate - ; - -cstate : C_STATE STRING STRING { - c_state($2->sym, $3->sym, ZS); - has_code = has_state = 1; - } - | C_TRACK STRING STRING { - c_track($2->sym, $3->sym, ZS); - has_code = has_state = 1; - } - | C_STATE STRING STRING STRING { - c_state($2->sym, $3->sym, $4->sym); - has_code = has_state = 1; - } - | C_TRACK STRING STRING STRING { - c_track($2->sym, $3->sym, $4->sym); - has_code = has_state = 1; - } - ; - -ccode : C_CODE { Symbol *s; - NamesNotAdded++; - s = prep_inline(ZS, ZN); - NamesNotAdded--; - $$ = nn(ZN, C_CODE, ZN, ZN); - $$->sym = s; - $$->ln = $1->ln; - $$->fn = $1->fn; - has_code = 1; - } - | C_DECL { Symbol *s; - NamesNotAdded++; - s = prep_inline(ZS, ZN); - NamesNotAdded--; - s->type = CODE_DECL; - $$ = nn(ZN, C_CODE, ZN, ZN); - $$->sym = s; - $$->ln = $1->ln; - $$->fn = $1->fn; - has_code = 1; - } - ; -cexpr : C_EXPR { Symbol *s; - NamesNotAdded++; - s = prep_inline(ZS, ZN); + memset(tb, 0, 32); + sprintf(tb, "ltl_%d", nltl++); + $$ = nn(ZN, NAME, ZN, ZN); + $$->sym = lookup(tb); + } + | NAME { $$ = $1; } + ; + +events : TRACE { context = $1->sym; + if (eventmap) + non_fatal("trace %s redefined", eventmap); + eventmap = $1->sym->name; + inEventMap++; + } + body { + if (strcmp($1->sym->name, ":trace:") == 0) + { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, E_TRACE); + } else + { (void) mk_rdy($1->sym, ZN, $3->sq, 0, ZN, N_TRACE); + } + context = ZS; + inEventMap--; + } + ; + +utype : TYPEDEF NAME '{' { if (context) + { fatal("typedef %s must be global", + $2->sym->name); + } + owner = $2->sym; + in_seq = $1->ln; + } + decl_lst '}' { setuname($5); + owner = ZS; + in_seq = 0; + } + ; + +nm : NAME { $$ = $1; } + | INAME { $$ = $1; + if (IArgs) + fatal("invalid use of '%s'", $1->sym->name); + } + ; + +ns : INLINE nm l_par { NamesNotAdded++; } + args r_par { prep_inline($2->sym, $5); + NamesNotAdded--; + } + ; + +c_fcts : ccode { /* leaves pseudo-inlines with sym of + * type CODE_FRAG or CODE_DECL in global context + */ + } + | cstate + ; + +cstate : C_STATE STRING STRING { + c_state($2->sym, $3->sym, ZS); + has_code = has_state = 1; + } + | C_TRACK STRING STRING { + c_track($2->sym, $3->sym, ZS); + has_code = has_state = 1; + } + | C_STATE STRING STRING STRING { + c_state($2->sym, $3->sym, $4->sym); + has_code = has_state = 1; + } + | C_TRACK STRING STRING STRING { + c_track($2->sym, $3->sym, $4->sym); + has_code = has_state = 1; + } + ; + +ccode : C_CODE { Symbol *s; + NamesNotAdded++; + s = prep_inline(ZS, ZN); + NamesNotAdded--; + $$ = nn(ZN, C_CODE, ZN, ZN); + $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; + has_code = 1; + } + | C_DECL { Symbol *s; + NamesNotAdded++; + s = prep_inline(ZS, ZN); + NamesNotAdded--; + s->type = CODE_DECL; + $$ = nn(ZN, C_CODE, ZN, ZN); + $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; + has_code = 1; + } + ; +cexpr : C_EXPR { Symbol *s; + NamesNotAdded++; + s = prep_inline(ZS, ZN); /* if context is 0 this was inside an ltl formula mark the last inline added to seqnames */ - if (!context) - { mark_last(); - } - NamesNotAdded--; - $$ = nn(ZN, C_EXPR, ZN, ZN); - $$->sym = s; - $$->ln = $1->ln; - $$->fn = $1->fn; - no_side_effects(s->name); - has_code = 1; - } - ; - -body : '{' { open_seq(1); in_seq = $1->ln; } - sequence OS { add_seq(Stop); } - '}' { $$->sq = close_seq(0); in_seq = 0; - if (scope_level != 0) - { non_fatal("missing '}' ?", 0); - scope_level = 0; - } - } - ; - -sequence: step { if ($1) add_seq($1); } - | sequence MS step { if ($3) add_seq($3); } - ; - -step : one_decl { $$ = ZN; } - | XU vref_lst { setxus($2, $1->val); $$ = ZN; } - | NAME ':' one_decl { fatal("label preceding declaration,", (char *)0); } - | NAME ':' XU { fatal("label preceding xr/xs claim,", 0); } - | stmnt { $$ = $1; } - | stmnt UNLESS { if ($1->ntyp == DO) { safe_break(); } } - stmnt { if ($1->ntyp == DO) { restore_break(); } - $$ = do_unless($1, $4); - } - | error - ; - -vis : /* empty */ { $$ = ZN; } - | HIDDEN { $$ = $1; } - | SHOW { $$ = $1; } - | ISLOCAL { $$ = $1; } - ; - -asgn : /* empty */ { $$ = ZN; } - | ':' NAME ASGN { $$ = $2; /* mtype decl */ } - | ASGN { $$ = ZN; /* mtype decl */ } - ; - -osubt : /* empty */ { $$ = ZN; } - | ':' NAME { $$ = $2; } - ; + if (!context) + { mark_last(); + } + NamesNotAdded--; + $$ = nn(ZN, C_EXPR, ZN, ZN); + $$->sym = s; + $$->ln = $1->ln; + $$->fn = $1->fn; + no_side_effects(s->name); + has_code = 1; + } + ; + +body : '{' { open_seq(1); in_seq = $1->ln; } + sequence OS { add_seq(Stop); } + '}' { $$->sq = close_seq(0); in_seq = 0; + if (scope_level != 0) + { non_fatal("missing '}' ?", 0); + scope_level = 0; + } + } + ; + +sequence: step { if ($1) add_seq($1); } + | sequence MS step { if ($3) add_seq($3); } + ; + +step : one_decl { $$ = ZN; } + | XU vref_lst { setxus($2, $1->val); $$ = ZN; } + | NAME ':' one_decl { fatal("label preceding declaration,", (char *)0); } + | NAME ':' XU { fatal("label preceding xr/xs claim,", 0); } + | stmnt { $$ = $1; } + | stmnt UNLESS { if ($1->ntyp == DO) { safe_break(); } } + stmnt { if ($1->ntyp == DO) { restore_break(); } + $$ = do_unless($1, $4); + } + | error + ; + +vis : /* empty */ { $$ = ZN; } + | HIDDEN { $$ = $1; } + | SHOW { $$ = $1; } + | ISLOCAL { $$ = $1; } + ; + +asgn : /* empty */ { $$ = ZN; } + | ':' NAME ASGN { $$ = $2; /* mtype decl */ } + | ASGN { $$ = ZN; /* mtype decl */ } + ; + +osubt : /* empty */ { $$ = ZN; } + | ':' NAME { $$ = $2; } + ; one_decl: vis TYPE osubt var_list { - setptype($3, $4, $2->val, $1); - $4->val = $2->val; - $$ = $4; - } - | vis UNAME var_list { setutype($3, $2->sym, $1); - $$ = expand($3, Expand_Ok); - } - | vis TYPE asgn '{' nlst '}' { - if ($2->val != MTYPE) - fatal("malformed declaration", 0); - setmtype($3, $5); - if ($1) - non_fatal("cannot %s mtype (ignored)", - $1->sym->name); - if (context != ZS) - fatal("mtype declaration must be global", 0); - } - ; - -decl_lst: one_decl { $$ = nn(ZN, ',', $1, ZN); } - | one_decl SEMI - decl_lst { $$ = nn(ZN, ',', $1, $3); } - ; - -decl : /* empty */ { $$ = ZN; } - | decl_lst { $$ = $1; } - ; - -vref_lst: varref { $$ = nn($1, XU, $1, ZN); } - | varref ',' vref_lst { $$ = nn($1, XU, $1, $3); } - ; - -var_list: ivar { $$ = nn($1, TYPE, ZN, ZN); } - | ivar ',' var_list { $$ = nn($1, TYPE, ZN, $3); } - ; - -c_list : CONST { $1->ntyp = CONST; $$ = $1; } - | CONST ',' c_list { $1->ntyp = CONST; $$ = nn($1, ',', $1, $3); } - ; - -ivar : vardcl { $$ = $1; - $1->sym->ini = nn(ZN,CONST,ZN,ZN); - $1->sym->ini->val = 0; - if (!initialization_ok) - { Lextok *zx, *xz; - zx = nn(ZN, NAME, ZN, ZN); - zx->sym = $1->sym; - xz = nn(zx, ASGN, zx, $1->sym->ini); - keep_track_off(xz); - /* make sure zx doesnt turn out to be a STRUCT later */ - add_seq(xz); - } - } - | vardcl ASGN '{' c_list '}' { /* array initialization */ - if (!$1->sym->isarray) - fatal("%s must be an array", $1->sym->name); - $$ = $1; - $1->sym->ini = $4; - has_ini = 1; - $1->sym->hidden |= (4|8); /* conservative */ - if (!initialization_ok) - { Lextok *zx = nn(ZN, NAME, ZN, ZN); - zx->sym = $1->sym; - add_seq(nn(zx, ASGN, zx, $4)); - } - } - | vardcl ASGN expr { $$ = $1; /* initialized scalar */ - $1->sym->ini = $3; - if ($3->ntyp == CONST - || ($3->ntyp == NAME && $3->sym->context)) - { has_ini = 2; /* local init */ - } else - { has_ini = 1; /* possibly global */ - } - trackvar($1, $3); - if (any_oper($3, RUN)) - { fatal("cannot use 'run' in var init, saw", (char *) 0); - } - nochan_manip($1, $3, 0); - no_internals($1); - if (!initialization_ok) - { if ($1->sym->isarray) - { fprintf(stderr, "warning: %s:%d initialization of %s[] ", - $1->fn->name, $1->ln, - $1->sym->name); - fprintf(stderr, "could fail if placed here\n"); - } else - { Lextok *zx = nn(ZN, NAME, ZN, ZN); - zx->sym = $1->sym; - add_seq(nn(zx, ASGN, zx, $3)); - $1->sym->ini = 0; /* Patrick Trentlin */ - } } - } - | vardcl ASGN ch_init { $1->sym->ini = $3; /* channel declaration */ - $$ = $1; has_ini = 1; - if (!initialization_ok) - { non_fatal(PART1 "'%s'" PART2, $1->sym->name); - } - } - ; + setptype($3, $4, $2->val, $1); + $4->val = $2->val; + $$ = $4; + } + | vis UNAME var_list { setutype($3, $2->sym, $1); + $$ = expand($3, Expand_Ok); + } + | vis TYPE asgn '{' nlst '}' { + if ($2->val != MTYPE) + fatal("malformed declaration", 0); + setmtype($3, $5); + if ($1) + non_fatal("cannot %s mtype (ignored)", + $1->sym->name); + if (context != ZS) + fatal("mtype declaration must be global", 0); + } + ; + +decl_lst: one_decl { $$ = nn(ZN, ',', $1, ZN); } + | one_decl SEMI + decl_lst { $$ = nn(ZN, ',', $1, $3); } + ; + +decl : /* empty */ { $$ = ZN; } + | decl_lst { $$ = $1; } + ; + +vref_lst: varref { $$ = nn($1, XU, $1, ZN); } + | varref ',' vref_lst { $$ = nn($1, XU, $1, $3); } + ; + +var_list: ivar { $$ = nn($1, TYPE, ZN, ZN); } + | ivar ',' var_list { $$ = nn($1, TYPE, ZN, $3); } + ; + +c_list : CONST { $1->ntyp = CONST; $$ = $1; } + | CONST ',' c_list { $1->ntyp = CONST; $$ = nn($1, ',', $1, $3); } + ; + +ivar : vardcl { $$ = $1; + $1->sym->ini = nn(ZN,CONST,ZN,ZN); + $1->sym->ini->val = 0; + if (!initialization_ok) + { Lextok *zx, *xz; + zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + xz = nn(zx, ASGN, zx, $1->sym->ini); + keep_track_off(xz); + /* make sure zx doesnt turn out to be a STRUCT later */ + add_seq(xz); + } + } + | vardcl ASGN '{' c_list '}' { /* array initialization */ + if (!$1->sym->isarray) + fatal("%s must be an array", $1->sym->name); + $$ = $1; + $1->sym->ini = $4; + has_ini = 1; + $1->sym->hidden |= (4|8); /* conservative */ + if (!initialization_ok) + { Lextok *zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + add_seq(nn(zx, ASGN, zx, $4)); + } + } + | vardcl ASGN expr { $$ = $1; /* initialized scalar */ + $1->sym->ini = $3; + if ($3->ntyp == CONST + || ($3->ntyp == NAME && $3->sym->context)) + { has_ini = 2; /* local init */ + } else + { has_ini = 1; /* possibly global */ + } + trackvar($1, $3); + if (any_oper($3, RUN)) + { fatal("cannot use 'run' in var init, saw", (char *) 0); + } + nochan_manip($1, $3, 0); + no_internals($1); + if (!initialization_ok) + { if ($1->sym->isarray) + { fprintf(stderr, "warning: %s:%d initialization of %s[] ", + $1->fn->name, $1->ln, + $1->sym->name); + fprintf(stderr, "could fail if placed here\n"); + } else + { Lextok *zx = nn(ZN, NAME, ZN, ZN); + zx->sym = $1->sym; + add_seq(nn(zx, ASGN, zx, $3)); + $1->sym->ini = 0; /* Patrick Trentlin */ + } } + } + | vardcl ASGN ch_init { $1->sym->ini = $3; /* channel declaration */ + $$ = $1; has_ini = 1; + if (!initialization_ok) + { non_fatal(PART1 "'%s'" PART2, $1->sym->name); + } + } + ; ch_init : '[' const_expr ']' OF - '{' typ_list '}' { if ($2->val) - u_async++; - else - u_sync++; - { int i = cnt_mpars($6); - Mpars = max(Mpars, i); - } - $$ = nn(ZN, CHAN, ZN, $6); - $$->val = $2->val; - $$->ln = $1->ln; - $$->fn = $1->fn; - } - ; - -vardcl : NAME { $1->sym->nel = 1; $$ = $1; } - | NAME ':' CONST { $1->sym->nbits = $3->val; - if ($3->val >= 8*sizeof(long)) - { non_fatal("width-field %s too large", - $1->sym->name); - $3->val = 8*sizeof(long)-1; - } - $1->sym->nel = 1; $$ = $1; - } - | NAME '[' const_expr ']' { $1->sym->nel = $3->val; $1->sym->isarray = 1; $$ = $1; } - | NAME '[' NAME ']' { /* make an exception for an initialized scalars */ - $$ = nn(ZN, CONST, ZN, ZN); - fprintf(stderr, "spin: %s:%d, warning: '%s' in array bound ", - $1->fn->name, $1->ln, $3->sym->name); - if ($3->sym->ini - && $3->sym->ini->val > 0) - { fprintf(stderr, "evaluated as %d\n", $3->sym->ini->val); - $$->val = $3->sym->ini->val; - } else - { fprintf(stderr, "evaluated as 1 by default (to avoid zero)\n"); - $$->val = 1; - } - $1->sym->nel = $$->val; - $1->sym->isarray = 1; - $$ = $1; - } - ; - -varref : cmpnd { $$ = mk_explicit($1, Expand_Ok, NAME); } - ; - -pfld : NAME { $$ = nn($1, NAME, ZN, ZN); - if ($1->sym->isarray && !in_for && !IArgs) - { non_fatal("missing array index for '%s'", - $1->sym->name); - } - } - | NAME { owner = ZS; } - '[' expr ']' { $$ = nn($1, NAME, $4, ZN); } - ; - -cmpnd : pfld { Embedded++; - if ($1->sym->type == STRUCT) - owner = $1->sym->Snm; - } - sfld { $$ = $1; $$->rgt = $3; - if ($3 && $1->sym->type != STRUCT) - $1->sym->type = STRUCT; - Embedded--; - if (!Embedded && !NamesNotAdded - && !$1->sym->type) - fatal("undeclared variable: %s", - $1->sym->name); - if ($3) validref($1, $3->lft); - owner = ZS; - } - ; - -sfld : /* empty */ { $$ = ZN; } - | '.' cmpnd %prec DOT { $$ = nn(ZN, '.', $2, ZN); } - ; - -stmnt : Special { $$ = $1; initialization_ok = 0; } - | Stmnt { $$ = $1; initialization_ok = 0; - if (inEventMap) non_fatal("not an event", (char *)0); - } - ; - -for_pre : FOR l_par { in_for = 1; } - varref { trapwonly($4 /*, "for" */); - pushbreak(); /* moved up */ - $$ = $4; - } - ; + '{' typ_list '}' { if ($2->val) + u_async++; + else + u_sync++; + { int i = cnt_mpars($6); + Mpars = MaX(Mpars, i); + } + $$ = nn(ZN, CHAN, ZN, $6); + $$->val = $2->val; + $$->ln = $1->ln; + $$->fn = $1->fn; + } + ; + +vardcl : NAME { $1->sym->nel = 1; $$ = $1; } + | NAME ':' CONST { $1->sym->nbits = $3->val; + if ($3->val >= (int)(8*sizeof(long))) + { non_fatal("width-field %s too large", + $1->sym->name); + $3->val = 8*sizeof(long)-1; + } + $1->sym->nel = 1; $$ = $1; + } + | NAME '[' const_expr ']' { $1->sym->nel = $3->val; $1->sym->isarray = 1; $$ = $1; } + | NAME '[' NAME ']' { /* make an exception for an initialized scalars */ + $$ = nn(ZN, CONST, ZN, ZN); + fprintf(stderr, "spin: %s:%d, warning: '%s' in array bound ", + $1->fn->name, $1->ln, $3->sym->name); + if ($3->sym->ini + && $3->sym->ini->val > 0) + { fprintf(stderr, "evaluated as %d\n", $3->sym->ini->val); + $$->val = $3->sym->ini->val; + } else + { fprintf(stderr, "evaluated as 1 by default (to avoid zero)\n"); + $$->val = 1; + } + $1->sym->nel = $$->val; + $1->sym->isarray = 1; + $$ = $1; + } + ; + +varref : cmpnd { $$ = mk_explicit($1, Expand_Ok, NAME); } + ; + +pfld : NAME { $$ = nn($1, NAME, ZN, ZN); + if ($1->sym->isarray && !in_for && !IArgs) + { non_fatal("missing array index for '%s'", + $1->sym->name); + } + } + | NAME { owner = ZS; } + '[' expr ']' { $$ = nn($1, NAME, $4, ZN); } + ; + +cmpnd : pfld { Embedded++; + if ($1->sym->type == STRUCT) + owner = $1->sym->Snm; + } + sfld { $$ = $1; $$->rgt = $3; + if ($3 && $1->sym->type != STRUCT) + $1->sym->type = STRUCT; + Embedded--; + if (!Embedded && !NamesNotAdded + && !$1->sym->type) + fatal("undeclared variable: %s", + $1->sym->name); + if ($3) validref($1, $3->lft); + owner = ZS; + } + ; + +sfld : /* empty */ { $$ = ZN; } + | '.' cmpnd %prec DOT { $$ = nn(ZN, '.', $2, ZN); } + ; + +stmnt : Special { $$ = $1; initialization_ok = 0; } + | Stmnt { $$ = $1; initialization_ok = 0; + if (inEventMap) non_fatal("not an event", (char *)0); + } + ; + +for_pre : FOR l_par { in_for = 1; } + varref { trapwonly($4 /*, "for" */); + pushbreak(); /* moved up */ + $$ = $4; + } + ; for_post: '{' sequence OS '}' - | SEMI '{' sequence OS '}' - -Special : varref RCV { Expand_Ok++; } - rargs { Expand_Ok--; has_io++; - $$ = nn($1, 'r', $1, $4); - trackchanuse($4, ZN, 'R'); - } - | varref SND { Expand_Ok++; } - margs { Expand_Ok--; has_io++; - $$ = nn($1, 's', $1, $4); - $$->val=0; trackchanuse($4, ZN, 'S'); - any_runs($4); - } - | for_pre ':' expr DOTDOT expr r_par { - for_setup($1, $3, $5); in_for = 0; - } - for_post { $$ = for_body($1, 1); - } - | for_pre IN varref r_par { $$ = for_index($1, $3); in_for = 0; - } - for_post { $$ = for_body($5, 1); - } - | SELECT l_par varref ':' expr DOTDOT expr r_par { - trapwonly($3 /*, "select" */); - $$ = sel_index($3, $5, $7); - } - | IF options FI { $$ = nn($1, IF, ZN, ZN); - $$->sl = $2->sl; - $$->ln = $1->ln; - $$->fn = $1->fn; - prune_opts($$); - } - | DO { pushbreak(); } - options OD { $$ = nn($1, DO, ZN, ZN); - $$->sl = $3->sl; - $$->ln = $1->ln; - $$->fn = $1->fn; - prune_opts($$); - } - | BREAK { $$ = nn(ZN, GOTO, ZN, ZN); - $$->sym = break_dest(); - } - | GOTO NAME { $$ = nn($2, GOTO, ZN, ZN); - if ($2->sym->type != 0 - && $2->sym->type != LABEL) { - non_fatal("bad label-name %s", - $2->sym->name); - } - $2->sym->type = LABEL; - } - | NAME ':' stmnt { $$ = nn($1, ':',$3, ZN); - if ($1->sym->type != 0 - && $1->sym->type != LABEL) { - non_fatal("bad label-name %s", - $1->sym->name); - } - $1->sym->type = LABEL; - } - | NAME ':' { $$ = nn($1, ':',ZN,ZN); - if ($1->sym->type != 0 - && $1->sym->type != LABEL) { - non_fatal("bad label-name %s", - $1->sym->name); - } - $$->lft = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); - $$->lft->lft->val = 1; /* skip */ - $1->sym->type = LABEL; - } - | error { $$ = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); - $$->lft->val = 1; /* skip */ - } - ; - -Stmnt : varref ASGN full_expr { $$ = nn($1, ASGN, $1, $3); /* assignment */ - trackvar($1, $3); - nochan_manip($1, $3, 0); - no_internals($1); - } - | varref INCR { $$ = nn(ZN,CONST, ZN, ZN); $$->val = 1; - $$ = nn(ZN, '+', $1, $$); - $$ = nn($1, ASGN, $1, $$); - trackvar($1, $1); - no_internals($1); - if ($1->sym->type == CHAN) - fatal("arithmetic on chan", (char *)0); - } - | varref DECR { $$ = nn(ZN,CONST, ZN, ZN); $$->val = 1; - $$ = nn(ZN, '-', $1, $$); - $$ = nn($1, ASGN, $1, $$); - trackvar($1, $1); - no_internals($1); - if ($1->sym->type == CHAN) - fatal("arithmetic on chan id's", (char *)0); - } - | SET_P l_par two_args r_par { $$ = nn(ZN, SET_P, $3, ZN); has_priority++; } - | PRINT l_par STRING { realread = 0; } - prargs r_par { $$ = nn($3, PRINT, $5, ZN); realread = 1; } - | PRINTM l_par varref r_par { $$ = nn(ZN, PRINTM, $3, ZN); } - | PRINTM l_par CONST r_par { $$ = nn(ZN, PRINTM, $3, ZN); } - | ASSERT full_expr { $$ = nn(ZN, ASSERT, $2, ZN); AST_track($2, 0); } - | ccode { $$ = $1; } - | varref R_RCV { Expand_Ok++; } - rargs { Expand_Ok--; has_io++; - $$ = nn($1, 'r', $1, $4); - $$->val = has_random = 1; - trackchanuse($4, ZN, 'R'); - } - | varref RCV { Expand_Ok++; } - LT rargs GT { Expand_Ok--; has_io++; - $$ = nn($1, 'r', $1, $5); - $$->val = 2; /* fifo poll */ - trackchanuse($5, ZN, 'R'); - } - | varref R_RCV { Expand_Ok++; } - LT rargs GT { Expand_Ok--; has_io++; /* rrcv poll */ - $$ = nn($1, 'r', $1, $5); - $$->val = 3; has_random = 1; - trackchanuse($5, ZN, 'R'); - } - | varref O_SND { Expand_Ok++; } - margs { Expand_Ok--; has_io++; - $$ = nn($1, 's', $1, $4); - $$->val = has_sorted = 1; - trackchanuse($4, ZN, 'S'); - any_runs($4); - } - | full_expr { $$ = nn(ZN, 'c', $1, ZN); count_runs($$); } - | ELSE { $$ = nn(ZN,ELSE,ZN,ZN); - } - | ATOMIC '{' { open_seq(0); } - sequence OS '}' { $$ = nn($1, ATOMIC, ZN, ZN); - $$->sl = seqlist(close_seq(3), 0); - $$->ln = $1->ln; - $$->fn = $1->fn; - make_atomic($$->sl->this, 0); - } - | D_STEP '{' { open_seq(0); - rem_Seq(); - } - sequence OS '}' { $$ = nn($1, D_STEP, ZN, ZN); - $$->sl = seqlist(close_seq(4), 0); - $$->ln = $1->ln; - $$->fn = $1->fn; - make_atomic($$->sl->this, D_ATOM); - unrem_Seq(); - } - | '{' { open_seq(0); } - sequence OS '}' { $$ = nn(ZN, NON_ATOMIC, ZN, ZN); - $$->sl = seqlist(close_seq(5), 0); - $$->ln = $1->ln; - $$->fn = $1->fn; - } - | INAME { IArgs++; } - l_par args r_par { initialization_ok = 0; - pickup_inline($1->sym, $4, ZN); - IArgs--; - } - Stmnt { $$ = $7; } - - | varref ASGN INAME { IArgs++; /* inline call */ } - l_par args r_par { initialization_ok = 0; - pickup_inline($3->sym, $6, $1); - IArgs--; - } - Stmnt { $$ = $9; } - | RETURN full_expr { $$ = return_statement($2); } - ; - -options : option { $$->sl = seqlist($1->sq, 0); } - | option options { $$->sl = seqlist($1->sq, $2->sl); } - ; - -option : SEP { open_seq(0); } - sequence OS { $$ = nn(ZN,0,ZN,ZN); - $$->sq = close_seq(6); - $$->ln = $1->ln; - $$->fn = $1->fn; - } - ; - -OS : /* empty */ - | semi { /* redundant semi at end of sequence */ } - ; - -semi : SEMI - | ARROW - ; - -MS : semi { /* at least one semi-colon */ } - | MS semi { /* but more are okay too */ } - ; - -aname : NAME { $$ = $1; } - | PNAME { $$ = $1; } - ; - -const_expr: CONST { $$ = $1; } - | '-' const_expr %prec UMIN { $$ = $2; $$->val = -($2->val); } - | l_par const_expr r_par { $$ = $2; } - | const_expr '+' const_expr { $$ = $1; $$->val = $1->val + $3->val; } - | const_expr '-' const_expr { $$ = $1; $$->val = $1->val - $3->val; } - | const_expr '*' const_expr { $$ = $1; $$->val = $1->val * $3->val; } - | const_expr '/' const_expr { $$ = $1; - if ($3->val == 0) - { fatal("division by zero", (char *) 0); - } - $$->val = $1->val / $3->val; - } - | const_expr '%' const_expr { $$ = $1; - if ($3->val == 0) - { fatal("attempt to take modulo of zero", (char *) 0); - } - $$->val = $1->val % $3->val; - } - ; - -expr : l_par expr r_par { $$ = $2; } - | expr '+' expr { $$ = nn(ZN, '+', $1, $3); } - | expr '-' expr { $$ = nn(ZN, '-', $1, $3); } - | expr '*' expr { $$ = nn(ZN, '*', $1, $3); } - | expr '/' expr { $$ = nn(ZN, '/', $1, $3); } - | expr '%' expr { $$ = nn(ZN, '%', $1, $3); } - | expr '&' expr { $$ = nn(ZN, '&', $1, $3); } - | expr '^' expr { $$ = nn(ZN, '^', $1, $3); } - | expr '|' expr { $$ = nn(ZN, '|', $1, $3); } - | expr GT expr { $$ = nn(ZN, GT, $1, $3); } - | expr LT expr { $$ = nn(ZN, LT, $1, $3); } - | expr GE expr { $$ = nn(ZN, GE, $1, $3); } - | expr LE expr { $$ = nn(ZN, LE, $1, $3); } - | expr EQ expr { $$ = nn(ZN, EQ, $1, $3); } - | expr NE expr { $$ = nn(ZN, NE, $1, $3); } - | expr AND expr { $$ = nn(ZN, AND, $1, $3); } - | expr OR expr { $$ = nn(ZN, OR, $1, $3); } - | expr LSHIFT expr { $$ = nn(ZN, LSHIFT,$1, $3); } - | expr RSHIFT expr { $$ = nn(ZN, RSHIFT,$1, $3); } - | '~' expr { $$ = nn(ZN, '~', $2, ZN); } - | '-' expr %prec UMIN { $$ = nn(ZN, UMIN, $2, ZN); } - | SND expr %prec NEG { $$ = nn(ZN, '!', $2, ZN); } - - | l_par expr ARROW expr ':' expr r_par { - $$ = nn(ZN, OR, $4, $6); - $$ = nn(ZN, '?', $2, $$); - } - - | RUN aname { Expand_Ok++; - if (!context) - fatal("used 'run' outside proctype", (char *) 0); - } - l_par args r_par - Opt_priority { Expand_Ok--; - $$ = nn($2, RUN, $5, ZN); - $$->val = ($7) ? $7->val : 0; - trackchanuse($5, $2, 'A'); trackrun($$); - } - | LEN l_par varref r_par { $$ = nn($3, LEN, $3, ZN); } - | ENABLED l_par expr r_par { $$ = nn(ZN, ENABLED, $3, ZN); has_enabled++; } - | GET_P l_par expr r_par { $$ = nn(ZN, GET_P, $3, ZN); has_priority++; } - | varref RCV { Expand_Ok++; } - '[' rargs ']' { Expand_Ok--; has_io++; - $$ = nn($1, 'R', $1, $5); - } - | varref R_RCV { Expand_Ok++; } - '[' rargs ']' { Expand_Ok--; has_io++; - $$ = nn($1, 'R', $1, $5); - $$->val = has_random = 1; - } - | varref { $$ = $1; trapwonly($1 /*, "varref" */); } - | cexpr { $$ = $1; } - | CONST { $$ = nn(ZN,CONST,ZN,ZN); - $$->ismtyp = $1->ismtyp; - $$->sym = $1->sym; - $$->val = $1->val; - } - | TIMEOUT { $$ = nn(ZN,TIMEOUT, ZN, ZN); } - | NONPROGRESS { $$ = nn(ZN,NONPROGRESS, ZN, ZN); - has_np++; - } - | PC_VAL l_par expr r_par { $$ = nn(ZN, PC_VAL, $3, ZN); - has_pcvalue++; - } - | PNAME '[' expr ']' '@' NAME - { $$ = rem_lab($1->sym, $3, $6->sym); } - | PNAME '[' expr ']' ':' pfld - { $$ = rem_var($1->sym, $3, $6->sym, $6->lft); } - | PNAME '@' NAME { $$ = rem_lab($1->sym, ZN, $3->sym); } - | PNAME ':' pfld { $$ = rem_var($1->sym, ZN, $3->sym, $3->lft); } - | ltl_expr { $$ = $1; /* sanity_check($1); */ } - ; - -Opt_priority: /* none */ { $$ = ZN; } - | PRIORITY CONST { $$ = $2; has_priority++; } - ; - -full_expr: expr { $$ = $1; } - | Expr { $$ = $1; } - ; - -ltl_expr: expr UNTIL expr { $$ = nn(ZN, UNTIL, $1, $3); } - | expr RELEASE expr { $$ = nn(ZN, RELEASE, $1, $3); } - | expr WEAK_UNTIL expr { $$ = nn(ZN, ALWAYS, $1, ZN); - $$ = nn(ZN, OR, $$, nn(ZN, UNTIL, $1, $3)); - } - | expr IMPLIES expr { $$ = nn(ZN, '!', $1, ZN); - $$ = nn(ZN, OR, $$, $3); - } - | expr EQUIV expr { $$ = nn(ZN, EQUIV, $1, $3); } - | NEXT expr %prec NEG { $$ = nn(ZN, NEXT, $2, ZN); } - | ALWAYS expr %prec NEG { $$ = nn(ZN, ALWAYS,$2, ZN); } - | EVENTUALLY expr %prec NEG { $$ = nn(ZN, EVENTUALLY, $2, ZN); } - ; - - /* an Expr cannot be negated - to protect Probe expressions */ -Expr : Probe { $$ = $1; } - | l_par Expr r_par { $$ = $2; } - | Expr AND Expr { $$ = nn(ZN, AND, $1, $3); } - | Expr AND expr { $$ = nn(ZN, AND, $1, $3); } - | expr AND Expr { $$ = nn(ZN, AND, $1, $3); } - | Expr OR Expr { $$ = nn(ZN, OR, $1, $3); } - | Expr OR expr { $$ = nn(ZN, OR, $1, $3); } - | expr OR Expr { $$ = nn(ZN, OR, $1, $3); } - ; - -Probe : FULL l_par varref r_par { $$ = nn($3, FULL, $3, ZN); } - | NFULL l_par varref r_par { $$ = nn($3, NFULL, $3, ZN); } - | EMPTY l_par varref r_par { $$ = nn($3, EMPTY, $3, ZN); } - | NEMPTY l_par varref r_par { $$ = nn($3,NEMPTY, $3, ZN); } - ; - -Opt_enabler: /* none */ { $$ = ZN; } - | PROVIDED l_par full_expr r_par { - if (!proper_enabler($3)) - { non_fatal("invalid PROVIDED clause", (char *)0); - $$ = ZN; - } else - { $$ = $3; - } } - | PROVIDED error { $$ = ZN; - non_fatal("usage: provided ( ..expr.. )", (char *)0); - } - ; - -oname : /* empty */ { $$ = ZN; } - | ':' NAME { $$ = $2; } - ; - -basetype: TYPE oname { if ($2) - { if ($1->val != MTYPE) - { explain($1->val); - fatal("unexpected type", (char *) 0); - } } - $$->sym = $2 ? $2->sym : ZS; - $$->val = $1->val; - if ($$->val == UNSIGNED) - fatal("unsigned cannot be used as mesg type", 0); - } - | UNAME { $$->sym = $1->sym; - $$->val = STRUCT; - } - | error /* e.g., unsigned ':' const */ - ; - -typ_list: basetype { $$ = nn($1, $1->val, ZN, ZN); } - | basetype ',' typ_list { $$ = nn($1, $1->val, ZN, $3); } - ; - -two_args: expr ',' expr { $$ = nn(ZN, ',', $1, $3); } - ; - -args : /* empty */ { $$ = ZN; } - | arg { $$ = $1; } - ; - -prargs : /* empty */ { $$ = ZN; } - | ',' arg { $$ = $2; } - ; - -margs : arg { $$ = $1; } - | expr l_par arg r_par { if ($1->ntyp == ',') - $$ = tail_add($1, $3); - else - $$ = nn(ZN, ',', $1, $3); - } - ; - -arg : expr { if ($1->ntyp == ',') - $$ = $1; - else - $$ = nn(ZN, ',', $1, ZN); - } - | expr ',' arg { if ($1->ntyp == ',') - $$ = tail_add($1, $3); - else - $$ = nn(ZN, ',', $1, $3); - } - ; - -rarg : varref { $$ = $1; trackvar($1, $1); - trapwonly($1 /*, "rarg" */); } - | EVAL l_par expr r_par { $$ = nn(ZN,EVAL,$3,ZN); - trapwonly($1 /*, "eval rarg" */); } - | CONST { $$ = nn(ZN,CONST,ZN,ZN); - $$->ismtyp = $1->ismtyp; - $$->sym = $1->sym; - $$->val = $1->val; - } - | '-' CONST %prec UMIN { $$ = nn(ZN,CONST,ZN,ZN); - $$->val = - ($2->val); - } - ; - -rargs : rarg { if ($1->ntyp == ',') - $$ = $1; - else - $$ = nn(ZN, ',', $1, ZN); - } - | rarg ',' rargs { if ($1->ntyp == ',') - $$ = tail_add($1, $3); - else - $$ = nn(ZN, ',', $1, $3); - } - | rarg l_par rargs r_par { if ($1->ntyp == ',') - $$ = tail_add($1, $3); - else - $$ = nn(ZN, ',', $1, $3); - } - | l_par rargs r_par { $$ = $2; } - ; - -nlst : NAME { $$ = nn($1, NAME, ZN, ZN); - $$ = nn(ZN, ',', $$, ZN); } - | nlst NAME { $$ = nn($2, NAME, ZN, ZN); - $$ = nn(ZN, ',', $$, $1); - } - | nlst ',' { $$ = $1; /* commas optional */ } - ; + | SEMI '{' sequence OS '}' + +Special : varref RCV { Expand_Ok++; } + rargs { Expand_Ok--; has_io++; + $$ = nn($1, 'r', $1, $4); + trackchanuse($4, ZN, 'R'); + } + | varref SND { Expand_Ok++; } + margs { Expand_Ok--; has_io++; + $$ = nn($1, 's', $1, $4); + $$->val=0; trackchanuse($4, ZN, 'S'); + any_runs($4); + } + | for_pre ':' expr DOTDOT expr r_par { + for_setup($1, $3, $5); in_for = 0; + } + for_post { $$ = for_body($1, 1); + } + | for_pre IN varref r_par { $$ = for_index($1, $3); in_for = 0; + } + for_post { $$ = for_body($5, 1); + } + | SELECT l_par varref ':' expr DOTDOT expr r_par { + trapwonly($3 /*, "select" */); + $$ = sel_index($3, $5, $7); + } + | IF options FI { $$ = nn($1, IF, ZN, ZN); + $$->sl = $2->sl; + $$->ln = $1->ln; + $$->fn = $1->fn; + prune_opts($$); + } + | DO { pushbreak(); } + options OD { $$ = nn($1, DO, ZN, ZN); + $$->sl = $3->sl; + $$->ln = $1->ln; + $$->fn = $1->fn; + prune_opts($$); + } + | BREAK { $$ = nn(ZN, GOTO, ZN, ZN); + $$->sym = break_dest(); + } + | GOTO NAME { $$ = nn($2, GOTO, ZN, ZN); + if ($2->sym->type != 0 + && $2->sym->type != LABEL) { + non_fatal("bad label-name %s", + $2->sym->name); + } + $2->sym->type = LABEL; + } + | NAME ':' stmnt { $$ = nn($1, ':',$3, ZN); + if ($1->sym->type != 0 + && $1->sym->type != LABEL) { + non_fatal("bad label-name %s", + $1->sym->name); + } + $1->sym->type = LABEL; + } + | NAME ':' { $$ = nn($1, ':',ZN,ZN); + if ($1->sym->type != 0 + && $1->sym->type != LABEL) { + non_fatal("bad label-name %s", + $1->sym->name); + } + $$->lft = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); + $$->lft->lft->val = 1; /* skip */ + $1->sym->type = LABEL; + } + | error { $$ = nn(ZN, 'c', nn(ZN,CONST,ZN,ZN), ZN); + $$->lft->val = 1; /* skip */ + } + ; + +Stmnt : varref ASGN full_expr { $$ = nn($1, ASGN, $1, $3); /* assignment */ + trackvar($1, $3); + nochan_manip($1, $3, 0); + no_internals($1); + } + | varref INCR { $$ = nn(ZN,CONST, ZN, ZN); $$->val = 1; + $$ = nn(ZN, '+', $1, $$); + $$ = nn($1, ASGN, $1, $$); + trackvar($1, $1); + no_internals($1); + if ($1->sym->type == CHAN) + fatal("arithmetic on chan", (char *)0); + } + | varref DECR { $$ = nn(ZN,CONST, ZN, ZN); $$->val = 1; + $$ = nn(ZN, '-', $1, $$); + $$ = nn($1, ASGN, $1, $$); + trackvar($1, $1); + no_internals($1); + if ($1->sym->type == CHAN) + fatal("arithmetic on chan id's", (char *)0); + } + | SET_P l_par two_args r_par { $$ = nn(ZN, SET_P, $3, ZN); has_priority++; } + | PRINT l_par STRING { realread = 0; } + prargs r_par { $$ = nn($3, PRINT, $5, ZN); realread = 1; } + | PRINTM l_par varref r_par { $$ = nn(ZN, PRINTM, $3, ZN); } + | PRINTM l_par CONST r_par { $$ = nn(ZN, PRINTM, $3, ZN); } + | ASSERT full_expr { $$ = nn(ZN, ASSERT, $2, ZN); AST_track($2, 0); } + | ccode { $$ = $1; } + | varref R_RCV { Expand_Ok++; } + rargs { Expand_Ok--; has_io++; + $$ = nn($1, 'r', $1, $4); + $$->val = has_random = 1; + trackchanuse($4, ZN, 'R'); + } + | varref RCV { Expand_Ok++; } + LT rargs GT { Expand_Ok--; has_io++; + $$ = nn($1, 'r', $1, $5); + $$->val = 2; /* fifo poll */ + trackchanuse($5, ZN, 'R'); + } + | varref R_RCV { Expand_Ok++; } + LT rargs GT { Expand_Ok--; has_io++; /* rrcv poll */ + $$ = nn($1, 'r', $1, $5); + $$->val = 3; has_random = 1; + trackchanuse($5, ZN, 'R'); + } + | varref O_SND { Expand_Ok++; } + margs { Expand_Ok--; has_io++; + $$ = nn($1, 's', $1, $4); + $$->val = has_sorted = 1; + trackchanuse($4, ZN, 'S'); + any_runs($4); + } + | full_expr { $$ = nn(ZN, 'c', $1, ZN); count_runs($$); } + | ELSE { $$ = nn(ZN,ELSE,ZN,ZN); + } + | ATOMIC '{' { open_seq(0); } + sequence OS '}' { $$ = nn($1, ATOMIC, ZN, ZN); + $$->sl = seqlist(close_seq(3), 0); + $$->ln = $1->ln; + $$->fn = $1->fn; + make_atomic($$->sl->thisS, 0); + } + | D_STEP '{' { open_seq(0); + rem_Seq(); + } + sequence OS '}' { $$ = nn($1, D_STEP, ZN, ZN); + $$->sl = seqlist(close_seq(4), 0); + $$->ln = $1->ln; + $$->fn = $1->fn; + make_atomic($$->sl->thisS, D_ATOM); + unrem_Seq(); + } + | '{' { open_seq(0); } + sequence OS '}' { $$ = nn(ZN, NON_ATOMIC, ZN, ZN); + $$->sl = seqlist(close_seq(5), 0); + $$->ln = $1->ln; + $$->fn = $1->fn; + } + | INAME { IArgs++; } + l_par args r_par { initialization_ok = 0; + pickup_inline($1->sym, $4, ZN); + IArgs--; + } + Stmnt { $$ = $7; } + + | varref ASGN INAME { IArgs++; /* inline call */ } + l_par args r_par { initialization_ok = 0; + pickup_inline($3->sym, $6, $1); + IArgs--; + } + Stmnt { $$ = $9; } + | RETURN full_expr { $$ = return_statement($2); } + ; + +options : option { $$->sl = seqlist($1->sq, 0); } + | option options { $$->sl = seqlist($1->sq, $2->sl); } + ; + +option : SEP { open_seq(0); } + sequence OS { $$ = nn(ZN,0,ZN,ZN); + $$->sq = close_seq(6); + $$->ln = $1->ln; + $$->fn = $1->fn; + } + ; + +OS : /* empty */ + | semi { /* redundant semi at end of sequence */ } + ; + +semi : SEMI + | ARROW + ; + +MS : semi { /* at least one semi-colon */ } + | MS semi { /* but more are okay too */ } + ; + +aname : NAME { $$ = $1; } + | PNAME { $$ = $1; } + ; + +const_expr: CONST { $$ = $1; } + | '-' const_expr %prec UMIN { $$ = $2; $$->val = -($2->val); } + | l_par const_expr r_par { $$ = $2; } + | const_expr '+' const_expr { $$ = $1; $$->val = $1->val + $3->val; } + | const_expr '-' const_expr { $$ = $1; $$->val = $1->val - $3->val; } + | const_expr '*' const_expr { $$ = $1; $$->val = $1->val * $3->val; } + | const_expr '/' const_expr { $$ = $1; + if ($3->val == 0) + { fatal("division by zero", (char *) 0); + } + $$->val = $1->val / $3->val; + } + | const_expr '%' const_expr { $$ = $1; + if ($3->val == 0) + { fatal("attempt to take modulo of zero", (char *) 0); + } + $$->val = $1->val % $3->val; + } + ; + +expr : l_par expr r_par { $$ = $2; } + | expr '+' expr { $$ = nn(ZN, '+', $1, $3); } + | expr '-' expr { $$ = nn(ZN, '-', $1, $3); } + | expr '*' expr { $$ = nn(ZN, '*', $1, $3); } + | expr '/' expr { $$ = nn(ZN, '/', $1, $3); } + | expr '%' expr { $$ = nn(ZN, '%', $1, $3); } + | expr '&' expr { $$ = nn(ZN, '&', $1, $3); } + | expr '^' expr { $$ = nn(ZN, '^', $1, $3); } + | expr '|' expr { $$ = nn(ZN, '|', $1, $3); } + | expr GT expr { $$ = nn(ZN, GT, $1, $3); } + | expr LT expr { $$ = nn(ZN, LT, $1, $3); } + | expr GE expr { $$ = nn(ZN, GE, $1, $3); } + | expr LE expr { $$ = nn(ZN, LE, $1, $3); } + | expr EQ expr { $$ = nn(ZN, EQ, $1, $3); } + | expr NE expr { $$ = nn(ZN, NE, $1, $3); } + | expr AND expr { $$ = nn(ZN, AND, $1, $3); } + | expr OR expr { $$ = nn(ZN, OR, $1, $3); } + | expr LSHIFT expr { $$ = nn(ZN, LSHIFT,$1, $3); } + | expr RSHIFT expr { $$ = nn(ZN, RSHIFT,$1, $3); } + | '~' expr { $$ = nn(ZN, '~', $2, ZN); } + | '-' expr %prec UMIN { $$ = nn(ZN, UMIN, $2, ZN); } + | SND expr %prec NEG { $$ = nn(ZN, '!', $2, ZN); } + + | l_par expr ARROW expr ':' expr r_par { + $$ = nn(ZN, OR, $4, $6); + $$ = nn(ZN, '?', $2, $$); + } + + | RUN aname { Expand_Ok++; + if (!context) + fatal("used 'run' outside proctype", (char *) 0); + } + l_par args r_par + Opt_priority { Expand_Ok--; + $$ = nn($2, RUN, $5, ZN); + $$->val = ($7) ? $7->val : 0; + trackchanuse($5, $2, 'A'); trackrun($$); + } + | LEN l_par varref r_par { $$ = nn($3, LEN, $3, ZN); } + | ENABLED l_par expr r_par { $$ = nn(ZN, ENABLED, $3, ZN); has_enabled++; } + | GET_P l_par expr r_par { $$ = nn(ZN, GET_P, $3, ZN); has_priority++; } + | varref RCV { Expand_Ok++; } + '[' rargs ']' { Expand_Ok--; has_io++; + $$ = nn($1, 'R', $1, $5); + } + | varref R_RCV { Expand_Ok++; } + '[' rargs ']' { Expand_Ok--; has_io++; + $$ = nn($1, 'R', $1, $5); + $$->val = has_random = 1; + } + | varref { $$ = $1; trapwonly($1 /*, "varref" */); } + | cexpr { $$ = $1; } + | CONST { $$ = nn(ZN,CONST,ZN,ZN); + $$->ismtyp = $1->ismtyp; + $$->sym = $1->sym; + $$->val = $1->val; + } + | TIMEOUT { $$ = nn(ZN,TIMEOUT, ZN, ZN); } + | NONPROGRESS { $$ = nn(ZN,NONPROGRESS, ZN, ZN); + has_np++; + } + | PC_VAL l_par expr r_par { $$ = nn(ZN, PC_VAL, $3, ZN); + has_pcvalue++; + } + | PNAME '[' expr ']' '@' NAME + { $$ = rem_lab($1->sym, $3, $6->sym); } + | PNAME '[' expr ']' ':' pfld + { $$ = rem_var($1->sym, $3, $6->sym, $6->lft); } + | PNAME '@' NAME { $$ = rem_lab($1->sym, ZN, $3->sym); } + | PNAME ':' pfld { $$ = rem_var($1->sym, ZN, $3->sym, $3->lft); } + | ltl_expr { $$ = $1; /* sanity_check($1); */ } + ; + +Opt_priority: /* none */ { $$ = ZN; } + | PRIORITY CONST { $$ = $2; has_priority++; } + ; + +full_expr: expr { $$ = $1; } + | Expr { $$ = $1; } + ; + +ltl_expr: expr UNTIL expr { $$ = nn(ZN, UNTIL, $1, $3); } + | expr RELEASE expr { $$ = nn(ZN, RELEASE, $1, $3); } + | expr WEAK_UNTIL expr { $$ = nn(ZN, ALWAYS, $1, ZN); + $$ = nn(ZN, OR, $$, nn(ZN, UNTIL, $1, $3)); + } + | expr IMPLIES expr { $$ = nn(ZN, '!', $1, ZN); + $$ = nn(ZN, OR, $$, $3); + } + | expr EQUIV expr { $$ = nn(ZN, EQUIV, $1, $3); } + | NEXT expr %prec NEG { $$ = nn(ZN, NEXT, $2, ZN); } + | ALWAYS expr %prec NEG { $$ = nn(ZN, ALWAYS,$2, ZN); } + | EVENTUALLY expr %prec NEG { $$ = nn(ZN, EVENTUALLY, $2, ZN); } + ; + + /* an Expr cannot be negated - to protect Probe expressions */ +Expr : Probe { $$ = $1; } + | l_par Expr r_par { $$ = $2; } + | Expr AND Expr { $$ = nn(ZN, AND, $1, $3); } + | Expr AND expr { $$ = nn(ZN, AND, $1, $3); } + | expr AND Expr { $$ = nn(ZN, AND, $1, $3); } + | Expr OR Expr { $$ = nn(ZN, OR, $1, $3); } + | Expr OR expr { $$ = nn(ZN, OR, $1, $3); } + | expr OR Expr { $$ = nn(ZN, OR, $1, $3); } + ; + +Probe : FULL l_par varref r_par { $$ = nn($3, FULL, $3, ZN); } + | NFULL l_par varref r_par { $$ = nn($3, NFULL, $3, ZN); } + | EMPTY l_par varref r_par { $$ = nn($3, EMPTY, $3, ZN); } + | NEMPTY l_par varref r_par { $$ = nn($3,NEMPTY, $3, ZN); } + ; + +Opt_enabler: /* none */ { $$ = ZN; } + | PROVIDED l_par full_expr r_par { + if (!proper_enabler($3)) + { non_fatal("invalid PROVIDED clause", (char *)0); + $$ = ZN; + } else + { $$ = $3; + } } + | PROVIDED error { $$ = ZN; + non_fatal("usage: provided ( ..expr.. )", (char *)0); + } + ; + +oname : /* empty */ { $$ = ZN; } + | ':' NAME { $$ = $2; } + ; + +basetype: TYPE oname { if ($2) + { if ($1->val != MTYPE) + { explain($1->val); + fatal("unexpected type", (char *) 0); + } } + $$->sym = $2 ? $2->sym : ZS; + $$->val = $1->val; + if ($$->val == UNSIGNED) + fatal("unsigned cannot be used as mesg type", 0); + } + | UNAME { $$->sym = $1->sym; + $$->val = STRUCT; + } + | error /* e.g., unsigned ':' const */ + ; + +typ_list: basetype { $$ = nn($1, $1->val, ZN, ZN); } + | basetype ',' typ_list { $$ = nn($1, $1->val, ZN, $3); } + ; + +two_args: expr ',' expr { $$ = nn(ZN, ',', $1, $3); } + ; + +args : /* empty */ { $$ = ZN; } + | arg { $$ = $1; } + ; + +prargs : /* empty */ { $$ = ZN; } + | ',' arg { $$ = $2; } + ; + +margs : arg { $$ = $1; } + | expr l_par arg r_par { if ($1->ntyp == ',') + $$ = tail_add($1, $3); + else + $$ = nn(ZN, ',', $1, $3); + } + ; + +arg : expr { if ($1->ntyp == ',') + $$ = $1; + else + $$ = nn(ZN, ',', $1, ZN); + } + | expr ',' arg { if ($1->ntyp == ',') + $$ = tail_add($1, $3); + else + $$ = nn(ZN, ',', $1, $3); + } + ; + +rarg : varref { $$ = $1; trackvar($1, $1); + trapwonly($1 /*, "rarg" */); } + | EVAL l_par expr r_par { $$ = nn(ZN,EVAL,$3,ZN); + trapwonly($1 /*, "eval rarg" */); } + | CONST { $$ = nn(ZN,CONST,ZN,ZN); + $$->ismtyp = $1->ismtyp; + $$->sym = $1->sym; + $$->val = $1->val; + } + | '-' CONST %prec UMIN { $$ = nn(ZN,CONST,ZN,ZN); + $$->val = - ($2->val); + } + ; + +rargs : rarg { if ($1->ntyp == ',') + $$ = $1; + else + $$ = nn(ZN, ',', $1, ZN); + } + | rarg ',' rargs { if ($1->ntyp == ',') + $$ = tail_add($1, $3); + else + $$ = nn(ZN, ',', $1, $3); + } + | rarg l_par rargs r_par { if ($1->ntyp == ',') + $$ = tail_add($1, $3); + else + $$ = nn(ZN, ',', $1, $3); + } + | l_par rargs r_par { $$ = $2; } + ; + +nlst : NAME { $$ = nn($1, NAME, ZN, ZN); + $$ = nn(ZN, ',', $$, ZN); } + | nlst NAME { $$ = nn($2, NAME, ZN, ZN); + $$ = nn(ZN, ',', $$, $1); + } + | nlst ',' { $$ = $1; /* commas optional */ } + ; %% -#define binop(n, sop) fprintf(fd, "("); recursive(fd, n->lft); \ - fprintf(fd, ") %s (", sop); recursive(fd, n->rgt); \ - fprintf(fd, ")"); -#define unop(n, sop) fprintf(fd, "%s (", sop); recursive(fd, n->lft); \ - fprintf(fd, ")"); +#define binop(n, sop) fprintf(fd, "("); recursive(fd, n->lft); \ + fprintf(fd, ") %s (", sop); recursive(fd, n->rgt); \ + fprintf(fd, ")"); +#define unop(n, sop) fprintf(fd, "%s (", sop); recursive(fd, n->lft); \ + fprintf(fd, ")"); static void recursive(FILE *fd, Lextok *n) { - if (n) - switch (n->ntyp) { - case NEXT: - unop(n, "X"); - break; - case ALWAYS: - unop(n, "[]"); - break; - case EVENTUALLY: - unop(n, "<>"); - break; - case '!': - unop(n, "!"); - break; - case UNTIL: - binop(n, "U"); - break; - case WEAK_UNTIL: - binop(n, "W"); - break; - case RELEASE: /* see http://en.wikipedia.org/wiki/Linear_temporal_logic */ - binop(n, "V"); - break; - case OR: - binop(n, "||"); - break; - case AND: - binop(n, "&&"); - break; - case IMPLIES: - binop(n, "->"); - break; - case EQUIV: - binop(n, "<->"); - break; - case C_EXPR: - fprintf(fd, "c_expr { %s }", put_inline(fd, n->sym->name)); - break; - default: - comment(fd, n, 0); - break; - } + if (n) + switch (n->ntyp) { + case NEXT: + unop(n, "X"); + break; + case ALWAYS: + unop(n, "[]"); + break; + case EVENTUALLY: + unop(n, "<>"); + break; + case '!': + unop(n, "!"); + break; + case UNTIL: + binop(n, "U"); + break; + case WEAK_UNTIL: + binop(n, "W"); + break; + case RELEASE: /* see http://en.wikipedia.org/wiki/Linear_temporal_logic */ + binop(n, "V"); + break; + case OR: + binop(n, "||"); + break; + case AND: + binop(n, "&&"); + break; + case IMPLIES: + binop(n, "->"); + break; + case EQUIV: + binop(n, "<->"); + break; + case C_EXPR: + fprintf(fd, "c_expr { %s }", put_inline(fd, n->sym->name)); + break; + default: + comment(fd, n, 0); + break; + } } #ifdef __MINGW32__ @@ -1079,87 +1079,87 @@ extern ssize_t getline(char **, size_t *, FILE *); /* see main.c */ static Lextok * ltl_to_string(Lextok *n) -{ Lextok *m = nn(ZN, 0, ZN, ZN); - ssize_t retval; - char *ltl_formula = NULL; - FILE *tf = fopen(TMP_FILE1, "w+"); /* tmpfile() fails on Windows 7 */ - - /* convert the parsed ltl to a string - by writing into a file, using existing functions, - and then passing it to the existing interface for - conversion into a never claim - (this means parsing everything twice, which is - a little redundant, but adds only miniscule overhead) - */ - - if (!tf) - { fatal("cannot create temporary file", (char *) 0); - } - dont_simplify = 1; - recursive(tf, n); - dont_simplify = 0; - (void) fseek(tf, 0L, SEEK_SET); - - size_t linebuffsize = 0; - retval = getline(<l_formula, &linebuffsize, tf); - fclose(tf); - - (void) unlink(TMP_FILE1); - - if (!retval) - { printf("%ld\n", (long int) retval); - fatal("could not translate ltl ltl_formula", 0); - } - - if (1) printf("ltl %s: %s\n", ltl_name, ltl_formula); - - m->sym = lookup(ltl_formula); +{ Lextok *m = nn(ZN, 0, ZN, ZN); + ssize_t retval; + char *ltl_formula = NULL; + FILE *tf = fopen(TMP_FILE1, "w+"); /* tmpfile() fails on Windows 7 */ + + /* convert the parsed ltl to a string + by writing into a file, using existing functions, + and then passing it to the existing interface for + conversion into a never claim + (this means parsing everything twice, which is + a little redundant, but adds only miniscule overhead) + */ + + if (!tf) + { fatal("cannot create temporary file", (char *) 0); + } + dont_simplify = 1; + recursive(tf, n); + dont_simplify = 0; + (void) fseek(tf, 0L, SEEK_SET); + + size_t linebuffsize = 0; + retval = getline(<l_formula, &linebuffsize, tf); + fclose(tf); + + (void) unlink(TMP_FILE1); + + if (!retval) + { printf("%ld\n", (long int) retval); + fatal("could not translate ltl ltl_formula", 0); + } + + if (1) printf("ltl %s: %s\n", ltl_name, ltl_formula); + + m->sym = lookup(ltl_formula); #ifndef __MINGW32__ - free(ltl_formula); + free(ltl_formula); #endif - return m; + return m; } int is_temporal(int t) { - return (t == EVENTUALLY || t == ALWAYS || t == UNTIL - || t == WEAK_UNTIL || t == RELEASE); + return (t == EVENTUALLY || t == ALWAYS || t == UNTIL + || t == WEAK_UNTIL || t == RELEASE); } int is_boolean(int t) { - return (t == AND || t == OR || t == IMPLIES || t == EQUIV); + return (t == AND || t == OR || t == IMPLIES || t == EQUIV); } #if 0 /* flags correct formula like: ltl { true U (true U true) } */ void -sanity_check(Lextok *t) /* check proper embedding of ltl_expr */ +sanity_check(Lextok *t) /* check proper embedding of ltl_expr */ { - if (!t) return; - sanity_check(t->lft); - sanity_check(t->rgt); - - if (t->lft && t->rgt) - { if (!is_boolean(t->ntyp) - && (is_temporal(t->lft->ntyp) - || is_temporal(t->rgt->ntyp))) - { printf("spin: attempt to apply '"); - explain(t->ntyp); - printf("' to '"); - explain(t->lft->ntyp); - printf("' and '"); - explain(t->rgt->ntyp); - printf("'\n"); - /* non_fatal("missing parentheses?", (char *)0); */ - } } + if (!t) return; + sanity_check(t->lft); + sanity_check(t->rgt); + + if (t->lft && t->rgt) + { if (!is_boolean(t->ntyp) + && (is_temporal(t->lft->ntyp) + || is_temporal(t->rgt->ntyp))) + { printf("spin: attempt to apply '"); + explain(t->ntyp); + printf("' to '"); + explain(t->lft->ntyp); + printf("' and '"); + explain(t->rgt->ntyp); + printf("'\n"); + /* non_fatal("missing parentheses?", (char *)0); */ + } } } #endif void -yyerror(char *fmt, ...) +yyerror(const char *fmt, ...) { - non_fatal(fmt, (char *) 0); + non_fatal(fmt, (char *) 0); } diff --git a/Src/spinlex.c b/Src/spinlex.c index dc4b3bc..e1620e8 100644 --- a/Src/spinlex.c +++ b/Src/spinlex.c @@ -6,78 +6,81 @@ * Tool documentation is available at http://spinroot.com */ +#include "get_strdup.h" /* include this first */ + #include #include #include #include +#include #include "spin.h" #include "y.tab.h" -#define MAXINL 32 /* max recursion depth inline fcts */ -#define MAXPAR 32 /* max params to an inline call */ -#define MAXLEN 512 /* max len of an actual parameter text */ +#define MAXINL 32 /* max recursion depth inline fcts */ +#define MAXPAR 32 /* max params to an inline call */ +#define MAXLEN 512 /* max len of an actual parameter text */ typedef struct IType { - Symbol *nm; /* name of the type */ - Lextok *cn; /* contents */ - Lextok *params; /* formal pars if any */ - Lextok *rval; /* variable to assign return value, if any */ - char **anms; /* literal text for actual pars */ - char *prec; /* precondition for c_code or c_expr */ - int uiid; /* unique inline id */ - int is_expr; /* c_expr in an ltl formula */ - int dln, cln; /* def and call linenr */ - Symbol *dfn, *cfn; /* def and call filename */ - struct IType *nxt; /* linked list */ + Symbol *nm; /* name of the type */ + Lextok *cn; /* contents */ + Lextok *params; /* formal pars if any */ + Lextok *rval; /* variable to assign return value, if any */ + char **anms; /* literal text for actual pars */ + char *prec; /* precondition for c_code or c_expr */ + int uiid; /* unique inline id */ + int is_expr; /* c_expr in an ltl formula */ + int dln, cln; /* def and call linenr */ + Symbol *dfn, *cfn; /* def and call filename */ + struct IType *nxt; /* linked list */ } IType; typedef struct C_Added { - Symbol *s; - Symbol *t; - Symbol *ival; - Symbol *fnm; - int lno; - struct C_Added *nxt; + Symbol *s; + Symbol *t; + Symbol *ival; + Symbol *fnm; + int lno; + struct C_Added *nxt; } C_Added; -extern RunList *X_lst; -extern ProcList *ready; -extern Symbol *Fname, *oFname; -extern Symbol *context, *owner; -extern YYSTYPE yylval; -extern short has_last, has_code, has_priority; -extern int verbose, IArgs, hastrack, separate, in_for; -extern int implied_semis, ltl_mode, in_seq, par_cnt; - -short has_stack = 0; -int lineno = 1; -int scope_seq[256], scope_level = 0; -char CurScope[MAXSCOPESZ]; -char yytext[2048]; -FILE *yyin, *yyout; - -static C_Added *c_added, *c_tracked; -static IType *Inline_stub[MAXINL]; -static char *ReDiRect; -static char *Inliner[MAXINL], IArg_cont[MAXPAR][MAXLEN]; -static unsigned char in_comment=0; -static int IArgno = 0, Inlining = -1; -static int check_name(char *); -static int last_token = 0; - -#define ValToken(x, y) { if (in_comment) goto again; \ - yylval = nn(ZN,0,ZN,ZN); \ - yylval->val = x; \ - last_token = y; \ - return y; \ - } - -#define SymToken(x, y) { if (in_comment) goto again; \ - yylval = nn(ZN,0,ZN,ZN); \ - yylval->sym = x; \ - last_token = y; \ - return y; \ - } +extern RunList *X_lst; +extern ProcList *ready; +extern Symbol *Fname, *oFname; +extern Symbol *context, *owner; +extern YYSTYPE yylval; +extern short has_last, has_code, has_priority; +extern int verbose, IArgs, hastrack, separate, in_for; +extern int implied_semis, ltl_mode, in_seq, par_cnt; + +short has_stack = 0; +int lineno = 1; +int scope_seq[256], scope_level = 0; +char CurScope[MAXSCOPESZ]; +char yytext[2048]; +FILE *yyin, *yyout; + +static C_Added *c_added, *c_tracked; +static IType *Inline_stub[MAXINL]; +static char *ReDiRect; +static char *Inliner[MAXINL], IArg_cont[MAXPAR][MAXLEN]; +static unsigned char in_comment=0; +static int IArgno = 0, Inlining = -1; +static int check_name(char *); +static int last_token = 0; + +#define ValToken(x, y) { if (in_comment) goto again; \ + yylval = nn(ZN,0,ZN,ZN); \ + yylval->val = x; \ + last_token = y; \ + return y; \ + } + +#define SymToken(x, y) { if (in_comment) goto again; \ + yylval = nn(ZN,0,ZN,ZN); \ + yylval->sym = x; \ + last_token = y; \ + return y; \ + } static int getinline(void); static void uninline(void); @@ -87,830 +90,827 @@ static int PushedBack; static char pushedback[4096]; static void -push_back(char *s) +push_back(const char *s) { - if (PushedBack + strlen(s) > 4094) - { fatal("select statement too large", 0); - } - strcat(pushedback, s); - PushedBack += strlen(s); + if (PushedBack + strlen(s) > 4094) + { fatal("select statement too large", 0); + } + strcat(pushedback, s); + PushedBack += strlen(s); } static int Getchar(void) -{ int c; - - if (PushedBack > 0 && PushBack < PushedBack) - { c = pushedback[PushBack++]; - if (PushBack == PushedBack) - { pushedback[0] = '\0'; - PushBack = PushedBack = 0; - } - return c; /* expanded select statement */ - } - if (Inlining<0) - { do { c = getc(yyin); - } while (c == 0); // ignore null chars - // eventually there will always be an EOF - } else - { c = getinline(); - } +{ int c; + + if (PushedBack > 0 && PushBack < PushedBack) + { c = pushedback[PushBack++]; + if (PushBack == PushedBack) + { pushedback[0] = '\0'; + PushBack = PushedBack = 0; + } + return c; /* expanded select statement */ + } + if (Inlining<0) + { do { c = getc(yyin); + } while (c == 0); // ignore null chars + // eventually there will always be an EOF + } else + { c = getinline(); + } #if 0 - if (0) - { printf("<%c:%d>[%d] ", c, c, Inlining); - } else - { printf("%c", c); - } + if (0) + { printf("<%c:%d>[%d] ", c, c, Inlining); + } else + { printf("%c", c); + } #endif - return c; + return c; } static void Ungetch(int c) { - if (PushedBack > 0 && PushBack > 0) - { PushBack--; - return; - } - - if (Inlining<0) - { ungetc(c,yyin); - } else - { uninline(); - } - if (0) - { printf("\n\n", c); - } + if (PushedBack > 0 && PushBack > 0) + { PushBack--; + return; + } + + if (Inlining<0) + { ungetc(c,yyin); + } else + { uninline(); + } + if (0) + { printf("\n\n", c); + } } static int notdollar(int c) -{ return (c != '$' && c != '\n'); +{ return (c != '$' && c != '\n'); } static int notquote(int c) -{ return (c != '\"' && c != '\n'); +{ return (c != '\"' && c != '\n'); } int isalnum_(int c) -{ return (isalnum(c) || c == '_'); +{ return (isalnum(c) || c == '_'); } static int isalpha_(int c) -{ return isalpha(c); /* could be macro */ +{ return isalpha(c); /* could be macro */ } - + static int isdigit_(int c) -{ return isdigit(c); /* could be macro */ +{ return isdigit(c); /* could be macro */ } static void getword(int first, int (*tst)(int)) -{ int i=0, c; - - yytext[i++]= (char) first; - while (tst(c = Getchar())) - { if (c == EOF) - { break; - } - yytext[i++] = (char) c; - if (c == '\\') - { c = Getchar(); - yytext[i++] = (char) c; /* no tst */ - } } - yytext[i] = '\0'; - - Ungetch(c); +{ int i=0, c; + + yytext[i++]= (char) first; + while (tst(c = Getchar())) + { if (c == EOF) + { break; + } + yytext[i++] = (char) c; + if (c == '\\') + { c = Getchar(); + yytext[i++] = (char) c; /* no tst */ + } } + yytext[i] = '\0'; + + Ungetch(c); } static int follow(int tok, int ifyes, int ifno) -{ int c; +{ int c; - if ((c = Getchar()) == tok) - { return ifyes; - } - Ungetch(c); + if ((c = Getchar()) == tok) + { return ifyes; + } + Ungetch(c); - return ifno; + return ifno; } static IType *seqnames; static void def_inline(Symbol *s, int ln, char *ptr, char *prc, Lextok *nms) -{ IType *tmp; - int cnt = 0; - char *nw = (char *) emalloc(strlen(ptr)+1); - strcpy(nw, ptr); - - for (tmp = seqnames; tmp; cnt++, tmp = tmp->nxt) - if (!strcmp(s->name, tmp->nm->name)) - { non_fatal("procedure name %s redefined", - tmp->nm->name); - tmp->cn = (Lextok *) nw; - tmp->params = nms; - tmp->dln = ln; - tmp->dfn = Fname; - return; - } - tmp = (IType *) emalloc(sizeof(IType)); - tmp->nm = s; - tmp->cn = (Lextok *) nw; - tmp->params = nms; - if (strlen(prc) > 0) - { tmp->prec = (char *) emalloc(strlen(prc)+1); - strcpy(tmp->prec, prc); - } - tmp->dln = ln; - tmp->dfn = Fname; - tmp->uiid = cnt+1; /* so that 0 means: not an inline */ - tmp->nxt = seqnames; - seqnames = tmp; +{ IType *tmp; + int cnt = 0; + char *nw = (char *) emalloc(strlen(ptr)+1); + strcpy(nw, ptr); + + for (tmp = seqnames; tmp; cnt++, tmp = tmp->nxt) + if (!strcmp(s->name, tmp->nm->name)) + { non_fatal("procedure name %s redefined", + tmp->nm->name); + tmp->cn = (Lextok *) nw; + tmp->params = nms; + tmp->dln = ln; + tmp->dfn = Fname; + return; + } + tmp = (IType *) emalloc(sizeof(IType)); + tmp->nm = s; + tmp->cn = (Lextok *) nw; + tmp->params = nms; + if (strlen(prc) > 0) + { tmp->prec = (char *) emalloc(strlen(prc)+1); + strcpy(tmp->prec, prc); + } + tmp->dln = ln; + tmp->dfn = Fname; + tmp->uiid = cnt+1; /* so that 0 means: not an inline */ + tmp->nxt = seqnames; + seqnames = tmp; } void gencodetable(FILE *fd) -{ IType *tmp; - char *q; - int cnt; - - if (separate == 2) return; - - fprintf(fd, "struct {\n"); - fprintf(fd, " char *c; char *t;\n"); - fprintf(fd, "} code_lookup[] = {\n"); - - if (has_code) - for (tmp = seqnames; tmp; tmp = tmp->nxt) - if (tmp->nm->type == CODE_FRAG - || tmp->nm->type == CODE_DECL) - { fprintf(fd, "\t{ \"%s\", ", - tmp->nm->name); - q = (char *) tmp->cn; - - while (*q == '\n' || *q == '\r' || *q == '\\') - q++; - - fprintf(fd, "\""); - cnt = 0; - while (*q && cnt < 1024) /* pangen1.h allows 2048 */ - { switch (*q) { - case '"': - fprintf(fd, "\\\""); - break; - case '%': - fprintf(fd, "%%"); - break; - case '\n': - fprintf(fd, "\\n"); - break; - default: - putc(*q, fd); - break; - } - q++; cnt++; - } - if (*q) fprintf(fd, "..."); - fprintf(fd, "\""); - fprintf(fd, " },\n"); - } - - fprintf(fd, " { (char *) 0, \"\" }\n"); - fprintf(fd, "};\n"); +{ IType *tmp; + char *q; + int cnt; + + if (separate == 2) return; + + fprintf(fd, "struct {\n"); + fprintf(fd, " char *c; char *t;\n"); + fprintf(fd, "} code_lookup[] = {\n"); + + if (has_code) + for (tmp = seqnames; tmp; tmp = tmp->nxt) + if (tmp->nm->type == CODE_FRAG + || tmp->nm->type == CODE_DECL) + { fprintf(fd, "\t{ \"%s\", ", + tmp->nm->name); + q = (char *) tmp->cn; + + while (*q == '\n' || *q == '\r' || *q == '\\') + q++; + + fprintf(fd, "\""); + cnt = 0; + while (*q && cnt < 1024) /* pangen1.h allows 2048 */ + { switch (*q) { + case '"': + fprintf(fd, "\\\""); + break; + case '%': + fprintf(fd, "%%"); + break; + case '\n': + fprintf(fd, "\\n"); + break; + default: + putc(*q, fd); + break; + } + q++; cnt++; + } + if (*q) fprintf(fd, "..."); + fprintf(fd, "\""); + fprintf(fd, " },\n"); + } + + fprintf(fd, " { (char *) 0, \"\" }\n"); + fprintf(fd, "};\n"); } static int iseqname(char *t) -{ IType *tmp; +{ IType *tmp; - for (tmp = seqnames; tmp; tmp = tmp->nxt) - { if (!strcmp(t, tmp->nm->name)) - return 1; - } - return 0; + for (tmp = seqnames; tmp; tmp = tmp->nxt) + { if (!strcmp(t, tmp->nm->name)) + return 1; + } + return 0; } Lextok * return_statement(Lextok *n) { - if (Inline_stub[Inlining]->rval) - { Lextok *g = nn(ZN, NAME, ZN, ZN); - Lextok *h = Inline_stub[Inlining]->rval; - g->sym = lookup("rv_"); - return nn(h, ASGN, h, n); - } else - { fatal("return statement outside inline", (char *) 0); - } - return ZN; + if (Inline_stub[Inlining]->rval) + { Lextok *g = nn(ZN, NAME, ZN, ZN); + Lextok *h = Inline_stub[Inlining]->rval; + g->sym = lookup("rv_"); + return nn(h, ASGN, h, n); + } else + { fatal("return statement outside inline", (char *) 0); + } + return ZN; } static int getinline(void) -{ int c; - - if (ReDiRect) - { c = *ReDiRect++; - if (c == '\0') - { ReDiRect = (char *) 0; - c = *Inliner[Inlining]++; - } - } else - { - c = *Inliner[Inlining]++; - } - - if (c == '\0') - { - lineno = Inline_stub[Inlining]->cln; - Fname = Inline_stub[Inlining]->cfn; - Inlining--; +{ int c; + + if (ReDiRect) + { c = *ReDiRect++; + if (c == '\0') + { ReDiRect = (char *) 0; + c = *Inliner[Inlining]++; + } + } else + { + c = *Inliner[Inlining]++; + } + + if (c == '\0') + { + lineno = Inline_stub[Inlining]->cln; + Fname = Inline_stub[Inlining]->cfn; + Inlining--; #if 0 - if (verbose&32) - printf("spin: %s:%d, done inlining %s\n", - Fname, lineno, Inline_stub[Inlining+1]->nm->name); + if (verbose&32) + printf("spin: %s:%d, done inlining %s\n", + Fname, lineno, Inline_stub[Inlining+1]->nm->name); #endif - return Getchar(); - } - return c; + return Getchar(); + } + return c; } static void uninline(void) { - if (ReDiRect) - ReDiRect--; - else - Inliner[Inlining]--; + if (ReDiRect) + ReDiRect--; + else + Inliner[Inlining]--; } int is_inline(void) { - if (Inlining < 0) - return 0; /* i.e., not an inline */ - if (Inline_stub[Inlining] == NULL) - fatal("unexpected, inline_stub not set", 0); - return Inline_stub[Inlining]->uiid; + if (Inlining < 0) + return 0; /* i.e., not an inline */ + if (Inline_stub[Inlining] == NULL) + fatal("unexpected, inline_stub not set", 0); + return Inline_stub[Inlining]->uiid; } IType * -find_inline(char *s) -{ IType *tmp; +find_inline(const char *s) +{ IType *tmp; - for (tmp = seqnames; tmp; tmp = tmp->nxt) - if (!strcmp(s, tmp->nm->name)) - break; - if (!tmp) - fatal("cannot happen, missing inline def %s", s); + for (tmp = seqnames; tmp; tmp = tmp->nxt) + if (!strcmp(s, tmp->nm->name)) + break; + if (!tmp) + fatal("cannot happen, missing inline def %s", s); - return tmp; + return tmp; } void -c_state(Symbol *s, Symbol *t, Symbol *ival) /* name, scope, ival */ -{ C_Added *r; - - r = (C_Added *) emalloc(sizeof(C_Added)); - r->s = s; /* pointer to a data object */ - r->t = t; /* size of object, or "global", or "local proctype_name" */ - r->ival = ival; - r->lno = lineno; - r->fnm = Fname; - r->nxt = c_added; - - if(strncmp(r->s->name, "\"unsigned unsigned", 18) == 0) - { int i; - for (i = 10; i < 18; i++) - { r->s->name[i] = ' '; - } - /* printf("corrected <%s>\n", r->s->name); */ - } - c_added = r; +c_state(Symbol *s, Symbol *t, Symbol *ival) /* name, scope, ival */ +{ C_Added *r; + + r = (C_Added *) emalloc(sizeof(C_Added)); + r->s = s; /* pointer to a data object */ + r->t = t; /* size of object, or "global", or "local proctype_name" */ + r->ival = ival; + r->lno = lineno; + r->fnm = Fname; + r->nxt = c_added; + + if(strncmp(r->s->name, "\"unsigned unsigned", 18) == 0) + { r->s->name = strdup("\"unsigned "); + /* printf("corrected <%s>\n", r->s->name); */ + } + c_added = r; } void -c_track(Symbol *s, Symbol *t, Symbol *stackonly) /* name, size */ -{ C_Added *r; - - r = (C_Added *) emalloc(sizeof(C_Added)); - r->s = s; - r->t = t; - r->ival = stackonly; /* abuse of name */ - r->nxt = c_tracked; - r->fnm = Fname; - r->lno = lineno; - c_tracked = r; - - if (stackonly != ZS) - { if (strcmp(stackonly->name, "\"Matched\"") == 0) - r->ival = ZS; /* the default */ - else if (strcmp(stackonly->name, "\"UnMatched\"") != 0 - && strcmp(stackonly->name, "\"unMatched\"") != 0 - && strcmp(stackonly->name, "\"StackOnly\"") != 0) - non_fatal("expecting '[Un]Matched', saw %s", stackonly->name); - else - has_stack = 1; /* unmatched stack */ - } +c_track(Symbol *s, Symbol *t, Symbol *stackonly) /* name, size */ +{ C_Added *r; + + r = (C_Added *) emalloc(sizeof(C_Added)); + r->s = s; + r->t = t; + r->ival = stackonly; /* abuse of name */ + r->nxt = c_tracked; + r->fnm = Fname; + r->lno = lineno; + c_tracked = r; + + if (stackonly != ZS) + { if (strcmp(stackonly->name, "\"Matched\"") == 0) + r->ival = ZS; /* the default */ + else if (strcmp(stackonly->name, "\"UnMatched\"") != 0 + && strcmp(stackonly->name, "\"unMatched\"") != 0 + && strcmp(stackonly->name, "\"StackOnly\"") != 0) + non_fatal("expecting '[Un]Matched', saw %s", stackonly->name); + else + has_stack = 1; /* unmatched stack */ + } } -char * -skip_white(char *p) +const char * +skip_white(const char *p) { - if (p != NULL) - { while (*p == ' ' || *p == '\t') - p++; - } else - { fatal("bad format - 1", (char *) 0); - } - return p; + if (p != NULL) + { while (*p == ' ' || *p == '\t') + p++; + } else + { fatal("bad format - 1", (char *) 0); + } + return p; } -char * -skip_nonwhite(char *p) +const char * +skip_nonwhite(const char *p) { - if (p != NULL) - { while (*p != ' ' && *p != '\t') - p++; - } else - { fatal("bad format - 2", (char *) 0); - } - return p; + if (p != NULL) + { while (*p != ' ' && *p != '\t') + p++; + } else + { fatal("bad format - 2", (char *) 0); + } + return p; } -static char * +static const char * jump_etc(C_Added *r) -{ char *op = r->s->name; - char *p = op; - char *q = (char *) 0; - int oln = lineno; - Symbol *ofnm = Fname; - - /* try to get the type separated from the name */ - lineno = r->lno; - Fname = r->fnm; - - p = skip_white(p); /* initial white space */ - - if (strncmp(p, "enum", strlen("enum")) == 0) /* special case: a two-part typename */ - { p += strlen("enum")+1; - p = skip_white(p); - } - if (strncmp(p, "unsigned", strlen("unsigned")) == 0) /* possibly a two-part typename */ - { p += strlen("unsigned")+1; - q = p = skip_white(p); - } - p = skip_nonwhite(p); /* type name */ - p = skip_white(p); /* white space */ - while (*p == '*') p++; /* decorations */ - p = skip_white(p); /* white space */ - - if (*p == '\0') - { if (q) - { p = q; /* unsigned with implied 'int' */ - } else - { fatal("c_state format (%s)", op); - } } - - if (strchr(p, '[') - && (!r->ival - || !r->ival->name - || !strchr(r->ival->name, '{'))) /* was !strchr(p, '{')) */ - { non_fatal("array initialization error, c_state (%s)", p); - p = (char *) 0; - } - - lineno = oln; - Fname = ofnm; - - return p; +{ const char *op = r->s->name; + const char *p = op; + const char *q = (const char *) 0; + int oln = lineno; + Symbol *ofnm = Fname; + + /* try to get the type separated from the name */ + lineno = r->lno; + Fname = r->fnm; + + p = skip_white(p); /* initial white space */ + + if (strncmp(p, "enum", strlen("enum")) == 0) /* special case: a two-part typename */ + { p += strlen("enum")+1; + p = skip_white(p); + } + if (strncmp(p, "unsigned", strlen("unsigned")) == 0) /* possibly a two-part typename */ + { p += strlen("unsigned")+1; + q = p = skip_white(p); + } + p = skip_nonwhite(p); /* type name */ + p = skip_white(p); /* white space */ + while (*p == '*') p++; /* decorations */ + p = skip_white(p); /* white space */ + + if (*p == '\0') + { if (q) + { p = q; /* unsigned with implied 'int' */ + } else + { fatal("c_state format (%s)", op); + } } + + if (strchr(p, '[') + && (!r->ival + || !r->ival->name + || !strchr(r->ival->name, '{'))) /* was !strchr(p, '{')) */ + { non_fatal("array initialization error, c_state (%s)", p); + p = (const char *) 0; + } + + lineno = oln; + Fname = ofnm; + + return p; } void c_add_globinit(FILE *fd) -{ C_Added *r; - char *p, *q; - - fprintf(fd, "void\nglobinit(void)\n{\n"); - for (r = c_added; r; r = r->nxt) - { if (r->ival == ZS) - continue; - - if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0) - { for (q = r->ival->name; *q; q++) - { if (*q == '\"') - *q = ' '; - if (*q == '\\') - *q++ = ' '; /* skip over the next */ - } - p = jump_etc(r); /* e.g., "int **q" */ - if (p) - fprintf(fd, " now.%s = %s;\n", p, r->ival->name); - - } else - if (strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0) - { for (q = r->ival->name; *q; q++) - { if (*q == '\"') - *q = ' '; - if (*q == '\\') - *q++ = ' '; /* skip over the next */ - } - p = jump_etc(r); /* e.g., "int **q" */ - if (p) - fprintf(fd, " %s = %s;\n", p, r->ival->name); /* no now. prefix */ - - } } - fprintf(fd, "}\n"); +{ C_Added *r; + const char *p; char *q; + + fprintf(fd, "void\nglobinit(void)\n{\n"); + for (r = c_added; r; r = r->nxt) + { if (r->ival == ZS) + continue; + + if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0) + { for (q = r->ival->name; *q; q++) + { if (*q == '\"') + *q = ' '; + if (*q == '\\') + *q++ = ' '; /* skip over the next */ + } + p = jump_etc(r); /* e.g., "int **q" */ + if (p) + fprintf(fd, " now.%s = %s;\n", p, r->ival->name); + + } else + if (strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0) + { for (q = r->ival->name; *q; q++) + { if (*q == '\"') + *q = ' '; + if (*q == '\\') + *q++ = ' '; /* skip over the next */ + } + p = jump_etc(r); /* e.g., "int **q" */ + if (p) + fprintf(fd, " %s = %s;\n", p, r->ival->name); /* no now. prefix */ + + } } + fprintf(fd, "}\n"); } void -c_add_locinit(FILE *fd, int tpnr, char *pnm) -{ C_Added *r; - char *p, *q, *s; - int frst = 1; - - fprintf(fd, "void\nlocinit%d(int h)\n{\n", tpnr); - for (r = c_added; r; r = r->nxt) - if (r->ival != ZS - && strncmp(r->t->name, " Local", strlen(" Local")) == 0) - { for (q = r->ival->name; *q; q++) - if (*q == '\"') - *q = ' '; - p = jump_etc(r); /* e.g., "int **q" */ - - q = r->t->name + strlen(" Local"); - while (*q == ' ' || *q == '\t') - q++; /* process name */ - - s = (char *) emalloc(strlen(q)+1); - strcpy(s, q); - - q = &s[strlen(s)-1]; - while (*q == ' ' || *q == '\t') - *q-- = '\0'; - - if (strcmp(pnm, s) != 0) - continue; - - if (frst) - { fprintf(fd, "\tuchar *_this = pptr(h);\n"); - frst = 0; - } - - if (p) - { fprintf(fd, "\t\t((P%d *)_this)->%s = %s;\n", - tpnr, p, r->ival->name); - } - } - fprintf(fd, "}\n"); +c_add_locinit(FILE *fd, int tpnr, const char *pnm) +{ C_Added *r; + const char *p; char *q, *s; + int frst = 1; + + fprintf(fd, "void\nlocinit%d(int h)\n{\n", tpnr); + for (r = c_added; r; r = r->nxt) + if (r->ival != ZS + && strncmp(r->t->name, " Local", strlen(" Local")) == 0) + { for (q = r->ival->name; *q; q++) + if (*q == '\"') + *q = ' '; + p = jump_etc(r); /* e.g., "int **q" */ + + q = r->t->name + strlen(" Local"); + while (*q == ' ' || *q == '\t') + q++; /* process name */ + + s = (char *) emalloc(strlen(q)+1); + strcpy(s, q); + + q = &s[strlen(s)-1]; + while (*q == ' ' || *q == '\t') + *q-- = '\0'; + + if (strcmp(pnm, s) != 0) + continue; + + if (frst) + { fprintf(fd, "\tuchar *_this = pptr(h);\n"); + frst = 0; + } + + if (p) + { fprintf(fd, "\t\t((P%d *)_this)->%s = %s;\n", + tpnr, p, r->ival->name); + } + } + fprintf(fd, "}\n"); } /* tracking: - 1. for non-global and non-local c_state decls: add up all the sizes in c_added - 2. add a global char array of that size into now - 3. generate a routine that memcpy's the required values into that array - 4. generate a call to that routine + 1. for non-global and non-local c_state decls: add up all the sizes in c_added + 2. add a global char array of that size into now + 3. generate a routine that memcpy's the required values into that array + 4. generate a call to that routine */ void c_preview(void) -{ C_Added *r; - - hastrack = 0; - if (c_tracked) - hastrack = 1; - else - for (r = c_added; r; r = r->nxt) - if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 - && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 - && strncmp(r->t->name, " Local", strlen(" Local")) != 0) - { hastrack = 1; /* c_state variant now obsolete */ - break; - } +{ C_Added *r; + + hastrack = 0; + if (c_tracked) + hastrack = 1; + else + for (r = c_added; r; r = r->nxt) + if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 + && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 + && strncmp(r->t->name, " Local", strlen(" Local")) != 0) + { hastrack = 1; /* c_state variant now obsolete */ + break; + } } int -c_add_sv(FILE *fd) /* 1+2 -- called in pangen1.c */ -{ C_Added *r; - int cnt = 0; - - if (!c_added && !c_tracked) return 0; - - for (r = c_added; r; r = r->nxt) /* pickup global decls */ - if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0) - fprintf(fd, " %s;\n", r->s->name); - - for (r = c_added; r; r = r->nxt) - if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 - && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 - && strncmp(r->t->name, " Local", strlen(" Local")) != 0) - { cnt++; /* obsolete use */ - } - - for (r = c_tracked; r; r = r->nxt) - cnt++; /* preferred use */ - - if (cnt == 0) return 0; - - cnt = 0; - fprintf(fd, " uchar c_state["); - for (r = c_added; r; r = r->nxt) - if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 - && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 - && strncmp(r->t->name, " Local", strlen(" Local")) != 0) - { fprintf(fd, "%ssizeof(%s)", - (cnt==0)?"":"+", r->t->name); - cnt++; - } - - for (r = c_tracked; r; r = r->nxt) - { if (r->ival != ZS) continue; - - fprintf(fd, "%s%s", - (cnt==0)?"":"+", r->t->name); - cnt++; - } - - if (cnt == 0) fprintf(fd, "4"); /* now redundant */ - fprintf(fd, "];\n"); - return 1; +c_add_sv(FILE *fd) /* 1+2 -- called in pangen1.c */ +{ C_Added *r; + int cnt = 0; + + if (!c_added && !c_tracked) return 0; + + for (r = c_added; r; r = r->nxt) /* pickup global decls */ + if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0) + fprintf(fd, " %s;\n", r->s->name); + + for (r = c_added; r; r = r->nxt) + if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 + && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 + && strncmp(r->t->name, " Local", strlen(" Local")) != 0) + { cnt++; /* obsolete use */ + } + + for (r = c_tracked; r; r = r->nxt) + cnt++; /* preferred use */ + + if (cnt == 0) return 0; + + cnt = 0; + fprintf(fd, " uchar c_state["); + for (r = c_added; r; r = r->nxt) + if (strncmp(r->t->name, " Global ", strlen(" Global ")) != 0 + && strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) != 0 + && strncmp(r->t->name, " Local", strlen(" Local")) != 0) + { fprintf(fd, "%ssizeof(%s)", + (cnt==0)?"":"+", r->t->name); + cnt++; + } + + for (r = c_tracked; r; r = r->nxt) + { if (r->ival != ZS) continue; + + fprintf(fd, "%s%s", + (cnt==0)?"":"+", r->t->name); + cnt++; + } + + if (cnt == 0) fprintf(fd, "4"); /* now redundant */ + fprintf(fd, "];\n"); + return 1; } void c_stack_size(FILE *fd) -{ C_Added *r; - int cnt = 0; - - for (r = c_tracked; r; r = r->nxt) - if (r->ival != ZS) - { fprintf(fd, "%s%s", - (cnt==0)?"":"+", r->t->name); - cnt++; - } - if (cnt == 0) - { fprintf(fd, "WS"); - } +{ C_Added *r; + int cnt = 0; + + for (r = c_tracked; r; r = r->nxt) + if (r->ival != ZS) + { fprintf(fd, "%s%s", + (cnt==0)?"":"+", r->t->name); + cnt++; + } + if (cnt == 0) + { fprintf(fd, "WS"); + } } void c_add_stack(FILE *fd) -{ C_Added *r; - int cnt = 0; +{ C_Added *r; + int cnt = 0; - if ((!c_added && !c_tracked) || !has_stack) - { return; - } + if ((!c_added && !c_tracked) || !has_stack) + { return; + } - for (r = c_tracked; r; r = r->nxt) - if (r->ival != ZS) - { cnt++; - } + for (r = c_tracked; r; r = r->nxt) + if (r->ival != ZS) + { cnt++; + } - if (cnt > 0) - { fprintf(fd, " uchar c_stack[StackSize];\n"); - } + if (cnt > 0) + { fprintf(fd, " uchar c_stack[StackSize];\n"); + } } void c_add_hidden(FILE *fd) -{ C_Added *r; - - for (r = c_added; r; r = r->nxt) /* pickup hidden decls */ - if (strncmp(r->t->name, "\"Hidden\"", strlen("\"Hidden\"")) == 0) - { r->s->name[strlen(r->s->name)-1] = ' '; - fprintf(fd, "%s; /* Hidden */\n", &r->s->name[1]); - r->s->name[strlen(r->s->name)-1] = '"'; - } - /* called before c_add_def - quotes are still there */ +{ C_Added *r; + + for (r = c_added; r; r = r->nxt) /* pickup hidden decls */ + if (strncmp(r->t->name, "\"Hidden\"", strlen("\"Hidden\"")) == 0) + { r->s->name[strlen(r->s->name)-1] = ' '; + fprintf(fd, "%s; /* Hidden */\n", &r->s->name[1]); + r->s->name[strlen(r->s->name)-1] = '"'; + } + /* called before c_add_def - quotes are still there */ } void -c_add_loc(FILE *fd, char *s) /* state vector entries for proctype s */ -{ C_Added *r; - static char buf[1024]; - char *p; - - if (!c_added) return; - - strcpy(buf, s); - strcat(buf, " "); - for (r = c_added; r; r = r->nxt) /* pickup local decls */ - { if (strncmp(r->t->name, " Local", strlen(" Local")) == 0) - { p = r->t->name + strlen(" Local"); - fprintf(fd, "/* XXX p=<%s>, s=<%s>, buf=<%s> r->s->name=<%s>XXX */\n", - p, s, buf, r->s->name); - while (*p == ' ' || *p == '\t') - { p++; - } - if (strcmp(p, buf) == 0 - || (strncmp(p, "init", 4) == 0 && strncmp(buf, ":init:", 6) == 0)) - { fprintf(fd, " %s;\n", r->s->name); - } } } +c_add_loc(FILE *fd, const char *s) /* state vector entries for proctype s */ +{ C_Added *r; + static char buf[1024]; + char *p; + + if (!c_added) return; + + strcpy(buf, s); + strcat(buf, " "); + for (r = c_added; r; r = r->nxt) /* pickup local decls */ + { if (strncmp(r->t->name, " Local", strlen(" Local")) == 0) + { p = r->t->name + strlen(" Local"); + fprintf(fd, "/* XXX p=<%s>, s=<%s>, buf=<%s> r->s->name=<%s>XXX */\n", + p, s, buf, r->s->name); + while (*p == ' ' || *p == '\t') + { p++; + } + if (strcmp(p, buf) == 0 + || (strncmp(p, "init", 4) == 0 && strncmp(buf, ":init:", 6) == 0)) + { fprintf(fd, " %s;\n", r->s->name); + } } } } void -c_add_def(FILE *fd) /* 3 - called in plunk_c_fcts() */ -{ C_Added *r; - - fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n"); - for (r = c_added; r; r = r->nxt) - { r->s->name[strlen(r->s->name)-1] = ' '; - r->s->name[0] = ' '; /* remove the "s */ - - r->t->name[strlen(r->t->name)-1] = ' '; - r->t->name[0] = ' '; - - if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 - || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 - || strncmp(r->t->name, " Local", strlen(" Local")) == 0) - continue; - - if (strchr(r->s->name, '&')) - fatal("dereferencing state object: %s", r->s->name); - - fprintf(fd, "extern %s %s;\n", r->t->name, r->s->name); - } - for (r = c_tracked; r; r = r->nxt) - { r->s->name[strlen(r->s->name)-1] = ' '; - r->s->name[0] = ' '; /* remove " */ - - r->t->name[strlen(r->t->name)-1] = ' '; - r->t->name[0] = ' '; - } - - if (separate == 2) - { fprintf(fd, "#endif\n"); - return; - } - - if (has_stack) - { fprintf(fd, "int cpu_printf(const char *, ...);\n"); - fprintf(fd, "void\nc_stack(uchar *p_t_r)\n{\n"); - fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " cpu_printf(\"c_stack %%u\\n\", p_t_r);\n"); - fprintf(fd, "#endif\n"); - for (r = c_tracked; r; r = r->nxt) - { if (r->ival == ZS) continue; - - fprintf(fd, "\tif(%s)\n", r->s->name); - fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n", - r->s->name, r->t->name); - fprintf(fd, "\telse\n"); - fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n", - r->t->name); - fprintf(fd, "\tp_t_r += %s;\n", r->t->name); - } - fprintf(fd, "}\n\n"); - } - - fprintf(fd, "void\nc_update(uchar *p_t_r)\n{\n"); - fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " printf(\"c_update %%p\\n\", p_t_r);\n"); - fprintf(fd, "#endif\n"); - for (r = c_added; r; r = r->nxt) - { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 - || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 - || strncmp(r->t->name, " Local", strlen(" Local")) == 0) - continue; - - fprintf(fd, "\tmemcpy(p_t_r, &%s, sizeof(%s));\n", - r->s->name, r->t->name); - fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name); - } - - for (r = c_tracked; r; r = r->nxt) - { if (r->ival) continue; - - fprintf(fd, "\tif(%s)\n", r->s->name); - fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n", - r->s->name, r->t->name); - fprintf(fd, "\telse\n"); - fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n", - r->t->name); - fprintf(fd, "\tp_t_r += %s;\n", r->t->name); - } - - fprintf(fd, "}\n"); - - if (has_stack) - { fprintf(fd, "void\nc_unstack(uchar *p_t_r)\n{\n"); - fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " cpu_printf(\"c_unstack %%u\\n\", p_t_r);\n"); - fprintf(fd, "#endif\n"); - for (r = c_tracked; r; r = r->nxt) - { if (r->ival == ZS) continue; - - fprintf(fd, "\tif(%s)\n", r->s->name); - fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n", - r->s->name, r->t->name); - fprintf(fd, "\tp_t_r += %s;\n", r->t->name); - } - fprintf(fd, "}\n"); - } - - fprintf(fd, "void\nc_revert(uchar *p_t_r)\n{\n"); - fprintf(fd, "#ifdef VERBOSE\n"); - fprintf(fd, " printf(\"c_revert %%p\\n\", p_t_r);\n"); - fprintf(fd, "#endif\n"); - for (r = c_added; r; r = r->nxt) - { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 - || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 - || strncmp(r->t->name, " Local", strlen(" Local")) == 0) - continue; - - fprintf(fd, "\tmemcpy(&%s, p_t_r, sizeof(%s));\n", - r->s->name, r->t->name); - fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name); - } - for (r = c_tracked; r; r = r->nxt) - { if (r->ival != ZS) continue; - - fprintf(fd, "\tif(%s)\n", r->s->name); - fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n", - r->s->name, r->t->name); - fprintf(fd, "\tp_t_r += %s;\n", r->t->name); - } - - fprintf(fd, "}\n"); - fprintf(fd, "#endif\n"); +c_add_def(FILE *fd) /* 3 - called in plunk_c_fcts() */ +{ C_Added *r; + + fprintf(fd, "#if defined(C_States) && (HAS_TRACK==1)\n"); + for (r = c_added; r; r = r->nxt) + { r->s->name[strlen(r->s->name)-1] = ' '; + r->s->name[0] = ' '; /* remove the "s */ + + r->t->name[strlen(r->t->name)-1] = ' '; + r->t->name[0] = ' '; + + if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 + || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 + || strncmp(r->t->name, " Local", strlen(" Local")) == 0) + continue; + + if (strchr(r->s->name, '&')) + fatal("dereferencing state object: %s", r->s->name); + + fprintf(fd, "extern %s %s;\n", r->t->name, r->s->name); + } + for (r = c_tracked; r; r = r->nxt) + { r->s->name[strlen(r->s->name)-1] = ' '; + r->s->name[0] = ' '; /* remove " */ + + r->t->name[strlen(r->t->name)-1] = ' '; + r->t->name[0] = ' '; + } + + if (separate == 2) + { fprintf(fd, "#endif\n"); + return; + } + + if (has_stack) + { fprintf(fd, "int cpu_printf(const char *, ...);\n"); + fprintf(fd, "void\nc_stack(uchar *p_t_r)\n{\n"); + fprintf(fd, "#ifdef VERBOSE\n"); + fprintf(fd, " cpu_printf(\"c_stack %%u\\n\", p_t_r);\n"); + fprintf(fd, "#endif\n"); + for (r = c_tracked; r; r = r->nxt) + { if (r->ival == ZS) continue; + + fprintf(fd, "\tif(%s)\n", r->s->name); + fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n", + r->s->name, r->t->name); + fprintf(fd, "\telse\n"); + fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n", + r->t->name); + fprintf(fd, "\tp_t_r += %s;\n", r->t->name); + } + fprintf(fd, "}\n\n"); + } + + fprintf(fd, "void\nc_update(uchar *p_t_r)\n{\n"); + fprintf(fd, "#ifdef VERBOSE\n"); + fprintf(fd, " printf(\"c_update %%p\\n\", p_t_r);\n"); + fprintf(fd, "#endif\n"); + for (r = c_added; r; r = r->nxt) + { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 + || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 + || strncmp(r->t->name, " Local", strlen(" Local")) == 0) + continue; + + fprintf(fd, "\tmemcpy(p_t_r, &%s, sizeof(%s));\n", + r->s->name, r->t->name); + fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name); + } + + for (r = c_tracked; r; r = r->nxt) + { if (r->ival) continue; + + fprintf(fd, "\tif(%s)\n", r->s->name); + fprintf(fd, "\t\tmemcpy(p_t_r, %s, %s);\n", + r->s->name, r->t->name); + fprintf(fd, "\telse\n"); + fprintf(fd, "\t\tmemset(p_t_r, 0, %s);\n", + r->t->name); + fprintf(fd, "\tp_t_r += %s;\n", r->t->name); + } + + fprintf(fd, "}\n"); + + if (has_stack) + { fprintf(fd, "void\nc_unstack(uchar *p_t_r)\n{\n"); + fprintf(fd, "#ifdef VERBOSE\n"); + fprintf(fd, " cpu_printf(\"c_unstack %%u\\n\", p_t_r);\n"); + fprintf(fd, "#endif\n"); + for (r = c_tracked; r; r = r->nxt) + { if (r->ival == ZS) continue; + + fprintf(fd, "\tif(%s)\n", r->s->name); + fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n", + r->s->name, r->t->name); + fprintf(fd, "\tp_t_r += %s;\n", r->t->name); + } + fprintf(fd, "}\n"); + } + + fprintf(fd, "void\nc_revert(uchar *p_t_r)\n{\n"); + fprintf(fd, "#ifdef VERBOSE\n"); + fprintf(fd, " printf(\"c_revert %%p\\n\", p_t_r);\n"); + fprintf(fd, "#endif\n"); + for (r = c_added; r; r = r->nxt) + { if (strncmp(r->t->name, " Global ", strlen(" Global ")) == 0 + || strncmp(r->t->name, " Hidden ", strlen(" Hidden ")) == 0 + || strncmp(r->t->name, " Local", strlen(" Local")) == 0) + continue; + + fprintf(fd, "\tmemcpy(&%s, p_t_r, sizeof(%s));\n", + r->s->name, r->t->name); + fprintf(fd, "\tp_t_r += sizeof(%s);\n", r->t->name); + } + for (r = c_tracked; r; r = r->nxt) + { if (r->ival != ZS) continue; + + fprintf(fd, "\tif(%s)\n", r->s->name); + fprintf(fd, "\t\tmemcpy(%s, p_t_r, %s);\n", + r->s->name, r->t->name); + fprintf(fd, "\tp_t_r += %s;\n", r->t->name); + } + + fprintf(fd, "}\n"); + fprintf(fd, "#endif\n"); } void plunk_reverse(FILE *fd, IType *p, int matchthis) -{ char *y, *z; - - if (!p) return; - plunk_reverse(fd, p->nxt, matchthis); - - if (!p->nm->context - && p->nm->type == matchthis - && p->is_expr == 0) - { fprintf(fd, "\n/* start of %s */\n", p->nm->name); - z = (char *) p->cn; - while (*z == '\n' || *z == '\r' || *z == '\\') - { z++; - } - /* e.g.: \#include "..." */ - - y = z; - while ((y = strstr(y, "\\#")) != NULL) - { *y = '\n'; y++; - } - - fprintf(fd, "%s\n", z); - fprintf(fd, "\n/* end of %s */\n", p->nm->name); - } +{ char *y, *z; + + if (!p) return; + plunk_reverse(fd, p->nxt, matchthis); + + if (!p->nm->context + && p->nm->type == matchthis + && p->is_expr == 0) + { fprintf(fd, "\n/* start of %s */\n", p->nm->name); + z = (char *) p->cn; + while (*z == '\n' || *z == '\r' || *z == '\\') + { z++; + } + /* e.g.: \#include "..." */ + + y = z; + while ((y = strstr(y, "\\#")) != NULL) + { *y = '\n'; y++; + } + + fprintf(fd, "%s\n", z); + fprintf(fd, "\n/* end of %s */\n", p->nm->name); + } } void plunk_c_decls(FILE *fd) { - plunk_reverse(fd, seqnames, CODE_DECL); + plunk_reverse(fd, seqnames, CODE_DECL); } void plunk_c_fcts(FILE *fd) { - if (separate == 2 && hastrack) - { c_add_def(fd); - return; - } + if (separate == 2 && hastrack) + { c_add_def(fd); + return; + } - c_add_hidden(fd); - plunk_reverse(fd, seqnames, CODE_FRAG); + c_add_hidden(fd); + plunk_reverse(fd, seqnames, CODE_FRAG); - if (c_added || c_tracked) /* enables calls to c_revert and c_update */ - fprintf(fd, "#define C_States 1\n"); - else - fprintf(fd, "#undef C_States\n"); + if (c_added || c_tracked) /* enables calls to c_revert and c_update */ + fprintf(fd, "#define C_States 1\n"); + else + fprintf(fd, "#undef C_States\n"); - if (hastrack) - c_add_def(fd); + if (hastrack) + c_add_def(fd); - c_add_globinit(fd); - do_locinits(fd); + c_add_globinit(fd); + do_locinits(fd); } static void check_inline(IType *tmp) -{ char buf[128]; - ProcList *p; - - if (!X_lst) return; - - for (p = ready; p; p = p->nxt) - { if (strcmp(p->n->name, X_lst->n->name) == 0) - continue; - sprintf(buf, "P%s->", p->n->name); - if (strstr((char *)tmp->cn, buf)) - { printf("spin: in proctype %s, ref to object in proctype %s\n", - X_lst->n->name, p->n->name); - fatal("invalid variable ref in '%s'", tmp->nm->name); - } } +{ char buf[128]; + ProcList *p; + + if (!X_lst) return; + + for (p = ready; p; p = p->nxt) + { if (strcmp(p->n->name, X_lst->n->name) == 0) + continue; + sprintf(buf, "P%s->", p->n->name); + if (strstr((char *)tmp->cn, buf)) + { printf("spin: in proctype %s, ref to object in proctype %s\n", + X_lst->n->name, p->n->name); + fatal("invalid variable ref in '%s'", tmp->nm->name); + } } } extern short terse; @@ -918,1103 +918,1103 @@ extern short nocast; void plunk_expr(FILE *fd, char *s) -{ IType *tmp; - char *q; - - tmp = find_inline(s); - check_inline(tmp); - - if (terse && nocast) - { for (q = (char *) tmp->cn; q && *q != '\0'; q++) - { fflush(fd); - if (*q == '"') - { fprintf(fd, "\\"); - } - fprintf(fd, "%c", *q); - } - } else - { fprintf(fd, "%s", (char *) tmp->cn); - } +{ IType *tmp; + char *q; + + tmp = find_inline(s); + check_inline(tmp); + + if (terse && nocast) + { for (q = (char *) tmp->cn; q && *q != '\0'; q++) + { fflush(fd); + if (*q == '"') + { fprintf(fd, "\\"); + } + fprintf(fd, "%c", *q); + } + } else + { fprintf(fd, "%s", (char *) tmp->cn); + } } void -preruse(FILE *fd, Lextok *n) /* check a condition for c_expr with preconditions */ -{ IType *tmp; - - if (!n) return; - if (n->ntyp == C_EXPR) - { tmp = find_inline(n->sym->name); - if (tmp->prec) - { fprintf(fd, "if (!(%s)) { if (!readtrail) { depth++; ", tmp->prec); - fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t; trpt->st = tt; "); - fprintf(fd, "uerror(\"c_expr line %d precondition false: %s\"); continue;", - tmp->dln, tmp->prec); - fprintf(fd, " } else { printf(\"pan: precondition false: %s\\n\"); ", - tmp->prec); - fprintf(fd, "_m = 3; goto P999; } } \n\t\t"); - } - } else - { preruse(fd, n->rgt); - preruse(fd, n->lft); - } +preruse(FILE *fd, Lextok *n) /* check a condition for c_expr with preconditions */ +{ IType *tmp; + + if (!n) return; + if (n->ntyp == C_EXPR) + { tmp = find_inline(n->sym->name); + if (tmp->prec) + { fprintf(fd, "if (!(%s)) { if (!readtrail) { depth++; ", tmp->prec); + fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t; trpt->st = tt; "); + fprintf(fd, "uerror(\"c_expr line %d precondition false: %s\"); continue;", + tmp->dln, tmp->prec); + fprintf(fd, " } else { printf(\"pan: precondition false: %s\\n\"); ", + tmp->prec); + fprintf(fd, "_m = 3; goto P999; } } \n\t\t"); + } + } else + { preruse(fd, n->rgt); + preruse(fd, n->lft); + } } int glob_inline(char *s) -{ IType *tmp; - char *bdy; +{ IType *tmp; + char *bdy; - tmp = find_inline(s); - bdy = (char *) tmp->cn; - return (strstr(bdy, "now.") /* global ref or */ - || strchr(bdy, '(') > bdy); /* possible C-function call */ + tmp = find_inline(s); + bdy = (char *) tmp->cn; + return (strstr(bdy, "now.") /* global ref or */ + || strchr(bdy, '(') > bdy); /* possible C-function call */ } char * -put_inline(FILE *fd, char *s) -{ IType *tmp; +put_inline(__attribute__ ((unused)) FILE *fd, const char *s) +{ IType *tmp; - tmp = find_inline(s); - check_inline(tmp); - return (char *) tmp->cn; + tmp = find_inline(s); + check_inline(tmp); + return (char *) tmp->cn; } void mark_last(void) { - if (seqnames) - { seqnames->is_expr = 1; - } + if (seqnames) + { seqnames->is_expr = 1; + } } void -plunk_inline(FILE *fd, char *s, int how, int gencode) /* c_code with precondition */ -{ IType *tmp; - - tmp = find_inline(s); - check_inline(tmp); - - fprintf(fd, "{ "); - if (how && tmp->prec) - { fprintf(fd, "if (!(%s)) { if (!readtrail) {", - tmp->prec); - fprintf(fd, " uerror(\"c_code line %d precondition false: %s\"); continue; ", - tmp->dln, - tmp->prec); - fprintf(fd, "} else { "); - fprintf(fd, "printf(\"pan: precondition false: %s\\n\"); _m = 3; goto P999; } } ", - tmp->prec); - } - - if (!gencode) /* not in d_step */ - { fprintf(fd, "\n\t\tsv_save();"); - } - - fprintf(fd, "%s", (char *) tmp->cn); - fprintf(fd, " }\n"); +plunk_inline(FILE *fd, char *s, int how, int gencode) /* c_code with precondition */ +{ IType *tmp; + + tmp = find_inline(s); + check_inline(tmp); + + fprintf(fd, "{ "); + if (how && tmp->prec) + { fprintf(fd, "if (!(%s)) { if (!readtrail) {", + tmp->prec); + fprintf(fd, " uerror(\"c_code line %d precondition false: %s\"); continue; ", + tmp->dln, + tmp->prec); + fprintf(fd, "} else { "); + fprintf(fd, "printf(\"pan: precondition false: %s\\n\"); _m = 3; goto P999; } } ", + tmp->prec); + } + + if (!gencode) /* not in d_step */ + { fprintf(fd, "\n\t\tsv_save();"); + } + + fprintf(fd, "%s", (char *) tmp->cn); + fprintf(fd, " }\n"); } int -side_scan(char *t, char *pat) -{ char *r = strstr(t, pat); - return (r - && *(r-1) != '"' - && *(r-1) != '\''); -} +side_scan(const char *t, const char *pat) + { const char *r = strstr(t, pat); + return (r + && *(r-1) != '"' + && *(r-1) != '\''); + } void -no_side_effects(char *s) -{ IType *tmp; - char *t; - char *z; - - /* could still defeat this check via hidden - * side effects in function calls, - * but this will catch at least some cases - */ - - tmp = find_inline(s); - t = (char *) tmp->cn; - while (t && *t == ' ') - { t++; - } - - z = strchr(t, '('); - if (z - && z > t - && isalnum((int) *(z-1)) - && strncmp(t, "spin_mutex_free(", strlen("spin_mutex_free(")) != 0) - { goto bad; /* fct call */ - } - - if (side_scan(t, ";") - || side_scan(t, "++") - || side_scan(t, "--")) - { -bad: lineno = tmp->dln; - Fname = tmp->dfn; - non_fatal("c_expr %s has side-effects", s); - return; - } - while ((t = strchr(t, '=')) != NULL) - { if (*(t-1) == '!' - || *(t-1) == '>' - || *(t-1) == '<' - || *(t-1) == '"' - || *(t-1) == '\'') - { t += 2; - continue; - } - t++; - if (*t != '=') - goto bad; - t++; - } -} - -void -pickup_inline(Symbol *t, Lextok *apars, Lextok *rval) -{ IType *tmp; Lextok *p, *q; int j; - - tmp = find_inline(t->name); - - if (++Inlining >= MAXINL) - fatal("inlines nested too deeply", 0); - tmp->cln = lineno; /* remember calling point */ - tmp->cfn = Fname; /* and filename */ - tmp->rval = rval; - - for (p = apars, q = tmp->params, j = 0; p && q; p = p->rgt, q = q->rgt) - j++; /* count them */ - if (p || q) - fatal("wrong nr of params on call of '%s'", t->name); - - tmp->anms = (char **) emalloc(j * sizeof(char *)); - for (p = apars, j = 0; p; p = p->rgt, j++) - { tmp->anms[j] = (char *) emalloc(strlen(IArg_cont[j])+1); - strcpy(tmp->anms[j], IArg_cont[j]); - } - - lineno = tmp->dln; /* linenr of def */ - Fname = tmp->dfn; /* filename of same */ - Inliner[Inlining] = (char *)tmp->cn; - Inline_stub[Inlining] = tmp; -#if 0 - if (verbose&32) - printf("spin: %s:%d, inlining '%s' (from %s:%d)\n", - tmp->cfn->name, tmp->cln, t->name, tmp->dfn->name, tmp->dln); -#endif - for (j = 0; j < Inlining; j++) - { if (Inline_stub[j] == Inline_stub[Inlining]) - { fatal("cyclic inline attempt on: %s", t->name); - } } - last_token = SEMI; /* avoid insertion of extra semi */ -} - -extern int pp_mode; - -static void -do_directive(int first) -{ int c = first; /* handles lines starting with pound */ - - getword(c, isalpha_); - - if (strcmp(yytext, "#ident") == 0) - goto done; - - if ((c = Getchar()) != ' ') - fatal("malformed preprocessor directive - # .", 0); - - if (!isdigit_(c = Getchar())) - fatal("malformed preprocessor directive - # .lineno", 0); - - getword(c, isdigit_); - lineno = atoi(yytext); /* pickup the line number */ - - if ((c = Getchar()) == '\n') - return; /* no filename */ - - if (c != ' ') - fatal("malformed preprocessor directive - .fname", 0); - - if ((c = Getchar()) != '\"') - { printf("got %c, expected \" -- lineno %d\n", c, lineno); - fatal("malformed preprocessor directive - .fname (%s)", yytext); - } - - getword(Getchar(), notquote); /* was getword(c, notquote); */ - if (Getchar() != '\"') - fatal("malformed preprocessor directive - fname.", 0); - - /* strcat(yytext, "\""); */ - Fname = lookup(yytext); -done: - while (Getchar() != '\n') - ; -} - -void -precondition(char *q) -{ int c, nest = 1; - - for (;;) - { c = Getchar(); - *q++ = c; - switch (c) { - case '\n': - lineno++; - break; - case '[': - nest++; - break; - case ']': - if (--nest <= 0) - { *--q = '\0'; - return; - } - break; - } - } - fatal("cannot happen", (char *) 0); /* unreachable */ -} - - -Symbol * -prep_inline(Symbol *s, Lextok *nms) -{ int c, nest = 1, dln, firstchar, cnr; - char *p; - Lextok *t; - static char Buf1[SOMETHINGBIG], Buf2[RATHERSMALL]; - static int c_code = 1; - - for (t = nms; t; t = t->rgt) - if (t->lft) - { if (t->lft->ntyp != NAME) - fatal("bad param to inline %s", s?s->name:"--"); - t->lft->sym->hidden |= 32; - } - - if (!s) /* C_Code fragment */ - { s = (Symbol *) emalloc(sizeof(Symbol)); - s->name = (char *) emalloc(strlen("c_code")+26); - sprintf(s->name, "c_code%d", c_code++); - s->context = context; - s->type = CODE_FRAG; - } else - { s->type = PREDEF; - } - - p = &Buf1[0]; - Buf2[0] = '\0'; - for (;;) - { c = Getchar(); - switch (c) { - case '[': - if (s->type != CODE_FRAG) - goto bad; - precondition(&Buf2[0]); /* e.g., c_code [p] { r = p-r; } */ - continue; - case '{': - break; - case '\n': - lineno++; - /* fall through */ - case ' ': case '\t': case '\f': case '\r': - continue; - default : - printf("spin: saw char '%c'\n", c); -bad: fatal("bad inline: %s", s->name); - } - break; - } - dln = lineno; - if (s->type == CODE_FRAG) - { if (verbose&32) - { sprintf(Buf1, "\t/* line %d %s */\n\t\t", - lineno, Fname->name); - } else - { strcpy(Buf1, ""); - } - } else - { sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name); - } - p += strlen(Buf1); - firstchar = 1; - - cnr = 1; /* not zero */ -more: - c = Getchar(); - *p++ = (char) c; - if (p - Buf1 >= SOMETHINGBIG) - fatal("inline text too long", 0); - switch (c) { - case '\n': - lineno++; - cnr = 0; - break; - case '{': - cnr++; - nest++; - break; - case '}': - cnr++; - if (--nest <= 0) - { *p = '\0'; - if (s->type == CODE_FRAG) - { *--p = '\0'; /* remove trailing '}' */ - } - def_inline(s, dln, &Buf1[0], &Buf2[0], nms); - if (firstchar) - { printf("%3d: %s, warning: empty inline definition (%s)\n", - dln, Fname->name, s->name); - } - return s; /* normal return */ - } - break; - case '#': - if (cnr == 0) - { p--; - do_directive(c); /* reads to newline */ - } else - { firstchar = 0; - cnr++; - } - break; - case '\t': - case ' ': - case '\f': - cnr++; - break; - case '"': - do { - c = Getchar(); - *p++ = (char) c; - if (c == '\\') - { *p++ = (char) Getchar(); - } - if (p - Buf1 >= SOMETHINGBIG) - { fatal("inline text too long", 0); - } - } while (c != '"'); /* end of string */ - /* *p = '\0'; */ - break; - case '\'': - c = Getchar(); - *p++ = (char) c; - if (c == '\\') - { *p++ = (char) Getchar(); - } - c = Getchar(); - *p++ = (char) c; - assert(c == '\''); - break; - default: - firstchar = 0; - cnr++; - break; - } - goto more; -} - -static void -set_cur_scope(void) -{ int i; - char tmpbuf[256]; - - strcpy(CurScope, "_"); - - if (context) - for (i = 0; i < scope_level; i++) - { sprintf(tmpbuf, "%d_", scope_seq[i]); - strcat(CurScope, tmpbuf); - } -} - -static int -pre_proc(void) -{ char b[512]; - int c, i = 0; - - b[i++] = '#'; - while ((c = Getchar()) != '\n' && c != EOF) - { b[i++] = (char) c; - } - b[i] = '\0'; - yylval = nn(ZN, 0, ZN, ZN); - yylval->sym = lookup(b); - return PREPROC; -} - -static int specials[] = { - '}', ')', ']', - OD, FI, ELSE, BREAK, - C_CODE, C_EXPR, C_DECL, - NAME, CONST, INCR, DECR, 0 -}; - -int -follows_token(int c) -{ int i; - - for (i = 0; specials[i]; i++) - { if (c == specials[i]) - { return 1; - } } - return 0; -} -#define DEFER_LTL -#ifdef DEFER_LTL -/* defer ltl formula to the end of the spec - * no matter where they appear in the original - */ - -static int deferred = 0; -static FILE *defer_fd; - -int -get_deferred(void) -{ - if (!defer_fd) - { return 0; /* nothing was deferred */ - } - fclose(defer_fd); - - defer_fd = fopen(TMP_FILE2, "r"); - if (!defer_fd) - { non_fatal("cannot retrieve deferred ltl formula", (char *) 0); - return 0; - } - fclose(yyin); - yyin = defer_fd; - return 1; -} - -void -zap_deferred(void) -{ - (void) unlink(TMP_FILE2); -} - -int -put_deferred(void) -{ int c, cnt; - if (!defer_fd) - { defer_fd = fopen(TMP_FILE2, "w+"); - if (!defer_fd) - { non_fatal("cannot defer ltl expansion", (char *) 0); - return 0; - } } - fprintf(defer_fd, "ltl "); - cnt = 0; - while ((c = getc(yyin)) != EOF) - { if (c == '{') - { cnt++; - } - if (c == '}') - { cnt--; - if (cnt == 0) - { break; - } } - fprintf(defer_fd, "%c", c); - } - fprintf(defer_fd, "}\n"); - fflush(defer_fd); - return 1; -} -#endif - -#define EXPAND_SELECT -#ifdef EXPAND_SELECT -static char tmp_hold[256]; -static int tmp_has; - -void -new_select(void) -{ tmp_hold[0] = '\0'; - tmp_has = 0; -} - -static int -scan_to(int stop, int (*tst)(int), char *buf, int bufsz) -{ int c, i = 0; - - do { c = Getchar(); - if (tmp_has < sizeof(tmp_hold)) - { tmp_hold[tmp_has++] = c; - } - if (c == '\n') - { lineno++; - } else if (buf && i < bufsz-1) - { buf[i++] = c; - } else if (buf && i >= bufsz-1) - { buf[bufsz-1] = '\0'; - fatal("name too long", buf); - } - if (tst && !tst(c) && c != ' ' && c != '\t') - { break; - } - } while (c != stop && c != EOF); - - if (buf) - { if (i <= 0) - { fatal("input error", (char *) 0); - } - buf[i-1] = '\0'; - } - - if (c != stop) - { if (0) - { printf("saw: '%c', expected '%c'\n", c, stop); - } - if (tmp_has < sizeof(tmp_hold)) - { tmp_hold[tmp_has] = '\0'; - push_back(tmp_hold); - if (0) - { printf("pushed back: <'%s'>\n", tmp_hold); - } - return 0; /* internal expansion fails */ - } else - { fatal("expecting select ( name : constant .. constant )", 0); - } } - return 1; /* success */ -} -#endif - -int -lex(void) -{ int c; -again: - c = Getchar(); -/* more: */ - yytext[0] = (char) c; - yytext[1] = '\0'; - switch (c) { - case EOF: -#ifdef DEFER_LTL - if (!deferred) - { deferred = 1; - if (get_deferred()) - { goto again; - } - } else - { zap_deferred(); - } -#endif - return c; - case '\n': /* newline */ - lineno++; - /* make most semi-colons optional */ - if (implied_semis - /* && context */ - && in_seq - && par_cnt == 0 - && follows_token(last_token)) - { if (last_token == '}') - { do { c = Getchar(); - if (c == '\n') - { lineno++; - } - } while (c == ' ' || c == '\t' || - c == '\f' || c == '\n' || - c == '\r'); - Ungetch(c); - if (0) printf("%d: saw %d\n", lineno, c); - if (c == 'u') /* first letter of UNLESS */ - { goto again; - } } - if (0) - { printf("insert ; line %d, last_token %d in_seq %d\n", - lineno-1, last_token, in_seq); - } - ValToken(1, SEMI); - } - /* else fall thru */ - case '\r': /* carriage return */ - goto again; - - case ' ': case '\t': case '\f': /* white space */ - goto again; - - case '#': /* preprocessor directive */ - if (in_comment) goto again; - if (pp_mode) - { last_token = PREPROC; - return pre_proc(); - } - do_directive(c); - goto again; - - case '\"': - getword(c, notquote); - if (Getchar() != '\"') - fatal("string not terminated", yytext); - strcat(yytext, "\""); - SymToken(lookup(yytext), STRING) - - case '$': - getword('\"', notdollar); - if (Getchar() != '$') - fatal("ltl definition not terminated", yytext); - strcat(yytext, "\""); - SymToken(lookup(yytext), STRING) - - case '\'': /* new 3.0.9 */ - c = Getchar(); - if (c == '\\') - { c = Getchar(); - if (c == 'n') c = '\n'; - else if (c == 'r') c = '\r'; - else if (c == 't') c = '\t'; - else if (c == 'f') c = '\f'; - } - if (Getchar() != '\'' && !in_comment) - fatal("character quote missing: %s", yytext); - ValToken(c, CONST) - - default: - break; - } - - if (isdigit_(c)) - { long int nr; - getword(c, isdigit_); - errno = 0; - nr = strtol(yytext, NULL, 10); - if (errno != 0) - { fprintf(stderr, "spin: value out of range: '%s' read as '%d'\n", - yytext, (int) nr); - } - ValToken((int)nr, CONST) - } - - if (isalpha_(c) || c == '_') - { getword(c, isalnum_); - if (!in_comment) - { c = check_name(yytext); - -/* replace timeout with (timeout) */ - if (c == TIMEOUT - && Inlining < 0 - && last_token != '(') - { push_back("timeout)"); - last_token = '('; - return '('; - } -/* end */ - -#ifdef EXPAND_SELECT - if (c == SELECT && Inlining < 0) - { char name[64], from[32], upto[32]; - int i, a, b; - new_select(); - if (!scan_to('(', 0, 0, 0) - || !scan_to(':', isalnum, name, sizeof(name)) - || !scan_to('.', isdigit, from, sizeof(from)) - || !scan_to('.', 0, 0, 0) - || !scan_to(')', isdigit, upto, sizeof(upto))) - { goto not_expanded; - } - a = atoi(from); - b = atoi(upto); - if (0) - { printf("Select %s from %d to %d\n", - name, a, b); - } - if (a > b) - { non_fatal("bad range in select statement", 0); - goto again; - } - if (b - a <= 32) - { push_back("if "); - for (i = a; i <= b; i++) - { char buf[256]; - push_back(":: "); - sprintf(buf, "%s = %d ", - name, i); - push_back(buf); - } - push_back("fi "); - } else - { char buf[256]; - sprintf(buf, "%s = %d; do ", - name, a); - push_back(buf); - sprintf(buf, ":: (%s < %d) -> %s++ ", - name, b, name); - push_back(buf); - push_back(":: break od; "); - } - goto again; - } -not_expanded: -#endif - -#ifdef DEFER_LTL - if (c == LTL && !deferred) - { if (put_deferred()) - { goto again; - } } -#endif - if (c) - { last_token = c; - return c; - } - /* else fall through */ - } - goto again; - } - - if (ltl_mode) - { switch (c) { - case '-': c = follow('>', IMPLIES, '-'); break; - case '[': c = follow(']', ALWAYS, '['); break; - case '/': c = follow('\\', AND, '/'); break; - case '\\': c = follow('/', OR, '\\'); break; - case '<': c = follow('>', EVENTUALLY, '<'); - if (c == '<') - { c = Getchar(); - if (c == '-') - { c = follow('>', EQUIV, '-'); - if (c == '-') - { Ungetch(c); - c = '<'; - } - } else - { Ungetch(c); - c = '<'; - } } - default: break; - } } - - switch (c) { - case '/': c = follow('*', 0, '/'); - if (!c) { in_comment = 1; goto again; } - break; - case '*': c = follow('/', 0, '*'); - if (!c) { in_comment = 0; goto again; } - break; - case ':': c = follow(':', SEP, ':'); break; - case '-': c = follow('>', ARROW, follow('-', DECR, '-')); break; - case '+': c = follow('+', INCR, '+'); break; - case '<': c = follow('<', LSHIFT, follow('=', LE, LT)); break; - case '>': c = follow('>', RSHIFT, follow('=', GE, GT)); break; - case '=': c = follow('=', EQ, ASGN); break; - case '!': c = follow('=', NE, follow('!', O_SND, SND)); break; - case '?': c = follow('?', R_RCV, RCV); break; - case '&': c = follow('&', AND, '&'); break; - case '|': c = follow('|', OR, '|'); break; - case ';': c = SEMI; break; - case '.': c = follow('.', DOTDOT, '.'); break; - case '{': - assert(scope_level < sizeof(scope_seq)-1); - scope_seq[scope_level++]++; - set_cur_scope(); - break; - case '}': - assert(scope_level > 0); - scope_level--; - set_cur_scope(); - break; - default : break; - } - ValToken(0, c) -} - -static struct { - char *s; int tok; -} LTL_syms[] = { - /* [], <>, ->, and <-> are intercepted in lex() */ - { "U", UNTIL }, - { "V", RELEASE }, - { "W", WEAK_UNTIL }, - { "X", NEXT }, - { "always", ALWAYS }, - { "eventually", EVENTUALLY }, - { "until", UNTIL }, - { "stronguntil",UNTIL }, - { "weakuntil", WEAK_UNTIL }, - { "release", RELEASE }, - { "next", NEXT }, - { "implies", IMPLIES }, - { "equivalent", EQUIV }, - { 0, 0 }, -}; - -static struct { - char *s; int tok; int val; char *sym; -} Names[] = { - {"active", ACTIVE, 0, 0}, - {"assert", ASSERT, 0, 0}, - {"atomic", ATOMIC, 0, 0}, - {"bit", TYPE, BIT, 0}, - {"bool", TYPE, BIT, 0}, - {"break", BREAK, 0, 0}, - {"byte", TYPE, BYTE, 0}, - {"c_code", C_CODE, 0, 0}, - {"c_decl", C_DECL, 0, 0}, - {"c_expr", C_EXPR, 0, 0}, - {"c_state", C_STATE, 0, 0}, - {"c_track", C_TRACK, 0, 0}, - {"D_proctype", D_PROCTYPE, 0, 0}, - {"do", DO, 0, 0}, - {"chan", TYPE, CHAN, 0}, - {"else", ELSE, 0, 0}, - {"empty", EMPTY, 0, 0}, - {"enabled", ENABLED, 0, 0}, - {"eval", EVAL, 0, 0}, - {"false", CONST, 0, 0}, - {"fi", FI, 0, 0}, - {"for", FOR, 0, 0}, - {"full", FULL, 0, 0}, - {"get_priority", GET_P, 0, 0}, - {"goto", GOTO, 0, 0}, - {"hidden", HIDDEN, 0, ":hide:"}, - {"if", IF, 0, 0}, - {"in", IN, 0, 0}, - {"init", INIT, 0, ":init:"}, - {"inline", INLINE, 0, 0}, - {"int", TYPE, INT, 0}, - {"len", LEN, 0, 0}, - {"local", ISLOCAL, 0, ":local:"}, - {"ltl", LTL, 0, ":ltl:"}, - {"mtype", TYPE, MTYPE, 0}, - {"nempty", NEMPTY, 0, 0}, - {"never", CLAIM, 0, ":never:"}, - {"nfull", NFULL, 0, 0}, - {"notrace", TRACE, 0, ":notrace:"}, - {"np_", NONPROGRESS, 0, 0}, - {"od", OD, 0, 0}, - {"of", OF, 0, 0}, - {"pc_value", PC_VAL, 0, 0}, - {"pid", TYPE, BYTE, 0}, - {"printf", PRINT, 0, 0}, - {"printm", PRINTM, 0, 0}, - {"priority", PRIORITY, 0, 0}, - {"proctype", PROCTYPE, 0, 0}, - {"provided", PROVIDED, 0, 0}, - {"return", RETURN, 0, 0}, - {"run", RUN, 0, 0}, - {"d_step", D_STEP, 0, 0}, - {"select", SELECT, 0, 0}, - {"set_priority", SET_P, 0, 0}, - {"short", TYPE, SHORT, 0}, - {"skip", CONST, 1, 0}, - {"timeout", TIMEOUT, 0, 0}, - {"trace", TRACE, 0, ":trace:"}, - {"true", CONST, 1, 0}, - {"show", SHOW, 0, ":show:"}, - {"typedef", TYPEDEF, 0, 0}, - {"unless", UNLESS, 0, 0}, - {"unsigned", TYPE, UNSIGNED, 0}, - {"xr", XU, XR, 0}, - {"xs", XU, XS, 0}, - {0, 0, 0, 0}, -}; - -static int -check_name(char *s) -{ int i; - - yylval = nn(ZN, 0, ZN, ZN); - - if (ltl_mode) - { for (i = 0; LTL_syms[i].s; i++) - { if (strcmp(s, LTL_syms[i].s) == 0) - { return LTL_syms[i].tok; - } } } - - for (i = 0; Names[i].s; i++) - { if (strcmp(s, Names[i].s) == 0) - { yylval->val = Names[i].val; - if (Names[i].sym) - yylval->sym = lookup(Names[i].sym); - if (Names[i].tok == IN && !in_for) - { continue; - } - return Names[i].tok; - } } - - if ((yylval->val = ismtype(s)) != 0) - { yylval->ismtyp = 1; - yylval->sym = (Symbol *) emalloc(sizeof(Symbol)); - yylval->sym->name = (char *) emalloc(strlen(s)+1); - strcpy(yylval->sym->name, s); - return CONST; - } - - if (strcmp(s, "_last") == 0) - has_last++; - - if (strcmp(s, "_priority") == 0) - has_priority++; - - if (Inlining >= 0 && !ReDiRect) - { Lextok *tt, *t = Inline_stub[Inlining]->params; - - for (i = 0; t; t = t->rgt, i++) /* formal pars */ - if (!strcmp(s, t->lft->sym->name) /* varname matches formal */ - && strcmp(s, Inline_stub[Inlining]->anms[i]) != 0) /* actual pars */ - { -#if 0 - if (verbose&32) - printf("\tline %d, replace %s in call of '%s' with %s\n", - lineno, s, - Inline_stub[Inlining]->nm->name, - Inline_stub[Inlining]->anms[i]); -#endif - for (tt = Inline_stub[Inlining]->params; tt; tt = tt->rgt) - if (!strcmp(Inline_stub[Inlining]->anms[i], - tt->lft->sym->name)) - { /* would be cyclic if not caught */ - printf("spin: %s:%d replacement value: %s\n", - oFname->name?oFname->name:"--", lineno, tt->lft->sym->name); - fatal("formal par of %s contains replacement value", - Inline_stub[Inlining]->nm->name); - yylval->ntyp = tt->lft->ntyp; - yylval->sym = lookup(tt->lft->sym->name); - return NAME; - } - - /* check for occurrence of param as field of struct */ - { char *ptr = Inline_stub[Inlining]->anms[i]; - char *optr = ptr; - while ((ptr = strstr(ptr, s)) != NULL) - { if ((ptr > optr && *(ptr-1) == '.') - || *(ptr+strlen(s)) == '.') - { fatal("formal par of %s used in structure name", - Inline_stub[Inlining]->nm->name); - } - ptr++; - } } - ReDiRect = Inline_stub[Inlining]->anms[i]; - return 0; - } } - - yylval->sym = lookup(s); /* symbol table */ - if (isutype(s)) - return UNAME; - if (isproctype(s)) - return PNAME; - if (iseqname(s)) - return INAME; - - return NAME; +no_side_effects(const char *s) + { IType *tmp; + char *t; + char *z; + + /* could still defeat this check via hidden + * side effects in function calls, + * but this will catch at least some cases + */ + + tmp = find_inline(s); + t = (char *) tmp->cn; + while (t && *t == ' ') + { t++; + } + + z = strchr(t, '('); + if (z + && z > t + && isalnum((int) *(z-1)) + && strncmp(t, "spin_mutex_free(", strlen("spin_mutex_free(")) != 0) + { goto bad; /* fct call */ + } + + if (side_scan(t, ";") + || side_scan(t, "++") + || side_scan(t, "--")) + { + bad: lineno = tmp->dln; + Fname = tmp->dfn; + non_fatal("c_expr %s has side-effects", s); + return; + } + while ((t = strchr(t, '=')) != NULL) + { if (*(t-1) == '!' + || *(t-1) == '>' + || *(t-1) == '<' + || *(t-1) == '"' + || *(t-1) == '\'') + { t += 2; + continue; + } + t++; + if (*t != '=') + goto bad; + t++; + } + } + + void + pickup_inline(Symbol *t, Lextok *apars, Lextok *rval) + { IType *tmp; Lextok *p, *q; int j; + + tmp = find_inline(t->name); + + if (++Inlining >= MAXINL) + fatal("inlines nested too deeply", 0); + tmp->cln = lineno; /* remember calling point */ + tmp->cfn = Fname; /* and filename */ + tmp->rval = rval; + + for (p = apars, q = tmp->params, j = 0; p && q; p = p->rgt, q = q->rgt) + j++; /* count them */ + if (p || q) + fatal("wrong nr of params on call of '%s'", t->name); + + tmp->anms = (char **) emalloc(j * sizeof(char *)); + for (p = apars, j = 0; p; p = p->rgt, j++) + { tmp->anms[j] = (char *) emalloc(strlen(IArg_cont[j])+1); + strcpy(tmp->anms[j], IArg_cont[j]); + } + + lineno = tmp->dln; /* linenr of def */ + Fname = tmp->dfn; /* filename of same */ + Inliner[Inlining] = (char *)tmp->cn; + Inline_stub[Inlining] = tmp; + #if 0 + if (verbose&32) + printf("spin: %s:%d, inlining '%s' (from %s:%d)\n", + tmp->cfn->name, tmp->cln, t->name, tmp->dfn->name, tmp->dln); + #endif + for (j = 0; j < Inlining; j++) + { if (Inline_stub[j] == Inline_stub[Inlining]) + { fatal("cyclic inline attempt on: %s", t->name); + } } + last_token = SEMI; /* avoid insertion of extra semi */ + } + + extern int pp_mode; + + static void + do_directive(int first) + { int c = first; /* handles lines starting with pound */ + + getword(c, isalpha_); + + if (strcmp(yytext, "#ident") == 0) + goto done; + + if ((c = Getchar()) != ' ') + fatal("malformed preprocessor directive - # .", 0); + + if (!isdigit_(c = Getchar())) + fatal("malformed preprocessor directive - # .lineno", 0); + + getword(c, isdigit_); + lineno = atoi(yytext); /* pickup the line number */ + + if ((c = Getchar()) == '\n') + return; /* no filename */ + + if (c != ' ') + fatal("malformed preprocessor directive - .fname", 0); + + if ((c = Getchar()) != '\"') + { printf("got %c, expected \" -- lineno %d\n", c, lineno); + fatal("malformed preprocessor directive - .fname (%s)", yytext); + } + + getword(Getchar(), notquote); /* was getword(c, notquote); */ + if (Getchar() != '\"') + fatal("malformed preprocessor directive - fname.", 0); + + /* strcat(yytext, "\""); */ + Fname = lookup(yytext); + done: + while (Getchar() != '\n') + ; + } + + void + precondition(char *q) + { int c, nest = 1; + + for (;;) + { c = Getchar(); + *q++ = c; + switch (c) { + case '\n': + lineno++; + break; + case '[': + nest++; + break; + case ']': + if (--nest <= 0) + { *--q = '\0'; + return; + } + break; + } + } + fatal("cannot happen", (char *) 0); /* unreachable */ + } + + + Symbol * + prep_inline(Symbol *s, Lextok *nms) + { int c, nest = 1, dln, firstchar, cnr; + char *p; + Lextok *t; + static char Buf1[SOMETHINGBIG], Buf2[RATHERSMALL]; + static int c_code = 1; + + for (t = nms; t; t = t->rgt) + if (t->lft) + { if (t->lft->ntyp != NAME) + fatal("bad param to inline %s", s?s->name:"--"); + t->lft->sym->hidden |= 32; + } + + if (!s) /* C_Code fragment */ + { s = (Symbol *) emalloc(sizeof(Symbol)); + s->name = (char *) emalloc(strlen("c_code")+26); + sprintf(s->name, "c_code%d", c_code++); + s->context = context; + s->type = CODE_FRAG; + } else + { s->type = PREDEF; + } + + p = &Buf1[0]; + Buf2[0] = '\0'; + for (;;) + { c = Getchar(); + switch (c) { + case '[': + if (s->type != CODE_FRAG) + goto bad; + precondition(&Buf2[0]); /* e.g., c_code [p] { r = p-r; } */ + continue; + case '{': + break; + case '\n': + lineno++; + /* fall through */ + case ' ': case '\t': case '\f': case '\r': + continue; + default : + printf("spin: saw char '%c'\n", c); + bad: fatal("bad inline: %s", s->name); + } + break; + } + dln = lineno; + if (s->type == CODE_FRAG) + { if (verbose&32) + { sprintf(Buf1, "\t/* line %d %s */\n\t\t", + lineno, Fname->name); + } else + { strcpy(Buf1, ""); + } + } else + { sprintf(Buf1, "\n#line %d \"%s\"\n{", lineno, Fname->name); + } + p += strlen(Buf1); + firstchar = 1; + + cnr = 1; /* not zero */ + more: + c = Getchar(); + *p++ = (char) c; + if (p - Buf1 >= SOMETHINGBIG) + fatal("inline text too long", 0); + switch (c) { + case '\n': + lineno++; + cnr = 0; + break; + case '{': + cnr++; + nest++; + break; + case '}': + cnr++; + if (--nest <= 0) + { *p = '\0'; + if (s->type == CODE_FRAG) + { *--p = '\0'; /* remove trailing '}' */ + } + def_inline(s, dln, &Buf1[0], &Buf2[0], nms); + if (firstchar) + { printf("%3d: %s, warning: empty inline definition (%s)\n", + dln, Fname->name, s->name); + } + return s; /* normal return */ + } + break; + case '#': + if (cnr == 0) + { p--; + do_directive(c); /* reads to newline */ + } else + { firstchar = 0; + cnr++; + } + break; + case '\t': + case ' ': + case '\f': + cnr++; + break; + case '"': + do { + c = Getchar(); + *p++ = (char) c; + if (c == '\\') + { *p++ = (char) Getchar(); + } + if (p - Buf1 >= SOMETHINGBIG) + { fatal("inline text too long", 0); + } + } while (c != '"'); /* end of string */ + /* *p = '\0'; */ + break; + case '\'': + c = Getchar(); + *p++ = (char) c; + if (c == '\\') + { *p++ = (char) Getchar(); + } + c = Getchar(); + *p++ = (char) c; + assert(c == '\''); + break; + default: + firstchar = 0; + cnr++; + break; + } + goto more; + } + + static void + set_cur_scope(void) + { int i; + char tmpbuf[256]; + + strcpy(CurScope, "_"); + + if (context) + for (i = 0; i < scope_level; i++) + { sprintf(tmpbuf, "%d_", scope_seq[i]); + strcat(CurScope, tmpbuf); + } + } + + static int + pre_proc(void) + { char b[512]; + int c, i = 0; + + b[i++] = '#'; + while ((c = Getchar()) != '\n' && c != EOF) + { b[i++] = (char) c; + } + b[i] = '\0'; + yylval = nn(ZN, 0, ZN, ZN); + yylval->sym = lookup(b); + return PREPROC; + } + + static int specials[] = { + '}', ')', ']', + OD, FI, ELSE, BREAK, + C_CODE, C_EXPR, C_DECL, + NAME, CONST, INCR, DECR, 0 + }; + + int + follows_token(int c) + { int i; + + for (i = 0; specials[i]; i++) + { if (c == specials[i]) + { return 1; + } } + return 0; + } + #define DEFER_LTL + #ifdef DEFER_LTL + /* defer ltl formula to the end of the spec + * no matter where they appear in the original + */ + + static int deferred = 0; + static FILE *defer_fd; + + int + get_deferred(void) + { + if (!defer_fd) + { return 0; /* nothing was deferred */ + } + fclose(defer_fd); + + defer_fd = fopen(TMP_FILE2, "r"); + if (!defer_fd) + { non_fatal("cannot retrieve deferred ltl formula", (char *) 0); + return 0; + } + fclose(yyin); + yyin = defer_fd; + return 1; + } + + void + zap_deferred(void) + { + (void) unlink(TMP_FILE2); + } + + int + put_deferred(void) + { int c, cnt; + if (!defer_fd) + { defer_fd = fopen(TMP_FILE2, "w+"); + if (!defer_fd) + { non_fatal("cannot defer ltl expansion", (char *) 0); + return 0; + } } + fprintf(defer_fd, "ltl "); + cnt = 0; + while ((c = getc(yyin)) != EOF) + { if (c == '{') + { cnt++; + } + if (c == '}') + { cnt--; + if (cnt == 0) + { break; + } } + fprintf(defer_fd, "%c", c); + } + fprintf(defer_fd, "}\n"); + fflush(defer_fd); + return 1; + } + #endif + + #define EXPAND_SELECT + #ifdef EXPAND_SELECT + static char tmp_hold[256]; + static int tmp_has; + + void + new_select(void) + { tmp_hold[0] = '\0'; + tmp_has = 0; + } + + static int + scan_to(int stop, int (*tst)(int), char *buf, int bufsz) + { int c, i = 0; + + do { c = Getchar(); + if (tmp_has < (int)sizeof(tmp_hold)) + { tmp_hold[tmp_has++] = c; + } + if (c == '\n') + { lineno++; + } else if (buf && i < bufsz-1) + { buf[i++] = c; + } else if (buf && i >= bufsz-1) + { buf[bufsz-1] = '\0'; + fatal("name too long", buf); + } + if (tst && !tst(c) && c != ' ' && c != '\t') + { break; + } + } while (c != stop && c != EOF); + + if (buf) + { if (i <= 0) + { fatal("input error", (char *) 0); + } + buf[i-1] = '\0'; + } + + if (c != stop) + { if (0) + { printf("saw: '%c', expected '%c'\n", c, stop); + } + if (tmp_has < (int)sizeof(tmp_hold)) + { tmp_hold[tmp_has] = '\0'; + push_back(tmp_hold); + if (0) + { printf("pushed back: <'%s'>\n", tmp_hold); + } + return 0; /* internal expansion fails */ + } else + { fatal("expecting select ( name : constant .. constant )", 0); + } } + return 1; /* success */ + } + #endif + + int + lex(void) + { int c; + again: + c = Getchar(); + /* more: */ + yytext[0] = (char) c; + yytext[1] = '\0'; + switch (c) { + case EOF: + #ifdef DEFER_LTL + if (!deferred) + { deferred = 1; + if (get_deferred()) + { goto again; + } + } else + { zap_deferred(); + } + #endif + return c; + case '\n': /* newline */ + lineno++; + /* make most semi-colons optional */ + if (implied_semis + /* && context */ + && in_seq + && par_cnt == 0 + && follows_token(last_token)) + { if (last_token == '}') + { do { c = Getchar(); + if (c == '\n') + { lineno++; + } + } while (c == ' ' || c == '\t' || + c == '\f' || c == '\n' || + c == '\r'); + Ungetch(c); + if (0) printf("%d: saw %d\n", lineno, c); + if (c == 'u') /* first letter of UNLESS */ + { goto again; + } } + if (0) + { printf("insert ; line %d, last_token %d in_seq %d\n", + lineno-1, last_token, in_seq); + } + ValToken(1, SEMI); + } + /* else fall thru */ + case '\r': /* carriage return */ + goto again; + + case ' ': case '\t': case '\f': /* white space */ + goto again; + + case '#': /* preprocessor directive */ + if (in_comment) goto again; + if (pp_mode) + { last_token = PREPROC; + return pre_proc(); + } + do_directive(c); + goto again; + + case '\"': + getword(c, notquote); + if (Getchar() != '\"') + fatal("string not terminated", yytext); + strcat(yytext, "\""); + SymToken(lookup(yytext), STRING) + + case '$': + getword('\"', notdollar); + if (Getchar() != '$') + fatal("ltl definition not terminated", yytext); + strcat(yytext, "\""); + SymToken(lookup(yytext), STRING) + + case '\'': /* new 3.0.9 */ + c = Getchar(); + if (c == '\\') + { c = Getchar(); + if (c == 'n') c = '\n'; + else if (c == 'r') c = '\r'; + else if (c == 't') c = '\t'; + else if (c == 'f') c = '\f'; + } + if (Getchar() != '\'' && !in_comment) + fatal("character quote missing: %s", yytext); + ValToken(c, CONST) + + default: + break; + } + + if (isdigit_(c)) + { long int nr; + getword(c, isdigit_); + errno = 0; + nr = strtol(yytext, NULL, 10); + if (errno != 0) + { fprintf(stderr, "spin: value out of range: '%s' read as '%d'\n", + yytext, (int) nr); + } + ValToken((int)nr, CONST) + } + + if (isalpha_(c) || c == '_') + { getword(c, isalnum_); + if (!in_comment) + { c = check_name(yytext); + + /* replace timeout with (timeout) */ + if (c == TIMEOUT + && Inlining < 0 + && last_token != '(') + { push_back("timeout)"); + last_token = '('; + return '('; + } + /* end */ + + #ifdef EXPAND_SELECT + if (c == SELECT && Inlining < 0) + { char name[64], from[32], upto[32]; + int i, a, b; + new_select(); + if (!scan_to('(', 0, 0, 0) + || !scan_to(':', isalnum, name, sizeof(name)) + || !scan_to('.', isdigit, from, sizeof(from)) + || !scan_to('.', 0, 0, 0) + || !scan_to(')', isdigit, upto, sizeof(upto))) + { goto not_expanded; + } + a = atoi(from); + b = atoi(upto); + if (0) + { printf("Select %s from %d to %d\n", + name, a, b); + } + if (a > b) + { non_fatal("bad range in select statement", 0); + goto again; + } + if (b - a <= 32) + { push_back("if "); + for (i = a; i <= b; i++) + { char buf[256]; + push_back(":: "); + sprintf(buf, "%s = %d ", + name, i); + push_back(buf); + } + push_back("fi "); + } else + { char buf[256]; + sprintf(buf, "%s = %d; do ", + name, a); + push_back(buf); + sprintf(buf, ":: (%s < %d) -> %s++ ", + name, b, name); + push_back(buf); + push_back(":: break od; "); + } + goto again; + } + not_expanded: + #endif + + #ifdef DEFER_LTL + if (c == LTL && !deferred) + { if (put_deferred()) + { goto again; + } } + #endif + if (c) + { last_token = c; + return c; + } + /* else fall through */ + } + goto again; + } + + if (ltl_mode) + { switch (c) { + case '-': c = follow('>', IMPLIES, '-'); break; + case '[': c = follow(']', ALWAYS, '['); break; + case '/': c = follow('\\', AND, '/'); break; + case '\\': c = follow('/', OR, '\\'); break; + case '<': c = follow('>', EVENTUALLY, '<'); + if (c == '<') + { c = Getchar(); + if (c == '-') + { c = follow('>', EQUIV, '-'); + if (c == '-') + { Ungetch(c); + c = '<'; + } + } else + { Ungetch(c); + c = '<'; + } } + default: break; + } } + + switch (c) { + case '/': c = follow('*', 0, '/'); + if (!c) { in_comment = 1; goto again; } + break; + case '*': c = follow('/', 0, '*'); + if (!c) { in_comment = 0; goto again; } + break; + case ':': c = follow(':', SEP, ':'); break; + case '-': c = follow('>', ARROW, follow('-', DECR, '-')); break; + case '+': c = follow('+', INCR, '+'); break; + case '<': c = follow('<', LSHIFT, follow('=', LE, LT)); break; + case '>': c = follow('>', RSHIFT, follow('=', GE, GT)); break; + case '=': c = follow('=', EQ, ASGN); break; + case '!': c = follow('=', NE, follow('!', O_SND, SND)); break; + case '?': c = follow('?', R_RCV, RCV); break; + case '&': c = follow('&', AND, '&'); break; + case '|': c = follow('|', OR, '|'); break; + case ';': c = SEMI; break; + case '.': c = follow('.', DOTDOT, '.'); break; + case '{': + assert(scope_level < (int)sizeof(scope_seq)-1); + scope_seq[scope_level++]++; + set_cur_scope(); + break; + case '}': + assert(scope_level > 0); + scope_level--; + set_cur_scope(); + break; + default : break; + } + ValToken(0, c) + } + + static struct { + const char *s; int tok; + } LTL_syms[] = { + /* [], <>, ->, and <-> are intercepted in lex() */ + { "U", UNTIL }, + { "V", RELEASE }, + { "W", WEAK_UNTIL }, + { "X", NEXT }, + { "always", ALWAYS }, + { "eventually", EVENTUALLY }, + { "until", UNTIL }, + { "stronguntil",UNTIL }, + { "weakuntil", WEAK_UNTIL }, + { "release", RELEASE }, + { "next", NEXT }, + { "implies", IMPLIES }, + { "equivalent", EQUIV }, + { 0, 0 }, + }; + + static struct { + const char *s; int tok; int val; const char *sym; + } Names[] = { + {"active", ACTIVE, 0, 0}, + {"assert", ASSERT, 0, 0}, + {"atomic", ATOMIC, 0, 0}, + {"bit", TYPE, BIT, 0}, + {"bool", TYPE, BIT, 0}, + {"break", BREAK, 0, 0}, + {"byte", TYPE, BYTE, 0}, + {"c_code", C_CODE, 0, 0}, + {"c_decl", C_DECL, 0, 0}, + {"c_expr", C_EXPR, 0, 0}, + {"c_state", C_STATE, 0, 0}, + {"c_track", C_TRACK, 0, 0}, + {"D_proctype", D_PROCTYPE, 0, 0}, + {"do", DO, 0, 0}, + {"chan", TYPE, CHAN, 0}, + {"else", ELSE, 0, 0}, + {"empty", EMPTY, 0, 0}, + {"enabled", ENABLED, 0, 0}, + {"eval", EVAL, 0, 0}, + {"false", CONST, 0, 0}, + {"fi", FI, 0, 0}, + {"for", FOR, 0, 0}, + {"full", FULL, 0, 0}, + {"get_priority", GET_P, 0, 0}, + {"goto", GOTO, 0, 0}, + {"hidden", HIDDEN, 0, ":hide:"}, + {"if", IF, 0, 0}, + {"in", IN, 0, 0}, + {"init", INIT, 0, ":init:"}, + {"inline", INLINE, 0, 0}, + {"int", TYPE, INT, 0}, + {"len", LEN, 0, 0}, + {"local", ISLOCAL, 0, ":local:"}, + {"ltl", LTL, 0, ":ltl:"}, + {"mtype", TYPE, MTYPE, 0}, + {"nempty", NEMPTY, 0, 0}, + {"never", CLAIM, 0, ":never:"}, + {"nfull", NFULL, 0, 0}, + {"notrace", TRACE, 0, ":notrace:"}, + {"np_", NONPROGRESS, 0, 0}, + {"od", OD, 0, 0}, + {"of", OF, 0, 0}, + {"pc_value", PC_VAL, 0, 0}, + {"pid", TYPE, BYTE, 0}, + {"printf", PRINT, 0, 0}, + {"printm", PRINTM, 0, 0}, + {"priority", PRIORITY, 0, 0}, + {"proctype", PROCTYPE, 0, 0}, + {"provided", PROVIDED, 0, 0}, + {"return", RETURN, 0, 0}, + {"run", RUN, 0, 0}, + {"d_step", D_STEP, 0, 0}, + {"select", SELECT, 0, 0}, + {"set_priority", SET_P, 0, 0}, + {"short", TYPE, SHORT, 0}, + {"skip", CONST, 1, 0}, + {"timeout", TIMEOUT, 0, 0}, + {"trace", TRACE, 0, ":trace:"}, + {"true", CONST, 1, 0}, + {"show", SHOW, 0, ":show:"}, + {"typedef", TYPEDEF, 0, 0}, + {"unless", UNLESS, 0, 0}, + {"unsigned", TYPE, UNSIGNED, 0}, + {"xr", XU, XR, 0}, + {"xs", XU, XS, 0}, + {0, 0, 0, 0}, + }; + + static int + check_name(char *s) + { int i; + + yylval = nn(ZN, 0, ZN, ZN); + + if (ltl_mode) + { for (i = 0; LTL_syms[i].s; i++) + { if (strcmp(s, LTL_syms[i].s) == 0) + { return LTL_syms[i].tok; + } } } + + for (i = 0; Names[i].s; i++) + { if (strcmp(s, Names[i].s) == 0) + { yylval->val = Names[i].val; + if (Names[i].sym) + yylval->sym = lookup(Names[i].sym); + if (Names[i].tok == IN && !in_for) + { continue; + } + return Names[i].tok; + } } + + if ((yylval->val = ismtype(s)) != 0) + { yylval->ismtyp = 1; + yylval->sym = (Symbol *) emalloc(sizeof(Symbol)); + yylval->sym->name = (char *) emalloc(strlen(s)+1); + strcpy(yylval->sym->name, s); + return CONST; + } + + if (strcmp(s, "_last") == 0) + has_last++; + + if (strcmp(s, "_priority") == 0) + has_priority++; + + if (Inlining >= 0 && !ReDiRect) + { Lextok *tt, *t = Inline_stub[Inlining]->params; + + for (i = 0; t; t = t->rgt, i++) /* formal pars */ + if (!strcmp(s, t->lft->sym->name) /* varname matches formal */ + && strcmp(s, Inline_stub[Inlining]->anms[i]) != 0) /* actual pars */ + { + #if 0 + if (verbose&32) + printf("\tline %d, replace %s in call of '%s' with %s\n", + lineno, s, + Inline_stub[Inlining]->nm->name, + Inline_stub[Inlining]->anms[i]); + #endif + for (tt = Inline_stub[Inlining]->params; tt; tt = tt->rgt) + if (!strcmp(Inline_stub[Inlining]->anms[i], + tt->lft->sym->name)) + { /* would be cyclic if not caught */ + printf("spin: %s:%d replacement value: %s\n", + oFname->name?oFname->name:"--", lineno, tt->lft->sym->name); + fatal("formal par of %s contains replacement value", + Inline_stub[Inlining]->nm->name); + yylval->ntyp = tt->lft->ntyp; + yylval->sym = lookup(tt->lft->sym->name); + return NAME; + } + + /* check for occurrence of param as field of struct */ + { char *ptr = Inline_stub[Inlining]->anms[i]; + char *optr = ptr; + while ((ptr = strstr(ptr, s)) != NULL) + { if ((ptr > optr && *(ptr-1) == '.') + || *(ptr+strlen(s)) == '.') + { fatal("formal par of %s used in structure name", + Inline_stub[Inlining]->nm->name); + } + ptr++; + } } + ReDiRect = Inline_stub[Inlining]->anms[i]; + return 0; + } } + + yylval->sym = lookup(s); /* symbol table */ + if (isutype(s)) + return UNAME; + if (isproctype(s)) + return PNAME; + if (iseqname(s)) + return INAME; + + return NAME; } int yylex(void) -{ static int last = 0; - static int hold = 0; - int c; - /* - * repair two common syntax mistakes with - * semi-colons before or after a '}' - */ - if (hold) - { c = hold; - hold = 0; - last_token = c; - } else - { c = lex(); - if (last == ELSE - && c != SEMI - && c != ARROW - && c != FI) - { hold = c; - last = 0; - last_token = SEMI; - return SEMI; - } - if (last == '}' - && c != PROCTYPE - && c != INIT - && c != CLAIM - && c != SEP - && c != FI - && c != OD - && c != '}' - && c != UNLESS - && c != SEMI - && c != ARROW - && c != EOF) - { hold = c; - last = 0; - last_token = SEMI; - return SEMI; /* insert ';' */ - } - if (c == SEMI || c == ARROW) - { /* if context, we're not in a typedef - * because they're global. - * if owner, we're at the end of a ref - * to a struct field -- prevent that the - * lookahead is interpreted as a field of - * the same struct... - */ - if (context) owner = ZS; - hold = lex(); /* look ahead */ - if (hold == '}' - || hold == ARROW - || hold == SEMI) - { c = hold; /* omit ';' */ - hold = 0; - } - } - } - last = c; - - if (IArgs) - { static int IArg_nst = 0; - - if (strcmp(yytext, ",") == 0) - { IArg_cont[++IArgno][0] = '\0'; - } else if (strcmp(yytext, "(") == 0) - { if (IArg_nst++ == 0) - { IArgno = 0; - IArg_cont[0][0] = '\0'; - } else - { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); - strcat(IArg_cont[IArgno], yytext); - } - } else if (strcmp(yytext, ")") == 0) - { if (--IArg_nst > 0) - { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); - strcat(IArg_cont[IArgno], yytext); - } - } else if (c == CONST && yytext[0] == '\'') - { sprintf(yytext, "'%c'", yylval->val); - assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); - strcat(IArg_cont[IArgno], yytext); - } else if (c == CONST) - { sprintf(yytext, "%d", yylval->val); - assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); - strcat(IArg_cont[IArgno], yytext); - } else - { - switch (c) { - case ARROW: strcpy(yytext, "->"); break; /* NEW */ - case SEP: strcpy(yytext, "::"); break; - case SEMI: strcpy(yytext, ";"); break; - case DECR: strcpy(yytext, "--"); break; - case INCR: strcpy(yytext, "++"); break; - case LSHIFT: strcpy(yytext, "<<"); break; - case RSHIFT: strcpy(yytext, ">>"); break; - case LE: strcpy(yytext, "<="); break; - case LT: strcpy(yytext, "<"); break; - case GE: strcpy(yytext, ">="); break; - case GT: strcpy(yytext, ">"); break; - case EQ: strcpy(yytext, "=="); break; - case ASGN: strcpy(yytext, "="); break; - case NE: strcpy(yytext, "!="); break; - case R_RCV: strcpy(yytext, "??"); break; - case RCV: strcpy(yytext, "?"); break; - case O_SND: strcpy(yytext, "!!"); break; - case SND: strcpy(yytext, "!"); break; - case AND: strcpy(yytext, "&&"); break; - case OR: strcpy(yytext, "||"); break; - } - assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); - strcat(IArg_cont[IArgno], yytext); - } - } - return c; +{ static int last = 0; + static int hold = 0; + int c; + /* + * repair two common syntax mistakes with + * semi-colons before or after a '}' + */ + if (hold) + { c = hold; + hold = 0; + last_token = c; + } else + { c = lex(); + if (last == ELSE + && c != SEMI + && c != ARROW + && c != FI) + { hold = c; + last = 0; + last_token = SEMI; + return SEMI; + } + if (last == '}' + && c != PROCTYPE + && c != INIT + && c != CLAIM + && c != SEP + && c != FI + && c != OD + && c != '}' + && c != UNLESS + && c != SEMI + && c != ARROW + && c != EOF) + { hold = c; + last = 0; + last_token = SEMI; + return SEMI; /* insert ';' */ + } + if (c == SEMI || c == ARROW) + { /* if context, we're not in a typedef + * because they're global. + * if owner, we're at the end of a ref + * to a struct field -- prevent that the + * lookahead is interpreted as a field of + * the same struct... + */ + if (context) owner = ZS; + hold = lex(); /* look ahead */ + if (hold == '}' + || hold == ARROW + || hold == SEMI) + { c = hold; /* omit ';' */ + hold = 0; + } + } + } + last = c; + + if (IArgs) + { static int IArg_nst = 0; + + if (strcmp(yytext, ",") == 0) + { IArg_cont[++IArgno][0] = '\0'; + } else if (strcmp(yytext, "(") == 0) + { if (IArg_nst++ == 0) + { IArgno = 0; + IArg_cont[0][0] = '\0'; + } else + { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); + strcat(IArg_cont[IArgno], yytext); + } + } else if (strcmp(yytext, ")") == 0) + { if (--IArg_nst > 0) + { assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); + strcat(IArg_cont[IArgno], yytext); + } + } else if (c == CONST && yytext[0] == '\'') + { sprintf(yytext, "'%c'", yylval->val); + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); + strcat(IArg_cont[IArgno], yytext); + } else if (c == CONST) + { sprintf(yytext, "%d", yylval->val); + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); + strcat(IArg_cont[IArgno], yytext); + } else + { + switch (c) { + case ARROW: strcpy(yytext, "->"); break; /* NEW */ + case SEP: strcpy(yytext, "::"); break; + case SEMI: strcpy(yytext, ";"); break; + case DECR: strcpy(yytext, "--"); break; + case INCR: strcpy(yytext, "++"); break; + case LSHIFT: strcpy(yytext, "<<"); break; + case RSHIFT: strcpy(yytext, ">>"); break; + case LE: strcpy(yytext, "<="); break; + case LT: strcpy(yytext, "<"); break; + case GE: strcpy(yytext, ">="); break; + case GT: strcpy(yytext, ">"); break; + case EQ: strcpy(yytext, "=="); break; + case ASGN: strcpy(yytext, "="); break; + case NE: strcpy(yytext, "!="); break; + case R_RCV: strcpy(yytext, "??"); break; + case RCV: strcpy(yytext, "?"); break; + case O_SND: strcpy(yytext, "!!"); break; + case SND: strcpy(yytext, "!"); break; + case AND: strcpy(yytext, "&&"); break; + case OR: strcpy(yytext, "||"); break; + } + assert(strlen(IArg_cont[IArgno])+strlen(yytext) < sizeof(IArg_cont)); + strcat(IArg_cont[IArgno], yytext); + } + } + return c; } diff --git a/Src/structs.c b/Src/structs.c index 6505a8e..0b88662 100644 --- a/Src/structs.c +++ b/Src/structs.c @@ -10,672 +10,672 @@ #include "y.tab.h" typedef struct UType { - Symbol *nm; /* name of the type */ - Lextok *cn; /* contents */ - struct UType *nxt; /* linked list */ + Symbol *nm; /* name of the type */ + Lextok *cn; /* contents */ + struct UType *nxt; /* linked list */ } UType; -extern Symbol *Fname; -extern int lineno, depth, Expand_Ok, has_hidden, in_for; +extern Symbol *Fname; +extern int lineno, depth, Expand_Ok, has_hidden, in_for; -Symbol *owner; +Symbol *owner; static UType *Unames = 0; static UType *Pnames = 0; -static Lextok *cpnn(Lextok *, int, int, int); -extern void sr_mesg(FILE *, int, int, const char *); -extern void Done_case(char *, Symbol *); +static Lextok *cpnn(Lextok *, int, int, int); +extern void sr_mesg(FILE *, int, int, const char *); +extern void Done_case(char *, Symbol *); void setuname(Lextok *n) -{ UType *tmp; - - if (!owner) - fatal("illegal reference inside typedef", (char *) 0); - - for (tmp = Unames; tmp; tmp = tmp->nxt) - if (!strcmp(owner->name, tmp->nm->name)) - { non_fatal("typename %s was defined before", - tmp->nm->name); - return; - } - - tmp = (UType *) emalloc(sizeof(UType)); - tmp->nm = owner; - tmp->cn = n; - tmp->nxt = Unames; - Unames = tmp; +{ UType *tmp; + + if (!owner) + fatal("illegal reference inside typedef", (char *) 0); + + for (tmp = Unames; tmp; tmp = tmp->nxt) + if (!strcmp(owner->name, tmp->nm->name)) + { non_fatal("typename %s was defined before", + tmp->nm->name); + return; + } + + tmp = (UType *) emalloc(sizeof(UType)); + tmp->nm = owner; + tmp->cn = n; + tmp->nxt = Unames; + Unames = tmp; } static void putUname(FILE *fd, UType *tmp) -{ Lextok *fp, *tl; - - if (!tmp) return; - putUname(fd, tmp->nxt); /* postorder */ - fprintf(fd, "struct %s { /* user defined type */\n", - tmp->nm->name); - for (fp = tmp->cn; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - typ2c(tl->sym); - fprintf(fd, "};\n"); +{ Lextok *fp, *tl; + + if (!tmp) return; + putUname(fd, tmp->nxt); /* postorder */ + fprintf(fd, "struct %s { /* user defined type */\n", + tmp->nm->name); + for (fp = tmp->cn; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + typ2c(tl->sym); + fprintf(fd, "};\n"); } void putunames(FILE *fd) { - putUname(fd, Unames); + putUname(fd, Unames); } int isutype(char *t) -{ UType *tmp; +{ UType *tmp; - for (tmp = Unames; tmp; tmp = tmp->nxt) - { if (!strcmp(t, tmp->nm->name)) - return 1; - } - return 0; + for (tmp = Unames; tmp; tmp = tmp->nxt) + { if (!strcmp(t, tmp->nm->name)) + return 1; + } + return 0; } Lextok * getuname(Symbol *t) -{ UType *tmp; - - for (tmp = Unames; tmp; tmp = tmp->nxt) - { if (!strcmp(t->name, tmp->nm->name)) - return tmp->cn; - } - fatal("%s is not a typename", t->name); - return (Lextok *)0; +{ UType *tmp; + + for (tmp = Unames; tmp; tmp = tmp->nxt) + { if (!strcmp(t->name, tmp->nm->name)) + return tmp->cn; + } + fatal("%s is not a typename", t->name); + return (Lextok *)0; } void -setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */ -{ int oln = lineno; - Symbol *ofn = Fname; - Lextok *m, *n; - - m = getuname(t); - for (n = p; n; n = n->rgt) - { lineno = n->ln; - Fname = n->fn; - if (n->sym->type) - { fatal("redeclaration of '%s'", n->sym->name); - } - - if (n->sym->nbits > 0) - non_fatal("(%s) only an unsigned can have width-field", - n->sym->name); - - if (Expand_Ok) - n->sym->hidden |= (4|8|16); /* formal par */ - - if (vis) - { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) - { n->sym->hidden |= 1; - has_hidden++; - } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0) - n->sym->hidden |= 2; - else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0) - n->sym->hidden |= 64; - } - n->sym->type = STRUCT; /* classification */ - n->sym->Slst = m; /* structure itself */ - n->sym->Snm = t; /* name of typedef */ - n->sym->Nid = 0; /* this is no chan */ - n->sym->hidden |= 4; - if (n->sym->nel <= 0) - non_fatal("bad array size for '%s'", n->sym->name); - } - lineno = oln; - Fname = ofn; +setutype(Lextok *p, Symbol *t, Lextok *vis) /* user-defined types */ +{ int oln = lineno; + Symbol *ofn = Fname; + Lextok *m, *n; + + m = getuname(t); + for (n = p; n; n = n->rgt) + { lineno = n->ln; + Fname = n->fn; + if (n->sym->type) + { fatal("redeclaration of '%s'", n->sym->name); + } + + if (n->sym->nbits > 0) + non_fatal("(%s) only an unsigned can have width-field", + n->sym->name); + + if (Expand_Ok) + n->sym->hidden |= (4|8|16); /* formal par */ + + if (vis) + { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) + { n->sym->hidden |= 1; + has_hidden++; + } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0) + n->sym->hidden |= 2; + else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0) + n->sym->hidden |= 64; + } + n->sym->type = STRUCT; /* classification */ + n->sym->Slst = m; /* structure itself */ + n->sym->Snm = t; /* name of typedef */ + n->sym->Nid = 0; /* this is no chan */ + n->sym->hidden |= 4; + if (n->sym->nel <= 0) + non_fatal("bad array size for '%s'", n->sym->name); + } + lineno = oln; + Fname = ofn; } static Symbol * do_same(Lextok *n, Symbol *v, int xinit) -{ Lextok *tmp, *fp, *tl; - int ix = eval(n->lft); - int oln = lineno; - Symbol *ofn = Fname; - - lineno = n->ln; - Fname = n->fn; - - /* n->sym->type == STRUCT - * index: n->lft - * subfields: n->rgt - * structure template: n->sym->Slst - * runtime values: n->sym->Sval - */ - if (xinit) ini_struct(v); /* once, at top level */ - - if (ix >= v->nel || ix < 0) - { printf("spin: indexing %s[%d] - size is %d\n", - v->name, ix, v->nel); - fatal("indexing error \'%s\'", v->name); - } - if (!n->rgt || !n->rgt->lft) - { non_fatal("no subfields %s", v->name); /* i.e., wants all */ - lineno = oln; Fname = ofn; - return ZS; - } - - if (n->rgt->ntyp != '.') - { printf("bad subfield type %d\n", n->rgt->ntyp); - alldone(1); - } - - tmp = n->rgt->lft; - if (tmp->ntyp != NAME && tmp->ntyp != TYPE) - { printf("bad subfield entry %d\n", tmp->ntyp); - alldone(1); - } - for (fp = v->Sval[ix]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - if (!strcmp(tl->sym->name, tmp->sym->name)) - { lineno = oln; Fname = ofn; - return tl->sym; - } - fatal("cannot locate subfield %s", tmp->sym->name); - return ZS; +{ Lextok *tmp, *fp, *tl; + int ix = eval(n->lft); + int oln = lineno; + Symbol *ofn = Fname; + + lineno = n->ln; + Fname = n->fn; + + /* n->sym->type == STRUCT + * index: n->lft + * subfields: n->rgt + * structure template: n->sym->Slst + * runtime values: n->sym->Sval + */ + if (xinit) ini_struct(v); /* once, at top level */ + + if (ix >= v->nel || ix < 0) + { printf("spin: indexing %s[%d] - size is %d\n", + v->name, ix, v->nel); + fatal("indexing error \'%s\'", v->name); + } + if (!n->rgt || !n->rgt->lft) + { non_fatal("no subfields %s", v->name); /* i.e., wants all */ + lineno = oln; Fname = ofn; + return ZS; + } + + if (n->rgt->ntyp != '.') + { printf("bad subfield type %d\n", n->rgt->ntyp); + alldone(1); + } + + tmp = n->rgt->lft; + if (tmp->ntyp != NAME && tmp->ntyp != TYPE) + { printf("bad subfield entry %d\n", tmp->ntyp); + alldone(1); + } + for (fp = v->Sval[ix]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + if (!strcmp(tl->sym->name, tmp->sym->name)) + { lineno = oln; Fname = ofn; + return tl->sym; + } + fatal("cannot locate subfield %s", tmp->sym->name); + return ZS; } int -Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */ -{ Symbol *tl; - Lextok *tmp; - int ix; - - if (!n || !(tl = do_same(n, v, xinit))) - return 0; - - tmp = n->rgt->lft; - if (tmp->sym->type == STRUCT) - { return Rval_struct(tmp, tl, 0); - } else if (tmp->rgt) - fatal("non-zero 'rgt' on non-structure", 0); - - ix = eval(tmp->lft); -/* printf("%d: ix: %d (%d) %d\n", depth, ix, tl->nel, tl->val[ix]); */ - if (ix >= tl->nel || ix < 0) - fatal("indexing error \'%s\'", tl->name); - - return cast_val(tl->type, tl->val[ix], tl->nbits); +Rval_struct(Lextok *n, Symbol *v, int xinit) /* n varref, v valref */ +{ Symbol *tl; + Lextok *tmp; + int ix; + + if (!n || !(tl = do_same(n, v, xinit))) + return 0; + + tmp = n->rgt->lft; + if (tmp->sym->type == STRUCT) + { return Rval_struct(tmp, tl, 0); + } else if (tmp->rgt) + fatal("non-zero 'rgt' on non-structure", 0); + + ix = eval(tmp->lft); +/* printf("%d: ix: %d (%d) %d\n", depth, ix, tl->nel, tl->val[ix]); */ + if (ix >= tl->nel || ix < 0) + fatal("indexing error \'%s\'", tl->name); + + return cast_val(tl->type, tl->val[ix], tl->nbits); } int Lval_struct(Lextok *n, Symbol *v, int xinit, int a) /* a = assigned value */ -{ Symbol *tl; - Lextok *tmp; - int ix; - - if (!(tl = do_same(n, v, xinit))) - return 1; - - tmp = n->rgt->lft; - if (tmp->sym->type == STRUCT) - return Lval_struct(tmp, tl, 0, a); - else if (tmp->rgt) - fatal("non-zero 'rgt' on non-structure", 0); - - ix = eval(tmp->lft); - if (ix >= tl->nel || ix < 0) - fatal("indexing error \'%s\'", tl->name); - - if (tl->nbits > 0) - a = (a & ((1<nbits)-1)); - - if (a != tl->val[ix]) - { tl->val[ix] = a; - tl->setat = depth; - } - return 1; +{ Symbol *tl; + Lextok *tmp; + int ix; + + if (!(tl = do_same(n, v, xinit))) + return 1; + + tmp = n->rgt->lft; + if (tmp->sym->type == STRUCT) + return Lval_struct(tmp, tl, 0, a); + else if (tmp->rgt) + fatal("non-zero 'rgt' on non-structure", 0); + + ix = eval(tmp->lft); + if (ix >= tl->nel || ix < 0) + fatal("indexing error \'%s\'", tl->name); + + if (tl->nbits > 0) + a = (a & ((1<nbits)-1)); + + if (a != tl->val[ix]) + { tl->val[ix] = a; + tl->setat = depth; + } + return 1; } int Cnt_flds(Lextok *m) -{ Lextok *fp, *tl, *n; - int cnt = 0; - - if (!m) - { return 0; - } - - if (m->ntyp == ',') - { n = m; - goto is_lst; - } - if (!m->sym - || m->ntyp != STRUCT) - { return 1; - } - - n = getuname(m->sym); +{ Lextok *fp, *tl, *n; + int cnt = 0; + + if (!m) + { return 0; + } + + if (m->ntyp == ',') + { n = m; + goto is_lst; + } + if (!m->sym + || m->ntyp != STRUCT) + { return 1; + } + + n = getuname(m->sym); is_lst: - for (fp = n; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - { if (tl->sym->nel > 1 || tl->sym->isarray) - fatal("array of structures in param list, %s", - tl->sym->name); - cnt += Cnt_flds(tl->sym->Slst); - } else - cnt += tl->sym->nel; - } - return cnt; + for (fp = n; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + { if (tl->sym->nel > 1 || tl->sym->isarray) + fatal("array of structures in param list, %s", + tl->sym->name); + cnt += Cnt_flds(tl->sym->Slst); + } else + cnt += tl->sym->nel; + } + return cnt; } int Sym_typ(Lextok *t) -{ Symbol *s = t->sym; +{ Symbol *s = t->sym; - if (!s) return 0; + if (!s) return 0; - if (s->type != STRUCT) - return s->type; + if (s->type != STRUCT) + return s->type; - if (!t->rgt - || t->rgt->ntyp != '.' /* gh: had ! in wrong place */ - || !t->rgt->lft) - return STRUCT; /* not a field reference */ + if (!t->rgt + || t->rgt->ntyp != '.' /* gh: had ! in wrong place */ + || !t->rgt->lft) + return STRUCT; /* not a field reference */ - return Sym_typ(t->rgt->lft); + return Sym_typ(t->rgt->lft); } int Width_set(int *wdth, int i, Lextok *n) -{ Lextok *fp, *tl; - int j = i, k; - - for (fp = n; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - j = Width_set(wdth, j, tl->sym->Slst); - else - { for (k = 0; k < tl->sym->nel; k++, j++) - wdth[j] = tl->sym->type; - } } - return j; +{ Lextok *fp, *tl; + int j = i, k; + + for (fp = n; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + j = Width_set(wdth, j, tl->sym->Slst); + else + { for (k = 0; k < tl->sym->nel; k++, j++) + wdth[j] = tl->sym->type; + } } + return j; } void ini_struct(Symbol *s) -{ int i; Lextok *fp, *tl; - - if (s->type != STRUCT) /* last step */ - { (void) checkvar(s, 0); - return; - } - if (s->Sval == (Lextok **) 0) - { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *)); - for (i = 0; i < s->nel; i++) - { s->Sval[i] = cpnn(s->Slst, 1, 1, 1); - - for (fp = s->Sval[i]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - ini_struct(tl->sym); - } } +{ int i; Lextok *fp, *tl; + + if (s->type != STRUCT) /* last step */ + { (void) checkvar(s, 0); + return; + } + if (s->Sval == (Lextok **) 0) + { s->Sval = (Lextok **) emalloc(s->nel * sizeof(Lextok *)); + for (i = 0; i < s->nel; i++) + { s->Sval[i] = cpnn(s->Slst, 1, 1, 1); + + for (fp = s->Sval[i]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + ini_struct(tl->sym); + } } } static Lextok * cpnn(Lextok *s, int L, int R, int S) -{ Lextok *d; extern int Nid_nr; - - if (!s) return ZN; - - d = (Lextok *) emalloc(sizeof(Lextok)); - d->uiid = s->uiid; - d->ntyp = s->ntyp; - d->val = s->val; - d->ln = s->ln; - d->fn = s->fn; - d->sym = s->sym; - if (L) d->lft = cpnn(s->lft, 1, 1, S); - if (R) d->rgt = cpnn(s->rgt, 1, 1, S); - - if (S && s->sym) - { d->sym = (Symbol *) emalloc(sizeof(Symbol)); - memcpy(d->sym, s->sym, sizeof(Symbol)); - if (d->sym->type == CHAN) - d->sym->Nid = ++Nid_nr; - } - if (s->sq || s->sl) - fatal("cannot happen cpnn", (char *) 0); - - return d; +{ Lextok *d; extern int Nid_nr; + + if (!s) return ZN; + + d = (Lextok *) emalloc(sizeof(Lextok)); + d->uiid = s->uiid; + d->ntyp = s->ntyp; + d->val = s->val; + d->ln = s->ln; + d->fn = s->fn; + d->sym = s->sym; + if (L) d->lft = cpnn(s->lft, 1, 1, S); + if (R) d->rgt = cpnn(s->rgt, 1, 1, S); + + if (S && s->sym) + { d->sym = (Symbol *) emalloc(sizeof(Symbol)); + memcpy(d->sym, s->sym, sizeof(Symbol)); + if (d->sym->type == CHAN) + d->sym->Nid = ++Nid_nr; + } + if (s->sq || s->sl) + fatal("cannot happen cpnn", (char *) 0); + + return d; } int full_name(FILE *fd, Lextok *n, Symbol *v, int xinit) -{ Symbol *tl; - Lextok *tmp; - int hiddenarrays = 0; - - fprintf(fd, "%s", v->name); - - if (!n || !(tl = do_same(n, v, xinit))) - return 0; - tmp = n->rgt->lft; - - if (tmp->sym->type == STRUCT) - { fprintf(fd, "."); - hiddenarrays = full_name(fd, tmp, tl, 0); - goto out; - } - fprintf(fd, ".%s", tl->name); -out: if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) - { fprintf(fd, "[%d]", eval(tmp->lft)); - hiddenarrays = 1; - } - return hiddenarrays; +{ Symbol *tl; + Lextok *tmp; + int hiddenarrays = 0; + + fprintf(fd, "%s", v->name); + + if (!n || !(tl = do_same(n, v, xinit))) + return 0; + tmp = n->rgt->lft; + + if (tmp->sym->type == STRUCT) + { fprintf(fd, "."); + hiddenarrays = full_name(fd, tmp, tl, 0); + goto out; + } + fprintf(fd, ".%s", tl->name); +out: if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) + { fprintf(fd, "[%d]", eval(tmp->lft)); + hiddenarrays = 1; + } + return hiddenarrays; } void validref(Lextok *p, Lextok *c) -{ Lextok *fp, *tl; - char lbuf[512]; +{ Lextok *fp, *tl; + char lbuf[512]; - for (fp = p->sym->Slst; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - if (strcmp(tl->sym->name, c->sym->name) == 0) - return; + for (fp = p->sym->Slst; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + if (strcmp(tl->sym->name, c->sym->name) == 0) + return; - sprintf(lbuf, "no field '%s' defined in structure '%s'\n", - c->sym->name, p->sym->name); - non_fatal(lbuf, (char *) 0); + sprintf(lbuf, "no field '%s' defined in structure '%s'\n", + c->sym->name, p->sym->name); + non_fatal(lbuf, (char *) 0); } void struct_name(Lextok *n, Symbol *v, int xinit, char *buf) -{ Symbol *tl; - Lextok *tmp; - char lbuf[512]; - - if (!n || !(tl = do_same(n, v, xinit))) - return; - tmp = n->rgt->lft; - if (tmp->sym->type == STRUCT) - { strcat(buf, "."); - struct_name(tmp, tl, 0, buf); - return; - } - sprintf(lbuf, ".%s", tl->name); - strcat(buf, lbuf); - if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) - { sprintf(lbuf, "[%d]", eval(tmp->lft)); - strcat(buf, lbuf); - } +{ Symbol *tl; + Lextok *tmp; + char lbuf[512]; + + if (!n || !(tl = do_same(n, v, xinit))) + return; + tmp = n->rgt->lft; + if (tmp->sym->type == STRUCT) + { strcat(buf, "."); + struct_name(tmp, tl, 0, buf); + return; + } + sprintf(lbuf, ".%s", tl->name); + strcat(buf, lbuf); + if (tmp->sym->nel > 1 || tmp->sym->isarray == 1) + { sprintf(lbuf, "[%d]", eval(tmp->lft)); + strcat(buf, lbuf); + } } void walk2_struct(char *s, Symbol *z) -{ Lextok *fp, *tl; - char eprefix[512]; - int ix; - - memset(eprefix, 0, sizeof(eprefix)); - ini_struct(z); - if (z->nel == 1 && z->isarray == 0) - snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); - for (ix = 0; ix < z->nel; ix++) - { if (z->nel > 1 || z->isarray == 1) - snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); - for (fp = z->Sval[ix]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - walk2_struct(eprefix, tl->sym); - else if (tl->sym->type == CHAN) - Done_case(eprefix, tl->sym); - } } +{ Lextok *fp, *tl; + char eprefix[512]; + int ix; + + memset(eprefix, 0, sizeof(eprefix)); + ini_struct(z); + if (z->nel == 1 && z->isarray == 0) + snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); + for (ix = 0; ix < z->nel; ix++) + { if (z->nel > 1 || z->isarray == 1) + snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); + for (fp = z->Sval[ix]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + walk2_struct(eprefix, tl->sym); + else if (tl->sym->type == CHAN) + Done_case(eprefix, tl->sym); + } } } void -walk_struct(FILE *ofd, int dowhat, char *s, Symbol *z, char *a, char *b, char *c) -{ Lextok *fp, *tl; - char eprefix[512]; - int ix; - - memset(eprefix, 0, sizeof(eprefix)); - ini_struct(z); - if (z->nel == 1 && z->isarray == 0) - snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); - for (ix = 0; ix < z->nel; ix++) - { if (z->nel > 1 || z->isarray == 1) - snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); - for (fp = z->Sval[ix]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c); - else - do_var(ofd, dowhat, eprefix, tl->sym, a,b,c); - } } +walk_struct(FILE *ofd, int dowhat, const char *s, Symbol *z, const char *a, const char *b, const char *c) +{ Lextok *fp, *tl; + char eprefix[512]; + int ix; + + memset(eprefix, 0, sizeof(eprefix)); + ini_struct(z); + if (z->nel == 1 && z->isarray == 0) + snprintf(eprefix, sizeof(eprefix)-1, "%s%s.", s, z->name); + for (ix = 0; ix < z->nel; ix++) + { if (z->nel > 1 || z->isarray == 1) + snprintf(eprefix, sizeof(eprefix)-1, "%s%s[%d].", s, z->name, ix); + for (fp = z->Sval[ix]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + walk_struct(ofd, dowhat, eprefix, tl->sym, a,b,c); + else + do_var(ofd, dowhat, eprefix, tl->sym, a,b,c); + } } } void -c_struct(FILE *fd, char *ipref, Symbol *z) -{ Lextok *fp, *tl; - char pref[512], eprefix[300]; - int ix; - - ini_struct(z); - - for (ix = 0; ix < z->nel; ix++) - for (fp = z->Sval[ix]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { strcpy(eprefix, ipref); - if (z->nel > 1 || z->isarray == 1) - { /* insert index before last '.' */ - eprefix[strlen(eprefix)-1] = '\0'; - sprintf(pref, "[ %d ].", ix); - strcat(eprefix, pref); - } - if (tl->sym->type == STRUCT) - { strcat(eprefix, tl->sym->name); - strcat(eprefix, "."); - c_struct(fd, eprefix, tl->sym); - } else - c_var(fd, eprefix, tl->sym); - } +c_struct(FILE *fd, const char *ipref, Symbol *z) +{ Lextok *fp, *tl; + char pref[512], eprefix[300]; + int ix; + + ini_struct(z); + + for (ix = 0; ix < z->nel; ix++) + for (fp = z->Sval[ix]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { strcpy(eprefix, ipref); + if (z->nel > 1 || z->isarray == 1) + { /* insert index before last '.' */ + eprefix[strlen(eprefix)-1] = '\0'; + sprintf(pref, "[ %d ].", ix); + strcat(eprefix, pref); + } + if (tl->sym->type == STRUCT) + { strcat(eprefix, tl->sym->name); + strcat(eprefix, "."); + c_struct(fd, eprefix, tl->sym); + } else + c_var(fd, eprefix, tl->sym); + } } void dump_struct(Symbol *z, char *prefix, RunList *r) -{ Lextok *fp, *tl; - char eprefix[512]; - int ix, jx; - - ini_struct(z); - - for (ix = 0; ix < z->nel; ix++) - { if (z->nel > 1 || z->isarray == 1) - sprintf(eprefix, "%s[%d]", prefix, ix); - else - strcpy(eprefix, prefix); - - for (fp = z->Sval[ix]; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - { char pref[300]; - strcpy(pref, eprefix); - strcat(pref, "."); - strcat(pref, tl->sym->name); - dump_struct(tl->sym, pref, r); - } else - for (jx = 0; jx < tl->sym->nel; jx++) - { if (tl->sym->type == CHAN) - doq(tl->sym, jx, r); - else - { char *s = 0; - printf("\t\t"); - if (r) - printf("%s(%d):", r->n->name, r->pid); - printf("%s.%s", eprefix, tl->sym->name); - if (tl->sym->nel > 1 || tl->sym->isarray == 1) - printf("[%d]", jx); - printf(" = "); - - if (tl->sym->type == MTYPE - && tl->sym->mtype_name) - { s = tl->sym->mtype_name->name; - } - - sr_mesg(stdout, tl->sym->val[jx], - tl->sym->type == MTYPE, s); - printf("\n"); - } } } - } +{ Lextok *fp, *tl; + char eprefix[512]; + int ix, jx; + + ini_struct(z); + + for (ix = 0; ix < z->nel; ix++) + { if (z->nel > 1 || z->isarray == 1) + sprintf(eprefix, "%s[%d]", prefix, ix); + else + strcpy(eprefix, prefix); + + for (fp = z->Sval[ix]; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + { char pref[300]; + strcpy(pref, eprefix); + strcat(pref, "."); + strcat(pref, tl->sym->name); + dump_struct(tl->sym, pref, r); + } else + for (jx = 0; jx < tl->sym->nel; jx++) + { if (tl->sym->type == CHAN) + doq(tl->sym, jx, r); + else + { char *s = 0; + printf("\t\t"); + if (r) + printf("%s(%d):", r->n->name, r->pid); + printf("%s.%s", eprefix, tl->sym->name); + if (tl->sym->nel > 1 || tl->sym->isarray == 1) + printf("[%d]", jx); + printf(" = "); + + if (tl->sym->type == MTYPE + && tl->sym->mtype_name) + { s = tl->sym->mtype_name->name; + } + + sr_mesg(stdout, tl->sym->val[jx], + tl->sym->type == MTYPE, s); + printf("\n"); + } } } + } } static int retrieve(Lextok **targ, int i, int want, Lextok *n, int Ntyp) -{ Lextok *fp, *tl; - int j = i, k; - - for (fp = n; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp); - if (j < 0) - { Lextok *x = cpnn(tl, 1, 0, 0); - x->rgt = nn(ZN, '.', (*targ), ZN); - (*targ) = x; - return -1; - } - } else - { for (k = 0; k < tl->sym->nel; k++, j++) - { if (j == want) - { *targ = cpnn(tl, 1, 0, 0); - (*targ)->lft = nn(ZN, CONST, ZN, ZN); - (*targ)->lft->val = k; - if (Ntyp) - (*targ)->ntyp = (short) Ntyp; - return -1; - } - } } } - return j; +{ Lextok *fp, *tl; + int j = i, k; + + for (fp = n; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + { j = retrieve(targ, j, want, tl->sym->Slst, Ntyp); + if (j < 0) + { Lextok *x = cpnn(tl, 1, 0, 0); + x->rgt = nn(ZN, '.', (*targ), ZN); + (*targ) = x; + return -1; + } + } else + { for (k = 0; k < tl->sym->nel; k++, j++) + { if (j == want) + { *targ = cpnn(tl, 1, 0, 0); + (*targ)->lft = nn(ZN, CONST, ZN, ZN); + (*targ)->lft->val = k; + if (Ntyp) + (*targ)->ntyp = (short) Ntyp; + return -1; + } + } } } + return j; } static int is_explicit(Lextok *n) { - if (!n) return 0; - if (!n->sym) fatal("unexpected - no symbol", 0); - if (n->sym->type != STRUCT) return 1; - if (!n->rgt) return 0; - if (n->rgt->ntyp != '.') - { lineno = n->ln; - Fname = n->fn; - printf("ntyp %d\n", n->rgt->ntyp); - fatal("unexpected %s, no '.'", n->sym->name); - } - return is_explicit(n->rgt->lft); + if (!n) return 0; + if (!n->sym) fatal("unexpected - no symbol", 0); + if (n->sym->type != STRUCT) return 1; + if (!n->rgt) return 0; + if (n->rgt->ntyp != '.') + { lineno = n->ln; + Fname = n->fn; + printf("ntyp %d\n", n->rgt->ntyp); + fatal("unexpected %s, no '.'", n->sym->name); + } + return is_explicit(n->rgt->lft); } Lextok * expand(Lextok *n, int Ok) - /* turn rgt-lnked list of struct nms, into ',' list of flds */ -{ Lextok *x = ZN, *y; + /* turn rgt-lnked list of struct nms, into ',' list of flds */ +{ Lextok *x = ZN, *y; - if (!Ok) return n; + if (!Ok) return n; - while (n) - { y = mk_explicit(n, 1, 0); - if (x) - (void) tail_add(x, y); - else - x = y; + while (n) + { y = mk_explicit(n, 1, 0); + if (x) + (void) tail_add(x, y); + else + x = y; - n = n->rgt; - } - return x; + n = n->rgt; + } + return x; } Lextok * mk_explicit(Lextok *n, int Ok, int Ntyp) - /* produce a single ',' list of fields */ -{ Lextok *bld = ZN, *x; - int i, cnt; extern int IArgs; - - if (n->sym->type != STRUCT - || in_for - || is_explicit(n)) - return n; - - - if (n->rgt - && n->rgt->ntyp == '.' - && n->rgt->lft - && n->rgt->lft->sym - && n->rgt->lft->sym->type == STRUCT) - { Lextok *y; - bld = mk_explicit(n->rgt->lft, Ok, Ntyp); - for (x = bld; x; x = x->rgt) - { y = cpnn(n, 1, 0, 0); - y->rgt = nn(ZN, '.', x->lft, ZN); - x->lft = y; - } - - return bld; - } - - if (!Ok || !n->sym->Slst) - { if (IArgs) return n; - printf("spin: saw '"); - comment(stdout, n, 0); - printf("'\n"); - fatal("incomplete structure ref '%s'", n->sym->name); - } - - cnt = Cnt_flds(n->sym->Slst); - for (i = cnt-1; i >= 0; i--) - { bld = nn(ZN, ',', ZN, bld); - if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0) - { printf("cannot retrieve field %d\n", i); - fatal("bad structure %s", n->sym->name); - } - x = cpnn(n, 1, 0, 0); - x->rgt = nn(ZN, '.', bld->lft, ZN); - bld->lft = x; - } - return bld; + /* produce a single ',' list of fields */ +{ Lextok *bld = ZN, *x; + int i, cnt; extern int IArgs; + + if (n->sym->type != STRUCT + || in_for + || is_explicit(n)) + return n; + + + if (n->rgt + && n->rgt->ntyp == '.' + && n->rgt->lft + && n->rgt->lft->sym + && n->rgt->lft->sym->type == STRUCT) + { Lextok *y; + bld = mk_explicit(n->rgt->lft, Ok, Ntyp); + for (x = bld; x; x = x->rgt) + { y = cpnn(n, 1, 0, 0); + y->rgt = nn(ZN, '.', x->lft, ZN); + x->lft = y; + } + + return bld; + } + + if (!Ok || !n->sym->Slst) + { if (IArgs) return n; + printf("spin: saw '"); + comment(stdout, n, 0); + printf("'\n"); + fatal("incomplete structure ref '%s'", n->sym->name); + } + + cnt = Cnt_flds(n->sym->Slst); + for (i = cnt-1; i >= 0; i--) + { bld = nn(ZN, ',', ZN, bld); + if (retrieve(&(bld->lft), 0, i, n->sym->Slst, Ntyp) >= 0) + { printf("cannot retrieve field %d\n", i); + fatal("bad structure %s", n->sym->name); + } + x = cpnn(n, 1, 0, 0); + x->rgt = nn(ZN, '.', bld->lft, ZN); + bld->lft = x; + } + return bld; } Lextok * tail_add(Lextok *a, Lextok *b) -{ Lextok *t; +{ Lextok *t; - for (t = a; t->rgt; t = t->rgt) - if (t->ntyp != ',') - fatal("unexpected type - tail_add", 0); - t->rgt = b; - return a; + for (t = a; t->rgt; t = t->rgt) + if (t->ntyp != ',') + fatal("unexpected type - tail_add", 0); + t->rgt = b; + return a; } void setpname(Lextok *n) -{ UType *tmp; - - for (tmp = Pnames; tmp; tmp = tmp->nxt) - if (!strcmp(n->sym->name, tmp->nm->name)) - { non_fatal("proctype %s redefined", - n->sym->name); - return; - } - tmp = (UType *) emalloc(sizeof(UType)); - tmp->nm = n->sym; - tmp->nxt = Pnames; - Pnames = tmp; +{ UType *tmp; + + for (tmp = Pnames; tmp; tmp = tmp->nxt) + if (!strcmp(n->sym->name, tmp->nm->name)) + { non_fatal("proctype %s redefined", + n->sym->name); + return; + } + tmp = (UType *) emalloc(sizeof(UType)); + tmp->nm = n->sym; + tmp->nxt = Pnames; + Pnames = tmp; } int isproctype(char *t) -{ UType *tmp; +{ UType *tmp; - for (tmp = Pnames; tmp; tmp = tmp->nxt) - { if (!strcmp(t, tmp->nm->name)) - return 1; - } - return 0; + for (tmp = Pnames; tmp; tmp = tmp->nxt) + { if (!strcmp(t, tmp->nm->name)) + return 1; + } + return 0; } diff --git a/Src/sym.c b/Src/sym.c index 94c3d61..408f257 100644 --- a/Src/sym.c +++ b/Src/sym.c @@ -9,686 +9,686 @@ #include "spin.h" #include "y.tab.h" -extern Symbol *Fname, *owner; -extern int lineno, depth, verbose, NamesNotAdded, deadvar; -extern int has_hidden, m_loss, old_scope_rules; -extern short has_xu; -extern char CurScope[MAXSCOPESZ]; +extern Symbol *Fname, *owner; +extern int lineno, depth, verbose, NamesNotAdded, deadvar; +extern int has_hidden, m_loss, old_scope_rules; +extern short has_xu; +extern char CurScope[MAXSCOPESZ]; -Symbol *context = ZS; -Ordered *all_names = (Ordered *)0; -int Nid_nr = 0; +Symbol *context = ZS; +Ordered *all_names = (Ordered *)0; +int Nid_nr = 0; -Mtypes_t *Mtypes; -Lextok *runstmnts = ZN; +Mtypes_t *Mtypes; +Lextok *runstmnts = ZN; -static Ordered *last_name = (Ordered *)0; -static Symbol *symtab[Nhash+1]; +static Ordered *last_name = (Ordered *)0; +static Symbol *symtab[Nhash+1]; static int samename(Symbol *a, Symbol *b) { - if (!a && !b) return 1; - if (!a || !b) return 0; - return !strcmp(a->name, b->name); + if (!a && !b) return 1; + if (!a || !b) return 0; + return !strcmp(a->name, b->name); } unsigned int hash(const char *s) -{ unsigned int h = 0; - - while (*s) - { h += (unsigned int) *s++; - h <<= 1; - if (h&(Nhash+1)) - h |= 1; - } - return h&Nhash; +{ unsigned int h = 0; + + while (*s) + { h += (unsigned int) *s++; + h <<= 1; + if (h&(Nhash+1)) + h |= 1; + } + return h&Nhash; } void disambiguate(void) -{ Ordered *walk; - Symbol *sp; - char *n, *m; - - if (old_scope_rules) - return; - - /* prepend the scope_prefix to the names */ - - for (walk = all_names; walk; walk = walk->next) - { sp = walk->entry; - if (sp->type != 0 - && sp->type != LABEL - && strlen((const char *)sp->bscp) > 1) - { if (sp->context) - { m = (char *) emalloc(strlen((const char *)sp->bscp) + 1); - sprintf(m, "_%d_", sp->context->sc); - if (strcmp((const char *) m, (const char *) sp->bscp) == 0) - { continue; - /* 6.2.0: only prepend scope for inner-blocks, - not for top-level locals within a proctype - this means that you can no longer use the same name - for a global and a (top-level) local variable - */ - } } - - n = (char *) emalloc(strlen((const char *)sp->name) - + strlen((const char *)sp->bscp) + 1); - sprintf(n, "%s%s", sp->bscp, sp->name); - sp->name = n; /* discard the old memory */ - } } +{ Ordered *walk; + Symbol *sp; + char *n, *m; + + if (old_scope_rules) + return; + + /* prepend the scope_prefix to the names */ + + for (walk = all_names; walk; walk = walk->next) + { sp = walk->entry; + if (sp->type != 0 + && sp->type != LABEL + && strlen((const char *)sp->bscp) > 1) + { if (sp->context) + { m = (char *) emalloc(strlen((const char *)sp->bscp) + 1); + sprintf(m, "_%d_", sp->context->sc); + if (strcmp((const char *) m, (const char *) sp->bscp) == 0) + { continue; + /* 6.2.0: only prepend scope for inner-blocks, + not for top-level locals within a proctype + this means that you can no longer use the same name + for a global and a (top-level) local variable + */ + } } + + n = (char *) emalloc(strlen((const char *)sp->name) + + strlen((const char *)sp->bscp) + 1); + sprintf(n, "%s%s", sp->bscp, sp->name); + sp->name = n; /* discard the old memory */ + } } } Symbol * -lookup(char *s) -{ Symbol *sp; Ordered *no; - unsigned int h = hash(s); - - if (old_scope_rules) - { /* same scope - global refering to global or local to local */ - for (sp = symtab[h]; sp; sp = sp->next) - { if (strcmp(sp->name, s) == 0 - && samename(sp->context, context) - && samename(sp->owner, owner)) - { return sp; /* found */ - } } - } else - { /* added 6.0.0: more traditional, scope rule */ - for (sp = symtab[h]; sp; sp = sp->next) - { if (strcmp(sp->name, s) == 0 - && samename(sp->context, context) - && (strcmp((const char *)sp->bscp, CurScope) == 0 - || strncmp((const char *)sp->bscp, CurScope, strlen((const char *)sp->bscp)) == 0) - && samename(sp->owner, owner)) - { - if (!samename(sp->owner, owner)) - { printf("spin: different container %s\n", sp->name); - printf(" old: %s\n", sp->owner?sp->owner->name:"--"); - printf(" new: %s\n", owner?owner->name:"--"); - /* alldone(1); */ - } - return sp; /* found */ - } } } - - if (context) /* in proctype, refers to global */ - for (sp = symtab[h]; sp; sp = sp->next) - { if (strcmp(sp->name, s) == 0 - && !sp->context - && samename(sp->owner, owner)) - { return sp; /* global */ - } } - sp = (Symbol *) emalloc(sizeof(Symbol)); - sp->name = (char *) emalloc(strlen(s) + 1); - strcpy(sp->name, s); - sp->nel = 1; - sp->setat = depth; - sp->context = context; - sp->owner = owner; /* if fld in struct */ - sp->bscp = (unsigned char *) emalloc(strlen((const char *)CurScope)+1); - strcpy((char *)sp->bscp, CurScope); - - if (NamesNotAdded == 0) - { sp->next = symtab[h]; - symtab[h] = sp; - no = (Ordered *) emalloc(sizeof(Ordered)); - no->entry = sp; - if (!last_name) - last_name = all_names = no; - else - { last_name->next = no; - last_name = no; - } } - - return sp; +lookup(const char *s) +{ Symbol *sp; Ordered *no; + unsigned int h = hash(s); + + if (old_scope_rules) + { /* same scope - global refering to global or local to local */ + for (sp = symtab[h]; sp; sp = sp->next) + { if (strcmp(sp->name, s) == 0 + && samename(sp->context, context) + && samename(sp->owner, owner)) + { return sp; /* found */ + } } + } else + { /* added 6.0.0: more traditional, scope rule */ + for (sp = symtab[h]; sp; sp = sp->next) + { if (strcmp(sp->name, s) == 0 + && samename(sp->context, context) + && (strcmp((const char *)sp->bscp, CurScope) == 0 + || strncmp((const char *)sp->bscp, CurScope, strlen((const char *)sp->bscp)) == 0) + && samename(sp->owner, owner)) + { + if (!samename(sp->owner, owner)) + { printf("spin: different container %s\n", sp->name); + printf(" old: %s\n", sp->owner?sp->owner->name:"--"); + printf(" new: %s\n", owner?owner->name:"--"); + /* alldone(1); */ + } + return sp; /* found */ + } } } + + if (context) /* in proctype, refers to global */ + for (sp = symtab[h]; sp; sp = sp->next) + { if (strcmp(sp->name, s) == 0 + && !sp->context + && samename(sp->owner, owner)) + { return sp; /* global */ + } } + sp = (Symbol *) emalloc(sizeof(Symbol)); + sp->name = (char *) emalloc(strlen(s) + 1); + strcpy(sp->name, s); + sp->nel = 1; + sp->setat = depth; + sp->context = context; + sp->owner = owner; /* if fld in struct */ + sp->bscp = (unsigned char *) emalloc(strlen((const char *)CurScope)+1); + strcpy((char *)sp->bscp, CurScope); + + if (NamesNotAdded == 0) + { sp->next = symtab[h]; + symtab[h] = sp; + no = (Ordered *) emalloc(sizeof(Ordered)); + no->entry = sp; + if (!last_name) + last_name = all_names = no; + else + { last_name->next = no; + last_name = no; + } } + + return sp; } void trackvar(Lextok *n, Lextok *m) -{ Symbol *sp = n->sym; - - if (!sp) return; /* a structure list */ - switch (m->ntyp) { - case NAME: - if (m->sym->type != BIT) - { sp->hidden |= 4; - if (m->sym->type != BYTE) - sp->hidden |= 8; - } - break; - case CONST: - if (m->val != 0 && m->val != 1) - sp->hidden |= 4; - if (m->val < 0 || m->val > 256) - sp->hidden |= 8; /* ditto byte-equiv */ - break; - default: /* unknown */ - sp->hidden |= (4|8); /* not known bit-equiv */ - } +{ Symbol *sp = n->sym; + + if (!sp) return; /* a structure list */ + switch (m->ntyp) { + case NAME: + if (m->sym->type != BIT) + { sp->hidden |= 4; + if (m->sym->type != BYTE) + sp->hidden |= 8; + } + break; + case CONST: + if (m->val != 0 && m->val != 1) + sp->hidden |= 4; + if (m->val < 0 || m->val > 256) + sp->hidden |= 8; /* ditto byte-equiv */ + break; + default: /* unknown */ + sp->hidden |= (4|8); /* not known bit-equiv */ + } } void trackrun(Lextok *n) { - runstmnts = nn(ZN, 0, n, runstmnts); + runstmnts = nn(ZN, 0, n, runstmnts); } void checkrun(Symbol *parnm, int posno) -{ Lextok *n, *now, *v; int i, m; - int res = 0; char buf[16], buf2[16]; - - for (n = runstmnts; n; n = n->rgt) - { now = n->lft; - if (now->sym != parnm->context) - continue; - for (v = now->lft, i = 0; v; v = v->rgt, i++) - if (i == posno) - { m = v->lft->ntyp; - if (m == CONST) - { m = v->lft->val; - if (m != 0 && m != 1) - res |= 4; - if (m < 0 || m > 256) - res |= 8; - } else if (m == NAME) - { m = v->lft->sym->type; - if (m != BIT) - { res |= 4; - if (m != BYTE) - res |= 8; - } - } else - res |= (4|8); /* unknown */ - break; - } } - if (!(res&4) || !(res&8)) - { if (!(verbose&32)) return; - strcpy(buf2, (!(res&4))?"bit":"byte"); - sputtype(buf, parnm->type); - i = (int) strlen(buf); - while (i > 0 && buf[--i] == ' ') buf[i] = '\0'; - if (i == 0 || strcmp(buf, buf2) == 0) return; - prehint(parnm); - printf("proctype %s, '%s %s' could be declared", - parnm->context?parnm->context->name:"", buf, parnm->name); - printf(" '%s %s'\n", buf2, parnm->name); - } +{ Lextok *n, *now, *v; int i, m; + int res = 0; char buf[16], buf2[16]; + + for (n = runstmnts; n; n = n->rgt) + { now = n->lft; + if (now->sym != parnm->context) + continue; + for (v = now->lft, i = 0; v; v = v->rgt, i++) + if (i == posno) + { m = v->lft->ntyp; + if (m == CONST) + { m = v->lft->val; + if (m != 0 && m != 1) + res |= 4; + if (m < 0 || m > 256) + res |= 8; + } else if (m == NAME) + { m = v->lft->sym->type; + if (m != BIT) + { res |= 4; + if (m != BYTE) + res |= 8; + } + } else + res |= (4|8); /* unknown */ + break; + } } + if (!(res&4) || !(res&8)) + { if (!(verbose&32)) return; + strcpy(buf2, (!(res&4))?"bit":"byte"); + sputtype(buf, parnm->type); + i = (int) strlen(buf); + while (i > 0 && buf[--i] == ' ') buf[i] = '\0'; + if (i == 0 || strcmp(buf, buf2) == 0) return; + prehint(parnm); + printf("proctype %s, '%s %s' could be declared", + parnm->context?parnm->context->name:"", buf, parnm->name); + printf(" '%s %s'\n", buf2, parnm->name); + } } void trackchanuse(Lextok *m, Lextok *w, int t) -{ Lextok *n = m; int cnt = 1; - while (n) - { if (n->lft - && n->lft->sym - && n->lft->sym->type == CHAN) - setaccess(n->lft->sym, w?w->sym:ZS, cnt, t); - n = n->rgt; cnt++; - } +{ Lextok *n = m; int cnt = 1; + while (n) + { if (n->lft + && n->lft->sym + && n->lft->sym->type == CHAN) + setaccess(n->lft->sym, w?w->sym:ZS, cnt, t); + n = n->rgt; cnt++; + } } void -setptype(Lextok *mtype_name, Lextok *n, int t, Lextok *vis) /* predefined types */ -{ int oln = lineno, cnt = 1; extern int Expand_Ok; - - while (n) - { if (n->sym->type && !(n->sym->hidden&32)) - { lineno = n->ln; Fname = n->fn; - fatal("redeclaration of '%s'", n->sym->name); - lineno = oln; - } - n->sym->type = (short) t; - - if (mtype_name && t != MTYPE) - { lineno = n->ln; Fname = n->fn; - fatal("missing semi-colon after '%s'?", - mtype_name->sym->name); - lineno = oln; - } - - if (mtype_name && n->sym->mtype_name - && strcmp(mtype_name->sym->name, n->sym->mtype_name->name) != 0) - { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but assigned type '%s'\n", - n->fn->name, n->ln, - n->sym->name, - mtype_name->sym->name, - n->sym->mtype_name->name); - non_fatal("type error", (char *) 0); - } - - n->sym->mtype_name = mtype_name?mtype_name->sym:0; /* if mtype, else 0 */ - - if (Expand_Ok) - { n->sym->hidden |= (4|8|16); /* formal par */ - if (t == CHAN) - setaccess(n->sym, ZS, cnt, 'F'); - } - - if (t == UNSIGNED) - { if (n->sym->nbits < 0 || n->sym->nbits >= 32) - fatal("(%s) has invalid width-field", n->sym->name); - if (n->sym->nbits == 0) - { n->sym->nbits = 16; - non_fatal("unsigned without width-field", 0); - } - } else if (n->sym->nbits > 0) - { non_fatal("(%s) only an unsigned can have width-field", - n->sym->name); - } - - if (vis) - { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) - { n->sym->hidden |= 1; - has_hidden++; - if (t == BIT) - fatal("bit variable (%s) cannot be hidden", - n->sym->name); - } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0) - { n->sym->hidden |= 2; - } else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0) - { n->sym->hidden |= 64; - } - } - - if (t == CHAN) - { n->sym->Nid = ++Nid_nr; - } else - { n->sym->Nid = 0; - if (n->sym->ini - && n->sym->ini->ntyp == CHAN) - { Fname = n->fn; - lineno = n->ln; - fatal("chan initializer for non-channel %s", - n->sym->name); - } } - - if (n->sym->nel <= 0) - { lineno = n->ln; Fname = n->fn; - non_fatal("bad array size for '%s'", n->sym->name); - lineno = oln; - } - - n = n->rgt; cnt++; - } +setptype(Lextok *mtype_name, Lextok *n, int t, Lextok *vis) /* predefined types */ +{ int oln = lineno, cnt = 1; extern int Expand_Ok; + + while (n) + { if (n->sym->type && !(n->sym->hidden&32)) + { lineno = n->ln; Fname = n->fn; + fatal("redeclaration of '%s'", n->sym->name); + lineno = oln; + } + n->sym->type = (short) t; + + if (mtype_name && t != MTYPE) + { lineno = n->ln; Fname = n->fn; + fatal("missing semi-colon after '%s'?", + mtype_name->sym->name); + lineno = oln; + } + + if (mtype_name && n->sym->mtype_name + && strcmp(mtype_name->sym->name, n->sym->mtype_name->name) != 0) + { fprintf(stderr, "spin: %s:%d, Error: '%s' is type '%s' but assigned type '%s'\n", + n->fn->name, n->ln, + n->sym->name, + mtype_name->sym->name, + n->sym->mtype_name->name); + non_fatal("type error", (char *) 0); + } + + n->sym->mtype_name = mtype_name?mtype_name->sym:0; /* if mtype, else 0 */ + + if (Expand_Ok) + { n->sym->hidden |= (4|8|16); /* formal par */ + if (t == CHAN) + setaccess(n->sym, ZS, cnt, 'F'); + } + + if (t == UNSIGNED) + { if (n->sym->nbits < 0 || n->sym->nbits >= 32) + fatal("(%s) has invalid width-field", n->sym->name); + if (n->sym->nbits == 0) + { n->sym->nbits = 16; + non_fatal("unsigned without width-field", 0); + } + } else if (n->sym->nbits > 0) + { non_fatal("(%s) only an unsigned can have width-field", + n->sym->name); + } + + if (vis) + { if (strncmp(vis->sym->name, ":hide:", (size_t) 6) == 0) + { n->sym->hidden |= 1; + has_hidden++; + if (t == BIT) + fatal("bit variable (%s) cannot be hidden", + n->sym->name); + } else if (strncmp(vis->sym->name, ":show:", (size_t) 6) == 0) + { n->sym->hidden |= 2; + } else if (strncmp(vis->sym->name, ":local:", (size_t) 7) == 0) + { n->sym->hidden |= 64; + } + } + + if (t == CHAN) + { n->sym->Nid = ++Nid_nr; + } else + { n->sym->Nid = 0; + if (n->sym->ini + && n->sym->ini->ntyp == CHAN) + { Fname = n->fn; + lineno = n->ln; + fatal("chan initializer for non-channel %s", + n->sym->name); + } } + + if (n->sym->nel <= 0) + { lineno = n->ln; Fname = n->fn; + non_fatal("bad array size for '%s'", n->sym->name); + lineno = oln; + } + + n = n->rgt; cnt++; + } } static void setonexu(Symbol *sp, int t) { - sp->xu |= t; - if (t == XR || t == XS) - { if (sp->xup[t-1] - && strcmp(sp->xup[t-1]->name, context->name)) - { printf("error: x[rs] claims from %s and %s\n", - sp->xup[t-1]->name, context->name); - non_fatal("conflicting claims on chan '%s'", - sp->name); - } - sp->xup[t-1] = context; - } + sp->xu |= t; + if (t == XR || t == XS) + { if (sp->xup[t-1] + && strcmp(sp->xup[t-1]->name, context->name)) + { printf("error: x[rs] claims from %s and %s\n", + sp->xup[t-1]->name, context->name); + non_fatal("conflicting claims on chan '%s'", + sp->name); + } + sp->xup[t-1] = context; + } } static void setallxu(Lextok *n, int t) -{ Lextok *fp, *tl; - - for (fp = n; fp; fp = fp->rgt) - for (tl = fp->lft; tl; tl = tl->rgt) - { if (tl->sym->type == STRUCT) - setallxu(tl->sym->Slst, t); - else if (tl->sym->type == CHAN) - setonexu(tl->sym, t); - } +{ Lextok *fp, *tl; + + for (fp = n; fp; fp = fp->rgt) + for (tl = fp->lft; tl; tl = tl->rgt) + { if (tl->sym->type == STRUCT) + setallxu(tl->sym->Slst, t); + else if (tl->sym->type == CHAN) + setonexu(tl->sym, t); + } } Lextok *Xu_List = (Lextok *) 0; void setxus(Lextok *p, int t) -{ Lextok *m, *n; - - has_xu = 1; - - if (m_loss && t == XS) - { printf("spin: %s:%d, warning, xs tag not compatible with -m (message loss)\n", - (p->fn != NULL) ? p->fn->name : "stdin", p->ln); - } - - if (!context) - { lineno = p->ln; - Fname = p->fn; - fatal("non-local x[rs] assertion", (char *)0); - } - for (m = p; m; m = m->rgt) - { Lextok *Xu_new = (Lextok *) emalloc(sizeof(Lextok)); - Xu_new->uiid = p->uiid; - Xu_new->val = t; - Xu_new->lft = m->lft; - Xu_new->sym = context; - Xu_new->rgt = Xu_List; - Xu_List = Xu_new; - - n = m->lft; - if (n->sym->type == STRUCT) - setallxu(n->sym->Slst, t); - else if (n->sym->type == CHAN) - setonexu(n->sym, t); - else - { int oln = lineno; - lineno = n->ln; Fname = n->fn; - non_fatal("xr or xs of non-chan '%s'", - n->sym->name); - lineno = oln; - } - } +{ Lextok *m, *n; + + has_xu = 1; + + if (m_loss && t == XS) + { printf("spin: %s:%d, warning, xs tag not compatible with -m (message loss)\n", + (p->fn != NULL) ? p->fn->name : "stdin", p->ln); + } + + if (!context) + { lineno = p->ln; + Fname = p->fn; + fatal("non-local x[rs] assertion", (char *)0); + } + for (m = p; m; m = m->rgt) + { Lextok *Xu_new = (Lextok *) emalloc(sizeof(Lextok)); + Xu_new->uiid = p->uiid; + Xu_new->val = t; + Xu_new->lft = m->lft; + Xu_new->sym = context; + Xu_new->rgt = Xu_List; + Xu_List = Xu_new; + + n = m->lft; + if (n->sym->type == STRUCT) + setallxu(n->sym->Slst, t); + else if (n->sym->type == CHAN) + setonexu(n->sym, t); + else + { int oln = lineno; + lineno = n->ln; Fname = n->fn; + non_fatal("xr or xs of non-chan '%s'", + n->sym->name); + lineno = oln; + } + } } Lextok ** find_mtype_list(const char *s) -{ Mtypes_t *lst; - - for (lst = Mtypes; lst; lst = lst->nxt) - { if (strcmp(lst->nm, s) == 0) - { return &(lst->mt); - } } - /* not found, create it */ - lst = (Mtypes_t *) emalloc(sizeof(Mtypes_t)); - lst->nm = (char *) emalloc(strlen(s)+1); - strcpy(lst->nm, s); - lst->nxt = Mtypes; - Mtypes = lst; - return &(lst->mt); +{ Mtypes_t *lst; + + for (lst = Mtypes; lst; lst = lst->nxt) + { if (strcmp(lst->nm, s) == 0) + { return &(lst->mt); + } } + /* not found, create it */ + lst = (Mtypes_t *) emalloc(sizeof(Mtypes_t)); + lst->nm = (char *) emalloc(strlen(s)+1); + strcpy(lst->nm, s); + lst->nxt = Mtypes; + Mtypes = lst; + return &(lst->mt); } void setmtype(Lextok *mtype_name, Lextok *m) -{ Lextok **mtl; /* mtype list */ - Lextok *n, *Mtype; - int cnt, oln = lineno; - char *s = "_unnamed_"; - - if (m) { lineno = m->ln; Fname = m->fn; } - - if (mtype_name && mtype_name->sym) - { s = mtype_name->sym->name; - } - - mtl = find_mtype_list(s); - Mtype = *mtl; - - if (!Mtype) - { *mtl = Mtype = m; - } else - { for (n = Mtype; n->rgt; n = n->rgt) - { ; - } - n->rgt = m; /* concatenate */ - } - - for (n = Mtype, cnt = 1; n; n = n->rgt, cnt++) /* syntax check */ - { if (!n->lft || !n->lft->sym - || n->lft->ntyp != NAME - || n->lft->lft) /* indexed variable */ - fatal("bad mtype definition", (char *)0); - /* label the name */ - if (n->lft->sym->type != MTYPE) - { n->lft->sym->hidden |= 128; /* is used */ - n->lft->sym->type = MTYPE; - n->lft->sym->ini = nn(ZN,CONST,ZN,ZN); - n->lft->sym->ini->val = cnt; - } else if (n->lft->sym->ini->val != cnt) - { non_fatal("name %s appears twice in mtype declaration", - n->lft->sym->name); - } } - - lineno = oln; - if (cnt > 256) - { fatal("too many mtype elements (>255)", (char *) 0); - } +{ Lextok **mtl; /* mtype list */ + Lextok *n, *Mtype; + int cnt, oln = lineno; + const char *s = "_unnamed_"; + + if (m) { lineno = m->ln; Fname = m->fn; } + + if (mtype_name && mtype_name->sym) + { s = mtype_name->sym->name; + } + + mtl = find_mtype_list(s); + Mtype = *mtl; + + if (!Mtype) + { *mtl = Mtype = m; + } else + { for (n = Mtype; n->rgt; n = n->rgt) + { ; + } + n->rgt = m; /* concatenate */ + } + + for (n = Mtype, cnt = 1; n; n = n->rgt, cnt++) /* syntax check */ + { if (!n->lft || !n->lft->sym + || n->lft->ntyp != NAME + || n->lft->lft) /* indexed variable */ + fatal("bad mtype definition", (char *)0); + /* label the name */ + if (n->lft->sym->type != MTYPE) + { n->lft->sym->hidden |= 128; /* is used */ + n->lft->sym->type = MTYPE; + n->lft->sym->ini = nn(ZN,CONST,ZN,ZN); + n->lft->sym->ini->val = cnt; + } else if (n->lft->sym->ini->val != cnt) + { non_fatal("name %s appears twice in mtype declaration", + n->lft->sym->name); + } } + + lineno = oln; + if (cnt > 256) + { fatal("too many mtype elements (>255)", (char *) 0); + } } char * which_mtype(const char *str) /* which mtype is str, 0 if not an mtype at all */ -{ Mtypes_t *lst; - Lextok *n; +{ Mtypes_t *lst; + Lextok *n; - for (lst = Mtypes; lst; lst = lst->nxt) - for (n = lst->mt; n; n = n->rgt) - { if (strcmp(str, n->lft->sym->name) == 0) - { return lst->nm; - } } + for (lst = Mtypes; lst; lst = lst->nxt) + for (n = lst->mt; n; n = n->rgt) + { if (strcmp(str, n->lft->sym->name) == 0) + { return lst->nm; + } } - return (char *) 0; + return (char *) 0; } char * which_mtype_val(const int v) /* which mtype is v, 0 if not an mtype at all */ -{ Mtypes_t *lst; - Lextok *n; - - for (lst = Mtypes; lst; lst = lst->nxt) - for (n = lst->mt; n; n = n->rgt) - { if (v == n->lft->sym->ini->val) - { return lst->nm; - } } - return (char *) 0; +{ Mtypes_t *lst; + Lextok *n; + + for (lst = Mtypes; lst; lst = lst->nxt) + for (n = lst->mt; n; n = n->rgt) + { if (v == n->lft->sym->ini->val) + { return lst->nm; + } } + return (char *) 0; } int -ismtype(char *str) /* name to number */ -{ Mtypes_t *lst; - Lextok *n; - int cnt; - - for (lst = Mtypes; lst; lst = lst->nxt) - { cnt = 1; - for (n = lst->mt; n; n = n->rgt) - { if (strcmp(str, n->lft->sym->name) == 0) - { return cnt; - } - cnt++; - } } - - return 0; +ismtype(char *str) /* name to number */ +{ Mtypes_t *lst; + Lextok *n; + int cnt; + + for (lst = Mtypes; lst; lst = lst->nxt) + { cnt = 1; + for (n = lst->mt; n; n = n->rgt) + { if (strcmp(str, n->lft->sym->name) == 0) + { return cnt; + } + cnt++; + } } + + return 0; } int sputtype(char *foo, int m) { - switch (m) { - case UNSIGNED: strcpy(foo, "unsigned "); break; - case BIT: strcpy(foo, "bit "); break; - case BYTE: strcpy(foo, "byte "); break; - case CHAN: strcpy(foo, "chan "); break; - case SHORT: strcpy(foo, "short "); break; - case INT: strcpy(foo, "int "); break; - case MTYPE: strcpy(foo, "mtype "); break; - case STRUCT: strcpy(foo, "struct"); break; - case PROCTYPE: strcpy(foo, "proctype"); break; - case LABEL: strcpy(foo, "label "); return 0; - default: strcpy(foo, "value "); return 0; - } - return 1; + switch (m) { + case UNSIGNED: strcpy(foo, "unsigned "); break; + case BIT: strcpy(foo, "bit "); break; + case BYTE: strcpy(foo, "byte "); break; + case CHAN: strcpy(foo, "chan "); break; + case SHORT: strcpy(foo, "short "); break; + case INT: strcpy(foo, "int "); break; + case MTYPE: strcpy(foo, "mtype "); break; + case STRUCT: strcpy(foo, "struct"); break; + case PROCTYPE: strcpy(foo, "proctype"); break; + case LABEL: strcpy(foo, "label "); return 0; + default: strcpy(foo, "value "); return 0; + } + return 1; } static int puttype(int m) -{ char buf[128]; +{ char buf[128]; - if (sputtype(buf, m)) - { printf("%s", buf); - return 1; - } - return 0; + if (sputtype(buf, m)) + { printf("%s", buf); + return 1; + } + return 0; } void symvar(Symbol *sp) -{ Lextok *m; - - if (!puttype(sp->type)) - return; - - printf("\t"); - if (sp->owner) printf("%s.", sp->owner->name); - printf("%s", sp->name); - if (sp->nel > 1 || sp->isarray == 1) printf("[%d]", sp->nel); - - if (sp->type == CHAN) - printf("\t%d", (sp->ini)?sp->ini->val:0); - else if (sp->type == STRUCT && sp->Snm != NULL) /* Frank Weil, 2.9.8 */ - printf("\t%s", sp->Snm->name); - else - printf("\t%d", eval(sp->ini)); - - if (sp->owner) - printf("\t<:struct-field:>"); - else - if (!sp->context) - printf("\t<:global:>"); - else - printf("\t<%s>", sp->context->name); - - if (sp->Nid < 0) /* formal parameter */ - printf("\t", -(sp->Nid)); - else if (sp->type == MTYPE) - printf("\t"); - else if (sp->isarray) - printf("\t"); - else - printf("\t"); - - if (sp->type == CHAN && sp->ini) - { int i; - for (m = sp->ini->rgt, i = 0; m; m = m->rgt) - i++; - printf("\t%d\t", i); - for (m = sp->ini->rgt; m; m = m->rgt) - { if (m->ntyp == STRUCT) - printf("struct %s", m->sym->name); - else - (void) puttype(m->ntyp); - if (m->rgt) printf("\t"); - } - } - - if (!old_scope_rules) - { printf("\t{scope %s}", sp->bscp); - } - - printf("\n"); +{ Lextok *m; + + if (!puttype(sp->type)) + return; + + printf("\t"); + if (sp->owner) printf("%s.", sp->owner->name); + printf("%s", sp->name); + if (sp->nel > 1 || sp->isarray == 1) printf("[%d]", sp->nel); + + if (sp->type == CHAN) + printf("\t%d", (sp->ini)?sp->ini->val:0); + else if (sp->type == STRUCT && sp->Snm != NULL) /* Frank Weil, 2.9.8 */ + printf("\t%s", sp->Snm->name); + else + printf("\t%d", eval(sp->ini)); + + if (sp->owner) + printf("\t<:struct-field:>"); + else + if (!sp->context) + printf("\t<:global:>"); + else + printf("\t<%s>", sp->context->name); + + if (sp->Nid < 0) /* formal parameter */ + printf("\t", -(sp->Nid)); + else if (sp->type == MTYPE) + printf("\t"); + else if (sp->isarray) + printf("\t"); + else + printf("\t"); + + if (sp->type == CHAN && sp->ini) + { int i; + for (m = sp->ini->rgt, i = 0; m; m = m->rgt) + i++; + printf("\t%d\t", i); + for (m = sp->ini->rgt; m; m = m->rgt) + { if (m->ntyp == STRUCT) + printf("struct %s", m->sym->name); + else + (void) puttype(m->ntyp); + if (m->rgt) printf("\t"); + } + } + + if (!old_scope_rules) + { printf("\t{scope %s}", sp->bscp); + } + + printf("\n"); } void symdump(void) -{ Ordered *walk; +{ Ordered *walk; - for (walk = all_names; walk; walk = walk->next) - symvar(walk->entry); + for (walk = all_names; walk; walk = walk->next) + symvar(walk->entry); } void chname(Symbol *sp) -{ printf("chan "); - if (sp->context) printf("%s-", sp->context->name); - if (sp->owner) printf("%s.", sp->owner->name); - printf("%s", sp->name); - if (sp->nel > 1 || sp->isarray == 1) printf("[%d]", sp->nel); - printf("\t"); +{ printf("chan "); + if (sp->context) printf("%s-", sp->context->name); + if (sp->owner) printf("%s.", sp->owner->name); + printf("%s", sp->name); + if (sp->nel > 1 || sp->isarray == 1) printf("[%d]", sp->nel); + printf("\t"); } static struct X_lkp { - int typ; char *nm; + int typ; const char *nm; } xx[] = { - { 'A', "exported as run parameter" }, - { 'F', "imported as proctype parameter" }, - { 'L', "used as l-value in asgnmnt" }, - { 'V', "used as r-value in asgnmnt" }, - { 'P', "polled in receive stmnt" }, - { 'R', "used as parameter in receive stmnt" }, - { 'S', "used as parameter in send stmnt" }, - { 'r', "received from" }, - { 's', "sent to" }, + { 'A', "exported as run parameter" }, + { 'F', "imported as proctype parameter" }, + { 'L', "used as l-value in asgnmnt" }, + { 'V', "used as r-value in asgnmnt" }, + { 'P', "polled in receive stmnt" }, + { 'R', "used as parameter in receive stmnt" }, + { 'S', "used as parameter in send stmnt" }, + { 'r', "received from" }, + { 's', "sent to" }, }; static void chan_check(Symbol *sp) -{ Access *a; int i, b=0, d; +{ Access *a; int i, b=0, d; - if (verbose&1) goto report; /* -C -g */ + if (verbose&1) goto report; /* -C -g */ - for (a = sp->access; a; a = a->lnk) - if (a->typ == 'r') - b |= 1; - else if (a->typ == 's') - b |= 2; - if (b == 3 || (sp->hidden&16)) /* balanced or formal par */ - return; + for (a = sp->access; a; a = a->lnk) + if (a->typ == 'r') + b |= 1; + else if (a->typ == 's') + b |= 2; + if (b == 3 || (sp->hidden&16)) /* balanced or formal par */ + return; report: - chname(sp); - for (i = d = 0; i < (int) (sizeof(xx)/sizeof(struct X_lkp)); i++) - { b = 0; - for (a = sp->access; a; a = a->lnk) - { if (a->typ == xx[i].typ) - { b++; - } } - if (b == 0) - { continue; - } - d++; - printf("\n\t%s by: ", xx[i].nm); - for (a = sp->access; a; a = a->lnk) - if (a->typ == xx[i].typ) - { printf("%s", a->who->name); - if (a->what) printf(" to %s", a->what->name); - if (a->cnt) printf(" par %d", a->cnt); - if (--b > 0) printf(", "); - } - } - printf("%s\n", (!d)?"\n\tnever used under this name":""); + chname(sp); + for (i = d = 0; i < (int) (sizeof(xx)/sizeof(struct X_lkp)); i++) + { b = 0; + for (a = sp->access; a; a = a->lnk) + { if (a->typ == xx[i].typ) + { b++; + } } + if (b == 0) + { continue; + } + d++; + printf("\n\t%s by: ", xx[i].nm); + for (a = sp->access; a; a = a->lnk) + if (a->typ == xx[i].typ) + { printf("%s", a->who->name); + if (a->what) printf(" to %s", a->what->name); + if (a->cnt) printf(" par %d", a->cnt); + if (--b > 0) printf(", "); + } + } + printf("%s\n", (!d)?"\n\tnever used under this name":""); } void chanaccess(void) -{ Ordered *walk; - char buf[128]; - extern int Caccess, separate; - extern short has_code; - - for (walk = all_names; walk; walk = walk->next) - { if (!walk->entry->owner) - switch (walk->entry->type) { - case CHAN: - if (Caccess) chan_check(walk->entry); - break; - case MTYPE: - case BIT: - case BYTE: - case SHORT: - case INT: - case UNSIGNED: - if ((walk->entry->hidden&128)) /* was: 32 */ - continue; - - if (!separate - && !walk->entry->context - && !has_code - && deadvar) - walk->entry->hidden |= 1; /* auto-hide */ - - if (!(verbose&32) || has_code) continue; - - printf("spin: %s:0, warning, ", Fname->name); - sputtype(buf, walk->entry->type); - if (walk->entry->context) - printf("proctype %s", - walk->entry->context->name); - else - printf("global"); - printf(", '%s%s' variable is never used (other than in print stmnts)\n", - buf, walk->entry->name); - } } +{ Ordered *walk; + char buf[128]; + extern int Caccess, separate; + extern short has_code; + + for (walk = all_names; walk; walk = walk->next) + { if (!walk->entry->owner) + switch (walk->entry->type) { + case CHAN: + if (Caccess) chan_check(walk->entry); + break; + case MTYPE: + case BIT: + case BYTE: + case SHORT: + case INT: + case UNSIGNED: + if ((walk->entry->hidden&128)) /* was: 32 */ + continue; + + if (!separate + && !walk->entry->context + && !has_code + && deadvar) + walk->entry->hidden |= 1; /* auto-hide */ + + if (!(verbose&32) || has_code) continue; + + printf("spin: %s:0, warning, ", Fname->name); + sputtype(buf, walk->entry->type); + if (walk->entry->context) + printf("proctype %s", + walk->entry->context->name); + else + printf("global"); + printf(", '%s%s' variable is never used (other than in print stmnts)\n", + buf, walk->entry->name); + } } } diff --git a/Src/tl.h b/Src/tl.h index 756bbd7..936ed12 100644 --- a/Src/tl.h +++ b/Src/tl.h @@ -12,126 +12,132 @@ #ifndef TLH #define TLH +#include "get_strdup.h" /* include this first for strdup & getline */ + #include #include +#include /* for exit() */ typedef struct Symbol { - char *name; - struct Symbol *next; /* linked list, symbol table */ + char *name; + struct Symbol *next; /* linked list, symbol table */ } Symbol; typedef struct Node { - short ntyp; /* node type */ - struct Symbol *sym; - struct Node *lft; /* tree */ - struct Node *rgt; /* tree */ - struct Node *nxt; /* if linked list */ + short ntyp; /* node type */ + struct Symbol *sym; + struct Node *lft; /* tree */ + struct Node *rgt; /* tree */ + struct Node *nxt; /* if linked list */ } Node; typedef struct Graph { - Symbol *name; - Symbol *incoming; - Symbol *outgoing; - Symbol *oldstring; - Symbol *nxtstring; - Node *New; - Node *Old; - Node *Other; - Node *Next; - unsigned char isred[64], isgrn[64]; - unsigned char redcnt, grncnt; - unsigned char reachable; - struct Graph *nxt; + Symbol *name; + Symbol *incoming; + Symbol *outgoing; + Symbol *oldstring; + Symbol *nxtstring; + Node *New; + Node *Old; + Node *Other; + Node *Next; + unsigned char isred[64], isgrn[64]; + unsigned char redcnt, grncnt; + unsigned char reachable; + struct Graph *nxt; } Graph; typedef struct Mapping { - char *from; - Graph *to; - struct Mapping *nxt; + char *from; + Graph *to; + struct Mapping *nxt; } Mapping; enum { - ALWAYS=257, - AND, /* 258 */ - EQUIV, /* 259 */ - EVENTUALLY, /* 260 */ - FALSE, /* 261 */ - IMPLIES, /* 262 */ - NOT, /* 263 */ - OR, /* 264 */ - PREDICATE, /* 265 */ - TRUE, /* 266 */ - U_OPER, /* 267 */ - V_OPER /* 268 */ + ALWAYS=257, + AND, /* 258 */ + EQUIV, /* 259 */ + EVENTUALLY, /* 260 */ + FALSE, /* 261 */ + IMPLIES, /* 262 */ + NOT, /* 263 */ + OR, /* 264 */ + PREDICATE, /* 265 */ + TRUE, /* 266 */ + U_OPER, /* 267 */ + V_OPER /* 268 */ #ifdef NXT - , NEXT /* 269 */ + , NEXT /* 269 */ #endif - , CEXPR /* 270 */ + , CEXPR /* 270 */ }; -Node *Canonical(Node *); -Node *canonical(Node *); -Node *cached(Node *); -Node *dupnode(Node *); -Node *getnode(Node *); -Node *in_cache(Node *); -Node *push_negation(Node *); -Node *right_linked(Node *); -Node *tl_nn(int, Node *, Node *); - -Symbol *tl_lookup(char *); -Symbol *getsym(Symbol *); -Symbol *DoDump(Node *); - -extern char *emalloc(size_t); /* in main.c */ - -extern unsigned int hash(const char *); /* in sym.c */ - -int anywhere(int, Node *, Node *); -int dump_cond(Node *, Node *, int); -int isalnum_(int); /* in spinlex.c */ -int isequal(Node *, Node *); -int tl_Getchar(void); - -void *tl_emalloc(int); -void *tl_erealloc(void*, int, int); -void a_stats(void); -void addtrans(Graph *, char *, Node *, char *); -void cache_stats(void); -void dump(Node *); -void exit(int); -void Fatal(char *, char *); -void fatal(char *, char *); -void fsm_print(void); -void ini_buchi(void); -void ini_cache(void); -void ini_rewrt(void); -void ini_trans(void); -void releasenode(int, Node *); -void tfree(void *); -void tl_explain(int); -void tl_UnGetchar(void); -void tl_parse(void); -void tl_yyerror(char *); -void trans(Node *); - -#define ZN (Node *)0 -#define ZS (Symbol *)0 -#define Nhash 255 /* must match size in spin.h */ -#define True tl_nn(TRUE, ZN, ZN) -#define False tl_nn(FALSE, ZN, ZN) -#define Not(a) push_negation(tl_nn(NOT, a, ZN)) -#define rewrite(n) canonical(right_linked(n)) - -typedef Node *Nodeptr; -#define YYSTYPE Nodeptr - -#define Debug(x) { if (tl_verbose) printf(x); } -#define Debug2(x,y) { if (tl_verbose) printf(x,y); } -#define Dump(x) { if (tl_verbose) dump(x); } -#define Explain(x) { if (tl_verbose) tl_explain(x); } - -#define Assert(x, y) { if (!(x)) { tl_explain(y); \ - Fatal(": assertion failed\n",(char *)0); } } +Node *Canonical(Node *); +Node *canonical(Node *); +Node *cached(Node *); +Node *dupnode(Node *); +Node *getnode(Node *); +Node *in_cache(Node *); +Node *push_negation(Node *); +Node *right_linked(Node *); +Node *tl_nn(int, Node *, Node *); + +Symbol *tl_lookup(const char *); +Symbol *getsym(Symbol *); +Symbol *DoDump(Node *); + +extern char *emalloc(size_t); /* in main.c */ + +extern unsigned int hash(const char *); /* in sym.c */ + +int anywhere(int, Node *, Node *); +int dump_cond(Node *, Node *, int); +int isalnum_(int); /* in spinlex.c */ +int isequal(Node *, Node *); +int tl_Getchar(void); + +void *tl_emalloc(int); +void *tl_erealloc(void*, int, int); +void a_stats(void); +void addtrans(Graph *, const char *, Node *, const char *); +void cache_stats(void); +void dump(Node *); +__attribute__ ((noreturn)) +void exit(int); +__attribute__ ((noreturn)) +void Fatal(const char *, const char *); +__attribute__ ((noreturn)) +void fatal(const char *, const char *); +void fsm_print(void); +void ini_buchi(void); +void ini_cache(void); +void ini_rewrt(void); +void ini_trans(void); +void releasenode(int, Node *); +void tfree(void *); +void tl_explain(int); +void tl_UnGetchar(void); +void tl_parse(void); +__attribute__ ((noreturn)) void tl_yyerror(const char *); +void trans(Node *); + +#define ZN (Node *)0 +#define ZS (Symbol *)0 +#define Nhash 255 /* must match size in spin.h */ +#define True tl_nn(TRUE, ZN, ZN) +#define False tl_nn(FALSE, ZN, ZN) +#define Not(a) push_negation(tl_nn(NOT, a, ZN)) +#define rewrite(n) canonical(right_linked(n)) + +typedef Node *Nodeptr; +#define YYSTYPE Nodeptr + +#define Debug(x) { if (tl_verbose) printf(x); } +#define Debug2(x,y) { if (tl_verbose) printf(x,y); } +#define Dump(x) { if (tl_verbose) dump(x); } +#define Explain(x) { if (tl_verbose) tl_explain(x); } + +#define Assert(x, y) { if (!(x)) { tl_explain(y); \ + Fatal(": assertion failed\n",(char *)0); } } #endif diff --git a/Src/tl_buchi.c b/Src/tl_buchi.c index 94f1019..91b09e8 100644 --- a/Src/tl_buchi.c +++ b/Src/tl_buchi.c @@ -15,23 +15,23 @@ extern int tl_verbose, tl_clutter, Total, Max_Red; extern char *claim_name; extern void put_uform(void); -FILE *tl_out; /* if standalone: = stdout; */ +FILE *tl_out; /* if standalone: = stdout; */ typedef struct Transition { - Symbol *name; - Node *cond; - int redundant, merged, marked; - struct Transition *nxt; + Symbol *name; + Node *cond; + int redundant, merged, marked; + struct Transition *nxt; } Transition; typedef struct State { - Symbol *name; - Transition *trans; - Graph *colors; - unsigned char redundant; - unsigned char accepting; - unsigned char reachable; - struct State *nxt; + Symbol *name; + Transition *trans; + Graph *colors; + unsigned char redundant; + unsigned char accepting; + unsigned char reachable; + struct State *nxt; } State; static State *never = (State *) 0; @@ -40,337 +40,337 @@ static int hitsall; void ini_buchi(void) { - never = (State *) 0; - hitsall = 0; + never = (State *) 0; + hitsall = 0; } static int sametrans(Transition *s, Transition *t) { - if (strcmp(s->name->name, t->name->name) != 0) - return 0; - return isequal(s->cond, t->cond); + if (strcmp(s->name->name, t->name->name) != 0) + return 0; + return isequal(s->cond, t->cond); } static Node * Prune(Node *p) { - if (p) - switch (p->ntyp) { - case PREDICATE: - case NOT: - case FALSE: - case TRUE: + if (p) + switch (p->ntyp) { + case PREDICATE: + case NOT: + case FALSE: + case TRUE: #ifdef NXT - case NEXT: + case NEXT: #endif - case CEXPR: - return p; - case OR: - p->lft = Prune(p->lft); - if (!p->lft) - { releasenode(1, p->rgt); - return ZN; - } - p->rgt = Prune(p->rgt); - if (!p->rgt) - { releasenode(1, p->lft); - return ZN; - } - return p; - case AND: - p->lft = Prune(p->lft); - if (!p->lft) - return Prune(p->rgt); - p->rgt = Prune(p->rgt); - if (!p->rgt) - return p->lft; - return p; - } - releasenode(1, p); - return ZN; + case CEXPR: + return p; + case OR: + p->lft = Prune(p->lft); + if (!p->lft) + { releasenode(1, p->rgt); + return ZN; + } + p->rgt = Prune(p->rgt); + if (!p->rgt) + { releasenode(1, p->lft); + return ZN; + } + return p; + case AND: + p->lft = Prune(p->lft); + if (!p->lft) + return Prune(p->rgt); + p->rgt = Prune(p->rgt); + if (!p->rgt) + return p->lft; + return p; + } + releasenode(1, p); + return ZN; } static State * -findstate(char *nm) -{ State *b; - for (b = never; b; b = b->nxt) - if (!strcmp(b->name->name, nm)) - return b; - if (strcmp(nm, "accept_all")) - { if (strncmp(nm, "accept", 6)) - { int i; char altnm[64]; - for (i = 0; i < 64; i++) - if (nm[i] == '_') - break; - if (i >= 64) - Fatal("name too long %s", nm); - sprintf(altnm, "accept%s", &nm[i]); - return findstate(altnm); - } - /* Fatal("buchi: no state %s", nm); */ - } - return (State *) 0; +findstate(const char *nm) +{ State *b; + for (b = never; b; b = b->nxt) + if (!strcmp(b->name->name, nm)) + return b; + if (strcmp(nm, "accept_all")) + { if (strncmp(nm, "accept", 6)) + { int i; char altnm[64]; + for (i = 0; i < 64; i++) + if (nm[i] == '_') + break; + if (i >= 64) + Fatal("name too long %s", nm); + sprintf(altnm, "accept%s", &nm[i]); + return findstate(altnm); + } + /* Fatal("buchi: no state %s", nm); */ + } + return (State *) 0; } static void Dfs(State *b) -{ Transition *t; - - if (!b || b->reachable) return; - b->reachable = 1; - - if (b->redundant) - printf("/* redundant state %s */\n", - b->name->name); - for (t = b->trans; t; t = t->nxt) - { if (!t->redundant) - { Dfs(findstate(t->name->name)); - if (!hitsall - && strcmp(t->name->name, "accept_all") == 0) - hitsall = 1; - } - } +{ Transition *t; + + if (!b || b->reachable) return; + b->reachable = 1; + + if (b->redundant) + printf("/* redundant state %s */\n", + b->name->name); + for (t = b->trans; t; t = t->nxt) + { if (!t->redundant) + { Dfs(findstate(t->name->name)); + if (!hitsall + && strcmp(t->name->name, "accept_all") == 0) + hitsall = 1; + } + } } void retarget(char *from, char *to) -{ State *b; - Transition *t; - Symbol *To = tl_lookup(to); - - if (tl_verbose) printf("replace %s with %s\n", from, to); - - for (b = never; b; b = b->nxt) - { if (!strcmp(b->name->name, from)) - b->redundant = 1; - else - for (t = b->trans; t; t = t->nxt) - { if (!strcmp(t->name->name, from)) - t->name = To; - } } +{ State *b; + Transition *t; + Symbol *To = tl_lookup(to); + + if (tl_verbose) printf("replace %s with %s\n", from, to); + + for (b = never; b; b = b->nxt) + { if (!strcmp(b->name->name, from)) + b->redundant = 1; + else + for (t = b->trans; t; t = t->nxt) + { if (!strcmp(t->name->name, from)) + t->name = To; + } } } #ifdef NXT static Node * nonxt(Node *n) { - switch (n->ntyp) { - case U_OPER: - case V_OPER: - case NEXT: - return ZN; - case OR: - n->lft = nonxt(n->lft); - n->rgt = nonxt(n->rgt); - if (!n->lft || !n->rgt) - return True; - return n; - case AND: - n->lft = nonxt(n->lft); - n->rgt = nonxt(n->rgt); - if (!n->lft) - { if (!n->rgt) - n = ZN; - else - n = n->rgt; - } else if (!n->rgt) - n = n->lft; - return n; - } - return n; + switch (n->ntyp) { + case U_OPER: + case V_OPER: + case NEXT: + return ZN; + case OR: + n->lft = nonxt(n->lft); + n->rgt = nonxt(n->rgt); + if (!n->lft || !n->rgt) + return True; + return n; + case AND: + n->lft = nonxt(n->lft); + n->rgt = nonxt(n->rgt); + if (!n->lft) + { if (!n->rgt) + n = ZN; + else + n = n->rgt; + } else if (!n->rgt) + n = n->lft; + return n; + } + return n; } #endif static Node * combination(Node *s, Node *t) -{ Node *nc; +{ Node *nc; #ifdef NXT - Node *a = nonxt(s); - Node *b = nonxt(t); - - if (tl_verbose) - { printf("\tnonxtA: "); dump(a); - printf("\n\tnonxtB: "); dump(b); - printf("\n"); - } - /* if there's only a X(f), its equivalent to true */ - if (!a || !b) - nc = True; - else - nc = tl_nn(OR, a, b); + Node *a = nonxt(s); + Node *b = nonxt(t); + + if (tl_verbose) + { printf("\tnonxtA: "); dump(a); + printf("\n\tnonxtB: "); dump(b); + printf("\n"); + } + /* if there's only a X(f), its equivalent to true */ + if (!a || !b) + nc = True; + else + nc = tl_nn(OR, a, b); #else - nc = tl_nn(OR, s, t); + nc = tl_nn(OR, s, t); #endif - if (tl_verbose) - { printf("\tcombo: "); dump(nc); - printf("\n"); - } - return nc; + if (tl_verbose) + { printf("\tcombo: "); dump(nc); + printf("\n"); + } + return nc; } Node * unclutter(Node *n, char *snm) -{ Node *t, *s, *v, *u; - Symbol *w; - - /* check only simple cases like !q && q */ - for (t = n; t; t = t->rgt) - { if (t->rgt) - { if (t->ntyp != AND || !t->lft) - return n; - if (t->lft->ntyp != PREDICATE +{ Node *t, *s, *v, *u; + Symbol *w; + + /* check only simple cases like !q && q */ + for (t = n; t; t = t->rgt) + { if (t->rgt) + { if (t->ntyp != AND || !t->lft) + return n; + if (t->lft->ntyp != PREDICATE #ifdef NXT - && t->lft->ntyp != NEXT + && t->lft->ntyp != NEXT #endif - && t->lft->ntyp != NOT) - return n; - } else - { if (t->ntyp != PREDICATE + && t->lft->ntyp != NOT) + return n; + } else + { if (t->ntyp != PREDICATE #ifdef NXT - && t->ntyp != NEXT + && t->ntyp != NEXT #endif - && t->ntyp != NOT) - return n; - } - } - - for (t = n; t; t = t->rgt) - { if (t->rgt) - v = t->lft; - else - v = t; - if (v->ntyp == NOT - && v->lft->ntyp == PREDICATE) - { w = v->lft->sym; - for (s = n; s; s = s->rgt) - { if (s == t) continue; - if (s->rgt) - u = s->lft; - else - u = s; - if (u->ntyp == PREDICATE - && strcmp(u->sym->name, w->name) == 0) - { if (tl_verbose) - { printf("BINGO %s:\t", snm); - dump(n); - printf("\n"); - } - return False; - } - } - } } - return n; + && t->ntyp != NOT) + return n; + } + } + + for (t = n; t; t = t->rgt) + { if (t->rgt) + v = t->lft; + else + v = t; + if (v->ntyp == NOT + && v->lft->ntyp == PREDICATE) + { w = v->lft->sym; + for (s = n; s; s = s->rgt) + { if (s == t) continue; + if (s->rgt) + u = s->lft; + else + u = s; + if (u->ntyp == PREDICATE + && strcmp(u->sym->name, w->name) == 0) + { if (tl_verbose) + { printf("BINGO %s:\t", snm); + dump(n); + printf("\n"); + } + return False; + } + } + } } + return n; } static void clutter(void) -{ State *p; - Transition *s; - - for (p = never; p; p = p->nxt) - for (s = p->trans; s; s = s->nxt) - { s->cond = unclutter(s->cond, p->name->name); - if (s->cond - && s->cond->ntyp == FALSE) - { if (s != p->trans - || s->nxt) - s->redundant = 1; - } - } +{ State *p; + Transition *s; + + for (p = never; p; p = p->nxt) + for (s = p->trans; s; s = s->nxt) + { s->cond = unclutter(s->cond, p->name->name); + if (s->cond + && s->cond->ntyp == FALSE) + { if (s != p->trans + || s->nxt) + s->redundant = 1; + } + } } static void showtrans(State *a) -{ Transition *s; +{ Transition *s; - for (s = a->trans; s; s = s->nxt) - { printf("%s ", s->name?s->name->name:"-"); - dump(s->cond); - printf(" %d %d %d\n", s->redundant, s->merged, s->marked); - } + for (s = a->trans; s; s = s->nxt) + { printf("%s ", s->name?s->name->name:"-"); + dump(s->cond); + printf(" %d %d %d\n", s->redundant, s->merged, s->marked); + } } static int mergetrans(void) -{ State *b; - Transition *s, *t; - Node *nc; int cnt = 0; - - for (b = never; b; b = b->nxt) - { if (!b->reachable) continue; - - for (s = b->trans; s; s = s->nxt) - { if (s->redundant) continue; - - for (t = s->nxt; t; t = t->nxt) - if (!t->redundant - && !strcmp(s->name->name, t->name->name)) - { if (tl_verbose) - { printf("===\nstate %s, trans to %s redundant\n", - b->name->name, s->name->name); - showtrans(b); - printf(" conditions "); - dump(s->cond); printf(" <-> "); - dump(t->cond); printf("\n"); - } - - if (!s->cond) /* same as T */ - { releasenode(1, t->cond); /* T or t */ - nc = True; - } else if (!t->cond) - { releasenode(1, s->cond); - nc = True; - } else - { nc = combination(s->cond, t->cond); - } - t->cond = rewrite(nc); - t->merged = 1; - s->redundant = 1; - cnt++; - break; - } } } - return cnt; +{ State *b; + Transition *s, *t; + Node *nc; int cnt = 0; + + for (b = never; b; b = b->nxt) + { if (!b->reachable) continue; + + for (s = b->trans; s; s = s->nxt) + { if (s->redundant) continue; + + for (t = s->nxt; t; t = t->nxt) + if (!t->redundant + && !strcmp(s->name->name, t->name->name)) + { if (tl_verbose) + { printf("===\nstate %s, trans to %s redundant\n", + b->name->name, s->name->name); + showtrans(b); + printf(" conditions "); + dump(s->cond); printf(" <-> "); + dump(t->cond); printf("\n"); + } + + if (!s->cond) /* same as T */ + { releasenode(1, t->cond); /* T or t */ + nc = True; + } else if (!t->cond) + { releasenode(1, s->cond); + nc = True; + } else + { nc = combination(s->cond, t->cond); + } + t->cond = rewrite(nc); + t->merged = 1; + s->redundant = 1; + cnt++; + break; + } } } + return cnt; } static int all_trans_match(State *a, State *b) -{ Transition *s, *t; - int found, result = 0; - - if (a->accepting != b->accepting) - goto done; - - for (s = a->trans; s; s = s->nxt) - { if (s->redundant) continue; - found = 0; - for (t = b->trans; t; t = t->nxt) - { if (t->redundant) continue; - if (sametrans(s, t)) - { found = 1; - t->marked = 1; - break; - } } - if (!found) - goto done; - } - for (s = b->trans; s; s = s->nxt) - { if (s->redundant || s->marked) continue; - found = 0; - for (t = a->trans; t; t = t->nxt) - { if (t->redundant) continue; - if (sametrans(s, t)) - { found = 1; - break; - } } - if (!found) - goto done; - } - result = 1; +{ Transition *s, *t; + int found, result = 0; + + if (a->accepting != b->accepting) + goto done; + + for (s = a->trans; s; s = s->nxt) + { if (s->redundant) continue; + found = 0; + for (t = b->trans; t; t = t->nxt) + { if (t->redundant) continue; + if (sametrans(s, t)) + { found = 1; + t->marked = 1; + break; + } } + if (!found) + goto done; + } + for (s = b->trans; s; s = s->nxt) + { if (s->redundant || s->marked) continue; + found = 0; + for (t = a->trans; t; t = t->nxt) + { if (t->redundant) continue; + if (sametrans(s, t)) + { found = 1; + break; + } } + if (!found) + goto done; + } + result = 1; done: - for (s = b->trans; s; s = s->nxt) - s->marked = 0; - return result; + for (s = b->trans; s; s = s->nxt) + s->marked = 0; + return result; } #ifndef NO_OPT @@ -380,167 +380,167 @@ all_trans_match(State *a, State *b) #ifdef BUCKY static int all_bucky(State *a, State *b) -{ Transition *s, *t; - int found, result = 0; - - for (s = a->trans; s; s = s->nxt) - { if (s->redundant) continue; - found = 0; - for (t = b->trans; t; t = t->nxt) - { if (t->redundant) continue; - - if (isequal(s->cond, t->cond)) - { if (strcmp(s->name->name, b->name->name) == 0 - && strcmp(t->name->name, a->name->name) == 0) - { found = 1; /* they point to each other */ - t->marked = 1; - break; - } - if (strcmp(s->name->name, t->name->name) == 0 - && strcmp(s->name->name, "accept_all") == 0) - { found = 1; - t->marked = 1; - break; - /* same exit from which there is no return */ - } - } - } - if (!found) - goto done; - } - for (s = b->trans; s; s = s->nxt) - { if (s->redundant || s->marked) continue; - found = 0; - for (t = a->trans; t; t = t->nxt) - { if (t->redundant) continue; - - if (isequal(s->cond, t->cond)) - { if (strcmp(s->name->name, a->name->name) == 0 - && strcmp(t->name->name, b->name->name) == 0) - { found = 1; - t->marked = 1; - break; - } - if (strcmp(s->name->name, t->name->name) == 0 - && strcmp(s->name->name, "accept_all") == 0) - { found = 1; - t->marked = 1; - break; - } - } - } - if (!found) - goto done; - } - result = 1; +{ Transition *s, *t; + int found, result = 0; + + for (s = a->trans; s; s = s->nxt) + { if (s->redundant) continue; + found = 0; + for (t = b->trans; t; t = t->nxt) + { if (t->redundant) continue; + + if (isequal(s->cond, t->cond)) + { if (strcmp(s->name->name, b->name->name) == 0 + && strcmp(t->name->name, a->name->name) == 0) + { found = 1; /* they point to each other */ + t->marked = 1; + break; + } + if (strcmp(s->name->name, t->name->name) == 0 + && strcmp(s->name->name, "accept_all") == 0) + { found = 1; + t->marked = 1; + break; + /* same exit from which there is no return */ + } + } + } + if (!found) + goto done; + } + for (s = b->trans; s; s = s->nxt) + { if (s->redundant || s->marked) continue; + found = 0; + for (t = a->trans; t; t = t->nxt) + { if (t->redundant) continue; + + if (isequal(s->cond, t->cond)) + { if (strcmp(s->name->name, a->name->name) == 0 + && strcmp(t->name->name, b->name->name) == 0) + { found = 1; + t->marked = 1; + break; + } + if (strcmp(s->name->name, t->name->name) == 0 + && strcmp(s->name->name, "accept_all") == 0) + { found = 1; + t->marked = 1; + break; + } + } + } + if (!found) + goto done; + } + result = 1; done: - for (s = b->trans; s; s = s->nxt) - s->marked = 0; - return result; + for (s = b->trans; s; s = s->nxt) + s->marked = 0; + return result; } static int buckyballs(void) -{ State *a, *b, *c, *d; - int m, cnt=0; - - do { - m = 0; cnt++; - for (a = never; a; a = a->nxt) - { if (!a->reachable) continue; - - if (a->redundant) continue; - - for (b = a->nxt; b; b = b->nxt) - { if (!b->reachable) continue; - - if (b->redundant) continue; - - if (all_bucky(a, b)) - { m++; - if (tl_verbose) - { printf("%s bucky match %s\n", - a->name->name, b->name->name); - } - - if (a->accepting && !b->accepting) - { if (strcmp(b->name->name, "T0_init") == 0) - { c = a; d = b; - b->accepting = 1; - } else - { c = b; d = a; - } - } else - { c = a; d = b; - } - - retarget(c->name->name, d->name->name); - if (!strncmp(c->name->name, "accept", 6) - && Max_Red == 0) - { char buf[64]; - sprintf(buf, "T0%s", &(c->name->name[6])); - retarget(buf, d->name->name); - } - break; - } - } } - } while (m && cnt < 10); - return cnt-1; +{ State *a, *b, *c, *d; + int m, cnt=0; + + do { + m = 0; cnt++; + for (a = never; a; a = a->nxt) + { if (!a->reachable) continue; + + if (a->redundant) continue; + + for (b = a->nxt; b; b = b->nxt) + { if (!b->reachable) continue; + + if (b->redundant) continue; + + if (all_bucky(a, b)) + { m++; + if (tl_verbose) + { printf("%s bucky match %s\n", + a->name->name, b->name->name); + } + + if (a->accepting && !b->accepting) + { if (strcmp(b->name->name, "T0_init") == 0) + { c = a; d = b; + b->accepting = 1; + } else + { c = b; d = a; + } + } else + { c = a; d = b; + } + + retarget(c->name->name, d->name->name); + if (!strncmp(c->name->name, "accept", 6) + && Max_Red == 0) + { char buf[64]; + sprintf(buf, "T0%s", &(c->name->name[6])); + retarget(buf, d->name->name); + } + break; + } + } } + } while (m && cnt < 10); + return cnt-1; } #endif static int mergestates(int v) -{ State *a, *b; - int m, cnt=0; - - if (tl_verbose) - return 0; - - do { - m = 0; cnt++; - for (a = never; a; a = a->nxt) - { if (v && !a->reachable) continue; - - if (a->redundant) continue; /* 3.3.10 */ - - for (b = a->nxt; b; b = b->nxt) - { if (v && !b->reachable) continue; - - if (b->redundant) continue; /* 3.3.10 */ - - if (all_trans_match(a, b)) - { m++; - if (tl_verbose) - { printf("%d: state %s equals state %s\n", - cnt, a->name->name, b->name->name); - showtrans(a); - printf("==\n"); - showtrans(b); - } - retarget(a->name->name, b->name->name); - if (!strncmp(a->name->name, "accept", 6) - && Max_Red == 0) - { char buf[64]; - sprintf(buf, "T0%s", &(a->name->name[6])); - retarget(buf, b->name->name); - } - break; - } +{ State *a, *b; + int m, cnt=0; + + if (tl_verbose) + return 0; + + do { + m = 0; cnt++; + for (a = never; a; a = a->nxt) + { if (v && !a->reachable) continue; + + if (a->redundant) continue; /* 3.3.10 */ + + for (b = a->nxt; b; b = b->nxt) + { if (v && !b->reachable) continue; + + if (b->redundant) continue; /* 3.3.10 */ + + if (all_trans_match(a, b)) + { m++; + if (tl_verbose) + { printf("%d: state %s equals state %s\n", + cnt, a->name->name, b->name->name); + showtrans(a); + printf("==\n"); + showtrans(b); + } + retarget(a->name->name, b->name->name); + if (!strncmp(a->name->name, "accept", 6) + && Max_Red == 0) + { char buf[64]; + sprintf(buf, "T0%s", &(a->name->name[6])); + retarget(buf, b->name->name); + } + break; + } #if 0 - else if (tl_verbose) - { printf("\n%d: state %s differs from state %s [%d,%d]\n", - cnt, a->name->name, b->name->name, - a->accepting, b->accepting); - showtrans(a); - printf("==\n"); - showtrans(b); - printf("\n"); - } + else if (tl_verbose) + { printf("\n%d: state %s differs from state %s [%d,%d]\n", + cnt, a->name->name, b->name->name, + a->accepting, b->accepting); + showtrans(a); + printf("==\n"); + showtrans(b); + printf("\n"); + } #endif - } } - } while (m && cnt < 10); - return cnt-1; + } } + } while (m && cnt < 10); + return cnt-1; } static int tcnt; @@ -548,137 +548,137 @@ static int tcnt; static void rev_trans(Transition *t) /* print transitions in reverse order... */ { - if (!t) return; - rev_trans(t->nxt); - - if (t->redundant && !tl_verbose) return; - - if (strcmp(t->name->name, "accept_all") == 0) /* 6.2.4 */ - { /* not d_step because there may be remote refs */ - fprintf(tl_out, "\t:: atomic { ("); - if (dump_cond(t->cond, t->cond, 1)) - fprintf(tl_out, "1"); - fprintf(tl_out, ") -> assert(!("); - if (dump_cond(t->cond, t->cond, 1)) - fprintf(tl_out, "1"); - fprintf(tl_out, ")) }\n"); - } else - { fprintf(tl_out, "\t:: ("); - if (dump_cond(t->cond, t->cond, 1)) - fprintf(tl_out, "1"); - fprintf(tl_out, ") -> goto %s\n", t->name->name); - } - tcnt++; + if (!t) return; + rev_trans(t->nxt); + + if (t->redundant && !tl_verbose) return; + + if (strcmp(t->name->name, "accept_all") == 0) /* 6.2.4 */ + { /* not d_step because there may be remote refs */ + fprintf(tl_out, "\t:: atomic { ("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ") -> assert(!("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ")) }\n"); + } else + { fprintf(tl_out, "\t:: ("); + if (dump_cond(t->cond, t->cond, 1)) + fprintf(tl_out, "1"); + fprintf(tl_out, ") -> goto %s\n", t->name->name); + } + tcnt++; } static void printstate(State *b) { - if (!b || (!tl_verbose && !b->reachable)) return; - - b->reachable = 0; /* print only once */ - fprintf(tl_out, "%s:\n", b->name->name); - - if (tl_verbose) - { fprintf(tl_out, " /* "); - dump(b->colors->Other); - fprintf(tl_out, " */\n"); - } - - if (strncmp(b->name->name, "accept", 6) == 0 - && Max_Red == 0) - fprintf(tl_out, "T0%s:\n", &(b->name->name[6])); - - fprintf(tl_out, "\tdo\n"); - tcnt = 0; - rev_trans(b->trans); - if (!tcnt) fprintf(tl_out, "\t:: false\n"); - fprintf(tl_out, "\tod;\n"); - Total++; + if (!b || (!tl_verbose && !b->reachable)) return; + + b->reachable = 0; /* print only once */ + fprintf(tl_out, "%s:\n", b->name->name); + + if (tl_verbose) + { fprintf(tl_out, " /* "); + dump(b->colors->Other); + fprintf(tl_out, " */\n"); + } + + if (strncmp(b->name->name, "accept", 6) == 0 + && Max_Red == 0) + fprintf(tl_out, "T0%s:\n", &(b->name->name[6])); + + fprintf(tl_out, "\tdo\n"); + tcnt = 0; + rev_trans(b->trans); + if (!tcnt) fprintf(tl_out, "\t:: false\n"); + fprintf(tl_out, "\tod;\n"); + Total++; } void -addtrans(Graph *col, char *from, Node *op, char *to) -{ State *b; - Transition *t; - - t = (Transition *) tl_emalloc(sizeof(Transition)); - t->name = tl_lookup(to); - t->cond = Prune(dupnode(op)); - - if (tl_verbose) - { printf("\n%s <<\t", from); dump(op); - printf("\n\t"); dump(t->cond); - printf(">> %s\n", t->name->name); - } - if (t->cond) t->cond = rewrite(t->cond); - - for (b = never; b; b = b->nxt) - if (!strcmp(b->name->name, from)) - { t->nxt = b->trans; - b->trans = t; - return; - } - b = (State *) tl_emalloc(sizeof(State)); - b->name = tl_lookup(from); - b->colors = col; - b->trans = t; - if (!strncmp(from, "accept", 6)) - b->accepting = 1; - b->nxt = never; - never = b; +addtrans(Graph *col, const char *from, Node *op, const char *to) +{ State *b; + Transition *t; + + t = (Transition *) tl_emalloc(sizeof(Transition)); + t->name = tl_lookup(to); + t->cond = Prune(dupnode(op)); + + if (tl_verbose) + { printf("\n%s <<\t", from); dump(op); + printf("\n\t"); dump(t->cond); + printf(">> %s\n", t->name->name); + } + if (t->cond) t->cond = rewrite(t->cond); + + for (b = never; b; b = b->nxt) + if (!strcmp(b->name->name, from)) + { t->nxt = b->trans; + b->trans = t; + return; + } + b = (State *) tl_emalloc(sizeof(State)); + b->name = tl_lookup(from); + b->colors = col; + b->trans = t; + if (!strncmp(from, "accept", 6)) + b->accepting = 1; + b->nxt = never; + never = b; } static void clr_reach(void) -{ State *p; - for (p = never; p; p = p->nxt) - p->reachable = 0; - hitsall = 0; +{ State *p; + for (p = never; p; p = p->nxt) + p->reachable = 0; + hitsall = 0; } void fsm_print(void) -{ State *b; int cnt1, cnt2=0; +{ State *b; int cnt1, cnt2=0; - if (tl_clutter) clutter(); + if (tl_clutter) clutter(); - b = findstate("T0_init"); - if (b && (Max_Red == 0)) - b->accepting = 1; + b = findstate("T0_init"); + if (b && (Max_Red == 0)) + b->accepting = 1; - mergestates(0); - b = findstate("T0_init"); + mergestates(0); + b = findstate("T0_init"); - fprintf(tl_out, "never %s { /* ", claim_name?claim_name:""); - put_uform(); - fprintf(tl_out, " */\n"); + fprintf(tl_out, "never %s { /* ", claim_name?claim_name:""); + put_uform(); + fprintf(tl_out, " */\n"); - do { - clr_reach(); - Dfs(b); - cnt1 = mergetrans(); - cnt2 = mergestates(1); - if (tl_verbose) - printf("/* >>%d,%d<< */\n", cnt1, cnt2); - } while (cnt2 > 0); + do { + clr_reach(); + Dfs(b); + cnt1 = mergetrans(); + cnt2 = mergestates(1); + if (tl_verbose) + printf("/* >>%d,%d<< */\n", cnt1, cnt2); + } while (cnt2 > 0); #ifdef BUCKY - buckyballs(); - clr_reach(); - Dfs(b); + buckyballs(); + clr_reach(); + Dfs(b); #endif - if (b && b->accepting) - fprintf(tl_out, "accept_init:\n"); - - if (!b && !never) - { fprintf(tl_out, " 0 /* false */;\n"); - } else - { printstate(b); /* init state must be first */ - for (b = never; b; b = b->nxt) - printstate(b); - } - if (hitsall) - fprintf(tl_out, "accept_all:\n skip\n"); - fprintf(tl_out, "}\n"); + if (b && b->accepting) + fprintf(tl_out, "accept_init:\n"); + + if (!b && !never) + { fprintf(tl_out, " 0 /* false */;\n"); + } else + { printstate(b); /* init state must be first */ + for (b = never; b; b = b->nxt) + printstate(b); + } + if (hitsall) + fprintf(tl_out, "accept_all:\n skip\n"); + fprintf(tl_out, "}\n"); } diff --git a/Src/tl_cache.c b/Src/tl_cache.c index 1cf0273..f3a0ec6 100644 --- a/Src/tl_cache.c +++ b/Src/tl_cache.c @@ -24,7 +24,7 @@ static unsigned long Caches, CacheHits; static int ismatch(Node *, Node *); static int sameform(Node *, Node *); -extern void fatal(char *, char *); +extern void fatal(const char *, const char *); void ini_cache(void) diff --git a/Src/tl_lex.c b/Src/tl_lex.c index 7b08e1f..e108c9b 100644 --- a/Src/tl_lex.c +++ b/Src/tl_lex.c @@ -13,254 +13,254 @@ #include #include "tl.h" -static Symbol *symtab[Nhash+1]; -static int tl_lex(void); +static Symbol *symtab[Nhash+1]; +static int tl_lex(void); extern int tl_peek(int); -extern YYSTYPE tl_yylval; -extern char yytext[]; +extern YYSTYPE tl_yylval; +extern char yytext[]; #define Token(y) tl_yylval = tl_nn(y,ZN,ZN); return y static void tl_getword(int first, int (*tst)(int)) -{ int i=0; int c; +{ int i=0; int c; - yytext[i++] = (char ) first; + yytext[i++] = (char ) first; - c = tl_Getchar(); - while (c != -1 && tst(c)) - { yytext[i++] = (char) c; - c = tl_Getchar(); - } + c = tl_Getchar(); + while (c != -1 && tst(c)) + { yytext[i++] = (char) c; + c = tl_Getchar(); + } -/* while (tst(c = tl_Getchar())) - * yytext[i++] = c; +/* while (tst(c = tl_Getchar())) + * yytext[i++] = c; */ - yytext[i] = '\0'; - tl_UnGetchar(); + yytext[i] = '\0'; + tl_UnGetchar(); } static int tl_follow(int tok, int ifyes, int ifno) -{ int c; - char buf[32]; - extern int tl_yychar; +{ int c; + char buf[32]; + extern int tl_yychar; - if ((c = tl_Getchar()) == tok) - return ifyes; - tl_UnGetchar(); - tl_yychar = c; - sprintf(buf, "expected '%c'", tok); - tl_yyerror(buf); /* no return from here */ - return ifno; + if ((c = tl_Getchar()) == tok) + return ifyes; + tl_UnGetchar(); + tl_yychar = c; + sprintf(buf, "expected '%c'", tok); + tl_yyerror(buf); /* no return from here */ + return ifno; } int tl_yylex(void) -{ int c = tl_lex(); +{ int c = tl_lex(); #if 0 - printf("c = %c (%d)\n", c, c); + printf("c = %c (%d)\n", c, c); #endif - return c; + return c; } static int is_predicate(int z) -{ char c, c_prev = z; - char want = (z == '{') ? '}' : ')'; - int i = 0, j, nesting = 0; - char peek_buf[512]; +{ char c, c_prev = z; + char want = (z == '{') ? '}' : ')'; + int i = 0, j, nesting = 0; + char peek_buf[512]; - c = tl_peek(i++); /* look ahead without changing position */ - while ((c != want || nesting > 0) && c != -1 && i < 2047) - { if (islower((int) c) || c == '_') - { peek_buf[0] = c; - j = 1; - while (j < (int) sizeof(peek_buf) - && (isalnum((int)(c = tl_peek(i))) || c == '_')) - { peek_buf[j++] = c; - i++; - } - c = 0; /* make sure we don't match on z or want on the peekahead */ - if (j >= (int) sizeof(peek_buf)) - { peek_buf[j-1] = '\0'; - fatal("name '%s' in ltl formula too long", peek_buf); - } - peek_buf[j] = '\0'; - if (strcmp(peek_buf, "always") == 0 - || strcmp(peek_buf, "equivalent") == 0 - || strcmp(peek_buf, "eventually") == 0 - || strcmp(peek_buf, "until") == 0 - || strcmp(peek_buf, "next") == 0 - || strcmp(peek_buf, "c_expr") == 0) - { return 0; - } - } else - { int c_nxt = tl_peek(i); - if (((c == 'U' || c == 'V' || c == 'X') - && !isalnum_(c_prev) - && (c_nxt == -1 || !isalnum_(c_nxt))) - || (c == '<' && c_nxt == '>') - || (c == '<' && c_nxt == '-') - || (c == '-' && c_nxt == '>') - || (c == '[' && c_nxt == ']')) - { return 0; - } } + c = tl_peek(i++); /* look ahead without changing position */ + while ((c != want || nesting > 0) && c != -1 && i < 2047) + { if (islower((int) c) || c == '_') + { peek_buf[0] = c; + j = 1; + while (j < (int) sizeof(peek_buf) + && (isalnum((int)(c = tl_peek(i))) || c == '_')) + { peek_buf[j++] = c; + i++; + } + c = 0; /* make sure we don't match on z or want on the peekahead */ + if (j >= (int) sizeof(peek_buf)) + { peek_buf[j-1] = '\0'; + fatal("name '%s' in ltl formula too long", peek_buf); + } + peek_buf[j] = '\0'; + if (strcmp(peek_buf, "always") == 0 + || strcmp(peek_buf, "equivalent") == 0 + || strcmp(peek_buf, "eventually") == 0 + || strcmp(peek_buf, "until") == 0 + || strcmp(peek_buf, "next") == 0 + || strcmp(peek_buf, "c_expr") == 0) + { return 0; + } + } else + { int c_nxt = tl_peek(i); + if (((c == 'U' || c == 'V' || c == 'X') + && !isalnum_(c_prev) + && (c_nxt == -1 || !isalnum_(c_nxt))) + || (c == '<' && c_nxt == '>') + || (c == '<' && c_nxt == '-') + || (c == '-' && c_nxt == '>') + || (c == '[' && c_nxt == ']')) + { return 0; + } } - if (c == z) - { nesting++; - } - if (c == want) - { nesting--; - } - c_prev = c; - c = tl_peek(i++); - } - return 1; + if (c == z) + { nesting++; + } + if (c == want) + { nesting--; + } + c_prev = c; + c = tl_peek(i++); + } + return 1; } static void read_upto_closing(int z) -{ char c, want = (z == '{') ? '}' : ')'; - int i = 0, nesting = 0; +{ char c, want = (z == '{') ? '}' : ')'; + int i = 0, nesting = 0; - c = tl_Getchar(); - while ((c != want || nesting > 0) && c != -1 && i < 2047) /* yytext is 2048 */ - { yytext[i++] = c; - if (c == z) - { nesting++; - } - if (c == want) - { nesting--; - } - c = tl_Getchar(); - } - yytext[i] = '\0'; + c = tl_Getchar(); + while ((c != want || nesting > 0) && c != -1 && i < 2047) /* yytext is 2048 */ + { yytext[i++] = c; + if (c == z) + { nesting++; + } + if (c == want) + { nesting--; + } + c = tl_Getchar(); + } + yytext[i] = '\0'; } static int tl_lex(void) -{ int c; +{ int c; - do { - c = tl_Getchar(); - yytext[0] = (char ) c; - yytext[1] = '\0'; + do { + c = tl_Getchar(); + yytext[0] = (char ) c; + yytext[1] = '\0'; - if (c <= 0) - { Token(';'); - } + if (c <= 0) + { Token(';'); + } - } while (c == ' '); /* '\t' is removed in tl_main.c */ + } while (c == ' '); /* '\t' is removed in tl_main.c */ - if (c == '{' || c == '(') /* new 6.0.0 */ - { if (is_predicate(c)) - { read_upto_closing(c); - tl_yylval = tl_nn(PREDICATE,ZN,ZN); - if (!tl_yylval) - { fatal("unexpected error 4", (char *) 0); - } - tl_yylval->sym = tl_lookup(yytext); - return PREDICATE; - } } + if (c == '{' || c == '(') /* new 6.0.0 */ + { if (is_predicate(c)) + { read_upto_closing(c); + tl_yylval = tl_nn(PREDICATE,ZN,ZN); + if (!tl_yylval) + { fatal("unexpected error 4", (char *) 0); + } + tl_yylval->sym = tl_lookup(yytext); + return PREDICATE; + } } - if (c == '}') - { tl_yyerror("unexpected '}'"); - } - if (islower(c)) - { tl_getword(c, isalnum_); - if (strcmp("true", yytext) == 0) - { Token(TRUE); - } - if (strcmp("false", yytext) == 0) - { Token(FALSE); - } - if (strcmp("always", yytext) == 0) - { Token(ALWAYS); - } - if (strcmp("eventually", yytext) == 0) - { Token(EVENTUALLY); - } - if (strcmp("until", yytext) == 0) - { Token(U_OPER); - } + if (c == '}') + { tl_yyerror("unexpected '}'"); + } + if (islower(c)) + { tl_getword(c, isalnum_); + if (strcmp("true", yytext) == 0) + { Token(TRUE); + } + if (strcmp("false", yytext) == 0) + { Token(FALSE); + } + if (strcmp("always", yytext) == 0) + { Token(ALWAYS); + } + if (strcmp("eventually", yytext) == 0) + { Token(EVENTUALLY); + } + if (strcmp("until", yytext) == 0) + { Token(U_OPER); + } #ifdef NXT - if (strcmp("next", yytext) == 0) - { Token(NEXT); - } + if (strcmp("next", yytext) == 0) + { Token(NEXT); + } #endif - if (strcmp("c_expr", yytext) == 0) - { Token(CEXPR); - } - if (strcmp("not", yytext) == 0) - { Token(NOT); - } - tl_yylval = tl_nn(PREDICATE,ZN,ZN); - if (!tl_yylval) - { fatal("unexpected error 5", (char *) 0); - } - tl_yylval->sym = tl_lookup(yytext); - return PREDICATE; - } + if (strcmp("c_expr", yytext) == 0) + { Token(CEXPR); + } + if (strcmp("not", yytext) == 0) + { Token(NOT); + } + tl_yylval = tl_nn(PREDICATE,ZN,ZN); + if (!tl_yylval) + { fatal("unexpected error 5", (char *) 0); + } + tl_yylval->sym = tl_lookup(yytext); + return PREDICATE; + } - if (c == '<') - { c = tl_Getchar(); - if (c == '>') - { Token(EVENTUALLY); - } - if (c != '-') - { tl_UnGetchar(); - tl_yyerror("expected '<>' or '<->'"); - } - c = tl_Getchar(); - if (c == '>') - { Token(EQUIV); - } - tl_UnGetchar(); - tl_yyerror("expected '<->'"); - } + if (c == '<') + { c = tl_Getchar(); + if (c == '>') + { Token(EVENTUALLY); + } + if (c != '-') + { tl_UnGetchar(); + tl_yyerror("expected '<>' or '<->'"); + } + c = tl_Getchar(); + if (c == '>') + { Token(EQUIV); + } + tl_UnGetchar(); + tl_yyerror("expected '<->'"); + } - switch (c) { - case '/' : c = tl_follow('\\', AND, '/'); break; - case '\\': c = tl_follow('/', OR, '\\'); break; - case '&' : c = tl_follow('&', AND, '&'); break; - case '|' : c = tl_follow('|', OR, '|'); break; - case '[' : c = tl_follow(']', ALWAYS, '['); break; - case '-' : c = tl_follow('>', IMPLIES, '-'); break; - case '!' : c = NOT; break; - case 'U' : c = U_OPER; break; - case 'V' : c = V_OPER; break; + switch (c) { + case '/' : c = tl_follow('\\', AND, '/'); break; + case '\\': c = tl_follow('/', OR, '\\'); break; + case '&' : c = tl_follow('&', AND, '&'); break; + case '|' : c = tl_follow('|', OR, '|'); break; + case '[' : c = tl_follow(']', ALWAYS, '['); break; + case '-' : c = tl_follow('>', IMPLIES, '-'); break; + case '!' : c = NOT; break; + case 'U' : c = U_OPER; break; + case 'V' : c = V_OPER; break; #ifdef NXT - case 'X' : c = NEXT; break; + case 'X' : c = NEXT; break; #endif - default : break; - } - Token(c); + default : break; + } + Token(c); } Symbol * -tl_lookup(char *s) -{ Symbol *sp; - unsigned int h = hash(s); +tl_lookup(const char *s) +{ Symbol *sp; + unsigned int h = hash(s); - for (sp = symtab[h]; sp; sp = sp->next) - if (strcmp(sp->name, s) == 0) - return sp; + for (sp = symtab[h]; sp; sp = sp->next) + if (strcmp(sp->name, s) == 0) + return sp; - sp = (Symbol *) tl_emalloc(sizeof(Symbol)); - sp->name = (char *) tl_emalloc((int) strlen(s) + 1); - strcpy(sp->name, s); - sp->next = symtab[h]; - symtab[h] = sp; + sp = (Symbol *) tl_emalloc(sizeof(Symbol)); + sp->name = (char *) tl_emalloc((int) strlen(s) + 1); + strcpy(sp->name, s); + sp->next = symtab[h]; + symtab[h] = sp; - return sp; + return sp; } Symbol * getsym(Symbol *s) -{ Symbol *n = (Symbol *) tl_emalloc(sizeof(Symbol)); +{ Symbol *n = (Symbol *) tl_emalloc(sizeof(Symbol)); - n->name = s->name; - return n; + n->name = s->name; + return n; } diff --git a/Src/tl_main.c b/Src/tl_main.c index 511b0b9..f186428 100644 --- a/Src/tl_main.c +++ b/Src/tl_main.c @@ -11,20 +11,20 @@ #include "tl.h" -extern FILE *tl_out; +extern FILE *tl_out; -int newstates = 0; /* debugging only */ -int tl_errs = 0; -int tl_verbose = 0; -int tl_terse = 0; -int tl_clutter = 0; -int state_cnt = 0; +int newstates = 0; /* debugging only */ +int tl_errs = 0; +int tl_verbose = 0; +int tl_terse = 0; +int tl_clutter = 0; +int state_cnt = 0; -unsigned long All_Mem = 0; -char *claim_name; +unsigned long All_Mem = 0; +char *claim_name; -static char *uform; -static int hasuform=0, cnt=0; +static char *uform; +static int hasuform=0, cnt=0; extern void cache_stats(void); extern void a_stats(void); @@ -32,261 +32,263 @@ extern void a_stats(void); int tl_Getchar(void) { - if (cnt < hasuform) - return uform[cnt++]; - cnt++; - return -1; + if (cnt < hasuform) + return uform[cnt++]; + cnt++; + return -1; } int tl_peek(int n) { - if (cnt+n < hasuform) - { return uform[cnt+n]; - } - return -1; + if (cnt+n < hasuform) + { return uform[cnt+n]; + } + return -1; } void tl_balanced(void) -{ int i; - int k = 0; +{ int i; + int k = 0; - for (i = 0; i < hasuform; i++) - { if (uform[i] == '(') - { if (i > 0 - && ((uform[i-1] == '"' && uform[i+1] == '"') - || (uform[i-1] == '\'' && uform[i+1] == '\''))) - { continue; - } - k++; - } else if (uform[i] == ')') - { if (i > 0 - && ((uform[i-1] == '"' && uform[i+1] == '"') - || (uform[i-1] == '\'' && uform[i+1] == '\''))) - { continue; - } - k--; - } } + for (i = 0; i < hasuform; i++) + { if (uform[i] == '(') + { if (i > 0 + && ((uform[i-1] == '"' && uform[i+1] == '"') + || (uform[i-1] == '\'' && uform[i+1] == '\''))) + { continue; + } + k++; + } else if (uform[i] == ')') + { if (i > 0 + && ((uform[i-1] == '"' && uform[i+1] == '"') + || (uform[i-1] == '\'' && uform[i+1] == '\''))) + { continue; + } + k--; + } } - if (k != 0) - { tl_errs++; - tl_yyerror("parentheses not balanced"); - } + if (k != 0) + { tl_errs++; + tl_yyerror("parentheses not balanced"); + } } void put_uform(void) { - fprintf(tl_out, "%s", uform); + fprintf(tl_out, "%s", uform); } void tl_UnGetchar(void) { - if (cnt > 0) cnt--; + if (cnt > 0) cnt--; } static void tl_stats(void) -{ extern int Stack_mx; - printf("total memory used: %9ld\n", All_Mem); - printf("largest stack sze: %9d\n", Stack_mx); - cache_stats(); - a_stats(); +{ extern int Stack_mx; + printf("total memory used: %9ld\n", All_Mem); + printf("largest stack sze: %9d\n", Stack_mx); + cache_stats(); + a_stats(); } int tl_main(int argc, char *argv[]) -{ int i; - extern int xspin, s_trail; +{ int i; + extern int xspin, s_trail; - tl_verbose = 0; /* was: tl_verbose = verbose; */ - if (xspin && s_trail) - { tl_clutter = 1; - /* generating claims for a replay should - be done the same as when generating the - pan.c that produced the error-trail */ - } else - { tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */ - } - newstates = 0; - state_cnt = 0; - tl_errs = 0; - tl_terse = 0; - All_Mem = 0; - hasuform=0; - cnt=0; - claim_name = (char *) 0; + tl_verbose = 0; /* was: tl_verbose = verbose; */ + if (xspin && s_trail) + { tl_clutter = 1; + /* generating claims for a replay should + be done the same as when generating the + pan.c that produced the error-trail */ + } else + { tl_clutter = 1-xspin; /* use -X -f to turn off uncluttering */ + } + newstates = 0; + state_cnt = 0; + tl_errs = 0; + tl_terse = 0; + All_Mem = 0; + hasuform=0; + cnt=0; + claim_name = (char *) 0; - ini_buchi(); - ini_cache(); - ini_rewrt(); - ini_trans(); + ini_buchi(); + ini_cache(); + ini_rewrt(); + ini_trans(); - while (argc > 1 && argv[1][0] == '-') - { - switch (argv[1][1]) { - case 'd': newstates = 1; /* debugging mode */ - break; - case 'f': argc--; argv++; - for (i = 0; argv[1][i]; i++) - { if (argv[1][i] == '\t' - || argv[1][i] == '\n') - argv[1][i] = ' '; - } - size_t len = strlen(argv[1]); - uform = tl_emalloc(len + 1); - strcpy(uform, argv[1]); - hasuform = (int) len; - break; - case 'v': tl_verbose++; - break; - case 'n': tl_terse = 1; - break; - case 'c': argc--; argv++; - claim_name = (char *) emalloc(strlen(argv[1])+1); - strcpy(claim_name, argv[1]); - break; - default : printf("spin -f: saw '-%c'\n", argv[1][1]); - goto nogood; - } - argc--; argv++; - } - if (hasuform == 0) - { -nogood: printf("usage:\tspin [-v] [-n] -f formula\n"); - printf(" -v verbose translation\n"); - printf(" -n normalize tl formula and exit\n"); - exit(1); - } - tl_balanced(); + while (argc > 1 && argv[1][0] == '-') + { + switch (argv[1][1]) { + case 'd': newstates = 1; /* debugging mode */ + break; + case 'f': argc--; argv++; + for (i = 0; argv[1][i]; i++) + { if (argv[1][i] == '\t' + || argv[1][i] == '\n') + argv[1][i] = ' '; + } + { + size_t len = strlen(argv[1]); + uform = (char *)tl_emalloc(len + 1); + strcpy(uform, argv[1]); + hasuform = (int) len; + } + break; + case 'v': tl_verbose++; + break; + case 'n': tl_terse = 1; + break; + case 'c': argc--; argv++; + claim_name = (char *) emalloc(strlen(argv[1])+1); + strcpy(claim_name, argv[1]); + break; + default : printf("spin -f: saw '-%c'\n", argv[1][1]); + goto nogood; + } + argc--; argv++; + } + if (hasuform == 0) + { +nogood: printf("usage:\tspin [-v] [-n] -f formula\n"); + printf(" -v verbose translation\n"); + printf(" -n normalize tl formula and exit\n"); + exit(1); + } + tl_balanced(); - if (tl_errs == 0) - tl_parse(); + if (tl_errs == 0) + tl_parse(); - if (tl_verbose) tl_stats(); - return tl_errs; + if (tl_verbose) tl_stats(); + return tl_errs; } -#define Binop(a) \ - fprintf(tl_out, "("); \ - dump(n->lft); \ - fprintf(tl_out, a); \ - dump(n->rgt); \ - fprintf(tl_out, ")") +#define Binop(a) \ + fprintf(tl_out, "("); \ + dump(n->lft); \ + fprintf(tl_out, a); \ + dump(n->rgt); \ + fprintf(tl_out, ")") void dump(Node *n) { - if (!n) return; + if (!n) return; - switch(n->ntyp) { - case OR: Binop(" || "); break; - case AND: Binop(" && "); break; - case U_OPER: Binop(" U "); break; - case V_OPER: Binop(" V "); break; + switch(n->ntyp) { + case OR: Binop(" || "); break; + case AND: Binop(" && "); break; + case U_OPER: Binop(" U "); break; + case V_OPER: Binop(" V "); break; #ifdef NXT - case NEXT: - fprintf(tl_out, "X"); - fprintf(tl_out, " ("); - dump(n->lft); - fprintf(tl_out, ")"); - break; + case NEXT: + fprintf(tl_out, "X"); + fprintf(tl_out, " ("); + dump(n->lft); + fprintf(tl_out, ")"); + break; #endif - case NOT: - fprintf(tl_out, "!"); - fprintf(tl_out, " ("); - dump(n->lft); - fprintf(tl_out, ")"); - break; - case FALSE: - fprintf(tl_out, "false"); - break; - case TRUE: - fprintf(tl_out, "true"); - break; - case PREDICATE: - fprintf(tl_out, "(%s)", n->sym->name); - break; - case CEXPR: - fprintf(tl_out, "c_expr"); - fprintf(tl_out, " {"); - dump(n->lft); - fprintf(tl_out, "}"); - break; - case -1: - fprintf(tl_out, " D "); - break; - default: - printf("Unknown token: "); - tl_explain(n->ntyp); - break; - } + case NOT: + fprintf(tl_out, "!"); + fprintf(tl_out, " ("); + dump(n->lft); + fprintf(tl_out, ")"); + break; + case FALSE: + fprintf(tl_out, "false"); + break; + case TRUE: + fprintf(tl_out, "true"); + break; + case PREDICATE: + fprintf(tl_out, "(%s)", n->sym->name); + break; + case CEXPR: + fprintf(tl_out, "c_expr"); + fprintf(tl_out, " {"); + dump(n->lft); + fprintf(tl_out, "}"); + break; + case -1: + fprintf(tl_out, " D "); + break; + default: + printf("Unknown token: "); + tl_explain(n->ntyp); + break; + } } void tl_explain(int n) { - switch (n) { - case ALWAYS: printf("[]"); break; - case EVENTUALLY: printf("<>"); break; - case IMPLIES: printf("->"); break; - case EQUIV: printf("<->"); break; - case PREDICATE: printf("predicate"); break; - case OR: printf("||"); break; - case AND: printf("&&"); break; - case NOT: printf("!"); break; - case U_OPER: printf("U"); break; - case V_OPER: printf("V"); break; + switch (n) { + case ALWAYS: printf("[]"); break; + case EVENTUALLY: printf("<>"); break; + case IMPLIES: printf("->"); break; + case EQUIV: printf("<->"); break; + case PREDICATE: printf("predicate"); break; + case OR: printf("||"); break; + case AND: printf("&&"); break; + case NOT: printf("!"); break; + case U_OPER: printf("U"); break; + case V_OPER: printf("V"); break; #ifdef NXT - case NEXT: printf("X"); break; + case NEXT: printf("X"); break; #endif - case CEXPR: printf("c_expr"); break; - case TRUE: printf("true"); break; - case FALSE: printf("false"); break; - case ';': printf("end of formula"); break; - default: printf("%c", n); break; - } + case CEXPR: printf("c_expr"); break; + case TRUE: printf("true"); break; + case FALSE: printf("false"); break; + case ';': printf("end of formula"); break; + default: printf("%c", n); break; + } } static void -tl_non_fatal(char *s1, char *s2) -{ extern int tl_yychar; - int i; +tl_non_fatal(const char *s1, const char *s2) +{ extern int tl_yychar; + int i; - printf("tl_spin: "); + printf("tl_spin: "); #if 1 - printf(s1, s2); /* prevent a compiler warning */ + printf(s1, s2); /* prevent a compiler warning */ #else - if (s2) - printf(s1, s2); - else - printf(s1); + if (s2) + printf(s1, s2); + else + printf(s1); #endif - if (tl_yychar != -1 && tl_yychar != 0) - { printf(", saw '"); - tl_explain(tl_yychar); - printf("'"); - } - printf("\ntl_spin: %s\n---------", uform); - for (i = 0; i < cnt; i++) - printf("-"); - printf("^\n"); - fflush(stdout); - tl_errs++; + if (tl_yychar != -1 && tl_yychar != 0) + { printf(", saw '"); + tl_explain(tl_yychar); + printf("'"); + } + printf("\ntl_spin: %s\n---------", uform); + for (i = 0; i < cnt; i++) + printf("-"); + printf("^\n"); + fflush(stdout); + tl_errs++; } -void -tl_yyerror(char *s1) +__attribute__ ((noreturn)) void +tl_yyerror(const char *s1) { - Fatal(s1, (char *) 0); + Fatal(s1, (char *) 0); } -void -Fatal(char *s1, char *s2) +__attribute__ ((noreturn)) void +Fatal(const char *s1, const char *s2) { - tl_non_fatal(s1, s2); - /* tl_stats(); */ - exit(1); + tl_non_fatal(s1, s2); + /* tl_stats(); */ + exit(1); } diff --git a/Src/tl_mem.c b/Src/tl_mem.c index 9cd36c3..8c7ad54 100644 --- a/Src/tl_mem.c +++ b/Src/tl_mem.c @@ -12,123 +12,123 @@ #include "tl.h" #if 1 -#define log(e, u, d) event[e][(int) u] += (long) d; +#define log(e, u, d) event[e][(int) u] += (long) d; #else #define log(e, u, d) #endif -#define A_LARGE 80 -#define A_USER 0x55000000 -#define NOTOOBIG 32768 +#define A_LARGE 80 +#define A_USER 0x55000000 +#define NOTOOBIG 32768 -#define POOL 0 -#define ALLOC 1 -#define FREE 2 -#define NREVENT 3 +#define POOL 0 +#define ALLOC 1 +#define FREE 2 +#define NREVENT 3 -extern unsigned long All_Mem; -extern int tl_verbose; +extern unsigned long All_Mem; +extern int tl_verbose; union M { - long size; - union M *link; + long size; + union M *link; }; static union M *freelist[A_LARGE]; -static long req[A_LARGE]; -static long event[NREVENT][A_LARGE]; +static long req[A_LARGE]; +static long event[NREVENT][A_LARGE]; void * tl_emalloc(int U) -{ union M *m; - long r, u; - void *rp; - - u = (long) ((U-1)/sizeof(union M) + 2); - - if (u >= A_LARGE) - { log(ALLOC, 0, 1); - if (tl_verbose) - { printf("tl_spin: memalloc %ld bytes\n", u); - } - m = (union M *) emalloc((int) u*sizeof(union M)); - All_Mem += (unsigned long) u*sizeof(union M); - } else - { if (!freelist[u]) - { r = req[u] += req[u] ? req[u] : 1; - if (r >= NOTOOBIG) - { r = req[u] = NOTOOBIG; - } - log(POOL, u, r); - freelist[u] = (union M *) - emalloc((int) r*u*sizeof(union M)); - All_Mem += (unsigned long) r*u*sizeof(union M); - m = freelist[u] + (r-2)*u; - for ( ; m >= freelist[u]; m -= u) - { m->link = m+u; - } } - log(ALLOC, u, 1); - m = freelist[u]; - freelist[u] = m->link; - } - m->size = (u|A_USER); - - for (r = 1; r < u; ) - { (&m->size)[r++] = 0; - } - - rp = (void *) (m+1); - memset(rp, 0, U); - return rp; +{ union M *m; + long r, u; + void *rp; + + u = (long) ((U-1)/sizeof(union M) + 2); + + if (u >= A_LARGE) + { log(ALLOC, 0, 1); + if (tl_verbose) + { printf("tl_spin: memalloc %ld bytes\n", u); + } + m = (union M *) emalloc((int) u*sizeof(union M)); + All_Mem += (unsigned long) u*sizeof(union M); + } else + { if (!freelist[u]) + { r = req[u] += req[u] ? req[u] : 1; + if (r >= NOTOOBIG) + { r = req[u] = NOTOOBIG; + } + log(POOL, u, r); + freelist[u] = (union M *) + emalloc((int) r*u*sizeof(union M)); + All_Mem += (unsigned long) r*u*sizeof(union M); + m = freelist[u] + (r-2)*u; + for ( ; m >= freelist[u]; m -= u) + { m->link = m+u; + } } + log(ALLOC, u, 1); + m = freelist[u]; + freelist[u] = m->link; + } + m->size = (u|A_USER); + + for (r = 1; r < u; ) + { (&m->size)[r++] = 0; + } + + rp = (void *) (m+1); + memset(rp, 0, U); + return rp; } /* could be more efficient, but not a bottleneck */ void* tl_erealloc(void *v, int U, int old_size) -{ void* tmp = tl_emalloc(U); +{ void* tmp = tl_emalloc(U); - if (v) - { strncpy(tmp, v, old_size); - tfree(v); - } + if (v) + { strncpy((char *)tmp, (char *)v, old_size); + tfree(v); + } - return tmp; + return tmp; } void tfree(void *v) -{ union M *m = (union M *) v; - long u; - - --m; - if ((m->size&0xFF000000) != A_USER) - { Fatal("releasing a free block", (char *)0); - } - - u = (m->size &= 0xFFFFFF); - if (u >= A_LARGE) - { log(FREE, 0, 1); - /* free(m); */ - } else - { log(FREE, u, 1); - m->link = freelist[u]; - freelist[u] = m; - } +{ union M *m = (union M *) v; + long u; + + --m; + if ((m->size&0xFF000000) != A_USER) + { Fatal("releasing a free block", (char *)0); + } + + u = (m->size &= 0xFFFFFF); + if (u >= A_LARGE) + { log(FREE, 0, 1); + /* free(m); */ + } else + { log(FREE, u, 1); + m->link = freelist[u]; + freelist[u] = m; + } } void a_stats(void) -{ long p, a, f; - int i; - - printf(" size\t pool\tallocs\t frees\n"); - for (i = 0; i < A_LARGE; i++) - { p = event[POOL][i]; - a = event[ALLOC][i]; - f = event[FREE][i]; - - if (p|a|f) - { printf("%5d\t%6ld\t%6ld\t%6ld\n", - i, p, a, f); - } } +{ long p, a, f; + int i; + + printf(" size\t pool\tallocs\t frees\n"); + for (i = 0; i < A_LARGE; i++) + { p = event[POOL][i]; + a = event[ALLOC][i]; + f = event[FREE][i]; + + if (p|a|f) + { printf("%5d\t%6ld\t%6ld\t%6ld\n", + i, p, a, f); + } } } diff --git a/Src/tl_trans.c b/Src/tl_trans.c index 20f84ac..4d45d1d 100644 --- a/Src/tl_trans.c +++ b/Src/tl_trans.c @@ -11,53 +11,53 @@ #include "tl.h" -extern FILE *tl_out; -extern int tl_errs, tl_verbose, tl_terse, newstates, state_cnt; +extern FILE *tl_out; +extern int tl_errs, tl_verbose, tl_terse, newstates, state_cnt; -int Stack_mx=0, Max_Red=0, Total=0; +int Stack_mx=0, Max_Red=0, Total=0; -static Mapping *Mapped = (Mapping *) 0; -static Graph *Nodes_Set = (Graph *) 0; -static Graph *Nodes_Stack = (Graph *) 0; +static Mapping *Mapped = (Mapping *) 0; +static Graph *Nodes_Set = (Graph *) 0; +static Graph *Nodes_Stack = (Graph *) 0; -static char *dumpbuf = NULL; +static char *dumpbuf = NULL; static size_t dumpbuf_size = 0; static size_t dumpbuf_capacity = 0; -static int Red_cnt = 0; -static int Lab_cnt = 0; -static int Base = 0; -static int Stack_sz = 0; - -static Graph *findgraph(char *); -static Graph *pop_stack(void); -static Node *Duplicate(Node *); -static Node *flatten(Node *); -static Symbol *catSlist(Symbol *, Symbol *); -static Symbol *dupSlist(Symbol *); -static char *newname(void); -static int choueka(Graph *, int); -static int not_new(Graph *); -static int set_prefix(char *, int, Graph *); -static void Addout(char *, char *); -static void fsm_trans(Graph *, int, char *); -static void mkbuchi(void); -static void expand_g(Graph *); -static void fixinit(Node *); -static void liveness(Node *); -static void mk_grn(Node *); -static void mk_red(Node *); -static void ng(Symbol *, Symbol *, Node *, Node *, Node *); -static void push_stack(Graph *); -static void sdump(Node *); +static int Red_cnt = 0; +static int Lab_cnt = 0; +static int Base = 0; +static int Stack_sz = 0; + +static Graph *findgraph(char *); +static Graph *pop_stack(void); +static Node *Duplicate(Node *); +static Node *flatten(Node *); +static Symbol *catSlist(Symbol *, Symbol *); +static Symbol *dupSlist(Symbol *); +static char *newname(void); +static int choueka(Graph *, int); +static int not_new(Graph *); +static int set_prefix(char *, int, Graph *); +static void Addout(char *, char *); +static void fsm_trans(Graph *, int, char *); +static void mkbuchi(void); +static void expand_g(Graph *); +static void fixinit(Node *); +static void liveness(Node *); +static void mk_grn(Node *); +static void mk_red(Node *); +static void ng(Symbol *, Symbol *, Node *, Node *, Node *); +static void push_stack(Graph *); +static void sdump(Node *); void -append_to_dumpbuf(char* s) +append_to_dumpbuf(const char* s) { size_t len = strlen(s); size_t size_needed = dumpbuf_size + len + 1; if (size_needed > dumpbuf_capacity) { - dumpbuf = tl_erealloc(dumpbuf, size_needed, dumpbuf_capacity); + dumpbuf = (char *) tl_erealloc(dumpbuf, size_needed, dumpbuf_capacity); dumpbuf_capacity = size_needed; } @@ -68,544 +68,544 @@ append_to_dumpbuf(char* s) void ini_trans(void) { - Stack_mx = 0; - Max_Red = 0; - Total = 0; - - Mapped = (Mapping *) 0; - Nodes_Set = (Graph *) 0; - Nodes_Stack = (Graph *) 0; - - dumpbuf_capacity = 4096; - dumpbuf = tl_emalloc(dumpbuf_capacity); - dumpbuf_size = 0; - memset(dumpbuf, 0, dumpbuf_capacity); - Red_cnt = 0; - Lab_cnt = 0; - Base = 0; - Stack_sz = 0; + Stack_mx = 0; + Max_Red = 0; + Total = 0; + + Mapped = (Mapping *) 0; + Nodes_Set = (Graph *) 0; + Nodes_Stack = (Graph *) 0; + + dumpbuf_capacity = 4096; + dumpbuf = (char *) tl_emalloc(dumpbuf_capacity); + dumpbuf_size = 0; + memset(dumpbuf, 0, dumpbuf_capacity); + Red_cnt = 0; + Lab_cnt = 0; + Base = 0; + Stack_sz = 0; } static void dump_graph(Graph *g) -{ Node *n1; - - printf("\n\tnew:\t"); - for (n1 = g->New; n1; n1 = n1->nxt) - { dump(n1); printf(", "); } - printf("\n\told:\t"); - for (n1 = g->Old; n1; n1 = n1->nxt) - { dump(n1); printf(", "); } - printf("\n\tnxt:\t"); - for (n1 = g->Next; n1; n1 = n1->nxt) - { dump(n1); printf(", "); } - printf("\n\tother:\t"); - for (n1 = g->Other; n1; n1 = n1->nxt) - { dump(n1); printf(", "); } - printf("\n"); +{ Node *n1; + + printf("\n\tnew:\t"); + for (n1 = g->New; n1; n1 = n1->nxt) + { dump(n1); printf(", "); } + printf("\n\told:\t"); + for (n1 = g->Old; n1; n1 = n1->nxt) + { dump(n1); printf(", "); } + printf("\n\tnxt:\t"); + for (n1 = g->Next; n1; n1 = n1->nxt) + { dump(n1); printf(", "); } + printf("\n\tother:\t"); + for (n1 = g->Other; n1; n1 = n1->nxt) + { dump(n1); printf(", "); } + printf("\n"); } static void push_stack(Graph *g) { - if (!g) return; - - g->nxt = Nodes_Stack; - Nodes_Stack = g; - if (tl_verbose) - { Symbol *z; - printf("\nPush %s, from ", g->name->name); - for (z = g->incoming; z; z = z->next) - printf("%s, ", z->name); - dump_graph(g); - } - Stack_sz++; - if (Stack_sz > Stack_mx) Stack_mx = Stack_sz; + if (!g) return; + + g->nxt = Nodes_Stack; + Nodes_Stack = g; + if (tl_verbose) + { Symbol *z; + printf("\nPush %s, from ", g->name->name); + for (z = g->incoming; z; z = z->next) + printf("%s, ", z->name); + dump_graph(g); + } + Stack_sz++; + if (Stack_sz > Stack_mx) Stack_mx = Stack_sz; } static Graph * pop_stack(void) -{ Graph *g = Nodes_Stack; +{ Graph *g = Nodes_Stack; - if (g) Nodes_Stack = g->nxt; + if (g) Nodes_Stack = g->nxt; - Stack_sz--; + Stack_sz--; - return g; + return g; } static char * newname(void) -{ static char buf[32]; - sprintf(buf, "S%d", state_cnt++); - return buf; +{ static char buf[32]; + sprintf(buf, "S%d", state_cnt++); + return buf; } static int has_clause(int tok, Graph *p, Node *n) -{ Node *q, *qq; - - switch (n->ntyp) { - case AND: - return has_clause(tok, p, n->lft) && - has_clause(tok, p, n->rgt); - case OR: - return has_clause(tok, p, n->lft) || - has_clause(tok, p, n->rgt); - } - - for (q = p->Other; q; q = q->nxt) - { qq = right_linked(q); - if (anywhere(tok, n, qq)) - return 1; - } - return 0; +{ Node *q, *qq; + + switch (n->ntyp) { + case AND: + return has_clause(tok, p, n->lft) && + has_clause(tok, p, n->rgt); + case OR: + return has_clause(tok, p, n->lft) || + has_clause(tok, p, n->rgt); + } + + for (q = p->Other; q; q = q->nxt) + { qq = right_linked(q); + if (anywhere(tok, n, qq)) + return 1; + } + return 0; } static void mk_grn(Node *n) -{ Graph *p; +{ Graph *p; - if (!n) return; + if (!n) return; - n = right_linked(n); + n = right_linked(n); more: - for (p = Nodes_Set; p; p = p->nxt) - if (p->outgoing - && has_clause(AND, p, n)) - { p->isgrn[p->grncnt++] = - (unsigned char) Red_cnt; - Lab_cnt++; - } - - if (n->ntyp == U_OPER) /* 3.4.0 */ - { n = n->rgt; - goto more; - } + for (p = Nodes_Set; p; p = p->nxt) + if (p->outgoing + && has_clause(AND, p, n)) + { p->isgrn[p->grncnt++] = + (unsigned char) Red_cnt; + Lab_cnt++; + } + + if (n->ntyp == U_OPER) /* 3.4.0 */ + { n = n->rgt; + goto more; + } } static void mk_red(Node *n) -{ Graph *p; - - if (!n) return; - - n = right_linked(n); - for (p = Nodes_Set; p; p = p->nxt) - { if (p->outgoing - && has_clause(0, p, n)) - { if (p->redcnt >= 63) - Fatal("too many Untils", (char *)0); - p->isred[p->redcnt++] = - (unsigned char) Red_cnt; - Lab_cnt++; Max_Red = Red_cnt; - } } +{ Graph *p; + + if (!n) return; + + n = right_linked(n); + for (p = Nodes_Set; p; p = p->nxt) + { if (p->outgoing + && has_clause(0, p, n)) + { if (p->redcnt >= 63) + Fatal("too many Untils", (char *)0); + p->isred[p->redcnt++] = + (unsigned char) Red_cnt; + Lab_cnt++; Max_Red = Red_cnt; + } } } static void liveness(Node *n) { - if (n) - switch (n->ntyp) { + if (n) + switch (n->ntyp) { #ifdef NXT - case NEXT: - liveness(n->lft); - break; + case NEXT: + liveness(n->lft); + break; #endif - case U_OPER: - Red_cnt++; - mk_red(n); - mk_grn(n->rgt); - /* fall through */ - case V_OPER: - case OR: case AND: - liveness(n->lft); - liveness(n->rgt); - break; - } + case U_OPER: + Red_cnt++; + mk_red(n); + mk_grn(n->rgt); + /* fall through */ + case V_OPER: + case OR: case AND: + liveness(n->lft); + liveness(n->rgt); + break; + } } static Graph * findgraph(char *nm) -{ Graph *p; - Mapping *m; - - for (p = Nodes_Set; p; p = p->nxt) - if (!strcmp(p->name->name, nm)) - return p; - for (m = Mapped; m; m = m->nxt) - if (strcmp(m->from, nm) == 0) - return m->to; - - printf("warning: node %s not found\n", nm); - return (Graph *) 0; +{ Graph *p; + Mapping *m; + + for (p = Nodes_Set; p; p = p->nxt) + if (!strcmp(p->name->name, nm)) + return p; + for (m = Mapped; m; m = m->nxt) + if (strcmp(m->from, nm) == 0) + return m->to; + + printf("warning: node %s not found\n", nm); + return (Graph *) 0; } static void Addout(char *to, char *from) -{ Graph *p = findgraph(from); - Symbol *s; +{ Graph *p = findgraph(from); + Symbol *s; - if (!p) return; - s = getsym(tl_lookup(to)); - s->next = p->outgoing; - p->outgoing = s; + if (!p) return; + s = getsym(tl_lookup(to)); + s->next = p->outgoing; + p->outgoing = s; } #ifdef NXT int only_nxt(Node *n) { - switch (n->ntyp) { - case NEXT: - return 1; - case OR: - case AND: - return only_nxt(n->rgt) && only_nxt(n->lft); - default: - return 0; - } + switch (n->ntyp) { + case NEXT: + return 1; + case OR: + case AND: + return only_nxt(n->rgt) && only_nxt(n->lft); + default: + return 0; + } } #endif int dump_cond(Node *pp, Node *r, int first) -{ Node *q; - int frst = first; +{ Node *q; + int frst = first; - if (!pp) return frst; + if (!pp) return frst; - q = dupnode(pp); - q = rewrite(q); + q = dupnode(pp); + q = rewrite(q); - if (q->ntyp == CEXPR) - { if (!frst) fprintf(tl_out, " && "); - fprintf(tl_out, "c_expr { "); - dump_cond(q->lft, r, 1); - fprintf(tl_out, " } "); - frst = 0; - return frst; - } + if (q->ntyp == CEXPR) + { if (!frst) fprintf(tl_out, " && "); + fprintf(tl_out, "c_expr { "); + dump_cond(q->lft, r, 1); + fprintf(tl_out, " } "); + frst = 0; + return frst; + } - if (q->ntyp == PREDICATE - || q->ntyp == NOT + if (q->ntyp == PREDICATE + || q->ntyp == NOT #ifndef NXT - || q->ntyp == OR + || q->ntyp == OR #endif - || q->ntyp == FALSE) - { if (!frst) fprintf(tl_out, " && "); - dump(q); - frst = 0; + || q->ntyp == FALSE) + { if (!frst) fprintf(tl_out, " && "); + dump(q); + frst = 0; #ifdef NXT - } else if (q->ntyp == OR) - { if (!frst) fprintf(tl_out, " && "); - fprintf(tl_out, "(("); - frst = dump_cond(q->lft, r, 1); - - if (!frst) - fprintf(tl_out, ") || ("); - else - { if (only_nxt(q->lft)) - { fprintf(tl_out, "1))"); - return 0; - } - } - - frst = dump_cond(q->rgt, r, 1); - - if (frst) - { if (only_nxt(q->rgt)) - fprintf(tl_out, "1"); - else - fprintf(tl_out, "0"); - frst = 0; - } - - fprintf(tl_out, "))"); + } else if (q->ntyp == OR) + { if (!frst) fprintf(tl_out, " && "); + fprintf(tl_out, "(("); + frst = dump_cond(q->lft, r, 1); + + if (!frst) + fprintf(tl_out, ") || ("); + else + { if (only_nxt(q->lft)) + { fprintf(tl_out, "1))"); + return 0; + } + } + + frst = dump_cond(q->rgt, r, 1); + + if (frst) + { if (only_nxt(q->rgt)) + fprintf(tl_out, "1"); + else + fprintf(tl_out, "0"); + frst = 0; + } + + fprintf(tl_out, "))"); #endif - } else if (q->ntyp == V_OPER - && !anywhere(AND, q->rgt, r)) - { frst = dump_cond(q->rgt, r, frst); - } else if (q->ntyp == AND) - { - frst = dump_cond(q->lft, r, frst); - frst = dump_cond(q->rgt, r, frst); - } - - return frst; + } else if (q->ntyp == V_OPER + && !anywhere(AND, q->rgt, r)) + { frst = dump_cond(q->rgt, r, frst); + } else if (q->ntyp == AND) + { + frst = dump_cond(q->lft, r, frst); + frst = dump_cond(q->rgt, r, frst); + } + + return frst; } static int choueka(Graph *p, int count) -{ int j, k, incr_cnt = 0; - - for (j = count; j <= Max_Red; j++) /* for each acceptance class */ - { int delta = 0; - - /* is state p labeled Grn-j OR not Red-j ? */ - - for (k = 0; k < (int) p->grncnt; k++) - if (p->isgrn[k] == j) - { delta = 1; - break; - } - if (delta) - { incr_cnt++; - continue; - } - for (k = 0; k < (int) p->redcnt; k++) - if (p->isred[k] == j) - { delta = 1; - break; - } - - if (delta) break; - - incr_cnt++; - } - return incr_cnt; +{ int j, k, incr_cnt = 0; + + for (j = count; j <= Max_Red; j++) /* for each acceptance class */ + { int delta = 0; + + /* is state p labeled Grn-j OR not Red-j ? */ + + for (k = 0; k < (int) p->grncnt; k++) + if (p->isgrn[k] == j) + { delta = 1; + break; + } + if (delta) + { incr_cnt++; + continue; + } + for (k = 0; k < (int) p->redcnt; k++) + if (p->isred[k] == j) + { delta = 1; + break; + } + + if (delta) break; + + incr_cnt++; + } + return incr_cnt; } static int set_prefix(char *pref, int count, Graph *r2) -{ int incr_cnt = 0; /* acceptance class 'count' */ - - if (Lab_cnt == 0 - || Max_Red == 0) - sprintf(pref, "accept"); /* new */ - else if (count >= Max_Red) - sprintf(pref, "T0"); /* cycle */ - else - { incr_cnt = choueka(r2, count+1); - if (incr_cnt + count >= Max_Red) - sprintf(pref, "accept"); /* last hop */ - else - sprintf(pref, "T%d", count+incr_cnt); - } - return incr_cnt; +{ int incr_cnt = 0; /* acceptance class 'count' */ + + if (Lab_cnt == 0 + || Max_Red == 0) + sprintf(pref, "accept"); /* new */ + else if (count >= Max_Red) + sprintf(pref, "T0"); /* cycle */ + else + { incr_cnt = choueka(r2, count+1); + if (incr_cnt + count >= Max_Red) + sprintf(pref, "accept"); /* last hop */ + else + sprintf(pref, "T%d", count+incr_cnt); + } + return incr_cnt; } static void fsm_trans(Graph *p, int count, char *curnm) -{ Graph *r; - Symbol *s; - char prefix[128], nwnm[256]; - - if (!p->outgoing) - addtrans(p, curnm, False, "accept_all"); - - for (s = p->outgoing; s; s = s->next) - { r = findgraph(s->name); - if (!r) continue; - if (r->outgoing) - { (void) set_prefix(prefix, count, r); - sprintf(nwnm, "%s_%s", prefix, s->name); - } else - strcpy(nwnm, "accept_all"); - - if (tl_verbose) - { printf("maxred=%d, count=%d, curnm=%s, nwnm=%s ", - Max_Red, count, curnm, nwnm); - printf("(greencnt=%d,%d, redcnt=%d,%d)\n", - r->grncnt, r->isgrn[0], - r->redcnt, r->isred[0]); - } - addtrans(p, curnm, r->Old, nwnm); - } +{ Graph *r; + Symbol *s; + char prefix[128], nwnm[256]; + + if (!p->outgoing) + addtrans(p, curnm, False, "accept_all"); + + for (s = p->outgoing; s; s = s->next) + { r = findgraph(s->name); + if (!r) continue; + if (r->outgoing) + { (void) set_prefix(prefix, count, r); + sprintf(nwnm, "%s_%s", prefix, s->name); + } else + strcpy(nwnm, "accept_all"); + + if (tl_verbose) + { printf("maxred=%d, count=%d, curnm=%s, nwnm=%s ", + Max_Red, count, curnm, nwnm); + printf("(greencnt=%d,%d, redcnt=%d,%d)\n", + r->grncnt, r->isgrn[0], + r->redcnt, r->isred[0]); + } + addtrans(p, curnm, r->Old, nwnm); + } } static void mkbuchi(void) -{ Graph *p; - int k; - char curnm[64]; - - for (k = 0; k <= Max_Red; k++) - for (p = Nodes_Set; p; p = p->nxt) - { if (!p->outgoing) - continue; - if (k != 0 - && !strcmp(p->name->name, "init") - && Max_Red != 0) - continue; - - if (k == Max_Red - && strcmp(p->name->name, "init") != 0) - strcpy(curnm, "accept_"); - else - sprintf(curnm, "T%d_", k); - - strcat(curnm, p->name->name); - - fsm_trans(p, k, curnm); - } - fsm_print(); +{ Graph *p; + int k; + char curnm[64]; + + for (k = 0; k <= Max_Red; k++) + for (p = Nodes_Set; p; p = p->nxt) + { if (!p->outgoing) + continue; + if (k != 0 + && !strcmp(p->name->name, "init") + && Max_Red != 0) + continue; + + if (k == Max_Red + && strcmp(p->name->name, "init") != 0) + strcpy(curnm, "accept_"); + else + sprintf(curnm, "T%d_", k); + + strcat(curnm, p->name->name); + + fsm_trans(p, k, curnm); + } + fsm_print(); } static Symbol * dupSlist(Symbol *s) -{ Symbol *p1, *p2, *p3, *d = ZS; - - for (p1 = s; p1; p1 = p1->next) - { for (p3 = d; p3; p3 = p3->next) - { if (!strcmp(p3->name, p1->name)) - break; - } - if (p3) continue; /* a duplicate */ - - p2 = getsym(p1); - p2->next = d; - d = p2; - } - return d; +{ Symbol *p1, *p2, *p3, *d = ZS; + + for (p1 = s; p1; p1 = p1->next) + { for (p3 = d; p3; p3 = p3->next) + { if (!strcmp(p3->name, p1->name)) + break; + } + if (p3) continue; /* a duplicate */ + + p2 = getsym(p1); + p2->next = d; + d = p2; + } + return d; } static Symbol * catSlist(Symbol *a, Symbol *b) -{ Symbol *p1, *p2, *p3, *tmp; - - /* remove duplicates from b */ - for (p1 = a; p1; p1 = p1->next) - { p3 = ZS; - p2 = b; - while (p2) - { if (strcmp(p1->name, p2->name)) - { p3 = p2; - p2 = p2->next; - continue; - } - tmp = p2->next; - tfree((void *) p2); - p2 = tmp; - if (p3) - p3->next = tmp; - else - b = tmp; - } } - if (!a) return b; - if (!b) return a; - if (!b->next) - { b->next = a; - return b; - } - /* find end of list */ - for (p1 = a; p1->next; p1 = p1->next) - ; - p1->next = b; - return a; +{ Symbol *p1, *p2, *p3, *tmp; + + /* remove duplicates from b */ + for (p1 = a; p1; p1 = p1->next) + { p3 = ZS; + p2 = b; + while (p2) + { if (strcmp(p1->name, p2->name)) + { p3 = p2; + p2 = p2->next; + continue; + } + tmp = p2->next; + tfree((void *) p2); + p2 = tmp; + if (p3) + p3->next = tmp; + else + b = tmp; + } } + if (!a) return b; + if (!b) return a; + if (!b->next) + { b->next = a; + return b; + } + /* find end of list */ + for (p1 = a; p1->next; p1 = p1->next) + ; + p1->next = b; + return a; } static void fixinit(Node *orig) -{ Graph *p1, *g; - Symbol *q1, *q2 = ZS; - - ng(tl_lookup("init"), ZS, ZN, ZN, ZN); - p1 = pop_stack(); - if (p1) - { p1->nxt = Nodes_Set; - p1->Other = p1->Old = orig; - Nodes_Set = p1; - } - - for (g = Nodes_Set; g; g = g->nxt) - { for (q1 = g->incoming; q1; q1 = q2) - { q2 = q1->next; - Addout(g->name->name, q1->name); - tfree((void *) q1); - } - g->incoming = ZS; - } +{ Graph *p1, *g; + Symbol *q1, *q2 = ZS; + + ng(tl_lookup("init"), ZS, ZN, ZN, ZN); + p1 = pop_stack(); + if (p1) + { p1->nxt = Nodes_Set; + p1->Other = p1->Old = orig; + Nodes_Set = p1; + } + + for (g = Nodes_Set; g; g = g->nxt) + { for (q1 = g->incoming; q1; q1 = q2) + { q2 = q1->next; + Addout(g->name->name, q1->name); + tfree((void *) q1); + } + g->incoming = ZS; + } } static Node * flatten(Node *p) -{ Node *q, *r, *z = ZN; - - for (q = p; q; q = q->nxt) - { r = dupnode(q); - if (z) - z = tl_nn(AND, r, z); - else - z = r; - } - if (!z) return z; - z = rewrite(z); - return z; +{ Node *q, *r, *z = ZN; + + for (q = p; q; q = q->nxt) + { r = dupnode(q); + if (z) + z = tl_nn(AND, r, z); + else + z = r; + } + if (!z) return z; + z = rewrite(z); + return z; } static Node * Duplicate(Node *n) -{ Node *n1, *n2, *lst = ZN, *d = ZN; - - for (n1 = n; n1; n1 = n1->nxt) - { n2 = dupnode(n1); - if (lst) - { lst->nxt = n2; - lst = n2; - } else - d = lst = n2; - } - return d; +{ Node *n1, *n2, *lst = ZN, *d = ZN; + + for (n1 = n; n1; n1 = n1->nxt) + { n2 = dupnode(n1); + if (lst) + { lst->nxt = n2; + lst = n2; + } else + d = lst = n2; + } + return d; } static void ng(Symbol *s, Symbol *in, Node *isnew, Node *isold, Node *next) -{ Graph *g = (Graph *) tl_emalloc(sizeof(Graph)); +{ Graph *g = (Graph *) tl_emalloc(sizeof(Graph)); - if (s) g->name = s; - else g->name = tl_lookup(newname()); + if (s) g->name = s; + else g->name = tl_lookup(newname()); - if (in) g->incoming = dupSlist(in); - if (isnew) g->New = flatten(isnew); - if (isold) g->Old = Duplicate(isold); - if (next) g->Next = flatten(next); + if (in) g->incoming = dupSlist(in); + if (isnew) g->New = flatten(isnew); + if (isold) g->Old = Duplicate(isold); + if (next) g->Next = flatten(next); - push_stack(g); + push_stack(g); } static void sdump(Node *n) { - switch (n->ntyp) { - case PREDICATE: append_to_dumpbuf(n->sym->name); - break; - case U_OPER: append_to_dumpbuf("U"); - goto common2; - case V_OPER: append_to_dumpbuf("V"); - goto common2; - case OR: append_to_dumpbuf("|"); - goto common2; - case AND: append_to_dumpbuf("&"); -common2: sdump(n->rgt); -common1: sdump(n->lft); - break; + switch (n->ntyp) { + case PREDICATE: append_to_dumpbuf(n->sym->name); + break; + case U_OPER: append_to_dumpbuf("U"); + goto common2; + case V_OPER: append_to_dumpbuf("V"); + goto common2; + case OR: append_to_dumpbuf("|"); + goto common2; + case AND: append_to_dumpbuf("&"); +common2: sdump(n->rgt); +common1: sdump(n->lft); + break; #ifdef NXT - case NEXT: append_to_dumpbuf("X"); - goto common1; + case NEXT: append_to_dumpbuf("X"); + goto common1; #endif - case CEXPR: append_to_dumpbuf("c_expr {"); - sdump(n->lft); - append_to_dumpbuf("}"); - break; - case NOT: append_to_dumpbuf("!"); - goto common1; - case TRUE: append_to_dumpbuf("T"); - break; - case FALSE: append_to_dumpbuf("F"); - break; - default: append_to_dumpbuf("?"); - break; - } + case CEXPR: append_to_dumpbuf("c_expr {"); + sdump(n->lft); + append_to_dumpbuf("}"); + break; + case NOT: append_to_dumpbuf("!"); + goto common1; + case TRUE: append_to_dumpbuf("T"); + break; + case FALSE: append_to_dumpbuf("F"); + break; + default: append_to_dumpbuf("?"); + break; + } } Symbol * DoDump(Node *n) { - if (!n) return ZS; + if (!n) return ZS; - if (n->ntyp == PREDICATE) - return n->sym; + if (n->ntyp == PREDICATE) + return n->sym; if (dumpbuf) { dumpbuf[0] = '\0'; @@ -620,322 +620,322 @@ DoDump(Node *n) static int not_new(Graph *g) -{ Graph *q1; Node *tmp, *n1, *n2; - Mapping *map; - - tmp = flatten(g->Old); /* duplicate, collapse, normalize */ - g->Other = g->Old; /* non normalized full version */ - g->Old = tmp; - - g->oldstring = DoDump(g->Old); - - tmp = flatten(g->Next); - g->nxtstring = DoDump(tmp); - - if (tl_verbose) dump_graph(g); - - Debug2("\tformula-old: [%s]\n", g->oldstring?g->oldstring->name:"true"); - Debug2("\tformula-nxt: [%s]\n", g->nxtstring?g->nxtstring->name:"true"); - for (q1 = Nodes_Set; q1; q1 = q1->nxt) - { Debug2(" compare old to: %s", q1->name->name); - Debug2(" [%s]", q1->oldstring?q1->oldstring->name:"true"); - - Debug2(" compare nxt to: %s", q1->name->name); - Debug2(" [%s]", q1->nxtstring?q1->nxtstring->name:"true"); - - if (q1->oldstring != g->oldstring - || q1->nxtstring != g->nxtstring) - { Debug(" => different\n"); - continue; - } - Debug(" => match\n"); - - if (g->incoming) - q1->incoming = catSlist(g->incoming, q1->incoming); - - /* check if there's anything in g->Other that needs - adding to q1->Other - */ - for (n2 = g->Other; n2; n2 = n2->nxt) - { for (n1 = q1->Other; n1; n1 = n1->nxt) - if (isequal(n1, n2)) - break; - if (!n1) - { Node *n3 = dupnode(n2); - /* don't mess up n2->nxt */ - n3->nxt = q1->Other; - q1->Other = n3; - } } - - map = (Mapping *) tl_emalloc(sizeof(Mapping)); - map->from = g->name->name; - map->to = q1; - map->nxt = Mapped; - Mapped = map; - - for (n1 = g->Other; n1; n1 = n2) - { n2 = n1->nxt; - releasenode(1, n1); - } - for (n1 = g->Old; n1; n1 = n2) - { n2 = n1->nxt; - releasenode(1, n1); - } - for (n1 = g->Next; n1; n1 = n2) - { n2 = n1->nxt; - releasenode(1, n1); - } - return 1; - } - - if (newstates) tl_verbose=1; - Debug2(" New Node %s [", g->name->name); - for (n1 = g->Old; n1; n1 = n1->nxt) - { Dump(n1); Debug(", "); } - Debug2("] nr %d\n", Base); - if (newstates) tl_verbose=0; - - Base++; - g->nxt = Nodes_Set; - Nodes_Set = g; - - return 0; +{ Graph *q1; Node *tmp, *n1, *n2; + Mapping *map; + + tmp = flatten(g->Old); /* duplicate, collapse, normalize */ + g->Other = g->Old; /* non normalized full version */ + g->Old = tmp; + + g->oldstring = DoDump(g->Old); + + tmp = flatten(g->Next); + g->nxtstring = DoDump(tmp); + + if (tl_verbose) dump_graph(g); + + Debug2("\tformula-old: [%s]\n", g->oldstring?g->oldstring->name:"true"); + Debug2("\tformula-nxt: [%s]\n", g->nxtstring?g->nxtstring->name:"true"); + for (q1 = Nodes_Set; q1; q1 = q1->nxt) + { Debug2(" compare old to: %s", q1->name->name); + Debug2(" [%s]", q1->oldstring?q1->oldstring->name:"true"); + + Debug2(" compare nxt to: %s", q1->name->name); + Debug2(" [%s]", q1->nxtstring?q1->nxtstring->name:"true"); + + if (q1->oldstring != g->oldstring + || q1->nxtstring != g->nxtstring) + { Debug(" => different\n"); + continue; + } + Debug(" => match\n"); + + if (g->incoming) + q1->incoming = catSlist(g->incoming, q1->incoming); + + /* check if there's anything in g->Other that needs + adding to q1->Other + */ + for (n2 = g->Other; n2; n2 = n2->nxt) + { for (n1 = q1->Other; n1; n1 = n1->nxt) + if (isequal(n1, n2)) + break; + if (!n1) + { Node *n3 = dupnode(n2); + /* don't mess up n2->nxt */ + n3->nxt = q1->Other; + q1->Other = n3; + } } + + map = (Mapping *) tl_emalloc(sizeof(Mapping)); + map->from = g->name->name; + map->to = q1; + map->nxt = Mapped; + Mapped = map; + + for (n1 = g->Other; n1; n1 = n2) + { n2 = n1->nxt; + releasenode(1, n1); + } + for (n1 = g->Old; n1; n1 = n2) + { n2 = n1->nxt; + releasenode(1, n1); + } + for (n1 = g->Next; n1; n1 = n2) + { n2 = n1->nxt; + releasenode(1, n1); + } + return 1; + } + + if (newstates) tl_verbose=1; + Debug2(" New Node %s [", g->name->name); + for (n1 = g->Old; n1; n1 = n1->nxt) + { Dump(n1); Debug(", "); } + Debug2("] nr %d\n", Base); + if (newstates) tl_verbose=0; + + Base++; + g->nxt = Nodes_Set; + Nodes_Set = g; + + return 0; } static void expand_g(Graph *g) -{ Node *now, *n1, *n2, *nx; - int can_release; - - if (!g->New) - { Debug2("\nDone with %s", g->name->name); - if (tl_verbose) dump_graph(g); - if (not_new(g)) - { if (tl_verbose) printf("\tIs Not New\n"); - return; - } - if (g->Next) - { Debug(" Has Next ["); - for (n1 = g->Next; n1; n1 = n1->nxt) - { Dump(n1); Debug(", "); } - Debug("]\n"); - - ng(ZS, getsym(g->name), g->Next, ZN, ZN); - } - return; - } - - if (tl_verbose) - { Symbol *z; - printf("\nExpand %s, from ", g->name->name); - for (z = g->incoming; z; z = z->next) - printf("%s, ", z->name); - printf("\n\thandle:\t"); Explain(g->New->ntyp); - dump_graph(g); - } - - if (g->New->ntyp == AND) - { if (g->New->nxt) - { n2 = g->New->rgt; - while (n2->nxt) - n2 = n2->nxt; - n2->nxt = g->New->nxt; - } - n1 = n2 = g->New->lft; - while (n2->nxt) - n2 = n2->nxt; - n2->nxt = g->New->rgt; - - releasenode(0, g->New); - - g->New = n1; - push_stack(g); - return; - } - - can_release = 0; /* unless it need not go into Old */ - now = g->New; - g->New = g->New->nxt; - now->nxt = ZN; - - if (now->ntyp != TRUE) - { if (g->Old) - { for (n1 = g->Old; n1->nxt; n1 = n1->nxt) - if (isequal(now, n1)) - { can_release = 1; - goto out; - } - n1->nxt = now; - } else - g->Old = now; - } +{ Node *now, *n1, *n2, *nx; + int can_release; + + if (!g->New) + { Debug2("\nDone with %s", g->name->name); + if (tl_verbose) dump_graph(g); + if (not_new(g)) + { if (tl_verbose) printf("\tIs Not New\n"); + return; + } + if (g->Next) + { Debug(" Has Next ["); + for (n1 = g->Next; n1; n1 = n1->nxt) + { Dump(n1); Debug(", "); } + Debug("]\n"); + + ng(ZS, getsym(g->name), g->Next, ZN, ZN); + } + return; + } + + if (tl_verbose) + { Symbol *z; + printf("\nExpand %s, from ", g->name->name); + for (z = g->incoming; z; z = z->next) + printf("%s, ", z->name); + printf("\n\thandle:\t"); Explain(g->New->ntyp); + dump_graph(g); + } + + if (g->New->ntyp == AND) + { if (g->New->nxt) + { n2 = g->New->rgt; + while (n2->nxt) + n2 = n2->nxt; + n2->nxt = g->New->nxt; + } + n1 = n2 = g->New->lft; + while (n2->nxt) + n2 = n2->nxt; + n2->nxt = g->New->rgt; + + releasenode(0, g->New); + + g->New = n1; + push_stack(g); + return; + } + + can_release = 0; /* unless it need not go into Old */ + now = g->New; + g->New = g->New->nxt; + now->nxt = ZN; + + if (now->ntyp != TRUE) + { if (g->Old) + { for (n1 = g->Old; n1->nxt; n1 = n1->nxt) + if (isequal(now, n1)) + { can_release = 1; + goto out; + } + n1->nxt = now; + } else + g->Old = now; + } out: - switch (now->ntyp) { - case FALSE: - push_stack(g); - break; - case TRUE: - releasenode(1, now); - push_stack(g); - break; - case PREDICATE: - case NOT: - case CEXPR: - if (can_release) releasenode(1, now); - push_stack(g); - break; - case V_OPER: - Assert(now->rgt != ZN, now->ntyp); - Assert(now->lft != ZN, now->ntyp); - Assert(now->rgt->nxt == ZN, now->ntyp); - Assert(now->lft->nxt == ZN, now->ntyp); - n1 = now->rgt; - n1->nxt = g->New; - - if (can_release) - nx = now; - else - nx = getnode(now); /* now also appears in Old */ - nx->nxt = g->Next; - - n2 = now->lft; - n2->nxt = getnode(now->rgt); - n2->nxt->nxt = g->New; - g->New = flatten(n2); - push_stack(g); - ng(ZS, g->incoming, n1, g->Old, nx); - break; - - case U_OPER: - Assert(now->rgt->nxt == ZN, now->ntyp); - Assert(now->lft->nxt == ZN, now->ntyp); - n1 = now->lft; - - if (can_release) - nx = now; - else - nx = getnode(now); /* now also appears in Old */ - nx->nxt = g->Next; - - n2 = now->rgt; - n2->nxt = g->New; - - goto common; + switch (now->ntyp) { + case FALSE: + push_stack(g); + break; + case TRUE: + releasenode(1, now); + push_stack(g); + break; + case PREDICATE: + case NOT: + case CEXPR: + if (can_release) releasenode(1, now); + push_stack(g); + break; + case V_OPER: + Assert(now->rgt != ZN, now->ntyp); + Assert(now->lft != ZN, now->ntyp); + Assert(now->rgt->nxt == ZN, now->ntyp); + Assert(now->lft->nxt == ZN, now->ntyp); + n1 = now->rgt; + n1->nxt = g->New; + + if (can_release) + nx = now; + else + nx = getnode(now); /* now also appears in Old */ + nx->nxt = g->Next; + + n2 = now->lft; + n2->nxt = getnode(now->rgt); + n2->nxt->nxt = g->New; + g->New = flatten(n2); + push_stack(g); + ng(ZS, g->incoming, n1, g->Old, nx); + break; + + case U_OPER: + Assert(now->rgt->nxt == ZN, now->ntyp); + Assert(now->lft->nxt == ZN, now->ntyp); + n1 = now->lft; + + if (can_release) + nx = now; + else + nx = getnode(now); /* now also appears in Old */ + nx->nxt = g->Next; + + n2 = now->rgt; + n2->nxt = g->New; + + goto common; #ifdef NXT - case NEXT: - Assert(now->lft != ZN, now->ntyp); - nx = dupnode(now->lft); - nx->nxt = g->Next; - g->Next = nx; - if (can_release) releasenode(0, now); - push_stack(g); - break; + case NEXT: + Assert(now->lft != ZN, now->ntyp); + nx = dupnode(now->lft); + nx->nxt = g->Next; + g->Next = nx; + if (can_release) releasenode(0, now); + push_stack(g); + break; #endif - case OR: - Assert(now->rgt->nxt == ZN, now->ntyp); - Assert(now->lft->nxt == ZN, now->ntyp); - n1 = now->lft; - nx = g->Next; + case OR: + Assert(now->rgt->nxt == ZN, now->ntyp); + Assert(now->lft->nxt == ZN, now->ntyp); + n1 = now->lft; + nx = g->Next; - n2 = now->rgt; - n2->nxt = g->New; + n2 = now->rgt; + n2->nxt = g->New; common: - n1->nxt = g->New; + n1->nxt = g->New; - ng(ZS, g->incoming, n1, g->Old, nx); - g->New = flatten(n2); + ng(ZS, g->incoming, n1, g->Old, nx); + g->New = flatten(n2); - if (can_release) releasenode(1, now); + if (can_release) releasenode(1, now); - push_stack(g); - break; - } + push_stack(g); + break; + } } Node * twocases(Node *p) -{ Node *q; - /* 1: ([]p1 && []p2) == [](p1 && p2) */ - /* 2: (<>p1 || <>p2) == <>(p1 || p2) */ - - if (!p) return p; - - switch(p->ntyp) { - case AND: - case OR: - case U_OPER: - case V_OPER: - p->lft = twocases(p->lft); - p->rgt = twocases(p->rgt); - break; +{ Node *q; + /* 1: ([]p1 && []p2) == [](p1 && p2) */ + /* 2: (<>p1 || <>p2) == <>(p1 || p2) */ + + if (!p) return p; + + switch(p->ntyp) { + case AND: + case OR: + case U_OPER: + case V_OPER: + p->lft = twocases(p->lft); + p->rgt = twocases(p->rgt); + break; #ifdef NXT - case NEXT: + case NEXT: #endif - case NOT: - p->lft = twocases(p->lft); - break; - - default: - break; - } - if (p->ntyp == AND /* 1 */ - && p->lft->ntyp == V_OPER - && p->lft->lft->ntyp == FALSE - && p->rgt->ntyp == V_OPER - && p->rgt->lft->ntyp == FALSE) - { q = tl_nn(V_OPER, False, - tl_nn(AND, p->lft->rgt, p->rgt->rgt)); - } else - if (p->ntyp == OR /* 2 */ - && p->lft->ntyp == U_OPER - && p->lft->lft->ntyp == TRUE - && p->rgt->ntyp == U_OPER - && p->rgt->lft->ntyp == TRUE) - { q = tl_nn(U_OPER, True, - tl_nn(OR, p->lft->rgt, p->rgt->rgt)); - } else - q = p; - return q; + case NOT: + p->lft = twocases(p->lft); + break; + + default: + break; + } + if (p->ntyp == AND /* 1 */ + && p->lft->ntyp == V_OPER + && p->lft->lft->ntyp == FALSE + && p->rgt->ntyp == V_OPER + && p->rgt->lft->ntyp == FALSE) + { q = tl_nn(V_OPER, False, + tl_nn(AND, p->lft->rgt, p->rgt->rgt)); + } else + if (p->ntyp == OR /* 2 */ + && p->lft->ntyp == U_OPER + && p->lft->lft->ntyp == TRUE + && p->rgt->ntyp == U_OPER + && p->rgt->lft->ntyp == TRUE) + { q = tl_nn(U_OPER, True, + tl_nn(OR, p->lft->rgt, p->rgt->rgt)); + } else + q = p; + return q; } void trans(Node *p) -{ Node *op; - Graph *g; - - if (!p || tl_errs) return; - - p = twocases(p); - - if (tl_verbose || tl_terse) - { fprintf(tl_out, "\t/* Normlzd: "); - dump(p); - fprintf(tl_out, " */\n"); - } - if (tl_terse) - return; - - op = dupnode(p); - - ng(ZS, getsym(tl_lookup("init")), p, ZN, ZN); - while ((g = Nodes_Stack) != (Graph *) 0) - { Nodes_Stack = g->nxt; - expand_g(g); - } - if (newstates) - return; - - fixinit(p); - liveness(flatten(op)); /* was: liveness(op); */ - - mkbuchi(); - if (tl_verbose) - { printf("/*\n"); - printf(" * %d states in Streett automaton\n", Base); - printf(" * %d Streett acceptance conditions\n", Max_Red); - printf(" * %d Buchi states\n", Total); - printf(" */\n"); - } +{ Node *op; + Graph *g; + + if (!p || tl_errs) return; + + p = twocases(p); + + if (tl_verbose || tl_terse) + { fprintf(tl_out, "\t/* Normlzd: "); + dump(p); + fprintf(tl_out, " */\n"); + } + if (tl_terse) + return; + + op = dupnode(p); + + ng(ZS, getsym(tl_lookup("init")), p, ZN, ZN); + while ((g = Nodes_Stack) != (Graph *) 0) + { Nodes_Stack = g->nxt; + expand_g(g); + } + if (newstates) + return; + + fixinit(p); + liveness(flatten(op)); /* was: liveness(op); */ + + mkbuchi(); + if (tl_verbose) + { printf("/*\n"); + printf(" * %d states in Streett automaton\n", Base); + printf(" * %d Streett acceptance conditions\n", Max_Red); + printf(" * %d Buchi states\n", Total); + printf(" */\n"); + } }