builtins.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package evaluator
  2. import "github/runnignwater/monkey/object"
  3. // 内建函数
  4. var builtins = map[string]*object.Builtin{
  5. "len": {
  6. Fn: func(args ...object.Object) object.Object {
  7. if len(args) != 1 {
  8. return newError("wrong number of arguments. got=%d, want=1", len(args))
  9. }
  10. switch arg := args[0].(type) {
  11. case *object.String:
  12. return &object.Integer{Value: int64(len(arg.Value))}
  13. case *object.Array:
  14. return &object.Integer{Value: int64(len(arg.Elements))}
  15. default:
  16. return newError("argument to `len` not supported, got %s", args[0].Type())
  17. }
  18. },
  19. },
  20. "first": {
  21. Fn: func(args ...object.Object) object.Object {
  22. if len(args) != 1 {
  23. return newError("wrong number of arguments. got=%d, want=1", len(args))
  24. }
  25. if args[0].Type() != object.ArrayObj {
  26. return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
  27. }
  28. arr := args[0].(*object.Array)
  29. if len(arr.Elements) > 0 {
  30. return arr.Elements[0]
  31. }
  32. return NULL
  33. },
  34. },
  35. "last": {
  36. Fn: func(args ...object.Object) object.Object {
  37. if len(args) != 1 {
  38. return newError("wrong number of arguments. got=%d, want=1", len(args))
  39. }
  40. if args[0].Type() != object.ArrayObj {
  41. return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
  42. }
  43. arr := args[0].(*object.Array)
  44. length := len(arr.Elements)
  45. if length > 0 {
  46. return arr.Elements[length-1]
  47. }
  48. return NULL
  49. },
  50. },
  51. // rest returns a new array containing all elements of the array passed as argument, except the first one
  52. // >> let a = [1, 2, 3, 4];
  53. // >> rest(a)
  54. // [2, 3, 4]
  55. // >> rest(rest(a))
  56. // [3, 4]
  57. // >> rest(rest(rest(a)))
  58. // [4]
  59. // >> rest(rest(rest(rest(a))))
  60. // []
  61. // >> rest(rest(rest(rest(rest(a)))))
  62. // null
  63. "rest": {
  64. Fn: func(args ...object.Object) object.Object {
  65. if len(args) != 1 {
  66. return newError("wrong number of arguments. got=%d, want=1", len(args))
  67. }
  68. if args[0].Type() != object.ArrayObj {
  69. return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
  70. }
  71. arr := args[0].(*object.Array)
  72. length := len(arr.Elements)
  73. if length > 0 {
  74. newElements := make([]object.Object, length-1, length-1)
  75. copy(newElements, arr.Elements[1:length])
  76. return &object.Array{Elements: newElements}
  77. }
  78. return NULL
  79. },
  80. },
  81. // It adds a new element to the end of the array. But, and here's the kicker, it doesn't modify the given array.
  82. // Instead, it allocates a new array with the same elements as the old one plus the new, pushed element.
  83. // >> let a = [1, 2, 3, 4];
  84. // >> let b = push(a, 5);
  85. // >> a
  86. //[1, 2, 3, 4]
  87. // >> b
  88. //[1, 2, 3, 4, 5]
  89. "push": {
  90. Fn: func(args ...object.Object) object.Object {
  91. if len(args) != 2 {
  92. return newError("wrong number of arguments. got=%d, want=1", len(args))
  93. }
  94. if args[0].Type() != object.ArrayObj {
  95. return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
  96. }
  97. arr := args[0].(*object.Array)
  98. length := len(arr.Elements)
  99. newElements := make([]object.Object, length+1, length+1)
  100. copy(newElements, arr.Elements)
  101. newElements[length] = args[1]
  102. return &object.Array{Elements: newElements}
  103. },
  104. },
  105. }