| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package evaluator
- import (
- "fmt"
- "github/runnignwater/monkey/object"
- )
- // 内建函数
- var builtins = map[string]*object.Builtin{
- "len": {
- Fn: func(args ...object.Object) object.Object {
- if len(args) != 1 {
- return newError("wrong number of arguments. got=%d, want=1", len(args))
- }
- 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", args[0].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.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}
- },
- },
- "puts": {
- Fn: func(args ...object.Object) object.Object {
- for _, arg := range args {
- fmt.Println(arg.Inspect())
- }
- return NULL
- },
- },
- }
|