You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: switch_type.go
    path of file: ./repos/gomacro/fast
    
    the code of the file until where you have to start completion: /*
 * gomacro - A Go interpreter with Lisp-like macros
 *
 * Copyright (C) 2017-2019 Massimiliano Ghilardi
 *
 *     This Source Code Form is subject to the terms of the Mozilla Public
 *     License, v. 2.0. If a copy of the MPL was not distributed with this
 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *
 * switch_type.go
 *
 *  Created on May 06, 2017
 *      Author Massimiliano Ghilardi
 */

package fast

import (
	"go/ast"
	"go/token"
	r "reflect"
	"sort"
	"unsafe"

	"github.com/cosmos72/gomacro/go/types"
	"github.com/cosmos72/gomacro/go/typeutil"
	xr "github.com/cosmos72/gomacro/xreflect"
)

type typecaseEntry struct {
	Type xr.Type
	Pos  token.Pos
	IP   int
}

type typecaseHelper struct {
	TypeMap     typeutil.Map // map types.Type -> typecaseEntry
	ConcreteMap typeutil.Map // only contains the initial segment of non-interface types
	AllConcrete bool
}

// keep track of types in type-switch. error on duplicates
func (seen *typecaseHelper) add(c *Comp, t xr.Type, entry typecaseEntry) {
	var gtype types.Type
	if t != nil {
		gtype = t.GoType()
	}
	prev := seen.TypeMap.At(gtype)
	if prev != nil {
		c.Errorf("duplicate case <%v> in switch\n\tprevio
    
func (c *Comp) typeswitchVar(varname string, t xr.Type, sym *Symbol) {
	sidx := sym.Bind.Desc.Index()

	bind := c.NewBind(varname, VarBind, t)
	idx := bind.Desc.Index()

	if sym.Upn != 1 {
		c.Errorf("typeswitchVar: impossible sym.Upn = %v", sym.Upn)
	}
	var stmt Stmt
	switch t.Kind() {
	case xr.Bool:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*bool)(unsafe.Pointer(&env.Ints[idx])) = env.Outer.Vals[sidx].Bool()
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Int:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*int)(unsafe.Pointer(&env.Ints[idx])) = int(env.Outer.Vals[sidx].Int())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Int8:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*int8)(unsafe.Pointer(&env.Ints[idx])) = int8(env.Outer.Vals[sidx].Int())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Int16:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*int16)(unsafe.Pointer(&env.Ints[idx])) = int16(env.Outer.Vals[sidx].Int())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Int32:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*int32)(unsafe.Pointer(&env.Ints[idx])) = int32(env.Outer.Vals[sidx].Int())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Int64:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*int64)(unsafe.Pointer(&env.Ints[idx])) = int64(env.Outer.Vals[sidx].Int())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uint:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*uint)(unsafe.Pointer(&env.Ints[idx])) = uint(env.Outer.Vals[sidx].Uint())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uint8:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*uint8)(unsafe.Pointer(&env.Ints[idx])) = uint8(env.Outer.Vals[sidx].Uint())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uint16:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*uint16)(unsafe.Pointer(&env.Ints[idx])) = uint16(env.Outer.Vals[sidx].Uint())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uint32:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*uint32)(unsafe.Pointer(&env.Ints[idx])) = uint32(env.Outer.Vals[sidx].Uint())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uint64:
		stmt = func(env *Env) (Stmt, *Env) {
			env.Ints[idx] = env.Outer.Vals[sidx].Uint()
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Uintptr:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*uintptr)(unsafe.Pointer(&env.Ints[idx])) = uintptr(env.Outer.Vals[sidx].Uint())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Float32:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*float32)(unsafe.Pointer(&env.Ints[idx])) = float32(env.Outer.Vals[sidx].Float())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Float64:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*float64)(unsafe.Pointer(&env.Ints[idx])) = env.Outer.Vals[sidx].Float()
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Complex64:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*complex64)(unsafe.Pointer(&env.Ints[idx])) = complex64(env.Outer.Vals[sidx].Complex())
			env.IP++
			return env.Code[env.IP], env
		}
	case xr.Complex128:
		stmt = func(env *Env) (Stmt, *Env) {
			*(*complex128)(unsafe.Pointer(&env.Ints[idx])) = env.Outer.Vals[sidx].Complex()
			env.IP++
			return env.Code[env.IP], env
		}
	default:
		rtype := t.ReflectType()
		zero := xr.ZeroR(rtype)
		stmt = func(env *Env) (Stmt, *Env) {
			v := env.Outer.Vals[sidx]
			place := xr.New(t).Elem()
			if !v.IsValid() {
				v = zero
			} else if v.Type() != rtype {
				v = convert(v, rtype)
			}
			place.Set(v)
			env.Vals[idx] = place
			env.IP++
			return env.Code[env.IP], env
		}
	}
	c.append(stmt)
}