1219b2ee8SDavid du Colombier /***** spin: dstep.c *****/
2219b2ee8SDavid du Colombier
3312a1df1SDavid du Colombier /* Copyright (c) 1989-2003 by Lucent Technologies, Bell Laboratories. */
47dd7cddfSDavid du Colombier /* All Rights Reserved. This software is for educational purposes only. */
5312a1df1SDavid du Colombier /* No guarantee whatsoever is expressed or implied by the distribution of */
6312a1df1SDavid du Colombier /* this code. Permission is given to distribute this code provided that */
7312a1df1SDavid du Colombier /* this introductory message is not removed and no monies are exchanged. */
8312a1df1SDavid du Colombier /* Software written by Gerard J. Holzmann. For tool documentation see: */
9312a1df1SDavid du Colombier /* http://spinroot.com/ */
10312a1df1SDavid du Colombier /* Send all bug-reports and/or questions to: bugs@spinroot.com */
11219b2ee8SDavid du Colombier
12219b2ee8SDavid du Colombier #include "spin.h"
13219b2ee8SDavid du Colombier #include "y.tab.h"
147dd7cddfSDavid du Colombier
15*00d97012SDavid du Colombier #define MAXDSTEP 2048 /* was 512 */
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier char *NextLab[64];
18219b2ee8SDavid du Colombier int Level=0, GenCode=0, IsGuard=0, TestOnly=0;
19219b2ee8SDavid du Colombier
207dd7cddfSDavid du Colombier static int Tj=0, Jt=0, LastGoto=0;
217dd7cddfSDavid du Colombier static int Tojump[MAXDSTEP], Jumpto[MAXDSTEP], Special[MAXDSTEP];
227dd7cddfSDavid du Colombier static void putCode(FILE *, Element *, Element *, Element *, int);
237dd7cddfSDavid du Colombier
24*00d97012SDavid du Colombier extern int Pid, separate, OkBreak;
257dd7cddfSDavid du Colombier
267dd7cddfSDavid du Colombier static void
Sourced(int n,int special)27219b2ee8SDavid du Colombier Sourced(int n, int special)
28219b2ee8SDavid du Colombier { int i;
29219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
30219b2ee8SDavid du Colombier if (Tojump[i] == n)
31219b2ee8SDavid du Colombier return;
327dd7cddfSDavid du Colombier if (Tj >= MAXDSTEP)
337dd7cddfSDavid du Colombier fatal("d_step sequence too long", (char *)0);
34219b2ee8SDavid du Colombier Special[Tj] = special;
35219b2ee8SDavid du Colombier Tojump[Tj++] = n;
36219b2ee8SDavid du Colombier }
37219b2ee8SDavid du Colombier
387dd7cddfSDavid du Colombier static void
Dested(int n)39219b2ee8SDavid du Colombier Dested(int n)
40219b2ee8SDavid du Colombier { int i;
41219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
42219b2ee8SDavid du Colombier if (Tojump[i] == n)
43219b2ee8SDavid du Colombier return;
44219b2ee8SDavid du Colombier for (i = 0; i < Jt; i++)
45219b2ee8SDavid du Colombier if (Jumpto[i] == n)
46219b2ee8SDavid du Colombier return;
477dd7cddfSDavid du Colombier if (Jt >= MAXDSTEP)
487dd7cddfSDavid du Colombier fatal("d_step sequence too long", (char *)0);
49219b2ee8SDavid du Colombier Jumpto[Jt++] = n;
507dd7cddfSDavid du Colombier LastGoto = 1;
51219b2ee8SDavid du Colombier }
52219b2ee8SDavid du Colombier
537dd7cddfSDavid du Colombier static void
Mopup(FILE * fd)54219b2ee8SDavid du Colombier Mopup(FILE *fd)
55312a1df1SDavid du Colombier { int i, j;
567dd7cddfSDavid du Colombier
57219b2ee8SDavid du Colombier for (i = 0; i < Jt; i++)
58219b2ee8SDavid du Colombier { for (j = 0; j < Tj; j++)
597dd7cddfSDavid du Colombier if (Tojump[j] == Jumpto[i])
60219b2ee8SDavid du Colombier break;
61219b2ee8SDavid du Colombier if (j == Tj)
62*00d97012SDavid du Colombier { char buf[16];
637dd7cddfSDavid du Colombier if (Jumpto[i] == OkBreak)
647dd7cddfSDavid du Colombier { if (!LastGoto)
657dd7cddfSDavid du Colombier fprintf(fd, "S_%.3d_0: /* break-dest */\n",
667dd7cddfSDavid du Colombier OkBreak);
677dd7cddfSDavid du Colombier } else {
68219b2ee8SDavid du Colombier sprintf(buf, "S_%.3d_0", Jumpto[i]);
69219b2ee8SDavid du Colombier non_fatal("goto %s breaks from d_step seq", buf);
707dd7cddfSDavid du Colombier } } }
71219b2ee8SDavid du Colombier for (j = 0; j < Tj; j++)
72219b2ee8SDavid du Colombier { for (i = 0; i < Jt; i++)
737dd7cddfSDavid du Colombier if (Tojump[j] == Jumpto[i])
74219b2ee8SDavid du Colombier break;
75219b2ee8SDavid du Colombier #ifdef DEBUG
76219b2ee8SDavid du Colombier if (i == Jt && !Special[i])
777dd7cddfSDavid du Colombier fprintf(fd, "\t\t/* no goto's to S_%.3d_0 */\n",
78219b2ee8SDavid du Colombier Tojump[j]);
79219b2ee8SDavid du Colombier #endif
80219b2ee8SDavid du Colombier }
81219b2ee8SDavid du Colombier for (j = i = 0; j < Tj; j++)
827dd7cddfSDavid du Colombier if (Special[j])
83219b2ee8SDavid du Colombier { Tojump[i] = Tojump[j];
84219b2ee8SDavid du Colombier Special[i] = 2;
857dd7cddfSDavid du Colombier if (i >= MAXDSTEP)
867dd7cddfSDavid du Colombier fatal("cannot happen (dstep.c)", (char *)0);
87219b2ee8SDavid du Colombier i++;
887dd7cddfSDavid du Colombier }
89219b2ee8SDavid du Colombier Tj = i; /* keep only the global exit-labels */
90219b2ee8SDavid du Colombier Jt = 0;
91219b2ee8SDavid du Colombier }
92219b2ee8SDavid du Colombier
937dd7cddfSDavid du Colombier static int
FirstTime(int n)94219b2ee8SDavid du Colombier FirstTime(int n)
95219b2ee8SDavid du Colombier { int i;
96219b2ee8SDavid du Colombier for (i = 0; i < Tj; i++)
97219b2ee8SDavid du Colombier if (Tojump[i] == n)
98219b2ee8SDavid du Colombier return (Special[i] <= 1);
99219b2ee8SDavid du Colombier return 1;
100219b2ee8SDavid du Colombier }
101219b2ee8SDavid du Colombier
1027dd7cddfSDavid du Colombier static void
illegal(Element * e,char * str)103219b2ee8SDavid du Colombier illegal(Element *e, char *str)
104219b2ee8SDavid du Colombier {
1057dd7cddfSDavid du Colombier printf("illegal operator in 'd_step:' '");
106219b2ee8SDavid du Colombier comment(stdout, e->n, 0);
107219b2ee8SDavid du Colombier printf("'\n");
1087dd7cddfSDavid du Colombier fatal("'%s'", str);
109219b2ee8SDavid du Colombier }
110219b2ee8SDavid du Colombier
1117dd7cddfSDavid du Colombier static void
filterbad(Element * e)112219b2ee8SDavid du Colombier filterbad(Element *e)
113219b2ee8SDavid du Colombier {
114219b2ee8SDavid du Colombier switch (e->n->ntyp) {
115219b2ee8SDavid du Colombier case ASSERT:
116219b2ee8SDavid du Colombier case PRINT:
117219b2ee8SDavid du Colombier case 'c':
118219b2ee8SDavid du Colombier /* run cannot be completely undone
119219b2ee8SDavid du Colombier * with sv_save-sv_restor
120219b2ee8SDavid du Colombier */
121219b2ee8SDavid du Colombier if (any_oper(e->n->lft, RUN))
1227dd7cddfSDavid du Colombier illegal(e, "run operator in d_step");
1237dd7cddfSDavid du Colombier
1247dd7cddfSDavid du Colombier /* remote refs inside d_step sequences
1257dd7cddfSDavid du Colombier * would be okay, but they cannot always
1267dd7cddfSDavid du Colombier * be interpreted by the simulator the
1277dd7cddfSDavid du Colombier * same as by the verifier (e.g., for an
1287dd7cddfSDavid du Colombier * error trail)
1297dd7cddfSDavid du Colombier */
1307dd7cddfSDavid du Colombier if (any_oper(e->n->lft, 'p'))
1317dd7cddfSDavid du Colombier illegal(e, "remote reference in d_step");
132219b2ee8SDavid du Colombier break;
133219b2ee8SDavid du Colombier case '@':
134219b2ee8SDavid du Colombier illegal(e, "process termination");
135219b2ee8SDavid du Colombier break;
136219b2ee8SDavid du Colombier case D_STEP:
137219b2ee8SDavid du Colombier illegal(e, "nested d_step sequence");
138219b2ee8SDavid du Colombier break;
139219b2ee8SDavid du Colombier case ATOMIC:
140219b2ee8SDavid du Colombier illegal(e, "nested atomic sequence");
141219b2ee8SDavid du Colombier break;
142219b2ee8SDavid du Colombier default:
143219b2ee8SDavid du Colombier break;
144219b2ee8SDavid du Colombier }
145219b2ee8SDavid du Colombier }
146219b2ee8SDavid du Colombier
1477dd7cddfSDavid du Colombier static int
CollectGuards(FILE * fd,Element * e,int inh)148219b2ee8SDavid du Colombier CollectGuards(FILE *fd, Element *e, int inh)
149219b2ee8SDavid du Colombier { SeqList *h; Element *ee;
150219b2ee8SDavid du Colombier
151219b2ee8SDavid du Colombier for (h = e->sub; h; h = h->nxt)
152219b2ee8SDavid du Colombier { ee = huntstart(h->this->frst);
153219b2ee8SDavid du Colombier filterbad(ee);
154219b2ee8SDavid du Colombier switch (ee->n->ntyp) {
1557dd7cddfSDavid du Colombier case NON_ATOMIC:
1567dd7cddfSDavid du Colombier inh += CollectGuards(fd, ee->n->sl->this->frst, inh);
1577dd7cddfSDavid du Colombier break;
158219b2ee8SDavid du Colombier case IF:
159219b2ee8SDavid du Colombier inh += CollectGuards(fd, ee, inh);
160219b2ee8SDavid du Colombier break;
161219b2ee8SDavid du Colombier case '.':
162219b2ee8SDavid du Colombier if (ee->nxt->n->ntyp == DO)
163219b2ee8SDavid du Colombier inh += CollectGuards(fd, ee->nxt, inh);
164219b2ee8SDavid du Colombier break;
165219b2ee8SDavid du Colombier case ELSE:
166219b2ee8SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
167*00d97012SDavid du Colombier /* 4.2.5 */ if (!pid_is_claim(Pid))
168f3793cddSDavid du Colombier fprintf(fd, "(boq == -1 /* else */)");
169f3793cddSDavid du Colombier else
170219b2ee8SDavid du Colombier fprintf(fd, "(1 /* else */)");
171219b2ee8SDavid du Colombier break;
1727dd7cddfSDavid du Colombier case 'R':
173312a1df1SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
174312a1df1SDavid du Colombier fprintf(fd, "("); TestOnly=1;
175312a1df1SDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
176312a1df1SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
177312a1df1SDavid du Colombier break;
1787dd7cddfSDavid du Colombier case 'r':
179312a1df1SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
180312a1df1SDavid du Colombier fprintf(fd, "("); TestOnly=1;
181312a1df1SDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
182312a1df1SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
183312a1df1SDavid du Colombier break;
1847dd7cddfSDavid du Colombier case 's':
1857dd7cddfSDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
1867dd7cddfSDavid du Colombier fprintf(fd, "("); TestOnly=1;
187*00d97012SDavid du Colombier /* 4.2.1 */ if (!pid_is_claim(Pid)) fprintf(fd, "(boq == -1) && ");
1887dd7cddfSDavid du Colombier putstmnt(fd, ee->n, ee->seqno);
1897dd7cddfSDavid du Colombier fprintf(fd, ")"); TestOnly=0;
1907dd7cddfSDavid du Colombier break;
191219b2ee8SDavid du Colombier case 'c':
192219b2ee8SDavid du Colombier if (inh++ > 0) fprintf(fd, " || ");
193219b2ee8SDavid du Colombier fprintf(fd, "("); TestOnly=1;
194*00d97012SDavid du Colombier if (!pid_is_claim(Pid))
1957dd7cddfSDavid du Colombier fprintf(fd, "(boq == -1 && ");
196219b2ee8SDavid du Colombier putstmnt(fd, ee->n->lft, e->seqno);
197*00d97012SDavid du Colombier if (!pid_is_claim(Pid))
1987dd7cddfSDavid du Colombier fprintf(fd, ")");
199219b2ee8SDavid du Colombier fprintf(fd, ")"); TestOnly=0;
200219b2ee8SDavid du Colombier break;
2017dd7cddfSDavid du Colombier } }
202219b2ee8SDavid du Colombier return inh;
203219b2ee8SDavid du Colombier }
204219b2ee8SDavid du Colombier
205219b2ee8SDavid du Colombier int
putcode(FILE * fd,Sequence * s,Element * nxt,int justguards,int ln,int seqno)206312a1df1SDavid du Colombier putcode(FILE *fd, Sequence *s, Element *nxt, int justguards, int ln, int seqno)
2077dd7cddfSDavid du Colombier { int isg=0; char buf[64];
208219b2ee8SDavid du Colombier
209219b2ee8SDavid du Colombier NextLab[0] = "continue";
210219b2ee8SDavid du Colombier filterbad(s->frst);
211219b2ee8SDavid du Colombier
212219b2ee8SDavid du Colombier switch (s->frst->n->ntyp) {
213219b2ee8SDavid du Colombier case UNLESS:
214219b2ee8SDavid du Colombier non_fatal("'unless' inside d_step - ignored", (char *) 0);
215312a1df1SDavid du Colombier return putcode(fd, s->frst->n->sl->this, nxt, 0, ln, seqno);
216219b2ee8SDavid du Colombier case NON_ATOMIC:
217312a1df1SDavid du Colombier (void) putcode(fd, s->frst->n->sl->this, ZE, 1, ln, seqno);
218219b2ee8SDavid du Colombier break;
219219b2ee8SDavid du Colombier case IF:
220219b2ee8SDavid du Colombier fprintf(fd, "if (!(");
221312a1df1SDavid du Colombier if (!CollectGuards(fd, s->frst, 0)) /* what about boq? */
222219b2ee8SDavid du Colombier fprintf(fd, "1");
223219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;");
224219b2ee8SDavid du Colombier isg = 1;
225219b2ee8SDavid du Colombier break;
226219b2ee8SDavid du Colombier case '.':
227219b2ee8SDavid du Colombier if (s->frst->nxt->n->ntyp == DO)
228219b2ee8SDavid du Colombier { fprintf(fd, "if (!(");
229219b2ee8SDavid du Colombier if (!CollectGuards(fd, s->frst->nxt, 0))
230219b2ee8SDavid du Colombier fprintf(fd, "1");
231219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;");
232219b2ee8SDavid du Colombier isg = 1;
233219b2ee8SDavid du Colombier }
234219b2ee8SDavid du Colombier break;
2357dd7cddfSDavid du Colombier case 'R': /* <- can't really happen (it's part of a 'c') */
236219b2ee8SDavid du Colombier fprintf(fd, "if (!("); TestOnly=1;
237219b2ee8SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
238219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
239219b2ee8SDavid du Colombier break;
240312a1df1SDavid du Colombier case 'r':
241312a1df1SDavid du Colombier fprintf(fd, "if (!("); TestOnly=1;
242312a1df1SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
243312a1df1SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
244312a1df1SDavid du Colombier break;
245312a1df1SDavid du Colombier case 's':
246312a1df1SDavid du Colombier fprintf(fd, "if (");
247312a1df1SDavid du Colombier #if 1
248*00d97012SDavid du Colombier /* 4.2.1 */ if (!pid_is_claim(Pid)) fprintf(fd, "(boq != -1) || ");
249312a1df1SDavid du Colombier #endif
250312a1df1SDavid du Colombier fprintf(fd, "!("); TestOnly=1;
251312a1df1SDavid du Colombier putstmnt(fd, s->frst->n, s->frst->seqno);
252312a1df1SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
253312a1df1SDavid du Colombier break;
254219b2ee8SDavid du Colombier case 'c':
2557dd7cddfSDavid du Colombier fprintf(fd, "if (!(");
256*00d97012SDavid du Colombier if (!pid_is_claim(Pid)) fprintf(fd, "boq == -1 && ");
2577dd7cddfSDavid du Colombier TestOnly=1;
258219b2ee8SDavid du Colombier putstmnt(fd, s->frst->n->lft, s->frst->seqno);
259219b2ee8SDavid du Colombier fprintf(fd, "))\n\t\t\tcontinue;"); TestOnly=0;
260219b2ee8SDavid du Colombier break;
261312a1df1SDavid du Colombier case ELSE:
262312a1df1SDavid du Colombier fprintf(fd, "if (boq != -1 || (");
263312a1df1SDavid du Colombier if (separate != 2) fprintf(fd, "trpt->");
264312a1df1SDavid du Colombier fprintf(fd, "o_pm&1))\n\t\t\tcontinue;");
265312a1df1SDavid du Colombier break;
2667dd7cddfSDavid du Colombier case ASGN: /* new 3.0.8 */
2677dd7cddfSDavid du Colombier fprintf(fd, "IfNotBlocked");
2687dd7cddfSDavid du Colombier break;
269219b2ee8SDavid du Colombier }
270219b2ee8SDavid du Colombier if (justguards) return 0;
271219b2ee8SDavid du Colombier
272312a1df1SDavid du Colombier fprintf(fd, "\n\t\tsv_save();\n\t\t");
273312a1df1SDavid du Colombier #if 1
274312a1df1SDavid du Colombier fprintf(fd, "reached[%d][%d] = 1;\n\t\t", Pid, seqno);
275312a1df1SDavid du Colombier fprintf(fd, "reached[%d][t->st] = 1;\n\t\t", Pid); /* true next state */
276312a1df1SDavid du Colombier fprintf(fd, "reached[%d][tt] = 1;\n", Pid); /* true current state */
277312a1df1SDavid du Colombier #endif
2787dd7cddfSDavid du Colombier sprintf(buf, "Uerror(\"block in d_step seq, line %d\")", ln);
2797dd7cddfSDavid du Colombier NextLab[0] = buf;
280219b2ee8SDavid du Colombier putCode(fd, s->frst, s->extent, nxt, isg);
281219b2ee8SDavid du Colombier
282219b2ee8SDavid du Colombier if (nxt)
283312a1df1SDavid du Colombier { extern Symbol *Fname;
284312a1df1SDavid du Colombier extern int lineno;
285312a1df1SDavid du Colombier
286312a1df1SDavid du Colombier if (FirstTime(nxt->Seqno)
287219b2ee8SDavid du Colombier && (!(nxt->status & DONE2) || !(nxt->status & D_ATOM)))
288219b2ee8SDavid du Colombier { fprintf(fd, "S_%.3d_0: /* 1 */\n", nxt->Seqno);
289219b2ee8SDavid du Colombier nxt->status |= DONE2;
290219b2ee8SDavid du Colombier LastGoto = 0;
291219b2ee8SDavid du Colombier }
292219b2ee8SDavid du Colombier Sourced(nxt->Seqno, 1);
293312a1df1SDavid du Colombier lineno = ln;
294312a1df1SDavid du Colombier Fname = nxt->n->fn;
295219b2ee8SDavid du Colombier Mopup(fd);
296219b2ee8SDavid du Colombier }
297219b2ee8SDavid du Colombier unskip(s->frst->seqno);
298219b2ee8SDavid du Colombier return LastGoto;
299219b2ee8SDavid du Colombier }
300219b2ee8SDavid du Colombier
3017dd7cddfSDavid du Colombier static void
putCode(FILE * fd,Element * f,Element * last,Element * next,int isguard)302219b2ee8SDavid du Colombier putCode(FILE *fd, Element *f, Element *last, Element *next, int isguard)
303219b2ee8SDavid du Colombier { Element *e, *N;
304219b2ee8SDavid du Colombier SeqList *h; int i;
3057dd7cddfSDavid du Colombier char NextOpt[64];
3067dd7cddfSDavid du Colombier static int bno = 0;
307219b2ee8SDavid du Colombier
308219b2ee8SDavid du Colombier for (e = f; e; e = e->nxt)
309219b2ee8SDavid du Colombier { if (e->status & DONE2)
310219b2ee8SDavid du Colombier continue;
311219b2ee8SDavid du Colombier e->status |= DONE2;
312219b2ee8SDavid du Colombier
313219b2ee8SDavid du Colombier if (!(e->status & D_ATOM))
314219b2ee8SDavid du Colombier { if (!LastGoto)
3157dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;\n",
3167dd7cddfSDavid du Colombier e->Seqno);
317219b2ee8SDavid du Colombier Dested(e->Seqno);
318219b2ee8SDavid du Colombier }
319219b2ee8SDavid du Colombier break;
320219b2ee8SDavid du Colombier }
321219b2ee8SDavid du Colombier fprintf(fd, "S_%.3d_0: /* 2 */\n", e->Seqno);
3227dd7cddfSDavid du Colombier LastGoto = 0;
323219b2ee8SDavid du Colombier Sourced(e->Seqno, 0);
324219b2ee8SDavid du Colombier
325219b2ee8SDavid du Colombier if (!e->sub)
326219b2ee8SDavid du Colombier { filterbad(e);
327219b2ee8SDavid du Colombier switch (e->n->ntyp) {
328219b2ee8SDavid du Colombier case NON_ATOMIC:
329219b2ee8SDavid du Colombier h = e->n->sl;
3307dd7cddfSDavid du Colombier putCode(fd, h->this->frst,
3317dd7cddfSDavid du Colombier h->this->extent, e->nxt, 0);
332219b2ee8SDavid du Colombier break;
333219b2ee8SDavid du Colombier case BREAK:
334219b2ee8SDavid du Colombier if (LastGoto) break;
3357dd7cddfSDavid du Colombier if (e->nxt)
3367dd7cddfSDavid du Colombier { i = target( huntele(e->nxt,
337312a1df1SDavid du Colombier e->status, -1))->Seqno;
3387dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3397dd7cddfSDavid du Colombier fprintf(fd, "/* 'break' */\n");
340219b2ee8SDavid du Colombier Dested(i);
3417dd7cddfSDavid du Colombier } else
3427dd7cddfSDavid du Colombier { if (next)
3437dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;",
3447dd7cddfSDavid du Colombier next->Seqno);
3457dd7cddfSDavid du Colombier fprintf(fd, " /* NEXT */\n");
3467dd7cddfSDavid du Colombier Dested(next->Seqno);
3477dd7cddfSDavid du Colombier } else
3487dd7cddfSDavid du Colombier fatal("cannot interpret d_step", 0);
3497dd7cddfSDavid du Colombier }
350219b2ee8SDavid du Colombier break;
351219b2ee8SDavid du Colombier case GOTO:
352219b2ee8SDavid du Colombier if (LastGoto) break;
3537dd7cddfSDavid du Colombier i = huntele( get_lab(e->n,1),
354312a1df1SDavid du Colombier e->status, -1)->Seqno;
3557dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3567dd7cddfSDavid du Colombier fprintf(fd, "/* 'goto' */\n");
357219b2ee8SDavid du Colombier Dested(i);
358219b2ee8SDavid du Colombier break;
359219b2ee8SDavid du Colombier case '.':
360219b2ee8SDavid du Colombier if (LastGoto) break;
3617dd7cddfSDavid du Colombier if (e->nxt && (e->nxt->status & DONE2))
362219b2ee8SDavid du Colombier { i = e->nxt?e->nxt->Seqno:0;
3637dd7cddfSDavid du Colombier fprintf(fd, "\t\tgoto S_%.3d_0;", i);
3647dd7cddfSDavid du Colombier fprintf(fd, " /* '.' */\n");
365219b2ee8SDavid du Colombier Dested(i);
366219b2ee8SDavid du Colombier }
367219b2ee8SDavid du Colombier break;
368219b2ee8SDavid du Colombier default:
369219b2ee8SDavid du Colombier putskip(e->seqno);
370219b2ee8SDavid du Colombier GenCode = 1; IsGuard = isguard;
371219b2ee8SDavid du Colombier fprintf(fd, "\t\t");
372219b2ee8SDavid du Colombier putstmnt(fd, e->n, e->seqno);
373219b2ee8SDavid du Colombier fprintf(fd, ";\n");
374219b2ee8SDavid du Colombier GenCode = IsGuard = isguard = LastGoto = 0;
375219b2ee8SDavid du Colombier break;
376219b2ee8SDavid du Colombier }
377219b2ee8SDavid du Colombier i = e->nxt?e->nxt->Seqno:0;
378219b2ee8SDavid du Colombier if (e->nxt && e->nxt->status & DONE2 && !LastGoto)
3797dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0; ", i);
3807dd7cddfSDavid du Colombier fprintf(fd, "/* ';' */\n");
381219b2ee8SDavid du Colombier Dested(i);
382219b2ee8SDavid du Colombier break;
383219b2ee8SDavid du Colombier }
384219b2ee8SDavid du Colombier } else
385219b2ee8SDavid du Colombier { for (h = e->sub, i=1; h; h = h->nxt, i++)
3867dd7cddfSDavid du Colombier { sprintf(NextOpt, "goto S_%.3d_%d",
3877dd7cddfSDavid du Colombier e->Seqno, i);
388219b2ee8SDavid du Colombier NextLab[++Level] = NextOpt;
389f3793cddSDavid du Colombier N = (e->n && e->n->ntyp == DO) ? e : e->nxt;
3907dd7cddfSDavid du Colombier putCode(fd, h->this->frst,
3917dd7cddfSDavid du Colombier h->this->extent, N, 1);
392219b2ee8SDavid du Colombier Level--;
393219b2ee8SDavid du Colombier fprintf(fd, "%s: /* 3 */\n", &NextOpt[5]);
3947dd7cddfSDavid du Colombier LastGoto = 0;
395219b2ee8SDavid du Colombier }
396219b2ee8SDavid du Colombier if (!LastGoto)
3977dd7cddfSDavid du Colombier { fprintf(fd, "\t\tUerror(\"blocking sel ");
3987dd7cddfSDavid du Colombier fprintf(fd, "in d_step (nr.%d, near line %d)\");\n",
3997dd7cddfSDavid du Colombier bno++, (e->n)?e->n->ln:0);
400219b2ee8SDavid du Colombier LastGoto = 0;
401219b2ee8SDavid du Colombier }
402219b2ee8SDavid du Colombier }
403219b2ee8SDavid du Colombier if (e == last)
404219b2ee8SDavid du Colombier { if (!LastGoto && next)
4057dd7cddfSDavid du Colombier { fprintf(fd, "\t\tgoto S_%.3d_0;\n",
4067dd7cddfSDavid du Colombier next->Seqno);
407219b2ee8SDavid du Colombier Dested(next->Seqno);
408219b2ee8SDavid du Colombier }
409219b2ee8SDavid du Colombier break;
410219b2ee8SDavid du Colombier } }
411219b2ee8SDavid du Colombier }
412