#include "display.h" #include "cgen.h" #include "parse.h" #include "prv.h" #include "stmt.h" #include "storage.h" #include #include #include static int finalize(const struct lex *l, const struct prv *p, const struct print *pr) { const struct ast *ast = p->ast; struct fn *fn = &ast->fns[ast->nfns - 1]; size_t n = fn->nstmts + 1; struct stmt *stmts = realloc(fn->stmts, n * sizeof *stmts); if (!stmts) { perror("realloc(3)"); return -1; } fn->stmts = stmts; fn->stmts[fn->nstmts++] = (struct stmt) { .type = DISPLAY, .u.display.p = *pr }; fprintf(stderr, "\t\tadding display statement with %zu entries%s\n", pr->nentries, pr->println ? "" : ", no lf"); return 0; } static int cg_val(const struct tk *tk) { const char *num = tk->s; int neg = *num == '-'; unsigned long long uv; char *end; fputs("call $printf(l $____fmt", stdout); errno = 0; uv = strtoull(num, &end, 16); if (!neg && !errno && !*end) printf("lx, ..., l %llu )\n", uv); else { errno = 0; uv = strtoull(num, &end, 0); if (neg || errno || *end) { long long v = strtoll(num, NULL, 0); printf("l, ..., l %lld )\n", v); } else printf("l, ..., l %llu )\n", uv); } return 0; } static int cg_lit(const struct prientry *e) { const struct lit *l = e->lit; const char *tmp; if (!l) { fprintf(stderr, "%s: unexpected null literal\n", __func__); return -1; } printf("%%%s =l loadl $stdout\n", (tmp = cgen_tmp(sizeof (void *)))); printf("call $fputs(l $%s, w %%%s)\n", l->name, tmp); return 0; } static int cg_id(const struct prientry *de, const struct fn *fn) { const struct stentry *e = de->entry; const struct type *t = e->t; const char *id = e->tk->s; int global = cgen_global(fn, e); size_t sz = t->sz; const char *asz = cgen_sz(sz < 4 ? 4 : sz), *tmp = cgen_tmp(sz); if (global) printf("%%%s =%s load%s $%s\n", tmp, asz, cgen_load(t), id); else printf("%%%s =%s load%s %%%s_\n", tmp, asz, cgen_load(t), id); fputs("call $printf(l $____fmt", stdout); if (t->type == PTR) fputs("lx, ..., l ", stdout); else printf("%s, ..., %s ", cgen_type(t), asz); printf("%%%s)\n", tmp); return 0; } int display_cgen(const struct display *d, struct cgen *c) { const struct print *p = &d->p; for (size_t i = 0; i < p->nentries; i++) { const struct prientry *e = &p->entries[i]; const struct tk *tk = e->tk; if (tk->type == LIT && cg_lit(e)) return -1; else if (tk->type == NUM && cg_val(tk)) return -1; else if (tk->type == ID && e->entry && cg_id(e, c->fn)) return -1; else if (tk->type == ID && e->lit && cg_lit(e)) return -1; } if (p->println) puts("call $putchar(l 10)"); return 0; } void display_free(struct display *d) { print_free(&d->p); } int display(const struct lex *l, struct prv *p) { return print(l, p, finalize); }