|
|
@@ -19,4 +19,94 @@ var builtins = map[string]*object.Builtin{
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
+ "first": {
|
|
|
+ Fn: func(args ...object.Object) object.Object {
|
|
|
+ if len(args) != 1 {
|
|
|
+ return newError("wrong number of arguments. got=%d, want=1", len(args))
|
|
|
+ }
|
|
|
+ if args[0].Type() != object.ArrayObj {
|
|
|
+ return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
|
|
|
+ }
|
|
|
+ arr := args[0].(*object.Array)
|
|
|
+ if len(arr.Elements) > 0 {
|
|
|
+ return arr.Elements[0]
|
|
|
+ }
|
|
|
+ return NULL
|
|
|
+ },
|
|
|
+ },
|
|
|
+ "last": {
|
|
|
+ Fn: func(args ...object.Object) object.Object {
|
|
|
+ if len(args) != 1 {
|
|
|
+ return newError("wrong number of arguments. got=%d, want=1", len(args))
|
|
|
+ }
|
|
|
+ if args[0].Type() != object.ArrayObj {
|
|
|
+ return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
|
|
|
+ }
|
|
|
+
|
|
|
+ arr := args[0].(*object.Array)
|
|
|
+ length := len(arr.Elements)
|
|
|
+ if length > 0 {
|
|
|
+ return arr.Elements[length-1]
|
|
|
+ }
|
|
|
+ return NULL
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // rest returns a new array containing all elements of the array passed as argument, except the first one
|
|
|
+ // >> let a = [1, 2, 3, 4];
|
|
|
+ // >> rest(a)
|
|
|
+ // [2, 3, 4]
|
|
|
+ // >> rest(rest(a))
|
|
|
+ // [3, 4]
|
|
|
+ // >> rest(rest(rest(a)))
|
|
|
+ // [4]
|
|
|
+ // >> rest(rest(rest(rest(a))))
|
|
|
+ // []
|
|
|
+ // >> rest(rest(rest(rest(rest(a)))))
|
|
|
+ // null
|
|
|
+ "rest": {
|
|
|
+ Fn: func(args ...object.Object) object.Object {
|
|
|
+ if len(args) != 1 {
|
|
|
+ return newError("wrong number of arguments. got=%d, want=1", len(args))
|
|
|
+ }
|
|
|
+ if args[0].Type() != object.ArrayObj {
|
|
|
+ return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
|
|
|
+ }
|
|
|
+
|
|
|
+ arr := args[0].(*object.Array)
|
|
|
+ length := len(arr.Elements)
|
|
|
+ if length > 0 {
|
|
|
+ newElements := make([]object.Object, length-1, length-1)
|
|
|
+ copy(newElements, arr.Elements[1:length])
|
|
|
+ return &object.Array{Elements: newElements}
|
|
|
+ }
|
|
|
+ return NULL
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // It adds a new element to the end of the array. But, and here's the kicker, it doesn't modify the given array.
|
|
|
+ // Instead, it allocates a new array with the same elements as the old one plus the new, pushed element.
|
|
|
+ // >> let a = [1, 2, 3, 4];
|
|
|
+ // >> let b = push(a, 5);
|
|
|
+ // >> a
|
|
|
+ //[1, 2, 3, 4]
|
|
|
+ // >> b
|
|
|
+ //[1, 2, 3, 4, 5]
|
|
|
+ "push": {
|
|
|
+ Fn: func(args ...object.Object) object.Object {
|
|
|
+ if len(args) != 2 {
|
|
|
+ return newError("wrong number of arguments. got=%d, want=1", len(args))
|
|
|
+ }
|
|
|
+ if args[0].Type() != object.ArrayObj {
|
|
|
+ return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
|
|
|
+ }
|
|
|
+
|
|
|
+ arr := args[0].(*object.Array)
|
|
|
+ length := len(arr.Elements)
|
|
|
+
|
|
|
+ newElements := make([]object.Object, length+1, length+1)
|
|
|
+ copy(newElements, arr.Elements)
|
|
|
+ newElements[length] = args[1]
|
|
|
+
|
|
|
+ return &object.Array{Elements: newElements}
|
|
|
+ },
|
|
|
+ },
|
|
|
}
|