aboutsummaryrefslogtreecommitdiff
path: root/src/prc1/print.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-10-01 01:04:30 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-10-11 00:14:35 +0200
commit4ce39e4fc1de9536de7dedfe91b6dee38dec76ae (patch)
treef9820f96b8eab624430c3700f32a2878a7036ee2 /src/prc1/print.c
parent9140988be4e5bb028b7140aca1a67af1370c72a7 (diff)
downloadprc-4ce39e4fc1de9536de7dedfe91b6dee38dec76ae.tar.gz
WIP sym + cgen
Diffstat (limited to 'src/prc1/print.c')
-rw-r--r--src/prc1/print.c178
1 files changed, 114 insertions, 64 deletions
diff --git a/src/prc1/print.c b/src/prc1/print.c
index abdb149..604c2a3 100644
--- a/src/prc1/print.c
+++ b/src/prc1/print.c
@@ -5,99 +5,149 @@
#include "parse.h"
#include "prv.h"
#include "stmt.h"
-#include "storage.h"
+#include "sym.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)
+static int etc(const struct lex *, struct prv *);
+
+static const struct seq seqs[] =
+{
+ {(struct step[]){{ID, "etc"}, {0}}, .fn = etc},
+ {0}
+};
+
+static int invalid(const struct sym *s, const struct type *t)
+{
+ char *tn = type_name(t);
+
+ if (tn)
+ errloc(s->tk, "cannot print type \"%s\"", tn);
+
+ free(tn);
+ return -1;
+}
+
+static const struct sym *inner(const struct sym *s)
+{
+ for (; s; s = s->child)
+ if (!s->child)
+ break;
+
+ return s;
+}
+
+static int setptr(struct prv *p, const struct sym *s, struct prisym *ps,
+ const struct type *t)
{
- 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;
+ const struct stentry *e = fn_var(fn, s->tk);
- if (tk->type == ID)
+ if (!e)
{
- const struct type *t = NULL;
+ errloc(s->tk, "undefined reference to \"%s\"", s->tk->s);
+ return -1;
+ }
+
+ ps->type = PRS_PTR;
+ ps->u.e = e;
+ return 0;
+}
+
+static int settype(struct prv *p, const struct sym *s, struct prisym *ps)
+{
+ const struct type *t = sym_type(p, s);
+ const struct tk *tk = s->tk;
- if ((t = type_find(fn, tk->s)))
+ if (!t)
+ {
+ errloc(tk, "undefined reference to \"%s\"", tk->s);
+ return -1;
+ }
+ else if (inner(s)->type == SYM_LIT)
+ {
+ const struct lit *l = lit_push(tk, p);
+
+ if (!l)
+ return -1;
+ else if (t == p->ast->littype)
{
- 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;
+ ps->type = PRS_LIT;
+ ps->u.lit = l;
}
- else if (!(stentry = fn_var(fn, tk)))
+ else
{
- errloc(tk, "undefined reference to \"%s\"", tk->s);
- return -1;
+ ps->type = PRS_NAM;
+ ps->u.name = l->name;
}
}
- else if (tk->type == LIT && !(lit = lit_push(tk, p)))
- return -1;
+ else
+ switch (t->type)
+ {
+ case U:
+ case S:
+ case T:
+ case ARY:
+ return invalid(s, t);
+ case C:
+ case BUILTIN:
+ fprintf(stderr, "%s: TODO\n", __func__);
+ return -1;
+ case P:
+ ps->type = PRS_NAM;
+ ps->u.name = s->tk->s;
+ break;
+ case PTR:
+ return setptr(p, s, ps, t);
+ }
- if (!(entries = realloc(pr->entries, n * sizeof *entries)))
+ return 0;
+}
+
+static int onsym(const struct lex *l, struct prv *p, const struct sym *s)
+{
+ struct stmt *stmt = stmt_cur(p);
+ struct print *pr = &stmt->u.print;
+ size_t n = pr->nsyms + 1;
+ struct prisym *syms, *nsym;
+
+ if (!(syms = realloc(pr->syms, n * sizeof *syms)))
{
perror("realloc(3)");
return -1;
}
- pr->entries = entries;
- pr->entries[pr->nentries++] = (struct prientry)
- {
- .tk = tk,
- .lit = lit,
- .entry = stentry
- };
+ pr->syms = syms;
+ nsym = &syms[pr->nsyms++];
+ *nsym = (struct prisym){.s = s};
+ return settype(p, s, nsym);
+}
+
+static int etc(const struct lex *l, struct prv *p)
+{
+ struct stmt *stmt = stmt_cur(p);
+ struct print *pr = &stmt->u.print;
+ pr->skipln = 1;
+ reset(p);
return 0;
}
void print_free(struct print *pr)
{
- free(pr->entries);
+ free(pr->syms);
}
-int print(const struct lex *l, struct prv *p,
- int (*fn)(const struct lex *, const struct prv *, const struct print *))
+int print(const struct lex *l, struct prv *p)
{
- 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))
+ struct pos init =
{
- 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;
+ .name = __func__,
+ .seq = seqs
+ };
- pos->seq = pos->stseq = stmts;
- pos->step = stmts->steps;
- p->stk = tk;
- return 1;
+ if (push(&init, p))
+ return -1;
-failure:
- print_free(&pr);
- return -1;
+ return sym(p, onsym);
}