func (fs *functionStore) predefFunc(fn ast.Expression, allowMethod bool) (int8, bool) {
	ti := fs.emitter.ti(fn)
	if (ti == nil) || (!ti.IsNative()) {
		return 0, false
	}
	if !allowMethod && ti.MethodType != noMethod {
		return 0, false
	}
	if ti.Type.Kind() != reflect.Func {
		return 0, false
	}
	if ti.Addressable() {
		return 0, false
	}
	var name string
	switch fn := fn.(type) {
	case *ast.Identifier:
		name = fn.Name
	case *ast.Selector:
		switch fn.Expr.(type) {
		case *ast.Identifier:
			name = fn.Ident
		}
	default:
	}
	fnRv := ti.value.(reflect.Value)
	currFn := fs.emitter.fb.fn
	if fs.predefFuncIndexes[currFn] == nil {
		fs.predefFuncIndexes[currFn] = map[reflect.Value]int8{}
	}
	if index, ok := fs.predefFuncIndexes[currFn][fnRv]; ok {
		return index, true
	}
	f := newNativeFunction(ti.NativePackageName, name, fnRv.Interface())
	index := int8(len(currFn.NativeFunctions))
	currFn.NativeFunctions = append(currFn.NativeFunctions, f)
	if fs.predefFuncIndexes[currFn] == nil {
		fs.predefFuncIndexes[currFn] = map[reflect.Value]int8{}
	}
	fs.predefFuncIndexes[currFn][fnRv] = index
	return index, true
}
predefFunc returns the index of the predefined function 'contained' in fn if
there's one, else returns 0 and false.
package compiler
import (
	"reflect"
	"github.com/open2b/scriggo/ast"
	"github.com/open2b/scriggo/internal/runtime"
)
type functionStore struct {
	emitter *emitter
	availableScriggoFuncs map[*ast.Package]map[string]*runtime.Function
	scriggoFuncIndexes map[*runtime.Function]map[*runtime.Function]int8
	predefFuncIndexes map[*runtime.Function]map[reflect.Value]int8
}
func newFunctionStore(emitter *emitter) *functionStore {
	return &functionStore{
		emitter:               emitter,
		availableScriggoFuncs: map[*ast.Package]map[string]*runtime.Function{},
		scriggoFuncIndexes:    map[*runtime.Function]map[*runtime.Function]int8{},
		predefFuncIndexes:     map[*runtime.Function]map[reflect.Value]int8{},
	}
}
func (fs *functionStore) makeAvailableScriggoFn(pkg *ast.Package, name string, fn *runtime.Function) {
	if fs.availableScriggoFuncs[pkg] == nil {
		fs.availableScriggoFuncs[pkg] = map[string]*runtime.Function{}
	}
	fs.availableScriggoFuncs[pkg][name] = fn
}
func (fs *functionStore) availableScriggoFn(pkg *ast.Package, name string) (*runtime.Function, bool) {
	fn, ok := fs.availableScriggoFuncs[pkg][name]
	return fn, ok
}
func (fs *functionStore) scriggoFnIndex(fn *runtime.Function) int8 {
	currFn := fs.emitter.fb.fn
	if fs.scriggoFuncIndexes[currFn] == nil {
		fs.scriggoFuncIndexes[currFn] = map[*runtime.Function]int8{}
	}
	if index, ok := fs.scriggoFuncIndexes[currFn][fn]; ok {
		return index
	}
	index := int8(len(currFn.Functions))
	currFn.Functions = append(currFn.Functions, fn)
	fs.scriggoFuncIndexes[currFn][fn] = index
	return index
}