umx_compiler

UMX virtual machine "Monkey" interpreter / bytecode compiler
git clone git://bsandro.tech/umx_compiler
Log | Files | Refs | README | LICENSE

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 }