📄 pangen2.c
字号:
/* end */ /* the src xrefs have the numbers in e->seqno builtin */ fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, e->seqno); doforward(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(tm, "/* stop at bad hop %d, %d */\n\t\t", f->seqno, ntarget); goto out; } fprintf(tm, "/* merge: "); comment(tm, f->n, 0); fprintf(tm, "(%d, %d, %d) */\n\t\t", f->merge, f->seqno, ntarget); fprintf(tm, "reached[%d][%d] = 1;\n\t\t", Pid, f->seqno); YZcnt++; lab_transfer(e, f); mark = f->status&(ATOM|L_ATOM); /* last step wins */ doforward(tm, f); if (f->merge_in == 1) f->merge_mark++; goto more; } }out: fprintf(tm, "_m = %d", getweight(e->n)); if (m_loss && e->n->ntyp == 's') fprintf(tm, "+delta_m; delta_m = 0"); fprintf(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(tb, ";\n\t\t"); if (e->merge || e->merge_start) { if (!didcase) { fprintf(tb, "\n\tcase %d: ", casenr); fprintf(tb, "/* STATE %d */", e->seqno); didcase++; } else fprintf(tb, ";"); } else fprintf(tb, ";"); fprintf(tb, "\n\t\t"); if (multi_undo) { fprintf(tb, "ungrab_ints(trpt->bup.ovals, %d);\n\t\t", multi_undo); multi_undo = 0; } if (didcase) { fprintf(tb, "goto R999;\n"); bupcase = casenr; } if (!e->merge && !e->merge_start) new_case(e, casenr, bupcase, Pid);gotit: j = a; if (e->merge_start) j = e->merge_start; else if (e->merge) j = e->merge;haveit: fprintf(tt, "%ssettr(%d,%d,%d,%d,%d,\"", fromcache?"/* c */ ":"", e->Seqno, mark, j, casenr, bupcase); return (fromcache)?0:casenr;}static voidput_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(tt, "\ttrans[%d][%d]\t= ", Pid, e->seqno); fprintf(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;#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: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); comment(tt, e->n, e->seqno); fprintf(tt, "\", %d, ", Global_ref); if (Tt0 != 2) { fprintf(tt, "%d, %d);", Tt0, Tt1); } else { Tpe(e->n); /* sets EPT */ fprintf(tt, "%d, %d);", EPT[0], EPT[1]); } if ((e->merge_start && e->merge_start != a) || (e->merge && e->merge != a)) { fprintf(tt, " /* m: %d -> %d,%d */\n", a, e->merge_start, e->merge); fprintf(tt, " reached%d[%d] = 1;", Pid, a); /* Sheinman's example */ } fprintf(tt, "\n"); if (casenr > 2) tr_map(casenr, e); put_escp(e);}static voidnested_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"); }}static voidput_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(tt, "\tT = trans[%d][%d] = ", Pid, e->seqno); fprintf(tt, "settr(%d,%d,0,0,0,\"", e->Seqno, e->status&ATOM); comment(tt, e->n, e->seqno); if (e->status&CHECK2) e->status |= I_GLOB; fprintf(tt, "\", %d, %d, %d);", (e->status&I_GLOB)?1:0, Tt0, Tt1); blurb(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(tt, "#if 0\n\t/* dead link: */\n"); deadlink = 1; if (verbose&32) printf("spin: line %3d %s, Warning: condition is always false\n", g->n->ln, g->n->fn?g->n->fn->name:""); } else deadlink = 0; if (0) printf(" settr %d %d\n", a, 0); if (h->nxt) fprintf(tt, "\tT = T->nxt\t= "); else fprintf(tt, "\t T->nxt\t= "); fprintf(tt, "settr(%d,%d,%d,0,0,\"", e->Seqno, e->status&ATOM, a); comment(tt, e->n, e->seqno); if (g->status&CHECK2) h->this->frst->status |= I_GLOB; fprintf(tt, "\", %d, %d, %d);", (h->this->frst->status&I_GLOB)?1:0, Tt0, Tt1); blurb(tt, e); if (deadlink) fprintf(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");}static voidpatch_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; }}static voidmark_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; }}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 *target(Element *e){ if (!e) return e; lineno = e->n->ln; Fname = e->n->fn; t_cyc = 0; return find_target(e);}static intseq_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;}static intscan_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);#if 1 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)))#endif { fprintf(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;}static intglob_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;}static intproc_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 = rdy; 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;}inthas_global(Lextok *n){ Lextok *v; 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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -