aboutsummaryrefslogtreecommitdiff
path: root/print.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-05-09 02:56:07 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-06-21 01:15:38 +0200
commitb25ff71bb198c227b3202ee32a8067cda413bc16 (patch)
tree41d665a87d948c10b17a853220cbcdbaeebf3672 /print.c
downloadprc-master.tar.gz
Add project skeletonHEADmaster
Diffstat (limited to 'print.c')
-rw-r--r--print.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/print.c b/print.c
new file mode 100644
index 0000000..abdb149
--- /dev/null
+++ b/print.c
@@ -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;
+}