builtins.go 3.3 KB

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