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: callnret0.go
    path of file: ./repos/gomacro/fast
    
    the code of the file until where you have to start completion: // -------------------------------------------------------------
// DO NOT EDIT! this file was generated automatically by gomacro
// Any change will be lost when the file is re-generated
// ----------------------------------------
    
func (c *Comp) call0ret0(call *Call, maxdepth int) func(env *Env) {
	expr := call.Fun
	funsym := expr.Sym
	if funsym == nil {
		exprfun := expr.AsX1()
		return func(env *Env) {
			fun := exprfun(env).Interface().(func())
			fun()
		}
	}

	var cachedfunv xr.Value
	var cachedfun func()

	funupn := funsym.Upn
	funindex := funsym.Desc.Index()
	switch funupn {
	case maxdepth - 1:
		return func(env *Env) {
			funv := env.FileEnv.Vals[funindex]
			if cachedfunv != funv {
				cachedfunv = funv
				cachedfun = funv.Interface().(func())
			}
			cachedfun()
		}
	case 0:
		return func(env *Env) {
			fun := env.Vals[funindex].Interface().(func())
			fun()
		}
	case 1:
		return func(env *Env) {
			fun := env.Outer.Vals[funindex].Interface().(func())
			fun()
		}
	case 2:
		return func(env *Env) {
			fun := env.Outer.Outer.Vals[funindex].Interface().(func())
			fun()
		}
	default:
		return func(env *Env) {
			env = env.Outer.Outer.Outer.Outer
			for i := 3; i < funupn; i++ {
				env = env.Outer
			}

			fun := env.Vals[funindex].Interface().(func())
			fun()
		}
	}
}