diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-05-09 02:56:07 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-06-21 01:15:38 +0200 |
| commit | b25ff71bb198c227b3202ee32a8067cda413bc16 (patch) | |
| tree | 41d665a87d948c10b17a853220cbcdbaeebf3672 /print.c | |
| download | prc-master.tar.gz | |
Diffstat (limited to 'print.c')
| -rw-r--r-- | print.c | 103 |
1 files changed, 103 insertions, 0 deletions
@@ -0,0 +1,103 @@ +#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 <stdlib.h> +#include <string.h> + +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; +} |
