shithub: hammer

ref: 893a6828d04ad197b2eb773d19bff69ba63af14e
dir: /fmt.c/

View raw version
#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;

	nt = f->prec;
	n = va_arg(f->args, Nod*);
	if(n == nil)
		return 0;
	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:
		return fmtprint(f, "%lld", n->lit.val);
	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:
		return fmtprint(f, "{\n%.*L\n%.*s}", nt+1, n->blk.body, nt, 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, n->func.body);
	}
}

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, "%.*s%N", nt, tabs, n.v[i]);
		if(i != n.nv-1)
			fmtprint(f, "\n");
	}
	return 0;
}

void
astfmtinstall(void)
{
	memset(tabs, '\t', nelem(tabs)-1);
	tabs[nelem(tabs)-1] = '\0';
	fmtinstall('N', nodfmt);
	fmtinstall('L', nlstfmt);
}