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 }