core.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Package core implements core interface for anko script.
  2. package core
  3. import (
  4. "fmt"
  5. "io/ioutil"
  6. "reflect"
  7. "github.com/mattn/anko/env"
  8. "github.com/mattn/anko/parser"
  9. "github.com/mattn/anko/vm"
  10. )
  11. // Import defines core language builtins - keys, range, println, etc.
  12. func Import(e *env.Env) *env.Env {
  13. e.Define("keys", func(v interface{}) []interface{} {
  14. rv := reflect.ValueOf(v)
  15. if rv.Kind() == reflect.Interface {
  16. rv = rv.Elem()
  17. }
  18. mapKeysValue := rv.MapKeys()
  19. mapKeys := make([]interface{}, len(mapKeysValue))
  20. for i := 0; i < len(mapKeysValue); i++ {
  21. mapKeys[i] = mapKeysValue[i].Interface()
  22. }
  23. return mapKeys
  24. })
  25. e.Define("range", func(args ...int64) []int64 {
  26. var start, stop int64
  27. var step int64 = 1
  28. switch len(args) {
  29. case 0:
  30. panic("range expected at least 1 argument, got 0")
  31. case 1:
  32. stop = args[0]
  33. case 2:
  34. start = args[0]
  35. stop = args[1]
  36. case 3:
  37. start = args[0]
  38. stop = args[1]
  39. step = args[2]
  40. if step == 0 {
  41. panic("range argument 3 must not be zero")
  42. }
  43. default:
  44. panic(fmt.Sprintf("range expected at most 3 arguments, got %d", len(args)))
  45. }
  46. arr := []int64{}
  47. for i := start; (step > 0 && i < stop) || (step < 0 && i > stop); i += step {
  48. arr = append(arr, i)
  49. }
  50. return arr
  51. })
  52. e.Define("typeOf", func(v interface{}) string {
  53. return reflect.TypeOf(v).String()
  54. })
  55. e.Define("kindOf", func(v interface{}) string {
  56. typeOf := reflect.TypeOf(v)
  57. if typeOf == nil {
  58. return "nil"
  59. }
  60. return typeOf.Kind().String()
  61. })
  62. e.Define("defined", func(s string) bool {
  63. _, err := e.Get(s)
  64. return err == nil
  65. })
  66. e.Define("load", func(s string) interface{} {
  67. body, err := ioutil.ReadFile(s)
  68. if err != nil {
  69. panic(err)
  70. }
  71. scanner := new(parser.Scanner)
  72. scanner.Init(string(body))
  73. stmts, err := parser.Parse(scanner)
  74. if err != nil {
  75. if pe, ok := err.(*parser.Error); ok {
  76. pe.Filename = s
  77. panic(pe)
  78. }
  79. panic(err)
  80. }
  81. rv, err := vm.Run(e, nil, stmts)
  82. if err != nil {
  83. panic(err)
  84. }
  85. return rv
  86. })
  87. e.Define("print", fmt.Print)
  88. e.Define("println", fmt.Println)
  89. e.Define("printf", fmt.Printf)
  90. ImportToX(e)
  91. return e
  92. }