aboutsummaryrefslogtreecommitdiff
path: root/evaluator/builtins.go
diff options
context:
space:
mode:
Diffstat (limited to 'evaluator/builtins.go')
-rw-r--r--evaluator/builtins.go117
1 files changed, 117 insertions, 0 deletions
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}
+ },
+ },
+}