1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
#include "end.h"
#include "errloc.h"
#include "fn.h"
#include "stmt.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
void end_free(struct end *e)
{
}
int end_cgen(const struct end *e, struct cgen *c)
{
const struct stmt *s = &c->fn->stmts[e->block_i];
if (!s->end)
{
fprintf(stderr, "%s: unreachable\n", __func__);
return -1;
}
else if (s->end(s, c))
return -1;
printf("@__end%zu\n", e->block_i);
return 0;
}
int end(const struct lex *l, struct prv *p)
{
struct pos *pos = &p->pos[p->i];
struct fn *fn = fn_cur(p);
size_t nst = fn->nstmts + 1, *bl, bl_i;
struct stmt *s;
if (!fn->nblocks)
{
errloc(p->stk, "unexpected \"end\" statement");
return -1;
}
bl_i = fn->blocks[fn->nblocks - 1];
if (fn->nblocks > 1)
{
if (!(bl = realloc(fn->blocks, (fn->nblocks - 1) * sizeof *bl)))
{
perror("realloc(3)");
return -1;
}
fn->blocks = bl;
}
else
{
free(fn->blocks);
fn->blocks = NULL;
}
fn->nblocks--;
if (!(s = realloc(fn->stmts, nst * sizeof *s)))
{
perror("realloc(3)");
return -1;
}
s[fn->nstmts++] = (struct stmt)
{
.type = END,
.u.end.block_i = bl_i
};
fn->stmts = s;
pos->seq = pos->stseq = stmts;
pos->step = stmts->steps;
p->stk = p->tk;
fprintf(stderr, "\t\tadding end statement, block index %zu\n", bl_i);
return 1;
}
|