/*
 * Function compiler
 */
973164
func (a *compiler) compileFunc(b *block, decl *FuncDecl, body *ast.BlockStmt) func(*Thread) Func {
	// Create body scope
	//
	// The scope of a parameter or result is the body of the
	// corresponding function.
	bodyScope := b.ChildScope()
	defer bodyScope.exit()
	for i, t := range decl.Type.In {
		if decl.InNames[i] != nil {
			bodyScope.DefineVar(decl.InNames[i].Name, decl.InNames[i].Pos(), t)
		} else {
			bodyScope.DefineTemp(t)
		}
	}
	for i, t := range decl.Type.Out {
		if decl.OutNames[i] != nil {
			bodyScope.DefineVar(decl.OutNames[i].Name, decl.OutNames[i].Pos(), t)
		} else {
			bodyScope.DefineTemp(t)
		}
	}

	// Create block context
	cb := newCodeBuf()
	fc := &funcCompiler{
		compiler:     a,
		fnType:       decl.Type,
		outVarsNamed: len(decl.OutNames) > 0 && decl.OutNames[0] != nil,
		codeBuf:      cb,
		flow:         newFlowBuf(cb),
		labels:       make(map[string]*label),
	}
	bc := &blockCompiler{
		funcCompiler: fc,
		block:        bodyScope.block,
	}

	// Compile body
	nerr := a.numError()
	bc.compileStmts(body)
	fc.checkLabels()
	if nerr != a.numError() {
		return nil
	}

	// Check that the body returned if necessary.  We only check
	// this if there were no errors compiling the body.
	if len(decl.Type.Out) > 0 && fc.flow.reachesEnd(0) {
		// XXX(Spec) Not specified.
		a.diagAt(body.Rbrace, "function ends without a return statement")
		return nil
	}

	code := fc.get()
	maxVars := bodyScope.maxVars
	return func(t *Thread) Func { return &evalFunc{t.f, maxVars, code} }
}
101438
func GetFunction(function interface{}) *runtime.Func {
	return runtime.FuncForPC(reflect.ValueOf(function).Pointer())
}
1164246
func init() {
	flag.BoolVar(&resolve.AllowFloat, "fp", resolve.AllowFloat, "allow floating-point numbers")
	flag.BoolVar(&resolve.AllowSet, "set", resolve.AllowSet, "allow set data type")
	flag.BoolVar(&resolve.AllowLambda, "lambda", resolve.AllowLambda, "allow lambda expressions")
	flag.BoolVar(&resolve.AllowNestedDef, "nesteddef", resolve.AllowNestedDef, "allow nested def statements")
	flag.BoolVar(&resolve.AllowBitwise, "bitwise", resolve.AllowBitwise, "allow bitwise operations (&, |, ^, ~, <<, and >>)")
}
391630
func interpolationFuncCeil() ast.Function {
	return ast.Function{
		ArgTypes:   []ast.Type{ast.TypeFloat},
		ReturnType: ast.TypeInt,
		Callback: func(args []interface{}) (interface{}, error) {
			return int(math.Ceil(args[0].(float64))), nil
		},
	}
}
627428
func TemplateFunc(name string, f interface{}) TemplateOption {
	return func(g Generator, t *template.Template) *template.Template {
		return t.Funcs(template.FuncMap{name: curryGenerator(f, g)})
	}
}
75822
func newFunctionProto(name string) *FunctionProto {
	return &FunctionProto{
		SourceName:         name,
		LineDefined:        0,
		LastLineDefined:    0,
		NumUpvalues:        0,
		NumParameters:      0,
		IsVarArg:           0,
		NumUsedRegisters:   2,
		Code:               make([]uint32, 0, 128),
		Constants:          make([]LValue, 0, 32),
		FunctionPrototypes: make([]*FunctionProto, 0, 16),

		DbgSourcePositions: make([]int, 0, 128),
		DbgLocals:          make([]*DbgLocalInfo, 0, 16),
		DbgCalls:           make([]DbgCall, 0, 128),
		DbgUpvalues:        make([]string, 0, 16),

		stringConstants: make([]string, 0, 32),
	}
}
494387
func RegisterFunctionalBuiltin4(name string, fun FunctionalBuiltin4) {
	builtinFunctions[name] = functionalWrapper4(name, fun)
}
1371483
func (f *functionQuery) Evaluate(t iterator) interface{} {
	return f.Func(f.Input, t)
}
50921
func interpolationFuncSlice() ast.Function {
	return ast.Function{
		ArgTypes: []ast.Type{
			ast.TypeList, // inputList
			ast.TypeInt,  // from
			ast.TypeInt,  // to
		},
		ReturnType: ast.TypeList,
		Variadic:   false,
		Callback: func(args []interface{}) (interface{}, error) {
			inputList := args[0].([]ast.Variable)
			from := args[1].(int)
			to := args[2].(int)

			if from < 0 {
				return nil, fmt.Errorf("from index must be >= 0")
			}
			if to > len(inputList) {
				return nil, fmt.Errorf("to index must be <= length of the input list")
			}
			if from > to {
				return nil, fmt.Errorf("from index must be <= to index")
			}

			var outputList []ast.Variable
			for i, val := range inputList {
				if i >= from && i < to {
					outputList = append(outputList, val)
				}
			}
			return outputList, nil
		},
	}
}
828181
func MakeFunc(fn func(this *Object, arguments []*Object) interface{}) *Object {
	return Global.Call("$makeFunc", InternalObject(fn))
}
1259234
func findFunction(name string) (reflect.Value, bool) {
	if fn := builtinFuncs[name]; fn.IsValid() {
		return fn, true
	}
	return reflect.Value{}, false
}
965555
func NewFnType(ts ...Type) *FunctionType {
	if len(ts) < 2 {
		panic("Expected at least 2 input types")
	}

	retVal := borrowFnType()
	retVal.a = ts[0]

	if len(ts) > 2 {
		retVal.b = NewFnType(ts[1:]...)
	} else {
		retVal.b = ts[1]
	}
	return retVal
}
771035
func ConvertFunction(fn *proc.Function) *Function {
	if fn == nil {
		return nil
	}

	// fn here used to be a *gosym.Func, the fields Type and GoType below
	// corresponded to the homonymous field of gosym.Func. Since the contents of
	// those fields is not documented their value was replaced with 0 when
	// gosym.Func was replaced by debug_info entries.
	return &Function{
		Name_:     fn.Name,
		Type:      0,
		Value:     fn.Entry,
		GoType:    0,
		Optimized: fn.Optimized(),
	}
}
55732
func (fn ScriptFunction) Source() interface{} {
	source := make(map[string]interface{})
	if fn.script != "" {
		source["script"] = fn.script
	}
	if fn.lang != "" {
		source["lang"] = fn.lang
	}
	if len(fn.params) > 0 {
		source["params"] = fn.params
	}
	// Notice that the weight has to be serialized in FunctionScoreQuery.
	return source
}
490028
func (s *Scope) Functions() map[string]function.Function {
	s.funcsLock.Lock()
	if s.funcs == nil {
		// Some of our functions are just directly the cty stdlib functions.
		// Others are implemented in the subdirectory "funcs" here in this
		// repository. New functions should generally start out their lives
		// in the "funcs" directory and potentially graduate to cty stdlib
		// later if the functionality seems to be something domain-agnostic
		// that would be useful to all applications using cty functions.

		s.funcs = map[string]function.Function{
			"abs":              stdlib.AbsoluteFunc,
			"basename":         funcs.BasenameFunc,
			"base64decode":     funcs.Base64DecodeFunc,
			"base64encode":     funcs.Base64EncodeFunc,
			"base64gzip":       funcs.Base64GzipFunc,
			"base64sha256":     funcs.Base64Sha256Func,
			"base64sha512":     funcs.Base64Sha512Func,
			"bcrypt":           funcs.BcryptFunc,
			"ceil":             funcs.CeilFunc,
			"chomp":            funcs.ChompFunc,
			"cidrhost":         funcs.CidrHostFunc,
			"cidrnetmask":      funcs.CidrNetmaskFunc,
			"cidrsubnet":       funcs.CidrSubnetFunc,
			"coalesce":         funcs.CoalesceFunc,
			"coalescelist":     funcs.CoalesceListFunc,
			"compact":          funcs.CompactFunc,
			"concat":           stdlib.ConcatFunc,
			"contains":         funcs.ContainsFunc,
			"csvdecode":        stdlib.CSVDecodeFunc,
			"dirname":          funcs.DirnameFunc,
			"distinct":         funcs.DistinctFunc,
			"element":          funcs.ElementFunc,
			"chunklist":        funcs.ChunklistFunc,
			"file":             funcs.MakeFileFunc(s.BaseDir, false),
			"fileexists":       funcs.MakeFileExistsFunc(s.BaseDir),
			"filebase64":       funcs.MakeFileFunc(s.BaseDir, true),
			"filebase64sha256": funcs.MakeFileBase64Sha256Func(s.BaseDir),
			"filebase64sha512": funcs.MakeFileBase64Sha512Func(s.BaseDir),
			"filemd5":          funcs.MakeFileMd5Func(s.BaseDir),
			"filesha1":         funcs.MakeFileSha1Func(s.BaseDir),
			"filesha256":       funcs.MakeFileSha256Func(s.BaseDir),
			"filesha512":       funcs.MakeFileSha512Func(s.BaseDir),
			"flatten":          funcs.FlattenFunc,
			"floor":            funcs.FloorFunc,
			"format":           stdlib.FormatFunc,
			"formatdate":       stdlib.FormatDateFunc,
			"formatlist":       stdlib.FormatListFunc,
			"indent":           funcs.IndentFunc,
			"index":            funcs.IndexFunc,
			"join":             funcs.JoinFunc,
			"jsondecode":       stdlib.JSONDecodeFunc,
			"jsonencode":       stdlib.JSONEncodeFunc,
			"keys":             funcs.KeysFunc,
			"length":           funcs.LengthFunc,
			"list":             funcs.ListFunc,
			"log":              funcs.LogFunc,
			"lookup":           funcs.LookupFunc,
			"lower":            stdlib.LowerFunc,
			"map":              funcs.MapFunc,
			"matchkeys":        funcs.MatchkeysFunc,
			"max":              stdlib.MaxFunc,
			"md5":              funcs.Md5Func,
			"merge":            funcs.MergeFunc,
			"min":              stdlib.MinFunc,
			"pathexpand":       funcs.PathExpandFunc,
			"pow":              funcs.PowFunc,
			"replace":          funcs.ReplaceFunc,
			"reverse":          funcs.ReverseFunc,
			"rsadecrypt":       funcs.RsaDecryptFunc,
			"setintersection":  stdlib.SetIntersectionFunc,
			"setproduct":       funcs.SetProductFunc,
			"setunion":         stdlib.SetUnionFunc,
			"sha1":             funcs.Sha1Func,
			"sha256":           funcs.Sha256Func,
			"sha512":           funcs.Sha512Func,
			"signum":           funcs.SignumFunc,
			"slice":            funcs.SliceFunc,
			"sort":             funcs.SortFunc,
			"split":            funcs.SplitFunc,
			"strrev":           stdlib.ReverseFunc,
			"substr":           stdlib.SubstrFunc,
			"timestamp":        funcs.TimestampFunc,
			"timeadd":          funcs.TimeAddFunc,
			"title":            funcs.TitleFunc,
			"tostring":         funcs.MakeToFunc(cty.String),
			"tonumber":         funcs.MakeToFunc(cty.Number),
			"tobool":           funcs.MakeToFunc(cty.Bool),
			"toset":            funcs.MakeToFunc(cty.Set(cty.DynamicPseudoType)),
			"tolist":           funcs.MakeToFunc(cty.List(cty.DynamicPseudoType)),
			"tomap":            funcs.MakeToFunc(cty.Map(cty.DynamicPseudoType)),
			"transpose":        funcs.TransposeFunc,
			"trimspace":        funcs.TrimSpaceFunc,
			"upper":            stdlib.UpperFunc,
			"urlencode":        funcs.URLEncodeFunc,
			"uuid":             funcs.UUIDFunc,
			"values":           funcs.ValuesFunc,
			"zipmap":           funcs.ZipmapFunc,
		}

		s.funcs["templatefile"] = funcs.MakeTemplateFileFunc(s.BaseDir, func() map[string]function.Function {
			// The templatefile function prevents recursive calls to itself
			// by copying this map and overwriting the "templatefile" entry.
			return s.funcs
		})

		if s.PureOnly {
			// Force our few impure functions to return unknown so that we
			// can defer evaluating them until a later pass.
			for _, name := range impureFunctions {
				s.funcs[name] = function.Unpredictable(s.funcs[name])
			}
		}
	}
	s.funcsLock.Unlock()

	return s.funcs
}
504082
func interpolationFuncMin() ast.Function {
	return ast.Function{
		ArgTypes:     []ast.Type{ast.TypeFloat},
		ReturnType:   ast.TypeFloat,
		Variadic:     true,
		VariadicType: ast.TypeFloat,
		Callback: func(args []interface{}) (interface{}, error) {
			min := args[0].(float64)

			for i := 1; i < len(args); i++ {
				min = math.Min(min, args[i].(float64))
			}

			return min, nil
		},
	}
}
739263
func (value Value) IsFunction() bool {
	if value.kind != valueObject {
		return false
	}
	return value.value.(*_object).class == "Function"
}