// funcExpr creates a function that reflect Call can use.
// When called, it will run runVMFunction, to run the function statements
497012
func (runInfo *runInfoStruct) funcExpr() {
	funcExpr := runInfo.expr.(*ast.FuncExpr)

	// create the inTypes needed by reflect.FuncOf
	inTypes := make([]reflect.Type, len(funcExpr.Params)+1)
	// for runVMFunction first arg is always context
	inTypes[0] = contextType
	for i := 1; i < len(inTypes); i++ {
		inTypes[i] = reflectValueType
	}
	if funcExpr.VarArg {
		inTypes[len(inTypes)-1] = interfaceSliceType
	}
	// create funcType, output is always slice of reflect.Type with two values
	funcType := reflect.FuncOf(inTypes, []reflect.Type{reflectValueType, reflectValueType}, funcExpr.VarArg)

	// for adding env into saved function
	envFunc := runInfo.env

	// create a function that can be used by reflect.MakeFunc
	// this function is a translator that converts a function call into a vm run
	// returns slice of reflect.Type with two values:
	// return value of the function and error value of the run
	runVMFunction := func(in []reflect.Value) []reflect.Value {
		runInfo := runInfoStruct{ctx: in[0].Interface().(context.Context), env: envFunc.NewEnv(), stmt: funcExpr.Stmt, rv: nilValue}

		// add Params to newEnv, except last Params
		for i := 0; i < len(funcExpr.Params)-1; i++ {
			runInfo.rv = in[i+1].Interface().(reflect.Value)
			runInfo.env.defineValue(funcExpr.Params[i], runInfo.rv)
		}
		// add last Params to newEnv
		if len(funcExpr.Params) > 0 {
			if funcExpr.VarArg {
				// function is variadic, add last Params to newEnv without convert to Interface and then reflect.Value
				runInfo.rv = in[len(funcExpr.Params)]
				runInfo.env.defineValue(funcExpr.Params[len(funcExpr.Params)-1], runInfo.rv)
			} else {
				// function is not variadic, add last Params to newEnv
				runInfo.rv = in[len(funcExpr.Params)].Interface().(reflect.Value)
				runInfo.env.defineValue(funcExpr.Params[len(funcExpr.Params)-1], runInfo.rv)
			}
		}

		// run function statements
		runInfo.runSingleStmt()
		if runInfo.err != nil && runInfo.err != ErrReturn {
			runInfo.err = newError(funcExpr, runInfo.err)
			// return nil value and error
			// need to do single reflect.ValueOf because nilValue is already reflect.Value of nil
			// need to do double reflect.ValueOf of newError in order to match
			return []reflect.Value{reflectValueNilValue, reflect.ValueOf(reflect.ValueOf(newError(funcExpr, runInfo.err)))}
		}

		// the reflect.ValueOf of rv is needed to work in the reflect.Value slice
		// reflectValueErrorNilValue is already a double reflect.ValueOf
		return []reflect.Value{reflect.ValueOf(runInfo.rv), reflectValueErrorNilValue}
	}

	// make the reflect.Value function that calls runVMFunction
	runInfo.rv = reflect.MakeFunc(funcType, runVMFunction)

	// if function name is not empty, define it in the env
	if funcExpr.Name != "" {
		runInfo.env.defineValue(funcExpr.Name, runInfo.rv)
	}
}
645272
func check_type_expr(e ast.Expr) bool {
	switch t := e.(type) {
	case *ast.StarExpr:
		return check_type_expr(t.X)
	case *ast.ArrayType:
		return check_type_expr(t.Elt)
	case *ast.SelectorExpr:
		return check_type_expr(t.X)
	case *ast.FuncType:
		a := check_func_field_list(t.Params)
		b := check_func_field_list(t.Results)
		return a && b
	case *ast.MapType:
		a := check_type_expr(t.Key)
		b := check_type_expr(t.Value)
		return a && b
	case *ast.Ellipsis:
		return check_type_expr(t.Elt)
	case *ast.ChanType:
		return check_type_expr(t.Value)
	case *ast.BadExpr:
		return false
	default:
		return true
	}
}
623196
func (frame *Frame) Func() *runtime.Func {
	if frame.ProgramCounter == 0 {
		return nil
	}
	return runtime.FuncForPC(frame.ProgramCounter)
}
361197
func (p *parser) parseExpr(expr interface{}) (interface{}, bool) {

	p.ExprCnt++
	if p.ExprCnt > p.maxExprCnt {
		panic(errMaxExprCnt)
	}

	var val interface{}
	var ok bool
	switch expr := expr.(type) {
	case *actionExpr:
		val, ok = p.parseActionExpr(expr)
	case *andCodeExpr:
		val, ok = p.parseAndCodeExpr(expr)
	case *andExpr:
		val, ok = p.parseAndExpr(expr)
	case *anyMatcher:
		val, ok = p.parseAnyMatcher(expr)
	case *charClassMatcher:
		val, ok = p.parseCharClassMatcher(expr)
	case *choiceExpr:
		val, ok = p.parseChoiceExpr(expr)
	case *labeledExpr:
		val, ok = p.parseLabeledExpr(expr)
	case *litMatcher:
		val, ok = p.parseLitMatcher(expr)
	case *notCodeExpr:
		val, ok = p.parseNotCodeExpr(expr)
	case *notExpr:
		val, ok = p.parseNotExpr(expr)
	case *oneOrMoreExpr:
		val, ok = p.parseOneOrMoreExpr(expr)
	case *recoveryExpr:
		val, ok = p.parseRecoveryExpr(expr)
	case *ruleRefExpr:
		val, ok = p.parseRuleRefExpr(expr)
	case *seqExpr:
		val, ok = p.parseSeqExpr(expr)
	case *throwExpr:
		val, ok = p.parseThrowExpr(expr)
	case *zeroOrMoreExpr:
		val, ok = p.parseZeroOrMoreExpr(expr)
	case *zeroOrOneExpr:
		val, ok = p.parseZeroOrOneExpr(expr)
	default:
		panic(fmt.Sprintf("unknown expression type %T", expr))
	}
	return val, ok
}
536393
func isMutableEffectsExpr(expr Expression) bool {
	switch x := expr.(type) {
	case *ScalarFunction:
		if _, ok := mutableEffectsFunctions[x.FuncName.L]; ok {
			return true
		}
		for _, arg := range x.GetArgs() {
			if isMutableEffectsExpr(arg) {
				return true
			}
		}
	case *Column:
	case *Constant:
		if x.DeferredExpr != nil {
			return isMutableEffectsExpr(x.DeferredExpr)
		}
	}
	return false
}
174565
func (p *Planner) planExpr(e *ast.Expr, iter planiter) error {

	if e.Negated {
		return p.planNot(e, iter)
	}

	if len(e.With) > 0 {
		return fmt.Errorf("with keyword not implemented")
	}

	if e.IsCall() {
		return p.planExprCall(e, iter)
	}

	return p.planExprTerm(e, iter)
}
453526
func (p *parser) parseRelationalExpr(n node) node {
	opnd := p.parseAdditiveExpr(n)
Loop:
	for {
		var op string
		switch p.r.typ {
		case itemLt:
			op = "<"
		case itemGt:
			op = ">"
		case itemLe:
			op = "<="
		case itemGe:
			op = ">="
		default:
			break Loop
		}
		p.next()
		opnd = newOperatorNode(op, opnd, p.parseAdditiveExpr(n))
	}
	return opnd
}
261979
func SpecFromStructReflect(fname string, args reflect.Type, rets reflect.Type) *FunctionSpec {
	s := FunctionSpec{
		Inputs:  make([]Argument, args.NumField()),
		Outputs: make([]Argument, rets.NumField()),
	}
	for i := 0; i < args.NumField(); i++ {
		f := args.Field(i)
		a := EVMTypeFromReflect(f.Type)
		a.Name = f.Name
		s.Inputs[i] = a
	}
	for i := 0; i < rets.NumField(); i++ {
		f := rets.Field(i)
		a := EVMTypeFromReflect(f.Type)
		a.Name = f.Name
		s.Outputs[i] = a
	}
	s.SetFunctionID(fname)

	return &s
}
1193399
func ParseExprWithFuncs(p TokenPager, fr FuncResolver) (Node, error) {
	t := newTreeFuncs(p, fr)
	// Parser panics on unexpected syntax, convert this into an err
	return t.parse()
}
1295447
func (runInfo *runInfoStruct) invokeExpr() {
	switch expr := runInfo.expr.(type) {

	// OpExpr
	case *ast.OpExpr:
		runInfo.operator = expr.Op
		runInfo.invokeOperator()

	// IdentExpr
	case *ast.IdentExpr:
		runInfo.rv, runInfo.err = runInfo.env.get(expr.Lit)
		if runInfo.err != nil {
			runInfo.err = newError(expr, runInfo.err)
		}

	// LiteralExpr
	case *ast.LiteralExpr:
		runInfo.rv = expr.Literal

	// ArrayExpr
	case *ast.ArrayExpr:
		if expr.TypeData == nil {
			slice := make([]interface{}, len(expr.Exprs))
			var i int
			for i, runInfo.expr = range expr.Exprs {
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				slice[i] = runInfo.rv.Interface()
			}
			runInfo.rv = reflect.ValueOf(slice)
			return
		}

		t := makeType(runInfo, expr.TypeData)
		if runInfo.err != nil {
			runInfo.rv = nilValue
			return
		}
		if t == nil {
			runInfo.err = newStringError(expr, "cannot make type nil")
			runInfo.rv = nilValue
			return
		}

		slice := reflect.MakeSlice(t, len(expr.Exprs), len(expr.Exprs))
		var i int
		valueType := t.Elem()
		for i, runInfo.expr = range expr.Exprs {
			runInfo.invokeExpr()
			if runInfo.err != nil {
				return
			}

			runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, valueType)
			if runInfo.err != nil {
				runInfo.err = newStringError(expr, "cannot use type "+runInfo.rv.Type().String()+" as type "+valueType.String()+" as slice value")
				runInfo.rv = nilValue
				return
			}

			slice.Index(i).Set(runInfo.rv)
		}
		runInfo.rv = slice

	// MapExpr
	case *ast.MapExpr:
		if expr.TypeData == nil {
			var i int
			var key reflect.Value
			m := make(map[interface{}]interface{}, len(expr.Keys))
			for i, runInfo.expr = range expr.Keys {
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				key = runInfo.rv

				runInfo.expr = expr.Values[i]
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}

				m[key.Interface()] = runInfo.rv.Interface()
			}
			runInfo.rv = reflect.ValueOf(m)
			return
		}

		t := makeType(runInfo, expr.TypeData)
		if runInfo.err != nil {
			runInfo.rv = nilValue
			return
		}
		if t == nil {
			runInfo.err = newStringError(expr, "cannot make type nil")
			runInfo.rv = nilValue
			return
		}

		runInfo.rv, runInfo.err = makeValue(t)
		if runInfo.err != nil {
			runInfo.rv = nilValue
			return
		}

		var i int
		var key reflect.Value
		m := runInfo.rv
		keyType := t.Key()
		valueType := t.Elem()
		for i, runInfo.expr = range expr.Keys {
			runInfo.invokeExpr()
			if runInfo.err != nil {
				return
			}
			key, runInfo.err = convertReflectValueToType(runInfo.rv, keyType)
			if runInfo.err != nil {
				runInfo.err = newStringError(expr, "cannot use type "+key.Type().String()+" as type "+keyType.String()+" as map key")
				runInfo.rv = nilValue
				return
			}

			runInfo.expr = expr.Values[i]
			runInfo.invokeExpr()
			if runInfo.err != nil {
				return
			}
			runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, valueType)
			if runInfo.err != nil {
				runInfo.err = newStringError(expr, "cannot use type "+runInfo.rv.Type().String()+" as type "+valueType.String()+" as map value")
				runInfo.rv = nilValue
				return
			}

			m.SetMapIndex(key, runInfo.rv)
		}
		runInfo.rv = m

	// DerefExpr
	case *ast.DerefExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if runInfo.rv.Kind() != reflect.Ptr {
			runInfo.err = newStringError(expr.Expr, "cannot deference non-pointer")
			runInfo.rv = nilValue
			return
		}
		runInfo.rv = runInfo.rv.Elem()

	// AddrExpr
	case *ast.AddrExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if runInfo.rv.CanAddr() {
			runInfo.rv = runInfo.rv.Addr()
		} else {
			i := runInfo.rv.Interface()
			runInfo.rv = reflect.ValueOf(&i)
		}

	// UnaryExpr
	case *ast.UnaryExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		switch expr.Operator {
		case "-":
			switch runInfo.rv.Kind() {
			case reflect.Int64:
				runInfo.rv = reflect.ValueOf(-runInfo.rv.Int())
			case reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int, reflect.Bool:
				runInfo.rv = reflect.ValueOf(-toInt64(runInfo.rv))
			case reflect.Float64:
				runInfo.rv = reflect.ValueOf(-runInfo.rv.Float())
			default:
				runInfo.rv = reflect.ValueOf(-toFloat64(runInfo.rv))
			}
		case "^":
			runInfo.rv = reflect.ValueOf(^toInt64(runInfo.rv))
		case "!":
			if toBool(runInfo.rv) {
				runInfo.rv = falseValue
			} else {
				runInfo.rv = trueValue
			}
		default:
			runInfo.err = newStringError(expr, "unknown operator")
			runInfo.rv = nilValue
		}

	// ParenExpr
	case *ast.ParenExpr:
		runInfo.expr = expr.SubExpr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

	// MemberExpr
	case *ast.MemberExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
			runInfo.rv = runInfo.rv.Elem()
		}

		if env, ok := runInfo.rv.Interface().(*Env); ok {
			runInfo.rv, runInfo.err = env.get(expr.Name)
			if runInfo.err != nil {
				runInfo.err = newError(expr, runInfo.err)
				runInfo.rv = nilValue
			}
			return
		}

		value := runInfo.rv.MethodByName(expr.Name)
		if value.IsValid() {
			runInfo.rv = value
			return
		}

		if runInfo.rv.Kind() == reflect.Ptr {
			runInfo.rv = runInfo.rv.Elem()
		}

		switch runInfo.rv.Kind() {
		case reflect.Struct:
			field, found := runInfo.rv.Type().FieldByName(expr.Name)
			if found {
				runInfo.rv = runInfo.rv.FieldByIndex(field.Index)
				return
			}
			if runInfo.rv.CanAddr() {
				runInfo.rv = runInfo.rv.Addr()
				method, found := runInfo.rv.Type().MethodByName(expr.Name)
				if found {
					runInfo.rv = runInfo.rv.Method(method.Index)
					return
				}
			}
			runInfo.err = newStringError(expr, "no member named '"+expr.Name+"' for struct")
			runInfo.rv = nilValue
		case reflect.Map:
			runInfo.rv = getMapIndex(reflect.ValueOf(expr.Name), runInfo.rv)
		default:
			runInfo.err = newStringError(expr, "type "+runInfo.rv.Kind().String()+" does not support member operation")
			runInfo.rv = nilValue
		}

	// ItemExpr
	case *ast.ItemExpr:
		runInfo.expr = expr.Item
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}
		item := runInfo.rv

		runInfo.expr = expr.Index
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if item.Kind() == reflect.Interface && !item.IsNil() {
			item = item.Elem()
		}

		switch item.Kind() {
		case reflect.String, reflect.Slice, reflect.Array:
			var index int
			index, runInfo.err = tryToInt(runInfo.rv)
			if runInfo.err != nil {
				runInfo.err = newStringError(expr, "index must be a number")
				runInfo.rv = nilValue
				return
			}
			if index < 0 || index >= item.Len() {
				runInfo.err = newStringError(expr, "index out of range")
				runInfo.rv = nilValue
				return
			}
			if item.Kind() != reflect.String {
				runInfo.rv = item.Index(index)
			} else {
				// String
				runInfo.rv = item.Index(index).Convert(stringType)
			}
		case reflect.Map:
			runInfo.rv = getMapIndex(runInfo.rv, item)
		default:
			runInfo.err = newStringError(expr, "type "+item.Kind().String()+" does not support index operation")
			runInfo.rv = nilValue
		}

	// SliceExpr
	case *ast.SliceExpr:
		runInfo.expr = expr.Item
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}
		item := runInfo.rv

		if item.Kind() == reflect.Interface && !item.IsNil() {
			item = item.Elem()
		}

		switch item.Kind() {
		case reflect.String, reflect.Slice, reflect.Array:
			var beginIndex int
			endIndex := item.Len()

			if expr.Begin != nil {
				runInfo.expr = expr.Begin
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				beginIndex, runInfo.err = tryToInt(runInfo.rv)
				if runInfo.err != nil {
					runInfo.err = newStringError(expr, "index must be a number")
					runInfo.rv = nilValue
					return
				}
				// (0 <= low) <= high <= len(a)
				if beginIndex < 0 {
					runInfo.err = newStringError(expr, "index out of range")
					runInfo.rv = nilValue
					return
				}
			}

			if expr.End != nil {
				runInfo.expr = expr.End
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				endIndex, runInfo.err = tryToInt(runInfo.rv)
				if runInfo.err != nil {
					runInfo.err = newStringError(expr, "index must be a number")
					runInfo.rv = nilValue
					return
				}
				// 0 <= low <= (high <= len(a))
				if endIndex > item.Len() {
					runInfo.err = newStringError(expr, "index out of range")
					runInfo.rv = nilValue
					return
				}
			}

			// 0 <= (low <= high) <= len(a)
			if beginIndex > endIndex {
				runInfo.err = newStringError(expr, "index out of range")
				runInfo.rv = nilValue
				return
			}

			if item.Kind() == reflect.String {
				if expr.Cap != nil {
					runInfo.err = newStringError(expr, "type string does not support cap")
					runInfo.rv = nilValue
					return
				}
				runInfo.rv = item.Slice(beginIndex, endIndex)
				return
			}

			sliceCap := item.Cap()
			if expr.Cap != nil {
				runInfo.expr = expr.Cap
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				sliceCap, runInfo.err = tryToInt(runInfo.rv)
				if runInfo.err != nil {
					runInfo.err = newStringError(expr, "cap must be a number")
					runInfo.rv = nilValue
					return
				}
				//  0 <= low <= (high <= max <= cap(a))
				if sliceCap < endIndex || sliceCap > item.Cap() {
					runInfo.err = newStringError(expr, "cap out of range")
					runInfo.rv = nilValue
					return
				}
			}

			runInfo.rv = item.Slice3(beginIndex, endIndex, sliceCap)

		default:
			runInfo.err = newStringError(expr, "type "+item.Kind().String()+" does not support slice operation")
			runInfo.rv = nilValue
		}

	// LetsExpr
	case *ast.LetsExpr:
		var i int
		for i, runInfo.expr = range expr.RHSS {
			runInfo.invokeExpr()
			if runInfo.err != nil {
				return
			}
			if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
				runInfo.rv = runInfo.rv.Elem()
			}
			if i < len(expr.LHSS) {
				runInfo.expr = expr.LHSS[i]
				runInfo.invokeLetExpr()
				if runInfo.err != nil {
					return
				}
			}

		}

	// TernaryOpExpr
	case *ast.TernaryOpExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if toBool(runInfo.rv) {
			runInfo.expr = expr.LHS
		} else {
			runInfo.expr = expr.RHS
		}
		runInfo.invokeExpr()

	// NilCoalescingOpExpr
	case *ast.NilCoalescingOpExpr:
		// if left side has no error and is not nil, returns left side
		// otherwise returns right side
		runInfo.expr = expr.LHS
		runInfo.invokeExpr()
		if runInfo.err == nil {
			if !isNil(runInfo.rv) {
				return
			}
		} else {
			runInfo.err = nil
		}
		runInfo.expr = expr.RHS
		runInfo.invokeExpr()

	// LenExpr
	case *ast.LenExpr:
		runInfo.expr = expr.Expr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
			runInfo.rv = runInfo.rv.Elem()
		}

		switch runInfo.rv.Kind() {
		case reflect.Slice, reflect.Array, reflect.Map, reflect.String, reflect.Chan:
			runInfo.rv = reflect.ValueOf(int64(runInfo.rv.Len()))
		default:
			runInfo.err = newStringError(expr, "type "+runInfo.rv.Kind().String()+" does not support len operation")
			runInfo.rv = nilValue
		}

	// MakeExpr
	case *ast.MakeExpr:
		t := makeType(runInfo, expr.TypeData)
		if runInfo.err != nil {
			runInfo.rv = nilValue
			return
		}
		if t == nil {
			runInfo.err = newStringError(expr, "cannot make type nil")
			runInfo.rv = nilValue
			return
		}

		switch expr.TypeData.Kind {
		case ast.TypeSlice:
			aLen := 0
			if expr.LenExpr != nil {
				runInfo.expr = expr.LenExpr
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				aLen = toInt(runInfo.rv)
			}
			cap := aLen
			if expr.CapExpr != nil {
				runInfo.expr = expr.CapExpr
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				cap = toInt(runInfo.rv)
			}
			if aLen > cap {
				runInfo.err = newStringError(expr, "make slice len > cap")
				runInfo.rv = nilValue
				return
			}
			runInfo.rv = reflect.MakeSlice(t, aLen, cap)
			return
		case ast.TypeChan:
			aLen := 0
			if expr.LenExpr != nil {
				runInfo.expr = expr.LenExpr
				runInfo.invokeExpr()
				if runInfo.err != nil {
					return
				}
				aLen = toInt(runInfo.rv)
			}
			runInfo.rv = reflect.MakeChan(t, aLen)
			return
		}

		runInfo.rv, runInfo.err = makeValue(t)

	// MakeTypeExpr
	case *ast.MakeTypeExpr:
		runInfo.expr = expr.Type
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		// if expr.Name has a dot in it, it should give a syntax error, so no needs to check err
		runInfo.env.DefineReflectType(expr.Name, runInfo.rv.Type())

		runInfo.rv = reflect.ValueOf(runInfo.rv.Type())

	// ChanExpr
	case *ast.ChanExpr:
		runInfo.expr = expr.RHS
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}
		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
			runInfo.rv = runInfo.rv.Elem()
		}
		rhs := runInfo.rv

		if expr.LHS != nil {
			runInfo.expr = expr.LHS
			runInfo.invokeExpr()
			if runInfo.err != nil {
				if len(runInfo.err.Error()) < 18 || runInfo.err.Error()[:17] != "undefined symbol " {
					return
				}
				runInfo.err = nil
			}
		}

		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
			runInfo.rv = runInfo.rv.Elem()
		}

		if expr.LHS == nil || runInfo.rv.Kind() != reflect.Chan {
			// lhs is not channel
			if rhs.Kind() != reflect.Chan {
				// rhs is not channel
				runInfo.err = newStringError(expr, "invalid operation for chan")
				runInfo.rv = nilValue
				return
			}
			// receive from rhs channel
			cases := []reflect.SelectCase{{
				Dir:  reflect.SelectRecv,
				Chan: reflect.ValueOf(runInfo.ctx.Done()),
			}, {
				Dir:  reflect.SelectRecv,
				Chan: rhs,
			}}
			var chosen int
			var ok bool
			chosen, runInfo.rv, ok = reflect.Select(cases)
			if chosen == 0 {
				runInfo.err = ErrInterrupt
				runInfo.rv = nilValue
				return
			}
			if !ok {
				runInfo.rv = nilValue
			}
			if expr.LHS != nil {
				// TOFIX: this runs the expr.LHS again, will sometimes cause bugs, for example with i++
				// most likely need a syntax change to expr = <- expr for let expr
				// TODO: add option to return ok
				runInfo.expr = expr.LHS
				runInfo.invokeLetExpr()
			}
			return
		}

		// send to lhs channel
		rhs, runInfo.err = convertReflectValueToType(rhs, runInfo.rv.Type().Elem())
		if runInfo.err != nil {
			runInfo.err = newStringError(expr, "cannot use type "+rhs.Type().String()+" as type "+runInfo.rv.Type().Elem().String()+" to send to chan")
			runInfo.rv = nilValue
			return
		}
		cases := []reflect.SelectCase{{
			Dir:  reflect.SelectRecv,
			Chan: reflect.ValueOf(runInfo.ctx.Done()),
		}, {
			Dir:  reflect.SelectSend,
			Chan: runInfo.rv,
			Send: rhs,
		}}
		// capture panics if not in debug mode
		defer func() {
			if os.Getenv("ANKO_DEBUG") == "" {
				if recoverResult := recover(); recoverResult != nil {
					runInfo.err = fmt.Errorf("%v", recoverResult)
				}
			}
		}()
		runInfo.rv = nilValue
		if chosen, _, _ := reflect.Select(cases); chosen == 0 {
			runInfo.err = ErrInterrupt
		}

	// FuncExpr
	case *ast.FuncExpr:
		runInfo.expr = expr
		runInfo.funcExpr()

	// AnonCallExpr
	case *ast.AnonCallExpr:
		runInfo.expr = expr
		runInfo.anonCallExpr()

	// CallExpr
	case *ast.CallExpr:
		runInfo.expr = expr
		runInfo.callExpr()

	// IncludeExpr
	case *ast.IncludeExpr:
		runInfo.expr = expr.ItemExpr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}
		itemExpr := runInfo.rv

		runInfo.expr = expr.ListExpr
		runInfo.invokeExpr()
		if runInfo.err != nil {
			return
		}

		if runInfo.rv.Kind() != reflect.Slice && runInfo.rv.Kind() != reflect.Array {
			runInfo.err = newStringError(expr, "second argument must be slice or array; but have "+runInfo.rv.Kind().String())
			runInfo.rv = nilValue
			return
		}

		for i := 0; i < runInfo.rv.Len(); i++ {
			if equal(itemExpr, runInfo.rv.Index(i)) {
				runInfo.rv = trueValue
				return
			}
		}
		runInfo.rv = falseValue

	default:
		runInfo.err = newStringError(expr, "unknown expression")
		runInfo.rv = nilValue
	}

}
644527
func (runInfo *runInfoStruct) callExpr() {
	// Note that if the function type looks the same as the VM function type, the returned values will probably be wrong

	callExpr := runInfo.expr.(*ast.CallExpr)

	f := callExpr.Func
	if !f.IsValid() {
		// if function is not valid try to get by function name
		f, runInfo.err = runInfo.env.get(callExpr.Name)
		if runInfo.err != nil {
			runInfo.err = newError(callExpr, runInfo.err)
			runInfo.rv = nilValue
			return
		}
	}

	if f.Kind() == reflect.Interface && !f.IsNil() {
		f = f.Elem()
	}
	if f.Kind() != reflect.Func {
		runInfo.err = newStringError(callExpr, "cannot call type "+f.Kind().String())
		runInfo.rv = nilValue
		return
	}

	var rvs []reflect.Value
	var args []reflect.Value
	var useCallSlice bool
	fType := f.Type()
	// check if this is a runVMFunction type
	isRunVMFunction := checkIfRunVMFunction(fType)
	// create/convert the args to the function
	args, useCallSlice = runInfo.makeCallArgs(fType, isRunVMFunction, callExpr)
	if runInfo.err != nil {
		return
	}

	// capture panics if not in debug mode
	defer func() {
		if os.Getenv("ANKO_DEBUG") == "" {
			if recoverResult := recover(); recoverResult != nil {
				runInfo.err = fmt.Errorf("%v", recoverResult)
				runInfo.rv = nilValue
			}
		}
	}()

	// useCallSlice lets us know to use CallSlice instead of Call because of the format of the args
	if useCallSlice {
		if callExpr.Go {
			go f.CallSlice(args)
			return
		}
		rvs = f.CallSlice(args)
	} else {
		if callExpr.Go {
			go f.Call(args)
			return
		}
		rvs = f.Call(args)
	}

	// TOFIX: how VM pointers/addressing work
	// Until then, this is a work around to set pointers back to VM variables
	// This will probably panic for some functions and/or calls that are variadic
	if !isRunVMFunction {
		for i, expr := range callExpr.SubExprs {
			if addrExpr, ok := expr.(*ast.AddrExpr); ok {
				if identExpr, ok := addrExpr.Expr.(*ast.IdentExpr); ok {
					runInfo.rv = args[i].Elem()
					runInfo.expr = identExpr
					runInfo.invokeLetExpr()
				}
			}
		}
	}

	// processCallReturnValues to get/convert return values to normal rv form
	runInfo.rv, runInfo.err = processCallReturnValues(rvs, isRunVMFunction, true)
}
842287
func (b ValExprBuilder) RegExp(val interface{}) BoolExprBuilder {
	return b.makeComparisonExpr(astRegExp, makeValExpr(val))
}
251536
func wrapFunc(fn Func) FuncCtx {
	if fn == nil {
		return nil // be sure not to wrap a bad function.
	}
	return func(ctx context.Context, fl FieldLevel) bool {
		return fn(fl)
	}
}
140862
func (er *expressionRewriter) handleOtherComparableSubq(lexpr, rexpr expression.Expression, np LogicalPlan, useMin bool, cmpFunc string, all bool) {
	funcName := ast.AggFuncMax
	if useMin {
		funcName = ast.AggFuncMin
	}
	aggFunc := expression.NewAggFunction(funcName, []expression.Expression{rexpr}, false)
	agg := &Aggregation{
		baseLogicalPlan: newBaseLogicalPlan(Agg, er.b.allocator),
		AggFuncs:        []expression.AggregationFunction{aggFunc},
	}
	agg.initIDAndContext(er.b.ctx)
	agg.self = agg
	addChild(agg, np)
	aggCol0 := &expression.Column{
		ColName:  model.NewCIStr("agg_Col_0"),
		FromID:   agg.id,
		Position: 0,
		RetType:  aggFunc.GetType(),
	}
	schema := expression.NewSchema([]*expression.Column{aggCol0})
	agg.SetSchema(schema)
	cond, _ := expression.NewFunction(er.ctx, cmpFunc, types.NewFieldType(mysql.TypeTiny), lexpr, aggCol0.Clone())
	er.buildQuantifierPlan(agg, cond, rexpr, all)
}
526148
func makeFunction(attributes []string) func(interface{}) string {
	return func(text interface{}) string {
		return fmt.Sprintf("\033[%sm%s\033[0m", strings.Join(attributes, ";"), text)
	}
}
496021
func ParseExpr(input string) (*Expr, error) {
	body, err := ParseBody(input)
	if err != nil {
		return nil, errors.Wrap(err, "failed to parse expression")
	}
	if len(body) != 1 {
		return nil, fmt.Errorf("expected exactly one expression but got: %v", body)
	}
	return body[0], 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)})
	}
}