diff options
| author | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-09-05 17:14:53 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi92@disroot.org> | 2026-09-26 03:41:55 +0200 |
| commit | 3c0819236e4f07c8f57aaf1ca46d0d68aa761558 (patch) | |
| tree | bd8b57cf5420cabc4ec29815052df545b55026f9 /td.c | |
| parent | a3f56c76444fee090e62a59f257ed5f60b4e552b (diff) | |
| download | prc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz | |
Move source to src/prc1
Diffstat (limited to 'td.c')
| -rw-r--r-- | td.c | 587 |
1 files changed, 0 insertions, 587 deletions
@@ -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; -} |
