Coder Social home page Coder Social logo

monkey's Introduction

#Monkey

A go implementation of the Monkey Language

Following both books, it implements the interpreter and the compiler

My code is shorter as I used high order functions in some places to reduce code duplication, i.e.:

Original

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())
		}
	},
	},
	"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
		},
	},

Refactored

func argSizeCheck(expectedSize int, args []object.Object, body func([]object.Object) object.Object) object.Object {
	argsLength := len(args)
	if argsLength != expectedSize {
		return newError("wrong number of arguments. got=%d, want=1", argsLength)
	}

	return body(args)
}

func arrayCheck(builtinName string, args []object.Object, body func(*object.Array, int) object.Object) object.Object {
	if args[0].Type() != object.ArrayObj {
		return newError("argument to `%s` must be ARRAY, got %s", builtinName, args[0].Type())
	}
	arr := args[0].(*object.Array)
	return body(arr, len(arr.Elements))
}

var builtins = map[string]*object.Builtin{
	"len": {
		Fn: func(args ...object.Object) object.Object {

			return argSizeCheck(1, args, func(args []object.Object) object.Object {
				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", arg.Type())
				}

			})
		}},
	"first": {
		Fn: func(args ...object.Object) object.Object {

			return argSizeCheck(1, args, func(args []object.Object) object.Object {
				return arrayCheck("first", args, func(arr *object.Array, length int) object.Object {
					if length > 0 {
						return arr.Elements[0]
					}
					return NULL
				})

			})
		},
	},
	"last": {
		Fn: func(args ...object.Object) object.Object {
			return argSizeCheck(1, args, func(args []object.Object) object.Object {
				return arrayCheck("last", args, func(arr *object.Array, length int) object.Object {
					if length > 0 {
						return arr.Elements[length-1]
					}
					return NULL
				})
			})
		},
	},

monkey's People

Contributors

marioariasc avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.