#include "print.h" #include "dbg.h" #include "errloc.h" #include "fn.h" #include "lit.h" #include "parse.h" #include "prv.h" #include "stmt.h" #include "sym.h" #include "type.h" #include #if 0 static int entry(const struct lex *l, const struct tk *tk, struct print *pr, struct prv *p) { size_t n = pr->nentries + 1; struct prientry *entries; const struct stentry *stentry = NULL; const struct fn *fn = fn_cur(p); const struct lit *lit = NULL; if (tk->type == ID) { const struct type *t = NULL; if ((t = type_find(fn, tk->s))) { if (t->type != C) { errloc(tk, "type \"%s\" not a constant", tk->s); return -1; } else if (!(lit = lit_push(t->tk, p))) return -1; } else if (!(stentry = fn_var(fn, tk))) { errloc(tk, "undefined reference to \"%s\"", tk->s); return -1; } } else if (tk->type == LIT && !(lit = lit_push(tk, p))) return -1; if (!(entries = realloc(pr->entries, n * sizeof *entries))) { perror("realloc(3)"); return -1; } pr->entries = entries; pr->entries[pr->nentries++] = (struct prientry) { .tk = tk, .lit = lit, .entry = stentry }; return 0; } #endif static int etc(const struct lex *, struct prv *); static const struct seq seqs[] = { {(struct step[]){{ID, "etc"}, {0}}, .fn = etc}, {0} }; static const struct sym *inner(const struct sym *s) { for (; s; s = s->child) if (!s->child) break; return s; } static int fill(struct prv *p, const struct sym *s, struct prisym *ps) { switch (s->type) { case SYM_LIT: if (!(ps->u.lit = lit_push(s->tk, p))) return -1; ps->type = PRS_LIT; break; case SYM_ID: case SYM_TMP: case SYM_NUM: fprintf(stderr, "%s: TODO\n", __func__); return -1; case SYM_CAST: case SYM_ADDR: case SYM_SZ: case SYM_CNT: case SYM_OFF: fprintf(stderr, "%s: unreachable\n", __func__); return -1; } return 0; } static int onsym(const struct lex *l, struct prv *p, const struct sym *s) { struct stmt *stmt = stmt_cur(p); struct print *pr = &stmt->u.print; size_t n = pr->nsyms + 1; struct prisym *syms, *nsym; if (!(syms = realloc(pr->syms, n * sizeof *syms))) { perror("realloc(3)"); return -1; } pr->syms = syms; nsym = &syms[pr->nsyms++]; *nsym = (struct prisym){.s = s}; return fill(p, inner(s), nsym); } static int cg_str(const struct prisym *s, const char *f) { fprintf(stderr, "%s: TODO\n", __func__); return -1; } static int cg_ptr(const struct prisym *s, const char *f) { fprintf(stderr, "%s: TODO\n", __func__); return -1; } static int cg_num(const struct prisym *s, const char *f) { fprintf(stderr, "%s: TODO\n", __func__); return -1; } static int cg_lit(const struct prisym *s, const char *f) { const struct lit *l = s->u.lit; const char *tmp; if (!l) { fprintf(stderr, "%s: unexpected null literal\n", __func__); return -1; } /* TODO: ask target for sizeof (void *) */ tmp = cgen_tmp(sizeof (void *)); printf("%%%s =l loadl $%s\n", tmp, f); printf("call $fputs(l $%s, w %%%s)\n", l->name, tmp); return 0; } int print_cgen(const struct print *pr, struct cgen *c, const char *f) { for (size_t i = 0; i < pr->nsyms; i++) { const struct prisym *ps = &pr->syms[i]; static int (*fn[])(const struct prisym *, const char *) = { [PRS_LIT] = cg_lit, [PRS_STR] = cg_str, [PRS_PTR] = cg_ptr, [PRS_NUM] = cg_num }; if (fn[ps->type](ps, f)) return -1; } if (!pr->skipln) { printf("%%v =l loadl $%s\n", f); puts("call $fputc(l 10 , w %v)"); } return 0; } static int etc(const struct lex *l, struct prv *p) { struct stmt *stmt = stmt_cur(p); struct print *pr = &stmt->u.print; pr->skipln = 1; reset(p); return 0; } void print_free(struct print *pr) { free(pr->syms); } int print(const struct lex *l, struct prv *p) { struct pos init = { .name = __func__, .seq = seqs }; if (push(&init, p)) return -1; return sym(p, onsym); }