From cab0135f57ca1c7e448e11f866b0adb8a1328d48 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Sun, 11 Oct 2026 01:26:41 +0200 Subject: WIP triplet --- src/prc1/cgen/CMakeLists.txt | 1 + src/prc1/cgen/from.c | 8 +++ src/prc1/cgen/prv.h | 2 + src/prc1/cgen/qbe/CMakeLists.txt | 1 + src/prc1/cgen/qbe/from.c | 134 +++++++++++++++++++++++++++++++++++++++ src/prc1/cgen/qbe/qbe.c | 1 + src/prc1/cgen/qbe/qbe.h | 2 + 7 files changed, 149 insertions(+) create mode 100644 src/prc1/cgen/from.c create mode 100644 src/prc1/cgen/qbe/from.c (limited to 'src/prc1/cgen') diff --git a/src/prc1/cgen/CMakeLists.txt b/src/prc1/cgen/CMakeLists.txt index 77aa786..d788d2f 100644 --- a/src/prc1/cgen/CMakeLists.txt +++ b/src/prc1/cgen/CMakeLists.txt @@ -3,6 +3,7 @@ target_sources(prc1 PRIVATE call.c fn.c free.c + from.c gl.c global.c param.c diff --git a/src/prc1/cgen/from.c b/src/prc1/cgen/from.c new file mode 100644 index 0000000..be018ef --- /dev/null +++ b/src/prc1/cgen/from.c @@ -0,0 +1,8 @@ +#include "cgen.h" +#include "cgen/prv.h" +#include "from.h" + +int from_cgen(const struct from *f, struct cgen *c) +{ + return c->drv->from(f, c); +} diff --git a/src/prc1/cgen/prv.h b/src/prc1/cgen/prv.h index dc99404..32601f0 100644 --- a/src/prc1/cgen/prv.h +++ b/src/prc1/cgen/prv.h @@ -3,6 +3,7 @@ #include "cgen.h" #include "call.h" +#include "from.h" #include "print.h" #include "set.h" #include "storage.h" @@ -13,6 +14,7 @@ struct cgen_drv int (*gl)(const struct storage *, struct cgen *); int (*ws)(const struct storage *, struct cgen *); int (*call)(const struct call *, struct cgen *); + int (*from)(const struct from *, struct cgen *); int (*set)(const struct set *, struct cgen *); int (*fn)(const struct fn *, struct cgen *); void (*free)(struct cgen_prv *); diff --git a/src/prc1/cgen/qbe/CMakeLists.txt b/src/prc1/cgen/qbe/CMakeLists.txt index 5d0bd63..a9e7155 100644 --- a/src/prc1/cgen/qbe/CMakeLists.txt +++ b/src/prc1/cgen/qbe/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(prc1 PRIVATE call.c free.c + from.c fn.c gl.c print.c diff --git a/src/prc1/cgen/qbe/from.c b/src/prc1/cgen/qbe/from.c new file mode 100644 index 0000000..40b2724 --- /dev/null +++ b/src/prc1/cgen/qbe/from.c @@ -0,0 +1,134 @@ +#include "from.h" +#include "stmt.h" +#include "cgen.h" +#include "qbe.h" +#include +#include +#include + +static int loadvar(const struct from_it *st, struct cgen *c) +{ + const struct stentry *e = st->u.e; + size_t sz = e->t->sz; + const char *tmp = cgen_tmp(sz); + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(e->t)); + cgen_printvar(c->fn, e); + putchar('\n'); + return 0; +} + +/* TODO: de-duplicate function */ +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 loadval(const struct from *fr, struct cgen *c) +{ + const struct stentry *dst = fr->var; + const struct from_it *st = &fr->start; + unsigned long long v = tonum(st->u.tk->s); + + printf("store%s %llu, ", cgen_sz(dst->t->sz), v); + cgen_printvar(c->fn, dst); + putchar('\n'); + return 0; +} + +static int endvar(const struct from *fr, struct cgen *c) +{ + fprintf(stderr, "%s: TODO\n", __func__); + return -1; +} + +static int endval(const struct from *fr, struct cgen *c) +{ + const struct stentry *src = fr->var; + size_t sz = src->t->sz; + const char *tmp = cgen_tmp(sz); + const struct from_it *end = &fr->end; + const struct tk *tk = end->u.tk; + int neg = *tk->s == '-'; + size_t bl = fr->block_i; + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(src->t)); + cgen_printvar(c->fn, src); + putchar('\n'); + printf("%%%s =%s c", tmp, cgen_sz(sz)); + fputs(neg ? "sge" : "uge", stdout); + printf("%s ", cgen_sz(sz)); + printf("%%%s, %s\n", tmp, tk->s); + printf("jnz %%%s, @__end%zu, @__blockbody%zu\n", tmp, bl, bl); + printf("@__blockbody%zu\n", bl); + return 0; +} + +static int from_var(const struct from *fr, struct cgen *c) +{ + const struct from_it *st = &fr->start; + + switch (st->type) + { + case FR_VAR: + if (loadvar(st, c)) + return -1; + break; + + case FR_VAL: + if (loadval(fr, c)) + return -1; + break; + } + + printf("@__block%zu\n", fr->block_i); + + switch (fr->end.type) + { + case FR_VAR: + if (endvar(fr, c)) + return -1; + break; + + case FR_VAL: + if (endval(fr, c)) + return -1; + break; + } + + return 0; +} + +int from_end(const struct stmt *s, struct cgen *c) +{ + const struct from *fr = &s->u.from; + const struct stentry *src = fr->var; + const struct type *t = src->t; + size_t sz = t->sz; + const char *tmp = cgen_tmp(sz); + const struct fn *fn = c->fn; + + printf("%%%s =%s load%s ", tmp, cgen_sz(sz), cgen_load(t)); + cgen_printvar(fn, src); + putchar('\n'); + printf("%%%s =%s add %%%s, 1\n", tmp, cgen_sz(sz), tmp); + printf("store%s %%%s, ", cgen_sz(sz), tmp); + cgen_printvar(fn, src); + putchar('\n'); + printf("jmp @__block%zu\n", fr->block_i); + return 0; +} + +int qbe_from(const struct from *fr, struct cgen *c) +{ + return from_var(fr, c); +} diff --git a/src/prc1/cgen/qbe/qbe.c b/src/prc1/cgen/qbe/qbe.c index c27bad6..d727bc0 100644 --- a/src/prc1/cgen/qbe/qbe.c +++ b/src/prc1/cgen/qbe/qbe.c @@ -154,6 +154,7 @@ int cgen_qbe(const struct ast *ast, struct cgen *c) .print = qbe_print, .call = qbe_call, .free = qbe_free, + .from = qbe_from, .set = qbe_set, .gl = qbe_gl, .ws = qbe_ws, diff --git a/src/prc1/cgen/qbe/qbe.h b/src/prc1/cgen/qbe/qbe.h index b0e66f1..206cf32 100644 --- a/src/prc1/cgen/qbe/qbe.h +++ b/src/prc1/cgen/qbe/qbe.h @@ -3,6 +3,7 @@ #include "call.h" #include "cgen.h" +#include "from.h" #include "print.h" #include "set.h" #include "storage.h" @@ -20,6 +21,7 @@ int qbe_call(const struct call *m, struct cgen *c); int qbe_set(const struct set *m, struct cgen *c); int qbe_gl(const struct storage *gl, struct cgen *c); int qbe_ws(const struct storage *s, struct cgen *c); +int qbe_from(const struct from *fn, struct cgen *c); int qbe_fn(const struct fn *fn, struct cgen *c); void qbe_free(struct cgen_prv *p); -- cgit v1.2.3