object

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 14, 2021 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

View Source
const (
	INTEGER_OBJ           = "INTEGER"
	BOOLEAN_OBJ           = "BOOLEAN"
	NULL_OBJ              = "NULL"
	RETURN_VALUE_OBJ      = "RETURN_VALUE"
	ERROR_OBJ             = "ERROR"
	FUNCTION_OBJ          = "FUNCTION"
	STRING_OBJ            = "STRING"
	BUILTIN_OBJ           = "BUILTIN"
	ARRAY_OBJ             = "ARRAY"
	HASH_OBJ              = "HASH"
	COMPILED_FUNCTION_OBJ = "COMPILED_FUNCTION_OBJ"
	CLOSURE_OBJ           = "CLOSURE"
)

Variables

View Source
var Builtins = []struct {
	Name    string
	Builtin *Builtin
}{
	{
		"len",
		&Builtin{
			Fn: func(args ...Object) Object {
				if len(args) != 1 {
					return newError("wrong number of arguments. got=%d, want=1", len(args))
				}

				switch arg := args[0].(type) {
				case *Array:
					return &Integer{Value: int64(len(arg.Elements))}
				case *String:
					return &Integer{Value: int64(len(arg.Value))}
				default:
					return newError("argument to `len` not supported, got=%s", args[0].Type())
				}
			},
		},
	},
	{
		"puts",
		&Builtin{
			Fn: func(args ...Object) Object {
				for _, arg := range args {
					fmt.Println(arg.Inspect())
				}
				return nil
			},
		},
	},
	{
		"first",
		&Builtin{
			Fn: func(args ...Object) Object {
				if len(args) != 1 {
					return newError("wrong number of arguments. got=%d, want=1", len(args))
				}

				if args[0].Type() != ARRAY_OBJ {
					return newError("argument to `first` must be ARRAY, got %s", args[0].Type())
				}

				arr := args[0].(*Array)
				if len(arr.Elements) > 0 {
					return arr.Elements[0]
				}

				return nil
			},
		},
	},
	{
		"last",
		&Builtin{
			Fn: func(args ...Object) Object {
				if len(args) != 1 {
					return newError("wrong number of arguments. got=%d, want=1", len(args))
				}

				if args[0].Type() != ARRAY_OBJ {
					return newError("argument to `last` must be ARRAY, got %s", args[0].Type())
				}

				arr := args[0].(*Array)
				length := len(arr.Elements)
				if length > 0 {
					return arr.Elements[length-1]
				}

				return nil
			},
		},
	},
	{
		"rest",
		&Builtin{
			Fn: func(args ...Object) Object {
				if len(args) != 1 {
					return newError("wrong number of arguments. got=%d, want=1", len(args))
				}

				if args[0].Type() != ARRAY_OBJ {
					return newError("argument to `rest` must be ARRAY, got %s", args[0].Type())
				}

				arr := args[0].(*Array)
				length := len(arr.Elements)
				if length > 0 {
					newElements := make([]Object, length-1, length-1)
					copy(newElements, arr.Elements[1:length])
					return &Array{Elements: newElements}
				}

				return nil
			},
		},
	},
	{
		"push",
		&Builtin{
			Fn: func(args ...Object) Object {
				if len(args) != 2 {
					return newError("wrong number of arguments. got=%d, want=2", len(args))
				}

				if args[0].Type() != ARRAY_OBJ {
					return newError("argument to `push` must be ARRAY, got %s", args[0].Type())
				}

				arr := args[0].(*Array)
				length := len(arr.Elements)

				newElements := make([]Object, length+1, length+1)
				copy(newElements, arr.Elements)
				newElements[length] = args[1]

				return &Array{Elements: newElements}
			},
		},
	},
}

Builtins contains a mapping of the supported built-in functions.

Functions

This section is empty.

Types

type Array

type Array struct {
	Elements []Object
}

Array is the referenced struct for Array Literals in our object system. The struct holds the evaluated elements of the array literal

func (*Array) Inspect

func (ao *Array) Inspect() string

Inspect will construct the Array as a string by stringifying its elements, and concatenating them into the expected array format.

func (*Array) Type

func (ao *Array) Type() ObjectType

Type returns the ObjectType (ARRAY_OBJ) associated with the referenced Array struct

type Boolean

type Boolean struct {
	Value bool // the evaluated value
}

Boolean is the referenced struct for Boolean Literals in our object system. The struct holds the evaluated value of the Boolean Literal.

func (*Boolean) HashKey

func (b *Boolean) HashKey() HashKey

HashKey constructs a boolean hash-key for a Hash. The hash-key can be a binary of 1 or 0 depending on the Boolean's Value (true or false). This HashKey struct will be used as a key in the evaluated Hash Literal.

func (*Boolean) Inspect

func (b *Boolean) Inspect() string

Inspect returns the Boolean struct's Value as a string

func (*Boolean) Type

func (b *Boolean) Type() ObjectType

Type returns the ObjectType (BOOLEAN_OBJ) associated with the referenced Boolean struct

type Builtin

type Builtin struct {
	Fn BuiltinFunction
}

Builtin is the referenced struct for built-in functions in our object system. The struct holds the defined built-in function.

func GetBuiltInByName added in v0.0.2

func GetBuiltInByName(name string) *Builtin

GetBuiltInByName simply finds a BuiltIn with a matching name

func (*Builtin) Inspect

func (b *Builtin) Inspect() string

Inspect returns a static string for the Builtin struct

func (*Builtin) Type

func (b *Builtin) Type() ObjectType

Type returns the ObjectType (BUILTIN_OBJ) associated with the referenced Builtin struct

type BuiltinFunction

type BuiltinFunction func(args ...Object) Object

BuiltinFunction is used to create built-in functions that can be called in the interpretor. The functions are defined by us and can be called by the user. A built-in function can be constructed with any number of arguments of the type Object, but it must return an Object.

type Closure added in v0.0.2

type Closure struct {
	Fn   *CompiledFunction
	Free []Object
}

Closure is the referenced struct for closures in the object system. Fn points to the CompiledFunction enclosed by the closure. Free is a slice that keeps track of the free-variables relevant to the closure. A Closure struct will be constructed during run-time (when the VM executes) The Compiler provides an OpClosure instruction and the VM executes it, the will wrap an *object.CompiledFunction from the constants pool in a new Closure and put it on the stack. NOTE: All *object.CompiledFunctions will be wrapped by a Closure.

func (*Closure) Inspect added in v0.0.2

func (c *Closure) Inspect() string

Inspect will simply return a preformatted string for the Closure with its memory-address.

func (*Closure) Type added in v0.0.2

func (c *Closure) Type() ObjectType

Type returns the ObjectType (CLOSURE_OBJ) associated with the referenced CLOSURE_OBJ struct

type CompiledFunction added in v0.0.2

type CompiledFunction struct {
	Instructions  code.Instructions
	NumLocals     int
	NumParameters int
}

CompiledFunction is the referenced struct for compiled functions in our object system. The Instructions field holds the bytecode instructions from compiling a function literal. NumLocals is the number of local bindings in the function. CompiledFunction is intended to be a bytecode constant, it will be loaded on to to the stack and eventually used by the VM when it executes the function as a call expression instruction (OpCall).

func (*CompiledFunction) Inspect added in v0.0.2

func (cf *CompiledFunction) Inspect() string

Inspect will simply return a preformatted string for the CompiledFunction with its memory-address.

func (*CompiledFunction) Type added in v0.0.2

func (cf *CompiledFunction) Type() ObjectType

Type returns the ObjectType (COMPILED_FUNCTION_OBJ) associated with the referenced CompiledFunction struct

type Environment

type Environment struct {
	// contains filtered or unexported fields
}

Environment employ a hashmap to keep track of evaluated values for expressions. Each value (Object) is associated with a name, typically the same name of the Identifier it was original bound too.

func NewEnclosedEnvironment

func NewEnclosedEnvironment(outer *Environment) *Environment

NewEnclosedEnvironment extends the given Environment (outer). We create a new instance of an Environment with a pointer to the environment it should extend. By doing that, we enclose a fresh and empty environment with an existing one (outer). This allows us to preserve previous bindings while at the same time making new ones available, effectively introducing the concept of variable "scoping" ie: Identifiers of the same name can exist in different environments and hold different values:

  // The outer enclosing environment
	let x = 5
	let printNum = fn(x) {
		// The inner environment
		puts(x)
	}

	printNum(10) ----> 10
	puts(x) ---->  5

The inner environment can always Get and reference the store of its outer environment

func NewEnvironment

func NewEnvironment() *Environment

NewEnvironment creates a new instance of an Environment

func (*Environment) Get

func (e *Environment) Get(name string) (Object, bool)

Get uses the given name to find an associated Object in the Environment store. If the name cannot be found in the current environment, and the current environment has an outer environment, then try to Get the Object from the outer environment. This repeats and surfaces up the Environment tree until an associated Object is found or when there are no enclosing Environments left (reached the root environment).

func (*Environment) Set

func (e *Environment) Set(name string, val Object) Object

Set will use the given name to update the associated entry in the Environment store with the new value

type Error

type Error struct {
	Message string
}

Error contains the Message corresponding to an error that was encountered while evaluating the AST

func (*Error) Inspect

func (e *Error) Inspect() string

Inspect returns the Error struct's Message as a formatted string to print out the error message

func (*Error) Type

func (e *Error) Type() ObjectType

Type returns the ObjectType (ERROR_OBJ) associated with the referenced Error struct

type Function

type Function struct {
	Parameters []*ast.Identifier
	Body       *ast.BlockStatement
	Env        *Environment
}

Function is the referenced struct for Function Literals in our object system. The struct holds the function's parameters and body to be later evaluated when referenced in its respective environment in a function call

func (*Function) Inspect

func (f *Function) Inspect() string

Inspect will construct the Function as a string by stringifying its components, the parameters and body, and concatenating them into the expected function format.

func (*Function) Type

func (f *Function) Type() ObjectType

Type returns the ObjectType (FUNCTION_OBJ) associated with the referenced Function struct

type Hash

type Hash struct {
	Pairs map[HashKey]HashPair
}

Hash is the referenced strsuct for Hash Literals in our object system The Pairs field holds the evaluated map of the hash literal.

func (*Hash) Inspect

func (h *Hash) Inspect() string

Inspect will construct the Hash as a string by stringifying its key-value pairs, and concatenating them into the expected hash format.

func (*Hash) Type

func (h *Hash) Type() ObjectType

Type returns the ObjectType (HASH_OBJ) associated with the referenced Hash struct

type HashKey

type HashKey struct {
	Type  ObjectType
	Value uint64
}

HashKey is the referenced struct for a hash-key used in a Hash. It helps us effectively look up keys in the Hash.Pairs. Type refers to the different object types a hash-key can have (string, integer, boolean) before being converted to a uint64. Value refers to the actual literal value of the key, the key in the key-value pair.

type HashPair

type HashPair struct {
	Key   Object
	Value Object
}

HashPair is the referenced struct used as the designated value to HashKeys. It helps us print the values of the map in a more practial manner by containing both the objects that generated the keys and values of the map.

type Hashable

type Hashable interface {
	HashKey() HashKey
}

Hashable is the interface used in our evaluator to check if the given object is usable as a hash key when we evaluate hash literals or index expressions for hashes.

type Integer

type Integer struct {
	Value int64 // the evaluated value
}

Integer is the referenced struct for Integer Literals in our object system. The struct holds the evaluated value of the Integer Literal.

func (*Integer) HashKey

func (i *Integer) HashKey() HashKey

HashKey constructs an integer hash-key for a Hash. It uses the Integer's Value as the HashKey value. This HashKey struct will be used as a key in the evaluated Hash Literal.

func (*Integer) Inspect

func (i *Integer) Inspect() string

Inspect returns the Integer struct's Value as a string

func (*Integer) Type

func (i *Integer) Type() ObjectType

Type returns the ObjectType (INTEGER_OBJ) associated with the referenced Integer struct

type Null

type Null struct{}

Null is the referenced struct for Null Literals in our object system. By nature it has no value, since it represents the absence of any value.

func (*Null) Inspect

func (n *Null) Inspect() string

Inspect returns a literal "null" string as there is no value to stringify on Null structs

func (*Null) Type

func (n *Null) Type() ObjectType

Type returns the ObjectType (NULL_OBJ) associated with the referenced Null struct

type Object

type Object interface {
	Type() ObjectType
	Inspect() string
}

Object is the interface that represents every value we encounter when evaluating Monkey source code. Every value will be wrapped inside a stuct, which fulfills this Object interface. Tt is foundation for our object system.

type ObjectType

type ObjectType string

ObjectType is the type that represents an evaluated value as a string

type ReturnValue

type ReturnValue struct {
	Value Object
}

ReturnValue wraps the intended return value inside an Object, giving us the ability to keep track of it. Keeping track of it helps us later decide whether to stop evalution or not.

func (*ReturnValue) Inspect

func (rv *ReturnValue) Inspect() string

Inspect returns the ReturnValue struct's Value as a string. Since the Value is of type Object (interface), we can call Inspect() from the underlying struct which implemeneted the Object interface.

func (*ReturnValue) Type

func (rv *ReturnValue) Type() ObjectType

Type returns the ObjectType (RETURN_VALUE_OBJ) associated with the referenced ReturnValue struct

type String

type String struct {
	Value string
}

String is the referenced struct for String Literals in our object system. The struct holds the evaluated value of the String Literal.

func (*String) HashKey

func (s *String) HashKey() HashKey

HashKey constructs a string hash-key for a Hash. The hash-key uses the String's Value to construct a new 64-bit hash and converts it to a primitive uint64 for the hash-key. This helps resolve the issue where &Object.Strings have the same Value, but have different memory allocations. There is an inequality when comparing the index operation's value, map[&Object.String{Value:"key"}] to a key in the map, {&Object.String{Value:"key"}: "value"}, we are comparing two different pointer addresses. Instead we should compare two structs. By using a HashKey, we convert the &Object.String.Value to a uint64 value and use that as the key. A unique input (string) will always return the same corresponding unique output (uint64). We take the inequal pointers out of the equation and now simply compare the two structs.

func (*String) Inspect

func (s *String) Inspect() string

Inspect returns the String struct's Value which is of type string

func (*String) Type

func (s *String) Type() ObjectType

Type returns the ObjectType (STRING_OBJ) associated with the referenced String struct

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL