OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [stmt.c] - Blame information for rev 55

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 hellwig
#include "c.h"
2
 
3
static char rcsid[] = "$Id: stmt.c,v 1.1 2002/08/28 23:12:46 drh Exp $";
4
 
5
#define SWSIZE 512
6
 
7
#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
8
 
9
struct code codehead = { Start };
10
Code codelist = &codehead;
11
float density = 0.5;
12
Table stmtlabs;
13
 
14
static int foldcond(Tree e1, Tree e2);
15
static void caselabel(Swtch, long, int);
16
static void cmp(int, Symbol, long, int);
17
static Tree conditional(int);
18
static void dostmt(int, Swtch, int);
19
static int equal(Symbol, Symbol);
20
static void forstmt(int, Swtch, int);
21
static void ifstmt(int, int, Swtch, int);
22
static Symbol localaddr(Tree);
23
static void stmtlabel(void);
24
static void swstmt(int, int, int);
25
static void whilestmt(int, Swtch, int);
26
Code code(int kind) {
27
        Code cp;
28
 
29
        if (!reachable(kind))
30
                warning("unreachable code\n");
31
 
32
        NEW(cp, FUNC);
33
        cp->kind = kind;
34
        cp->prev = codelist;
35
        cp->next = NULL;
36
        codelist->next = cp;
37
        codelist = cp;
38
        return cp;
39
}
40
int reachable(int kind) {
41
        Code cp;
42
 
43
        if (kind > Start) {
44
                Code cp;
45
                for (cp = codelist; cp->kind < Label; )
46
                        cp = cp->prev;
47
                if (cp->kind == Jump || cp->kind == Switch)
48
                        return 0;
49
        }
50
        return 1;
51
}
52
void addlocal(Symbol p) {
53
        if (!p->defined) {
54
                code(Local)->u.var = p;
55
                p->defined = 1;
56
                p->scope = level;
57
        }
58
}
59
void definept(Coordinate *p) {
60
        Code cp = code(Defpoint);
61
 
62
        cp->u.point.src = p ? *p : src;
63
        cp->u.point.point = npoints;
64
        if (ncalled > 0) {
65
                int n = findcount(cp->u.point.src.file,
66
                        cp->u.point.src.x, cp->u.point.src.y);
67
                if (n > 0)
68
                        refinc = (float)n/ncalled;
69
        }
70
        if (glevel > 2) locus(identifiers, &cp->u.point.src);
71
        if (events.points && reachable(Gen))
72
                {
73
                        Tree e = NULL;
74
                        apply(events.points, &cp->u.point.src, &e);
75
                        if (e)
76
                                listnodes(e, 0, 0);
77
                }
78
}
79
void statement(int loop, Swtch swp, int lev) {
80
        float ref = refinc;
81
 
82
        if (Aflag >= 2 && lev == 15)
83
                warning("more than 15 levels of nested statements\n");
84
        switch (t) {
85
        case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
86
 break;
87
        case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
88
        case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
89
                                        break;
90
 
91
        case FOR:      forstmt(genlabel(4), swp, lev + 1);
92
 break;
93
        case BREAK:    walk(NULL, 0, 0);
94
                       definept(NULL);
95
                       if (swp && swp->lab > loop)
96
                        branch(swp->lab + 1);
97
                       else if (loop)
98
                        branch(loop + 2);
99
                       else
100
                        error("illegal break statement\n");
101
                       t = gettok(); expect(';');
102
                                           break;
103
 
104
        case CONTINUE: walk(NULL, 0, 0);
105
                       definept(NULL);
106
                       if (loop)
107
                        branch(loop + 1);
108
                       else
109
                        error("illegal continue statement\n");
110
                       t = gettok(); expect(';');
111
                                              break;
112
 
113
        case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
114
 break;
115
        case CASE:     {
116
                        int lab = genlabel(1);
117
                        if (swp == NULL)
118
                                error("illegal case label\n");
119
                        definelab(lab);
120
                        while (t == CASE) {
121
                                static char stop[] = { IF, ID, 0 };
122
                                Tree p;
123
                                t = gettok();
124
                                p = constexpr(0);
125
                                if (generic(p->op) == CNST && isint(p->type)) {
126
                                        if (swp) {
127
                                                needconst++;
128
                                                p = cast(p, swp->sym->type);
129
                                                if (p->type->op == UNSIGNED)
130
                                                        p->u.v.i = extend(p->u.v.u, p->type);
131
                                                needconst--;
132
                                                caselabel(swp, p->u.v.i, lab);
133
                                        }
134
                                } else
135
                                        error("case label must be a constant integer expression\n");
136
 
137
                                test(':', stop);
138
                        }
139
                        statement(loop, swp, lev);
140
                       } break;
141
        case DEFAULT:  if (swp == NULL)
142
                        error("illegal default label\n");
143
                       else if (swp->deflab)
144
                        error("extra default label\n");
145
                       else {
146
                        swp->deflab = findlabel(swp->lab);
147
                        definelab(swp->deflab->u.l.label);
148
                       }
149
                       t = gettok();
150
                       expect(':');
151
                       statement(loop, swp, lev); break;
152
        case RETURN:   {
153
                        Type rty = freturn(cfunc->type);
154
                        t = gettok();
155
                        definept(NULL);
156
                        if (t != ';')
157
                                if (rty == voidtype) {
158
                                        error("extraneous return value\n");
159
                                        expr(0);
160
                                        retcode(NULL);
161
                                } else
162
                                        retcode(expr(0));
163
                        else {
164
                                if (rty != voidtype) {
165
                                        warning("missing return value\n");
166
                                        retcode(cnsttree(inttype, 0L));
167
                                } else
168
                                        retcode(NULL);
169
                        }
170
                        branch(cfunc->u.f.label);
171
                       } expect(';');
172
                                            break;
173
 
174
        case '{':      compound(loop, swp, lev + 1); break;
175
        case ';':      definept(NULL); t = gettok(); break;
176
        case GOTO:     walk(NULL, 0, 0);
177
                       definept(NULL);
178
                       t = gettok();
179
                       if (t == ID) {
180
                        Symbol p = lookup(token, stmtlabs);
181
                        if (p == NULL) {
182
                                p = install(token, &stmtlabs, 0, FUNC);
183
                                p->scope = LABELS;
184
                                p->u.l.label = genlabel(1);
185
                                p->src = src;
186
                        }
187
                        use(p, src);
188
                        branch(p->u.l.label);
189
                        t = gettok();
190
                       } else
191
                        error("missing label in goto\n"); expect(';');
192
                                          break;
193
 
194
        case ID:       if (getchr() == ':') {
195
                        stmtlabel();
196
                        statement(loop, swp, lev);
197
                        break;
198
                       }
199
        default:       definept(NULL);
200
                       if (kind[t] != ID) {
201
                        error("unrecognized statement\n");
202
                        t = gettok();
203
                       } else {
204
                        Tree e = expr0(0);
205
                        listnodes(e, 0, 0);
206
                        if (nodecount == 0 || nodecount > 200)
207
                                walk(NULL, 0, 0);
208
                        else if (glevel) walk(NULL, 0, 0);
209
                        deallocate(STMT);
210
                       } expect(';');
211
                                                break;
212
 
213
        }
214
        if (kind[t] != IF && kind[t] != ID
215
        && t != '}' && t != EOI) {
216
                static char stop[] = { IF, ID, '}', 0 };
217
                error("illegal statement termination\n");
218
                skipto(0, stop);
219
        }
220
        refinc = ref;
221
}
222
 
223
static void ifstmt(int lab, int loop, Swtch swp, int lev) {
224
        t = gettok();
225
        expect('(');
226
        definept(NULL);
227
        walk(conditional(')'), 0, lab);
228
        refinc /= 2.0;
229
        statement(loop, swp, lev);
230
        if (t == ELSE) {
231
                branch(lab + 1);
232
                t = gettok();
233
                definelab(lab);
234
                statement(loop, swp, lev);
235
                if (findlabel(lab + 1)->ref)
236
                        definelab(lab + 1);
237
        } else
238
                definelab(lab);
239
}
240
static Tree conditional(int tok) {
241
        Tree p = expr(tok);
242
 
243
        if (Aflag > 1 && isfunc(p->type))
244
                warning("%s used in a conditional expression\n",
245
                        funcname(p));
246
        return cond(p);
247
}
248
static void stmtlabel(void) {
249
        Symbol p = lookup(token, stmtlabs);
250
 
251
        if (p == NULL) {
252
                p = install(token, &stmtlabs, 0, FUNC);
253
                p->scope = LABELS;
254
                p->u.l.label = genlabel(1);
255
                p->src = src;
256
        }
257
        if (p->defined)
258
                error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
259
 
260
        p->defined = 1;
261
        definelab(p->u.l.label);
262
        t = gettok();
263
        expect(':');
264
}
265
static void forstmt(int lab, Swtch swp, int lev) {
266
        int once = 0;
267
        Tree e1 = NULL, e2 = NULL, e3 = NULL;
268
        Coordinate pt2, pt3;
269
 
270
        t = gettok();
271
        expect('(');
272
        definept(NULL);
273
        if (kind[t] == ID)
274
                e1 = texpr(expr0, ';', FUNC);
275
        else
276
                expect(';');
277
        walk(e1, 0, 0);
278
        pt2 = src;
279
        refinc *= 10.0;
280
        if (kind[t] == ID)
281
                e2 = texpr(conditional, ';', FUNC);
282
        else
283
                expect(';');
284
        pt3 = src;
285
        if (kind[t] == ID)
286
                e3 = texpr(expr0, ')', FUNC);
287
        else {
288
                static char stop[] = { IF, ID, '}', 0 };
289
                test(')', stop);
290
        }
291
        if (e2) {
292
                once = foldcond(e1, e2);
293
                if (!once)
294
                        branch(lab + 3);
295
        }
296
        definelab(lab);
297
        statement(lab, swp, lev);
298
        definelab(lab + 1);
299
        definept(&pt3);
300
        if (e3)
301
                walk(e3, 0, 0);
302
        if (e2) {
303
                if (!once)
304
                        definelab(lab + 3);
305
                definept(&pt2);
306
                walk(e2, lab, 0);
307
        } else {
308
                definept(&pt2);
309
                branch(lab);
310
        }
311
        if (findlabel(lab + 2)->ref)
312
                definelab(lab + 2);
313
}
314
static void swstmt(int loop, int lab, int lev) {
315
        Tree e;
316
        struct swtch sw;
317
        Code head, tail;
318
 
319
        t = gettok();
320
        expect('(');
321
        definept(NULL);
322
        e = expr(')');
323
        if (!isint(e->type)) {
324
                error("illegal type `%t' in switch expression\n",
325
                        e->type);
326
                e = retype(e, inttype);
327
        }
328
        e = cast(e, promote(e->type));
329
        if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
330
        && e->kids[0]->u.sym->type == e->type
331
        && !isvolatile(e->kids[0]->u.sym->type)) {
332
                sw.sym = e->kids[0]->u.sym;
333
                walk(NULL, 0, 0);
334
        } else {
335
                sw.sym = genident(REGISTER, e->type, level);
336
                addlocal(sw.sym);
337
                walk(asgn(sw.sym, e), 0, 0);
338
        }
339
        head = code(Switch);
340
        sw.lab = lab;
341
        sw.deflab = NULL;
342
        sw.ncases = 0;
343
        sw.size = SWSIZE;
344
        sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
345
        sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
346
        refinc /= 10.0;
347
        statement(loop, &sw, lev);
348
        if (sw.deflab == NULL) {
349
                sw.deflab = findlabel(lab);
350
                definelab(lab);
351
                if (sw.ncases == 0)
352
                        warning("switch statement with no cases\n");
353
        }
354
        if (findlabel(lab + 1)->ref)
355
                definelab(lab + 1);
356
        tail = codelist;
357
        codelist = head->prev;
358
        codelist->next = head->prev = NULL;
359
        if (sw.ncases > 0)
360
                swgen(&sw);
361
        branch(lab);
362
        head->next->prev = codelist;
363
        codelist->next = head->next;
364
        codelist = tail;
365
}
366
static void caselabel(Swtch swp, long val, int lab) {
367
        int k;
368
 
369
        if (swp->ncases >= swp->size)
370
                {
371
                long   *vals = swp->values;
372
                Symbol *labs = swp->labels;
373
                swp->size *= 2;
374
                swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
375
                swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
376
                for (k = 0; k < swp->ncases; k++) {
377
                        swp->values[k] = vals[k];
378
                        swp->labels[k] = labs[k];
379
                }
380
                }
381
        k = swp->ncases;
382
        for ( ; k > 0 && swp->values[k-1] >= val; k--) {
383
                swp->values[k] = swp->values[k-1];
384
                swp->labels[k] = swp->labels[k-1];
385
        }
386
        if (k < swp->ncases && swp->values[k] == val)
387
                error("duplicate case label `%d'\n", val);
388
        swp->values[k] = val;
389
        swp->labels[k] = findlabel(lab);
390
        ++swp->ncases;
391
        if (Aflag >= 2 && swp->ncases == 258)
392
                warning("more than 257 cases in a switch\n");
393
}
394
void swgen(Swtch swp) {
395
        int *buckets, k, n;
396
        long *v = swp->values;
397
 
398
        buckets = newarray(swp->ncases + 1,
399
                sizeof *buckets, FUNC);
400
        for (n = k = 0; k < swp->ncases; k++, n++) {
401
                buckets[n] = k;
402
                while (n > 0 && den(n-1, k) >= density)
403
                        n--;
404
        }
405
        buckets[n] = swp->ncases;
406
        swcode(swp, buckets, 0, n - 1);
407
}
408
void swcode(Swtch swp, int b[], int lb, int ub) {
409
        int hilab, lolab, l, u, k = (lb + ub)/2;
410
        long *v = swp->values;
411
 
412
        if (k > lb && k < ub) {
413
                lolab = genlabel(1);
414
                hilab = genlabel(1);
415
        } else if (k > lb) {
416
                lolab = genlabel(1);
417
                hilab = swp->deflab->u.l.label;
418
        } else if (k < ub) {
419
                lolab = swp->deflab->u.l.label;
420
                hilab = genlabel(1);
421
        } else
422
                lolab = hilab = swp->deflab->u.l.label;
423
        l = b[k];
424
        u = b[k+1] - 1;
425
        if (u - l + 1 <= 3)
426
                {
427
                        int i;
428
                        for (i = l; i <= u; i++)
429
                                cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
430
                        if (k > lb && k < ub)
431
                                cmp(GT, swp->sym, v[u], hilab);
432
                        else if (k > lb)
433
                                cmp(GT, swp->sym, v[u], hilab);
434
                        else if (k < ub)
435
                                cmp(LT, swp->sym, v[l], lolab);
436
                        else
437
                                assert(lolab == hilab),
438
                                branch(lolab);
439
                        walk(NULL, 0, 0);
440
                }
441
        else {
442
                Tree e;
443
                Type ty = signedint(swp->sym->type);
444
                Symbol table = genident(STATIC,
445
                        array(voidptype, u - l + 1, 0), GLOBAL);
446
                (*IR->defsymbol)(table);
447
                if (!isunsigned(swp->sym->type) || v[l] != 0)
448
                        cmp(LT, swp->sym, v[l], lolab);
449
                cmp(GT, swp->sym, v[u], hilab);
450
                e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
451
                if (e->type->size < unsignedptr->size)
452
                        e = cast(e, unsignedlong);
453
                walk(tree(JUMP, voidtype,
454
                        rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
455
                        0, 0);
456
                code(Switch);
457
                codelist->u.swtch.table = table;
458
                codelist->u.swtch.sym = swp->sym;
459
                codelist->u.swtch.deflab = swp->deflab;
460
                codelist->u.swtch.size = u - l + 1;
461
                codelist->u.swtch.values = &v[l];
462
                codelist->u.swtch.labels = &swp->labels[l];
463
                if (v[u] - v[l] + 1 >= 10000)
464
                        warning("switch generates a huge table\n");
465
        }
466
        if (k > lb) {
467
                assert(lolab != swp->deflab->u.l.label);
468
                definelab(lolab);
469
                swcode(swp, b, lb, k - 1);
470
        }
471
        if (k < ub) {
472
                assert(hilab != swp->deflab->u.l.label);
473
                definelab(hilab);
474
                swcode(swp, b, k + 1, ub);
475
        }
476
}
477
static void cmp(int op, Symbol p, long n, int lab) {
478
        Type ty = signedint(p->type);
479
 
480
        listnodes(eqtree(op,
481
                        cast(idtree(p), ty),
482
                        cnsttree(ty, n)),
483
                lab, 0);
484
}
485
void retcode(Tree p) {
486
        Type ty;
487
 
488
        if (p == NULL) {
489
                if (events.returns)
490
                        apply(events.returns, cfunc, NULL);
491
                return;
492
        }
493
        p = pointer(p);
494
        ty = assign(freturn(cfunc->type), p);
495
        if (ty == NULL) {
496
                error("illegal return type; found `%t' expected `%t'\n",
497
                        p->type, freturn(cfunc->type));
498
                return;
499
        }
500
        p = cast(p, ty);
501
        if (retv)
502
                {
503
                        if (iscallb(p))
504
                                p = tree(RIGHT, p->type,
505
                                        tree(CALL+B, p->type,
506
                                                p->kids[0]->kids[0], idtree(retv)),
507
                                        rvalue(idtree(retv)));
508
                        else {
509
                                Type ty = retv->type->type;
510
                                assert(isstruct(ty));
511
                                if (ty->u.sym->u.s.cfields) {
512
                                        ty->u.sym->u.s.cfields = 0;
513
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
514
                                        ty->u.sym->u.s.cfields = 1;
515
                                } else
516
                                        p = asgntree(ASGN, rvalue(idtree(retv)), p);
517
                        }
518
                        walk(p, 0, 0);
519
                        if (events.returns)
520
                                apply(events.returns, cfunc, rvalue(idtree(retv)));
521
                        return;
522
                }
523
        if (events.returns)
524
                {
525
                        Symbol t1 = genident(AUTO, p->type, level);
526
                        addlocal(t1);
527
                        walk(asgn(t1, p), 0, 0);
528
                        apply(events.returns, cfunc, idtree(t1));
529
                        p = idtree(t1);
530
                }
531
        if (!isfloat(p->type))
532
                p = cast(p, promote(p->type));
533
        if (isptr(p->type))
534
                {
535
                        Symbol q = localaddr(p);
536
                        if (q && (q->computed || q->generated))
537
                                warning("pointer to a %s is an illegal return value\n",
538
                                        q->scope == PARAM ? "parameter" : "local");
539
                        else if (q)
540
                                warning("pointer to %s `%s' is an illegal return value\n",
541
                                        q->scope == PARAM ? "parameter" : "local", q->name);
542
                }
543
        walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
544
}
545
void definelab(int lab) {
546
        Code cp;
547
        Symbol p = findlabel(lab);
548
 
549
        assert(lab);
550
        walk(NULL, 0, 0);
551
        code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
552
        for (cp = codelist->prev; cp->kind <= Label; )
553
                cp = cp->prev;
554
        while (   cp->kind == Jump
555
               && cp->u.forest->kids[0]
556
               && specific(cp->u.forest->kids[0]->op) == ADDRG+P
557
               && cp->u.forest->kids[0]->syms[0] == p) {
558
                assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
559
                p->ref--;
560
                assert(cp->next);
561
                assert(cp->prev);
562
                cp->prev->next = cp->next;
563
                cp->next->prev = cp->prev;
564
                cp = cp->prev;
565
                while (cp->kind <= Label)
566
                        cp = cp->prev;
567
        }
568
}
569
Node jump(int lab) {
570
        Symbol p = findlabel(lab);
571
 
572
        p->ref++;
573
        return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
574
                NULL, NULL);
575
}
576
void branch(int lab) {
577
        Code cp;
578
        Symbol p = findlabel(lab);
579
 
580
        assert(lab);
581
        walk(NULL, 0, 0);
582
        code(Label)->u.forest = jump(lab);
583
        for (cp = codelist->prev; cp->kind < Label; )
584
                cp = cp->prev;
585
        while (   cp->kind == Label
586
               && cp->u.forest->op == LABEL+V
587
               && !equal(cp->u.forest->syms[0], p)) {
588
                equatelab(cp->u.forest->syms[0], p);
589
                assert(cp->next);
590
                assert(cp->prev);
591
                cp->prev->next = cp->next;
592
                cp->next->prev = cp->prev;
593
                cp = cp->prev;
594
                while (cp->kind < Label)
595
                        cp = cp->prev;
596
        }
597
        if (cp->kind == Jump || cp->kind == Switch) {
598
                p->ref--;
599
                codelist->prev->next = NULL;
600
                codelist = codelist->prev;
601
        } else {
602
                codelist->kind = Jump;
603
                if (cp->kind == Label
604
                &&  cp->u.forest->op == LABEL+V
605
                &&  equal(cp->u.forest->syms[0], p))
606
                        warning("source code specifies an infinite loop\n");
607
        }
608
}
609
void equatelab(Symbol old, Symbol new) {
610
        assert(old->u.l.equatedto == NULL);
611
        old->u.l.equatedto = new;
612
        new->ref++;
613
}
614
static int equal(Symbol lprime, Symbol dst) {
615
        assert(dst && lprime);
616
        for ( ; dst; dst = dst->u.l.equatedto)
617
                if (lprime == dst)
618
                        return 1;
619
        return 0;
620
}
621
/* dostmt - do statement while ( expression ) */
622
static void dostmt(int lab, Swtch swp, int lev) {
623
        refinc *= 10.0;
624
        t = gettok();
625
        definelab(lab);
626
        statement(lab, swp, lev);
627
        definelab(lab + 1);
628
        expect(WHILE);
629
        expect('(');
630
        definept(NULL);
631
        walk(conditional(')'), lab, 0);
632
        if (findlabel(lab + 2)->ref)
633
                definelab(lab + 2);
634
}
635
 
636
/* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
637
static int foldcond(Tree e1, Tree e2) {
638
        int op = generic(e2->op);
639
        Symbol v;
640
 
641
        if (e1 == 0 || e2 == 0)
642
                return 0;
643
        if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
644
        && generic(e1->kids[1]->op) == CNST) {
645
                v = e1->kids[0]->u.sym;
646
                e1 = e1->kids[1];
647
        } else
648
                return 0;
649
        if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
650
        && generic(e2->kids[0]->op) == INDIR
651
        && e2->kids[0]->kids[0]->u.sym == v
652
        && e2->kids[1]->op == e1->op) {
653
                e1 = simplify(op, e2->type, e1, e2->kids[1]);
654
                if (e1->op == CNST+I)
655
                        return e1->u.v.i;
656
        }
657
        return 0;
658
}
659
 
660
/* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
661
static Symbol localaddr(Tree p) {
662
        if (p == NULL)
663
                return NULL;
664
        switch (generic(p->op)) {
665
        case INDIR: case CALL: case ARG:
666
                return NULL;
667
        case ADDRL: case ADDRF:
668
                return p->u.sym;
669
        case RIGHT: case ASGN:
670
                if (p->kids[1])
671
                        return localaddr(p->kids[1]);
672
                return localaddr(p->kids[0]);
673
        case COND: {
674
                Symbol q;
675
                assert(p->kids[1] && p->kids[1]->op == RIGHT);
676
                if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
677
                        return q;
678
                return localaddr(p->kids[1]->kids[1]);
679
                }
680
        default: {
681
                Symbol q;
682
                if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
683
                        return q;
684
                return localaddr(p->kids[1]);
685
                }
686
        }
687
}
688
 
689
/* whilestmt - while ( expression ) statement */
690
static void whilestmt(int lab, Swtch swp, int lev) {
691
        Coordinate pt;
692
        Tree e;
693
 
694
        refinc *= 10.0;
695
        t = gettok();
696
        expect('(');
697
        walk(NULL, 0, 0);
698
        pt = src;
699
        e = texpr(conditional, ')', FUNC);
700
        branch(lab + 1);
701
        definelab(lab);
702
        statement(lab, swp, lev);
703
        definelab(lab + 1);
704
        definept(&pt);
705
        walk(e, lab, 0);
706
        if (findlabel(lab + 2)->ref)
707
                definelab(lab + 2);
708
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.