obj

package
v1.4.5 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2022 License: GPL-3.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	Stdout io.Writer = os.Stdout
	Stdin  io.Reader = os.Stdin
)
View Source
var (
	NullObj     = NewNull()
	True        = NewBoolean(true)
	False       = NewBoolean(false)
	ContinueObj = NewContinue()
	BreakObj    = NewBreak()
)
View Source
var (
	ErrFileNotFound   = errors.New("file not found")
	ErrNoFileProvided = errors.New("no file provided")
)
View Source
var Builtins = []BuiltinImpl{
	{
		"len",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("len: wrong number of arguments, expected 1, got %d", l)
			}

			switch o := Unwrap(args[0]).(type) {
			case List:
				return Integer(len(o))
			case String:
				return Integer(len(o))
			case Bytes:
				return Integer(len(o))
			default:
				return NewError("len: object of type %q has no length", o.Type())
			}
		},
	},
	{
		"println",
		func(args ...Object) Object {
			fmt.Fprintln(Stdout, toAnySlice(args)...)
			return NullObj
		},
	},
	{
		"print",
		func(args ...Object) Object {
			fmt.Fprint(Stdout, toAnySlice(args)...)
			return NullObj
		},
	},
	{
		"input",
		func(args ...Object) Object {
			var tmp string

			args = UnwrapAll(args)
			switch l := len(args); l {
			case 0:
				fmt.Scanln(&tmp)

			case 1:
				fmt.Print(args[0])
				fmt.Scanln(&tmp)

			default:
				return NewError("input: wrong number of arguments, expected 1, got %d", l)
			}
			return NewString(tmp)
		},
	},
	{
		"string",
		func(args ...Object) Object {
			if len(args) == 0 {
				return NewError("string: no argument provided")
			}

			args = UnwrapAll(args)
			if b, ok := args[0].(Bytes); ok {
				return String(b)
			}
			return NewString(fmt.Sprint(toAnySlice(args)...))
		},
	},
	{
		"error",
		func(args ...Object) Object {
			return NewError(fmt.Sprint(toAnySlice(args)...))
		},
	},
	{
		"type",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("type: wrong number of arguments, expected 1, got %d", l)
			}
			return NewString(args[0].Type().String())
		},
	},
	{
		"int",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("int: wrong number of arguments, expected 1, got %d", l)
			}

			args = UnwrapAll(args)
			switch o := args[0].(type) {
			case Integer:
				return Integer(o)

			case Float:
				return Integer(o)

			case String:
				if a, err := strconv.ParseInt(string(o), 10, 64); err == nil {
					return Integer(a)
				}
				return NewError("%v is not a number", args[0])

			default:
				return NewError("%v is not a number", args[0])
			}
		},
	},
	{
		"float",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("float: wrong number of arguments, expected 1, got %d", l)
			}

			args = UnwrapAll(args)
			switch o := args[0].(type) {
			case Integer:
				return Float(o)

			case Float:
				return Float(o)

			case String:
				if a, err := strconv.ParseFloat(string(o), 64); err == nil {
					return Float(a)
				}
				return NewError("%v is not a number", args[0])

			default:
				return NewError("%v is not a number", args[0])
			}
		},
	},
	{
		"exit",
		func(args ...Object) Object {
			args = UnwrapAll(args)

			switch l := len(args); l {
			case 0:
				os.Exit(0)

			case 1:
				switch o := args[0].(type) {
				case Integer:
					os.Exit(int(o))

				case String, Error:
					fmt.Fprintln(Stdout, o)
					os.Exit(0)

				default:
					return NewError("exit: argument must be an integer, string or error")
				}

			case 2:
				msg, ok := args[0].(String)
				if !ok {
					return NewError("exit: first argument must be a string")
				}
				code, ok := args[1].(Integer)
				if !ok {
					return NewError("exit: second argument must be an int")
				}

				fmt.Fprintln(Stdout, string(msg))
				os.Exit(int(code))

			default:
				return NewError("exit: wrong number of arguments, max 2, got %d", l)
			}
			return NullObj
		},
	},
	{
		"append",
		func(args ...Object) Object {
			if len(args) == 0 {
				return NewError("append: no argument provided")
			}

			args = UnwrapAll(args)
			lst, ok := args[0].(List)
			if !ok {
				return NewError("append: first argument must be a list")
			}

			if len(args) > 1 {
				return append(lst, args[1:]...)
			}
			return lst
		},
	},
	{
		"push",
		func(args ...Object) Object {
			if len(args) == 0 {
				return NewError("push: no argument provided")
			}

			args = UnwrapAll(args)
			lst, ok := args[0].(List)
			if !ok {
				return NewError("push: first argument must be a list")
			}

			if len(args) > 1 {
				var tmp List

				for i := len(args) - 1; i > 0; i-- {
					tmp = append(tmp, args[i])
				}

				return append(tmp, lst...)
			}
			return lst
		},
	},
	{
		"range",
		func(args ...Object) Object {
			args = UnwrapAll(args)

			switch len(args) {
			case 1:
				if stop, ok := args[0].(Integer); ok {
					return listify(0, int(stop), 1)
				}
				return NewError("range: start value must be an int")

			case 2:
				start, ok := args[0].(Integer)
				if !ok {
					return NewError("range: start value must be an int")
				}

				stop, ok := args[1].(Integer)
				if !ok {
					return NewError("range: stop value must be an int")
				}
				return listify(int(start), int(stop), 1)

			case 3:
				start, ok := args[0].(Integer)
				if !ok {
					return NewError("range: start value must be an int")
				}

				stop, ok := args[1].(Integer)
				if !ok {
					return NewError("range: stop value must be an int")
				}

				step, ok := args[2].(Integer)
				if !ok {
					return NewError("range: step value must be an int")
				}

				if s := int(step); s != 0 {
					return listify(int(start), int(stop), s)
				}
				return NewError("range: step value must not be zero")

			default:
				return NewError("range: wrong number of arguments, max 3, got %d", len(args))
			}
		},
	},
	{
		"new",
		func(args ...Object) Object {
			if l := len(args); l != 0 {
				return NewError("new: wrong number of arguments, expected 0, got %d", l)
			}
			return NewClass()
		},
	},
	{
		"failed",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("failed: wrong number of arguments, expected 1, got %d", l)
			}

			_, ok := Unwrap(args[0]).(Error)
			return ParseBool(ok)
		},
	},
	{
		"plugin",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("plugin: wrong number of arguments, expected 1, got %d", l)
			}

			str, ok := Unwrap(args[0]).(String)
			if !ok {
				return NewError("plugin: first argument must be a string, got %s instead", args[0].Type())
			}

			return NewNativePlugin(str.String())
		},
	},
	{
		"pipe",
		func(args ...Object) Object {
			switch l := len(args); l {
			case 0:
				return NewPipe()

			case 1:
				n, ok := Unwrap(args[0]).(Integer)
				if !ok {
					return NewError("pipe: first argument must be an int, got %s instead", args[0].Type())
				}
				return NewPipeBuffered(int(n))

			default:
				return NewError("pipe: wrong number of arguments, expected 0 or 1, got %d", l)
			}
		},
	},
	{
		"send",
		func(args ...Object) (o Object) {
			if l := len(args); l != 2 {
				return NewError("send: wrong number of arguments, expected 2, got %d", l)
			}

			args = UnwrapAll(args)
			p, ok := args[0].(Pipe)
			if !ok {
				return NewError("send: first argument must be a pipe, got %s instead", args[0].Type())
			}

			p <- args[1]
			return args[1]
		},
	},
	{
		"recv",
		func(args ...Object) (o Object) {
			if l := len(args); l != 1 {
				return NewError("recv: wrong number of arguments, expected 1, got %d", l)
			}

			p, ok := Unwrap(args[0]).(Pipe)
			if !ok {
				return NewError("recv: first argument must be a pipe, got %s instead", args[0].Type())
			}

			if ret := Unwrap(<-p); ret != nil {
				return ret
			}
			return NullObj
		},
	},
	{
		"close",
		func(args ...Object) (o Object) {
			if l := len(args); l != 1 {
				return NewError("close: wrong number of arguments, expected 1, got %d", l)
			}

			p, ok := Unwrap(args[0]).(Pipe)
			if !ok {
				return NewError("close: first argument must be a pipe, got %s instead", args[0].Type())
			}

			close(p)
			return NullObj
		},
	},
	{
		"hex",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("hex: wrong number of arguments, expected 1, got %d", l)
			}

			i, ok := Unwrap(args[0]).(Integer)
			if !ok {
				return NewError("hex: first argument must be an int, got %s instead", args[0].Type())
			}

			return NewString(fmt.Sprintf("0x%x", i.Val()))
		},
	},
	{
		"oct",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("oct: wrong number of arguments, expected 1, got %d", l)
			}

			i, ok := Unwrap(args[0]).(Integer)
			if !ok {
				return NewError("oct: first argument must be an int, got %s instead", args[0].Type())
			}

			return NewString(fmt.Sprintf("%O", i.Val()))
		},
	},
	{
		"bin",
		func(args ...Object) Object {
			if l := len(args); l != 1 {
				return NewError("bin: wrong number of arguments, expected 1, got %d", l)
			}

			i, ok := Unwrap(args[0]).(Integer)
			if !ok {
				return NewError("bin: first argument must be an int, got %s instead", args[0].Type())
			}

			return NewString(fmt.Sprintf("0b%b", i.Val()))
		},
	},
	{
		"slice",
		func(args ...Object) Object {
			if l := len(args); l != 3 {
				return NewError("slice: wrong number of arguments, expected 3, got %d", l)
			}

			args = UnwrapAll(args)
			s, ok := args[1].(Integer)
			if !ok {
				return NewError("slice: second argument must be an int, got %s instead", args[1].Type())
			}

			e, ok := args[2].(Integer)
			if !ok {
				return NewError("slice: third argument must be an int, got %s instead", args[2].Type())
			}

			var start, end = int(s), int(e)

			switch slice := args[0].(type) {
			case List:
				if start < 0 || end < 0 {
					return NewError("slice: invalid argument: index arguments must not be negative")
				} else if end > len(slice) {
					return NewError("slice: list bounds out of range %d with capacity %d", end, len(slice))
				}
				return slice[start:end]

			case String:
				if start < 0 || end < 0 {
					return NewError("slice: invalid argument: index arguments must not be negative")
				} else if end > len(slice) {
					return NewError("slice: string bounds out of range %d with capacity %d", end, len(slice))
				}
				return slice[start:end]

			case Bytes:
				if start < 0 || end < 0 {
					return NewError("slice: invalid argument: index arguments must not be negative")
				} else if end > len(slice) {
					return NewError("slice: bytes bounds out of range %d with capacity %d", end, len(slice))
				}
				return slice[start:end]

			default:
				return NewError("slice: first argument must be a list or string, got %s instead", args[0].Type())
			}
		},
	},
	{
		"open",
		func(args ...Object) Object {
			var l = len(args)

			if l != 1 && l != 2 {
				return NewError("open: wrong number of arguments, expected 1 or 2, got %d", l)
			}

			args = UnwrapAll(args)
			path, ok := args[0].(String)
			if !ok {
				return NewError("open: first argument must be a string, got %s instead", args[0].Type())
			}

			var flag = os.O_RDONLY
			if l == 2 {
				mode, ok := args[1].(String)
				if !ok {
					return NewError("open: second argument must be a string, got %s instead", args[1].Type())
				}
				parsed, err := parseFlag(string(mode))
				if err != nil {
					return NewError("open: %v", err)
				}
				flag = parsed
			}

			ret, err := NewFile(string(path), flag)
			if err != nil {
				return NewError("open: %v", err)
			}
			return ret
		},
	},
	{
		"bytes",
		func(args ...Object) Object {
			if len(args) != 1 {
				return NewError("bytes: expected 1 argument but got %d", len(args))
			}

			args = UnwrapAll(args)
			switch a := args[0].(type) {
			case String:
				return Bytes(a)
			case Integer:
				return make(Bytes, a)
			case List:
				ret := make(Bytes, len(a))
				for i, e := range a {
					integer, ok := e.(Integer)
					if !ok {
						return NewError("bytes: list cannot be converted to bytes")
					}
					ret[i] = byte(integer)
				}
				return ret
			default:
				return NewError("bytes: %s cannot be converted to bytes", a.Type())
			}
		},
	},
}

Functions

func ImportLookup added in v1.2.0

func ImportLookup(taupath string) (string, error)

func Printf added in v1.4.0

func Printf(s string, a ...any)

func Println added in v1.4.0

func Println(a ...any)

Types

type Boolean

type Boolean bool

func (Boolean) KeyHash

func (b Boolean) KeyHash() KeyHash

func (Boolean) String

func (b Boolean) String() string

func (Boolean) Type

func (b Boolean) Type() Type

func (Boolean) Val

func (b Boolean) Val() bool

type Break

type Break struct{}

func (Break) String

func (b Break) String() string

func (Break) Type

func (b Break) Type() Type

type Builtin

type Builtin func(args ...Object) Object

func ResolveBuiltin

func ResolveBuiltin(name string) (Builtin, bool)

func (Builtin) String

func (b Builtin) String() string

func (Builtin) Type

func (b Builtin) Type() Type

type BuiltinImpl added in v1.4.3

type BuiltinImpl struct {
	Name    string
	Builtin Builtin
}

type Bytes added in v1.3.0

type Bytes []byte

func (Bytes) String added in v1.3.0

func (bytes Bytes) String() string

func (Bytes) Type added in v1.3.0

func (b Bytes) Type() Type

func (Bytes) Val added in v1.3.0

func (b Bytes) Val() []byte

type Class

type Class struct {
	Store
}

func (Class) String

func (c Class) String() string

func (Class) Type

func (c Class) Type() Type

type Closure

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

func NewClosure

func NewClosure(fn *CompiledFunction, free []Object) *Closure

func (*Closure) String

func (c *Closure) String() string

func (*Closure) Type

func (c *Closure) Type() Type

type CompiledFunction added in v1.3.1

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

func (CompiledFunction) String added in v1.3.1

func (c CompiledFunction) String() string

func (CompiledFunction) Type added in v1.3.1

func (c CompiledFunction) Type() Type

type Continue

type Continue struct{}

func (Continue) String

func (c Continue) String() string

func (Continue) Type

func (c Continue) Type() Type

type Env

type Env struct {
	Outer *Env
	Store Store
	// contains filtered or unexported fields
}

func NewEnv

func NewEnv(path string) *Env

func NewEnvWrap

func NewEnvWrap(e *Env) *Env

func (*Env) Dir added in v1.3.0

func (e *Env) Dir() string

func (*Env) File added in v1.3.1

func (e *Env) File() string

func (*Env) Get

func (e *Env) Get(n string) (Object, bool)

func (*Env) Module added in v1.2.0

func (e *Env) Module() *Module

func (*Env) Set

func (e *Env) Set(n string, o Object) Object

type Error

type Error string

func (Error) String

func (e Error) String() string

func (Error) Type

func (e Error) Type() Type

func (Error) Val

func (e Error) Val() string

type Evaluable added in v1.3.1

type Evaluable interface {
	Eval(*Env) Object
}

type Float

type Float float64

func (Float) KeyHash

func (f Float) KeyHash() KeyHash

func (Float) String

func (f Float) String() string

func (Float) Type

func (f Float) Type() Type

func (Float) Val

func (f Float) Val() float64

type Function

type Function struct {
	Params []string
	Body   Evaluable
	Env    *Env
}

func (Function) String

func (f Function) String() string

func (Function) Type

func (f Function) Type() Type

type GetSetter

type GetSetter interface {
	Object
	Getter
	Setter
}

type GetSetterImpl

type GetSetterImpl struct {
	GetFunc func() (Object, bool)
	SetFunc func(Object) Object
}

func (GetSetterImpl) Object

func (g GetSetterImpl) Object() Object

func (GetSetterImpl) Set

func (g GetSetterImpl) Set(o Object) Object

func (GetSetterImpl) String

func (g GetSetterImpl) String() string

func (GetSetterImpl) Type

func (g GetSetterImpl) Type() Type

type Getter

type Getter interface {
	Object() Object
}

type Hashable

type Hashable interface {
	KeyHash() KeyHash
}

type Integer

type Integer int64

func (Integer) KeyHash

func (i Integer) KeyHash() KeyHash

func (Integer) String

func (i Integer) String() string

func (Integer) Type

func (i Integer) Type() Type

func (Integer) Val

func (i Integer) Val() int64

type KeyHash

type KeyHash struct {
	Type  Type
	Value uint64
}

type List

type List []Object

func (List) String

func (l List) String() string

func (List) Type

func (l List) Type() Type

func (List) Val

func (l List) Val() []Object

type Map

type Map map[KeyHash]MapPair

func NewMap

func NewMap() Map

func (Map) Get

func (m Map) Get(k KeyHash) MapPair

func (Map) Set

func (m Map) Set(k KeyHash, v MapPair)

func (Map) String

func (m Map) String() string

func (Map) Type

func (m Map) Type() Type

type MapGetSetter

type MapGetSetter interface {
	Get(string) (Object, bool)
	Set(string, Object) Object
}

type MapPair

type MapPair struct {
	Key   Object
	Value Object
}

type Module added in v1.2.0

type Module struct {
	Exported   map[string]Object
	Unexported map[string]Object
}

func NewModule added in v1.2.0

func NewModule() *Module

func (*Module) Get added in v1.2.0

func (m *Module) Get(n string) (Object, bool)

func (*Module) Set added in v1.2.0

func (m *Module) Set(n string, o Object) Object

func (Module) String added in v1.2.0

func (m Module) String() string

func (Module) Type added in v1.2.0

func (m Module) Type() Type

type Moduler added in v1.2.0

type Moduler interface {
	Module() *Module
}

type NativePlugin

type NativePlugin struct {
	*plugin.Plugin
}

func (*NativePlugin) Get

func (n *NativePlugin) Get(name string) (Object, bool)

func (*NativePlugin) Set

func (n *NativePlugin) Set(name string, o Object) Object

func (NativePlugin) String

func (n NativePlugin) String() string

func (NativePlugin) Type

func (n NativePlugin) Type() Type

type NativeStruct

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

func (*NativeStruct) Get

func (n *NativeStruct) Get(name string) (Object, bool)

func (*NativeStruct) Set

func (n *NativeStruct) Set(name string, o Object) Object

func (NativeStruct) String

func (n NativeStruct) String() string

func (NativeStruct) Type

func (n NativeStruct) Type() Type

type Null

type Null struct{}

func (Null) String

func (n Null) String() string

func (Null) Type

func (n Null) Type() Type

func (Null) Val

func (n Null) Val() any

type Object

type Object interface {
	Type() Type
	String() string
}

func NewBoolean

func NewBoolean(b bool) Object

func NewBreak

func NewBreak() Object

func NewBytes added in v1.3.0

func NewBytes(b []byte) Object

func NewClass

func NewClass() Object

func NewContinue

func NewContinue() Object

func NewError

func NewError(f string, a ...any) Object

func NewFile added in v1.3.0

func NewFile(path string, flag int) (Object, error)

func NewFloat

func NewFloat(f float64) Object

func NewFunction

func NewFunction(params []string, env *Env, body Evaluable) Object

func NewFunctionCompiled

func NewFunctionCompiled(i code.Instructions, nLocals, nParams int) Object

func NewInteger

func NewInteger(i int64) Object

func NewList

func NewList(elems ...Object) Object

func NewNativePlugin

func NewNativePlugin(path string) Object

func NewNativeStruct

func NewNativeStruct(s any) Object

func NewNull

func NewNull() Object

func NewPipe added in v1.4.0

func NewPipe() Object

func NewPipeBuffered added in v1.4.0

func NewPipeBuffered(n int) Object

func NewReturn

func NewReturn(o Object) Object

func NewString

func NewString(s string) Object

func ParseBool

func ParseBool(b bool) Object

func Unwrap

func Unwrap(o Object) Object

func UnwrapAll added in v1.4.4

func UnwrapAll(a []Object) []Object

type Pipe added in v1.4.0

type Pipe chan Object

func (Pipe) String added in v1.4.0

func (p Pipe) String() string

func (Pipe) Type added in v1.4.0

func (p Pipe) Type() Type

type Return

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

func (Return) String

func (r Return) String() string

func (Return) Type

func (r Return) Type() Type

func (Return) Val

func (r Return) Val() Object

type Setter

type Setter interface {
	Set(Object) Object
}

type Store added in v1.3.1

type Store map[string]Object

func NewStore added in v1.3.1

func NewStore() Store

func (Store) Get added in v1.3.1

func (s Store) Get(n string) (Object, bool)

func (Store) Module added in v1.3.1

func (s Store) Module() *Module

func (Store) Set added in v1.3.1

func (s Store) Set(n string, o Object) Object

type String

type String string

func (String) KeyHash

func (s String) KeyHash() KeyHash

func (String) Quoted

func (s String) Quoted() string

func (String) String

func (s String) String() string

func (String) Type

func (s String) Type() Type

func (String) Val

func (s String) Val() string

type Type

type Type int
const (
	NullType     Type = iota // null
	ErrorType                // error
	IntType                  // int
	FloatType                // float
	BoolType                 // bool
	StringType               // string
	BytesType                // bytes
	ObjectType               // object
	ReturnType               // return
	FunctionType             // function
	ClosureType              // closure
	BuiltinType              // builtin
	ListType                 // list
	MapType                  // map
	ContinueType             // continue
	BreakType                // break
	PipeType                 // pipe
)

func (Type) String

func (i Type) String() string

Jump to

Keyboard shortcuts

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