/vendor/github.com/d5/tengo/v2/builtins.go

https://github.com/42wim/matterbridge · Go · 611 lines · 559 code · 38 blank · 14 comment · 138 complexity · f3d73e2be33ce98d74022cb5c7c1e8ff MD5 · raw file

  1. package tengo
  2. var builtinFuncs = []*BuiltinFunction{
  3. {
  4. Name: "len",
  5. Value: builtinLen,
  6. },
  7. {
  8. Name: "copy",
  9. Value: builtinCopy,
  10. },
  11. {
  12. Name: "append",
  13. Value: builtinAppend,
  14. },
  15. {
  16. Name: "delete",
  17. Value: builtinDelete,
  18. },
  19. {
  20. Name: "splice",
  21. Value: builtinSplice,
  22. },
  23. {
  24. Name: "string",
  25. Value: builtinString,
  26. },
  27. {
  28. Name: "int",
  29. Value: builtinInt,
  30. },
  31. {
  32. Name: "bool",
  33. Value: builtinBool,
  34. },
  35. {
  36. Name: "float",
  37. Value: builtinFloat,
  38. },
  39. {
  40. Name: "char",
  41. Value: builtinChar,
  42. },
  43. {
  44. Name: "bytes",
  45. Value: builtinBytes,
  46. },
  47. {
  48. Name: "time",
  49. Value: builtinTime,
  50. },
  51. {
  52. Name: "is_int",
  53. Value: builtinIsInt,
  54. },
  55. {
  56. Name: "is_float",
  57. Value: builtinIsFloat,
  58. },
  59. {
  60. Name: "is_string",
  61. Value: builtinIsString,
  62. },
  63. {
  64. Name: "is_bool",
  65. Value: builtinIsBool,
  66. },
  67. {
  68. Name: "is_char",
  69. Value: builtinIsChar,
  70. },
  71. {
  72. Name: "is_bytes",
  73. Value: builtinIsBytes,
  74. },
  75. {
  76. Name: "is_array",
  77. Value: builtinIsArray,
  78. },
  79. {
  80. Name: "is_immutable_array",
  81. Value: builtinIsImmutableArray,
  82. },
  83. {
  84. Name: "is_map",
  85. Value: builtinIsMap,
  86. },
  87. {
  88. Name: "is_immutable_map",
  89. Value: builtinIsImmutableMap,
  90. },
  91. {
  92. Name: "is_iterable",
  93. Value: builtinIsIterable,
  94. },
  95. {
  96. Name: "is_time",
  97. Value: builtinIsTime,
  98. },
  99. {
  100. Name: "is_error",
  101. Value: builtinIsError,
  102. },
  103. {
  104. Name: "is_undefined",
  105. Value: builtinIsUndefined,
  106. },
  107. {
  108. Name: "is_function",
  109. Value: builtinIsFunction,
  110. },
  111. {
  112. Name: "is_callable",
  113. Value: builtinIsCallable,
  114. },
  115. {
  116. Name: "type_name",
  117. Value: builtinTypeName,
  118. },
  119. {
  120. Name: "format",
  121. Value: builtinFormat,
  122. },
  123. }
  124. // GetAllBuiltinFunctions returns all builtin function objects.
  125. func GetAllBuiltinFunctions() []*BuiltinFunction {
  126. return append([]*BuiltinFunction{}, builtinFuncs...)
  127. }
  128. func builtinTypeName(args ...Object) (Object, error) {
  129. if len(args) != 1 {
  130. return nil, ErrWrongNumArguments
  131. }
  132. return &String{Value: args[0].TypeName()}, nil
  133. }
  134. func builtinIsString(args ...Object) (Object, error) {
  135. if len(args) != 1 {
  136. return nil, ErrWrongNumArguments
  137. }
  138. if _, ok := args[0].(*String); ok {
  139. return TrueValue, nil
  140. }
  141. return FalseValue, nil
  142. }
  143. func builtinIsInt(args ...Object) (Object, error) {
  144. if len(args) != 1 {
  145. return nil, ErrWrongNumArguments
  146. }
  147. if _, ok := args[0].(*Int); ok {
  148. return TrueValue, nil
  149. }
  150. return FalseValue, nil
  151. }
  152. func builtinIsFloat(args ...Object) (Object, error) {
  153. if len(args) != 1 {
  154. return nil, ErrWrongNumArguments
  155. }
  156. if _, ok := args[0].(*Float); ok {
  157. return TrueValue, nil
  158. }
  159. return FalseValue, nil
  160. }
  161. func builtinIsBool(args ...Object) (Object, error) {
  162. if len(args) != 1 {
  163. return nil, ErrWrongNumArguments
  164. }
  165. if _, ok := args[0].(*Bool); ok {
  166. return TrueValue, nil
  167. }
  168. return FalseValue, nil
  169. }
  170. func builtinIsChar(args ...Object) (Object, error) {
  171. if len(args) != 1 {
  172. return nil, ErrWrongNumArguments
  173. }
  174. if _, ok := args[0].(*Char); ok {
  175. return TrueValue, nil
  176. }
  177. return FalseValue, nil
  178. }
  179. func builtinIsBytes(args ...Object) (Object, error) {
  180. if len(args) != 1 {
  181. return nil, ErrWrongNumArguments
  182. }
  183. if _, ok := args[0].(*Bytes); ok {
  184. return TrueValue, nil
  185. }
  186. return FalseValue, nil
  187. }
  188. func builtinIsArray(args ...Object) (Object, error) {
  189. if len(args) != 1 {
  190. return nil, ErrWrongNumArguments
  191. }
  192. if _, ok := args[0].(*Array); ok {
  193. return TrueValue, nil
  194. }
  195. return FalseValue, nil
  196. }
  197. func builtinIsImmutableArray(args ...Object) (Object, error) {
  198. if len(args) != 1 {
  199. return nil, ErrWrongNumArguments
  200. }
  201. if _, ok := args[0].(*ImmutableArray); ok {
  202. return TrueValue, nil
  203. }
  204. return FalseValue, nil
  205. }
  206. func builtinIsMap(args ...Object) (Object, error) {
  207. if len(args) != 1 {
  208. return nil, ErrWrongNumArguments
  209. }
  210. if _, ok := args[0].(*Map); ok {
  211. return TrueValue, nil
  212. }
  213. return FalseValue, nil
  214. }
  215. func builtinIsImmutableMap(args ...Object) (Object, error) {
  216. if len(args) != 1 {
  217. return nil, ErrWrongNumArguments
  218. }
  219. if _, ok := args[0].(*ImmutableMap); ok {
  220. return TrueValue, nil
  221. }
  222. return FalseValue, nil
  223. }
  224. func builtinIsTime(args ...Object) (Object, error) {
  225. if len(args) != 1 {
  226. return nil, ErrWrongNumArguments
  227. }
  228. if _, ok := args[0].(*Time); ok {
  229. return TrueValue, nil
  230. }
  231. return FalseValue, nil
  232. }
  233. func builtinIsError(args ...Object) (Object, error) {
  234. if len(args) != 1 {
  235. return nil, ErrWrongNumArguments
  236. }
  237. if _, ok := args[0].(*Error); ok {
  238. return TrueValue, nil
  239. }
  240. return FalseValue, nil
  241. }
  242. func builtinIsUndefined(args ...Object) (Object, error) {
  243. if len(args) != 1 {
  244. return nil, ErrWrongNumArguments
  245. }
  246. if args[0] == UndefinedValue {
  247. return TrueValue, nil
  248. }
  249. return FalseValue, nil
  250. }
  251. func builtinIsFunction(args ...Object) (Object, error) {
  252. if len(args) != 1 {
  253. return nil, ErrWrongNumArguments
  254. }
  255. switch args[0].(type) {
  256. case *CompiledFunction:
  257. return TrueValue, nil
  258. }
  259. return FalseValue, nil
  260. }
  261. func builtinIsCallable(args ...Object) (Object, error) {
  262. if len(args) != 1 {
  263. return nil, ErrWrongNumArguments
  264. }
  265. if args[0].CanCall() {
  266. return TrueValue, nil
  267. }
  268. return FalseValue, nil
  269. }
  270. func builtinIsIterable(args ...Object) (Object, error) {
  271. if len(args) != 1 {
  272. return nil, ErrWrongNumArguments
  273. }
  274. if args[0].CanIterate() {
  275. return TrueValue, nil
  276. }
  277. return FalseValue, nil
  278. }
  279. // len(obj object) => int
  280. func builtinLen(args ...Object) (Object, error) {
  281. if len(args) != 1 {
  282. return nil, ErrWrongNumArguments
  283. }
  284. switch arg := args[0].(type) {
  285. case *Array:
  286. return &Int{Value: int64(len(arg.Value))}, nil
  287. case *ImmutableArray:
  288. return &Int{Value: int64(len(arg.Value))}, nil
  289. case *String:
  290. return &Int{Value: int64(len(arg.Value))}, nil
  291. case *Bytes:
  292. return &Int{Value: int64(len(arg.Value))}, nil
  293. case *Map:
  294. return &Int{Value: int64(len(arg.Value))}, nil
  295. case *ImmutableMap:
  296. return &Int{Value: int64(len(arg.Value))}, nil
  297. default:
  298. return nil, ErrInvalidArgumentType{
  299. Name: "first",
  300. Expected: "array/string/bytes/map",
  301. Found: arg.TypeName(),
  302. }
  303. }
  304. }
  305. func builtinFormat(args ...Object) (Object, error) {
  306. numArgs := len(args)
  307. if numArgs == 0 {
  308. return nil, ErrWrongNumArguments
  309. }
  310. format, ok := args[0].(*String)
  311. if !ok {
  312. return nil, ErrInvalidArgumentType{
  313. Name: "format",
  314. Expected: "string",
  315. Found: args[0].TypeName(),
  316. }
  317. }
  318. if numArgs == 1 {
  319. // okay to return 'format' directly as String is immutable
  320. return format, nil
  321. }
  322. s, err := Format(format.Value, args[1:]...)
  323. if err != nil {
  324. return nil, err
  325. }
  326. return &String{Value: s}, nil
  327. }
  328. func builtinCopy(args ...Object) (Object, error) {
  329. if len(args) != 1 {
  330. return nil, ErrWrongNumArguments
  331. }
  332. return args[0].Copy(), nil
  333. }
  334. func builtinString(args ...Object) (Object, error) {
  335. argsLen := len(args)
  336. if !(argsLen == 1 || argsLen == 2) {
  337. return nil, ErrWrongNumArguments
  338. }
  339. if _, ok := args[0].(*String); ok {
  340. return args[0], nil
  341. }
  342. v, ok := ToString(args[0])
  343. if ok {
  344. if len(v) > MaxStringLen {
  345. return nil, ErrStringLimit
  346. }
  347. return &String{Value: v}, nil
  348. }
  349. if argsLen == 2 {
  350. return args[1], nil
  351. }
  352. return UndefinedValue, nil
  353. }
  354. func builtinInt(args ...Object) (Object, error) {
  355. argsLen := len(args)
  356. if !(argsLen == 1 || argsLen == 2) {
  357. return nil, ErrWrongNumArguments
  358. }
  359. if _, ok := args[0].(*Int); ok {
  360. return args[0], nil
  361. }
  362. v, ok := ToInt64(args[0])
  363. if ok {
  364. return &Int{Value: v}, nil
  365. }
  366. if argsLen == 2 {
  367. return args[1], nil
  368. }
  369. return UndefinedValue, nil
  370. }
  371. func builtinFloat(args ...Object) (Object, error) {
  372. argsLen := len(args)
  373. if !(argsLen == 1 || argsLen == 2) {
  374. return nil, ErrWrongNumArguments
  375. }
  376. if _, ok := args[0].(*Float); ok {
  377. return args[0], nil
  378. }
  379. v, ok := ToFloat64(args[0])
  380. if ok {
  381. return &Float{Value: v}, nil
  382. }
  383. if argsLen == 2 {
  384. return args[1], nil
  385. }
  386. return UndefinedValue, nil
  387. }
  388. func builtinBool(args ...Object) (Object, error) {
  389. if len(args) != 1 {
  390. return nil, ErrWrongNumArguments
  391. }
  392. if _, ok := args[0].(*Bool); ok {
  393. return args[0], nil
  394. }
  395. v, ok := ToBool(args[0])
  396. if ok {
  397. if v {
  398. return TrueValue, nil
  399. }
  400. return FalseValue, nil
  401. }
  402. return UndefinedValue, nil
  403. }
  404. func builtinChar(args ...Object) (Object, error) {
  405. argsLen := len(args)
  406. if !(argsLen == 1 || argsLen == 2) {
  407. return nil, ErrWrongNumArguments
  408. }
  409. if _, ok := args[0].(*Char); ok {
  410. return args[0], nil
  411. }
  412. v, ok := ToRune(args[0])
  413. if ok {
  414. return &Char{Value: v}, nil
  415. }
  416. if argsLen == 2 {
  417. return args[1], nil
  418. }
  419. return UndefinedValue, nil
  420. }
  421. func builtinBytes(args ...Object) (Object, error) {
  422. argsLen := len(args)
  423. if !(argsLen == 1 || argsLen == 2) {
  424. return nil, ErrWrongNumArguments
  425. }
  426. // bytes(N) => create a new bytes with given size N
  427. if n, ok := args[0].(*Int); ok {
  428. if n.Value > int64(MaxBytesLen) {
  429. return nil, ErrBytesLimit
  430. }
  431. return &Bytes{Value: make([]byte, int(n.Value))}, nil
  432. }
  433. v, ok := ToByteSlice(args[0])
  434. if ok {
  435. if len(v) > MaxBytesLen {
  436. return nil, ErrBytesLimit
  437. }
  438. return &Bytes{Value: v}, nil
  439. }
  440. if argsLen == 2 {
  441. return args[1], nil
  442. }
  443. return UndefinedValue, nil
  444. }
  445. func builtinTime(args ...Object) (Object, error) {
  446. argsLen := len(args)
  447. if !(argsLen == 1 || argsLen == 2) {
  448. return nil, ErrWrongNumArguments
  449. }
  450. if _, ok := args[0].(*Time); ok {
  451. return args[0], nil
  452. }
  453. v, ok := ToTime(args[0])
  454. if ok {
  455. return &Time{Value: v}, nil
  456. }
  457. if argsLen == 2 {
  458. return args[1], nil
  459. }
  460. return UndefinedValue, nil
  461. }
  462. // append(arr, items...)
  463. func builtinAppend(args ...Object) (Object, error) {
  464. if len(args) < 2 {
  465. return nil, ErrWrongNumArguments
  466. }
  467. switch arg := args[0].(type) {
  468. case *Array:
  469. return &Array{Value: append(arg.Value, args[1:]...)}, nil
  470. case *ImmutableArray:
  471. return &Array{Value: append(arg.Value, args[1:]...)}, nil
  472. default:
  473. return nil, ErrInvalidArgumentType{
  474. Name: "first",
  475. Expected: "array",
  476. Found: arg.TypeName(),
  477. }
  478. }
  479. }
  480. // builtinDelete deletes Map keys
  481. // usage: delete(map, "key")
  482. // key must be a string
  483. func builtinDelete(args ...Object) (Object, error) {
  484. argsLen := len(args)
  485. if argsLen != 2 {
  486. return nil, ErrWrongNumArguments
  487. }
  488. switch arg := args[0].(type) {
  489. case *Map:
  490. if key, ok := args[1].(*String); ok {
  491. delete(arg.Value, key.Value)
  492. return UndefinedValue, nil
  493. }
  494. return nil, ErrInvalidArgumentType{
  495. Name: "second",
  496. Expected: "string",
  497. Found: args[1].TypeName(),
  498. }
  499. default:
  500. return nil, ErrInvalidArgumentType{
  501. Name: "first",
  502. Expected: "map",
  503. Found: arg.TypeName(),
  504. }
  505. }
  506. }
  507. // builtinSplice deletes and changes given Array, returns deleted items.
  508. // usage:
  509. // deleted_items := splice(array[,start[,delete_count[,item1[,item2[,...]]]])
  510. func builtinSplice(args ...Object) (Object, error) {
  511. argsLen := len(args)
  512. if argsLen == 0 {
  513. return nil, ErrWrongNumArguments
  514. }
  515. array, ok := args[0].(*Array)
  516. if !ok {
  517. return nil, ErrInvalidArgumentType{
  518. Name: "first",
  519. Expected: "array",
  520. Found: args[0].TypeName(),
  521. }
  522. }
  523. arrayLen := len(array.Value)
  524. var startIdx int
  525. if argsLen > 1 {
  526. arg1, ok := args[1].(*Int)
  527. if !ok {
  528. return nil, ErrInvalidArgumentType{
  529. Name: "second",
  530. Expected: "int",
  531. Found: args[1].TypeName(),
  532. }
  533. }
  534. startIdx = int(arg1.Value)
  535. if startIdx < 0 || startIdx > arrayLen {
  536. return nil, ErrIndexOutOfBounds
  537. }
  538. }
  539. delCount := len(array.Value)
  540. if argsLen > 2 {
  541. arg2, ok := args[2].(*Int)
  542. if !ok {
  543. return nil, ErrInvalidArgumentType{
  544. Name: "third",
  545. Expected: "int",
  546. Found: args[2].TypeName(),
  547. }
  548. }
  549. delCount = int(arg2.Value)
  550. if delCount < 0 {
  551. return nil, ErrIndexOutOfBounds
  552. }
  553. }
  554. // if count of to be deleted items is bigger than expected, truncate it
  555. if startIdx+delCount > arrayLen {
  556. delCount = arrayLen - startIdx
  557. }
  558. // delete items
  559. endIdx := startIdx + delCount
  560. deleted := append([]Object{}, array.Value[startIdx:endIdx]...)
  561. head := array.Value[:startIdx]
  562. var items []Object
  563. if argsLen > 3 {
  564. items = make([]Object, 0, argsLen-3)
  565. for i := 3; i < argsLen; i++ {
  566. items = append(items, args[i])
  567. }
  568. }
  569. items = append(items, array.Value[endIdx:]...)
  570. array.Value = append(head, items...)
  571. // return deleted items
  572. return &Array{Value: deleted}, nil
  573. }