code: func (v *evalVisitor) evalField(ctx reflect.Value, fieldName string, exprRoot bool) reflect.Value {
  	result := zero
  
  	ctx, _ = indirect(ctx)
  	if !ctx.IsValid() {
  		return result
  	}
  
  	// check if this is a method call
  	result, isMeth := v.evalMethod(ctx, fieldName, exprRoot)
  	if !isMeth {
  		switch ctx.Kind() {
  		case reflect.Struct:
  			// example: firstName => FirstName
  			expFieldName := strings.Title(fieldName)
  
  			// check if struct have this field and that it is exported
  			if tField, ok := ctx.Type().FieldByName(expFieldName); ok && (tField.PkgPath == "") {
  				// struct field
  				result = ctx.FieldByIndex(tField.Index)
  				break
  			}
  
  			// attempts to find template variable name as a struct tag
  			result = v.evalStructTag(ctx, fieldName)
  		case reflect.Map:
  			nameVal := reflect.ValueOf(fieldName)
  			if nameVal.Type().AssignableTo(ctx.Type().Key()) {
  				// map key
  				result = ctx.MapIndex(nameVal)
  			}
  		case reflect.Array, reflect.Slice:
  			if i, err := strconv.Atoi(fieldName); (err == nil) && (i < ctx.Len()) {
  				result = ctx.Index(i)
  			}
  		}
  	}
  
  	// check if result is a function
  	result, _ = indirect(result)
  	if result.Kind() == reflect.Func {
  		result = v.evalFieldFunc(fieldName, result, exprRoot)
  	}
  
  	return result
  }
docs: // evalField evaluates field with given context