aboutsummaryrefslogtreecommitdiff
path: root/set.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 /set.c
parenta3f56c76444fee090e62a59f257ed5f60b4e552b (diff)
downloadprc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz
Move source to src/prc1
Diffstat (limited to 'set.c')
-rw-r--r--set.c552
1 files changed, 0 insertions, 552 deletions
diff --git a/set.c b/set.c
deleted file mode 100644
index 3058040..0000000
--- a/set.c
+++ /dev/null
@@ -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;
-}