// 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 (
	"go/token"
	"log"
)

/*
 * Blocks and scopes
 */

// A definition can be a *Variable, *Constant, or Type.
type Def interface {
	Pos() token.Position
}

type Variable struct {
	token.Position
	// Index of this variable in the Frame structure
	Index int
	// Static type of this variable
	Type Type
	// Value of this variable.  This is only used by Scope.NewFrame;
	// therefore, it is useful for global scopes but cannot be used
	// in function scopes.
	Init Value
}

type Constant struct {
	token.Position
	Type  Type
	Value Value
}

// A block represents a definition block in which a name may not be
// defined more than once.
type block struct {
	// The block enclosing this one, including blocks in other
	// scopes.
	outer *block
	// The nested block currently being compiled, or nil.
	inner *block
	// The Scope containing this block.
	scope *Scope
	// The Variables, Constants, and Types defined in this block.
	defs map[string]Def
	// The index of the first variable defined in this block.
	// This must be greater than the index of any variable defined
	// in any parent of this block within the same Scope at the
	// time this block is entered.
	offset int
	// The number of Variables defined in this block.
	numVars int
	// If global, do not allocate new vars and consts in
	// the frame; assume that the refs will be compiled in
	// using defs[name].Init.
	global bool
}

// A Scope is the compile-time analogue of a Frame, which captures
// some subtree of blocks.
type Scope struct {
	// The root block of this scope.
	*block
	// The maximum number of variables required at any point in
	// this Scope.  This determines the number of slots needed in
	// Frame's created from this Scope at run-time.
	maxVars int
}

func (b *block) enterChild() *block {
	if b.inner != nil && b.inner.scope == b.scope {
		log.Crash("Failed to exit child block before entering another child")
	}
	sub := &block{
		outer: b,
		scope: b.scope,
		defs: make(map[string]Def),
		offset: b.offset + b.numVars,
	}
	b.inner = sub
	return sub
}

func (b *block) exit() {
	if b.outer == nil {
		log.Crash("Cannot exit top-level block")
	}
	if b.outer.scope == b.scope {
		if b.outer.inner != b {
			log.Crash("Already exited block")
		}
		if b.inner != nil && b.inner.scope == b.scope {
			log.Crash("Exit of parent block without exit of child block")
		}
	}
	b.outer.inner = nil
}

func (b *block) ChildScope() *Scope {
	if b.inner != nil && b.inner.scope == b.scope {
		log.Crash("Failed to exit child block before entering a child scope")
	}
	sub := b.enterChild()
	sub.offset = 0
	sub.scope = &Scope{sub, 0}
	return sub.scope
}

func (b *block) DefineVar(name string, pos token.Position, t Type) (*Variable, Def) {
	if prev, ok := b.defs[name]; ok {
		return nil, prev
	}
	v := b.defineSlot(t, false)
	v.Position = pos
	b.defs[name] = v
	return v, nil
}

func (b *block) DefineTemp(t Type) *Variable { return b.defineSlot(t, true) }

func (b *block) defineSlot(t Type, temp bool) *Variable {
	if b.inner != nil && b.inner.scope == b.scope {
		log.Crash("Failed to exit child block before defining variable")
	}
	index := -1
	if !b.global || temp {
		index = b.offset + b.numVars
		b.numVars++
		if index >= b.scope.maxVars {
			b.scope.maxVars = index + 1
		}
	}
	v := &Variable{token.Position{}, index, t, nil}
	return v
}

func (b *block) DefineConst(name string, pos token.Position, t Type, v Value) (*Constant, Def) {
	if prev, ok := b.defs[name]; ok {
		return nil, prev
	}
	c := &Constant{pos, t, v}
	b.defs[name] = c
	return c, nil
}

func (b *block) DefineType(name string, pos token.Position, t Type) Type {
	if _, ok := b.defs[name]; ok {
		return nil
	}
	nt := &NamedType{pos, name, nil, true, make(map[string]Method)}
	if t != nil {
		nt.Complete(t)
	}
	b.defs[name] = nt
	return nt
}

func (b *block) Lookup(name string) (bl *block, level int, def Def) {
	for b != nil {
		if d, ok := b.defs[name]; ok {
			return b, level, d
		}
		if b.outer != nil && b.scope != b.outer.scope {
			level++
		}
		b = b.outer
	}
	return nil, 0, nil
}

func (s *Scope) NewFrame(outer *Frame) *Frame { return outer.child(s.maxVars) }

/*
 * Frames
 */

type Frame struct {
	Outer *Frame
	Vars  []Value
}

func (f *Frame) Get(level int, index int) Value {
	for ; level > 0; level-- {
		f = f.Outer
	}
	return f.Vars[index]
}

func (f *Frame) child(numVars int) *Frame {
	// TODO(austin) This is probably rather expensive.  All values
	// require heap allocation and zeroing them when we execute a
	// definition typically requires some computation.
	return &Frame{f, make([]Value, numVars)}
}
