1219b2ee8SDavid du Colombier /***** spin: flow.c *****/
2219b2ee8SDavid du Colombier
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier */
8219b2ee8SDavid du Colombier
9219b2ee8SDavid du Colombier #include "spin.h"
10219b2ee8SDavid du Colombier #include "y.tab.h"
117dd7cddfSDavid du Colombier
127dd7cddfSDavid du Colombier extern Symbol *Fname;
13*de2caf28SDavid du Colombier extern int nr_errs, lineno, verbose, in_for, old_scope_rules, s_trail;
1400d97012SDavid du Colombier extern short has_unless, has_badelse, has_xu;
1500d97012SDavid du Colombier extern char CurScope[MAXSCOPESZ];
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier Element *Al_El = ZE;
18219b2ee8SDavid du Colombier Label *labtab = (Label *) 0;
197dd7cddfSDavid du Colombier int Unique = 0, Elcnt = 0, DstepStart = -1;
2000d97012SDavid du Colombier int initialization_ok = 1;
21*de2caf28SDavid du Colombier short has_accept;
22219b2ee8SDavid du Colombier
237dd7cddfSDavid du Colombier static Lbreak *breakstack = (Lbreak *) 0;
247dd7cddfSDavid du Colombier static Lextok *innermost;
257dd7cddfSDavid du Colombier static SeqList *cur_s = (SeqList *) 0;
267dd7cddfSDavid du Colombier static int break_id=0;
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier static Element *if_seq(Lextok *);
297dd7cddfSDavid du Colombier static Element *new_el(Lextok *);
307dd7cddfSDavid du Colombier static Element *unless_seq(Lextok *);
317dd7cddfSDavid du Colombier static void add_el(Element *, Sequence *);
327dd7cddfSDavid du Colombier static void attach_escape(Sequence *, Sequence *);
337dd7cddfSDavid du Colombier static void mov_lab(Symbol *, Element *, Element *);
347dd7cddfSDavid du Colombier static void walk_atomic(Element *, Element *, int);
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier void
open_seq(int top)37219b2ee8SDavid du Colombier open_seq(int top)
38219b2ee8SDavid du Colombier { SeqList *t;
39219b2ee8SDavid du Colombier Sequence *s = (Sequence *) emalloc(sizeof(Sequence));
40*de2caf28SDavid du Colombier s->minel = -1;
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier t = seqlist(s, cur_s);
43219b2ee8SDavid du Colombier cur_s = t;
4400d97012SDavid du Colombier if (top)
4500d97012SDavid du Colombier { Elcnt = 1;
4600d97012SDavid du Colombier initialization_ok = 1;
47*de2caf28SDavid du Colombier } else
48*de2caf28SDavid du Colombier { initialization_ok = 0;
4900d97012SDavid du Colombier }
50219b2ee8SDavid du Colombier }
51219b2ee8SDavid du Colombier
52219b2ee8SDavid du Colombier void
rem_Seq(void)53219b2ee8SDavid du Colombier rem_Seq(void)
54219b2ee8SDavid du Colombier {
55219b2ee8SDavid du Colombier DstepStart = Unique;
56219b2ee8SDavid du Colombier }
57219b2ee8SDavid du Colombier
58219b2ee8SDavid du Colombier void
unrem_Seq(void)59219b2ee8SDavid du Colombier unrem_Seq(void)
60219b2ee8SDavid du Colombier {
61219b2ee8SDavid du Colombier DstepStart = -1;
62219b2ee8SDavid du Colombier }
63219b2ee8SDavid du Colombier
647dd7cddfSDavid du Colombier static int
Rjumpslocal(Element * q,Element * stop)65219b2ee8SDavid du Colombier Rjumpslocal(Element *q, Element *stop)
66219b2ee8SDavid du Colombier { Element *lb, *f;
67219b2ee8SDavid du Colombier SeqList *h;
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier /* allow no jumps out of a d_step sequence */
70219b2ee8SDavid du Colombier for (f = q; f && f != stop; f = f->nxt)
71219b2ee8SDavid du Colombier { if (f && f->n && f->n->ntyp == GOTO)
72219b2ee8SDavid du Colombier { lb = get_lab(f->n, 0);
73219b2ee8SDavid du Colombier if (!lb || lb->Seqno < DstepStart)
74219b2ee8SDavid du Colombier { lineno = f->n->ln;
75219b2ee8SDavid du Colombier Fname = f->n->fn;
76219b2ee8SDavid du Colombier return 0;
77219b2ee8SDavid du Colombier } }
78219b2ee8SDavid du Colombier for (h = f->sub; h; h = h->nxt)
79219b2ee8SDavid du Colombier { if (!Rjumpslocal(h->this->frst, h->this->last))
80219b2ee8SDavid du Colombier return 0;
81219b2ee8SDavid du Colombier
82219b2ee8SDavid du Colombier } }
83219b2ee8SDavid du Colombier return 1;
84219b2ee8SDavid du Colombier }
85219b2ee8SDavid du Colombier
86219b2ee8SDavid du Colombier void
cross_dsteps(Lextok * a,Lextok * b)87219b2ee8SDavid du Colombier cross_dsteps(Lextok *a, Lextok *b)
88219b2ee8SDavid du Colombier {
89219b2ee8SDavid du Colombier if (a && b
90219b2ee8SDavid du Colombier && a->indstep != b->indstep)
91219b2ee8SDavid du Colombier { lineno = a->ln;
92219b2ee8SDavid du Colombier Fname = a->fn;
93*de2caf28SDavid du Colombier if (!s_trail)
94219b2ee8SDavid du Colombier fatal("jump into d_step sequence", (char *) 0);
95219b2ee8SDavid du Colombier }
96219b2ee8SDavid du Colombier }
97219b2ee8SDavid du Colombier
987dd7cddfSDavid du Colombier int
is_skip(Lextok * n)997dd7cddfSDavid du Colombier is_skip(Lextok *n)
1007dd7cddfSDavid du Colombier {
1017dd7cddfSDavid du Colombier return (n->ntyp == PRINT
102312a1df1SDavid du Colombier || n->ntyp == PRINTM
1037dd7cddfSDavid du Colombier || (n->ntyp == 'c'
1047dd7cddfSDavid du Colombier && n->lft
1057dd7cddfSDavid du Colombier && n->lft->ntyp == CONST
1067dd7cddfSDavid du Colombier && n->lft->val == 1));
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier void
check_sequence(Sequence * s)1107dd7cddfSDavid du Colombier check_sequence(Sequence *s)
1117dd7cddfSDavid du Colombier { Element *e, *le = ZE;
1127dd7cddfSDavid du Colombier Lextok *n;
1137dd7cddfSDavid du Colombier int cnt = 0;
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier for (e = s->frst; e; le = e, e = e->nxt)
1167dd7cddfSDavid du Colombier { n = e->n;
1177dd7cddfSDavid du Colombier if (is_skip(n) && !has_lab(e, 0))
1187dd7cddfSDavid du Colombier { cnt++;
119312a1df1SDavid du Colombier if (cnt > 1
120312a1df1SDavid du Colombier && n->ntyp != PRINT
121312a1df1SDavid du Colombier && n->ntyp != PRINTM)
1227dd7cddfSDavid du Colombier { if (verbose&32)
12300d97012SDavid du Colombier printf("spin: %s:%d, redundant skip\n",
12400d97012SDavid du Colombier n->fn->name, n->ln);
125312a1df1SDavid du Colombier if (e != s->frst
126312a1df1SDavid du Colombier && e != s->last
127312a1df1SDavid du Colombier && e != s->extent)
1287dd7cddfSDavid du Colombier { e->status |= DONE; /* not unreachable */
1297dd7cddfSDavid du Colombier le->nxt = e->nxt; /* remove it */
1307dd7cddfSDavid du Colombier e = le;
131312a1df1SDavid du Colombier }
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier } else
1347dd7cddfSDavid du Colombier cnt = 0;
1357dd7cddfSDavid du Colombier }
1367dd7cddfSDavid du Colombier }
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier void
prune_opts(Lextok * n)1397dd7cddfSDavid du Colombier prune_opts(Lextok *n)
1407dd7cddfSDavid du Colombier { SeqList *l;
1417dd7cddfSDavid du Colombier extern Symbol *context;
1427dd7cddfSDavid du Colombier extern char *claimproc;
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier if (!n
1457dd7cddfSDavid du Colombier || (context && claimproc && strcmp(context->name, claimproc) == 0))
1467dd7cddfSDavid du Colombier return;
1477dd7cddfSDavid du Colombier
1487dd7cddfSDavid du Colombier for (l = n->sl; l; l = l->nxt) /* find sequences of unlabeled skips */
1497dd7cddfSDavid du Colombier check_sequence(l->this);
1507dd7cddfSDavid du Colombier }
1517dd7cddfSDavid du Colombier
152219b2ee8SDavid du Colombier Sequence *
close_seq(int nottop)153219b2ee8SDavid du Colombier close_seq(int nottop)
154219b2ee8SDavid du Colombier { Sequence *s = cur_s->this;
155219b2ee8SDavid du Colombier Symbol *z;
156219b2ee8SDavid du Colombier
15700d97012SDavid du Colombier if (nottop == 0) /* end of proctype body */
15800d97012SDavid du Colombier { initialization_ok = 1;
15900d97012SDavid du Colombier }
16000d97012SDavid du Colombier
161*de2caf28SDavid du Colombier if (nottop > 0 && s->frst && (z = has_lab(s->frst, 0)))
162219b2ee8SDavid du Colombier { printf("error: (%s:%d) label %s placed incorrectly\n",
163219b2ee8SDavid du Colombier (s->frst->n)?s->frst->n->fn->name:"-",
164219b2ee8SDavid du Colombier (s->frst->n)?s->frst->n->ln:0,
165219b2ee8SDavid du Colombier z->name);
166219b2ee8SDavid du Colombier switch (nottop) {
167219b2ee8SDavid du Colombier case 1:
168219b2ee8SDavid du Colombier printf("=====> stmnt unless Label: stmnt\n");
169219b2ee8SDavid du Colombier printf("sorry, cannot jump to the guard of an\n");
170219b2ee8SDavid du Colombier printf("escape (it is not a unique state)\n");
171219b2ee8SDavid du Colombier break;
172219b2ee8SDavid du Colombier case 2:
173219b2ee8SDavid du Colombier printf("=====> instead of ");
174219b2ee8SDavid du Colombier printf("\"Label: stmnt unless stmnt\"\n");
175219b2ee8SDavid du Colombier printf("=====> always use ");
176219b2ee8SDavid du Colombier printf("\"Label: { stmnt unless stmnt }\"\n");
177219b2ee8SDavid du Colombier break;
178219b2ee8SDavid du Colombier case 3:
179219b2ee8SDavid du Colombier printf("=====> instead of ");
180219b2ee8SDavid du Colombier printf("\"atomic { Label: statement ... }\"\n");
181219b2ee8SDavid du Colombier printf("=====> always use ");
182219b2ee8SDavid du Colombier printf("\"Label: atomic { statement ... }\"\n");
183219b2ee8SDavid du Colombier break;
184219b2ee8SDavid du Colombier case 4:
185219b2ee8SDavid du Colombier printf("=====> instead of ");
186219b2ee8SDavid du Colombier printf("\"d_step { Label: statement ... }\"\n");
187219b2ee8SDavid du Colombier printf("=====> always use ");
188219b2ee8SDavid du Colombier printf("\"Label: d_step { statement ... }\"\n");
189219b2ee8SDavid du Colombier break;
190219b2ee8SDavid du Colombier case 5:
191219b2ee8SDavid du Colombier printf("=====> instead of ");
192219b2ee8SDavid du Colombier printf("\"{ Label: statement ... }\"\n");
193219b2ee8SDavid du Colombier printf("=====> always use ");
194219b2ee8SDavid du Colombier printf("\"Label: { statement ... }\"\n");
195219b2ee8SDavid du Colombier break;
196219b2ee8SDavid du Colombier case 6:
197219b2ee8SDavid du Colombier printf("=====> instead of\n");
198219b2ee8SDavid du Colombier printf(" do (or if)\n");
199219b2ee8SDavid du Colombier printf(" :: ...\n");
200219b2ee8SDavid du Colombier printf(" :: Label: statement\n");
201219b2ee8SDavid du Colombier printf(" od (of fi)\n");
202*de2caf28SDavid du Colombier printf("=====> use\n");
203219b2ee8SDavid du Colombier printf("Label: do (or if)\n");
204219b2ee8SDavid du Colombier printf(" :: ...\n");
205219b2ee8SDavid du Colombier printf(" :: statement\n");
206219b2ee8SDavid du Colombier printf(" od (or fi)\n");
207219b2ee8SDavid du Colombier break;
208219b2ee8SDavid du Colombier case 7:
209219b2ee8SDavid du Colombier printf("cannot happen - labels\n");
210219b2ee8SDavid du Colombier break;
211219b2ee8SDavid du Colombier }
212*de2caf28SDavid du Colombier if (nottop != 6)
213*de2caf28SDavid du Colombier { alldone(1);
214*de2caf28SDavid du Colombier } }
215219b2ee8SDavid du Colombier
216219b2ee8SDavid du Colombier if (nottop == 4
217219b2ee8SDavid du Colombier && !Rjumpslocal(s->frst, s->last))
218219b2ee8SDavid du Colombier fatal("non_local jump in d_step sequence", (char *) 0);
219219b2ee8SDavid du Colombier
220219b2ee8SDavid du Colombier cur_s = cur_s->nxt;
221219b2ee8SDavid du Colombier s->maxel = Elcnt;
222219b2ee8SDavid du Colombier s->extent = s->last;
2237dd7cddfSDavid du Colombier if (!s->last)
2247dd7cddfSDavid du Colombier fatal("sequence must have at least one statement", (char *) 0);
225219b2ee8SDavid du Colombier return s;
226219b2ee8SDavid du Colombier }
227219b2ee8SDavid du Colombier
228219b2ee8SDavid du Colombier Lextok *
do_unless(Lextok * No,Lextok * Es)229219b2ee8SDavid du Colombier do_unless(Lextok *No, Lextok *Es)
230219b2ee8SDavid du Colombier { SeqList *Sl;
231219b2ee8SDavid du Colombier Lextok *Re = nn(ZN, UNLESS, ZN, ZN);
232*de2caf28SDavid du Colombier
233219b2ee8SDavid du Colombier Re->ln = No->ln;
234219b2ee8SDavid du Colombier Re->fn = No->fn;
235219b2ee8SDavid du Colombier has_unless++;
236*de2caf28SDavid du Colombier
237219b2ee8SDavid du Colombier if (Es->ntyp == NON_ATOMIC)
238*de2caf28SDavid du Colombier { Sl = Es->sl;
239*de2caf28SDavid du Colombier } else
240219b2ee8SDavid du Colombier { open_seq(0); add_seq(Es);
241219b2ee8SDavid du Colombier Sl = seqlist(close_seq(1), 0);
242219b2ee8SDavid du Colombier }
243219b2ee8SDavid du Colombier
244219b2ee8SDavid du Colombier if (No->ntyp == NON_ATOMIC)
245219b2ee8SDavid du Colombier { No->sl->nxt = Sl;
246219b2ee8SDavid du Colombier Sl = No->sl;
247219b2ee8SDavid du Colombier } else if (No->ntyp == ':'
248219b2ee8SDavid du Colombier && (No->lft->ntyp == NON_ATOMIC
249219b2ee8SDavid du Colombier || No->lft->ntyp == ATOMIC
250219b2ee8SDavid du Colombier || No->lft->ntyp == D_STEP))
251219b2ee8SDavid du Colombier {
252219b2ee8SDavid du Colombier int tok = No->lft->ntyp;
253219b2ee8SDavid du Colombier
254219b2ee8SDavid du Colombier No->lft->sl->nxt = Sl;
255219b2ee8SDavid du Colombier Re->sl = No->lft->sl;
256219b2ee8SDavid du Colombier
257219b2ee8SDavid du Colombier open_seq(0); add_seq(Re);
258219b2ee8SDavid du Colombier Re = nn(ZN, tok, ZN, ZN);
259219b2ee8SDavid du Colombier Re->sl = seqlist(close_seq(7), 0);
260219b2ee8SDavid du Colombier Re->ln = No->ln;
261219b2ee8SDavid du Colombier Re->fn = No->fn;
262219b2ee8SDavid du Colombier
263219b2ee8SDavid du Colombier Re = nn(No, ':', Re, ZN); /* lift label */
264219b2ee8SDavid du Colombier Re->ln = No->ln;
265219b2ee8SDavid du Colombier Re->fn = No->fn;
266219b2ee8SDavid du Colombier return Re;
267219b2ee8SDavid du Colombier } else
268219b2ee8SDavid du Colombier { open_seq(0); add_seq(No);
269219b2ee8SDavid du Colombier Sl = seqlist(close_seq(2), Sl);
270219b2ee8SDavid du Colombier }
271219b2ee8SDavid du Colombier
272219b2ee8SDavid du Colombier Re->sl = Sl;
273219b2ee8SDavid du Colombier return Re;
274219b2ee8SDavid du Colombier }
275219b2ee8SDavid du Colombier
276219b2ee8SDavid du Colombier SeqList *
seqlist(Sequence * s,SeqList * r)277219b2ee8SDavid du Colombier seqlist(Sequence *s, SeqList *r)
278219b2ee8SDavid du Colombier { SeqList *t = (SeqList *) emalloc(sizeof(SeqList));
279219b2ee8SDavid du Colombier
280219b2ee8SDavid du Colombier t->this = s;
281219b2ee8SDavid du Colombier t->nxt = r;
282219b2ee8SDavid du Colombier return t;
283219b2ee8SDavid du Colombier }
284219b2ee8SDavid du Colombier
2857dd7cddfSDavid du Colombier static Element *
new_el(Lextok * n)286219b2ee8SDavid du Colombier new_el(Lextok *n)
287219b2ee8SDavid du Colombier { Element *m;
288219b2ee8SDavid du Colombier
289219b2ee8SDavid du Colombier if (n)
290219b2ee8SDavid du Colombier { if (n->ntyp == IF || n->ntyp == DO)
291219b2ee8SDavid du Colombier return if_seq(n);
292219b2ee8SDavid du Colombier if (n->ntyp == UNLESS)
293219b2ee8SDavid du Colombier return unless_seq(n);
294219b2ee8SDavid du Colombier }
295219b2ee8SDavid du Colombier m = (Element *) emalloc(sizeof(Element));
296219b2ee8SDavid du Colombier m->n = n;
297219b2ee8SDavid du Colombier m->seqno = Elcnt++;
298219b2ee8SDavid du Colombier m->Seqno = Unique++;
299219b2ee8SDavid du Colombier m->Nxt = Al_El; Al_El = m;
300219b2ee8SDavid du Colombier return m;
301219b2ee8SDavid du Colombier }
302219b2ee8SDavid du Colombier
3037dd7cddfSDavid du Colombier static int
has_chanref(Lextok * n)3047dd7cddfSDavid du Colombier has_chanref(Lextok *n)
3057dd7cddfSDavid du Colombier {
3067dd7cddfSDavid du Colombier if (!n) return 0;
3077dd7cddfSDavid du Colombier
3087dd7cddfSDavid du Colombier switch (n->ntyp) {
3097dd7cddfSDavid du Colombier case 's': case 'r':
3107dd7cddfSDavid du Colombier #if 0
3117dd7cddfSDavid du Colombier case 'R': case LEN:
3127dd7cddfSDavid du Colombier #endif
3137dd7cddfSDavid du Colombier case FULL: case NFULL:
3147dd7cddfSDavid du Colombier case EMPTY: case NEMPTY:
3157dd7cddfSDavid du Colombier return 1;
3167dd7cddfSDavid du Colombier default:
3177dd7cddfSDavid du Colombier break;
3187dd7cddfSDavid du Colombier }
3197dd7cddfSDavid du Colombier if (has_chanref(n->lft))
3207dd7cddfSDavid du Colombier return 1;
3217dd7cddfSDavid du Colombier
3227dd7cddfSDavid du Colombier return has_chanref(n->rgt);
3237dd7cddfSDavid du Colombier }
3247dd7cddfSDavid du Colombier
325312a1df1SDavid du Colombier void
loose_ends(void)326312a1df1SDavid du Colombier loose_ends(void) /* properly tie-up ends of sub-sequences */
327312a1df1SDavid du Colombier { Element *e, *f;
328312a1df1SDavid du Colombier
329312a1df1SDavid du Colombier for (e = Al_El; e; e = e->Nxt)
330312a1df1SDavid du Colombier { if (!e->n
331312a1df1SDavid du Colombier || !e->nxt)
332312a1df1SDavid du Colombier continue;
333312a1df1SDavid du Colombier switch (e->n->ntyp) {
334312a1df1SDavid du Colombier case ATOMIC:
335312a1df1SDavid du Colombier case NON_ATOMIC:
336312a1df1SDavid du Colombier case D_STEP:
337312a1df1SDavid du Colombier f = e->nxt;
338312a1df1SDavid du Colombier while (f && f->n->ntyp == '.')
339312a1df1SDavid du Colombier f = f->nxt;
340312a1df1SDavid du Colombier if (0) printf("link %d, {%d .. %d} -> %d (ntyp=%d) was %d\n",
341312a1df1SDavid du Colombier e->seqno,
342312a1df1SDavid du Colombier e->n->sl->this->frst->seqno,
343312a1df1SDavid du Colombier e->n->sl->this->last->seqno,
344312a1df1SDavid du Colombier f?f->seqno:-1, f?f->n->ntyp:-1,
345312a1df1SDavid du Colombier e->n->sl->this->last->nxt?e->n->sl->this->last->nxt->seqno:-1);
346312a1df1SDavid du Colombier if (!e->n->sl->this->last->nxt)
347312a1df1SDavid du Colombier e->n->sl->this->last->nxt = f;
348312a1df1SDavid du Colombier else
349312a1df1SDavid du Colombier { if (e->n->sl->this->last->nxt->n->ntyp != GOTO)
350312a1df1SDavid du Colombier { if (!f || e->n->sl->this->last->nxt->seqno != f->seqno)
351312a1df1SDavid du Colombier non_fatal("unexpected: loose ends", (char *)0);
352312a1df1SDavid du Colombier } else
353312a1df1SDavid du Colombier e->n->sl->this->last = e->n->sl->this->last->nxt;
354312a1df1SDavid du Colombier /*
355312a1df1SDavid du Colombier * fix_dest can push a goto into the nxt position
356312a1df1SDavid du Colombier * in that case the goto wins and f is not needed
357312a1df1SDavid du Colombier * but the last fields needs adjusting
358312a1df1SDavid du Colombier */
359312a1df1SDavid du Colombier }
360312a1df1SDavid du Colombier break;
361312a1df1SDavid du Colombier } }
362312a1df1SDavid du Colombier }
363312a1df1SDavid du Colombier
364*de2caf28SDavid du Colombier void
popbreak(void)365*de2caf28SDavid du Colombier popbreak(void)
366*de2caf28SDavid du Colombier {
367*de2caf28SDavid du Colombier if (!breakstack)
368*de2caf28SDavid du Colombier fatal("cannot happen, breakstack", (char *) 0);
369*de2caf28SDavid du Colombier
370*de2caf28SDavid du Colombier breakstack = breakstack->nxt; /* pop stack */
371*de2caf28SDavid du Colombier }
372*de2caf28SDavid du Colombier
373*de2caf28SDavid du Colombier static Lbreak *ob = (Lbreak *) 0;
374*de2caf28SDavid du Colombier
375*de2caf28SDavid du Colombier void
safe_break(void)376*de2caf28SDavid du Colombier safe_break(void)
377*de2caf28SDavid du Colombier {
378*de2caf28SDavid du Colombier ob = breakstack;
379*de2caf28SDavid du Colombier popbreak();
380*de2caf28SDavid du Colombier }
381*de2caf28SDavid du Colombier
382*de2caf28SDavid du Colombier void
restore_break(void)383*de2caf28SDavid du Colombier restore_break(void)
384*de2caf28SDavid du Colombier {
385*de2caf28SDavid du Colombier breakstack = ob;
386*de2caf28SDavid du Colombier ob = (Lbreak *) 0;
387*de2caf28SDavid du Colombier }
388*de2caf28SDavid du Colombier
3897dd7cddfSDavid du Colombier static Element *
if_seq(Lextok * n)390219b2ee8SDavid du Colombier if_seq(Lextok *n)
391219b2ee8SDavid du Colombier { int tok = n->ntyp;
392219b2ee8SDavid du Colombier SeqList *s = n->sl;
393219b2ee8SDavid du Colombier Element *e = new_el(ZN);
394219b2ee8SDavid du Colombier Element *t = new_el(nn(ZN,'.',ZN,ZN)); /* target */
395219b2ee8SDavid du Colombier SeqList *z, *prev_z = (SeqList *) 0;
396219b2ee8SDavid du Colombier SeqList *move_else = (SeqList *) 0; /* to end of optionlist */
3977dd7cddfSDavid du Colombier int ref_chans = 0;
398219b2ee8SDavid du Colombier
399219b2ee8SDavid du Colombier for (z = s; z; z = z->nxt)
4007dd7cddfSDavid du Colombier { if (!z->this->frst)
4017dd7cddfSDavid du Colombier continue;
4027dd7cddfSDavid du Colombier if (z->this->frst->n->ntyp == ELSE)
403219b2ee8SDavid du Colombier { if (move_else)
404219b2ee8SDavid du Colombier fatal("duplicate `else'", (char *) 0);
405219b2ee8SDavid du Colombier if (z->nxt) /* is not already at the end */
406219b2ee8SDavid du Colombier { move_else = z;
407219b2ee8SDavid du Colombier if (prev_z)
408219b2ee8SDavid du Colombier prev_z->nxt = z->nxt;
409219b2ee8SDavid du Colombier else
410219b2ee8SDavid du Colombier s = n->sl = z->nxt;
411219b2ee8SDavid du Colombier continue;
412219b2ee8SDavid du Colombier }
413219b2ee8SDavid du Colombier } else
4147dd7cddfSDavid du Colombier ref_chans |= has_chanref(z->this->frst->n);
415219b2ee8SDavid du Colombier prev_z = z;
416219b2ee8SDavid du Colombier }
417219b2ee8SDavid du Colombier if (move_else)
418219b2ee8SDavid du Colombier { move_else->nxt = (SeqList *) 0;
419219b2ee8SDavid du Colombier /* if there is no prev, then else was at the end */
420219b2ee8SDavid du Colombier if (!prev_z) fatal("cannot happen - if_seq", (char *) 0);
421219b2ee8SDavid du Colombier prev_z->nxt = move_else;
422219b2ee8SDavid du Colombier prev_z = move_else;
423219b2ee8SDavid du Colombier }
424219b2ee8SDavid du Colombier if (prev_z
4257dd7cddfSDavid du Colombier && ref_chans
426219b2ee8SDavid du Colombier && prev_z->this->frst->n->ntyp == ELSE)
4277dd7cddfSDavid du Colombier { prev_z->this->frst->n->val = 1;
4287dd7cddfSDavid du Colombier has_badelse++;
42900d97012SDavid du Colombier if (has_xu)
43000d97012SDavid du Colombier { fatal("invalid use of 'else' combined with i/o and xr/xs assertions,",
4317dd7cddfSDavid du Colombier (char *)0);
43200d97012SDavid du Colombier } else
43300d97012SDavid du Colombier { non_fatal("dubious use of 'else' combined with i/o,",
43400d97012SDavid du Colombier (char *)0);
43500d97012SDavid du Colombier }
4367dd7cddfSDavid du Colombier nr_errs--;
4377dd7cddfSDavid du Colombier }
438219b2ee8SDavid du Colombier
439219b2ee8SDavid du Colombier e->n = nn(n, tok, ZN, ZN);
440219b2ee8SDavid du Colombier e->n->sl = s; /* preserve as info only */
441219b2ee8SDavid du Colombier e->sub = s;
442*de2caf28SDavid du Colombier for (z = s; z; z = z->nxt)
443219b2ee8SDavid du Colombier add_el(t, z->this); /* append target */
444219b2ee8SDavid du Colombier if (tok == DO)
445219b2ee8SDavid du Colombier { add_el(t, cur_s->this); /* target upfront */
446219b2ee8SDavid du Colombier t = new_el(nn(n, BREAK, ZN, ZN)); /* break target */
447219b2ee8SDavid du Colombier set_lab(break_dest(), t); /* new exit */
448*de2caf28SDavid du Colombier popbreak();
449219b2ee8SDavid du Colombier }
450219b2ee8SDavid du Colombier add_el(e, cur_s->this);
451219b2ee8SDavid du Colombier add_el(t, cur_s->this);
452219b2ee8SDavid du Colombier return e; /* destination node for label */
453219b2ee8SDavid du Colombier }
454219b2ee8SDavid du Colombier
4557dd7cddfSDavid du Colombier static void
escape_el(Element * f,Sequence * e)4567dd7cddfSDavid du Colombier escape_el(Element *f, Sequence *e)
4577dd7cddfSDavid du Colombier { SeqList *z;
458219b2ee8SDavid du Colombier
4597dd7cddfSDavid du Colombier for (z = f->esc; z; z = z->nxt)
4607dd7cddfSDavid du Colombier if (z->this == e)
4617dd7cddfSDavid du Colombier return; /* already there */
4627dd7cddfSDavid du Colombier
4637dd7cddfSDavid du Colombier /* cover the lower-level escapes of this state */
4647dd7cddfSDavid du Colombier for (z = f->esc; z; z = z->nxt)
4657dd7cddfSDavid du Colombier attach_escape(z->this, e);
4667dd7cddfSDavid du Colombier
4677dd7cddfSDavid du Colombier /* now attach escape to the state itself */
4687dd7cddfSDavid du Colombier
4697dd7cddfSDavid du Colombier f->esc = seqlist(e, f->esc); /* in lifo order... */
470219b2ee8SDavid du Colombier #ifdef DEBUG
471219b2ee8SDavid du Colombier printf("attach %d (", e->frst->Seqno);
472219b2ee8SDavid du Colombier comment(stdout, e->frst->n, 0);
473219b2ee8SDavid du Colombier printf(") to %d (", f->Seqno);
474219b2ee8SDavid du Colombier comment(stdout, f->n, 0);
475219b2ee8SDavid du Colombier printf(")\n");
476219b2ee8SDavid du Colombier #endif
4777dd7cddfSDavid du Colombier switch (f->n->ntyp) {
4787dd7cddfSDavid du Colombier case UNLESS:
4797dd7cddfSDavid du Colombier attach_escape(f->sub->this, e);
4807dd7cddfSDavid du Colombier break;
4817dd7cddfSDavid du Colombier case IF:
4827dd7cddfSDavid du Colombier case DO:
4837dd7cddfSDavid du Colombier for (z = f->sub; z; z = z->nxt)
484219b2ee8SDavid du Colombier attach_escape(z->this, e);
4857dd7cddfSDavid du Colombier break;
4867dd7cddfSDavid du Colombier case D_STEP:
4877dd7cddfSDavid du Colombier /* attach only to the guard stmnt */
4887dd7cddfSDavid du Colombier escape_el(f->n->sl->this->frst, e);
4897dd7cddfSDavid du Colombier break;
4907dd7cddfSDavid du Colombier case ATOMIC:
4917dd7cddfSDavid du Colombier case NON_ATOMIC:
4927dd7cddfSDavid du Colombier /* attach to all stmnts */
4937dd7cddfSDavid du Colombier attach_escape(f->n->sl->this, e);
4947dd7cddfSDavid du Colombier break;
495219b2ee8SDavid du Colombier }
496219b2ee8SDavid du Colombier }
497219b2ee8SDavid du Colombier
4987dd7cddfSDavid du Colombier static void
attach_escape(Sequence * n,Sequence * e)4997dd7cddfSDavid du Colombier attach_escape(Sequence *n, Sequence *e)
5007dd7cddfSDavid du Colombier { Element *f;
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier for (f = n->frst; f; f = f->nxt)
5037dd7cddfSDavid du Colombier { escape_el(f, e);
5047dd7cddfSDavid du Colombier if (f == n->extent)
5057dd7cddfSDavid du Colombier break;
5067dd7cddfSDavid du Colombier }
5077dd7cddfSDavid du Colombier }
5087dd7cddfSDavid du Colombier
5097dd7cddfSDavid du Colombier static Element *
unless_seq(Lextok * n)510219b2ee8SDavid du Colombier unless_seq(Lextok *n)
511219b2ee8SDavid du Colombier { SeqList *s = n->sl;
512219b2ee8SDavid du Colombier Element *e = new_el(ZN);
513219b2ee8SDavid du Colombier Element *t = new_el(nn(ZN,'.',ZN,ZN)); /* target */
514219b2ee8SDavid du Colombier SeqList *z;
515219b2ee8SDavid du Colombier
516219b2ee8SDavid du Colombier e->n = nn(n, UNLESS, ZN, ZN);
517219b2ee8SDavid du Colombier e->n->sl = s; /* info only */
518219b2ee8SDavid du Colombier e->sub = s;
519219b2ee8SDavid du Colombier
5207dd7cddfSDavid du Colombier /* need 2 sequences: normal execution and escape */
521219b2ee8SDavid du Colombier if (!s || !s->nxt || s->nxt->nxt)
522219b2ee8SDavid du Colombier fatal("unexpected unless structure", (char *)0);
5237dd7cddfSDavid du Colombier
5247dd7cddfSDavid du Colombier /* append the target state to both */
525219b2ee8SDavid du Colombier for (z = s; z; z = z->nxt)
526219b2ee8SDavid du Colombier add_el(t, z->this);
5277dd7cddfSDavid du Colombier
5287dd7cddfSDavid du Colombier /* attach escapes to all states in normal sequence */
529219b2ee8SDavid du Colombier attach_escape(s->this, s->nxt->this);
530219b2ee8SDavid du Colombier
531219b2ee8SDavid du Colombier add_el(e, cur_s->this);
532219b2ee8SDavid du Colombier add_el(t, cur_s->this);
533219b2ee8SDavid du Colombier #ifdef DEBUG
534219b2ee8SDavid du Colombier printf("unless element (%d,%d):\n", e->Seqno, t->Seqno);
535219b2ee8SDavid du Colombier for (z = s; z; z = z->nxt)
536219b2ee8SDavid du Colombier { Element *x; printf("\t%d,%d,%d :: ",
537219b2ee8SDavid du Colombier z->this->frst->Seqno,
538219b2ee8SDavid du Colombier z->this->extent->Seqno,
539219b2ee8SDavid du Colombier z->this->last->Seqno);
540219b2ee8SDavid du Colombier for (x = z->this->frst; x; x = x->nxt)
541219b2ee8SDavid du Colombier printf("(%d)", x->Seqno);
542219b2ee8SDavid du Colombier printf("\n");
543219b2ee8SDavid du Colombier }
544219b2ee8SDavid du Colombier #endif
545219b2ee8SDavid du Colombier return e;
546219b2ee8SDavid du Colombier }
547219b2ee8SDavid du Colombier
548219b2ee8SDavid du Colombier Element *
mk_skip(void)549219b2ee8SDavid du Colombier mk_skip(void)
550219b2ee8SDavid du Colombier { Lextok *t = nn(ZN, CONST, ZN, ZN);
551219b2ee8SDavid du Colombier t->val = 1;
552219b2ee8SDavid du Colombier return new_el(nn(ZN, 'c', t, ZN));
553219b2ee8SDavid du Colombier }
554219b2ee8SDavid du Colombier
5557dd7cddfSDavid du Colombier static void
add_el(Element * e,Sequence * s)556219b2ee8SDavid du Colombier add_el(Element *e, Sequence *s)
557219b2ee8SDavid du Colombier {
558219b2ee8SDavid du Colombier if (e->n->ntyp == GOTO)
5597dd7cddfSDavid du Colombier { Symbol *z = has_lab(e, (1|2|4));
5607dd7cddfSDavid du Colombier if (z)
561219b2ee8SDavid du Colombier { Element *y; /* insert a skip */
562219b2ee8SDavid du Colombier y = mk_skip();
563219b2ee8SDavid du Colombier mov_lab(z, e, y); /* inherit label */
564219b2ee8SDavid du Colombier add_el(y, s);
565219b2ee8SDavid du Colombier } }
566219b2ee8SDavid du Colombier #ifdef DEBUG
567219b2ee8SDavid du Colombier printf("add_el %d after %d -- ",
568219b2ee8SDavid du Colombier e->Seqno, (s->last)?s->last->Seqno:-1);
569219b2ee8SDavid du Colombier comment(stdout, e->n, 0);
570219b2ee8SDavid du Colombier printf("\n");
571219b2ee8SDavid du Colombier #endif
572219b2ee8SDavid du Colombier if (!s->frst)
573219b2ee8SDavid du Colombier s->frst = e;
574219b2ee8SDavid du Colombier else
575219b2ee8SDavid du Colombier s->last->nxt = e;
576219b2ee8SDavid du Colombier s->last = e;
577219b2ee8SDavid du Colombier }
578219b2ee8SDavid du Colombier
5797dd7cddfSDavid du Colombier static Element *
colons(Lextok * n)580219b2ee8SDavid du Colombier colons(Lextok *n)
581219b2ee8SDavid du Colombier {
582219b2ee8SDavid du Colombier if (!n)
583219b2ee8SDavid du Colombier return ZE;
584219b2ee8SDavid du Colombier if (n->ntyp == ':')
585219b2ee8SDavid du Colombier { Element *e = colons(n->lft);
586219b2ee8SDavid du Colombier set_lab(n->sym, e);
587219b2ee8SDavid du Colombier return e;
588219b2ee8SDavid du Colombier }
589219b2ee8SDavid du Colombier innermost = n;
590219b2ee8SDavid du Colombier return new_el(n);
591219b2ee8SDavid du Colombier }
592219b2ee8SDavid du Colombier
593219b2ee8SDavid du Colombier void
add_seq(Lextok * n)594219b2ee8SDavid du Colombier add_seq(Lextok *n)
595219b2ee8SDavid du Colombier { Element *e;
596219b2ee8SDavid du Colombier
597219b2ee8SDavid du Colombier if (!n) return;
598219b2ee8SDavid du Colombier innermost = n;
599219b2ee8SDavid du Colombier e = colons(n);
600219b2ee8SDavid du Colombier if (innermost->ntyp != IF
601219b2ee8SDavid du Colombier && innermost->ntyp != DO
602219b2ee8SDavid du Colombier && innermost->ntyp != UNLESS)
603219b2ee8SDavid du Colombier add_el(e, cur_s->this);
604219b2ee8SDavid du Colombier }
605219b2ee8SDavid du Colombier
606219b2ee8SDavid du Colombier void
set_lab(Symbol * s,Element * e)607219b2ee8SDavid du Colombier set_lab(Symbol *s, Element *e)
608219b2ee8SDavid du Colombier { Label *l; extern Symbol *context;
60900d97012SDavid du Colombier int cur_uiid = is_inline();
610219b2ee8SDavid du Colombier
611219b2ee8SDavid du Colombier if (!s) return;
61200d97012SDavid du Colombier
6137dd7cddfSDavid du Colombier for (l = labtab; l; l = l->nxt)
61400d97012SDavid du Colombier { if (strcmp(l->s->name, s->name) == 0
61500d97012SDavid du Colombier && l->c == context
616*de2caf28SDavid du Colombier && (old_scope_rules || strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
61700d97012SDavid du Colombier && l->uiid == cur_uiid)
6187dd7cddfSDavid du Colombier { non_fatal("label %s redeclared", s->name);
6197dd7cddfSDavid du Colombier break;
62000d97012SDavid du Colombier } }
62100d97012SDavid du Colombier
622*de2caf28SDavid du Colombier if (strncmp(s->name, "accept", 6) == 0
623*de2caf28SDavid du Colombier && strncmp(s->name, "accept_all", 10) != 0)
624*de2caf28SDavid du Colombier { has_accept = 1;
625*de2caf28SDavid du Colombier }
626*de2caf28SDavid du Colombier
627219b2ee8SDavid du Colombier l = (Label *) emalloc(sizeof(Label));
628219b2ee8SDavid du Colombier l->s = s;
629219b2ee8SDavid du Colombier l->c = context;
630219b2ee8SDavid du Colombier l->e = e;
63100d97012SDavid du Colombier l->uiid = cur_uiid;
632219b2ee8SDavid du Colombier l->nxt = labtab;
633219b2ee8SDavid du Colombier labtab = l;
634219b2ee8SDavid du Colombier }
635219b2ee8SDavid du Colombier
63600d97012SDavid du Colombier static Label *
get_labspec(Lextok * n)63700d97012SDavid du Colombier get_labspec(Lextok *n)
63800d97012SDavid du Colombier { Symbol *s = n->sym;
63900d97012SDavid du Colombier Label *l, *anymatch = (Label *) 0;
640*de2caf28SDavid du Colombier int ln;
64100d97012SDavid du Colombier /*
642*de2caf28SDavid du Colombier * try to find a label with the same inline id (uiid)
643*de2caf28SDavid du Colombier * but if it doesn't exist, return any other match
644*de2caf28SDavid du Colombier * within the same scope
64500d97012SDavid du Colombier */
64600d97012SDavid du Colombier for (l = labtab; l; l = l->nxt)
647*de2caf28SDavid du Colombier { if (strcmp(l->s->name, s->name) == 0 /* labelname matches */
648*de2caf28SDavid du Colombier && s->context == l->s->context) /* same scope */
649*de2caf28SDavid du Colombier {
650*de2caf28SDavid du Colombier #if 0
651*de2caf28SDavid du Colombier if (anymatch && n->uiid == anymatch->uiid)
652*de2caf28SDavid du Colombier { if (0) non_fatal("label %s re-declared", s->name);
653*de2caf28SDavid du Colombier }
654*de2caf28SDavid du Colombier if (0)
655*de2caf28SDavid du Colombier { printf("Label %s uiid now::then %d :: %d bcsp %s :: %s\n",
656*de2caf28SDavid du Colombier s->name, n->uiid, l->uiid, s->bscp, l->s->bscp);
657*de2caf28SDavid du Colombier printf("get_labspec match on %s %s (bscp goto %s - label %s)\n",
658*de2caf28SDavid du Colombier s->name, s->context->name, s->bscp, l->s->bscp);
659*de2caf28SDavid du Colombier }
660*de2caf28SDavid du Colombier #endif
661*de2caf28SDavid du Colombier /* same block scope */
662*de2caf28SDavid du Colombier if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
663*de2caf28SDavid du Colombier { return l; /* definite match */
664*de2caf28SDavid du Colombier }
665*de2caf28SDavid du Colombier /* higher block scope */
666*de2caf28SDavid du Colombier ln = strlen((const char *) l->s->bscp);
667*de2caf28SDavid du Colombier if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0)
668*de2caf28SDavid du Colombier { anymatch = l; /* possible match */
669*de2caf28SDavid du Colombier } else if (!anymatch)
670*de2caf28SDavid du Colombier { anymatch = l; /* somewhere else in same context */
67100d97012SDavid du Colombier } } }
67200d97012SDavid du Colombier
673*de2caf28SDavid du Colombier return anymatch; /* return best match */
67400d97012SDavid du Colombier }
67500d97012SDavid du Colombier
676219b2ee8SDavid du Colombier Element *
get_lab(Lextok * n,int md)677219b2ee8SDavid du Colombier get_lab(Lextok *n, int md)
67800d97012SDavid du Colombier { Label *l = get_labspec(n);
679219b2ee8SDavid du Colombier
68000d97012SDavid du Colombier if (l != (Label *) 0)
68100d97012SDavid du Colombier { return (l->e);
68200d97012SDavid du Colombier }
683312a1df1SDavid du Colombier
68400d97012SDavid du Colombier if (md)
68500d97012SDavid du Colombier { lineno = n->ln;
686219b2ee8SDavid du Colombier Fname = n->fn;
68700d97012SDavid du Colombier fatal("undefined label %s", n->sym->name);
68800d97012SDavid du Colombier }
689219b2ee8SDavid du Colombier return ZE;
690219b2ee8SDavid du Colombier }
691219b2ee8SDavid du Colombier
692219b2ee8SDavid du Colombier Symbol *
has_lab(Element * e,int special)6937dd7cddfSDavid du Colombier has_lab(Element *e, int special)
694219b2ee8SDavid du Colombier { Label *l;
695219b2ee8SDavid du Colombier
696219b2ee8SDavid du Colombier for (l = labtab; l; l = l->nxt)
6977dd7cddfSDavid du Colombier { if (e != l->e)
6987dd7cddfSDavid du Colombier continue;
6997dd7cddfSDavid du Colombier if (special == 0
7007dd7cddfSDavid du Colombier || ((special&1) && !strncmp(l->s->name, "accept", 6))
7017dd7cddfSDavid du Colombier || ((special&2) && !strncmp(l->s->name, "end", 3))
7027dd7cddfSDavid du Colombier || ((special&4) && !strncmp(l->s->name, "progress", 8)))
703219b2ee8SDavid du Colombier return (l->s);
7047dd7cddfSDavid du Colombier }
705219b2ee8SDavid du Colombier return ZS;
706219b2ee8SDavid du Colombier }
707219b2ee8SDavid du Colombier
7087dd7cddfSDavid du Colombier static void
mov_lab(Symbol * z,Element * e,Element * y)709219b2ee8SDavid du Colombier mov_lab(Symbol *z, Element *e, Element *y)
710219b2ee8SDavid du Colombier { Label *l;
711219b2ee8SDavid du Colombier
712219b2ee8SDavid du Colombier for (l = labtab; l; l = l->nxt)
713219b2ee8SDavid du Colombier if (e == l->e)
714219b2ee8SDavid du Colombier { l->e = y;
715219b2ee8SDavid du Colombier return;
716219b2ee8SDavid du Colombier }
717219b2ee8SDavid du Colombier if (e->n)
718219b2ee8SDavid du Colombier { lineno = e->n->ln;
719219b2ee8SDavid du Colombier Fname = e->n->fn;
720219b2ee8SDavid du Colombier }
721219b2ee8SDavid du Colombier fatal("cannot happen - mov_lab %s", z->name);
722219b2ee8SDavid du Colombier }
723219b2ee8SDavid du Colombier
724219b2ee8SDavid du Colombier void
fix_dest(Symbol * c,Symbol * a)725312a1df1SDavid du Colombier fix_dest(Symbol *c, Symbol *a) /* c:label name, a:proctype name */
7267dd7cddfSDavid du Colombier { Label *l; extern Symbol *context;
727219b2ee8SDavid du Colombier
728312a1df1SDavid du Colombier #if 0
729312a1df1SDavid du Colombier printf("ref to label '%s' in proctype '%s', search:\n",
730312a1df1SDavid du Colombier c->name, a->name);
731312a1df1SDavid du Colombier for (l = labtab; l; l = l->nxt)
732312a1df1SDavid du Colombier printf(" %s in %s\n", l->s->name, l->c->name);
733312a1df1SDavid du Colombier #endif
734312a1df1SDavid du Colombier
735219b2ee8SDavid du Colombier for (l = labtab; l; l = l->nxt)
736219b2ee8SDavid du Colombier { if (strcmp(c->name, l->s->name) == 0
737312a1df1SDavid du Colombier && strcmp(a->name, l->c->name) == 0) /* ? */
738219b2ee8SDavid du Colombier break;
739219b2ee8SDavid du Colombier }
740219b2ee8SDavid du Colombier if (!l)
7417dd7cddfSDavid du Colombier { printf("spin: label '%s' (proctype %s)\n", c->name, a->name);
7427dd7cddfSDavid du Colombier non_fatal("unknown label '%s'", c->name);
7437dd7cddfSDavid du Colombier if (context == a)
7447dd7cddfSDavid du Colombier printf("spin: cannot remote ref a label inside the same proctype\n");
745219b2ee8SDavid du Colombier return;
746219b2ee8SDavid du Colombier }
747219b2ee8SDavid du Colombier if (!l->e || !l->e->n)
748219b2ee8SDavid du Colombier fatal("fix_dest error (%s)", c->name);
749219b2ee8SDavid du Colombier if (l->e->n->ntyp == GOTO)
750219b2ee8SDavid du Colombier { Element *y = (Element *) emalloc(sizeof(Element));
751219b2ee8SDavid du Colombier int keep_ln = l->e->n->ln;
752219b2ee8SDavid du Colombier Symbol *keep_fn = l->e->n->fn;
753219b2ee8SDavid du Colombier
754219b2ee8SDavid du Colombier /* insert skip - or target is optimized away */
755219b2ee8SDavid du Colombier y->n = l->e->n; /* copy of the goto */
756219b2ee8SDavid du Colombier y->seqno = find_maxel(a); /* unique seqno within proc */
757219b2ee8SDavid du Colombier y->nxt = l->e->nxt;
758219b2ee8SDavid du Colombier y->Seqno = Unique++; y->Nxt = Al_El; Al_El = y;
759219b2ee8SDavid du Colombier
760219b2ee8SDavid du Colombier /* turn the original element+seqno into a skip */
761219b2ee8SDavid du Colombier l->e->n = nn(ZN, 'c', nn(ZN, CONST, ZN, ZN), ZN);
762219b2ee8SDavid du Colombier l->e->n->ln = l->e->n->lft->ln = keep_ln;
763219b2ee8SDavid du Colombier l->e->n->fn = l->e->n->lft->fn = keep_fn;
764219b2ee8SDavid du Colombier l->e->n->lft->val = 1;
765219b2ee8SDavid du Colombier l->e->nxt = y; /* append the goto */
766219b2ee8SDavid du Colombier }
7677dd7cddfSDavid du Colombier l->e->status |= CHECK2; /* treat as if global */
768312a1df1SDavid du Colombier if (l->e->status & (ATOM | L_ATOM | D_ATOM))
769*de2caf28SDavid du Colombier { printf("spin: %s:%d, warning, reference to label ",
770*de2caf28SDavid du Colombier Fname->name, lineno);
771*de2caf28SDavid du Colombier printf("from inside atomic or d_step (%s)\n", c->name);
772312a1df1SDavid du Colombier }
773219b2ee8SDavid du Colombier }
774219b2ee8SDavid du Colombier
775219b2ee8SDavid du Colombier int
find_lab(Symbol * s,Symbol * c,int markit)7767dd7cddfSDavid du Colombier find_lab(Symbol *s, Symbol *c, int markit)
777*de2caf28SDavid du Colombier { Label *l, *pm = (Label *) 0, *apm = (Label *) 0;
778*de2caf28SDavid du Colombier int ln;
779219b2ee8SDavid du Colombier
780*de2caf28SDavid du Colombier /* generally called for remote references in never claims */
781219b2ee8SDavid du Colombier for (l = labtab; l; l = l->nxt)
782*de2caf28SDavid du Colombier {
783*de2caf28SDavid du Colombier if (strcmp(s->name, l->s->name) == 0
784219b2ee8SDavid du Colombier && strcmp(c->name, l->c->name) == 0)
785*de2caf28SDavid du Colombier { ln = strlen((const char *) l->s->bscp);
786*de2caf28SDavid du Colombier if (0)
787*de2caf28SDavid du Colombier { printf("want '%s' in context '%s', scope ref '%s' - label '%s'\n",
788*de2caf28SDavid du Colombier s->name, c->name, s->bscp, l->s->bscp);
789*de2caf28SDavid du Colombier }
790*de2caf28SDavid du Colombier /* same or higher block scope */
791*de2caf28SDavid du Colombier if (strcmp((const char *) s->bscp, (const char *) l->s->bscp) == 0)
792*de2caf28SDavid du Colombier { pm = l; /* definite match */
793*de2caf28SDavid du Colombier break;
794*de2caf28SDavid du Colombier }
795*de2caf28SDavid du Colombier if (strncmp((const char *) s->bscp, (const char *) l->s->bscp, ln) == 0)
796*de2caf28SDavid du Colombier { pm = l; /* possible match */
797*de2caf28SDavid du Colombier } else
798*de2caf28SDavid du Colombier { apm = l; /* remote */
799*de2caf28SDavid du Colombier } } }
800*de2caf28SDavid du Colombier
801*de2caf28SDavid du Colombier if (pm)
802*de2caf28SDavid du Colombier { pm->visible |= markit;
803*de2caf28SDavid du Colombier return pm->e->seqno;
804*de2caf28SDavid du Colombier }
805*de2caf28SDavid du Colombier if (apm)
806*de2caf28SDavid du Colombier { apm->visible |= markit;
807*de2caf28SDavid du Colombier return apm->e->seqno;
808*de2caf28SDavid du Colombier } /* else printf("Not Found\n"); */
809219b2ee8SDavid du Colombier return 0;
810219b2ee8SDavid du Colombier }
811219b2ee8SDavid du Colombier
812219b2ee8SDavid du Colombier void
pushbreak(void)813219b2ee8SDavid du Colombier pushbreak(void)
814219b2ee8SDavid du Colombier { Lbreak *r = (Lbreak *) emalloc(sizeof(Lbreak));
815219b2ee8SDavid du Colombier Symbol *l;
8167dd7cddfSDavid du Colombier char buf[64];
817219b2ee8SDavid du Colombier
818219b2ee8SDavid du Colombier sprintf(buf, ":b%d", break_id++);
819219b2ee8SDavid du Colombier l = lookup(buf);
820219b2ee8SDavid du Colombier r->l = l;
821219b2ee8SDavid du Colombier r->nxt = breakstack;
822219b2ee8SDavid du Colombier breakstack = r;
823219b2ee8SDavid du Colombier }
824219b2ee8SDavid du Colombier
825219b2ee8SDavid du Colombier Symbol *
break_dest(void)826219b2ee8SDavid du Colombier break_dest(void)
827219b2ee8SDavid du Colombier {
828219b2ee8SDavid du Colombier if (!breakstack)
829219b2ee8SDavid du Colombier fatal("misplaced break statement", (char *)0);
830219b2ee8SDavid du Colombier return breakstack->l;
831219b2ee8SDavid du Colombier }
832219b2ee8SDavid du Colombier
833219b2ee8SDavid du Colombier void
make_atomic(Sequence * s,int added)834219b2ee8SDavid du Colombier make_atomic(Sequence *s, int added)
835312a1df1SDavid du Colombier { Element *f;
836312a1df1SDavid du Colombier
837219b2ee8SDavid du Colombier walk_atomic(s->frst, s->last, added);
838312a1df1SDavid du Colombier
839312a1df1SDavid du Colombier f = s->last;
840312a1df1SDavid du Colombier switch (f->n->ntyp) { /* is last step basic stmnt or sequence ? */
841312a1df1SDavid du Colombier case NON_ATOMIC:
842312a1df1SDavid du Colombier case ATOMIC:
843312a1df1SDavid du Colombier /* redo and search for the last step of that sequence */
844312a1df1SDavid du Colombier make_atomic(f->n->sl->this, added);
845312a1df1SDavid du Colombier break;
846312a1df1SDavid du Colombier
847312a1df1SDavid du Colombier case UNLESS:
848312a1df1SDavid du Colombier /* escapes are folded into main sequence */
849312a1df1SDavid du Colombier make_atomic(f->sub->this, added);
850312a1df1SDavid du Colombier break;
851312a1df1SDavid du Colombier
852312a1df1SDavid du Colombier default:
853312a1df1SDavid du Colombier f->status &= ~ATOM;
854312a1df1SDavid du Colombier f->status |= L_ATOM;
855312a1df1SDavid du Colombier break;
856312a1df1SDavid du Colombier }
857219b2ee8SDavid du Colombier }
858219b2ee8SDavid du Colombier
85900d97012SDavid du Colombier #if 0
86000d97012SDavid du Colombier static int depth = 0;
86100d97012SDavid du Colombier void dump_sym(Symbol *, char *);
86200d97012SDavid du Colombier
86300d97012SDavid du Colombier void
86400d97012SDavid du Colombier dump_lex(Lextok *t, char *s)
86500d97012SDavid du Colombier { int i;
86600d97012SDavid du Colombier
86700d97012SDavid du Colombier depth++;
86800d97012SDavid du Colombier printf(s);
86900d97012SDavid du Colombier for (i = 0; i < depth; i++)
87000d97012SDavid du Colombier printf("\t");
87100d97012SDavid du Colombier explain(t->ntyp);
87200d97012SDavid du Colombier if (t->ntyp == NAME) printf(" %s ", t->sym->name);
87300d97012SDavid du Colombier if (t->ntyp == CONST) printf(" %d ", t->val);
87400d97012SDavid du Colombier if (t->ntyp == STRUCT)
87500d97012SDavid du Colombier { dump_sym(t->sym, "\n:Z:");
87600d97012SDavid du Colombier }
87700d97012SDavid du Colombier if (t->lft)
87800d97012SDavid du Colombier { dump_lex(t->lft, "\nL");
87900d97012SDavid du Colombier }
88000d97012SDavid du Colombier if (t->rgt)
88100d97012SDavid du Colombier { dump_lex(t->rgt, "\nR");
88200d97012SDavid du Colombier }
88300d97012SDavid du Colombier depth--;
88400d97012SDavid du Colombier }
88500d97012SDavid du Colombier void
88600d97012SDavid du Colombier dump_sym(Symbol *z, char *s)
88700d97012SDavid du Colombier { int i;
88800d97012SDavid du Colombier char txt[64];
88900d97012SDavid du Colombier depth++;
89000d97012SDavid du Colombier printf(s);
89100d97012SDavid du Colombier for (i = 0; i < depth; i++)
89200d97012SDavid du Colombier printf("\t");
89300d97012SDavid du Colombier
89400d97012SDavid du Colombier if (z->type == CHAN)
89500d97012SDavid du Colombier { if (z->ini && z->ini->rgt && z->ini->rgt->sym)
896*de2caf28SDavid du Colombier { /* dump_sym(z->ini->rgt->sym, "\n:I:"); -- could also be longer list */
89700d97012SDavid du Colombier if (z->ini->rgt->rgt
89800d97012SDavid du Colombier || !z->ini->rgt->sym)
89900d97012SDavid du Colombier fatal("chan %s in for should have only one field (a typedef)", z->name);
90000d97012SDavid du Colombier printf(" -- %s %p -- ", z->ini->rgt->sym->name, z->ini->rgt->sym);
90100d97012SDavid du Colombier }
90200d97012SDavid du Colombier } else if (z->type == STRUCT)
90300d97012SDavid du Colombier { if (z->Snm)
90400d97012SDavid du Colombier printf(" == %s %p == ", z->Snm->name, z->Snm);
90500d97012SDavid du Colombier else
90600d97012SDavid du Colombier { if (z->Slst)
90700d97012SDavid du Colombier dump_lex(z->Slst, "\n:X:");
90800d97012SDavid du Colombier if (z->ini)
90900d97012SDavid du Colombier dump_lex(z->ini, "\n:I:");
91000d97012SDavid du Colombier }
91100d97012SDavid du Colombier }
91200d97012SDavid du Colombier depth--;
91300d97012SDavid du Colombier
91400d97012SDavid du Colombier }
91500d97012SDavid du Colombier #endif
91600d97012SDavid du Colombier
91700d97012SDavid du Colombier int
match_struct(Symbol * s,Symbol * t)91800d97012SDavid du Colombier match_struct(Symbol *s, Symbol *t)
91900d97012SDavid du Colombier {
92000d97012SDavid du Colombier if (!t
92100d97012SDavid du Colombier || !t->ini
92200d97012SDavid du Colombier || !t->ini->rgt
92300d97012SDavid du Colombier || !t->ini->rgt->sym
92400d97012SDavid du Colombier || t->ini->rgt->rgt)
925*de2caf28SDavid du Colombier { fatal("chan %s in for should have only one field (a typedef)", t?t->name:"--");
92600d97012SDavid du Colombier }
92700d97012SDavid du Colombier /* we already know that s is a STRUCT */
92800d97012SDavid du Colombier if (0)
929*de2caf28SDavid du Colombier { printf("index type %s %p ==\n", s->Snm->name, (void *) s->Snm);
930*de2caf28SDavid du Colombier printf("chan type %s %p --\n\n", t->ini->rgt->sym->name, (void *) t->ini->rgt->sym);
93100d97012SDavid du Colombier }
93200d97012SDavid du Colombier
93300d97012SDavid du Colombier return (s->Snm == t->ini->rgt->sym);
93400d97012SDavid du Colombier }
93500d97012SDavid du Colombier
93600d97012SDavid du Colombier void
valid_name(Lextok * a3,Lextok * a5,Lextok * a8,char * tp)93700d97012SDavid du Colombier valid_name(Lextok *a3, Lextok *a5, Lextok *a8, char *tp)
93800d97012SDavid du Colombier {
93900d97012SDavid du Colombier if (a3->ntyp != NAME)
94000d97012SDavid du Colombier { fatal("%s ( .name : from .. to ) { ... }", tp);
94100d97012SDavid du Colombier }
94200d97012SDavid du Colombier if (a3->sym->type == CHAN
94300d97012SDavid du Colombier || a3->sym->type == STRUCT
94400d97012SDavid du Colombier || a3->sym->isarray != 0)
94500d97012SDavid du Colombier { fatal("bad index in for-construct %s", a3->sym->name);
94600d97012SDavid du Colombier }
94700d97012SDavid du Colombier if (a5->ntyp == CONST && a8->ntyp == CONST && a5->val > a8->val)
94800d97012SDavid du Colombier { non_fatal("start value for %s exceeds end-value", a3->sym->name);
94900d97012SDavid du Colombier }
95000d97012SDavid du Colombier }
95100d97012SDavid du Colombier
95200d97012SDavid du Colombier void
for_setup(Lextok * a3,Lextok * a5,Lextok * a8)95300d97012SDavid du Colombier for_setup(Lextok *a3, Lextok *a5, Lextok *a8)
95400d97012SDavid du Colombier { /* for ( a3 : a5 .. a8 ) */
95500d97012SDavid du Colombier
95600d97012SDavid du Colombier valid_name(a3, a5, a8, "for");
95700d97012SDavid du Colombier /* a5->ntyp = a8->ntyp = CONST; */
95800d97012SDavid du Colombier add_seq(nn(a3, ASGN, a3, a5)); /* start value */
95900d97012SDavid du Colombier open_seq(0);
96000d97012SDavid du Colombier add_seq(nn(ZN, 'c', nn(a3, LE, a3, a8), ZN)); /* condition */
96100d97012SDavid du Colombier }
96200d97012SDavid du Colombier
96300d97012SDavid du Colombier Lextok *
for_index(Lextok * a3,Lextok * a5)96400d97012SDavid du Colombier for_index(Lextok *a3, Lextok *a5)
96500d97012SDavid du Colombier { Lextok *z0, *z1, *z2, *z3;
96600d97012SDavid du Colombier Symbol *tmp_cnt;
967*de2caf28SDavid du Colombier char tmp_nm[MAXSCOPESZ+16];
96800d97012SDavid du Colombier /* for ( a3 in a5 ) { ... } */
96900d97012SDavid du Colombier
97000d97012SDavid du Colombier if (a3->ntyp != NAME)
97100d97012SDavid du Colombier { fatal("for ( .name in name ) { ... }", (char *) 0);
97200d97012SDavid du Colombier }
97300d97012SDavid du Colombier
97400d97012SDavid du Colombier if (a5->ntyp != NAME)
97500d97012SDavid du Colombier { fatal("for ( %s in .name ) { ... }", a3->sym->name);
97600d97012SDavid du Colombier }
97700d97012SDavid du Colombier
97800d97012SDavid du Colombier if (a3->sym->type == STRUCT)
97900d97012SDavid du Colombier { if (a5->sym->type != CHAN)
98000d97012SDavid du Colombier { fatal("for ( %s in .channel_name ) { ... }",
98100d97012SDavid du Colombier a3->sym->name);
98200d97012SDavid du Colombier }
98300d97012SDavid du Colombier z0 = a5->sym->ini;
98400d97012SDavid du Colombier if (!z0
98500d97012SDavid du Colombier || z0->val <= 0
98600d97012SDavid du Colombier || z0->rgt->ntyp != STRUCT
98700d97012SDavid du Colombier || z0->rgt->rgt != NULL)
98800d97012SDavid du Colombier { fatal("bad channel type %s in for", a5->sym->name);
98900d97012SDavid du Colombier }
99000d97012SDavid du Colombier
99100d97012SDavid du Colombier if (!match_struct(a3->sym, a5->sym))
99200d97012SDavid du Colombier { fatal("type of %s does not match chan", a3->sym->name);
99300d97012SDavid du Colombier }
99400d97012SDavid du Colombier
99500d97012SDavid du Colombier z1 = nn(ZN, CONST, ZN, ZN); z1->val = 0;
99600d97012SDavid du Colombier z2 = nn(a5, LEN, a5, ZN);
99700d97012SDavid du Colombier
99800d97012SDavid du Colombier sprintf(tmp_nm, "_f0r_t3mp%s", CurScope); /* make sure it's unique */
99900d97012SDavid du Colombier tmp_cnt = lookup(tmp_nm);
100000d97012SDavid du Colombier if (z0->val > 255) /* check nr of slots, i.e. max length */
100100d97012SDavid du Colombier { tmp_cnt->type = SHORT; /* should be rare */
100200d97012SDavid du Colombier } else
100300d97012SDavid du Colombier { tmp_cnt->type = BYTE;
100400d97012SDavid du Colombier }
100500d97012SDavid du Colombier z3 = nn(ZN, NAME, ZN, ZN);
100600d97012SDavid du Colombier z3->sym = tmp_cnt;
100700d97012SDavid du Colombier
100800d97012SDavid du Colombier add_seq(nn(z3, ASGN, z3, z1)); /* start value 0 */
100900d97012SDavid du Colombier
101000d97012SDavid du Colombier open_seq(0);
101100d97012SDavid du Colombier
101200d97012SDavid du Colombier add_seq(nn(ZN, 'c', nn(z3, LT, z3, z2), ZN)); /* condition */
101300d97012SDavid du Colombier
101400d97012SDavid du Colombier /* retrieve message from the right slot -- for now: rotate contents */
101500d97012SDavid du Colombier in_for = 0;
101600d97012SDavid du Colombier add_seq(nn(a5, 'r', a5, expand(a3, 1))); /* receive */
101700d97012SDavid du Colombier add_seq(nn(a5, 's', a5, expand(a3, 1))); /* put back in to rotate */
101800d97012SDavid du Colombier in_for = 1;
101900d97012SDavid du Colombier return z3;
102000d97012SDavid du Colombier } else
1021*de2caf28SDavid du Colombier { Lextok *leaf = a5;
1022*de2caf28SDavid du Colombier if (leaf->sym->type == STRUCT) // find leaf node, which should be an array
1023*de2caf28SDavid du Colombier { while (leaf->rgt
1024*de2caf28SDavid du Colombier && leaf->rgt->ntyp == '.')
1025*de2caf28SDavid du Colombier { leaf = leaf->rgt;
1026*de2caf28SDavid du Colombier }
1027*de2caf28SDavid du Colombier leaf = leaf->lft;
1028*de2caf28SDavid du Colombier // printf("%s %d\n", leaf->sym->name, leaf->sym->isarray);
1029*de2caf28SDavid du Colombier }
1030*de2caf28SDavid du Colombier
1031*de2caf28SDavid du Colombier if (leaf->sym->isarray == 0
1032*de2caf28SDavid du Colombier || leaf->sym->nel <= 0)
1033*de2caf28SDavid du Colombier { fatal("bad arrayname %s", leaf->sym->name);
103400d97012SDavid du Colombier }
103500d97012SDavid du Colombier z1 = nn(ZN, CONST, ZN, ZN); z1->val = 0;
1036*de2caf28SDavid du Colombier z2 = nn(ZN, CONST, ZN, ZN); z2->val = leaf->sym->nel - 1;
103700d97012SDavid du Colombier for_setup(a3, z1, z2);
103800d97012SDavid du Colombier return a3;
103900d97012SDavid du Colombier }
104000d97012SDavid du Colombier }
104100d97012SDavid du Colombier
104200d97012SDavid du Colombier Lextok *
for_body(Lextok * a3,int with_else)104300d97012SDavid du Colombier for_body(Lextok *a3, int with_else)
104400d97012SDavid du Colombier { Lextok *t1, *t2, *t0, *rv;
104500d97012SDavid du Colombier
104600d97012SDavid du Colombier rv = nn(ZN, CONST, ZN, ZN); rv->val = 1;
104700d97012SDavid du Colombier rv = nn(ZN, '+', a3, rv);
104800d97012SDavid du Colombier rv = nn(a3, ASGN, a3, rv);
104900d97012SDavid du Colombier add_seq(rv); /* initial increment */
105000d97012SDavid du Colombier
105100d97012SDavid du Colombier /* completed loop body, main sequence */
105200d97012SDavid du Colombier t1 = nn(ZN, 0, ZN, ZN);
105300d97012SDavid du Colombier t1->sq = close_seq(8);
105400d97012SDavid du Colombier
105500d97012SDavid du Colombier open_seq(0); /* add else -> break sequence */
105600d97012SDavid du Colombier if (with_else)
105700d97012SDavid du Colombier { add_seq(nn(ZN, ELSE, ZN, ZN));
105800d97012SDavid du Colombier }
105900d97012SDavid du Colombier t2 = nn(ZN, GOTO, ZN, ZN);
106000d97012SDavid du Colombier t2->sym = break_dest();
106100d97012SDavid du Colombier add_seq(t2);
106200d97012SDavid du Colombier t2 = nn(ZN, 0, ZN, ZN);
106300d97012SDavid du Colombier t2->sq = close_seq(9);
106400d97012SDavid du Colombier
106500d97012SDavid du Colombier t0 = nn(ZN, 0, ZN, ZN);
106600d97012SDavid du Colombier t0->sl = seqlist(t2->sq, seqlist(t1->sq, 0));
106700d97012SDavid du Colombier
106800d97012SDavid du Colombier rv = nn(ZN, DO, ZN, ZN);
106900d97012SDavid du Colombier rv->sl = t0->sl;
1070*de2caf28SDavid du Colombier
107100d97012SDavid du Colombier return rv;
107200d97012SDavid du Colombier }
107300d97012SDavid du Colombier
107400d97012SDavid du Colombier Lextok *
sel_index(Lextok * a3,Lextok * a5,Lextok * a7)107500d97012SDavid du Colombier sel_index(Lextok *a3, Lextok *a5, Lextok *a7)
107600d97012SDavid du Colombier { /* select ( a3 : a5 .. a7 ) */
107700d97012SDavid du Colombier
107800d97012SDavid du Colombier valid_name(a3, a5, a7, "select");
107900d97012SDavid du Colombier /* a5->ntyp = a7->ntyp = CONST; */
108000d97012SDavid du Colombier
108100d97012SDavid du Colombier add_seq(nn(a3, ASGN, a3, a5)); /* start value */
108200d97012SDavid du Colombier open_seq(0);
108300d97012SDavid du Colombier add_seq(nn(ZN, 'c', nn(a3, LT, a3, a7), ZN)); /* condition */
108400d97012SDavid du Colombier
1085*de2caf28SDavid du Colombier pushbreak(); /* new 6.2.1 */
108600d97012SDavid du Colombier return for_body(a3, 0); /* no else, just a non-deterministic break */
108700d97012SDavid du Colombier }
108800d97012SDavid du Colombier
10897dd7cddfSDavid du Colombier static void
walk_atomic(Element * a,Element * b,int added)1090219b2ee8SDavid du Colombier walk_atomic(Element *a, Element *b, int added)
10917dd7cddfSDavid du Colombier { Element *f; Symbol *ofn; int oln;
1092219b2ee8SDavid du Colombier SeqList *h;
1093219b2ee8SDavid du Colombier
10947dd7cddfSDavid du Colombier ofn = Fname;
10957dd7cddfSDavid du Colombier oln = lineno;
1096219b2ee8SDavid du Colombier for (f = a; ; f = f->nxt)
1097219b2ee8SDavid du Colombier { f->status |= (ATOM|added);
1098219b2ee8SDavid du Colombier switch (f->n->ntyp) {
1099219b2ee8SDavid du Colombier case ATOMIC:
11007dd7cddfSDavid du Colombier if (verbose&32)
1101*de2caf28SDavid du Colombier printf("spin: %s:%d, warning, atomic inside %s (ignored)\n",
110200d97012SDavid du Colombier f->n->fn->name, f->n->ln, (added)?"d_step":"atomic");
11037dd7cddfSDavid du Colombier goto mknonat;
1104219b2ee8SDavid du Colombier case D_STEP:
11057dd7cddfSDavid du Colombier if (!(verbose&32))
11067dd7cddfSDavid du Colombier { if (added) goto mknonat;
11077dd7cddfSDavid du Colombier break;
11087dd7cddfSDavid du Colombier }
1109*de2caf28SDavid du Colombier printf("spin: %s:%d, warning, d_step inside ",
111000d97012SDavid du Colombier f->n->fn->name, f->n->ln);
11117dd7cddfSDavid du Colombier if (added)
11127dd7cddfSDavid du Colombier { printf("d_step (ignored)\n");
11137dd7cddfSDavid du Colombier goto mknonat;
11147dd7cddfSDavid du Colombier }
11157dd7cddfSDavid du Colombier printf("atomic\n");
1116219b2ee8SDavid du Colombier break;
1117219b2ee8SDavid du Colombier case NON_ATOMIC:
11187dd7cddfSDavid du Colombier mknonat: f->n->ntyp = NON_ATOMIC; /* can jump here */
1119219b2ee8SDavid du Colombier h = f->n->sl;
1120219b2ee8SDavid du Colombier walk_atomic(h->this->frst, h->this->last, added);
1121219b2ee8SDavid du Colombier break;
1122312a1df1SDavid du Colombier case UNLESS:
1123312a1df1SDavid du Colombier if (added)
112400d97012SDavid du Colombier { printf("spin: error, %s:%d, unless in d_step (ignored)\n",
112500d97012SDavid du Colombier f->n->fn->name, f->n->ln);
1126312a1df1SDavid du Colombier }
1127219b2ee8SDavid du Colombier }
1128219b2ee8SDavid du Colombier for (h = f->sub; h; h = h->nxt)
1129219b2ee8SDavid du Colombier walk_atomic(h->this->frst, h->this->last, added);
1130219b2ee8SDavid du Colombier if (f == b)
1131219b2ee8SDavid du Colombier break;
1132219b2ee8SDavid du Colombier }
11337dd7cddfSDavid du Colombier Fname = ofn;
11347dd7cddfSDavid du Colombier lineno = oln;
1135219b2ee8SDavid du Colombier }
1136219b2ee8SDavid du Colombier
1137219b2ee8SDavid du Colombier void
dumplabels(void)1138219b2ee8SDavid du Colombier dumplabels(void)
1139219b2ee8SDavid du Colombier { Label *l;
1140219b2ee8SDavid du Colombier
1141219b2ee8SDavid du Colombier for (l = labtab; l; l = l->nxt)
1142219b2ee8SDavid du Colombier if (l->c != 0 && l->s->name[0] != ':')
114300d97012SDavid du Colombier { printf("label %s %d ",
114400d97012SDavid du Colombier l->s->name, l->e->seqno);
114500d97012SDavid du Colombier if (l->uiid == 0)
1146*de2caf28SDavid du Colombier printf("<%s>", l->c->name);
114700d97012SDavid du Colombier else
1148*de2caf28SDavid du Colombier printf("<%s i%d>", l->c->name, l->uiid);
1149*de2caf28SDavid du Colombier if (!old_scope_rules)
1150*de2caf28SDavid du Colombier { printf("\t{scope %s}", l->s->bscp);
1151*de2caf28SDavid du Colombier }
1152*de2caf28SDavid du Colombier printf("\n");
115300d97012SDavid du Colombier }
1154219b2ee8SDavid du Colombier }
1155