// Copyright 2013 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 ssa

// lvalues are the union of addressable expressions and map-index
// expressions.

import (
	"go/ast"
	"go/token"
	"go/types"
)

// An lvalue represents an assignable location that may appear on the
// left-hand side of an assignment.  This is a generalization of a
// pointer to permit updates to elements of maps.
type lvalue interface {
	store(fn *Function, v Value) // stores v into the location
	load(fn *Function) Value     // loads the contents of the location
	address(fn *Function) Value  // address of the location
	typ() types.Type             // returns the type of the location
}

// An address is an lvalue represented by a true pointer.
type address struct {
	addr Value
	pos  token.Pos // source position
	expr ast.Expr  // source syntax of the value (not address) [debug mode]
}

func (a *address) load(fn *Function) Value {
	load := emitLoad(fn, a.addr)
	load.pos = a.pos
	return load
}

func (a *address) store(fn *Function, v Value) {
	store := emitStore(fn, a.addr, v, a.pos)
	if a.expr != nil {
		// store.Val is v, converted for assignability.
		emitDebugRef(fn, a.expr, store.Val, false)
	}
}

func (a *address) address(fn *Function) Value {
	if a.expr != nil {
		emitDebugRef(fn, a.expr, a.addr, true)
	}
	return a.addr
}

func (a *address) typ() types.Type {
	return deref(a.addr.Type())
}

// An element is an lvalue represented by m[k], the location of an
// element of a map.  These locations are not addressable
// since pointers cannot be formed from them, but they do support
// load() and store().
type element struct {
	m, k Value      // map
	t    types.Type // map element type
	pos  token.Pos  // source position of colon ({k:v}) or lbrack (m[k]=v)
}

func (e *element) load(fn *Function) Value {
	l := &Lookup{
		X:     e.m,
		Index: e.k,
	}
	l.setPos(e.pos)
	l.setType(e.t)
	return fn.emit(l)
}

func (e *element) store(fn *Function, v Value) {
	up := &MapUpdate{
		Map:   e.m,
		Key:   e.k,
		Value: emitConv(fn, v, e.t),
	}
	up.pos = e.pos
	fn.emit(up)
}

func (e *element) address(fn *Function) Value {
	panic("map elements are not addressable")
}

func (e *element) typ() types.Type {
	return e.t
}

// A lazyAddress is an lvalue whose address is the result of an instruction.
// These work like an *address except a new address.address() Value
// is created on each load, store and address call.
// A lazyAddress can be used to control when a side effect (nil pointer
// dereference, index out of bounds) of using a location happens.
type lazyAddress struct {
	addr func(fn *Function) Value // emit to fn the computation of the address
	t    types.Type               // type of the location
	pos  token.Pos                // source position
	expr ast.Expr                 // source syntax of the value (not address) [debug mode]
}

func (l *lazyAddress) load(fn *Function) Value {
	load := emitLoad(fn, l.addr(fn))
	load.pos = l.pos
	return load
}

func (l *lazyAddress) store(fn *Function, v Value) {
	store := emitStore(fn, l.addr(fn), v, l.pos)
	if l.expr != nil {
		// store.Val is v, converted for assignability.
		emitDebugRef(fn, l.expr, store.Val, false)
	}
}

func (l *lazyAddress) address(fn *Function) Value {
	addr := l.addr(fn)
	if l.expr != nil {
		emitDebugRef(fn, l.expr, addr, true)
	}
	return addr
}

func (l *lazyAddress) typ() types.Type { return l.t }

// A blank is a dummy variable whose name is "_".
// It is not reified: loads are illegal and stores are ignored.
type blank struct{}

func (bl blank) load(fn *Function) Value {
	panic("blank.load is illegal")
}

func (bl blank) store(fn *Function, v Value) {
	// no-op
}

func (bl blank) address(fn *Function) Value {
	panic("blank var is not addressable")
}

func (bl blank) typ() types.Type {
	// This should be the type of the blank Ident; the typechecker
	// doesn't provide this yet, but fortunately, we don't need it
	// yet either.
	panic("blank.typ is unimplemented")
}
