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 /from.c | |
| parent | a3f56c76444fee090e62a59f257ed5f60b4e552b (diff) | |
| download | prc-3c0819236e4f07c8f57aaf1ca46d0d68aa761558.tar.gz | |
Move source to src/prc1
Diffstat (limited to 'from.c')
| -rw-r--r-- | from.c | 364 |
1 files changed, 0 insertions, 364 deletions
@@ -1,364 +0,0 @@ -#include "from.h" -#include "cgen.h" -#include "fn.h" -#include "errloc.h" -#include "stmt.h" -#include "storage.h" -#include "tmp.h" -#include "type.h" -#include <errno.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -void from_free(struct from *fr) -{ -} - -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_cgen(const struct from *fr, struct cgen *c) -{ - return from_var(fr, c); -} - -static 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; -} - -static int checksym(const struct fn *fn, const struct tk *tk, - struct from_it *fr) -{ - const struct stentry *e = fn_var(fn, tk); - - if (!e) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - - switch (e->t->type) - { - case C: - case BUILTIN: - break; - case U: - case S: - case P: - case T: - case PTR: - case ARY: - { - char *s = type_name(e->t); - - if (s) - errloc(tk, "\"%s\" (\"%s\") cannot be used in \"from\" loop", - tk->s, s); - - free(s); - return -1; - } - } - - fr->type = FR_VAR; - fr->u.e = e; - return 0; -} - -static int check(const struct fn *fn, const struct tk *tk, struct from_it *fr) -{ - switch (tk->type) - { - case NUM: - fr->type = FR_VAL; - fr->u.tk = tk; - break; - case ID: - return checksym(fn, tk, fr); - case LIT: - errloc(tk, "unexpected literal"); - return -1; - case UNDEF: - case ANY: - fprintf(stderr, "%s: unreachable\n", __func__); - return -1; - } - - return 0; -} - -static int finalize(struct prv *p, struct fn *fn, struct from *fr) -{ - struct stmt *s; - struct pos *pos = &p->pos[p->i]; - size_t nst = fn->nstmts + 1, nbl = fn->nblocks + 1, - *bl = realloc(fn->blocks, nbl * sizeof *bl); - - if (!bl) - { - perror("realloc(3)"); - return -1; - } - - fr->block_i = bl[fn->nblocks++] = fn->nstmts; - fn->blocks = bl; - - if (!(s = realloc(fn->stmts, nst * sizeof *s))) - { - perror("realloc(3)"); - return -1; - } - - s[fn->nstmts++] = (struct stmt) - { - .type = FROM, - .u.from = *fr, - .end = from_end - }; - - fn->stmts = s; - pos->seq = pos->stseq = stmts; - pos->step = stmts->steps; - fprintf(stderr, ", iterator %s, block index %zu\n", fr->var->tk->s, - bl[fn->nblocks - 1]); - return 0; -} - -static const struct type *valtype(const struct fn *fn, const struct tk *tk) -{ - char *end; - - errno = 0; - strtol(tk->s, &end, 0); - - if (errno || *end) - { - errno = 0; - strtoll(tk->s, &end, 0); - - if (errno || *end) - return type_find(fn, "ulong"); - - return type_find(fn, "long"); - } - - return type_find(fn, "word"); -} - -static const struct type *ittype(const struct fn *fn, const struct from_it *it) -{ - switch (it->type) - { - case FR_VAL: - return valtype(fn, it->u.tk); - case FR_VAR: - return it->u.e->t; - } - - fprintf(stderr, "%s: unreachable\n", __func__); - return NULL; -} - -static const struct type *gettype(const struct fn *fn, - const struct from_it *a, const struct from_it *b) -{ - const struct type *ta = ittype(fn, a), *tb = ittype(fn, b); - - return ta->sz > tb->sz ? ta : tb; -} - -int from(const struct lex *l, struct prv *p) -{ - const struct tk *start = p->stk + 1, *end = p->stk + 3; - struct fn *fn = fn_cur(p); - struct from fr = {0}; - const struct type *t; - - if (check(fn, start, &fr.start) - || check(fn, end, &fr.end) - || !(t = gettype(fn, &fr.start, &fr.end)) - || !(fr.var = tmp_create(fn, t))) - return -1; - - fprintf(stderr, "\t\tadding from statement [%s, %s]", start->s, end->s); - - if (finalize(p, fn, &fr)) - return -1; - - p->stk = ++end; - return 1; -} - -static int checkvar(const struct fn *fn, const struct tk *tk, struct from *fr) -{ - const struct stentry *e; - - if (tk->type != ID) - { - errloc(tk, "\"%s\" not a variable", tk->s); - return -1; - } - else if (!(e = fn_var(fn, tk))) - { - errloc(tk, "undefined reference to \"%s\"", tk->s); - return -1; - } - else if (e->t->type != BUILTIN) - { - errloc(tk, "variable \"%s\" not an integer", tk->s); - return -1; - } - - fr->var = e; - return 0; -} - -int from_id(const struct lex *l, struct prv *p) -{ - const struct tk *start = p->stk + 1, *end = p->stk + 3, *var = p->stk + 5; - struct fn *fn = fn_cur(p); - struct from fr = {0}; - - if (check(fn, start, &fr.start) - || check(fn, end, &fr.end) - || checkvar(fn, var, &fr)) - return -1; - - fprintf(stderr, "\t\tadding from statement [%s, %s] using %s", - start->s, end->s, var->s); - - if (finalize(p, fn, &fr)) - return -1; - - p->stk = ++var; - return 1; -} - -int from_by(const struct lex *l, struct prv *p) -{ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; -} - -int from_idby(const struct lex *l, struct prv *p) -{ - fprintf(stderr, "%s: TODO\n", __func__); - return -1; -} |
