github.com/mattn/anko@v0.1.10/vm/vmStmt.go (about) 1 package vm 2 3 import ( 4 "context" 5 "fmt" 6 "reflect" 7 8 "github.com/mattn/anko/ast" 9 "github.com/mattn/anko/env" 10 "github.com/mattn/anko/parser" 11 ) 12 13 // Execute parses script and executes in the specified environment. 14 func Execute(env *env.Env, options *Options, script string) (interface{}, error) { 15 stmt, err := parser.ParseSrc(script) 16 if err != nil { 17 return nilValue, err 18 } 19 20 return RunContext(context.Background(), env, options, stmt) 21 } 22 23 // ExecuteContext parses script and executes in the specified environment with context. 24 func ExecuteContext(ctx context.Context, env *env.Env, options *Options, script string) (interface{}, error) { 25 stmt, err := parser.ParseSrc(script) 26 if err != nil { 27 return nilValue, err 28 } 29 30 return RunContext(ctx, env, options, stmt) 31 } 32 33 // Run executes statement in the specified environment. 34 func Run(env *env.Env, options *Options, stmt ast.Stmt) (interface{}, error) { 35 return RunContext(context.Background(), env, options, stmt) 36 } 37 38 // RunContext executes statement in the specified environment with context. 39 func RunContext(ctx context.Context, env *env.Env, options *Options, stmt ast.Stmt) (interface{}, error) { 40 runInfo := runInfoStruct{ctx: ctx, env: env, options: options, stmt: stmt, rv: nilValue} 41 if runInfo.options == nil { 42 runInfo.options = &Options{} 43 } 44 runInfo.runSingleStmt() 45 if runInfo.err == ErrReturn { 46 runInfo.err = nil 47 } 48 return runInfo.rv.Interface(), runInfo.err 49 } 50 51 // runSingleStmt executes statement in the specified environment with context. 52 func (runInfo *runInfoStruct) runSingleStmt() { 53 select { 54 case <-runInfo.ctx.Done(): 55 runInfo.rv = nilValue 56 runInfo.err = ErrInterrupt 57 return 58 default: 59 } 60 61 switch stmt := runInfo.stmt.(type) { 62 63 // nil 64 case nil: 65 66 // StmtsStmt 67 case *ast.StmtsStmt: 68 for _, stmt := range stmt.Stmts { 69 switch stmt.(type) { 70 case *ast.BreakStmt: 71 runInfo.err = ErrBreak 72 return 73 case *ast.ContinueStmt: 74 runInfo.err = ErrContinue 75 return 76 case *ast.ReturnStmt: 77 runInfo.stmt = stmt 78 runInfo.runSingleStmt() 79 if runInfo.err != nil { 80 return 81 } 82 runInfo.err = ErrReturn 83 return 84 default: 85 runInfo.stmt = stmt 86 runInfo.runSingleStmt() 87 if runInfo.err != nil { 88 return 89 } 90 } 91 } 92 93 // ExprStmt 94 case *ast.ExprStmt: 95 runInfo.expr = stmt.Expr 96 runInfo.invokeExpr() 97 98 // VarStmt 99 case *ast.VarStmt: 100 // get right side expression values 101 rvs := make([]reflect.Value, len(stmt.Exprs)) 102 var i int 103 for i, runInfo.expr = range stmt.Exprs { 104 runInfo.invokeExpr() 105 if runInfo.err != nil { 106 return 107 } 108 if env, ok := runInfo.rv.Interface().(*env.Env); ok { 109 rvs[i] = reflect.ValueOf(env.DeepCopy()) 110 } else { 111 rvs[i] = runInfo.rv 112 } 113 } 114 115 if len(rvs) == 1 && len(stmt.Names) > 1 { 116 // only one right side value but many left side names 117 value := rvs[0] 118 if value.Kind() == reflect.Interface && !value.IsNil() { 119 value = value.Elem() 120 } 121 if (value.Kind() == reflect.Slice || value.Kind() == reflect.Array) && value.Len() > 0 { 122 // value is slice/array, add each value to left side names 123 for i := 0; i < value.Len() && i < len(stmt.Names); i++ { 124 runInfo.env.DefineValue(stmt.Names[i], value.Index(i)) 125 } 126 // return last value of slice/array 127 runInfo.rv = value.Index(value.Len() - 1) 128 return 129 } 130 } 131 132 // define all names with right side values 133 for i = 0; i < len(rvs) && i < len(stmt.Names); i++ { 134 runInfo.env.DefineValue(stmt.Names[i], rvs[i]) 135 } 136 137 // return last right side value 138 runInfo.rv = rvs[len(rvs)-1] 139 140 // LetsStmt 141 case *ast.LetsStmt: 142 // get right side expression values 143 rvs := make([]reflect.Value, len(stmt.RHSS)) 144 var i int 145 for i, runInfo.expr = range stmt.RHSS { 146 runInfo.invokeExpr() 147 if runInfo.err != nil { 148 return 149 } 150 if env, ok := runInfo.rv.Interface().(*env.Env); ok { 151 rvs[i] = reflect.ValueOf(env.DeepCopy()) 152 } else { 153 rvs[i] = runInfo.rv 154 } 155 } 156 157 if len(rvs) == 1 && len(stmt.LHSS) > 1 { 158 // only one right side value but many left side expressions 159 value := rvs[0] 160 if value.Kind() == reflect.Interface && !value.IsNil() { 161 value = value.Elem() 162 } 163 if (value.Kind() == reflect.Slice || value.Kind() == reflect.Array) && value.Len() > 0 { 164 // value is slice/array, add each value to left side expression 165 for i := 0; i < value.Len() && i < len(stmt.LHSS); i++ { 166 runInfo.rv = value.Index(i) 167 runInfo.expr = stmt.LHSS[i] 168 runInfo.invokeLetExpr() 169 if runInfo.err != nil { 170 return 171 } 172 } 173 // return last value of slice/array 174 runInfo.rv = value.Index(value.Len() - 1) 175 return 176 } 177 } 178 179 // invoke all left side expressions with right side values 180 for i = 0; i < len(rvs) && i < len(stmt.LHSS); i++ { 181 value := rvs[i] 182 if value.Kind() == reflect.Interface && !value.IsNil() { 183 value = value.Elem() 184 } 185 runInfo.rv = value 186 runInfo.expr = stmt.LHSS[i] 187 runInfo.invokeLetExpr() 188 if runInfo.err != nil { 189 return 190 } 191 } 192 193 // return last right side value 194 runInfo.rv = rvs[len(rvs)-1] 195 196 // LetMapItemStmt 197 case *ast.LetMapItemStmt: 198 runInfo.expr = stmt.RHS 199 runInfo.invokeExpr() 200 if runInfo.err != nil { 201 return 202 } 203 var rvs []reflect.Value 204 if isNil(runInfo.rv) { 205 rvs = []reflect.Value{nilValue, falseValue} 206 } else { 207 rvs = []reflect.Value{runInfo.rv, trueValue} 208 } 209 var i int 210 for i, runInfo.expr = range stmt.LHSS { 211 runInfo.rv = rvs[i] 212 if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() { 213 runInfo.rv = runInfo.rv.Elem() 214 } 215 runInfo.invokeLetExpr() 216 if runInfo.err != nil { 217 return 218 } 219 } 220 runInfo.rv = rvs[0] 221 222 // IfStmt 223 case *ast.IfStmt: 224 // if 225 runInfo.expr = stmt.If 226 runInfo.invokeExpr() 227 if runInfo.err != nil { 228 return 229 } 230 231 env := runInfo.env 232 233 if toBool(runInfo.rv) { 234 // then 235 runInfo.rv = nilValue 236 runInfo.stmt = stmt.Then 237 runInfo.env = env.NewEnv() 238 runInfo.runSingleStmt() 239 runInfo.env = env 240 return 241 } 242 243 for _, statement := range stmt.ElseIf { 244 elseIf := statement.(*ast.IfStmt) 245 246 // else if - if 247 runInfo.env = env.NewEnv() 248 runInfo.expr = elseIf.If 249 runInfo.invokeExpr() 250 if runInfo.err != nil { 251 runInfo.env = env 252 return 253 } 254 255 if !toBool(runInfo.rv) { 256 continue 257 } 258 259 // else if - then 260 runInfo.rv = nilValue 261 runInfo.stmt = elseIf.Then 262 runInfo.env = env.NewEnv() 263 runInfo.runSingleStmt() 264 runInfo.env = env 265 return 266 } 267 268 if stmt.Else != nil { 269 // else 270 runInfo.rv = nilValue 271 runInfo.stmt = stmt.Else 272 runInfo.env = env.NewEnv() 273 runInfo.runSingleStmt() 274 } 275 276 runInfo.env = env 277 278 // TryStmt 279 case *ast.TryStmt: 280 // only the try statement will ignore any error except ErrInterrupt 281 // all other parts will return the error 282 283 env := runInfo.env 284 runInfo.env = env.NewEnv() 285 286 runInfo.stmt = stmt.Try 287 runInfo.runSingleStmt() 288 289 if runInfo.err != nil { 290 if runInfo.err == ErrInterrupt { 291 runInfo.env = env 292 return 293 } 294 295 // Catch 296 runInfo.stmt = stmt.Catch 297 if stmt.Var != "" { 298 runInfo.env.DefineValue(stmt.Var, reflect.ValueOf(runInfo.err)) 299 } 300 runInfo.err = nil 301 runInfo.runSingleStmt() 302 if runInfo.err != nil { 303 runInfo.env = env 304 return 305 } 306 } 307 308 if stmt.Finally != nil { 309 // Finally 310 runInfo.stmt = stmt.Finally 311 runInfo.runSingleStmt() 312 } 313 314 runInfo.env = env 315 316 // LoopStmt 317 case *ast.LoopStmt: 318 env := runInfo.env 319 runInfo.env = env.NewEnv() 320 321 for { 322 select { 323 case <-runInfo.ctx.Done(): 324 runInfo.err = ErrInterrupt 325 runInfo.rv = nilValue 326 runInfo.env = env 327 return 328 default: 329 } 330 331 if stmt.Expr != nil { 332 runInfo.expr = stmt.Expr 333 runInfo.invokeExpr() 334 if runInfo.err != nil { 335 break 336 } 337 if !toBool(runInfo.rv) { 338 break 339 } 340 } 341 342 runInfo.stmt = stmt.Stmt 343 runInfo.runSingleStmt() 344 if runInfo.err != nil { 345 if runInfo.err == ErrContinue { 346 runInfo.err = nil 347 continue 348 } 349 if runInfo.err == ErrReturn { 350 runInfo.env = env 351 return 352 } 353 if runInfo.err == ErrBreak { 354 runInfo.err = nil 355 } 356 break 357 } 358 } 359 360 runInfo.rv = nilValue 361 runInfo.env = env 362 363 // ForStmt 364 case *ast.ForStmt: 365 runInfo.expr = stmt.Value 366 runInfo.invokeExpr() 367 value := runInfo.rv 368 if runInfo.err != nil { 369 return 370 } 371 if value.Kind() == reflect.Interface && !value.IsNil() { 372 value = value.Elem() 373 } 374 375 env := runInfo.env 376 runInfo.env = env.NewEnv() 377 378 switch value.Kind() { 379 case reflect.Slice, reflect.Array: 380 for i := 0; i < value.Len(); i++ { 381 select { 382 case <-runInfo.ctx.Done(): 383 runInfo.err = ErrInterrupt 384 runInfo.rv = nilValue 385 runInfo.env = env 386 return 387 default: 388 } 389 390 iv := value.Index(i) 391 if iv.Kind() == reflect.Interface && !iv.IsNil() { 392 iv = iv.Elem() 393 } 394 if iv.Kind() == reflect.Ptr { 395 iv = iv.Elem() 396 } 397 runInfo.env.DefineValue(stmt.Vars[0], iv) 398 399 runInfo.stmt = stmt.Stmt 400 runInfo.runSingleStmt() 401 if runInfo.err != nil { 402 if runInfo.err == ErrContinue { 403 runInfo.err = nil 404 continue 405 } 406 if runInfo.err == ErrReturn { 407 runInfo.env = env 408 return 409 } 410 if runInfo.err == ErrBreak { 411 runInfo.err = nil 412 } 413 break 414 } 415 } 416 runInfo.rv = nilValue 417 runInfo.env = env 418 419 case reflect.Map: 420 keys := value.MapKeys() 421 for i := 0; i < len(keys); i++ { 422 select { 423 case <-runInfo.ctx.Done(): 424 runInfo.err = ErrInterrupt 425 runInfo.rv = nilValue 426 runInfo.env = env 427 return 428 default: 429 } 430 431 runInfo.env.DefineValue(stmt.Vars[0], keys[i]) 432 433 if len(stmt.Vars) > 1 { 434 runInfo.env.DefineValue(stmt.Vars[1], value.MapIndex(keys[i])) 435 } 436 437 runInfo.stmt = stmt.Stmt 438 runInfo.runSingleStmt() 439 if runInfo.err != nil { 440 if runInfo.err == ErrContinue { 441 runInfo.err = nil 442 continue 443 } 444 if runInfo.err == ErrReturn { 445 runInfo.env = env 446 return 447 } 448 if runInfo.err == ErrBreak { 449 runInfo.err = nil 450 } 451 break 452 } 453 } 454 runInfo.rv = nilValue 455 runInfo.env = env 456 457 case reflect.Chan: 458 var chosen int 459 var ok bool 460 for { 461 cases := []reflect.SelectCase{{ 462 Dir: reflect.SelectRecv, 463 Chan: reflect.ValueOf(runInfo.ctx.Done()), 464 }, { 465 Dir: reflect.SelectRecv, 466 Chan: value, 467 }} 468 chosen, runInfo.rv, ok = reflect.Select(cases) 469 if chosen == 0 { 470 runInfo.err = ErrInterrupt 471 runInfo.rv = nilValue 472 break 473 } 474 if !ok { 475 break 476 } 477 478 if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() { 479 runInfo.rv = runInfo.rv.Elem() 480 } 481 if runInfo.rv.Kind() == reflect.Ptr { 482 runInfo.rv = runInfo.rv.Elem() 483 } 484 485 runInfo.env.DefineValue(stmt.Vars[0], runInfo.rv) 486 487 runInfo.stmt = stmt.Stmt 488 runInfo.runSingleStmt() 489 if runInfo.err != nil { 490 if runInfo.err == ErrContinue { 491 runInfo.err = nil 492 continue 493 } 494 if runInfo.err == ErrReturn { 495 runInfo.env = env 496 return 497 } 498 if runInfo.err == ErrBreak { 499 runInfo.err = nil 500 } 501 break 502 } 503 } 504 runInfo.rv = nilValue 505 runInfo.env = env 506 507 default: 508 runInfo.err = newStringError(stmt, "for cannot loop over type "+value.Kind().String()) 509 runInfo.rv = nilValue 510 runInfo.env = env 511 } 512 513 // CForStmt 514 case *ast.CForStmt: 515 env := runInfo.env 516 runInfo.env = env.NewEnv() 517 518 if stmt.Stmt1 != nil { 519 runInfo.stmt = stmt.Stmt1 520 runInfo.runSingleStmt() 521 if runInfo.err != nil { 522 runInfo.env = env 523 return 524 } 525 } 526 527 for { 528 select { 529 case <-runInfo.ctx.Done(): 530 runInfo.err = ErrInterrupt 531 runInfo.rv = nilValue 532 runInfo.env = env 533 return 534 default: 535 } 536 537 if stmt.Expr2 != nil { 538 runInfo.expr = stmt.Expr2 539 runInfo.invokeExpr() 540 if runInfo.err != nil { 541 break 542 } 543 if !toBool(runInfo.rv) { 544 break 545 } 546 } 547 548 runInfo.stmt = stmt.Stmt 549 runInfo.runSingleStmt() 550 if runInfo.err == ErrContinue { 551 runInfo.err = nil 552 } 553 if runInfo.err != nil { 554 if runInfo.err == ErrReturn { 555 runInfo.env = env 556 return 557 } 558 if runInfo.err == ErrBreak { 559 runInfo.err = nil 560 } 561 break 562 } 563 564 if stmt.Expr3 != nil { 565 runInfo.expr = stmt.Expr3 566 runInfo.invokeExpr() 567 if runInfo.err != nil { 568 break 569 } 570 } 571 } 572 runInfo.rv = nilValue 573 runInfo.env = env 574 575 // ReturnStmt 576 case *ast.ReturnStmt: 577 switch len(stmt.Exprs) { 578 case 0: 579 runInfo.rv = nilValue 580 return 581 case 1: 582 runInfo.expr = stmt.Exprs[0] 583 runInfo.invokeExpr() 584 return 585 } 586 rvs := make([]interface{}, len(stmt.Exprs)) 587 var i int 588 for i, runInfo.expr = range stmt.Exprs { 589 runInfo.invokeExpr() 590 if runInfo.err != nil { 591 return 592 } 593 rvs[i] = runInfo.rv.Interface() 594 } 595 runInfo.rv = reflect.ValueOf(rvs) 596 597 // ThrowStmt 598 case *ast.ThrowStmt: 599 runInfo.expr = stmt.Expr 600 runInfo.invokeExpr() 601 if runInfo.err != nil { 602 return 603 } 604 runInfo.err = newStringError(stmt, fmt.Sprint(runInfo.rv.Interface())) 605 606 // ModuleStmt 607 case *ast.ModuleStmt: 608 e := runInfo.env 609 runInfo.env, runInfo.err = e.NewModule(stmt.Name) 610 if runInfo.err != nil { 611 return 612 } 613 runInfo.stmt = stmt.Stmt 614 runInfo.runSingleStmt() 615 runInfo.env = e 616 if runInfo.err != nil { 617 return 618 } 619 runInfo.rv = nilValue 620 621 // SwitchStmt 622 case *ast.SwitchStmt: 623 env := runInfo.env 624 runInfo.env = env.NewEnv() 625 626 runInfo.expr = stmt.Expr 627 runInfo.invokeExpr() 628 if runInfo.err != nil { 629 runInfo.env = env 630 return 631 } 632 value := runInfo.rv 633 634 for _, switchCaseStmt := range stmt.Cases { 635 caseStmt := switchCaseStmt.(*ast.SwitchCaseStmt) 636 for _, runInfo.expr = range caseStmt.Exprs { 637 runInfo.invokeExpr() 638 if runInfo.err != nil { 639 runInfo.env = env 640 return 641 } 642 if equal(runInfo.rv, value) { 643 runInfo.stmt = caseStmt.Stmt 644 runInfo.runSingleStmt() 645 runInfo.env = env 646 return 647 } 648 } 649 } 650 651 if stmt.Default == nil { 652 runInfo.rv = nilValue 653 } else { 654 runInfo.stmt = stmt.Default 655 runInfo.runSingleStmt() 656 } 657 658 runInfo.env = env 659 660 // GoroutineStmt 661 case *ast.GoroutineStmt: 662 runInfo.expr = stmt.Expr 663 runInfo.invokeExpr() 664 665 // DeleteStmt 666 case *ast.DeleteStmt: 667 runInfo.expr = stmt.Item 668 runInfo.invokeExpr() 669 if runInfo.err != nil { 670 return 671 } 672 item := runInfo.rv 673 674 if stmt.Key != nil { 675 runInfo.expr = stmt.Key 676 runInfo.invokeExpr() 677 if runInfo.err != nil { 678 return 679 } 680 } 681 682 if item.Kind() == reflect.Interface && !item.IsNil() { 683 item = item.Elem() 684 } 685 686 switch item.Kind() { 687 case reflect.String: 688 if stmt.Key != nil && runInfo.rv.Kind() == reflect.Bool && runInfo.rv.Bool() { 689 runInfo.env.DeleteGlobal(item.String()) 690 runInfo.rv = nilValue 691 return 692 } 693 runInfo.env.Delete(item.String()) 694 runInfo.rv = nilValue 695 696 case reflect.Map: 697 if stmt.Key == nil { 698 runInfo.err = newStringError(stmt, "second argument to delete cannot be nil for map") 699 runInfo.rv = nilValue 700 return 701 } 702 if item.IsNil() { 703 runInfo.rv = nilValue 704 return 705 } 706 runInfo.rv, runInfo.err = convertReflectValueToType(runInfo.rv, item.Type().Key()) 707 if runInfo.err != nil { 708 runInfo.err = newStringError(stmt, "cannot use type "+item.Type().Key().String()+" as type "+runInfo.rv.Type().String()+" in delete") 709 runInfo.rv = nilValue 710 return 711 } 712 item.SetMapIndex(runInfo.rv, reflect.Value{}) 713 runInfo.rv = nilValue 714 default: 715 runInfo.err = newStringError(stmt, "first argument to delete cannot be type "+item.Kind().String()) 716 runInfo.rv = nilValue 717 } 718 719 // CloseStmt 720 case *ast.CloseStmt: 721 runInfo.expr = stmt.Expr 722 runInfo.invokeExpr() 723 if runInfo.err != nil { 724 return 725 } 726 if runInfo.rv.Kind() == reflect.Chan { 727 runInfo.rv.Close() 728 runInfo.rv = nilValue 729 return 730 } 731 runInfo.err = newStringError(stmt, "type cannot be "+runInfo.rv.Kind().String()+" for close") 732 runInfo.rv = nilValue 733 734 // ChanStmt 735 case *ast.ChanStmt: 736 runInfo.expr = stmt.RHS 737 runInfo.invokeExpr() 738 if runInfo.err != nil { 739 return 740 } 741 if runInfo.rv.Kind() == reflect.Interface && !runInfo.rv.IsNil() { 742 runInfo.rv = runInfo.rv.Elem() 743 } 744 745 if runInfo.rv.Kind() != reflect.Chan { 746 // rhs is not channel 747 runInfo.err = newStringError(stmt, "receive from non-chan type "+runInfo.rv.Kind().String()) 748 runInfo.rv = nilValue 749 return 750 } 751 752 // rhs is channel 753 // receive from rhs channel 754 rhs := runInfo.rv 755 cases := []reflect.SelectCase{{ 756 Dir: reflect.SelectRecv, 757 Chan: reflect.ValueOf(runInfo.ctx.Done()), 758 }, { 759 Dir: reflect.SelectRecv, 760 Chan: rhs, 761 }} 762 var chosen int 763 var ok bool 764 chosen, runInfo.rv, ok = reflect.Select(cases) 765 if chosen == 0 { 766 runInfo.err = ErrInterrupt 767 runInfo.rv = nilValue 768 return 769 } 770 771 rhs = runInfo.rv // store rv in rhs temporarily 772 773 if stmt.OkExpr != nil { 774 // set ok to OkExpr 775 if ok { 776 runInfo.rv = trueValue 777 } else { 778 runInfo.rv = falseValue 779 } 780 runInfo.expr = stmt.OkExpr 781 runInfo.invokeLetExpr() 782 // TODO: ok to ignore error? 783 } 784 785 if ok { 786 // set rv to lhs 787 runInfo.rv = rhs 788 runInfo.expr = stmt.LHS 789 runInfo.invokeLetExpr() 790 if runInfo.err != nil { 791 return 792 } 793 } else { 794 runInfo.rv = nilValue 795 } 796 797 // default 798 default: 799 runInfo.err = newStringError(stmt, "unknown statement") 800 runInfo.rv = nilValue 801 } 802 803 }