func (a address) assign(k bool, value int8, valueType reflect.Type) {
	switch a.target {
	case assignNonLocalVar:
		a.em.fb.emitSetVar(k, value, int(decodeInt16(a.op1, a.op2)), a.addressedType.Kind())
	case assignBlank:
	case assignLocalVar:
		a.em.changeRegister(k, value, a.op1, a.targetType(), a.addressedType)
	case assignNewIndirectVar:
		a.em.fb.emitNew(a.addressedType, -a.op1)
		a.em.changeRegister(k, value, a.op1, a.targetType(), a.addressedType)
	case assignPtrIndirection:
		a.em.changeRegister(k, value, -a.op1, a.targetType(), a.addressedType)
	case assignLocalSliceIndex:
		a.em.fb.emitSetSlice(k, a.op1, value, a.op2, a.pos, valueType.Kind())
	case assignNonLocalSliceIndex:
		a.em.fb.emitSetSlice(k, a.op1, value, a.op2, a.pos, valueType.Kind())
		a.em.fb.emitSetVar(false, a.op1, a.nonLocal, a.addressedType.Kind())
	case assignLocalMapIndex:
		a.em.fb.emitSetMap(k, a.op1, value, a.op2, a.addressedType, a.pos)
	case assignNonLocalMapIndex:
		a.em.fb.emitSetMap(k, a.op1, value, a.op2, a.addressedType, a.pos)
		a.em.fb.emitSetVar(false, a.op1, a.nonLocal, a.addressedType.Kind())
	case assignLocalStructSelector:
		a.em.fb.emitSetField(k, a.op1, a.op2, value, valueType.Kind())
	case assignNonLocalStructSelector:
		a.em.fb.emitSetField(k, a.op1, a.op2, value, valueType.Kind())
		a.em.fb.emitSetVar(false, a.op1, a.nonLocal, a.addressedType.Kind())
	}
}
assign assigns value, with type valueType, to the address. If k is true
value is a constant otherwise is a register.
package compiler
import (
	"reflect"
	"github.com/open2b/scriggo/ast"
	"github.com/open2b/scriggo/internal/runtime"
)
type address struct {
	em            *emitter            
	target        assignmentTarget    
	addressedType reflect.Type        
	op1, op2      int8                
	pos           *ast.Position       
	operator      ast.AssignmentType  
	nonLocal      int                 
}
type assignmentTarget int16
const (
	assignBlank          assignmentTarget = iota  
	assignNewIndirectVar                          
	assignPtrIndirection                          
	assignLocalVar     
	assignNonLocalVar  
	assignLocalMapIndex     
	assignNonLocalMapIndex  
	assignLocalSliceIndex     
	assignNonLocalSliceIndex  
	assignLocalStructSelector     
	assignNonLocalStructSelector  
)
func (em *emitter) addressBlankIdent(pos *ast.Position) address {
	return address{
		em:     em,
		pos:    pos,
		target: assignBlank,
	}
}
func (em *emitter) addressLocalVar(reg int8, typ reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: typ,
		em:            em,
		op1:           reg,
		operator:      op,
		pos:           pos,
		target:        assignLocalVar,
	}
}
func (em *emitter) addressLocalMapIndex(mapReg int8, keyReg int8, mapType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: mapType,
		em:            em,
		op1:           mapReg,
		op2:           keyReg,
		operator:      op,
		pos:           pos,
		target:        assignLocalMapIndex,
	}
}
func (em *emitter) addressNonLocalMapIndex(nonLocalMap int, mapReg int8, keyReg int8, mapType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: mapType,
		em:            em,
		op1:           mapReg,
		op2:           keyReg,
		operator:      op,
		pos:           pos,
		target:        assignNonLocalMapIndex,
		nonLocal:      nonLocalMap,
	}
}
func (em *emitter) addressNewIndirectVar(reg int8, typ reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: typ,
		em:            em,
		op1:           reg,
		operator:      op,
		pos:           pos,
		target:        assignNewIndirectVar,
	}
}
func (em *emitter) addressNonLocalVar(index int16, typ reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	msb, lsb := encodeInt16(index)
	return address{
		addressedType: typ,
		em:            em,
		op1:           msb,
		op2:           lsb,
		operator:      op,
		pos:           pos,
		target:        assignNonLocalVar,
	}
}
func (em *emitter) addressPtrIndirect(reg int8, pointedType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: pointedType,
		em:            em,
		op1:           reg,
		operator:      op,
		pos:           pos,
		target:        assignPtrIndirection,
	}
}
func (em *emitter) addressSliceIndex(sliceReg int8, indexReg int8, sliceType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: sliceType,
		em:            em,
		op1:           sliceReg,
		op2:           indexReg,
		operator:      op,
		pos:           pos,
		target:        assignLocalSliceIndex,
	}
}
func (em *emitter) addressGlobalSliceIndex(sliceIndex int, sliceReg int8, indexReg int8, sliceType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: sliceType,
		em:            em,
		op1:           sliceReg,
		op2:           indexReg,
		operator:      op,
		pos:           pos,
		target:        assignNonLocalSliceIndex,
		nonLocal:      sliceIndex,
	}
}
func (em *emitter) addressLocalStructSelector(structReg int8, kFieldIndex int8, structType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: structType,
		em:            em,
		op1:           structReg,
		op2:           kFieldIndex,
		operator:      op,
		pos:           pos,
		target:        assignLocalStructSelector,
	}
}
func (em *emitter) addressNonLocalStructSelector(structIndex int, localStructReg int8, kFieldIndex int8, structType reflect.Type, pos *ast.Position, op ast.AssignmentType) address {
	return address{
		addressedType: structType,
		em:            em,
		op1:           localStructReg,
		op2:           kFieldIndex,
		operator:      op,
		pos:           pos,
		target:        assignNonLocalStructSelector,
		nonLocal:      structIndex,
	}
}