// Copyright 2009 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.

// The printer package implements printing of AST nodes.
package printer

import (
	"fmt";
	"go/ast";
	"go/token";
	"io";
	"os";
	"reflect";
)


// Printing is controlled with these flags supplied
// to Fprint via the mode parameter.
//
const (
	ExportsOnly uint = 1 << iota;  // print exported code only
	DocComments;  // print documentation comments
	OptCommas;  // print optional commas
	OptSemis;  // print optional semicolons
)


type printer struct {
	// configuration (does not change after initialization)
	output io.Writer;
	mode uint;
	errors chan os.Error;
	comments ast.Comments;  // list of unassociated comments; or nil

	// current state (changes during printing)
	written int;  // number of bytes written
	level int;  // function nesting level; 0 = package scope, 1 = top-level function scope, etc.
	indent int;  // indent level
	pos token.Position;  // output position (possibly estimated) in "AST space"

	// comments
	cindex int;  // the current comment index
	cpos token.Position;  // the position of the next comment
}


func (p *printer) hasComment(pos token.Position) bool {
	return p.cpos.Offset < pos.Offset;
}


func (p *printer) nextComment() {
	p.cindex++;
	if p.comments != nil && p.cindex < len(p.comments) && p.comments[p.cindex] != nil {
		p.cpos = p.comments[p.cindex].Pos();
	} else {
		p.cpos = token.Position{1<<30, 1<<30, 1};  // infinite
	}
}


func (p *printer) setComments(comments ast.Comments) {
	p.comments = comments;
	p.cindex = -1;
	p.nextComment();
}


func (p *printer) init(output io.Writer, mode uint) {
	p.output = output;
	p.mode = mode;
	p.errors = make(chan os.Error);
	p.setComments(nil);
}


var (
	blank = []byte{' '};
	tab = []byte{'\t'};
	newline = []byte{'\n'};
	formfeed = []byte{'\f'};
)


// Writing to p.output is done with write0 which also handles errors.
// It should only be called by write.
//
func (p *printer) write0(data []byte) {
	n, err := p.output.Write(data);
	p.written += n;
	if err != nil {
		p.errors <- err;
	}
}


func (p *printer) write(data []byte) {
	i0 := 0;
	for i, b := range data {
		if b == '\n' || b == '\f' {
			// write segment ending in a newline/formfeed followed by indentation
			// TODO should convert '\f' into '\n' if the output is not going through
			//      tabwriter
			p.write0(data[i0 : i+1]);
			for j := p.indent; j > 0; j-- {
				p.write0(tab);
			}
			i0 = i+1;

			// update p.pos
			p.pos.Offset += i+1 - i0 + p.indent;
			p.pos.Line++;
			p.pos.Column = p.indent + 1;
		}
	}

	// write remaining segment
	p.write0(data[i0 : len(data)]);

	// update p.pos
	n := len(data) - i0;
	p.pos.Offset += n;
	p.pos.Column += n;
}


// Reduce contiguous sequences of '\t' in a []byte to a single '\t'.
func untabify(src []byte) []byte {
	dst := make([]byte, len(src));
	j := 0;
	for i, c := range src {
		if c != '\t' || i == 0 || src[i-1] != '\t' {
			dst[j] = c;
			j++;
		}
	}
	return dst[0 : j];
}


func (p *printer) adjustSpacingAndMergeComments() {
	for ; p.hasComment(p.pos); p.nextComment() {
		// we have a comment that comes before the current position
		comment := p.comments[p.cindex];
		p.write(untabify(comment.Text));
		// TODO
		// - classify comment and provide better formatting
		// - add extra newlines if so indicated by source positions
	}
}


func (p *printer) print(args ...) {
	v := reflect.NewValue(args).(reflect.StructValue);
	for i := 0; i < v.Len(); i++ {
		p.adjustSpacingAndMergeComments();
		f := v.Field(i);
		switch x := f.Interface().(type) {
		case int:
			// indentation delta
			p.indent += x;
			if p.indent < 0 {
				panic("print: negative indentation");
			}
		case []byte:
			p.write(x);
		case string:
			p.write(io.StringBytes(x));
		case token.Token:
			p.write(io.StringBytes(x.String()));
		case token.Position:
			// set current position
			p.pos = x;
		default:
			panicln("print: unsupported argument type", f.Type().String());
		}
	}
}


// ----------------------------------------------------------------------------
// Predicates

func (p *printer) optSemis() bool {
	return p.mode & OptSemis != 0;
}


func (p *printer) exportsOnly() bool {
	return p.mode & ExportsOnly != 0;
}


// The isVisibleX predicates return true if X should produce any output
// given the printing mode and depending on whether X contains exported
// names.

func (p *printer) isVisibleIdent(x *ast.Ident) bool {
	// identifiers in local scopes (p.level > 0) are always visible
	// if the surrounding code is printed in the first place
	return !p.exportsOnly() || x.IsExported() || p.level > 0;
}


func (p *printer) isVisibleIdentList(list []*ast.Ident) bool {
	for _, x := range list {
		if p.isVisibleIdent(x) {
			return true;
		}
	}
	return false;
}


func (p *printer) isVisibleFieldList(list []*ast.Field) bool {
	for _, f := range list {
		if len(f.Names) == 0 {
			// anonymous field
			// TODO should only return true if the anonymous field
			//      type is visible (for now be conservative and
			//      print it so that the generated code is valid)
			return true;
		}
		if p.isVisibleIdentList(f.Names) {
			return true;
		}
	}
	return false;
}


func (p *printer) isVisibleSpec(spec ast.Spec) bool {
	switch s := spec.(type) {
	case *ast.ImportSpec:
		return !p.exportsOnly();
	case *ast.ValueSpec:
		return p.isVisibleIdentList(s.Names);
	case *ast.TypeSpec:
		return p.isVisibleIdent(s.Name);
	}
	panic("unreachable");
	return false;
}


func (p *printer) isVisibleSpecList(list []ast.Spec) bool {
	for _, s := range list {
		if p.isVisibleSpec(s) {
			return true;
		}
	}
	return false;
}


func (p *printer) isVisibleDecl(decl ast.Decl) bool {
	switch d := decl.(type) {
	case *ast.BadDecl:
		return false;
	case *ast.GenDecl:
		return p.isVisibleSpecList(d.Specs);
	case *ast.FuncDecl:
		return p.isVisibleIdent(d.Name);
	}
	panic("unreachable");
	return false;
}


// ----------------------------------------------------------------------------
// Printing of common AST nodes.

func (p *printer) comment(c *ast.Comment) {
	if c != nil {
		text := c.Text;
		if text[1] == '/' {
			// //-style comment - dont print the '\n'
			// TODO scanner should probably not include the '\n' in this case
			text = text[0 : len(text)-1];
		}
		p.print(tab, c.Pos(), text);  // tab-separated trailing comment
	}
}


func (p *printer) doc(d ast.Comments) {
	if p.mode & DocComments != 0 {
		for _, c := range d {
			p.print(c.Pos(), c.Text);
		}
	}
}


func (p *printer) expr(x ast.Expr) bool

func (p *printer) identList(list []*ast.Ident) {
	needsComma := false;
	for i, x := range list {
		if p.isVisibleIdent(x) {
			if needsComma {
				p.print(token.COMMA, blank);
			}
			p.expr(x);
			needsComma = true;
		}
	}
}


func (p *printer) exprList(list []ast.Expr) {
	for i, x := range list {
		if i > 0 {
			p.print(token.COMMA, blank);
		}
		p.expr(x);
	}
}


func (p *printer) parameters(list []*ast.Field) {
	p.print(token.LPAREN);
	if len(list) > 0 {
		p.level++;  // adjust nesting level for parameters
		for i, par := range list {
			if i > 0 {
				p.print(token.COMMA, blank);
			}
			p.identList(par.Names);  // p.level > 0; all identifiers will be printed
			if len(par.Names) > 0 {
				// at least one identifier
				p.print(blank);
			};
			p.expr(par.Type);
		}
		p.level--;
	}
	p.print(token.RPAREN);
}


func (p *printer) signature(params, result []*ast.Field) {
	p.parameters(params);
	if result != nil {
		p.print(blank);

		if len(result) == 1 && result[0].Names == nil {
			// single anonymous result; no ()'s unless it's a function type
			f := result[0];
			if _, isFtyp := f.Type.(*ast.FuncType); !isFtyp {
				p.expr(f.Type);
				return;
			}
		}

		p.parameters(result);
	}
}


// Returns true if the field list ends in a closing brace.
func (p *printer) fieldList(lbrace token.Position, list []*ast.Field, rbrace token.Position, isInterface bool) bool {
	hasBody := p.isVisibleFieldList(list);
	if !lbrace.IsValid() || p.exportsOnly() && !hasBody {
		// forward declaration without {}'s or no visible exported fields
		// (in all other cases, the {}'s must be printed even if there are
		// no fields, otherwise the type is incorrect)
		return false;  // no {}'s
	}

	p.print(blank, lbrace, token.LBRACE);

	if hasBody {
		p.print(+1, newline);

		var needsSemi bool;
		var lastWasAnon bool;  // true if the previous line was an anonymous field
		var lastComment *ast.Comment;  // the comment from the previous line
		for _, f := range list {
			hasNames := p.isVisibleIdentList(f.Names);
			isAnon := len(f.Names) == 0;

			if hasNames || isAnon {
				// at least one visible identifier or anonymous field
				// TODO this is conservative - see isVisibleFieldList
				if needsSemi {
					p.print(token.SEMICOLON);
					p.comment(lastComment);
					if lastWasAnon == isAnon {
						// previous and current line have same structure;
						// continue with existing columns
						p.print(newline);
					} else {
						// previous and current line have different structure;
						// flush tabwriter and start new columns (the "type
						// column" on a line with named fields may line up
						// with the "trailing comment column" on a line with
						// an anonymous field, leading to bad alignment)
						p.print(formfeed);
					}
				}

				p.doc(f.Doc);
				if hasNames {
					p.identList(f.Names);
					p.print(tab);
				}

				if isInterface {
					if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
						// methods
						p.signature(ftyp.Params, ftyp.Results);
					} else {
						// embedded interface
						p.expr(f.Type);
					}
				} else {
					p.expr(f.Type);
					if f.Tag != nil && !p.exportsOnly() {
						p.print(tab);
						p.expr(&ast.StringList{f.Tag});
					}
				}

				needsSemi = true;
				lastWasAnon = isAnon;
				lastComment = f.Comment;
			}
		}

		if p.optSemis() {
			p.print(token.SEMICOLON);
		}

		p.comment(lastComment);
		p.print(-1, newline);
	}

	p.print(rbrace, token.RBRACE);
	return true;  // field list with {}'s
}


// ----------------------------------------------------------------------------
// Expressions

func (p *printer) stmt(s ast.Stmt) (optSemi bool)

// Returns true if a separating semicolon is optional.
func (p *printer) expr1(expr ast.Expr, prec1 int) (optSemi bool) {
	p.print(expr.Pos());

	switch x := expr.(type) {
	case *ast.BadExpr:
		p.print("BadExpr");

	case *ast.Ident:
		p.print(x.Value);

	case *ast.BinaryExpr:
		prec := x.Op.Precedence();
		if prec < prec1 {
			p.print(token.LPAREN);
		}
		p.expr1(x.X, prec);
		p.print(blank, x.OpPos, x.Op, blank);
		p.expr1(x.Y, prec);
		if prec < prec1 {
			p.print(token.RPAREN);
		}

	case *ast.KeyValueExpr:
		p.expr(x.Key);
		p.print(blank, x.Colon, token.COLON, blank);
		p.expr(x.Value);

	case *ast.StarExpr:
		p.print(token.MUL);
		p.expr(x.X);

	case *ast.UnaryExpr:
		prec := token.UnaryPrec;
		if prec < prec1 {
			p.print(token.LPAREN);
		}
		p.print(x.Op);
		if x.Op == token.RANGE {
			p.print(blank);
		}
		p.expr1(x.X, prec);
		if prec < prec1 {
			p.print(token.RPAREN);
		}

	case *ast.IntLit:
		p.print(x.Value);

	case *ast.FloatLit:
		p.print(x.Value);

	case *ast.CharLit:
		p.print(x.Value);

	case *ast.StringLit:
		p.print(x.Value);

	case *ast.StringList:
		for i, x := range x.Strings {
			if i > 0 {
				p.print(blank);
			}
			p.expr(x);
		}

	case *ast.FuncLit:
		p.expr(x.Type);
		p.print(blank);
		p.level++;  // adjust nesting level for function body
		p.stmt(x.Body);
		p.level--;

	case *ast.ParenExpr:
		p.print(token.LPAREN);
		p.expr(x.X);
		p.print(x.Rparen, token.RPAREN);

	case *ast.SelectorExpr:
		p.expr1(x.X, token.HighestPrec);
		p.print(token.PERIOD);
		p.expr1(x.Sel, token.HighestPrec);

	case *ast.TypeAssertExpr:
		p.expr1(x.X, token.HighestPrec);
		p.print(token.PERIOD, token.LPAREN);
		p.expr(x.Type);
		p.print(token.RPAREN);

	case *ast.IndexExpr:
		p.expr1(x.X, token.HighestPrec);
		p.print(token.LBRACK);
		p.expr(x.Index);
		if x.End != nil {
			p.print(blank, token.COLON, blank);
			p.expr(x.End);
		}
		p.print(token.RBRACK);

	case *ast.CallExpr:
		p.expr1(x.Fun, token.HighestPrec);
		p.print(x.Lparen, token.LPAREN);
		p.exprList(x.Args);
		p.print(x.Rparen, token.RPAREN);

	case *ast.CompositeLit:
		p.expr1(x.Type, token.HighestPrec);
		p.print(x.Lbrace, token.LBRACE);
		p.exprList(x.Elts);
		if p.mode & OptCommas != 0 {
			p.print(token.COMMA);
		}
		p.print(x.Rbrace, token.RBRACE);

	case *ast.Ellipsis:
		p.print(token.ELLIPSIS);

	case *ast.ArrayType:
		p.print(token.LBRACK);
		if x.Len != nil {
			p.expr(x.Len);
		}
		p.print(token.RBRACK);
		p.expr(x.Elt);

	case *ast.StructType:
		p.print(token.STRUCT);
		optSemi = p.fieldList(x.Lbrace, x.Fields, x.Rbrace, false);

	case *ast.FuncType:
		p.print(token.FUNC);
		p.signature(x.Params, x.Results);

	case *ast.InterfaceType:
		p.print(token.INTERFACE);
		optSemi = p.fieldList(x.Lbrace, x.Methods, x.Rbrace, true);

	case *ast.MapType:
		p.print(token.MAP, blank, token.LBRACK);
		p.expr(x.Key);
		p.print(token.RBRACK);
		p.expr(x.Value);

	case *ast.ChanType:
		switch x.Dir {
		case ast.SEND | ast.RECV:
			p.print(token.CHAN);
		case ast.RECV:
			p.print(token.ARROW, token.CHAN);
		case ast.SEND:
			p.print(token.CHAN, blank, token.ARROW);
		}
		p.print(blank);
		p.expr(x.Value);

	default:
		panic("unreachable");
	}

	return optSemi;
}


// Returns true if a separating semicolon is optional.
func (p *printer) expr(x ast.Expr) bool {
	return p.expr1(x, token.LowestPrec);
}


// ----------------------------------------------------------------------------
// Statements

func (p *printer) decl(decl ast.Decl) (optSemi bool)

// Print the statement list indented, but without a newline after the last statement.
func (p *printer) stmtList(list []ast.Stmt) {
	if len(list) > 0 {
		p.print(+1, newline);
		optSemi := false;
		for i, s := range list {
			if i > 0 {
				if !optSemi || p.optSemis() {
					// semicolon is required
					p.print(token.SEMICOLON);
				}
				p.print(newline);
			}
			optSemi = p.stmt(s);
		}
		if p.optSemis() {
			p.print(token.SEMICOLON);
		}
		p.print(-1);
	}
}


func (p *printer) block(s *ast.BlockStmt) {
	p.print(s.Pos(), token.LBRACE);
	if len(s.List) > 0 {
		p.stmtList(s.List);
		p.print(newline);
	}
	p.print(s.Rbrace, token.RBRACE);
}


func (p *printer) switchBlock(s *ast.BlockStmt) {
	p.print(s.Pos(), token.LBRACE);
	if len(s.List) > 0 {
		for i, s := range s.List {
			// s is one of *ast.CaseClause, *ast.TypeCaseClause, *ast.CommClause;
			p.print(newline);
			p.stmt(s);
		}
		p.print(newline);
	}
	p.print(s.Rbrace, token.RBRACE);
}


func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, post ast.Stmt) {
	if init == nil && post == nil {
		// no semicolons required
		if expr != nil {
			p.print(blank);
			p.expr(expr);
		}
	} else {
		// all semicolons required
		// (they are not separators, print them explicitly)
		p.print(blank);
		if init != nil {
			p.stmt(init);
		}
		p.print(token.SEMICOLON, blank);
		if expr != nil {
			p.expr(expr);
		}
		if isForStmt {
			p.print(token.SEMICOLON, blank);
			if post != nil {
				p.stmt(post);
			}
		}
	}
}


// Returns true if a separating semicolon is optional.
func (p *printer) stmt(stmt ast.Stmt) (optSemi bool) {
	p.print(stmt.Pos());

	switch s := stmt.(type) {
	case *ast.BadStmt:
		p.print("BadStmt");

	case *ast.DeclStmt:
		optSemi = p.decl(s.Decl);

	case *ast.EmptyStmt:
		// nothing to do

	case *ast.LabeledStmt:
		p.print(-1, newline);
		p.expr(s.Label);
		p.print(token.COLON, tab, +1);
		optSemi = p.stmt(s.Stmt);

	case *ast.ExprStmt:
		p.expr(s.X);

	case *ast.IncDecStmt:
		p.expr(s.X);
		p.print(s.Tok);

	case *ast.AssignStmt:
		p.exprList(s.Lhs);
		p.print(blank, s.TokPos, s.Tok, blank);
		p.exprList(s.Rhs);

	case *ast.GoStmt:
		p.print(token.GO, blank);
		p.expr(s.Call);

	case *ast.DeferStmt:
		p.print(token.DEFER, blank);
		p.expr(s.Call);

	case *ast.ReturnStmt:
		p.print(token.RETURN);
		if s.Results != nil {
			p.print(blank);
			p.exprList(s.Results);
		}

	case *ast.BranchStmt:
		p.print(s.Tok);
		if s.Label != nil {
			p.print(blank);
			p.expr(s.Label);
		}

	case *ast.BlockStmt:
		p.block(s);
		optSemi = true;

	case *ast.IfStmt:
		p.print(token.IF);
		p.controlClause(false, s.Init, s.Cond, nil);
		p.print(blank);
		p.block(s.Body);
		optSemi = true;
		if s.Else != nil {
			p.print(blank, token.ELSE, blank);
			optSemi = p.stmt(s.Else);
		}

	case *ast.CaseClause:
		if s.Values != nil {
			p.print(token.CASE, blank);
			p.exprList(s.Values);
		} else {
			p.print(token.DEFAULT);
		}
		p.print(s.Colon, token.COLON);
		p.stmtList(s.Body);

	case *ast.SwitchStmt:
		p.print(token.SWITCH);
		p.controlClause(false, s.Init, s.Tag, nil);
		p.print(blank);
		p.switchBlock(s.Body);
		optSemi = true;

	case *ast.TypeCaseClause:
		if s.Type != nil {
			p.print(token.CASE, blank);
			p.expr(s.Type);
		} else {
			p.print(token.DEFAULT);
		}
		p.print(s.Colon, token.COLON);
		p.stmtList(s.Body);

	case *ast.TypeSwitchStmt:
		p.print(token.SWITCH);
		if s.Init != nil {
			p.print(blank);
			p.stmt(s.Init);
			p.print(token.SEMICOLON);
		}
		p.print(blank);
		p.stmt(s.Assign);
		p.print(blank);
		p.switchBlock(s.Body);
		optSemi = true;

	case *ast.CommClause:
		if s.Rhs != nil {
			p.print(token.CASE, blank);
			if s.Lhs != nil {
				p.expr(s.Lhs);
				p.print(blank, s.Tok, blank);
			}
			p.expr(s.Rhs);
		} else {
			p.print(token.DEFAULT);
		}
		p.print(s.Colon, token.COLON);
		p.stmtList(s.Body);

	case *ast.SelectStmt:
		p.print(token.SELECT, blank);
		p.switchBlock(s.Body);
		optSemi = true;

	case *ast.ForStmt:
		p.print(token.FOR);
		p.controlClause(true, s.Init, s.Cond, s.Post);
		p.print(blank);
		p.block(s.Body);
		optSemi = true;

	case *ast.RangeStmt:
		p.print(token.FOR, blank);
		p.expr(s.Key);
		if s.Value != nil {
			p.print(token.COMMA, blank);
			p.expr(s.Value);
		}
		p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank);
		p.expr(s.X);
		p.print(blank);
		p.block(s.Body);
		optSemi = true;

	default:
		panic("unreachable");
	}

	return optSemi;
}


// ----------------------------------------------------------------------------
// Declarations

// Returns true if a separating semicolon is optional.
func (p *printer) spec(spec ast.Spec) (optSemi bool) {
	switch s := spec.(type) {
	case *ast.ImportSpec:
		p.doc(s.Doc);
		if s.Name != nil {
			p.expr(s.Name);
		}
		// TODO fix for longer package names
		p.print(tab, s.Path[0].Pos(), s.Path[0].Value);

	case *ast.ValueSpec:
		p.doc(s.Doc);
		p.identList(s.Names);
		if s.Type != nil {
			p.print(blank);  // TODO switch to tab? (indent problem with structs)
			p.expr(s.Type);
		}
		if s.Values != nil {
			p.print(tab, token.ASSIGN, blank);
			p.exprList(s.Values);
		}

	case *ast.TypeSpec:
		p.doc(s.Doc);
		p.expr(s.Name);
		p.print(blank);  // TODO switch to tab? (but indent problem with structs)
		optSemi = p.expr(s.Type);

	default:
		panic("unreachable");
	}

	return optSemi;
}


// Returns true if a separating semicolon is optional.
func (p *printer) decl(decl ast.Decl) (optSemi bool) {
	switch d := decl.(type) {
	case *ast.BadDecl:
		p.print(d.Pos(), "BadDecl");

	case *ast.GenDecl:
		p.doc(d.Doc);
		p.print(d.Pos(), d.Tok, blank);

		if d.Lparen.IsValid() {
			// group of parenthesized declarations
			p.print(d.Lparen, token.LPAREN);
			if p.isVisibleSpecList(d.Specs) {
				p.print(+1, newline);
				semi := false;
				for _, s := range d.Specs {
					if p.isVisibleSpec(s) {
						if semi {
							p.print(token.SEMICOLON, newline);
						}
						p.spec(s);
						semi = true;
					}
				}
				if p.optSemis() {
					p.print(token.SEMICOLON);
				}
				p.print(-1, newline);
			}
			p.print(d.Rparen, token.RPAREN);
			optSemi = true;

		} else {
			// single declaration
			optSemi = p.spec(d.Specs[0]);
		}

	case *ast.FuncDecl:
		p.doc(d.Doc);
		p.print(d.Pos(), token.FUNC, blank);
		if recv := d.Recv; recv != nil {
			// method: print receiver
			p.print(token.LPAREN);
			if len(recv.Names) > 0 {
				p.expr(recv.Names[0]);
				p.print(blank);
			}
			p.expr(recv.Type);
			p.print(token.RPAREN, blank);
		}
		p.expr(d.Name);
		p.signature(d.Type.Params, d.Type.Results);
		if !p.exportsOnly() && d.Body != nil {
			p.print(blank);
			p.level++;  // adjust nesting level for function body
			p.stmt(d.Body);
			p.level--;
		}

	default:
		panic("unreachable");
	}

	return optSemi;
}


// ----------------------------------------------------------------------------
// Programs

func (p *printer) program(prog *ast.Program) {
	// set unassociated comments if all code is printed
	if !p.exportsOnly() {
		// TODO enable this once comments are properly interspersed
		//p.setComments(prog.Comments);
	}

	p.doc(prog.Doc);
	p.print(prog.Pos(), token.PACKAGE, blank);
	p.expr(prog.Name);

	for _, d := range prog.Decls {
		if p.isVisibleDecl(d) {
			p.print(newline, newline);
			p.decl(d);
			if p.optSemis() {
				p.print(token.SEMICOLON);
			}
		}
	}

	p.print(newline);
}


// ----------------------------------------------------------------------------
// Public interface

// Fprint "pretty-prints" an AST node to output and returns the number of
// bytes written, and an error, if any. The node type must be *ast.Program,
// or assignment-compatible to ast.Expr, ast.Decl, or ast.Stmt. Printing is
// controlled by the mode parameter. For best results, the output should be
// a tabwriter.Writer.
//
func Fprint(output io.Writer, node interface{}, mode uint) (int, os.Error) {
	var p printer;
	p.init(output, mode);

	go func() {
		switch n := node.(type) {
		case ast.Expr:
			p.expr(n);
		case ast.Stmt:
			p.stmt(n);
		case ast.Decl:
			p.decl(n);
		case *ast.Program:
			p.program(n);
		default:
			p.errors <- os.NewError("unsupported node type");
		}
		p.errors <- nil;  // no errors
	}();
	err := <-p.errors;  // wait for completion of goroutine

	return p.written, err;
}
