aboutsummaryrefslogtreecommitdiff
path: root/td.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-09-05 17:14:53 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-09-26 03:41:55 +0200
commit3c0819236e4f07c8f57aaf1ca46d0d68aa761558 (patch)
treebd8b57cf5420cabc4ec29815052df545b55026f9 /td.c
parenta3f56c76444fee090e62a59f257ed5f60b4e552b (diff)
downloadprc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz
Move source to src/prc1
Diffstat (limited to 'td.c')
-rw-r--r--td.c587
1 files changed, 0 insertions, 587 deletions
diff --git a/td.c b/td.c
deleted file mode 100644
index 72c379f..0000000
--- a/td.c
+++ /dev/null
@@ -1,587 +0,0 @@
-#include "td.h"
-#include "div.h"
-#include "errloc.h"
-#include "fn.h"
-#include "lex.h"
-#include "parse.h"
-#include "prv.h"
-#include "storage.h"
-#include "type.h"
-#include <errno.h>
-#include <limits.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static int cid(const struct lex *, struct prv *);
-static int cnum(const struct lex *, struct prv *);
-static int end(const struct lex *, struct prv *);
-static int endp(const struct lex *, struct prv *);
-static int u(const struct lex *, struct prv *);
-static int s(const struct lex *, struct prv *);
-static int c(const struct lex *, struct prv *);
-static int a(const struct lex *, struct prv *);
-static int p(const struct lex *, struct prv *);
-
-static const struct seq seqs[] =
-{
- {(struct step[]){{ID, "end"}, {0}}, .fn = end},
- {(struct step[]){{ID}, {ID, "constant"}, {ID, "to"}, {ID}, {0}}, .fn = cid},
- {(struct step[]){{ID}, {ID, "constant"}, {ID, "to"}, {NUM}, {0}}, .fn = cnum},
- {(struct step[]){{ID}, {ID, "alias"}, {0}}, .fn = a},
- {(struct step[]){{ID}, {ID, "union"}, {0}}, .fn = u},
- {(struct step[]){{ID}, {ID, "struct"}, {0}}, .fn = s},
- {(struct step[]){{ID}, {ID, "constant"}, {0}}, .fn = c},
- {(struct step[]){{ID}, {ID, "prototype"}, {0}}, .fn = p, .end = endp},
- {0}
-};
-
-static void reset(struct prv *p)
-{
- struct pos *pos = &p->pos[p->i];
-
- pos->seq = seqs;
- pos->step = seqs->steps;
- p->stk = p->tk;
-}
-
-static int bump(const struct tk *tk, const struct type *t, struct prv *p)
-{
- struct tdconstant *tdc = p->tdc;
- int neg = 0;
-
- if (!t->sign)
- {
- unsigned long long uv = t->u.c.uv;
-
- if (uv + 1 < uv)
- {
- errloc(tk, "constant value exceeds maximum (%llu)", ULLONG_MAX);
- return -1;
- }
-
- tdc->u.uv = ++uv;
- }
- else
- {
- long long v = t->u.c.v;
-
- if (++v < 0)
- neg = 1;
-
- tdc->u.v = v;
- }
-
- tdc->neg = neg;
-
- for (size_t i = 0; i < p->block; i++)
- fputc('\t', stderr);
-
- fprintf(stderr, "\t\tnext %s constant value set to ",
- neg ? "negative" : "positive");
-
- if (neg)
- fprintf(stderr, "%lld", tdc->u.v);
- else
- fprintf(stderr, "%llu", tdc->u.uv);
-
- fputc('\n', stderr);
- return 0;
-}
-
-static int cid(const struct lex *l, struct prv *p)
-{
- const struct fn *fn = fn_cur(p);
- const struct tk *id = p->stk, *v = p->stk + 3;
- const struct stentry *e;
- const struct type *t = type_find(fn, id->s);
- struct tdconstant *tdc = p->tdc;
- struct td *td = fn->td;
- size_t n = td->ntypes + 1;
- struct type *types, *nt;
-
- if (t)
- {
- const struct loc *loc = &t->tk->loc;
-
- errloc(id, "type \"%s\" already defined at %s:%d:%d", id->s, loc->f,
- loc->line, loc->col);
- return -1;
- }
- else if ((e = fn_var(fn, id)))
- {
- const struct loc *loc = &e->tk->loc;
-
- errloc(id, "\"%s\" already defined as a variable at %s:%d:%d", id->s,
- loc->f, loc->line, loc->col);
- return -1;
- }
- else if ((e = fn_var(fn, v)))
- {
- const struct loc *loc = &e->tk->loc;
-
- errloc(id, "value \"%s\" (defined at %s:%d:%d) is not a constant",
- v->s, loc->f, loc->line, loc->col);
- return -1;
- }
- else if (!(t = type_find(fn, v->s)))
- {
- errloc(id, "undefined reference to value \"%s\"", v->s);
- return -1;
- }
- else if (t->type != C)
- {
- const struct loc *loc = &t->tk->loc;
-
- errloc(id, "value \"%s\" (defined at %s:%d:%d) is not a constant",
- v->s, loc->f, loc->line, loc->col);
- return -1;
- }
- else if (!(types = realloc(td->types, n * sizeof *types)))
- {
- perror("realloc(3)");
- return -1;
- }
-
- td->types = types;
- nt = &td->types[td->ntypes++];
- *nt = (struct type)
- {
- .type = C,
- .tk = id,
- .sign = t->sign,
- .u.c = t->u.c
- };
-
- tdc->neg = t->sign;
-
- if (bump(id, t, p))
- return -1;
-
- for (size_t i = 0; i < p->block; i++)
- fputc('\t', stderr);
-
- fprintf(stderr, "\tadding constant %s to %s (%lld)\n", id->s, v->s,
- t->u.c.v);
- reset(p);
- return 1;
-}
-
-static int cnum(const struct lex *l, struct prv *p)
-{
- const struct fn *fn = fn_cur(p);
- const struct tk *id = p->stk, *num = p->stk + 3;
- const char *name = id->s;
- const struct stentry *e;
- struct td *td = fn->td;
- size_t n = td->ntypes + 1;
- struct type *types, *nt;
- struct tdconstant *tdc = p->tdc;
- const struct type *t = type_find(fn, name);
- int sign = *num->s == '-';
- unsigned long long uv = 0;
- long long v;
- char *end;
-
- errno = 0;
- v = strtoll(num->s, &end, 0);
-
- if (!sign || errno || *end)
- {
- errno = 0;
- uv = strtoull(num->s, NULL, 0);
- }
-
- if (t)
- {
- const struct loc *loc = &t->tk->loc;
-
- errloc(id, "type \"%s\" already defined at %s:%d:%d", name, loc->f,
- loc->line, loc->col);
- return -1;
- }
- else if ((e = fn_var(fn, id)))
- {
- const struct loc *loc = &e->tk->loc;
-
- errloc(id, "\"%s\" already defined as a variable at %s:%d:%d", id->s,
- loc->f, loc->line, loc->col);
- return -1;
- }
- else if (!(types = realloc(td->types, n * sizeof *types)))
- {
- perror("realloc(3)");
- return -1;
- }
-
- td->types = types;
- nt = &td->types[td->ntypes++];
- *nt = (struct type)
- {
- .type = C,
- .tk = id,
- .sign = sign
- };
-
- if (sign)
- tdc->u.v = nt->u.c.v = v;
- else
- tdc->u.uv = nt->u.c.uv = uv;
-
- tdc->neg = sign;
-
- for (size_t i = 0; i < p->block; i++)
- fputc('\t', stderr);
-
- fprintf(stderr, "\tadding constant %s to %s\n", id->s, num->s);
-
- if (bump(id, nt, p))
- return -1;
-
- reset(p);
- return 1;
-}
-
-static int c(const struct lex *l, struct prv *p)
-{
- const struct fn *fn = fn_cur(p);
- const struct tk *id = p->stk;
- const struct stentry *e;
- const struct type *t = type_find(fn, id->s);
- struct td *td = fn->td;
- size_t n = td->ntypes + 1;
- struct type *types, *nt;
- const struct tdconstant *tdc = p->tdc;
-
- if (t)
- {
- const struct loc *loc = &t->tk->loc;
-
- errloc(id, "type \"%s\" already defined at %s:%d:%d", id->s, loc->f,
- loc->line, loc->col);
- return -1;
- }
- else if ((e = fn_var(fn, id)))
- {
- const struct loc *loc = &e->tk->loc;
-
- errloc(id, "\"%s\" already defined as a variable at %s:%d:%d", id->s,
- loc->f, loc->line, loc->col);
- return -1;
- }
- else if (!(types = realloc(td->types, n * sizeof *types)))
- {
- perror("realloc(3)");
- return -1;
- }
-
- td->types = types;
- nt = &td->types[td->ntypes];
- *nt = (struct type)
- {
- .type = C,
- .tk = id,
- .sign = tdc->neg,
- };
-
- if (nt->sign)
- nt->u.c.v = tdc->u.v;
- else
- nt->u.c.uv = tdc->u.uv;
-
- for (size_t i = 0; i < p->block; i++)
- fputc('\t', stderr);
-
- fprintf(stderr, "\tadding constant %s to ", id->s);
-
- if (tdc->neg)
- fprintf(stderr, "%lld", tdc->u.v);
- else
- fprintf(stderr, "%llu", tdc->u.uv);
-
- fputc('\n', stderr);
-
- if (bump(id, &td->types[td->ntypes++], p))
- return -1;
-
- reset(p);
- return 1;
-}
-
-static int p(const struct lex *l, struct prv *p)
-{
- struct fn *fn = fn_cur(p), *pt = NULL;
- struct td *td = fn->td;
- size_t n = td->ntypes + 1;
- struct type *types;
-
- if (!(pt = malloc(sizeof *pt)))
- {
- perror("malloc(3)");
- goto failure;
- }
-
- *pt = (struct fn){.tk = p->stk, .parent = fn};
-
- if (!(types = realloc(td->types, n * sizeof *types)))
- {
- perror("realloc(3)");
- goto failure;
- }
-
- types[td->ntypes++] = (struct type)
- {
- .type = P,
- .tk = p->stk,
- .sz = sizeof (void *),
- .align = sizeof (void *),
- .u.p.fn = pt
- };
-
- td->types = types;
- p->proto = pt;
- fprintf(stderr, "\tadding prototype %s\n", p->stk->s);
- return div_p(l, p);
-
-failure:
- free(pt);
- return -1;
-}
-
-static int ends(struct type *t)
-{
- const struct s *s = &t->u.s;
- const struct storage *st = s->storage;
- const struct stentry *e;
-
- if (!st->nentries)
- {
- errloc(t->tk, "struct \"%s\" has no members", t->tk->s);
- return -1;
- }
-
- e = &st->entries[st->nentries - 1];
- t->align = st->entries->t->align;
- t->sz = e->offset + e->t->sz;
- t->sz += t->align - (t->sz % t->align);
- fprintf(stderr, "\tadding struct %s, size %zu, align %zu\n", t->tk->s,
- t->sz, t->align);
- return 0;
-}
-
-static int endu(struct type *t)
-{
- const struct u *u = &t->u.u;
-
- if (!u->storage->nentries)
- {
- errloc(t->tk, "union \"%s\" has no members", t->tk->s);
- return -1;
- }
-
- return 0;
-}
-
-static int end(const struct lex *l, struct prv *p)
-{
- const struct tk *tk = p->tk - 1;
- struct type *t;
-
- if (!p->block)
- {
- errloc(tk, "unexpected \"end\" statement");
- return -1;
- }
- else if (!(t = p->ag))
- {
- errloc(tk, "unreachable");
- return -1;
- }
-
- switch (t->type)
- {
- case U:
- if (endu(t))
- return -1;
-
- break;
-
- case S:
- if (ends(t))
- return -1;
-
- break;
-
- default:
- errloc(tk, "unreachable");
- return -1;
- }
-
- p->ag = NULL;
- p->block--;
- reset(p);
- return 1;
-}
-
-static int endp(const struct lex *l, struct prv *p)
-{
- if (fn_end(l, p))
- return -1;
-
- p->proto = NULL;
- return 0;
-}
-
-static int s(const struct lex *l, struct prv *p)
-{
- const struct tk *id = p->stk;
- struct fn *fn = fn_cur(p);
- struct td *td = fn->td;
- size_t nt = td->ntypes + 1;
- struct type *types, *newt;
- const struct type *t = type_find(fn, id->s);
-
- if (t)
- {
- const struct loc *loc = &t->tk->loc;
-
- errloc(id, "type \"%s\" already defined at %s:%d:%d", id->s, loc->f,
- loc->line, loc->col);
- return -1;
- }
- else if (!(types = realloc(td->types, nt * sizeof *types)))
- {
- perror("realloc(3)");
- return -1;
- }
-
- td->types = types;
- newt = &td->types[td->ntypes++];
- *newt = (struct type)
- {
- .type = S,
- .tk = id
- };
-
- p->ag = newt;
- p->block++;
- return storage(l, p, id->s, 0, &newt->u.s.storage);
-}
-
-static int u(const struct lex *l, struct prv *p)
-{
- fprintf(stderr, "%s: TODO\n", __func__);
- return -1;
-}
-
-static int tt(const struct lex *l, struct prv *p, const struct type *t)
-{
- int ret = -1;
- const struct fn *fn = fn_cur(p);
- const struct tk *id = p->id;
- const struct type *tp = type_ufind(fn, id->s);
- const struct loc *loc = &id->loc;
- struct td *td = fn->td;
- size_t n = td->ntypes + 1;
- struct type *types, *nt;
- char *s = type_name(t);
-
- if (!s)
- goto end;
- else if (tp)
- {
- const struct loc *loc = &tp->tk->loc;
-
- errloc(id, "type \"%s\" already defined at %s:%d:%d", id->s, loc->f,
- loc->line, loc->col);
- goto end;
- }
- else if (pop(l, p))
- return -1;
- else if (!(types = realloc(td->types, n * sizeof *types)))
- {
- perror("realloc(3)");
- goto end;
- }
-
- td->types = types;
- nt = &td->types[td->ntypes++];
- *nt = (struct type)
- {
- .type = T,
- .tk = id,
- .u.t.alias = t
- };
-
- fprintf(stderr, "\tadding %s (%d:%d) alias %s\n", id->s, loc->line,
- loc->col, s);
- reset(p);
- p->id = NULL;
- ret = 1;
-end:
- free(s);
- return ret;
-}
-
-static int a(const struct lex *l, struct prv *p)
-{
- p->id = p->stk;
- return type(l, p, tt);
-}
-
-void td_free(struct td *td)
-{
- if (td)
- {
- for (size_t i = 0; i < td->ntypes; i++)
- type_free(&td->types[i]);
-
- free(td->types);
- }
-
- free(td);
-}
-
-int td(const struct lex *l, struct prv *p)
-{
- const struct tk *tk = p->stk;
- struct fn *fn = fn_cur(p);
- struct td *td = NULL, *prev = fn->td;
- struct tdconstant *tdc = NULL;
- struct pos init =
- {
- .seq = seqs,
- .stseq = seqs,
- .step = seqs->steps
- };
-
- if (prev)
- {
- const struct loc *loc = &prev->tk->loc;
-
- errloc(tk, "types section already defined at %s:%d:%d", loc->f,
- loc->line, loc->col);
- goto failure;
- }
- else if (!(td = malloc(sizeof *td))
- || !(tdc = malloc(sizeof *tdc)))
- {
- perror("malloc(3)");
- goto failure;
- }
- else if (push(&init, p))
- goto failure;
-
- *tdc = (struct tdconstant){0};
- *td = (struct td){.tk = tk};
- fn->td = td;
- p->tdc = tdc;
- p->stk = p->tk;
- return 1;
-
-failure:
- free(tdc);
- free(td);
- return -1;
-}