From 523f40968b9c1a23da1f4a1c2f125197d7611fef Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 20 May 2017 16:28:10 +0200 Subject: 04 --- evaluator/builtins.go | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 evaluator/builtins.go (limited to 'evaluator/builtins.go') diff --git a/evaluator/builtins.go b/evaluator/builtins.go new file mode 100644 index 0000000..68eadcd --- /dev/null +++ b/evaluator/builtins.go @@ -0,0 +1,117 @@ +package evaluator + +import ( + "fmt" + "monkey/object" +) + +var builtins = map[string]*object.Builtin{ + "len": &object.Builtin{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.Array: + return &object.Integer{Value: int64(len(arg.Elements))} + case *object.String: + return &object.Integer{Value: int64(len(arg.Value))} + default: + return newError("argument to `len` not supported, got %s", + args[0].Type()) + } + }, + }, + "puts": &object.Builtin{ + Fn: func(args ...object.Object) object.Object { + for _, arg := range args { + fmt.Println(arg.Inspect()) + } + + return NULL + }, + }, + "first": &object.Builtin{ + 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": &object.Builtin{ + 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": &object.Builtin{ + 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, length-1) + copy(newElements, arr.Elements[1:length]) + return &object.Array{Elements: newElements} + } + + return NULL + }, + }, + "push": &object.Builtin{ + 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.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, length+1) + copy(newElements, arr.Elements) + newElements[length] = args[1] + + return &object.Array{Elements: newElements} + }, + }, +} -- cgit v1.2.3