// 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";
	"strings";
)


// 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(strings.Bytes(x));
		case token.Token:
			p.write(strings.Bytes(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;
}
