builtins.go (3525B)
1 package eval 2 3 import ( 4 "fmt" 5 "umx_compiler/object" 6 ) 7 8 var builtins = map[string]*object.Builtin{ 9 "len": &object.Builtin{ 10 Fn: func(args ...object.Object) object.Object { 11 if len(args) != 1 { 12 return newError("wrong number of arguments (%d instead of %d)", len(args), 1) 13 } 14 switch arg := args[0].(type) { 15 case *object.String: 16 return &object.Integer{Value: int64(len(arg.Value))} 17 case *object.Array: 18 return &object.Integer{Value: int64(len(arg.Elements))} 19 default: 20 return newError("unsupported `len` argument, got %s", args[0].Type()) 21 } 22 }, 23 }, 24 "first": &object.Builtin{ 25 Fn: func(args ...object.Object) object.Object { 26 if len(args) != 1 { 27 return newError("invalid number of arguments") 28 } 29 if args[0].Type() != object.ARRAY_OBJ { 30 return newError("argument has to be an array") 31 } 32 arr := args[0].(*object.Array) 33 if len(arr.Elements) > 0 { 34 return arr.Elements[0] 35 } 36 return NULL 37 }, 38 }, 39 "last": &object.Builtin{ 40 Fn: func(args ...object.Object) object.Object { 41 if len(args) != 1 { 42 return newError("invalid number of arguments") 43 } 44 if args[0].Type() != object.ARRAY_OBJ { 45 return newError("argument has to be an array") 46 } 47 arr := args[0].(*object.Array) 48 arrLen := len(arr.Elements) 49 if arrLen > 0 { 50 return arr.Elements[arrLen-1] 51 } 52 return NULL 53 }, 54 }, 55 "push": &object.Builtin{ 56 Fn: func(args ...object.Object) object.Object { 57 if len(args) != 2 { 58 return newError("invalid number of arguments") 59 } 60 if args[0].Type() != object.ARRAY_OBJ { 61 return newError("argument has to be an array") 62 } 63 arr := args[0].(*object.Array) 64 newElements := append(arr.Elements, args[1]) 65 return &object.Array{Elements: newElements} 66 }, 67 }, 68 "pop": &object.Builtin{ 69 Fn: func(args ...object.Object) object.Object { 70 if len(args) != 1 { 71 return newError("invalid number of arguments") 72 } 73 if args[0].Type() != object.ARRAY_OBJ { 74 return newError("argument has to be an array") 75 } 76 arr := args[0].(*object.Array) 77 arrLen := len(arr.Elements) 78 if arrLen > 1 { 79 newElements := make([]object.Object, arrLen-1, arrLen-1) 80 copy(newElements, arr.Elements[:arrLen-1]) 81 return &object.Array{Elements: newElements} 82 } else { 83 var emptyArr []object.Object 84 return &object.Array{Elements: emptyArr} 85 } 86 }, 87 }, 88 "rpush": &object.Builtin{ 89 Fn: func(args ...object.Object) object.Object { 90 if len(args) != 2 { 91 return newError("invalid number of arguments") 92 } 93 if args[0].Type() != object.ARRAY_OBJ { 94 return newError("argument has to be an array") 95 } 96 arr := args[0].(*object.Array) 97 newElements := append([]object.Object{args[1]}, arr.Elements...) 98 return &object.Array{Elements: newElements} 99 }, 100 }, 101 "rpop": &object.Builtin{ 102 Fn: func(args ...object.Object) object.Object { 103 if len(args) != 1 { 104 return newError("invalid number of arguments") 105 } 106 if args[0].Type() != object.ARRAY_OBJ { 107 return newError("argument has to be an array") 108 } 109 arr := args[0].(*object.Array) 110 arrLen := len(arr.Elements) 111 if arrLen > 1 { 112 newElements := make([]object.Object, arrLen-1, arrLen-1) 113 copy(newElements, arr.Elements[1:arrLen]) 114 return &object.Array{Elements: newElements} 115 } else { 116 var emptyArr []object.Object 117 return &object.Array{Elements: emptyArr} 118 } 119 }, 120 }, 121 "puts": &object.Builtin{ 122 Fn: func(args ...object.Object) object.Object { 123 for _, arg := range args { 124 fmt.Println(arg.Inspect()) 125 } 126 return NULL 127 }, 128 }, 129 }