#include "end.h" #include "errloc.h" #include "fn.h" #include "stmt.h" #include #include #include 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; }