github.com/mattn/anko@v0.1.10/vm/vmExpr.go (about)

     1  package vm
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/mattn/anko/ast"
     7  	"github.com/mattn/anko/env"
     8  )
     9  
    10  // invokeExpr evaluates one expression.
    11  func (runInfo *runInfoStruct) invokeExpr() {
    12  	switch expr := runInfo.expr.(type) {
    13  
    14  	// OpExpr
    15  	case *ast.OpExpr:
    16  		runInfo.operator = expr.Op
    17  		runInfo.invokeOperator()
    18  
    19  	// IdentExpr
    20  	case *ast.IdentExpr:
    21  		runInfo.rv, runInfo.err = runInfo.env.GetValue(expr.Lit)
    22  		if runInfo.err != nil {
    23  			runInfo.err = newError(expr, runInfo.err)
    24  		}
    25  
    26  	// LiteralExpr
    27  	case *ast.LiteralExpr:
    28  		runInfo.rv = expr.Literal
    29  
    30  	// ArrayExpr
    31  	case *ast.ArrayExpr:
    32  		if expr.TypeData == nil {
    33  			slice := make([]interface{}, len(expr.Exprs))
    34  			var i int
    35  			for i, runInfo.expr = range expr.Exprs {
    36  				runInfo.invokeExpr()
    37  				if runInfo.err != nil {
    38  					return
    39  				}
    40  				slice[i] = runInfo.rv.Interface()
    41  			}
    42  			runInfo.rv = reflect.ValueOf(slice)
    43  			return
    44  		}
    45  
    46  		t := makeType(runInfo, expr.TypeData)
    47  		if runInfo.err != nil {
    48  			runInfo.rv = nilValue
    49  			return
    50  		}
    51  		if t == nil {
    52  			runInfo.err = newStringError(expr, "cannot make type nil")
    53  			runInfo.rv = nilValue
    54  			return
    55  		}
    56  
    57  		slice := reflect.MakeSlice(t, len(expr.Exprs), len(expr.Exprs))
    58  		var i int
    59  		valueType := t.Elem()
    60  		for i, runInfo.expr = range expr.Exprs {
    61  			runInfo.invokeExpr()
    62  			if runInfo.err != nil {
    63  				return
    64  			}
    65  
    66  			runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, valueType)
    67  			if runInfo.err != nil {
    68  				runInfo.err = newStringError(expr, "cannot use type "+runInfo.rv.Type().String()+" as type "+valueType.String()+" as slice value")
    69  				runInfo.rv = nilValue
    70  				return
    71  			}
    72  
    73  			slice.Index(i).Set(runInfo.rv)
    74  		}
    75  		runInfo.rv = slice
    76  
    77  	// MapExpr
    78  	case *ast.MapExpr:
    79  		if expr.TypeData == nil {
    80  			var i int
    81  			var key reflect.Value
    82  			m := make(map[interface{}]interface{}, len(expr.Keys))
    83  			for i, runInfo.expr = range expr.Keys {
    84  				runInfo.invokeExpr()
    85  				if runInfo.err != nil {
    86  					return
    87  				}
    88  				key = runInfo.rv
    89  
    90  				runInfo.expr = expr.Values[i]
    91  				runInfo.invokeExpr()
    92  				if runInfo.err != nil {
    93  					return
    94  				}
    95  
    96  				m[key.Interface()] = runInfo.rv.Interface()
    97  			}
    98  			runInfo.rv = reflect.ValueOf(m)
    99  			return
   100  		}
   101  
   102  		t := makeType(runInfo, expr.TypeData)
   103  		if runInfo.err != nil {
   104  			runInfo.rv = nilValue
   105  			return
   106  		}
   107  		if t == nil {
   108  			runInfo.err = newStringError(expr, "cannot make type nil")
   109  			runInfo.rv = nilValue
   110  			return
   111  		}
   112  
   113  		runInfo.rv, runInfo.err = makeValue(t)
   114  		if runInfo.err != nil {
   115  			runInfo.rv = nilValue
   116  			return
   117  		}
   118  
   119  		var i int
   120  		var key reflect.Value
   121  		m := runInfo.rv
   122  		keyType := t.Key()
   123  		valueType := t.Elem()
   124  		for i, runInfo.expr = range expr.Keys {
   125  			runInfo.invokeExpr()
   126  			if runInfo.err != nil {
   127  				return
   128  			}
   129  			key, runInfo.err = convertReflectValueToType(runInfo.rv, keyType)
   130  			if runInfo.err != nil {
   131  				runInfo.err = newStringError(expr, "cannot use type "+key.Type().String()+" as type "+keyType.String()+" as map key")
   132  				runInfo.rv = nilValue
   133  				return
   134  			}
   135  
   136  			runInfo.expr = expr.Values[i]
   137  			runInfo.invokeExpr()
   138  			if runInfo.err != nil {
   139  				return
   140  			}
   141  			runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, valueType)
   142  			if runInfo.err != nil {
   143  				runInfo.err = newStringError(expr, "cannot use type "+runInfo.rv.Type().String()+" as type "+valueType.String()+" as map value")
   144  				runInfo.rv = nilValue
   145  				return
   146  			}
   147  
   148  			m.SetMapIndex(key, runInfo.rv)
   149  		}
   150  		runInfo.rv = m
   151  
   152  	// DerefExpr
   153  	case *ast.DerefExpr:
   154  		runInfo.expr = expr.Expr
   155  		runInfo.invokeExpr()
   156  		if runInfo.err != nil {
   157  			return
   158  		}
   159  
   160  		if runInfo.rv.Kind() != reflect.Ptr {
   161  			runInfo.err = newStringError(expr.Expr, "cannot deference non-pointer")
   162  			runInfo.rv = nilValue
   163  			return
   164  		}
   165  		runInfo.rv = runInfo.rv.Elem()
   166  
   167  	// AddrExpr
   168  	case *ast.AddrExpr:
   169  		runInfo.expr = expr.Expr
   170  		runInfo.invokeExpr()
   171  		if runInfo.err != nil {
   172  			return
   173  		}
   174  
   175  		if runInfo.rv.CanAddr() {
   176  			runInfo.rv = runInfo.rv.Addr()
   177  		} else {
   178  			i := runInfo.rv.Interface()
   179  			runInfo.rv = reflect.ValueOf(&i)
   180  		}
   181  
   182  	// UnaryExpr
   183  	case *ast.UnaryExpr:
   184  		runInfo.expr = expr.Expr
   185  		runInfo.invokeExpr()
   186  		if runInfo.err != nil {
   187  			return
   188  		}
   189  
   190  		switch expr.Operator {
   191  		case "-":
   192  			switch runInfo.rv.Kind() {
   193  			case reflect.Int64:
   194  				runInfo.rv = reflect.ValueOf(-runInfo.rv.Int())
   195  			case reflect.Int32, reflect.Int16, reflect.Int8, reflect.Int, reflect.Bool:
   196  				runInfo.rv = reflect.ValueOf(-toInt64(runInfo.rv))
   197  			case reflect.Float64:
   198  				runInfo.rv = reflect.ValueOf(-runInfo.rv.Float())
   199  			default:
   200  				runInfo.rv = reflect.ValueOf(-toFloat64(runInfo.rv))
   201  			}
   202  		case "^":
   203  			runInfo.rv = reflect.ValueOf(^toInt64(runInfo.rv))
   204  		case "!":
   205  			if toBool(runInfo.rv) {
   206  				runInfo.rv = falseValue
   207  			} else {
   208  				runInfo.rv = trueValue
   209  			}
   210  		default:
   211  			runInfo.err = newStringError(expr, "unknown operator")
   212  			runInfo.rv = nilValue
   213  		}
   214  
   215  	// ParenExpr
   216  	case *ast.ParenExpr:
   217  		runInfo.expr = expr.SubExpr
   218  		runInfo.invokeExpr()
   219  		if runInfo.err != nil {
   220  			return
   221  		}
   222  
   223  	// MemberExpr
   224  	case *ast.MemberExpr:
   225  		runInfo.expr = expr.Expr
   226  		runInfo.invokeExpr()
   227  		if runInfo.err != nil {
   228  			return
   229  		}
   230  
   231  		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
   232  			runInfo.rv = runInfo.rv.Elem()
   233  		}
   234  
   235  		if env, ok := runInfo.rv.Interface().(*env.Env); ok {
   236  			runInfo.rv, runInfo.err = env.GetValue(expr.Name)
   237  			if runInfo.err != nil {
   238  				runInfo.err = newError(expr, runInfo.err)
   239  				runInfo.rv = nilValue
   240  			}
   241  			return
   242  		}
   243  
   244  		value := runInfo.rv.MethodByName(expr.Name)
   245  		if value.IsValid() {
   246  			runInfo.rv = value
   247  			return
   248  		}
   249  
   250  		if runInfo.rv.Kind() == reflect.Ptr {
   251  			runInfo.rv = runInfo.rv.Elem()
   252  		}
   253  
   254  		switch runInfo.rv.Kind() {
   255  		case reflect.Struct:
   256  			field, found := runInfo.rv.Type().FieldByName(expr.Name)
   257  			if found {
   258  				runInfo.rv = runInfo.rv.FieldByIndex(field.Index)
   259  				return
   260  			}
   261  			if runInfo.rv.CanAddr() {
   262  				runInfo.rv = runInfo.rv.Addr()
   263  				method, found := runInfo.rv.Type().MethodByName(expr.Name)
   264  				if found {
   265  					runInfo.rv = runInfo.rv.Method(method.Index)
   266  					return
   267  				}
   268  			} else {
   269  				// Check wether method with pointer receiver is defined,
   270  				// if yes, invoke it in the copied instance
   271  				method, found := reflect.PtrTo(runInfo.rv.Type()).MethodByName(expr.Name)
   272  				if found {
   273  					// Create pointer value to given struct type which were passed by value
   274  					cv := reflect.New(runInfo.rv.Type())
   275  					cv.Elem().Set(runInfo.rv)
   276  					runInfo.rv = cv.Method(method.Index)
   277  					return
   278  				}
   279  			}
   280  			runInfo.err = newStringError(expr, "no member named '"+expr.Name+"' for struct")
   281  			runInfo.rv = nilValue
   282  		case reflect.Map:
   283  			runInfo.rv = getMapIndex(reflect.ValueOf(expr.Name), runInfo.rv)
   284  		default:
   285  			runInfo.err = newStringError(expr, "type "+runInfo.rv.Kind().String()+" does not support member operation")
   286  			runInfo.rv = nilValue
   287  		}
   288  
   289  	// ItemExpr
   290  	case *ast.ItemExpr:
   291  		runInfo.expr = expr.Item
   292  		runInfo.invokeExpr()
   293  		if runInfo.err != nil {
   294  			return
   295  		}
   296  		item := runInfo.rv
   297  
   298  		runInfo.expr = expr.Index
   299  		runInfo.invokeExpr()
   300  		if runInfo.err != nil {
   301  			return
   302  		}
   303  
   304  		if item.Kind() == reflect.Interface && !item.IsNil() {
   305  			item = item.Elem()
   306  		}
   307  
   308  		switch item.Kind() {
   309  		case reflect.String, reflect.Slice, reflect.Array:
   310  			var index int
   311  			index, runInfo.err = tryToInt(runInfo.rv)
   312  			if runInfo.err != nil {
   313  				runInfo.err = newStringError(expr, "index must be a number")
   314  				runInfo.rv = nilValue
   315  				return
   316  			}
   317  			if index < 0 || index >= item.Len() {
   318  				runInfo.err = newStringError(expr, "index out of range")
   319  				runInfo.rv = nilValue
   320  				return
   321  			}
   322  			if item.Kind() != reflect.String {
   323  				runInfo.rv = item.Index(index)
   324  			} else {
   325  				// String
   326  				runInfo.rv = item.Index(index).Convert(stringType)
   327  			}
   328  		case reflect.Map:
   329  			runInfo.rv = getMapIndex(runInfo.rv, item)
   330  		default:
   331  			runInfo.err = newStringError(expr, "type "+item.Kind().String()+" does not support index operation")
   332  			runInfo.rv = nilValue
   333  		}
   334  
   335  	// SliceExpr
   336  	case *ast.SliceExpr:
   337  		runInfo.expr = expr.Item
   338  		runInfo.invokeExpr()
   339  		if runInfo.err != nil {
   340  			return
   341  		}
   342  		item := runInfo.rv
   343  
   344  		if item.Kind() == reflect.Interface && !item.IsNil() {
   345  			item = item.Elem()
   346  		}
   347  
   348  		switch item.Kind() {
   349  		case reflect.String, reflect.Slice, reflect.Array:
   350  			var beginIndex int
   351  			endIndex := item.Len()
   352  
   353  			if expr.Begin != nil {
   354  				runInfo.expr = expr.Begin
   355  				runInfo.invokeExpr()
   356  				if runInfo.err != nil {
   357  					return
   358  				}
   359  				beginIndex, runInfo.err = tryToInt(runInfo.rv)
   360  				if runInfo.err != nil {
   361  					runInfo.err = newStringError(expr, "index must be a number")
   362  					runInfo.rv = nilValue
   363  					return
   364  				}
   365  				// (0 <= low) <= high <= len(a)
   366  				if beginIndex < 0 {
   367  					runInfo.err = newStringError(expr, "index out of range")
   368  					runInfo.rv = nilValue
   369  					return
   370  				}
   371  			}
   372  
   373  			if expr.End != nil {
   374  				runInfo.expr = expr.End
   375  				runInfo.invokeExpr()
   376  				if runInfo.err != nil {
   377  					return
   378  				}
   379  				endIndex, runInfo.err = tryToInt(runInfo.rv)
   380  				if runInfo.err != nil {
   381  					runInfo.err = newStringError(expr, "index must be a number")
   382  					runInfo.rv = nilValue
   383  					return
   384  				}
   385  				// 0 <= low <= (high <= len(a))
   386  				if endIndex > item.Len() {
   387  					runInfo.err = newStringError(expr, "index out of range")
   388  					runInfo.rv = nilValue
   389  					return
   390  				}
   391  			}
   392  
   393  			// 0 <= (low <= high) <= len(a)
   394  			if beginIndex > endIndex {
   395  				runInfo.err = newStringError(expr, "index out of range")
   396  				runInfo.rv = nilValue
   397  				return
   398  			}
   399  
   400  			if item.Kind() == reflect.String {
   401  				if expr.Cap != nil {
   402  					runInfo.err = newStringError(expr, "type string does not support cap")
   403  					runInfo.rv = nilValue
   404  					return
   405  				}
   406  				runInfo.rv = item.Slice(beginIndex, endIndex)
   407  				return
   408  			}
   409  
   410  			sliceCap := item.Cap()
   411  			if expr.Cap != nil {
   412  				runInfo.expr = expr.Cap
   413  				runInfo.invokeExpr()
   414  				if runInfo.err != nil {
   415  					return
   416  				}
   417  				sliceCap, runInfo.err = tryToInt(runInfo.rv)
   418  				if runInfo.err != nil {
   419  					runInfo.err = newStringError(expr, "cap must be a number")
   420  					runInfo.rv = nilValue
   421  					return
   422  				}
   423  				//  0 <= low <= (high <= max <= cap(a))
   424  				if sliceCap < endIndex || sliceCap > item.Cap() {
   425  					runInfo.err = newStringError(expr, "cap out of range")
   426  					runInfo.rv = nilValue
   427  					return
   428  				}
   429  			}
   430  
   431  			runInfo.rv = item.Slice3(beginIndex, endIndex, sliceCap)
   432  
   433  		default:
   434  			runInfo.err = newStringError(expr, "type "+item.Kind().String()+" does not support slice operation")
   435  			runInfo.rv = nilValue
   436  		}
   437  
   438  	// LetsExpr
   439  	case *ast.LetsExpr:
   440  		var i int
   441  		for i, runInfo.expr = range expr.RHSS {
   442  			runInfo.invokeExpr()
   443  			if runInfo.err != nil {
   444  				return
   445  			}
   446  			if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
   447  				runInfo.rv = runInfo.rv.Elem()
   448  			}
   449  			if i < len(expr.LHSS) {
   450  				runInfo.expr = expr.LHSS[i]
   451  				runInfo.invokeLetExpr()
   452  				if runInfo.err != nil {
   453  					return
   454  				}
   455  			}
   456  
   457  		}
   458  
   459  	// TernaryOpExpr
   460  	case *ast.TernaryOpExpr:
   461  		runInfo.expr = expr.Expr
   462  		runInfo.invokeExpr()
   463  		if runInfo.err != nil {
   464  			return
   465  		}
   466  
   467  		if toBool(runInfo.rv) {
   468  			runInfo.expr = expr.LHS
   469  		} else {
   470  			runInfo.expr = expr.RHS
   471  		}
   472  		runInfo.invokeExpr()
   473  
   474  	// NilCoalescingOpExpr
   475  	case *ast.NilCoalescingOpExpr:
   476  		// if left side has no error and is not nil, returns left side
   477  		// otherwise returns right side
   478  		runInfo.expr = expr.LHS
   479  		runInfo.invokeExpr()
   480  		if runInfo.err == nil {
   481  			if !isNil(runInfo.rv) {
   482  				return
   483  			}
   484  		} else {
   485  			runInfo.err = nil
   486  		}
   487  		runInfo.expr = expr.RHS
   488  		runInfo.invokeExpr()
   489  
   490  	// LenExpr
   491  	case *ast.LenExpr:
   492  		runInfo.expr = expr.Expr
   493  		runInfo.invokeExpr()
   494  		if runInfo.err != nil {
   495  			return
   496  		}
   497  
   498  		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
   499  			runInfo.rv = runInfo.rv.Elem()
   500  		}
   501  
   502  		switch runInfo.rv.Kind() {
   503  		case reflect.Slice, reflect.Array, reflect.Map, reflect.String, reflect.Chan:
   504  			runInfo.rv = reflect.ValueOf(int64(runInfo.rv.Len()))
   505  		default:
   506  			runInfo.err = newStringError(expr, "type "+runInfo.rv.Kind().String()+" does not support len operation")
   507  			runInfo.rv = nilValue
   508  		}
   509  
   510  	// ImportExpr
   511  	case *ast.ImportExpr:
   512  		runInfo.expr = expr.Name
   513  		runInfo.invokeExpr()
   514  		if runInfo.err != nil {
   515  			return
   516  		}
   517  		runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, stringType)
   518  		if runInfo.err != nil {
   519  			runInfo.rv = nilValue
   520  			return
   521  		}
   522  		name := runInfo.rv.String()
   523  		runInfo.rv = nilValue
   524  
   525  		methods, ok := env.Packages[name]
   526  		if !ok {
   527  			runInfo.err = newStringError(expr, "package not found: "+name)
   528  			return
   529  		}
   530  		var err error
   531  		pack := runInfo.env.NewEnv()
   532  		for methodName, methodValue := range methods {
   533  			err = pack.DefineValue(methodName, methodValue)
   534  			if err != nil {
   535  				runInfo.err = newStringError(expr, "import DefineValue error: "+err.Error())
   536  				return
   537  			}
   538  		}
   539  
   540  		types, ok := env.PackageTypes[name]
   541  		if ok {
   542  			for typeName, typeValue := range types {
   543  				err = pack.DefineReflectType(typeName, typeValue)
   544  				if err != nil {
   545  					runInfo.err = newStringError(expr, "import DefineReflectType error: "+err.Error())
   546  					return
   547  				}
   548  			}
   549  		}
   550  
   551  		runInfo.rv = reflect.ValueOf(pack)
   552  
   553  	// MakeExpr
   554  	case *ast.MakeExpr:
   555  		t := makeType(runInfo, expr.TypeData)
   556  		if runInfo.err != nil {
   557  			runInfo.rv = nilValue
   558  			return
   559  		}
   560  		if t == nil {
   561  			runInfo.err = newStringError(expr, "cannot make type nil")
   562  			runInfo.rv = nilValue
   563  			return
   564  		}
   565  
   566  		switch expr.TypeData.Kind {
   567  		case ast.TypeSlice:
   568  			aLen := 0
   569  			if expr.LenExpr != nil {
   570  				runInfo.expr = expr.LenExpr
   571  				runInfo.invokeExpr()
   572  				if runInfo.err != nil {
   573  					return
   574  				}
   575  				aLen = toInt(runInfo.rv)
   576  			}
   577  			cap := aLen
   578  			if expr.CapExpr != nil {
   579  				runInfo.expr = expr.CapExpr
   580  				runInfo.invokeExpr()
   581  				if runInfo.err != nil {
   582  					return
   583  				}
   584  				cap = toInt(runInfo.rv)
   585  			}
   586  			if aLen > cap {
   587  				runInfo.err = newStringError(expr, "make slice len > cap")
   588  				runInfo.rv = nilValue
   589  				return
   590  			}
   591  			runInfo.rv = reflect.MakeSlice(t, aLen, cap)
   592  			return
   593  		case ast.TypeChan:
   594  			aLen := 0
   595  			if expr.LenExpr != nil {
   596  				runInfo.expr = expr.LenExpr
   597  				runInfo.invokeExpr()
   598  				if runInfo.err != nil {
   599  					return
   600  				}
   601  				aLen = toInt(runInfo.rv)
   602  			}
   603  			runInfo.rv = reflect.MakeChan(t, aLen)
   604  			return
   605  		}
   606  
   607  		runInfo.rv, runInfo.err = makeValue(t)
   608  
   609  	// MakeTypeExpr
   610  	case *ast.MakeTypeExpr:
   611  		runInfo.expr = expr.Type
   612  		runInfo.invokeExpr()
   613  		if runInfo.err != nil {
   614  			return
   615  		}
   616  
   617  		// if expr.Name has a dot in it, it should give a syntax error, so no needs to check err
   618  		runInfo.env.DefineReflectType(expr.Name, runInfo.rv.Type())
   619  
   620  		runInfo.rv = reflect.ValueOf(runInfo.rv.Type())
   621  
   622  	// ChanExpr
   623  	case *ast.ChanExpr:
   624  		runInfo.expr = expr.RHS
   625  		runInfo.invokeExpr()
   626  		if runInfo.err != nil {
   627  			return
   628  		}
   629  		if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
   630  			runInfo.rv = runInfo.rv.Elem()
   631  		}
   632  
   633  		var lhs reflect.Value
   634  		rhs := runInfo.rv
   635  
   636  		if expr.LHS == nil {
   637  			// lhs is nil
   638  			if rhs.Kind() != reflect.Chan {
   639  				// rhs is not channel
   640  				runInfo.err = newStringError(expr, "receive from non-chan type "+rhs.Kind().String())
   641  				runInfo.rv = nilValue
   642  				return
   643  			}
   644  		} else {
   645  			// lhs is not nil
   646  			runInfo.expr = expr.LHS
   647  			runInfo.invokeExpr()
   648  			if runInfo.err != nil {
   649  				return
   650  			}
   651  			if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() {
   652  				runInfo.rv = runInfo.rv.Elem()
   653  			}
   654  			if runInfo.rv.Kind() != reflect.Chan {
   655  				// lhs is not channel
   656  				// lhs <- chan rhs or lhs <- rhs
   657  				runInfo.err = newStringError(expr, "send to non-chan type "+runInfo.rv.Kind().String())
   658  				runInfo.rv = nilValue
   659  				return
   660  			}
   661  			lhs = runInfo.rv
   662  		}
   663  
   664  		var chosen int
   665  		var ok bool
   666  
   667  		if rhs.Kind() == reflect.Chan {
   668  			// rhs is channel
   669  			// receive from rhs channel
   670  			cases := []reflect.SelectCase{{
   671  				Dir:  reflect.SelectRecv,
   672  				Chan: reflect.ValueOf(runInfo.ctx.Done()),
   673  			}, {
   674  				Dir:  reflect.SelectRecv,
   675  				Chan: rhs,
   676  			}}
   677  			chosen, runInfo.rv, ok = reflect.Select(cases)
   678  			if chosen == 0 {
   679  				runInfo.err = ErrInterrupt
   680  				runInfo.rv = nilValue
   681  				return
   682  			}
   683  			if !ok {
   684  				runInfo.rv = nilValue
   685  				return
   686  			}
   687  			rhs = runInfo.rv
   688  		}
   689  
   690  		if expr.LHS == nil {
   691  			// <- chan rhs is receive
   692  			return
   693  		}
   694  
   695  		// chan lhs <- chan rhs is receive & send
   696  		// or
   697  		// chan lhs <- rhs is send
   698  
   699  		runInfo.rv = nilValue
   700  		rhs, runInfo.err = convertReflectValueToType(rhs, lhs.Type().Elem())
   701  		if runInfo.err != nil {
   702  			runInfo.err = newStringError(expr, "cannot use type "+rhs.Type().String()+" as type "+lhs.Type().Elem().String()+" to send to chan")
   703  			return
   704  		}
   705  		// send rhs to lhs channel
   706  		cases := []reflect.SelectCase{{
   707  			Dir:  reflect.SelectRecv,
   708  			Chan: reflect.ValueOf(runInfo.ctx.Done()),
   709  		}, {
   710  			Dir:  reflect.SelectSend,
   711  			Chan: lhs,
   712  			Send: rhs,
   713  		}}
   714  		if !runInfo.options.Debug {
   715  			// captures panic
   716  			defer recoverFunc(runInfo)
   717  		}
   718  		chosen, _, _ = reflect.Select(cases)
   719  		if chosen == 0 {
   720  			runInfo.err = ErrInterrupt
   721  		}
   722  
   723  	// FuncExpr
   724  	case *ast.FuncExpr:
   725  		runInfo.expr = expr
   726  		runInfo.funcExpr()
   727  
   728  	// AnonCallExpr
   729  	case *ast.AnonCallExpr:
   730  		runInfo.expr = expr
   731  		runInfo.anonCallExpr()
   732  
   733  	// CallExpr
   734  	case *ast.CallExpr:
   735  		runInfo.expr = expr
   736  		runInfo.callExpr()
   737  
   738  	// IncludeExpr
   739  	case *ast.IncludeExpr:
   740  		runInfo.expr = expr.ItemExpr
   741  		runInfo.invokeExpr()
   742  		if runInfo.err != nil {
   743  			return
   744  		}
   745  		itemExpr := runInfo.rv
   746  
   747  		runInfo.expr = expr.ListExpr
   748  		runInfo.invokeExpr()
   749  		if runInfo.err != nil {
   750  			return
   751  		}
   752  
   753  		if runInfo.rv.Kind() != reflect.Slice && runInfo.rv.Kind() != reflect.Array {
   754  			runInfo.err = newStringError(expr, "second argument must be slice or array; but have "+runInfo.rv.Kind().String())
   755  			runInfo.rv = nilValue
   756  			return
   757  		}
   758  
   759  		for i := 0; i < runInfo.rv.Len(); i++ {
   760  			if equal(itemExpr, runInfo.rv.Index(i)) {
   761  				runInfo.rv = trueValue
   762  				return
   763  			}
   764  		}
   765  		runInfo.rv = falseValue
   766  
   767  	default:
   768  		runInfo.err = newStringError(expr, "unknown expression")
   769  		runInfo.rv = nilValue
   770  	}
   771  
   772  }