// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include	<u.h>
#include	<libc.h>
#include	"go.h"
#include	"opnames.h"

//
// Format conversions
//	%L int		Line numbers
//
//	%E int		etype values (aka 'Kind')
//
//	%O int		Node Opcodes
//		Flags: "%#O": print go syntax. (automatic unless fmtmode == FDbg)
//
//	%J Node*	Node details
//		Flags: "%hJ" supresses things not relevant until walk.
//
//	%V Val*		Constant values
//
//	%S Sym*		Symbols
//		Flags: +,- #: mode (see below)
//			"%hS"	unqualified identifier in any mode
//			"%hhS"  strip type qualifier off of method name
//
//	%T Type*	Types
//		Flags: +,- #: mode (see below)
//			'l' definition instead of name. 
//			'h' omit "func" and receiver in function types
//			'u' (only in -/Sym mode) print type identifiers wit package name instead of prefix. 
//
//	%N Node*	Nodes
//		Flags: +,- #: mode (see below)
//			'h' (only in +/debug mode) suppress recursion
//			'l' (only in Error mode) print "foo (type Bar)"
//
//	%H NodeList*	NodeLists
//		Flags: those of %N
//			','  separate items with ',' instead of ';'
//
//	%Z Strlit*	String literals 
//
//   In mparith1.c:
//      %B Mpint*	Big integers
//	%F Mpflt*	Big floats
//
//   %S, %T and %N obey use the following flags to set the format mode:
enum {
	FErr,	//     error mode (default)
	FDbg,	//     "%+N" debug mode
	FExp,	//     "%#N" export mode
	FTypeId,  //   "%-N" turning-types-into-symbols-mode: identical types give identical strings
};
static int fmtmode;
static int fmtpkgpfx;	// %uT stickyness
//
// E.g. for %S:	%+S %#S %-S	print an identifier properly qualified for debug/export/internal mode.
//
// The mode flags  +, - and # are sticky, meaning they persist through
// recursions of %N, %T and %S, but not the h and l flags.  The u flag is
// sticky only on %T recursions and only used in %-/Sym mode.

//
// Useful format combinations:
//
//	%+N   %+H	multiline recursive debug dump of node/nodelist
//	%+hN  %+hH	non recursive debug dump
//
//	%#N   %#T	export format
//	%#lT		type definition instead of name
//	%#hT		omit"func" and receiver in function signature
//
//	%lN		"foo (type Bar)" for error messages
//
//	%-T		type identifiers
//	%-hT		type identifiers without "func" and arg names in type signatures (methodsym)
//	%-uT		type identifiers with package name instead of prefix (typesym, dcommontype, typehash)
//


static int
setfmode(unsigned long *flags)
{
	int fm;

	fm = fmtmode;
	if(*flags & FmtSign)
		fmtmode = FDbg;
	else if(*flags & FmtSharp)
		fmtmode = FExp;
	else if(*flags & FmtLeft)
		fmtmode = FTypeId;

	*flags &= ~(FmtSharp|FmtLeft|FmtSign);
	return fm;
}

// Fmt "%L": Linenumbers
static int
Lconv(Fmt *fp)
{
	struct
	{
		Hist*	incl;	/* start of this include file */
		int32	idel;	/* delta line number to apply to include */
		Hist*	line;	/* start of this #line directive */
		int32	ldel;	/* delta line number to apply to #line */
	} a[HISTSZ];
	int32 lno, d;
	int i, n;
	Hist *h;

	lno = va_arg(fp->args, int32);

	n = 0;
	for(h=hist; h!=H; h=h->link) {
		if(h->offset < 0)
			continue;
		if(lno < h->line)
			break;
		if(h->name) {
			if(h->offset > 0) {
				// #line directive
				if(n > 0 && n < HISTSZ) {
					a[n-1].line = h;
					a[n-1].ldel = h->line - h->offset + 1;
				}
			} else {
				// beginning of file
				if(n < HISTSZ) {
					a[n].incl = h;
					a[n].idel = h->line;
					a[n].line = 0;
				}
				n++;
			}
			continue;
		}
		n--;
		if(n > 0 && n < HISTSZ) {
			d = h->line - a[n].incl->line;
			a[n-1].ldel += d;
			a[n-1].idel += d;
		}
	}

	if(n > HISTSZ)
		n = HISTSZ;

	for(i=n-1; i>=0; i--) {
		if(i != n-1) {
			if(fp->flags & ~(FmtWidth|FmtPrec))
				break;
			fmtprint(fp, " ");
		}
		if(debug['L'])
			fmtprint(fp, "%s/", pathname);
		if(a[i].line)
			fmtprint(fp, "%s:%d[%s:%d]",
				a[i].line->name, lno-a[i].ldel+1,
				a[i].incl->name, lno-a[i].idel+1);
		else
			fmtprint(fp, "%s:%d",
				a[i].incl->name, lno-a[i].idel+1);
		lno = a[i].incl->line - 1;	// now print out start of this file
	}
	if(n == 0)
		fmtprint(fp, "<epoch>");

	return 0;
}

static char*
goopnames[] =
{
	[OADDR]		= "&",
	[OADD]		= "+",
	[OADDSTR]	= "+",
	[OANDAND]	= "&&",
	[OANDNOT]	= "&^",
	[OAND]		= "&",
	[OAPPEND]	= "append",
	[OAS]		= "=",
	[OAS2]		= "=",
	[OBREAK]	= "break",
	[OCALL]		= "function call",	// not actual syntax
	[OCAP]		= "cap",
	[OCASE]		= "case",
	[OCLOSE]	= "close",
	[OCOMPLEX]	= "complex",
	[OCOM]		= "^",
	[OCONTINUE]	= "continue",
	[OCOPY]		= "copy",
	[ODEC]		= "--",
	[ODEFER]	= "defer",
	[ODIV]		= "/",
	[OEQ]		= "==",
	[OFALL]		= "fallthrough",
	[OFOR]		= "for",
	[OGE]		= ">=",
	[OGOTO]		= "goto",
	[OGT]		= ">",
	[OIF]		= "if",
	[OIMAG]		= "imag",
	[OINC]		= "++",
	[OIND]		= "*",
	[OLEN]		= "len",
	[OLE]		= "<=",
	[OLSH]		= "<<",
	[OLT]		= "<",
	[OMAKE]		= "make",
	[OMINUS]	= "-",
	[OMOD]		= "%",
	[OMUL]		= "*",
	[ONEW]		= "new",
	[ONE]		= "!=",
	[ONOT]		= "!",
	[OOROR]		= "||",
	[OOR]		= "|",
	[OPANIC]	= "panic",
	[OPLUS]		= "+",
	[OPRINTN]	= "println",
	[OPRINT]	= "print",
	[ORANGE]	= "range",
	[OREAL]		= "real",
	[ORECV]		= "<-",
	[ORETURN]	= "return",
	[ORSH]		= ">>",
	[OSELECT]	= "select",
	[OSEND]		= "<-",
	[OSUB]		= "-",
	[OSWITCH]	= "switch",
	[OXOR]		= "^",
};

// Fmt "%O":  Node opcodes
static int
Oconv(Fmt *fp)
{
	int o;

	o = va_arg(fp->args, int);
	if((fp->flags & FmtSharp) || fmtmode != FDbg)
		if(o >= 0 && o < nelem(goopnames) && goopnames[o] != nil)
			return fmtstrcpy(fp, goopnames[o]);

	if(o >= 0 && o < nelem(opnames) && opnames[o] != nil)
		return fmtstrcpy(fp, opnames[o]);

	return fmtprint(fp, "O-%d", o);
}

static const char* classnames[] = {
	"Pxxx",
	"PEXTERN",
	"PAUTO",
	"PPARAM",
	"PPARAMOUT",
	"PPARAMREF",
	"PFUNC",
};

// Fmt "%J": Node details.
static int
Jconv(Fmt *fp)
{
	Node *n;
	char *s;
	int c;

	n = va_arg(fp->args, Node*);

	c = fp->flags&FmtShort;

	if(!c && n->ullman != 0)
		fmtprint(fp, " u(%d)", n->ullman);

	if(!c && n->addable != 0)
		fmtprint(fp, " a(%d)", n->addable);

	if(!c && n->vargen != 0)
		fmtprint(fp, " g(%d)", n->vargen);

	if(n->lineno != 0)
		fmtprint(fp, " l(%d)", n->lineno);

	if(!c && n->xoffset != BADWIDTH)
		fmtprint(fp, " x(%lld%+d)", n->xoffset, n->stkdelta);

	if(n->class != 0) {
		s = "";
		if(n->class & PHEAP) s = ",heap";
		if((n->class & ~PHEAP) < nelem(classnames))
			fmtprint(fp, " class(%s%s)", classnames[n->class&~PHEAP], s);
		else
			fmtprint(fp, " class(%d?%s)", n->class&~PHEAP, s);
	}

	if(n->colas != 0)
		fmtprint(fp, " colas(%d)", n->colas);

	if(n->funcdepth != 0)
		fmtprint(fp, " f(%d)", n->funcdepth);

	switch(n->esc) {
	case EscUnknown:
		break;
	case EscHeap:
		fmtprint(fp, " esc(h)");
		break;
	case EscScope:
		fmtprint(fp, " esc(s)");
		break;
	case EscNone:
		fmtprint(fp, " esc(no)");
		break;
	case EscNever:
		if(!c)
			fmtprint(fp, " esc(N)");
		break;
	default:
		fmtprint(fp, " esc(%d)", n->esc);
		break;
	}

	if(n->escloopdepth)
		fmtprint(fp, " ld(%d)", n->escloopdepth);

	if(!c && n->typecheck != 0)
		fmtprint(fp, " tc(%d)", n->typecheck);

	if(!c && n->dodata != 0)
		fmtprint(fp, " dd(%d)", n->dodata);

	if(n->isddd != 0)
		fmtprint(fp, " isddd(%d)", n->isddd);

	if(n->implicit != 0)
		fmtprint(fp, " implicit(%d)", n->implicit);

	if(!c && n->used != 0)
		fmtprint(fp, " used(%d)", n->used);
	return 0;
}

// Fmt "%V": Values
static int
Vconv(Fmt *fp)
{
	Val *v;

	v = va_arg(fp->args, Val*);

	switch(v->ctype) {
	case CTINT:
		return fmtprint(fp, "%B", v->u.xval);
	case CTFLT:
		return fmtprint(fp, "%F", v->u.fval);
	case CTCPLX:  // ? 1234i ->  (0p+0+617p+1)
		return fmtprint(fp, "(%F+%F)", &v->u.cval->real, &v->u.cval->imag);
	case CTSTR:
		return fmtprint(fp, "\"%Z\"", v->u.sval);
	case CTBOOL:
		if( v->u.bval)
			return fmtstrcpy(fp, "true");
		return fmtstrcpy(fp, "false");
	case CTNIL:
		return fmtstrcpy(fp, "nil");
	}
	return fmtprint(fp, "<%d>", v->ctype);
}

// Fmt "%Z": escaped string literals
static int
Zconv(Fmt *fp)
{
	Rune r;
	Strlit *sp;
	char *s, *se;
	int n;

	sp = va_arg(fp->args, Strlit*);
	if(sp == nil)
		return fmtstrcpy(fp, "<nil>");

	s = sp->s;
	se = s + sp->len;
	while(s < se) {
		n = chartorune(&r, s);
		s += n;
		switch(r) {
		case Runeerror:
			if(n == 1) {
				fmtprint(fp, "\\x%02x", (uchar)*(s-1));
				break;
			}
			// fall through
		default:
			if(r < ' ') {
				fmtprint(fp, "\\x%02x", r);
				break;
			}
			fmtrune(fp, r);
			break;
		case '\t':
			fmtstrcpy(fp, "\\t");
			break;
		case '\n':
			fmtstrcpy(fp, "\\n");
			break;
		case '\"':
		case '\\':
			fmtrune(fp, '\\');
			fmtrune(fp, r);
			break;
		}
	}
	return 0;
}

/*
s%,%,\n%g
s%\n+%\n%g
s%^[	]*T%%g
s%,.*%%g
s%.+%	[T&]		= "&",%g
s%^	........*\]%&~%g
s%~	%%g
*/

static char*
etnames[] =
{
	[TINT]		= "INT",
	[TUINT]		= "UINT",
	[TINT8]		= "INT8",
	[TUINT8]	= "UINT8",
	[TINT16]	= "INT16",
	[TUINT16]	= "UINT16",
	[TINT32]	= "INT32",
	[TUINT32]	= "UINT32",
	[TINT64]	= "INT64",
	[TUINT64]	= "UINT64",
	[TUINTPTR]	= "UINTPTR",
	[TFLOAT32]	= "FLOAT32",
	[TFLOAT64]	= "FLOAT64",
	[TCOMPLEX64]	= "COMPLEX64",
	[TCOMPLEX128]	= "COMPLEX128",
	[TBOOL]		= "BOOL",
	[TPTR32]	= "PTR32",
	[TPTR64]	= "PTR64",
	[TFUNC]		= "FUNC",
	[TARRAY]	= "ARRAY",
	[TSTRUCT]	= "STRUCT",
	[TCHAN]		= "CHAN",
	[TMAP]		= "MAP",
	[TINTER]	= "INTER",
	[TFORW]		= "FORW",
	[TFIELD]	= "FIELD",
	[TSTRING]	= "STRING",
	[TANY]		= "ANY",
};

// Fmt "%E": etype
static int
Econv(Fmt *fp)
{
	int et;

	et = va_arg(fp->args, int);
	if(et >= 0 && et < nelem(etnames) && etnames[et] != nil)
		return fmtstrcpy(fp, etnames[et]);
	return fmtprint(fp, "E-%d", et);
}

// Fmt "%S": syms
static int
symfmt(Fmt *fp, Sym *s)
{
	char *p;

	if(s->pkg && !(fp->flags&FmtShort)) {
		switch(fmtmode) {
		case FErr:	// This is for the user
			if(s->pkg == localpkg)
				return fmtstrcpy(fp, s->name);
			// If the name was used by multiple packages, display the full path,
			if(pkglookup(s->pkg->name, nil)->npkg > 1)
				return fmtprint(fp, "\"%Z\".%s", s->pkg->path, s->name);
			return fmtprint(fp, "%s.%s", s->pkg->name, s->name);
		case FDbg:
			return fmtprint(fp, "%s.%s", s->pkg->name, s->name);
		case FTypeId:
			if(fp->flags&FmtUnsigned)
				return fmtprint(fp, "%s.%s", s->pkg->name, s->name);	// dcommontype, typehash
			return fmtprint(fp, "%s.%s", s->pkg->prefix, s->name);	// (methodsym), typesym, weaksym
		case FExp:
			return fmtprint(fp, "@\"%Z\".%s", s->pkg->path, s->name);
		}
	}

	if(fp->flags&FmtByte) {
		// skip leading "type." in method name
		p = utfrrune(s->name, '.');
		if(p)
			return fmtstrcpy(fp, p+1);
	}

	return fmtstrcpy(fp, s->name);
}

static char*
basicnames[] =
{
	[TINT]		= "int",
	[TUINT]		= "uint",
	[TINT8]		= "int8",
	[TUINT8]	= "uint8",
	[TINT16]	= "int16",
	[TUINT16]	= "uint16",
	[TINT32]	= "int32",
	[TUINT32]	= "uint32",
	[TINT64]	= "int64",
	[TUINT64]	= "uint64",
	[TUINTPTR]	= "uintptr",
	[TFLOAT32]	= "float32",
	[TFLOAT64]	= "float64",
	[TCOMPLEX64]	= "complex64",
	[TCOMPLEX128]	= "complex128",
	[TBOOL]		= "bool",
	[TANY]		= "any",
	[TSTRING]	= "string",
	[TNIL]		= "nil",
	[TIDEAL]	= "ideal",
	[TBLANK]	= "blank",
};

static int
typefmt(Fmt *fp, Type *t)
{
	Type *t1;

	if(t == T)
		return fmtstrcpy(fp, "<T>");

	if (t == bytetype || t == runetype) {
		// in %-T mode collapse rune and byte with their originals.
		if(fmtmode != FTypeId)
			return fmtprint(fp, "%hS", t->sym);
		t = types[t->etype];
	}

	// Unless the 'l' flag was specified, if the type has a name, just print that name.
	if(!(fp->flags&FmtLong) && t->sym && t->etype != TFIELD && t != types[t->etype]) {
		switch(fmtmode) {
		case FTypeId:
			if(fp->flags&FmtShort)
				return fmtprint(fp, "%hS", t->sym);
			if(fp->flags&FmtUnsigned)
				return fmtprint(fp, "%uS", t->sym);
			// fallthrough
		case FExp:
			if(t->sym->pkg == localpkg && t->vargen)
				return fmtprint(fp, "%S·%d", t->sym, t->vargen);
			break;
		}
		return fmtprint(fp, "%S", t->sym);
	}

	if(t->etype < nelem(basicnames) && basicnames[t->etype] != nil) {
		if(fmtmode == FErr && (t == idealbool || t == idealstring))
			fmtstrcpy(fp, "ideal ");
		return fmtstrcpy(fp, basicnames[t->etype]);
	}

	if(fmtmode == FDbg)
		fmtprint(fp, "%E-", t->etype);

	switch(t->etype) {
	case TPTR32:
	case TPTR64:
		if(fmtmode == FTypeId && (fp->flags&FmtShort))
			return fmtprint(fp, "*%hT", t->type);
		return fmtprint(fp, "*%T", t->type);

	case TARRAY:
		if(t->bound >= 0)
			return fmtprint(fp, "[%d]%T", (int)t->bound, t->type);
		if(t->bound == -100)
			return fmtprint(fp, "[...]%T", t->type);
		return fmtprint(fp, "[]%T", t->type);

	case TCHAN:
		switch(t->chan) {
		case Crecv:
			return fmtprint(fp, "<-chan %T", t->type);
		case Csend:
			return fmtprint(fp, "chan<- %T", t->type);
		}

		if(t->type != T && t->type->etype == TCHAN && t->type->sym == S && t->type->chan == Crecv)
			return fmtprint(fp, "chan (%T)", t->type);
		return fmtprint(fp, "chan %T", t->type);

	case TMAP:
		return fmtprint(fp, "map[%T] %T", t->down, t->type);

	case TINTER:
		fmtstrcpy(fp, "interface {");
		for(t1=t->type; t1!=T; t1=t1->down)
			if(exportname(t1->sym->name)) {
				if(t1->down)
					fmtprint(fp, " %hS%hT;", t1->sym, t1->type);
				else
					fmtprint(fp, " %hS%hT ", t1->sym, t1->type);
			} else {
				// non-exported method names must be qualified
				if(t1->down)
					fmtprint(fp, " %uS%hT;", t1->sym, t1->type);
				else
					fmtprint(fp, " %uS%hT ", t1->sym, t1->type);
			}
		fmtstrcpy(fp, "}");
		return 0;

	case TFUNC:
		if(fp->flags & FmtShort) {
			fmtprint(fp, "%T", getinargx(t));
		} else {
			if(t->thistuple)
				fmtprint(fp, "method%T func%T", getthisx(t), getinargx(t));
			else
				fmtprint(fp, "func%T", getinargx(t));
		}
		switch(t->outtuple) {
		case 0:
			break;
		case 1:
			fmtprint(fp, " %T", getoutargx(t)->type->type);	 // struct->field->field's type
			break;
		default:
			fmtprint(fp, " %T", getoutargx(t));
			break;
		}
		return 0;

	case TSTRUCT:
		if(t->funarg) {
			fmtstrcpy(fp, "(");
			if(fmtmode == FTypeId) {	// no argument names on function signature, and no "noescape" tags
				for(t1=t->type; t1!=T; t1=t1->down)
					if(t1->down)
						fmtprint(fp, "%hT, ", t1);
					else
						fmtprint(fp, "%hT", t1);
			} else {
				for(t1=t->type; t1!=T; t1=t1->down)
					if(t1->down)
						fmtprint(fp, "%T, ", t1);
					else
						fmtprint(fp, "%T", t1);
			}
			fmtstrcpy(fp, ")");
		} else {
			fmtstrcpy(fp, "struct {");
			for(t1=t->type; t1!=T; t1=t1->down)
				if(t1->down)
					fmtprint(fp, " %T;", t1);
				else
					fmtprint(fp, " %T ", t1);
			fmtstrcpy(fp, "}");
		}
		return 0;

	case TFIELD:
		if(!(fp->flags&FmtShort)) {
			if(t->sym != S && !t->embedded)
				fmtprint(fp, "%hS ", t->sym);
			if((!t->sym || t->embedded) && fmtmode == FExp)
				fmtstrcpy(fp, "? ");
		}

		if(t->isddd)
			fmtprint(fp, "...%T", t->type->type);
		else
			fmtprint(fp, "%T", t->type);

		if(!(fp->flags&FmtShort) && t->note)
			fmtprint(fp, " \"%Z\"", t->note);
		return 0;

	case TFORW:
		if(t->sym)
			return fmtprint(fp, "undefined %S", t->sym);
		return fmtstrcpy(fp, "undefined");

	case TUNSAFEPTR:
		if(fmtmode == FExp)
			return fmtprint(fp, "@\"unsafe\".Pointer");
		return fmtprint(fp, "unsafe.Pointer");
	}

	if(fmtmode == FExp)
		fatal("missing %E case during export", t->etype);
	// Don't know how to handle - fall back to detailed prints.
	return fmtprint(fp, "%E <%S> %T", t->etype, t->sym, t->type);
}

// Statements which may be rendered with a simplestmt as init.
static int
stmtwithinit(int op)
{
	switch(op) {
	case OIF:
	case OFOR:
	case OSWITCH:
		return 1;
	}
	return 0;
}

static int
stmtfmt(Fmt *f, Node *n)
{
	int complexinit, simpleinit, extrablock;

	// some statements allow for an init, but at most one,
	// but we may have an arbitrary number added, eg by typecheck
	// and inlining.  If it doesn't fit the syntax, emit an enclosing
	// block starting with the init statements.

	// if we can just say "for" n->ninit; ... then do so
	simpleinit = n->ninit && !n->ninit->next && !n->ninit->n->ninit && stmtwithinit(n->op);
	// otherwise, print the inits as separate statements
	complexinit = n->ninit && !simpleinit && (fmtmode != FErr);
	// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
	extrablock = complexinit && stmtwithinit(n->op);

	if(extrablock)
		fmtstrcpy(f, "{");

	if(complexinit)
		fmtprint(f, " %H; ", n->ninit);

	switch(n->op){
	case ODCL:
		switch(n->left->class) {
		case PFUNC:
		case PEXTERN:
			fmtprint(f, "var %S %T", n->left->sym, n->left->type);
			break;
		default:
			fmtprint(f, "var %hS %T", n->left->sym, n->left->type);
			break;
		}
		break;

	case ODCLFIELD:
		if(n->left)
			fmtprint(f, "%N %N", n->left, n->right);
		else
			fmtprint(f, "%N", n->right);
		break;

	case OAS:
		if(n->colas && !complexinit)
			fmtprint(f, "%N := %N", n->left, n->right);
		else
			fmtprint(f, "%N = %N", n->left, n->right);
		break;

	case OASOP:
		fmtprint(f, "%N %#O= %N", n->left, n->etype, n->right);
		break;

	case OAS2:
		if(n->colas && !complexinit) {
			fmtprint(f, "%,H := %,H", n->list, n->rlist);
			break;
		}
		// fallthrough
	case OAS2DOTTYPE:
	case OAS2FUNC:
	case OAS2MAPR:
	case OAS2MAPW:
	case OAS2RECV:
		fmtprint(f, "%,H = %,H", n->list, n->rlist);
		break;

	case ORETURN:
		fmtprint(f, "return %,H", n->list);
		break;

	case OPROC:
		fmtprint(f, "go %N", n->left);
		break;

	case ODEFER:
		fmtprint(f, "defer %N", n->left);
		break;

	case OIF:
		if(simpleinit)
			fmtprint(f, "if %N; %N { %H }", n->ninit->n, n->ntest, n->nbody);
		else
			fmtprint(f, "if %N { %H }", n->ntest, n->nbody);
		if(n->nelse)
			fmtprint(f, " else { %H }", n->nelse);
		break;

	case OFOR:
		if(fmtmode == FErr) {	// TODO maybe only if FmtShort, same below
			fmtstrcpy(f, "for loop");
			break;
		}

		fmtstrcpy(f, "for");
		if(simpleinit)
			fmtprint(f, " %N;", n->ninit->n);
		else if(n->nincr)
			fmtstrcpy(f, " ;");

		if(n->ntest)
			fmtprint(f, " %N", n->ntest);

		if(n->nincr)
			fmtprint(f, "; %N", n->nincr);
		else if(simpleinit)
			fmtstrcpy(f, ";");


		fmtprint(f, " { %H }", n->nbody);
		break;

	case ORANGE:
		if(fmtmode == FErr) {
			fmtstrcpy(f, "for loop");
			break;
		}

		fmtprint(f, "for %,H = range %N { %H }", n->list, n->right, n->nbody);
		break;

	case OSELECT:
	case OSWITCH:
		if(fmtmode == FErr) {
			fmtprint(f, "%O statement", n->op);
			break;
		}

		fmtprint(f, "%#O", n->op);
		if(simpleinit)
			fmtprint(f, " %N;", n->ninit->n);
		if(n->ntest)
			fmtprint(f, "%N", n->ntest);

		fmtprint(f, " { %H }", n->list);
		break;

	case OCASE:
	case OXCASE:
		if(n->list)
			fmtprint(f, "case %,H: %H", n->list, n->nbody);
		else
			fmtprint(f, "default: %H", n->nbody);
		break;

	case OBREAK:
	case OCONTINUE:
	case OGOTO:
	case OFALL:
	case OXFALL:
		if(n->left)
			fmtprint(f, "%#O %N", n->op, n->left);
		else
			fmtprint(f, "%#O", n->op);
		break;
	}

	if(extrablock)
		fmtstrcpy(f, "}");

	return 0;
}


static int opprec[] = {
	[OAPPEND] = 8,
	[OARRAYBYTESTR] = 8,
	[OCALLFUNC] = 8,
	[OCALLINTER] = 8,
	[OCALLMETH] = 8,
	[OCALL] = 8,
	[OCAP] = 8,
	[OCLOSE] = 8,
	[OCONVIFACE] = 8,
	[OCONVNOP] = 8,
	[OCONV] = 8,
	[OCOPY] = 8,
	[OLEN] = 8,
	[OLITERAL] = 8,
	[OMAKESLICE] = 8,
	[OMAKE] = 8,
	[ONAME] = 8,
	[ONEW] = 8,
	[ONONAME] = 8,
	[OPACK] = 8,
	[OPANIC] = 8,
	[OPAREN] = 8,
	[OPRINTN] = 8,
	[OPRINT] = 8,
	[ORECV] = 8,
	[ORUNESTR] = 8,
	[OTPAREN] = 8,

	[OINDEXMAP] = 8,
	[OINDEX] = 8,
	[OIND] = 8,
	[ODOTINTER] = 8,
	[ODOTMETH] = 8,
	[ODOTPTR] = 8,
	[ODOTTYPE2] = 8,
	[ODOTTYPE] = 8,
	[ODOT] = 8,
	[OXDOT] = 8,

	[OPLUS] = 7,
	[ONOT] = 7,
	[OCOM] = 7,
	[OMINUS] = 7,
	[OADDR] = 7,
	[OIND] = 7,

	[OMUL] = 6,
	[ODIV] = 6,
	[OMOD] = 6,
	[OLSH] = 6,
	[ORSH] = 6,
	[OAND] = 6,
	[OANDNOT] = 6,

	[OADD] = 5,
	[OSUB] = 5,
	[OOR] = 5,
	[OXOR] = 5,

	[OEQ] = 4,
	[OLT] = 4,
	[OLE] = 4,
	[OGE] = 4,
	[OGT] = 4,
	[ONE] = 4,
	[OCMPSTR] = 4,

	[OSEND] = 3,
	[OANDAND] = 2,
	[OOROR] = 1,

	// Statements handled by stmtfmt
	[OAS] = -1,
	[OAS2] = -1,
	[OAS2DOTTYPE] = -1,
	[OAS2FUNC] = -1,
	[OAS2MAPR] = -1,
	[OAS2MAPW] = -1,
	[OAS2RECV] = -1,
	[OASOP] = -1,
	[OBREAK] = -1,
	[OCASE] = -1,
	[OCONTINUE] = -1,
	[ODCL] = -1,
	[ODCLFIELD] = -1,
	[ODEFER] = -1,
	[OFALL] = -1,
	[OFOR] = -1,
	[OIF] = -1,
	[OPROC] = -1,
	[ORANGE] = -1,
	[ORETURN] = -1,
	[OSELECT] = -1,
	[OSWITCH] = -1,
	[OXCASE] = -1,
	[OXFALL] = -1,

	[OEND] = 0
};

static int
exprfmt(Fmt *f, Node *n, int prec)
{
	int nprec;

	while(n && n->implicit)
		n = n->left;

	if(n == N)
		return fmtstrcpy(f, "<N>");

	nprec = opprec[n->op];
	if(n->op == OTYPE && n->sym != S)
		nprec = 8;

	if(prec > nprec)
		return fmtprint(f, "(%N)", n);

	switch(n->op) {
	case OPAREN:
		return fmtprint(f, "(%N)", n->left);

	case ODDDARG:
		return fmtprint(f, "... argument");

	case OREGISTER:
		return fmtprint(f, "%R", n->val.u.reg);

	case OLITERAL:  // this is still a bit of a mess
		if(fmtmode == FErr && n->sym != S)
			return fmtprint(f, "%S", n->sym);
		if(n->type != types[n->type->etype] && n->type != idealbool && n->type != idealstring) {
			if(isptr[n->type->etype])
				return fmtprint(f, "(%T)(%V)", n->type, &n->val);
			else 
				return fmtprint(f, "%T(%V)", n->type, &n->val);
		}
		return fmtprint(f, "%V", &n->val);

	case ONAME:
	case OPACK:
	case ONONAME:
		if(fmtmode == FExp) {
			switch(n->class&~PHEAP) {
			case PEXTERN:
			case PFUNC:
				break;
			default:
				return fmtprint(f, "%hS", n->sym);
			}
		}
		return fmtprint(f, "%S", n->sym);

	case OTYPE:
		if(n->type == T && n->sym != S)
			return fmtprint(f, "%S", n->sym);
		return fmtprint(f, "%T", n->type);

	case OTARRAY:
		return fmtprint(f, "[]%N", n->left);

	case OTPAREN:
		return fmtprint(f, "(%N)", n->left);

	case OTMAP:
		return fmtprint(f, "map[%N] %N", n->left, n->right);

	case OTCHAN:
		switch(n->etype) {
		case Crecv:
			return fmtprint(f, "<-chan %N", n->left);
		case Csend:
			return fmtprint(f, "chan<- %N", n->left);
		default:
			if(n->left != N && n->left->op == TCHAN && n->left->sym == S && n->left->etype == Crecv)
				return fmtprint(f, "chan (%N)", n->left);
			else
				return fmtprint(f, "chan %N", n->left);
		}

	case OTSTRUCT:
		return fmtprint(f, "<struct>");

	case OTINTER:
		return fmtprint(f, "<inter>");

	case OTFUNC:
		return fmtprint(f, "<func>");

	case OPLUS:
	case OMINUS:
		if(n->left->op == n->op)
			return fmtprint(f, "%#O %N", n->op, n->left);
		// fallthrough
	case OADDR:
	case OCOM:
	case OIND:
	case ONOT:
	case ORECV:
		return fmtprint(f, "%#O%N", n->op, n->left);

	case OCLOSURE:
		if(fmtmode == FErr)
			return fmtstrcpy(f, "func literal");
		// return fmtprint(f, "%T { %H }", n->type, n->nbody); this prints the list/rlist turned to types, not what we want
		if(!n->rlist)
			return fmtprint(f, "func(%,H) { %H } ", n->list, n->nbody);
		if(!n->rlist->next && !n->rlist->n->left)
			return fmtprint(f, "func(%,H) %N { %H } ", n->list, n->rlist->n->right, n->nbody);
		return fmtprint(f, "func(%,H) (%,H) { %H } ", n->list, n->rlist, n->nbody);

	case OCOMPLIT:
		return fmtstrcpy(f, "composite literal");

	case OARRAYLIT:
	case OMAPLIT:
	case OSTRUCTLIT:
		if(fmtmode == FErr)
			return fmtprint(f, "%T literal", n->type);
		return fmtprint(f, "%T{ %,H }", n->type, n->list);

	case OKEY:
		if(n->left && n->right)
			return fmtprint(f, "%N:%N", n->left, n->right);
		if(!n->left && n->right)
			return fmtprint(f, ":%N", n->right);
		if(n->left && !n->right)
			return fmtprint(f, "%N:", n->left);
		return fmtstrcpy(f, ":");

	case OXDOT:
	case ODOT:
	case ODOTPTR:
	case ODOTINTER:
	case ODOTMETH:
		exprfmt(f, n->left, nprec);
		if(n->right == N || n->right->sym == S)
			fmtstrcpy(f, ".<nil>");
		return fmtprint(f, ".%hhS", n->right->sym);

	case ODOTTYPE:
	case ODOTTYPE2:
		exprfmt(f, n->left, nprec);
		if(n->right != N)
			return fmtprint(f, ".(%N)", n->right);
		return fmtprint(f, ".(%T)", n->type);

	case OINDEX:
	case OINDEXMAP:
	case OSLICE:
	case OSLICESTR:
	case OSLICEARR:
		exprfmt(f, n->left, nprec);
		return fmtprint(f, "[%N]", n->right);

	case OCOMPLEX:
		return fmtprint(f, "%#O(%N, %N)", n->op, n->left, n->right);

	case OCONV:
	case OCONVIFACE:
	case OCONVNOP:
	case OARRAYBYTESTR:
	case OSTRARRAYBYTE:
	case ORUNESTR:
		if(n->type == T || n->type->sym == S)
			return fmtprint(f, "(%T)(%N)", n->type, n->left);
		if(n->left)
			return fmtprint(f, "%T(%N)", n->type, n->left);
		return fmtprint(f, "%T(%,H)", n->type, n->list);

	case OREAL:
	case OIMAG:
	case OAPPEND:
	case OCAP:
	case OCLOSE:
	case OLEN:
	case OCOPY:
	case OMAKE:
	case ONEW:
	case OPANIC:
	case OPRINT:
	case OPRINTN:
		if(n->left)
			return fmtprint(f, "%#O(%N)", n->op, n->left);
		if(n->isddd)
			return fmtprint(f, "%#O(%,H...)", n->op, n->list);
		return fmtprint(f, "%#O(%,H)", n->op, n->list);

	case OCALL:
	case OCALLFUNC:
	case OCALLINTER:
	case OCALLMETH:
		exprfmt(f, n->left, nprec);
		if(n->isddd)
			return fmtprint(f, "(%,H...)", n->list);
		return fmtprint(f, "(%,H)", n->list);

	case OMAKESLICE:
		if(count(n->list) > 2)
			return fmtprint(f, "make(%T, %N, %N)", n->type, n->left, n->right);   // count list, but print l/r?
		return fmtprint(f, "make(%T, %N)", n->type, n->left);

	case OMAKEMAP:
	case OMAKECHAN:
		return fmtprint(f, "make(%T)", n->type);

	case OADD:
	case OADDSTR:
	case OAND:
	case OANDAND:
	case OANDNOT:
	case ODIV:
	case OEQ:
	case OGE:
	case OGT:
	case OLE:
	case OLT:
	case OLSH:
	case OMOD:
	case OMUL:
	case ONE:
	case OOR:
	case OOROR:
	case ORSH:
	case OSEND:
	case OSUB:
	case OXOR:
		exprfmt(f, n->left, nprec);
		fmtprint(f, " %#O ", n->op);
		exprfmt(f, n->right, nprec+1);
		return 0;

	case OCMPSTR:
		exprfmt(f, n->left, nprec);
		fmtprint(f, " %#O ", n->etype);
		exprfmt(f, n->right, nprec+1);
		return 0;
	}

	return fmtprint(f, "<node %O>", n->op);
}

static int
nodefmt(Fmt *f, Node *n)
{

	if(f->flags&FmtLong && n->type != T) {
		if(n->type->etype == TNIL)
			return fmtprint(f, "nil");
		else
			return fmtprint(f, "%N (type %T)", n, n->type);

	}

	// TODO inlining produces expressions with ninits. we can't print these yet.

	if(opprec[n->op] < 0)
		return stmtfmt(f, n);

	return exprfmt(f, n, 0);
}

static int dumpdepth;

static void
indent(Fmt *fp)
{
	int i;

	for(i = 0; i < dumpdepth; ++i)
		fmtstrcpy(fp, ".   ");
}

static int
nodedump(Fmt *fp, Node *n)
{
	int recur;

	if(n == N)
		return 0;

	recur = !(fp->flags&FmtShort);

	if(recur) {
		indent(fp);
		if(dumpdepth > 10)
			return fmtstrcpy(fp, "...\n");

		if(n->ninit != nil) {
			fmtprint(fp, "%O-init\n%H", n->op, n->ninit);
			indent(fp);
		}
	}

	switch(n->op) {
	default:
		fmtprint(fp, "%O%J", n->op, n);
		break;
	case OREGISTER:
		fmtprint(fp, "%O-%R%J", n->op, n->val.u.reg, n);
		break;
	case OLITERAL:
		fmtprint(fp, "%O-%V%J", n->op, &n->val, n);
		break;
	case ONAME:
	case ONONAME:
		if(n->sym != S)
			fmtprint(fp, "%O-%S%J", n->op, n->sym, n);
		else
			fmtprint(fp, "%O%J", n->op, n);
		break;
	case OASOP:
		fmtprint(fp, "%O-%O%J", n->op, n->etype, n);
		break;
	case OTYPE:
		fmtprint(fp, "%O %S type=%T", n->op, n->sym, n->type);
		if(recur && n->type == T && n->ntype) {
			fmtstrcpy(fp, "\n");
			indent(fp);
			fmtprint(fp, "%O-ntype\n%N", n->op, n->ntype);
		}
		break;
	}

	if(n->sym != S && n->op != ONAME)
		fmtprint(fp, " %S G%d", n->sym, n->vargen);

	if(n->type != T)
		fmtprint(fp, " %T", n->type);

	if(recur) {
		fmtstrcpy(fp, "\n");
		if(n->left)
			fmtprint(fp, "%N", n->left);
		if(n->right)
			fmtprint(fp, "%N", n->right);
		if(n->list) {
			indent(fp);
			fmtprint(fp, "%O-list\n%H", n->op, n->list);
		}
		if(n->rlist) {
			indent(fp);
			fmtprint(fp, "%O-rlist\n%H", n->op, n->rlist);
		}
		if(n->ntest) {
			indent(fp);
			fmtprint(fp, "%O-test\n%N", n->op, n->ntest);
		}
		if(n->nbody) {
			indent(fp);
			fmtprint(fp, "%O-body\n%H", n->op, n->nbody);
		}
		if(n->nelse) {
			indent(fp);
			fmtprint(fp, "%O-else\n%H", n->op, n->nelse);
		}
		if(n->nincr) {
			indent(fp);
			fmtprint(fp, "%O-incr\n%N", n->op, n->nincr);
		}
	}

	return 0;
}

// Fmt "%S": syms
// Flags:  "%hS" suppresses qualifying with package
static int
Sconv(Fmt *fp)
{
	Sym *s;
	int r, sm;
	unsigned long sf;

	s = va_arg(fp->args, Sym*);
	if(s == S)
		return fmtstrcpy(fp, "<S>");

	sf = fp->flags;
	sm = setfmode(&fp->flags);
	r = symfmt(fp, s);
	fp->flags = sf;
	fmtmode = sm;
	return r;
}

// Fmt "%T": types.
// Flags: 'l' print definition, not name
//	  'h' omit 'func' and receiver from function types, short type names
//	  'u' package name, not prefix (FTypeId mode, sticky)
static int
Tconv(Fmt *fp)
{
	Type *t;
	int r, sm;
	unsigned long sf;

	t = va_arg(fp->args, Type*);
	if(t == T)
		return fmtstrcpy(fp, "<T>");

	if(t->trecur > 4)
		return fmtstrcpy(fp, "<...>");

	t->trecur++;
	sf = fp->flags;
	sm = setfmode(&fp->flags);

	if(fmtmode == FTypeId && (sf&FmtUnsigned))
		fmtpkgpfx++;
	if(fmtpkgpfx)
		fp->flags |= FmtUnsigned;

	r = typefmt(fp, t);

	if(fmtmode == FTypeId && (sf&FmtUnsigned))
		fmtpkgpfx--;

	fp->flags = sf;
	fmtmode = sm;
	t->trecur--;
	return r;
}

// Fmt '%N': Nodes.
// Flags: 'l' suffix with "(type %T)" where possible
//	  '+h' in debug mode, don't recurse, no multiline output
static int
Nconv(Fmt *fp)
{
	Node *n;
	int r, sm;
	unsigned long sf;

	n = va_arg(fp->args, Node*);
	if(n == N)
		return fmtstrcpy(fp, "<N>");
	sf = fp->flags;
	sm = setfmode(&fp->flags);

	r = -1;
	switch(fmtmode) {
	case FErr:
	case FExp:
		if(n->orig != N)
			n = n->orig;
		r = nodefmt(fp, n);
		break;
	case FDbg:
		dumpdepth++;
		r = nodedump(fp, n);
		dumpdepth--;
		break;
	default:
		fatal("unhandled %%N mode");
	}

	fp->flags = sf;
	fmtmode = sm;
	return r;
}

// Fmt '%H': NodeList.
// Flags: all those of %N plus ',': separate with comma's instead of semicolons.
static int
Hconv(Fmt *fp)
{
	NodeList *l;
	int r, sm;
	unsigned long sf;
	char *sep;

	l = va_arg(fp->args, NodeList*);

	if(l == nil && fmtmode == FDbg)
		return fmtstrcpy(fp, "<nil>");

	sf = fp->flags;
	sm = setfmode(&fp->flags);
	r = 0;
	sep = "; ";
	if(fmtmode == FDbg)
		sep = "\n";
	else if(fp->flags & FmtComma)
		sep = ", ";

	for(;l; l=l->next) {
		r += fmtprint(fp, "%N", l->n);
		if(l->next)
			r += fmtstrcpy(fp, sep);
	}

	fp->flags = sf;
	fmtmode = sm;
	return r;
}

void
fmtinstallgo(void)
{
	fmtmode = FErr;
	fmtinstall('E', Econv);		// etype opcodes
	fmtinstall('J', Jconv);		// all the node flags
	fmtinstall('H', Hconv);		// node lists
	fmtinstall('L', Lconv);		// line number
	fmtinstall('N', Nconv);		// node pointer
	fmtinstall('O', Oconv);		// node opcodes
	fmtinstall('S', Sconv);		// sym pointer
	fmtinstall('T', Tconv);		// type pointer
	fmtinstall('V', Vconv);		// val pointer
	fmtinstall('Z', Zconv);		// escaped string

	// These are in mparith1.c
	fmtinstall('B', Bconv);	// big numbers
	fmtinstall('F', Fconv);	// big float numbers

}

void
dumplist(char *s, NodeList *l)
{
	print("%s\n%+H", s, l);
}

void
dump(char *s, Node *n)
{
	print("%s [%p]\n%+N", s, n, n);
}
