#include "print.h" #include "errloc.h" #include "fn.h" #include "lit.h" #include "parse.h" #include "prv.h" #include "stmt.h" #include "storage.h" #include "type.h" #include #include static int entry(const struct lex *l, const struct tk *tk, struct print *pr, struct prv *p) { size_t n = pr->nentries + 1; struct prientry *entries; const struct stentry *stentry = NULL; const struct fn *fn = fn_cur(p); const struct lit *lit = NULL; if (tk->type == ID) { const struct type *t = NULL; if ((t = type_find(fn, tk->s))) { if (t->type != C) { errloc(tk, "type \"%s\" not a constant", tk->s); return -1; } else if (!(lit = lit_push(t->tk, p))) return -1; } else if (!(stentry = fn_var(fn, tk))) { errloc(tk, "undefined reference to \"%s\"", tk->s); return -1; } } else if (tk->type == LIT && !(lit = lit_push(tk, p))) return -1; if (!(entries = realloc(pr->entries, n * sizeof *entries))) { perror("realloc(3)"); return -1; } pr->entries = entries; pr->entries[pr->nentries++] = (struct prientry) { .tk = tk, .lit = lit, .entry = stentry }; return 0; } void print_free(struct print *pr) { free(pr->entries); } int print(const struct lex *l, struct prv *p, int (*fn)(const struct lex *, const struct prv *, const struct print *)) { const struct tk *tk = p->stk + 1; struct print pr = {0}; struct pos *pos = &p->pos[p->i]; int eof; if (lex_eof(l, tk)) { errloc(tk - 1, "incomplete %s statement", p->stk->s); return -1; } for (;;) if (entry(l, tk, &pr, p)) goto failure; else if ((eof = lex_eof(l, ++tk)) || kw(tk->s)) break; if (eof || strcmp(tk->s, "etc")) pr.println = 1; else if (!eof) tk++; if (fn(l, p, &pr)) goto failure; pos->seq = pos->stseq = stmts; pos->step = stmts->steps; p->stk = tk; return 1; failure: print_free(&pr); return -1; }