diff options
Diffstat (limited to 'evaluator')
| -rw-r--r-- | evaluator/builtins.go | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/evaluator/builtins.go b/evaluator/builtins.go index 0e6846a..1c7a312 100644 --- a/evaluator/builtins.go +++ b/evaluator/builtins.go @@ -15,9 +15,97 @@ var builtins = map[string]*object.Builtin{ switch arg := args[0].(type) { case *object.String: return &object.Integer{Value: int64(len(arg.Value))} + case *object.Array: + return &object.Integer{Value: int64(len(arg.Elements))} default: return newError("argument to `len` not supported, got %s", arg.Type()) } }, }, + "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.ARRAY_OBJ { + 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.ARRAY_OBJ { + return newError("argument to `last` 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": { + 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.ARRAY_OBJ { + return newError("argument to `rest` 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) + copy(newElements, arr.Elements[1:length]) + return &object.Array{Elements: newElements} + } + + return NULL + }, + }, + "push": { + Fn: func(args ...object.Object) object.Object { + if len(args) != 2 { + return newError("wrong number of arguments. got=%d, want=2", + len(args)) + } + + if args[0].Type() != object.ARRAY_OBJ { + return newError("argument to `push` must be ARRAY, got %s", + args[0].Type()) + } + + arr := args[0].(*object.Array) + length := len(arr.Elements) + + newElements := make([]object.Object, length+1) + copy(newElements, arr.Elements) + newElements[length] = args[1] + + return &object.Array{Elements: newElements} + }, + }, } |
