ref: e01f61f0d55b37630264e8d74107199752a6e76f
dir: /fmt.c/
#include <u.h> #include <libc.h> #include "dat.h" #include "fns.h" static char *expoptab[] = { [Olit] "", [Ovar] "", [Oasn] "=", [Oadd] "+", [Osub] "-", [Omul] "*", [Odiv] "/", [Omod] "%", [Oshl] "<<", [Oshr] ">>", [Olor] "||", [Oland] "&&", [Ogt] ">", [Olt] "<", [Oge] ">=", [Ole] "<=", [Oeq] "==", [One] "!=", [Oinc] "++", [Odec] "--", [Orcv] "←" }; static char tabs[128]; int nodfmt(Fmt *f) { Nod *n; int nt, e; nt = f->prec; n = va_arg(f->args, Nod*); if(n == nil) return 0; if(nt && n->t != Nblk) fmtprint(f, "%.*s", nt, tabs); switch(n->t){ default: return fmtprint(f, "unknown nod type %d", n->t); case Niter: return fmtprint(f, "FOR ( %N ← %N ) %.*N", n->iter.idx, n->iter.arg, nt+1, n->iter.body); case Nfor: return fmtprint(f, "FOR ( %N ; %N ; %N ) %.*N", n->nfor.init, n->nfor.cond, n->nfor.step, nt+1, n->nfor.body); case Nif: if(n->nif.f) return fmtprint(f, "IF ( %N ) %.*N ELSE %.*N", n->nif.cond, nt+1, n->nif.t, nt+1, n->nif.f); return fmtprint(f, "IF ( %N ) %.*N", n->nif.cond, nt+1, n->nif.t); case Nsym: return fmtprint(f, "%s", n->sym.sym); case Nlit: switch(n->lit.t){ case Lint: return fmtprint(f, "%lld", n->lit.i); case Lstr: return fmtprint(f, "\"%s\"", n->lit.s); default: return fmtprint(f, "\n#error unknown literal type\n"); } case Nexpr: if(n->expr.op == Olit || n->expr.op == Ovar) return fmtprint(f, "%N", n->expr.lhs); else return fmtprint(f, "EXPR(%N %s %N)", n->expr.lhs, expoptab[n->expr.op], n->expr.rhs); case Nblk: e = nt - 1; if(e < 0) e = 0; return fmtprint(f, "{\n%.*L\n%.*s}", nt, n->blk.body, e, tabs); case Ndcl: return fmtprint(f, "DCL %s : %s", n->dcl.name, n->dcl.type->name); case Nfunc: return fmtprint(f, "FN %s (\n%.*L\n) → %.*N", n->func.name, nt+1, n->func.args, nt+1, n->func.body); case Ncall: return fmtprint(f, "CALL %s (\n%.*L\n%.*s)", n->call.name, nt+1, n->call.args, nt, tabs); } } int nlstfmt(Fmt *f) { int i, nt; Nlst n; nt = f->prec; n = va_arg(f->args, Nlst); for(i = 0; i < n.nv; i++){ fmtprint(f, "%.*N", nt, n.v[i]); if(i != n.nv-1) fmtprint(f, "\n"); } return 0; } int cnodfmt(Fmt *f) { Nod *n; int nt, e; nt = f->prec; n = va_arg(f->args, Nod*); if(n == nil) return 0; if(nt && n->t != Nblk) fmtprint(f, "%.*s", nt, tabs); switch(n->t){ default: return fmtprint(f, "unknown nod type %d", n->t); case Nfor: return fmtprint(f, "for(%O; %O; %O) %.*O", n->nfor.init, n->nfor.cond, n->nfor.step, nt+1, n->nfor.body); case Nif: if(n->nif.f) return fmtprint(f, "if(%O)%.*Oelse%.*O", n->nif.cond, nt+1, n->nif.t, nt+1, n->nif.f); return fmtprint(f, "if(%O)%.*O", n->nif.cond, nt+1, n->nif.t); case Nsym: return fmtprint(f, "%s", n->sym.sym); case Nlit: switch(n->lit.t){ case Lint: return fmtprint(f, "%lld", n->lit.i); case Lstr: return fmtprint(f, "\"%s\"", n->lit.s); default: return fmtprint(f, "\n#error unknown literal type\n"); } case Nexpr: if(n->expr.op == Olit || n->expr.op == Ovar) return fmtprint(f, "%O", n->expr.lhs); else return fmtprint(f, "%O %s %O", n->expr.lhs, expoptab[n->expr.op], n->expr.rhs); case Nblk: e = nt - 1; if(e < 0) e = 0; return fmtprint(f, "{\n%.*M\n%.*s}", nt, n->blk.body, e, tabs); case Ndcl: return fmtprint(f, "%s %s", n->dcl.type->name, n->dcl.name); case Nfunc: return fmtprint(f, "void\n%s(%M)\n%.*O", n->func.name, n->func.args, nt+1, n->func.body); case Ncall: return fmtprint(f, "%s(%M)", n->call.name, n->call.args); } } int cnlstfmt(Fmt *f) { int i, nt; Nlst n; nt = f->prec; n = va_arg(f->args, Nlst); for(i = 0; i < n.nv; i++){ fmtprint(f, "%.*O", nt, n.v[i]); if(i != n.nv-1) fmtprint(f, ", "); } return 0; } void astfmtinstall(void) { memset(tabs, '\t', nelem(tabs)-1); tabs[nelem(tabs)-1] = '\0'; fmtinstall('N', nodfmt); fmtinstall('L', nlstfmt); fmtinstall('O', cnodfmt); fmtinstall('M', cnlstfmt); }