/***** spin: reprosrc.c *****/ /* * This file is part of the public release of Spin. It is subject to the * terms in the LICENSE file that is included in this source directory. * Tool documentation is available at http://spinroot.com */ #include <stdio.h>#include <assert.h>#include "spin.h"#include "y.tab.h" static int indent = 1; extern YYSTYPE yylval;extern ProcList *rdy;static void repro_seq(Sequence *); voiddoindent(void){ int i; for (i = 0; i < indent; i++) printf(" ");} voidrepro_sub(Element *e){ doindent(); switch (e->n->ntyp) { case D_STEP: printf("d_step {\n"); break; case ATOMIC: printf("atomic {\n"); break; case NON_ATOMIC: printf(" {\n"); break; } indent++; repro_seq(e->n->sl->this); indent--; doindent(); printf(" };\n");} static voidrepro_seq(Sequence *s){ Element *e; Symbol *v; SeqList *h; for (e = s->frst; e; e = e->nxt) { v = has_lab(e, 0); if (v) printf("%s:\n", v->name); if (e->n->ntyp == UNLESS) { printf("/* normal */ {\n"); repro_seq(e->n->sl->this); doindent(); printf("} unless {\n"); repro_seq(e->n->sl->nxt->this); doindent(); printf("}; /* end unless */\n"); } else if (e->sub) { switch (e->n->ntyp) { case DO: doindent(); printf("do\n"); indent++; break; case IF: doindent(); printf("if\n"); indent++; break; } for (h = e->sub; h; h = h->nxt) { indent--; doindent(); indent++; printf("::\n"); repro_seq(h->this); printf("\n"); } switch (e->n->ntyp) { case DO: indent--; doindent(); printf("od;\n"); break; case IF: indent--; doindent(); printf("fi;\n"); break; } } else { if (e->n->ntyp == ATOMIC || e->n->ntyp == D_STEP || e->n->ntyp == NON_ATOMIC) repro_sub(e); else if (e->n->ntyp != '.' && e->n->ntyp != '@' && e->n->ntyp != BREAK) { doindent(); if (e->n->ntyp == C_CODE) { printf("c_code "); plunk_inline(stdout, e->n->sym->name, 1, 1); } else if (e->n->ntyp == 'c' && e->n->lft->ntyp == C_EXPR) { printf("c_expr { "); plunk_expr(stdout, e->n->lft->sym->name); printf("} ->\n"); } else { comment(stdout, e->n, 0); printf(";\n"); } } } if (e == s->last) break; }} voidrepro_proc(ProcList *p){ if (!p) return; if (p->nxt) repro_proc(p->nxt); if (p->det) printf("D"); /* deterministic */ printf("proctype %s()", p->n->name); if (p->prov) { printf(" provided "); comment(stdout, p->prov, 0); } printf("\n{\n"); repro_seq(p->s); printf("}\n");} voidrepro_src(void){ repro_proc(rdy);} static int in_decl;static int in_c_decl;static int in_c_code; voidblip(int n, char *b){ char mtxt[1024]; strcpy(mtxt, ""); switch (n) { default: if (n > 0 && n < 256) sprintf(mtxt, "%c", n); else sprintf(mtxt, "<%d?>", n); break; case '(': strcpy(mtxt, "("); in_decl++; break; case ')': strcpy(mtxt, ")"); in_decl--; break; case '{': strcpy(mtxt, "{"); break; case '}': strcpy(mtxt, "}"); break; case '\t': sprintf(mtxt, "\\t"); break; case '\f': sprintf(mtxt, "\\f"); break; case '\n': sprintf(mtxt, "\\n"); break; case '\r': sprintf(mtxt, "\\r"); break; case 'c': sprintf(mtxt, "condition"); break; case 's': sprintf(mtxt, "send"); break; case 'r': sprintf(mtxt, "recv"); break; case 'R': sprintf(mtxt, "recv poll"); break; case '@': sprintf(mtxt, "@"); break; case '?': sprintf(mtxt, "(x->y:z)"); break; case NEXT: sprintf(mtxt, "X"); break; case ALWAYS: sprintf(mtxt, "[]"); break; case EVENTUALLY: sprintf(mtxt, "<>"); break; case IMPLIES: sprintf(mtxt, "->"); break; case EQUIV: sprintf(mtxt, "<->"); break; case UNTIL: sprintf(mtxt, "U"); break; case WEAK_UNTIL: sprintf(mtxt, "W"); break; case IN: sprintf(mtxt, "in"); break; case ACTIVE: sprintf(mtxt, "active"); break; case AND: sprintf(mtxt, "&&"); break; case ARROW: sprintf(mtxt, "->"); break; case ASGN: sprintf(mtxt, "="); break; case ASSERT: sprintf(mtxt, "assert"); break; case ATOMIC: sprintf(mtxt, "atomic"); break; case BREAK: sprintf(mtxt, "break"); break; case C_CODE: sprintf(mtxt, "c_code"); in_c_code++; break; case C_DECL: sprintf(mtxt, "c_decl"); in_c_decl++; break; case C_EXPR: sprintf(mtxt, "c_expr"); break; case C_STATE: sprintf(mtxt, "c_state"); break; case C_TRACK: sprintf(mtxt, "c_track"); break; case CLAIM: sprintf(mtxt, "never"); break; case CONST: sprintf(mtxt, "%d", yylval->val); break; case DECR: sprintf(mtxt, "--"); break; case D_STEP: sprintf(mtxt, "d_step"); break; case D_PROCTYPE: sprintf(mtxt, "d_proctype"); break; case DO: sprintf(mtxt, "do"); break; case DOT: sprintf(mtxt, "."); break; case ELSE: sprintf(mtxt, "else"); break; case EMPTY: sprintf(mtxt, "empty"); break; case ENABLED: sprintf(mtxt, "enabled"); break; case EQ: sprintf(mtxt, "=="); break; case EVAL: sprintf(mtxt, "eval"); break; case FI: sprintf(mtxt, "fi"); break; case FULL: sprintf(mtxt, "full"); break; case GE: sprintf(mtxt, ">="); break; case GET_P: sprintf(mtxt, "get_priority"); break; case GOTO: sprintf(mtxt, "goto"); break; case GT: sprintf(mtxt, ">"); break; case HIDDEN: sprintf(mtxt, "hidden"); break; case IF: sprintf(mtxt, "if"); break; case INCR: sprintf(mtxt, "++"); break; case INLINE: sprintf(mtxt, "inline"); break; case INIT: sprintf(mtxt, "init"); break; case ISLOCAL: sprintf(mtxt, "local"); break; case LABEL: sprintf(mtxt, "<label-name>"); break; case LE: sprintf(mtxt, "<="); break; case LEN: sprintf(mtxt, "len"); break; case LSHIFT: sprintf(mtxt, "<<"); break; case LT: sprintf(mtxt, "<"); break; case LTL: sprintf(mtxt, "ltl"); break; case NAME: sprintf(mtxt, "%s", yylval->sym->name); break; case XU: switch (yylval->val) { case XR: sprintf(mtxt, "xr"); break; case XS: sprintf(mtxt, "xs"); break; default: sprintf(mtxt, "<?>"); break; } break; case TYPE: switch (yylval->val) { case BIT: sprintf(mtxt, "bit"); break; case BYTE: sprintf(mtxt, "byte"); break; case CHAN: sprintf(mtxt, "chan"); in_decl++; break; case INT: sprintf(mtxt, "int"); break; case MTYPE: sprintf(mtxt, "mtype"); break; case SHORT: sprintf(mtxt, "short"); break; case UNSIGNED: sprintf(mtxt, "unsigned"); break; default: sprintf(mtxt, "<unknown type>"); break; } break; case NE: sprintf(mtxt, "!="); break; case NEG: sprintf(mtxt, "!"); break; case NEMPTY: sprintf(mtxt, "nempty"); break; case NFULL: sprintf(mtxt, "nfull"); break; case NON_ATOMIC: sprintf(mtxt, "<sub-sequence>"); break; case NONPROGRESS: sprintf(mtxt, "np_"); break; case OD: sprintf(mtxt, "od"); break; case OF: sprintf(mtxt, "of"); break; case OR: sprintf(mtxt, "||"); break; case O_SND: sprintf(mtxt, "!!"); break; case PC_VAL: sprintf(mtxt, "pc_value"); break; case PRINT: sprintf(mtxt, "printf"); break; case PRINTM: sprintf(mtxt, "printm"); break; case PRIORITY: sprintf(mtxt, "priority"); break; case PROCTYPE: sprintf(mtxt, "proctype"); break; case PROVIDED: sprintf(mtxt, "provided"); break; case RCV: sprintf(mtxt, "?"); break; case R_RCV: sprintf(mtxt, "??"); break; case RSHIFT: sprintf(mtxt, ">>"); break; case RUN: sprintf(mtxt, "run"); break; case SEP: sprintf(mtxt, "::"); break; case SEMI: sprintf(mtxt, ";"); break; case SET_P: sprintf(mtxt, "set_priority"); break; case SHOW: sprintf(mtxt, "show"); break; case SND: sprintf(mtxt, "!"); break; case INAME: case UNAME: case PNAME: case STRING: sprintf(mtxt, "%s", yylval->sym->name); break; case TRACE: sprintf(mtxt, "trace"); break; case TIMEOUT: sprintf(mtxt, "timeout"); break; case TYPEDEF: sprintf(mtxt, "typedef"); break; case UMIN: sprintf(mtxt, "-"); break; case UNLESS: sprintf(mtxt, "unless"); break; } strcat(b, mtxt);} voidpurge(char *b){ if (strlen(b) == 0) return; if (b[strlen(b)-1] != ':') /* label? */ { if (b[0] == ':' && b[1] == ':') { indent--; doindent(); indent++; } else { doindent(); } } printf("%s\n", b); strcpy(b, ""); in_decl = 0; in_c_code = 0; in_c_decl = 0;} int pp_mode;extern int lex(void); voidpretty_print(void){ int c, lastc = 0; char buf[1024]; pp_mode = 1; indent = 0; strcpy(buf, ""); while ((c = lex()) != EOF) { if ((lastc == IF || lastc == DO) && c != SEP) { indent--; /* c_code if */ } if (c == C_DECL || c == C_STATE || c == C_TRACK || c == SEP || c == DO || c == IF || (c == TYPE && !in_decl)) { purge(buf); /* start on new line */ } if (c == '{' && lastc != OF && lastc != IN && lastc != ATOMIC && lastc != D_STEP && lastc != C_CODE && lastc != C_DECL && lastc != C_EXPR) { purge(buf); } if (c == PREPROC) { int oi = indent; purge(buf); assert(strlen(yylval->sym->name) < sizeof(buf)); strcpy(buf, yylval->sym->name); indent = 0; purge(buf); indent = oi; continue; } if (c != ':' && c != SEMI && c != ',' && c != '(' && c != '#' && lastc != '#' && c != ARROW && lastc != ARROW && c != '.' && lastc != '.' && c != '!' && lastc != '!' && c != SND && lastc != SND && c != RCV && lastc != RCV && c != O_SND && lastc != O_SND && c != R_RCV && lastc != R_RCV && (c != ']' || lastc != '[') && (c != '>' || lastc != '<') && (c != GT || lastc != LT) && c != '@' && lastc != '@' && c != DO && c != OD && c != IF && c != FI && c != SEP && strlen(buf) > 0) strcat(buf, " "); if (c == '}' || c == OD || c == FI) { purge(buf); indent--; } blip(c, buf); if (c == '{' || c == DO || c == IF) { purge(buf); indent++; } if (c == '}' || c == BREAK || c == SEMI || (c == ':' && lastc == NAME)) { purge(buf); } lastc = c; } purge(buf);}
/***** spin: reprosrc.c *****/
/*
* This file is part of the public release of Spin. It is subject to the
* terms in the LICENSE file that is included in this source directory.
* Tool documentation is available at http://spinroot.com
*/
#include <stdio.h>
#include <assert.h>
#include "spin.h"
#include "y.tab.h"
static int indent = 1;
extern YYSTYPE yylval;
extern ProcList *rdy;
static void repro_seq(Sequence *);
void
doindent(void)
{ int i;
for (i = 0; i < indent; i++)
printf(" ");
}
void
repro_sub(Element *e)
{
doindent();
switch (e->n->ntyp) {
case D_STEP:
printf("d_step {\n");
break;
case ATOMIC:
printf("atomic {\n");
break;
case NON_ATOMIC:
printf(" {\n");
break;
}
indent++;
repro_seq(e->n->sl->this);
indent--;
doindent();
printf(" };\n");
}
static void
repro_seq(Sequence *s)
{ Element *e;
Symbol *v;
SeqList *h;
for (e = s->frst; e; e = e->nxt)
{
v = has_lab(e, 0);
if (v) printf("%s:\n", v->name);
if (e->n->ntyp == UNLESS)
{ printf("/* normal */ {\n");
repro_seq(e->n->sl->this);
doindent();
printf("} unless {\n");
repro_seq(e->n->sl->nxt->this);
doindent();
printf("}; /* end unless */\n");
} else if (e->sub)
{
switch (e->n->ntyp) {
case DO: doindent(); printf("do\n"); indent++; break;
case IF: doindent(); printf("if\n"); indent++; break;
}
for (h = e->sub; h; h = h->nxt)
{ indent--; doindent(); indent++; printf("::\n");
repro_seq(h->this);
printf("\n");
}
switch (e->n->ntyp) {
case DO: indent--; doindent(); printf("od;\n"); break;
case IF: indent--; doindent(); printf("fi;\n"); break;
}
} else
{ if (e->n->ntyp == ATOMIC
|| e->n->ntyp == D_STEP
|| e->n->ntyp == NON_ATOMIC)
repro_sub(e);
else if (e->n->ntyp != '.'
&& e->n->ntyp != '@'
&& e->n->ntyp != BREAK)
{
doindent();
if (e->n->ntyp == C_CODE)
{ printf("c_code ");
plunk_inline(stdout, e->n->sym->name, 1, 1);
} else if (e->n->ntyp == 'c'
&& e->n->lft->ntyp == C_EXPR)
{ printf("c_expr { ");
plunk_expr(stdout, e->n->lft->sym->name);
printf("} ->\n");
} else
{ comment(stdout, e->n, 0);
printf(";\n");
} }
}
if (e == s->last)
break;
}
}
void
repro_proc(ProcList *p)
{
if (!p) return;
if (p->nxt) repro_proc(p->nxt);
if (p->det) printf("D"); /* deterministic */
printf("proctype %s()", p->n->name);
if (p->prov)
{ printf(" provided ");
comment(stdout, p->prov, 0);
}
printf("\n{\n");
repro_seq(p->s);
printf("}\n");
}
void
repro_src(void)
{
repro_proc(rdy);
}
static int in_decl;
static int in_c_decl;
static int in_c_code;
void
blip(int n, char *b)
{ char mtxt[1024];
strcpy(mtxt, "");
switch (n) {
default: if (n > 0 && n < 256)
sprintf(mtxt, "%c", n);
else
sprintf(mtxt, "<%d?>", n);
break;
case '(': strcpy(mtxt, "("); in_decl++; break;
case ')': strcpy(mtxt, ")"); in_decl--; break;
case '{': strcpy(mtxt, "{"); break;
case '}': strcpy(mtxt, "}"); break;
case '\t': sprintf(mtxt, "\\t"); break;
case '\f': sprintf(mtxt, "\\f"); break;
case '\n': sprintf(mtxt, "\\n"); break;
case '\r': sprintf(mtxt, "\\r"); break;
case 'c': sprintf(mtxt, "condition"); break;
case 's': sprintf(mtxt, "send"); break;
case 'r': sprintf(mtxt, "recv"); break;
case 'R': sprintf(mtxt, "recv poll"); break;
case '@': sprintf(mtxt, "@"); break;
case '?': sprintf(mtxt, "(x->y:z)"); break;
case NEXT: sprintf(mtxt, "X"); break;
case ALWAYS: sprintf(mtxt, "[]"); break;
case EVENTUALLY: sprintf(mtxt, "<>"); break;
case IMPLIES: sprintf(mtxt, "->"); break;
case EQUIV: sprintf(mtxt, "<->"); break;
case UNTIL: sprintf(mtxt, "U"); break;
case WEAK_UNTIL: sprintf(mtxt, "W"); break;
case IN: sprintf(mtxt, "in"); break;
case ACTIVE: sprintf(mtxt, "active"); break;
case AND: sprintf(mtxt, "&&"); break;
case ARROW: sprintf(mtxt, "->"); break;
case ASGN: sprintf(mtxt, "="); break;
case ASSERT: sprintf(mtxt, "assert"); break;
case ATOMIC: sprintf(mtxt, "atomic"); break;
case BREAK: sprintf(mtxt, "break"); break;
case C_CODE: sprintf(mtxt, "c_code"); in_c_code++; break;
case C_DECL: sprintf(mtxt, "c_decl"); in_c_decl++; break;
case C_EXPR: sprintf(mtxt, "c_expr"); break;
case C_STATE: sprintf(mtxt, "c_state"); break;
case C_TRACK: sprintf(mtxt, "c_track"); break;
case CLAIM: sprintf(mtxt, "never"); break;
case CONST: sprintf(mtxt, "%d", yylval->val); break;
case DECR: sprintf(mtxt, "--"); break;
case D_STEP: sprintf(mtxt, "d_step"); break;
case D_PROCTYPE: sprintf(mtxt, "d_proctype"); break;
case DO: sprintf(mtxt, "do"); break;
case DOT: sprintf(mtxt, "."); break;
case ELSE: sprintf(mtxt, "else"); break;
case EMPTY: sprintf(mtxt, "empty"); break;
case ENABLED: sprintf(mtxt, "enabled"); break;
case EQ: sprintf(mtxt, "=="); break;
case EVAL: sprintf(mtxt, "eval"); break;
case FI: sprintf(mtxt, "fi"); break;
case FULL: sprintf(mtxt, "full"); break;
case GE: sprintf(mtxt, ">="); break;
case GET_P: sprintf(mtxt, "get_priority"); break;
case GOTO: sprintf(mtxt, "goto"); break;
case GT: sprintf(mtxt, ">"); break;
case HIDDEN: sprintf(mtxt, "hidden"); break;
case IF: sprintf(mtxt, "if"); break;
case INCR: sprintf(mtxt, "++"); break;
case INLINE: sprintf(mtxt, "inline"); break;
case INIT: sprintf(mtxt, "init"); break;
case ISLOCAL: sprintf(mtxt, "local"); break;
case LABEL: sprintf(mtxt, "<label-name>"); break;
case LE: sprintf(mtxt, "<="); break;
case LEN: sprintf(mtxt, "len"); break;
case LSHIFT: sprintf(mtxt, "<<"); break;
case LT: sprintf(mtxt, "<"); break;
case LTL: sprintf(mtxt, "ltl"); break;
case NAME: sprintf(mtxt, "%s", yylval->sym->name); break;
case XU: switch (yylval->val) {
case XR: sprintf(mtxt, "xr"); break;
case XS: sprintf(mtxt, "xs"); break;
default: sprintf(mtxt, "<?>"); break;
}
break;
case TYPE: switch (yylval->val) {
case BIT: sprintf(mtxt, "bit"); break;
case BYTE: sprintf(mtxt, "byte"); break;
case CHAN: sprintf(mtxt, "chan"); in_decl++; break;
case INT: sprintf(mtxt, "int"); break;
case MTYPE: sprintf(mtxt, "mtype"); break;
case SHORT: sprintf(mtxt, "short"); break;
case UNSIGNED: sprintf(mtxt, "unsigned"); break;
default: sprintf(mtxt, "<unknown type>"); break;
}
break;
case NE: sprintf(mtxt, "!="); break;
case NEG: sprintf(mtxt, "!"); break;
case NEMPTY: sprintf(mtxt, "nempty"); break;
case NFULL: sprintf(mtxt, "nfull"); break;
case NON_ATOMIC: sprintf(mtxt, "<sub-sequence>"); break;
case NONPROGRESS: sprintf(mtxt, "np_"); break;
case OD: sprintf(mtxt, "od"); break;
case OF: sprintf(mtxt, "of"); break;
case OR: sprintf(mtxt, "||"); break;
case O_SND: sprintf(mtxt, "!!"); break;
case PC_VAL: sprintf(mtxt, "pc_value"); break;
case PRINT: sprintf(mtxt, "printf"); break;
case PRINTM: sprintf(mtxt, "printm"); break;
case PRIORITY: sprintf(mtxt, "priority"); break;
case PROCTYPE: sprintf(mtxt, "proctype"); break;
case PROVIDED: sprintf(mtxt, "provided"); break;
case RCV: sprintf(mtxt, "?"); break;
case R_RCV: sprintf(mtxt, "??"); break;
case RSHIFT: sprintf(mtxt, ">>"); break;
case RUN: sprintf(mtxt, "run"); break;
case SEP: sprintf(mtxt, "::"); break;
case SEMI: sprintf(mtxt, ";"); break;
case SET_P: sprintf(mtxt, "set_priority"); break;
case SHOW: sprintf(mtxt, "show"); break;
case SND: sprintf(mtxt, "!"); break;
case INAME:
case UNAME:
case PNAME:
case STRING: sprintf(mtxt, "%s", yylval->sym->name); break;
case TRACE: sprintf(mtxt, "trace"); break;
case TIMEOUT: sprintf(mtxt, "timeout"); break;
case TYPEDEF: sprintf(mtxt, "typedef"); break;
case UMIN: sprintf(mtxt, "-"); break;
case UNLESS: sprintf(mtxt, "unless"); break;
}
strcat(b, mtxt);
}
void
purge(char *b)
{
if (strlen(b) == 0) return;
if (b[strlen(b)-1] != ':') /* label? */
{ if (b[0] == ':' && b[1] == ':')
{ indent--;
doindent();
indent++;
} else
{ doindent();
}
}
printf("%s\n", b);
strcpy(b, "");
in_decl = 0;
in_c_code = 0;
in_c_decl = 0;
}
int pp_mode;
extern int lex(void);
void
pretty_print(void)
{ int c, lastc = 0;
char buf[1024];
pp_mode = 1;
indent = 0;
strcpy(buf, "");
while ((c = lex()) != EOF)
{
if ((lastc == IF || lastc == DO) && c != SEP)
{ indent--; /* c_code if */
}
if (c == C_DECL || c == C_STATE
|| c == C_TRACK || c == SEP
|| c == DO || c == IF
|| (c == TYPE && !in_decl))
{ purge(buf); /* start on new line */
}
if (c == '{'
&& lastc != OF && lastc != IN
&& lastc != ATOMIC && lastc != D_STEP
&& lastc != C_CODE && lastc != C_DECL && lastc != C_EXPR)
{ purge(buf);
}
if (c == PREPROC)
{ int oi = indent;
purge(buf);
assert(strlen(yylval->sym->name) < sizeof(buf));
strcpy(buf, yylval->sym->name);
indent = 0;
purge(buf);
indent = oi;
continue;
}
if (c != ':' && c != SEMI
&& c != ',' && c != '('
&& c != '#' && lastc != '#'
&& c != ARROW && lastc != ARROW
&& c != '.' && lastc != '.'
&& c != '!' && lastc != '!'
&& c != SND && lastc != SND
&& c != RCV && lastc != RCV
&& c != O_SND && lastc != O_SND
&& c != R_RCV && lastc != R_RCV
&& (c != ']' || lastc != '[')
&& (c != '>' || lastc != '<')
&& (c != GT || lastc != LT)
&& c != '@' && lastc != '@'
&& c != DO && c != OD && c != IF && c != FI
&& c != SEP && strlen(buf) > 0)
strcat(buf, " ");
if (c == '}' || c == OD || c == FI)
{ purge(buf);
indent--;
}
blip(c, buf);
if (c == '{' || c == DO || c == IF)
{ purge(buf);
indent++;
}
if (c == '}' || c == BREAK || c == SEMI
|| (c == ':' && lastc == NAME))
{ purge(buf);
}
lastc = c;
}
purge(buf);
}