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

package eval

import (
	"bignum"
	"log"
	"go/ast"
	"go/token"
)

const (
	returnPC = ^uint(0)
	badPC    = ^uint(1)
)

/*
 * Statement compiler
 */

type stmtCompiler struct {
	*blockCompiler
	pos token.Position
	// This statement's label, or nil if it is not labeled.
	stmtLabel *label
}

func (a *stmtCompiler) diag(format string, args ...) {
	a.diagAt(&a.pos, format, args)
}

/*
 * Flow checker
 */

type flowEnt struct {
	// Whether this flow entry is conditional.  If true, flow can
	// continue to the next PC.
	cond bool
	// True if this will terminate flow (e.g., a return statement).
	// cond must be false and jumps must be nil if this is true.
	term bool
	// PC's that can be reached from this flow entry.
	jumps []*uint
	// Whether this flow entry has been visited by reachesEnd.
	visited bool
}

type flowBlock struct {
	// If this is a goto, the target label.
	target string
	// The inner-most block containing definitions.
	block *block
	// The numVars from each block leading to the root of the
	// scope, starting at block.
	numVars []int
}

type flowBuf struct {
	cb *codeBuf
	// ents is a map from PC's to flow entries.  Any PC missing
	// from this map is assumed to reach only PC+1.
	ents map[uint]*flowEnt
	// gotos is a map from goto positions to information on the
	// block at the point of the goto.
	gotos map[*token.Position]*flowBlock
	// labels is a map from label name to information on the block
	// at the point of the label.  labels are tracked by name,
	// since mutliple labels at the same PC can have different
	// blocks.
	labels map[string]*flowBlock
}

func newFlowBuf(cb *codeBuf) *flowBuf {
	return &flowBuf{cb, make(map[uint]*flowEnt), make(map[*token.Position]*flowBlock), make(map[string]*flowBlock)}
}

// put creates a flow control point for the next PC in the code buffer.
// This should be done before pushing the instruction into the code buffer.
func (f *flowBuf) put(cond bool, term bool, jumps []*uint) {
	pc := f.cb.nextPC()
	if ent, ok := f.ents[pc]; ok {
		log.Crashf("Flow entry already exists at PC %d: %+v", pc, ent)
	}
	f.ents[pc] = &flowEnt{cond, term, jumps, false}
}

// putTerm creates a flow control point at the next PC that
// unconditionally terminates execution.
func (f *flowBuf) putTerm() { f.put(false, true, nil) }

// put1 creates a flow control point at the next PC that jumps to one
// PC and, if cond is true, can also continue to the PC following the
// next PC.
func (f *flowBuf) put1(cond bool, jumpPC *uint) {
	f.put(cond, false, []*uint{jumpPC})
}

func newFlowBlock(target string, b *block) *flowBlock {
	// Find the inner-most block containing definitions
	for b.numVars == 0 && b.outer != nil && b.outer.scope == b.scope {
		b = b.outer
	}

	// Count parents leading to the root of the scope
	n := 0
	for bp := b; bp.scope == b.scope; bp = bp.outer {
		n++
	}

	// Capture numVars from each block to the root of the scope
	numVars := make([]int, n)
	i := 0
	for bp := b; i < n; bp = bp.outer {
		numVars[i] = bp.numVars
		i++
	}

	return &flowBlock{target, b, numVars}
}

// putGoto captures the block at a goto statement.  This should be
// called in addition to putting a flow control point.
func (f *flowBuf) putGoto(pos token.Position, target string, b *block) {
	f.gotos[&pos] = newFlowBlock(target, b)
}

// putLabel captures the block at a label.
func (f *flowBuf) putLabel(name string, b *block) {
	f.labels[name] = newFlowBlock("", b)
}

// reachesEnd returns true if the end of f's code buffer can be
// reached from the given program counter.  Error reporting is the
// caller's responsibility.
func (f *flowBuf) reachesEnd(pc uint) bool {
	endPC := f.cb.nextPC()
	if pc > endPC {
		log.Crashf("Reached bad PC %d past end PC %d", pc, endPC)
	}

	for ; pc < endPC; pc++ {
		ent, ok := f.ents[pc]
		if !ok {
			continue
		}

		if ent.visited {
			return false
		}
		ent.visited = true

		if ent.term {
			return false
		}

		// If anything can reach the end, we can reach the end
		// from pc.
		for _, j := range ent.jumps {
			if f.reachesEnd(*j) {
				return true
			}
		}
		// If the jump was conditional, we can reach the next
		// PC, so try reaching the end from it.
		if ent.cond {
			continue
		}
		return false
	}
	return true
}

// gotosObeyScopes returns true if no goto statement causes any
// variables to come into scope that were not in scope at the point of
// the goto.  Reports any errors using the given compiler.
func (f *flowBuf) gotosObeyScopes(a *compiler) {
	for pos, src := range f.gotos {
		tgt := f.labels[src.target]

		// The target block must be a parent of this block
		numVars := src.numVars
		b := src.block
		for len(numVars) > 0 && b != tgt.block {
			b = b.outer
			numVars = numVars[1:]
		}
		if b != tgt.block {
			// We jumped into a deeper block
			a.diagAt(pos, "goto causes variables to come into scope")
			return
		}

		// There must be no variables in the target block that
		// did not exist at the jump
		tgtNumVars := tgt.numVars
		for i := range numVars {
			if tgtNumVars[i] > numVars[i] {
				a.diagAt(pos, "goto causes variables to come into scope")
				return
			}
		}
	}
}

/*
 * Statement generation helpers
 */

func (a *stmtCompiler) defineVar(ident *ast.Ident, t Type) *Variable {
	v, prev := a.block.DefineVar(ident.Value, ident.Pos(), t)
	if prev != nil {
		// TODO(austin) It's silly that we have to capture
		// Pos() in a variable.
		pos := prev.Pos()
		if pos.IsValid() {
			a.diagAt(ident, "variable %s redeclared in this block\n\tprevious declaration at %s", ident.Value, &pos)
		} else {
			a.diagAt(ident, "variable %s redeclared in this block", ident.Value)
		}
		return nil
	}

	// Initialize the variable
	index := v.Index
	if v.Index >= 0 {
		a.push(func(v *Thread) { v.f.Vars[index] = t.Zero() })
	}
	return v
}

// TODO(austin) Move doAssign to here

/*
 * Statement compiler
 */

func (a *stmtCompiler) compile(s ast.Stmt) {
	if a.block.inner != nil {
		log.Crash("Child scope still entered")
	}

	notimpl := false
	switch s := s.(type) {
	case *ast.BadStmt:
		// Error already reported by parser.
		a.silentErrors++

	case *ast.DeclStmt:
		a.compileDeclStmt(s)

	case *ast.EmptyStmt:
		// Do nothing.

	case *ast.LabeledStmt:
		a.compileLabeledStmt(s)

	case *ast.ExprStmt:
		a.compileExprStmt(s)

	case *ast.IncDecStmt:
		a.compileIncDecStmt(s)

	case *ast.AssignStmt:
		a.compileAssignStmt(s)

	case *ast.GoStmt:
		notimpl = true

	case *ast.DeferStmt:
		notimpl = true

	case *ast.ReturnStmt:
		a.compileReturnStmt(s)

	case *ast.BranchStmt:
		a.compileBranchStmt(s)

	case *ast.BlockStmt:
		a.compileBlockStmt(s)

	case *ast.IfStmt:
		a.compileIfStmt(s)

	case *ast.CaseClause:
		a.diag("case clause outside switch")

	case *ast.SwitchStmt:
		a.compileSwitchStmt(s)

	case *ast.TypeCaseClause:
		notimpl = true

	case *ast.TypeSwitchStmt:
		notimpl = true

	case *ast.CommClause:
		notimpl = true

	case *ast.SelectStmt:
		notimpl = true

	case *ast.ForStmt:
		a.compileForStmt(s)

	case *ast.RangeStmt:
		notimpl = true

	default:
		log.Crashf("unexpected ast node type %T", s)
	}

	if notimpl {
		a.diag("%T statment node not implemented", s)
	}

	if a.block.inner != nil {
		log.Crash("Forgot to exit child scope")
	}
}

func (a *stmtCompiler) compileDeclStmt(s *ast.DeclStmt) {
	switch decl := s.Decl.(type) {
	case *ast.BadDecl:
		// Do nothing.  Already reported by parser.
		a.silentErrors++

	case *ast.FuncDecl:
		if !a.block.global {
			log.Crash("FuncDecl at statement level")
		}

	case *ast.GenDecl:
		if decl.Tok == token.IMPORT && !a.block.global {
			log.Crash("import at statement level")
		}

	default:
		log.Crashf("Unexpected Decl type %T", s.Decl)
	}
	a.compileDecl(s.Decl)
}

func (a *stmtCompiler) compileVarDecl(decl *ast.GenDecl) {
	for _, spec := range decl.Specs {
		spec := spec.(*ast.ValueSpec)
		if spec.Values == nil {
			// Declaration without assignment
			if spec.Type == nil {
				// Parser should have caught
				log.Crash("Type and Values nil")
			}
			t := a.compileType(a.block, spec.Type)
			// Define placeholders even if type compile failed
			for _, n := range spec.Names {
				a.defineVar(n, t)
			}
		} else {
			// Declaration with assignment
			lhs := make([]ast.Expr, len(spec.Names))
			for i, n := range spec.Names {
				lhs[i] = n
			}
			a.doAssign(lhs, spec.Values, decl.Tok, spec.Type)
		}
	}
}

func (a *stmtCompiler) compileDecl(decl ast.Decl) {
	switch d := decl.(type) {
	case *ast.BadDecl:
		// Do nothing.  Already reported by parser.
		a.silentErrors++

	case *ast.FuncDecl:
		decl := a.compileFuncType(a.block, d.Type)
		if decl == nil {
			return
		}
		// Declare and initialize v before compiling func
		// so that body can refer to itself.
		c, prev := a.block.DefineConst(d.Name.Value, a.pos, decl.Type, decl.Type.Zero())
		if prev != nil {
			pos := prev.Pos()
			if pos.IsValid() {
				a.diagAt(d.Name, "identifier %s redeclared in this block\n\tprevious declaration at %s", d.Name.Value, &pos)
			} else {
				a.diagAt(d.Name, "identifier %s redeclared in this block", d.Name.Value)
			}
		}
		fn := a.compileFunc(a.block, decl, d.Body)
		if c == nil || fn == nil {
			return
		}
		var zeroThread Thread
		c.Value.(FuncValue).Set(nil, fn(&zeroThread))

	case *ast.GenDecl:
		switch d.Tok {
		case token.IMPORT:
			log.Crashf("%v not implemented", d.Tok)
		case token.CONST:
			log.Crashf("%v not implemented", d.Tok)
		case token.TYPE:
			a.compileTypeDecl(a.block, d)
		case token.VAR:
			a.compileVarDecl(d)
		}

	default:
		log.Crashf("Unexpected Decl type %T", decl)
	}
}

func (a *stmtCompiler) compileLabeledStmt(s *ast.LabeledStmt) {
	// Define label
	l, ok := a.labels[s.Label.Value]
	if ok {
		if l.resolved.IsValid() {
			a.diag("label %s redeclared in this block\n\tprevious declaration at %s", s.Label.Value, &l.resolved)
		}
	} else {
		pc := badPC
		l = &label{name: s.Label.Value, gotoPC: &pc}
		a.labels[l.name] = l
	}
	l.desc = "regular label"
	l.resolved = s.Pos()

	// Set goto PC
	*l.gotoPC = a.nextPC()

	// Define flow entry so we can check for jumps over declarations.
	a.flow.putLabel(l.name, a.block)

	// Compile the statement.  Reuse our stmtCompiler for simplicity.
	sc := &stmtCompiler{a.blockCompiler, s.Stmt.Pos(), l}
	sc.compile(s.Stmt)
}

func (a *stmtCompiler) compileExprStmt(s *ast.ExprStmt) {
	bc := a.enterChild()
	defer bc.exit()

	e := a.compileExpr(bc.block, false, s.X)
	if e == nil {
		return
	}

	if e.exec == nil {
		a.diag("%s cannot be used as expression statement", e.desc)
		return
	}

	a.push(e.exec)
}

func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) {
	// Create temporary block for extractEffect
	bc := a.enterChild()
	defer bc.exit()

	l := a.compileExpr(bc.block, false, s.X)
	if l == nil {
		return
	}

	if l.evalAddr == nil {
		l.diag("cannot assign to %s", l.desc)
		return
	}
	if !(l.t.isInteger() || l.t.isFloat()) {
		l.diagOpType(s.Tok, l.t)
		return
	}

	var op token.Token
	var desc string
	switch s.Tok {
	case token.INC:
		op = token.ADD
		desc = "increment statement"
	case token.DEC:
		op = token.SUB
		desc = "decrement statement"
	default:
		log.Crashf("Unexpected IncDec token %v", s.Tok)
	}

	effect, l := l.extractEffect(bc.block, desc)

	one := l.newExpr(IdealIntType, "constant")
	one.pos = s.Pos()
	one.eval = func() *bignum.Integer { return bignum.Int(1) }

	binop := l.compileBinaryExpr(op, l, one)
	if binop == nil {
		return
	}

	assign := a.compileAssign(s.Pos(), bc.block, l.t, []*expr{binop}, "", "")
	if assign == nil {
		log.Crashf("compileAssign type check failed")
	}

	lf := l.evalAddr
	a.push(func(v *Thread) {
		effect(v)
		assign(lf(v), v)
	})
}

func (a *stmtCompiler) doAssign(lhs []ast.Expr, rhs []ast.Expr, tok token.Token, declTypeExpr ast.Expr) {
	nerr := a.numError()

	// Compile right side first so we have the types when
	// compiling the left side and so we don't see definitions
	// made on the left side.
	rs := make([]*expr, len(rhs))
	for i, re := range rhs {
		rs[i] = a.compileExpr(a.block, false, re)
	}

	errOp := "assignment"
	if tok == token.DEFINE || tok == token.VAR {
		errOp = "declaration"
	}
	ac, ok := a.checkAssign(a.pos, rs, errOp, "value")
	ac.allowMapForms(len(lhs))

	// If this is a definition and the LHS is too big, we won't be
	// able to produce the usual error message because we can't
	// begin to infer the types of the LHS.
	if (tok == token.DEFINE || tok == token.VAR) && len(lhs) > len(ac.rmt.Elems) {
		a.diag("not enough values for definition")
	}

	// Compile left type if there is one
	var declType Type
	if declTypeExpr != nil {
		declType = a.compileType(a.block, declTypeExpr)
	}

	// Compile left side
	ls := make([]*expr, len(lhs))
	nDefs := 0
	for i, le := range lhs {
		// If this is a definition, get the identifier and its type
		var ident *ast.Ident
		var lt Type
		switch tok {
		case token.DEFINE:
			// Check that it's an identifier
			ident, ok = le.(*ast.Ident)
			if !ok {
				a.diagAt(le, "left side of := must be a name")
				// Suppress new defitions errors
				nDefs++
				continue
			}

			// Is this simply an assignment?
			if _, ok := a.block.defs[ident.Value]; ok {
				ident = nil
				break
			}
			nDefs++

		case token.VAR:
			ident = le.(*ast.Ident)
		}

		// If it's a definition, get or infer its type.
		if ident != nil {
			// Compute the identifier's type from the RHS
			// type.  We use the computed MultiType so we
			// don't have to worry about unpacking.
			switch {
			case declTypeExpr != nil:
				// We have a declaration type, use it.
				// If declType is nil, we gave an
				// error when we compiled it.
				lt = declType

			case i >= len(ac.rmt.Elems):
				// Define a placeholder.  We already
				// gave the "not enough" error above.
				lt = nil

			case ac.rmt.Elems[i] == nil:
				// We gave the error when we compiled
				// the RHS.
				lt = nil

			case ac.rmt.Elems[i].isIdeal():
				// If the type is absent and the
				// corresponding expression is a
				// constant expression of ideal
				// integer or ideal float type, the
				// type of the declared variable is
				// int or float respectively.
				switch {
				case ac.rmt.Elems[i].isInteger():
					lt = IntType
				case ac.rmt.Elems[i].isFloat():
					lt = FloatType
				default:
					log.Crashf("unexpected ideal type %v", rs[i].t)
				}

			default:
				lt = ac.rmt.Elems[i]
			}
		}

		// If it's a definition, define the identifier
		if ident != nil {
			if a.defineVar(ident, lt) == nil {
				continue
			}
		}

		// Compile LHS
		ls[i] = a.compileExpr(a.block, false, le)
		if ls[i] == nil {
			continue
		}

		if ls[i].evalMapValue != nil {
			// Map indexes are not generally addressable,
			// but they are assignable.
			//
			// TODO(austin) Now that the expression
			// compiler uses semantic values, this might
			// be easier to implement as a function call.
			sub := ls[i]
			ls[i] = ls[i].newExpr(sub.t, sub.desc)
			ls[i].evalMapValue = sub.evalMapValue
			mvf := sub.evalMapValue
			et := sub.t
			ls[i].evalAddr = func(t *Thread) Value {
				m, k := mvf(t)
				e := m.Elem(t, k)
				if e == nil {
					e = et.Zero()
					m.SetElem(t, k, e)
				}
				return e
			}
		} else if ls[i].evalAddr == nil {
			ls[i].diag("cannot assign to %s", ls[i].desc)
			continue
		}
	}

	// A short variable declaration may redeclare variables
	// provided they were originally declared in the same block
	// with the same type, and at least one of the variables is
	// new.
	if tok == token.DEFINE && nDefs == 0 {
		a.diag("at least one new variable must be declared")
		return
	}

	// If there have been errors, our arrays are full of nil's so
	// get out of here now.
	if nerr != a.numError() {
		return
	}

	// Check for 'a[x] = r, ok'
	if len(ls) == 1 && len(rs) == 2 && ls[0].evalMapValue != nil {
		a.diag("a[x] = r, ok form not implemented")
		return
	}

	// Create assigner
	var lt Type
	n := len(lhs)
	if n == 1 {
		lt = ls[0].t
	} else {
		lts := make([]Type, len(ls))
		for i, l := range ls {
			if l != nil {
				lts[i] = l.t
			}
		}
		lt = NewMultiType(lts)
	}
	bc := a.enterChild()
	defer bc.exit()
	assign := ac.compile(bc.block, lt)
	if assign == nil {
		return
	}

	// Compile
	if n == 1 {
		// Don't need temporaries and can avoid []Value.
		lf := ls[0].evalAddr
		a.push(func(t *Thread) { assign(lf(t), t) })
	} else if tok == token.VAR || (tok == token.DEFINE && nDefs == n) {
		// Don't need temporaries
		lfs := make([]func(*Thread) Value, n)
		for i, l := range ls {
			lfs[i] = l.evalAddr
		}
		a.push(func(t *Thread) {
			dest := make([]Value, n)
			for i, lf := range lfs {
				dest[i] = lf(t)
			}
			assign(multiV(dest), t)
		})
	} else {
		// Need temporaries
		lmt := lt.(*MultiType)
		lfs := make([]func(*Thread) Value, n)
		for i, l := range ls {
			lfs[i] = l.evalAddr
		}
		a.push(func(t *Thread) {
			temp := lmt.Zero().(multiV)
			assign(temp, t)
			// Copy to destination
			for i := 0; i < n; i++ {
				// TODO(austin) Need to evaluate LHS
				// before RHS
				lfs[i](t).Assign(t, temp[i])
			}
		})
	}
}

var assignOpToOp = map[token.Token]token.Token{
	token.ADD_ASSIGN: token.ADD,
	token.SUB_ASSIGN: token.SUB,
	token.MUL_ASSIGN: token.MUL,
	token.QUO_ASSIGN: token.QUO,
	token.REM_ASSIGN: token.REM,

	token.AND_ASSIGN: token.AND,
	token.OR_ASSIGN: token.OR,
	token.XOR_ASSIGN: token.XOR,
	token.SHL_ASSIGN: token.SHL,
	token.SHR_ASSIGN: token.SHR,
	token.AND_NOT_ASSIGN: token.AND_NOT,
}

func (a *stmtCompiler) doAssignOp(s *ast.AssignStmt) {
	if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
		a.diag("tuple assignment cannot be combined with an arithmetic operation")
		return
	}

	// Create temporary block for extractEffect
	bc := a.enterChild()
	defer bc.exit()

	l := a.compileExpr(bc.block, false, s.Lhs[0])
	r := a.compileExpr(bc.block, false, s.Rhs[0])
	if l == nil || r == nil {
		return
	}

	if l.evalAddr == nil {
		l.diag("cannot assign to %s", l.desc)
		return
	}

	effect, l := l.extractEffect(bc.block, "operator-assignment")

	binop := r.compileBinaryExpr(assignOpToOp[s.Tok], l, r)
	if binop == nil {
		return
	}

	assign := a.compileAssign(s.Pos(), bc.block, l.t, []*expr{binop}, "assignment", "value")
	if assign == nil {
		log.Crashf("compileAssign type check failed")
	}

	lf := l.evalAddr
	a.push(func(t *Thread) {
		effect(t)
		assign(lf(t), t)
	})
}

func (a *stmtCompiler) compileAssignStmt(s *ast.AssignStmt) {
	switch s.Tok {
	case token.ASSIGN, token.DEFINE:
		a.doAssign(s.Lhs, s.Rhs, s.Tok, nil)

	default:
		a.doAssignOp(s)
	}
}

func (a *stmtCompiler) compileReturnStmt(s *ast.ReturnStmt) {
	if a.fnType == nil {
		a.diag("cannot return at the top level")
		return
	}

	if len(s.Results) == 0 && (len(a.fnType.Out) == 0 || a.outVarsNamed) {
		// Simple case.  Simply exit from the function.
		a.flow.putTerm()
		a.push(func(v *Thread) { v.pc = returnPC })
		return
	}

	bc := a.enterChild()
	defer bc.exit()

	// Compile expressions
	bad := false
	rs := make([]*expr, len(s.Results))
	for i, re := range s.Results {
		rs[i] = a.compileExpr(bc.block, false, re)
		if rs[i] == nil {
			bad = true
		}
	}
	if bad {
		return
	}

	// Create assigner

	// However, if the expression list in the "return" statement
	// is a single call to a multi-valued function, the values
	// returned from the called function will be returned from
	// this one.
	assign := a.compileAssign(s.Pos(), bc.block, NewMultiType(a.fnType.Out), rs, "return", "value")

	// XXX(Spec) "The result types of the current function and the
	// called function must match."  Match is fuzzy.  It should
	// say that they must be assignment compatible.

	// Compile
	start := len(a.fnType.In)
	nout := len(a.fnType.Out)
	a.flow.putTerm()
	a.push(func(t *Thread) {
		assign(multiV(t.f.Vars[start:start+nout]), t)
		t.pc = returnPC
	})
}

func (a *stmtCompiler) findLexicalLabel(name *ast.Ident, pred func(*label) bool, errOp, errCtx string) *label {
	bc := a.blockCompiler
	for ; bc != nil; bc = bc.parent {
		if bc.label == nil {
			continue
		}
		l := bc.label
		if name == nil && pred(l) {
			return l
		}
		if name != nil && l.name == name.Value {
			if !pred(l) {
				a.diag("cannot %s to %s %s", errOp, l.desc, l.name)
				return nil
			}
			return l
		}
	}
	if name == nil {
		a.diag("%s outside %s", errOp, errCtx)
	} else {
		a.diag("%s label %s not defined", errOp, name.Value)
	}
	return nil
}

func (a *stmtCompiler) compileBranchStmt(s *ast.BranchStmt) {
	var pc *uint

	switch s.Tok {
	case token.BREAK:
		l := a.findLexicalLabel(s.Label, func(l *label) bool { return l.breakPC != nil }, "break", "for loop, switch, or select")
		if l == nil {
			return
		}
		pc = l.breakPC

	case token.CONTINUE:
		l := a.findLexicalLabel(s.Label, func(l *label) bool { return l.continuePC != nil }, "continue", "for loop")
		if l == nil {
			return
		}
		pc = l.continuePC

	case token.GOTO:
		l, ok := a.labels[s.Label.Value]
		if !ok {
			pc := badPC
			l = &label{name: s.Label.Value, desc: "unresolved label", gotoPC: &pc, used: s.Pos()}
			a.labels[l.name] = l
		}

		pc = l.gotoPC
		a.flow.putGoto(s.Pos(), l.name, a.block)

	case token.FALLTHROUGH:
		a.diag("fallthrough outside switch")
		return

	default:
		log.Crash("Unexpected branch token %v", s.Tok)
	}

	a.flow.put1(false, pc)
	a.push(func(v *Thread) { v.pc = *pc })
}

func (a *stmtCompiler) compileBlockStmt(s *ast.BlockStmt) {
	bc := a.enterChild()
	bc.compileStmts(s)
	bc.exit()
}

func (a *stmtCompiler) compileIfStmt(s *ast.IfStmt) {
	// The scope of any variables declared by [the init] statement
	// extends to the end of the "if" statement and the variables
	// are initialized once before the statement is entered.
	//
	// XXX(Spec) What this really wants to say is that there's an
	// implicit scope wrapping every if, for, and switch
	// statement.  This is subtly different from what it actually
	// says when there's a non-block else clause, because that
	// else claus has to execute in a scope that is *not* the
	// surrounding scope.
	bc := a.enterChild()
	defer bc.exit()

	// Compile init statement, if any
	if s.Init != nil {
		bc.compileStmt(s.Init)
	}

	elsePC := badPC
	endPC := badPC

	// Compile condition, if any.  If there is no condition, we
	// fall through to the body.
	if s.Cond != nil {
		e := bc.compileExpr(bc.block, false, s.Cond)
		switch {
		case e == nil:
			// Error reported by compileExpr
		case !e.t.isBoolean():
			e.diag("'if' condition must be boolean\n\t%v", e.t)
		default:
			eval := e.asBool()
			a.flow.put1(true, &elsePC)
			a.push(func(t *Thread) {
				if !eval(t) {
					t.pc = elsePC
				}
			})
		}
	}

	// Compile body
	body := bc.enterChild()
	body.compileStmts(s.Body)
	body.exit()

	// Compile else
	if s.Else != nil {
		// Skip over else if we executed the body
		a.flow.put1(false, &endPC)
		a.push(func(v *Thread) { v.pc = endPC })
		elsePC = a.nextPC()
		bc.compileStmt(s.Else)
	} else {
		elsePC = a.nextPC()
	}
	endPC = a.nextPC()
}

func (a *stmtCompiler) compileSwitchStmt(s *ast.SwitchStmt) {
	// Create implicit scope around switch
	bc := a.enterChild()
	defer bc.exit()

	// Compile init statement, if any
	if s.Init != nil {
		bc.compileStmt(s.Init)
	}

	// Compile condition, if any, and extract its effects
	var cond *expr
	condbc := bc.enterChild()
	if s.Tag != nil {
		e := condbc.compileExpr(condbc.block, false, s.Tag)
		if e != nil {
			var effect func(*Thread)
			effect, cond = e.extractEffect(condbc.block, "switch")
			a.push(effect)
		}
	}

	// Count cases
	ncases := 0
	hasDefault := false
	for _, c := range s.Body.List {
		clause, ok := c.(*ast.CaseClause)
		if !ok {
			a.diagAt(clause, "switch statement must contain case clauses")
			continue
		}
		if clause.Values == nil {
			if hasDefault {
				a.diagAt(clause, "switch statement contains more than one default case")
			}
			hasDefault = true
		} else {
			ncases += len(clause.Values)
		}
	}

	// Compile case expressions
	cases := make([]func(*Thread) bool, ncases)
	i := 0
	for _, c := range s.Body.List {
		clause, ok := c.(*ast.CaseClause)
		if !ok {
			continue
		}
		for _, v := range clause.Values {
			e := condbc.compileExpr(condbc.block, false, v)
			switch {
			case e == nil:
				// Error reported by compileExpr
			case cond == nil && !e.t.isBoolean():
				a.diagAt(v, "'case' condition must be boolean")
			case cond == nil:
				cases[i] = e.asBool()
			case cond != nil:
				// Create comparison
				// TOOD(austin) This produces bad error messages
				compare := e.compileBinaryExpr(token.EQL, cond, e)
				if compare != nil {
					cases[i] = compare.asBool()
				}
			}
			i++
		}
	}

	// Emit condition
	casePCs := make([]*uint, ncases+1)
	endPC := badPC

	a.flow.put(false, false, casePCs)
	a.push(func(t *Thread) {
		for i, c := range cases {
			if c(t) {
				t.pc = *casePCs[i]
				return
			}
		}
		t.pc = *casePCs[ncases]
	})
	condbc.exit()

	// Compile cases
	i = 0
	for _, c := range s.Body.List {
		clause, ok := c.(*ast.CaseClause)
		if !ok {
			continue
		}

		// Save jump PC's
		pc := a.nextPC()
		if clause.Values != nil {
			for _ = range clause.Values {
				casePCs[i] = &pc
				i++
			}
		} else {
			// Default clause
			casePCs[ncases] = &pc
		}

		// Compile body
		fall := false
		for j, s := range clause.Body {
			if br, ok := s.(*ast.BranchStmt); ok && br.Tok == token.FALLTHROUGH {
				// println("Found fallthrough");
				// It may be used only as the final
				// non-empty statement in a case or
				// default clause in an expression
				// "switch" statement.
				for _, s2 := range clause.Body[j+1:] {
					// XXX(Spec) 6g also considers
					// empty blocks to be empty
					// statements.
					if _, ok := s2.(*ast.EmptyStmt); !ok {
						a.diagAt(s, "fallthrough statement must be final statement in case")
						break
					}
				}
				fall = true
			} else {
				bc.compileStmt(s)
			}
		}
		// Jump out of switch, unless there was a fallthrough
		if !fall {
			a.flow.put1(false, &endPC)
			a.push(func(v *Thread) { v.pc = endPC })
		}
	}

	// Get end PC
	endPC = a.nextPC()
	if !hasDefault {
		casePCs[ncases] = &endPC
	}
}

func (a *stmtCompiler) compileForStmt(s *ast.ForStmt) {
	// Wrap the entire for in a block.
	bc := a.enterChild()
	defer bc.exit()

	// Compile init statement, if any
	if s.Init != nil {
		bc.compileStmt(s.Init)
	}

	bodyPC := badPC
	postPC := badPC
	checkPC := badPC
	endPC := badPC

	// Jump to condition check.  We generate slightly less code by
	// placing the condition check after the body.
	a.flow.put1(false, &checkPC)
	a.push(func(v *Thread) { v.pc = checkPC })

	// Compile body
	bodyPC = a.nextPC()
	body := bc.enterChild()
	if a.stmtLabel != nil {
		body.label = a.stmtLabel
	} else {
		body.label = &label{resolved: s.Pos()}
	}
	body.label.desc = "for loop"
	body.label.breakPC = &endPC
	body.label.continuePC = &postPC
	body.compileStmts(s.Body)
	body.exit()

	// Compile post, if any
	postPC = a.nextPC()
	if s.Post != nil {
		// TODO(austin) Does the parser disallow short
		// declarations in s.Post?
		bc.compileStmt(s.Post)
	}

	// Compile condition check, if any
	checkPC = a.nextPC()
	if s.Cond == nil {
		// If the condition is absent, it is equivalent to true.
		a.flow.put1(false, &bodyPC)
		a.push(func(v *Thread) { v.pc = bodyPC })
	} else {
		e := bc.compileExpr(bc.block, false, s.Cond)
		switch {
		case e == nil:
			// Error reported by compileExpr
		case !e.t.isBoolean():
			a.diag("'for' condition must be boolean\n\t%v", e.t)
		default:
			eval := e.asBool()
			a.flow.put1(true, &bodyPC)
			a.push(func(t *Thread) {
				if eval(t) {
					t.pc = bodyPC
				}
			})
		}
	}

	endPC = a.nextPC()
}

/*
 * Block compiler
 */

func (a *blockCompiler) compileStmt(s ast.Stmt) {
	sc := &stmtCompiler{a, s.Pos(), nil}
	sc.compile(s)
}

func (a *blockCompiler) compileStmts(block *ast.BlockStmt) {
	for _, sub := range block.List {
		a.compileStmt(sub)
	}
}

func (a *blockCompiler) enterChild() *blockCompiler {
	block := a.block.enterChild()
	return &blockCompiler{
		funcCompiler: a.funcCompiler,
		block: block,
		parent: a,
	}
}

func (a *blockCompiler) exit() { a.block.exit() }

/*
 * Function compiler
 */

func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) (func(*Thread) Func) {
	// Create body scope
	//
	// The scope of a parameter or result is the body of the
	// corresponding function.
	bodyScope := b.ChildScope()
	defer bodyScope.exit()
	for i, t := range decl.Type.In {
		if decl.InNames[i] != nil {
			bodyScope.DefineVar(decl.InNames[i].Value, decl.InNames[i].Pos(), t)
		} else {
			bodyScope.DefineTemp(t)
		}
	}
	for i, t := range decl.Type.Out {
		if decl.OutNames[i] != nil {
			bodyScope.DefineVar(decl.OutNames[i].Value, decl.OutNames[i].Pos(), t)
		} else {
			bodyScope.DefineTemp(t)
		}
	}

	// Create block context
	cb := newCodeBuf()
	fc := &funcCompiler{
		compiler: a,
		fnType: decl.Type,
		outVarsNamed: len(decl.OutNames) > 0 && decl.OutNames[0] != nil,
		codeBuf: cb,
		flow: newFlowBuf(cb),
		labels: make(map[string]*label),
	}
	bc := &blockCompiler{
		funcCompiler: fc,
		block: bodyScope.block,
	}

	// Compile body
	nerr := a.numError()
	bc.compileStmts(body)
	fc.checkLabels()
	if nerr != a.numError() {
		return nil
	}

	// Check that the body returned if necessary.  We only check
	// this if there were no errors compiling the body.
	if len(decl.Type.Out) > 0 && fc.flow.reachesEnd(0) {
		// XXX(Spec) Not specified.
		a.diagAt(&body.Rbrace, "function ends without a return statement")
		return nil
	}

	code := fc.get()
	maxVars := bodyScope.maxVars
	return func(t *Thread) Func { return &evalFunc{t.f, maxVars, code} }
}

// Checks that labels were resolved and that all jumps obey scoping
// rules.  Reports an error and set fc.err if any check fails.
func (a *funcCompiler) checkLabels() {
	nerr := a.numError()
	for _, l := range a.labels {
		if !l.resolved.IsValid() {
			a.diagAt(&l.used, "label %s not defined", l.name)
		}
	}
	if nerr != a.numError() {
		// Don't check scopes if we have unresolved labels
		return
	}

	// Executing the "goto" statement must not cause any variables
	// to come into scope that were not already in scope at the
	// point of the goto.
	a.flow.gotosObeyScopes(a.compiler)
}
