tengo.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. package tengo
  2. import (
  3. "errors"
  4. "fmt"
  5. "strconv"
  6. "time"
  7. )
  8. var (
  9. // MaxStringLen is the maximum byte-length for string value. Note this
  10. // limit applies to all compiler/VM instances in the process.
  11. MaxStringLen = 2147483647
  12. // MaxBytesLen is the maximum length for bytes value. Note this limit
  13. // applies to all compiler/VM instances in the process.
  14. MaxBytesLen = 2147483647
  15. )
  16. const (
  17. // GlobalsSize is the maximum number of global variables for a VM.
  18. GlobalsSize = 1024
  19. // StackSize is the maximum stack size for a VM.
  20. StackSize = 2048
  21. // MaxFrames is the maximum number of function frames for a VM.
  22. MaxFrames = 1024
  23. // SourceFileExtDefault is the default extension for source files.
  24. SourceFileExtDefault = ".tengo"
  25. )
  26. // CallableFunc is a function signature for the callable functions.
  27. type CallableFunc = func(args ...Object) (ret Object, err error)
  28. // CountObjects returns the number of objects that a given object o contains.
  29. // For scalar value types, it will always be 1. For compound value types,
  30. // this will include its elements and all of their elements recursively.
  31. func CountObjects(o Object) (c int) {
  32. c = 1
  33. switch o := o.(type) {
  34. case *Array:
  35. for _, v := range o.Value {
  36. c += CountObjects(v)
  37. }
  38. case *ImmutableArray:
  39. for _, v := range o.Value {
  40. c += CountObjects(v)
  41. }
  42. case *Map:
  43. for _, v := range o.Value {
  44. c += CountObjects(v)
  45. }
  46. case *ImmutableMap:
  47. for _, v := range o.Value {
  48. c += CountObjects(v)
  49. }
  50. case *Error:
  51. c += CountObjects(o.Value)
  52. }
  53. return
  54. }
  55. // ToString will try to convert object o to string value.
  56. func ToString(o Object) (v string, ok bool) {
  57. if o == UndefinedValue {
  58. return
  59. }
  60. ok = true
  61. if str, isStr := o.(*String); isStr {
  62. v = str.Value
  63. } else {
  64. v = o.String()
  65. }
  66. return
  67. }
  68. // ToInt will try to convert object o to int value.
  69. func ToInt(o Object) (v int, ok bool) {
  70. switch o := o.(type) {
  71. case *Int:
  72. v = int(o.Value)
  73. ok = true
  74. case *Float:
  75. v = int(o.Value)
  76. ok = true
  77. case *Char:
  78. v = int(o.Value)
  79. ok = true
  80. case *Bool:
  81. if o == TrueValue {
  82. v = 1
  83. }
  84. ok = true
  85. case *String:
  86. c, err := strconv.ParseInt(o.Value, 10, 64)
  87. if err == nil {
  88. v = int(c)
  89. ok = true
  90. }
  91. }
  92. return
  93. }
  94. // ToInt64 will try to convert object o to int64 value.
  95. func ToInt64(o Object) (v int64, ok bool) {
  96. switch o := o.(type) {
  97. case *Int:
  98. v = o.Value
  99. ok = true
  100. case *Float:
  101. v = int64(o.Value)
  102. ok = true
  103. case *Char:
  104. v = int64(o.Value)
  105. ok = true
  106. case *Bool:
  107. if o == TrueValue {
  108. v = 1
  109. }
  110. ok = true
  111. case *String:
  112. c, err := strconv.ParseInt(o.Value, 10, 64)
  113. if err == nil {
  114. v = c
  115. ok = true
  116. }
  117. }
  118. return
  119. }
  120. // ToFloat64 will try to convert object o to float64 value.
  121. func ToFloat64(o Object) (v float64, ok bool) {
  122. switch o := o.(type) {
  123. case *Int:
  124. v = float64(o.Value)
  125. ok = true
  126. case *Float:
  127. v = o.Value
  128. ok = true
  129. case *String:
  130. c, err := strconv.ParseFloat(o.Value, 64)
  131. if err == nil {
  132. v = c
  133. ok = true
  134. }
  135. }
  136. return
  137. }
  138. // ToBool will try to convert object o to bool value.
  139. func ToBool(o Object) (v bool, ok bool) {
  140. ok = true
  141. v = !o.IsFalsy()
  142. return
  143. }
  144. // ToRune will try to convert object o to rune value.
  145. func ToRune(o Object) (v rune, ok bool) {
  146. switch o := o.(type) {
  147. case *Int:
  148. v = rune(o.Value)
  149. ok = true
  150. case *Char:
  151. v = o.Value
  152. ok = true
  153. }
  154. return
  155. }
  156. // ToByteSlice will try to convert object o to []byte value.
  157. func ToByteSlice(o Object) (v []byte, ok bool) {
  158. switch o := o.(type) {
  159. case *Bytes:
  160. v = o.Value
  161. ok = true
  162. case *String:
  163. v = []byte(o.Value)
  164. ok = true
  165. }
  166. return
  167. }
  168. // ToTime will try to convert object o to time.Time value.
  169. func ToTime(o Object) (v time.Time, ok bool) {
  170. switch o := o.(type) {
  171. case *Time:
  172. v = o.Value
  173. ok = true
  174. case *Int:
  175. v = time.Unix(o.Value, 0)
  176. ok = true
  177. }
  178. return
  179. }
  180. // ToInterface attempts to convert an object o to an interface{} value
  181. func ToInterface(o Object) (res interface{}) {
  182. switch o := o.(type) {
  183. case *Int:
  184. res = o.Value
  185. case *String:
  186. res = o.Value
  187. case *Float:
  188. res = o.Value
  189. case *Bool:
  190. res = o == TrueValue
  191. case *Char:
  192. res = o.Value
  193. case *Bytes:
  194. res = o.Value
  195. case *Array:
  196. res = make([]interface{}, len(o.Value))
  197. for i, val := range o.Value {
  198. res.([]interface{})[i] = ToInterface(val)
  199. }
  200. case *ImmutableArray:
  201. res = make([]interface{}, len(o.Value))
  202. for i, val := range o.Value {
  203. res.([]interface{})[i] = ToInterface(val)
  204. }
  205. case *Map:
  206. res = make(map[string]interface{})
  207. for key, v := range o.Value {
  208. res.(map[string]interface{})[key] = ToInterface(v)
  209. }
  210. case *ImmutableMap:
  211. res = make(map[string]interface{})
  212. for key, v := range o.Value {
  213. res.(map[string]interface{})[key] = ToInterface(v)
  214. }
  215. case *Time:
  216. res = o.Value
  217. case *Error:
  218. res = errors.New(o.String())
  219. case *Undefined:
  220. res = nil
  221. case Object:
  222. return o
  223. }
  224. return
  225. }
  226. // FromInterface will attempt to convert an interface{} v to a Tengo Object
  227. func FromInterface(v interface{}) (Object, error) {
  228. switch v := v.(type) {
  229. case nil:
  230. return UndefinedValue, nil
  231. case string:
  232. if len(v) > MaxStringLen {
  233. return nil, ErrStringLimit
  234. }
  235. return &String{Value: v}, nil
  236. case int64:
  237. return &Int{Value: v}, nil
  238. case int:
  239. return &Int{Value: int64(v)}, nil
  240. case bool:
  241. if v {
  242. return TrueValue, nil
  243. }
  244. return FalseValue, nil
  245. case rune:
  246. return &Char{Value: v}, nil
  247. case byte:
  248. return &Char{Value: rune(v)}, nil
  249. case float64:
  250. return &Float{Value: v}, nil
  251. case []byte:
  252. if len(v) > MaxBytesLen {
  253. return nil, ErrBytesLimit
  254. }
  255. return &Bytes{Value: v}, nil
  256. case error:
  257. return &Error{Value: &String{Value: v.Error()}}, nil
  258. case map[string]Object:
  259. return &Map{Value: v}, nil
  260. case map[string]interface{}:
  261. kv := make(map[string]Object)
  262. for vk, vv := range v {
  263. vo, err := FromInterface(vv)
  264. if err != nil {
  265. return nil, err
  266. }
  267. kv[vk] = vo
  268. }
  269. return &Map{Value: kv}, nil
  270. case []Object:
  271. return &Array{Value: v}, nil
  272. case []interface{}:
  273. arr := make([]Object, len(v))
  274. for i, e := range v {
  275. vo, err := FromInterface(e)
  276. if err != nil {
  277. return nil, err
  278. }
  279. arr[i] = vo
  280. }
  281. return &Array{Value: arr}, nil
  282. case time.Time:
  283. return &Time{Value: v}, nil
  284. case Object:
  285. return v, nil
  286. case CallableFunc:
  287. return &UserFunction{Value: v}, nil
  288. }
  289. return nil, fmt.Errorf("cannot convert to object: %T", v)
  290. }