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 /set.c | |
| parent | a3f56c76444fee090e62a59f257ed5f60b4e552b (diff) | |
| download | prc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz | |
Move source to src/prc1
Diffstat (limited to 'set.c')
| -rw-r--r-- | set.c | 552 |
1 files changed, 0 insertions, 552 deletions
@@ -1,552 +0,0 @@ -#include "set.h" -#include "cgen.h" -#include "errloc.h" -#include "fn.h" -#include "lex.h" -#include "parse.h" -#include "prv.h" -#include "stmt.h" -#include "storage.h" -#include "type.h" -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -static int mv(const struct lex *l, struct prv *p); -static int maddr(const struct lex *l, struct prv *p); -static int msz(const struct lex *l, struct prv *p); -static int mimb(const struct lex *l, struct prv *p); - -static const struct seq seqs[] = -{ - /* size of elementary data types */ - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "void"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "byte"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "halfword"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "word"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "long"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "ubyte"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "uhalfword"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "uword"}, - {0}}, .fn = msz}, - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ID, "ulong"}, - {0}}, .fn = msz}, - - /* address of variable */ - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "address"}, - {ID, "of"}, - {ID}, - {0}}, .fn = maddr}, - - /* size of variable or type alias */ - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ID, "size"}, - {ID, "of"}, - {ANY}, - {0}}, .fn = msz}, - - /* array index or aggregate member */ - {(struct step[]){ - {ID, NULL, 1}, - {ID, "to"}, - {ANY}, - {ID, "of"}, - {ID}, - {0}}, .fn = mimb}, - - /* simple set */ - {(struct step[]){{ID, NULL, 1}, {ID, "to"}, {ANY}, {0}}, .fn = mv}, - {0} -}; - -static unsigned long long tonum(const char *s) -{ - unsigned long long v; - char *end; - - errno = 0; - v = strtoull(s, &end, 0); - - if (*s == '-' || errno || *end) - return strtoll(s, NULL, 0); - - return v; -} - -static int dst(const struct lex *l, const struct tk *tk, struct set *s, - struct prv *p) -{ - const struct stentry *e = fn_var(fn_cur(p), tk); - size_t n = s->ndsts + 1; - struct setdst *dsts; - - if (!e) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - else if (!(dsts = realloc(s->dsts, n * sizeof *dsts))) - { - perror("realloc(3)"); - return -1; - } - - s->dsts = dsts; - s->dsts[s->ndsts++] = (struct setdst){.entry = e}; - return 0; -} - -static int checkzero(const struct tk *tk, const struct set *s, - unsigned long long v) -{ - if (!s->srcv) - return 0; - - for (size_t i = 0; i < s->ndsts; i++) - { - const struct stentry *dst = s->dsts[i].entry; - - if (dst->t->type != BUILTIN) - { - errloc(tk, "destination \"%s\" cannot be set to \"%s\"", - dst->tk->s, tk->s); - return -1; - } - } - - return 0; -} - - -static int checkcompat(const struct tk *tk, const struct set *s) -{ - for (size_t i = 0; i < s->ndsts; i++) - { - const struct stentry *dst = s->dsts[i].entry; - const struct type *st = s->src->t, *dt = dst->t; - - /* TODO: integer promotions */ - if (st->type != dt->type - || st->sz != dt->sz - || st->sign != dt->sign) - { - errloc(tk, "destination \"%s\" cannot be set to \"%s\"", - dst->tk->s, tk->s); - return -1; - } - } - - return 0; -} - -static int mv(const struct lex *l, struct prv *p) -{ - const struct tk *tk = p->stk; - const struct stentry *e; - struct stmt *stmt = stmt_cur(p); - struct set *s = &stmt->u.set; - - while (!lex_eof(l, tk) && !kw((tk)->s)) - if (dst(l, tk++, s, p)) - return -1; - - /* skip "to" */ - tk++; - - if (tk->type == LIT) - { - /* this can only be applied to arrays of/pointers to chars */ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; - } - else if (tk->type == NUM) - { - s->type = SET_VAL; - s->srcv = tonum(tk->s); - - if (checkzero(tk, s, s->srcv)) - return -1; - } - else if (tk->type == ID) - { - const struct fn *fn = fn_cur(p); - const struct type *t = type_find(fn, tk->s); - - if (t) - { - if (t->type != C) - { - errloc(tk, "type \"%s\" not a constant", tk->s); - return -1; - } - - s->type = SET_VAL; - s->srcv = t->u.c.v; - - if (checkzero(tk, s, s->srcv)) - return -1; - } - else if ((e = fn_var(fn_cur(p), tk))) - { - s->type = SET_VAR; - s->src = e; - - if (checkcompat(tk, s)) - return -1; - } - else - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - } - - fputs("\t\tadding set ", stderr); - - for (size_t i = 0; i < s->ndsts; i++) - fprintf(stderr, "%s ", s->dsts[i].entry->tk->s); - - fprintf(stderr, "to %s\n", tk->s); - - if (pop(l, p)) - return -1; - - p->stk = ++tk; - return 1; -} - -static int maddr(const struct lex *l, struct prv *p) -{ - const struct tk *tk = p->stk; - struct stmt *stmt = stmt_cur(p); - struct set *s = &stmt->u.set; - const struct stentry *e; - - while (!lex_eof(l, tk) && !kw((tk)->s)) - { - const struct stentry *e = fn_var(fn_cur(p), tk); - - if (e && e->t->type != PTR) - { - errloc(tk, "destination \"%s\" not a pointer", tk->s); - return -1; - } - else if (dst(l, tk++, s, p)) - return -1; - } - - /* skip "to address of" */ - tk += 3; - - if (!(e = fn_var(fn_cur(p), tk))) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - else if (pop(l, p)) - return -1; - - s->type = SET_ADDR; - s->src = e; - p->stk = ++tk; - fputs("\t\tadding set ", stderr); - - for (size_t i = 0; i < s->ndsts; i++) - fprintf(stderr, "%s ", s->dsts[i].entry->tk->s); - - fprintf(stderr, "to address of %s\n", s->src->tk->s); - return 1; -} - -static int msz(const struct lex *l, struct prv *p) -{ - const struct tk *tk = p->stk; - const struct stentry *e; - struct stmt *stmt = stmt_cur(p); - struct set *s = &stmt->u.set; - const struct fn *fn = fn_cur(p); - const struct type *t; - - while (!lex_eof(l, tk) && !kw(tk->s)) - { - const struct stentry *e = fn_var(fn_cur(p), tk); - - if (e && e->t->type != BUILTIN) - { - errloc(tk, "destination \"%s\" not an integer", tk->s); - return -1; - } - else if (dst(l, tk++, s, p)) - return -1; - } - - /* skip "to size of" */ - tk += 3; - - if (tk->type == NUM) - { - errloc(tk, "cannot compute size of a number"); - return -1; - } - else if (tk->type == LIT) - s->srcv = strlen(tk->s) + 1; - else if ((t = type_find(fn, tk->s))) - { - if (!t->sz) - { - errloc(tk, "type \"%s\" has no size", tk->s); - return-1; - } - - s->srcv = t->sz; - } - else if ((e = fn_var(fn, tk))) - s->srcv = e->t->sz; - else - return-1; - - if (pop(l, p)) - return -1; - - s->type = SET_VAL; - p->stk = ++tk; - fputs("\t\tadding set ", stderr); - - for (size_t i = 0; i < s->ndsts; i++) - fprintf(stderr, "%s ", s->dsts[i].entry->tk->s); - - fprintf(stderr, "size=%llu\n", s->srcv); - return 1; -} - -static int mimb(const struct lex *l, struct prv *p) -{ - const struct tk *tk = p->stk; - const struct fn *fn = fn_cur(p); - struct stmt *stmt = stmt_cur(p); - struct set *s = &stmt->u.set; - - while (!lex_eof(l, tk) && !kw((tk)->s)) - if (dst(l, tk++, s, p)) - return -1; - - /* skip "to" */ - tk++; - - fputs("\t\tadding set ", stderr); - - for (size_t i = 0; i < s->ndsts; i++) - fprintf(stderr, "%s ", s->dsts[i].entry->tk->s); - - if (tk->type == LIT) - { - errloc(tk, "unexpected literal \"%s\"", tk->s); - return -1; - } - else if (tk->type == ID && !(s->off = fn_var(fn, tk))) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - else if (tk->type == NUM) - s->srcv = tonum(tk->s); - - fprintf(stderr, "to [%s] ", tk->s); - - /* skip index and "of" */ - tk += 2; - - if (!(s->src = fn_var(fn, tk))) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - else if (pop(l, p)) - return -1; - - fprintf(stderr, " of %s\n", tk->s); - s->type = SET_IMB; - p->stk = ++tk; - return 1; -} - -void set_free(struct set *m) -{ - if (m) - free(m->dsts); -} - -static int cg_val(const struct set *s, const struct stentry *dst, - struct cgen *c) -{ - const char *szstr = cgen_sz(dst->t->sz), *ab = cgen_abity(dst->t); - const struct fn *fn = c->fn; - - if (ab) - { - printf("store%s %llu, ", szstr, s->srcv); - cgen_printvar(fn, dst); - } - else - { - fputs("%r =l call $memset(l ", stdout); - cgen_printvar(fn, dst); - printf(", w 0, l %zu)", dst->t->sz); - } - - putchar('\n'); - return 0; -} - -static int cg_addr(const struct set *s, const struct stentry *dst, - struct cgen *c) -{ - printf("store%s ", cgen_sz(dst->t->sz)); - cgen_printvar(c->fn, s->src); - fputs(", ", stdout); - cgen_printvar(c->fn, dst); - putchar('\n'); - return 0; -} - -static int cg_var(const struct set *s, const struct stentry *dst, - struct cgen *c) -{ - const struct stentry *src = s->src; - const char *tmp = cgen_tmp(src->t->sz); - - printf("%%%s =%s load%s ", tmp, cgen_sz(src->t->sz), cgen_load(src->t)); - cgen_printvar(c->fn, src); - putchar('\n'); - printf("store%s %%%s, ", cgen_sz(dst->t->sz), tmp); - cgen_printvar(c->fn, dst); - putchar('\n'); - return 0; -} - -static int cg_imb(const struct set *s, const struct stentry *e, struct cgen *c) -{ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; -} - -int set_cgen(const struct set *s, struct cgen *c) -{ - for (size_t i = 0; i < s->ndsts; i++) - { - const struct stentry *dst = s->dsts[i].entry; - - static int (*const f[])(const struct set *, const struct stentry *, - struct cgen *) = - { - [SET_VAL] = cg_val, - [SET_ADDR] = cg_addr, - [SET_VAR] = cg_var, - [SET_IMB] = cg_imb - }; - - if (f[s->type](s, dst, c)) - return -1; - } - - return 0; -} - -int set(const struct lex *l, struct prv *p) -{ - const struct tk *next = p->tk; - const char *ns; - struct fn *fn = fn_cur(p); - size_t n = fn->nstmts + 1; - struct stmt *stmts; - - if (lex_eof(l, next)) - { - errloc(next - 1, "incomplete set statement"); - return -1; - } - else if (kw((ns = next->s))) - { - errloc(next, "incomplete set statement"); - return -1; - } - else if (!(stmts = realloc(fn->stmts, n * sizeof *stmts))) - { - perror("realloc(3)"); - return -1; - } - - fn->stmts = stmts; - fn->stmts[fn->nstmts++] = (struct stmt){.type = SET}; - - struct pos init = - { - .seq = seqs, - .stseq = seqs, - .step = seqs->steps - }; - - if (push(&init, p)) - return -1; - - p->stk = p->tk; - return 1; -} |
