📄 spinlex.c
字号:
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; }}intc_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;}voidc_add_stack(FILE *fd){ C_Added *r; int cnt = 0; if ((!c_added && !c_tracked) || !has_stack) return; for (r = c_tracked; r; r = r->nxt) if (r->ival != ZS) cnt++; if (cnt == 0) return; fprintf(fd, " uchar c_stack["); cnt = 0; 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"); /* can't happen */ fprintf(fd, "];\n");}voidc_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 */}voidc_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"); while (*p == ' ' || *p == '\t') p++; if (strcmp(p, buf) == 0) fprintf(fd, " %s;\n", r->s->name); }}voidc_add_def(FILE *fd) /* 3 - called in plunk_c_fcts() */{ C_Added *r; fprintf(fd, "#if defined(C_States) && defined(HAS_TRACK)\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, "void\nc_stack(char *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); fprintf(fd, " 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(char *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); fprintf(fd, " printf(\"c_update %%u\\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(char *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); fprintf(fd, " 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(char *p_t_r)\n{\n"); fprintf(fd, "#ifdef VERBOSE\n"); fprintf(fd, " printf(\"c_revert %%u\\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");}voidplunk_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) { 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); }}voidplunk_c_decls(FILE *fd){ plunk_reverse(fd, seqnames, CODE_DECL);}voidplunk_c_fcts(FILE *fd){ if (separate == 2 && hastrack) { c_add_def(fd); return; } 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 (hastrack) c_add_def(fd); c_add_globinit(fd); do_locinits(fd);}static voidcheck_inline(IType *tmp){ char buf[128]; ProcList *p; if (!X) return; for (p = rdy; p; p = p->nxt) { if (strcmp(p->n->name, X->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->n->name, p->n->name); fatal("invalid variable ref in '%s'", tmp->nm->name); } }}voidplunk_expr(FILE *fd, char *s){ IType *tmp; tmp = find_inline(s); check_inline(tmp); fprintf(fd, "%s", (char *) tmp->cn);}voidpreruse(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;"); fprintf(fd, "trpt->st = tt; Uerror(\"%s\"); } ", 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); }}intglob_inline(char *s){ 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 */}voidplunk_inline(FILE *fd, char *s, int how) /* 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) { depth++; ", tmp->prec); fprintf(fd, "trpt++; trpt->pr = II; trpt->o_t = t;"); fprintf(fd, "trpt->st = tt; Uerror(\"%s\"); } ", tmp->prec); fprintf(fd, "else { printf(\"pan: precondition false: %s\\n\"); ", tmp->prec); fprintf(fd, "_m = 3; goto P999; } } "); } fprintf(fd, "%s", (char *) tmp->cn); fprintf(fd, " }\n");}voidno_side_effects(char *s){ IType *tmp; char *t; /* 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; if (strchr(t, ';') || strstr(t, "++") || strstr(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++; continue; } t++; if (*t != '=') goto bad; t++; }}voidpickup_inline(Symbol *t, Lextok *apars){ IType *tmp; Lextok *p, *q; int j; tmp = find_inline(t->name); if (++Inlining >= MAXINL) fatal("inline fcts too deeply nested", 0); tmp->cln = lineno; /* remember calling point */ tmp->cfn = Fname; /* and filename */ 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((int) 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: line %d, file %s, inlining '%s' (from line %d, file %s)\n", tmp->cln, tmp->cfn->name, t->name, tmp->dln, tmp->dfn->name);#endif for (j = 0; j < Inlining; j++) if (Inline_stub[j] == Inline_stub[Inlining]) fatal("cyclic inline attempt on: %s", t->name);}static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -