lib

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: May 3, 2024 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ArrayPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					var b strings.Builder
					b.WriteString("[")
					for i, v := range ctx.This.(*Array).Elements {
						if i > 0 {
							b.WriteString(", ")
						}
						b.WriteString(ToString(ctx.Interp, ctx.Scope, v))
					}
					b.WriteString("]")
					return NewReturn(NewString(b.String()))
				},
			},

			"push": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) < 1 {
					ctx.Interp.Throw("push(value): expected at least 1 argument")
				}

				values := ctx.This.(*Array).Elements

				if len(ctx.Args) >= 1 {
					values = append(values, ctx.Args[0:]...)
				}

				ctx.This.(*Array).Elements = values
				return NewReturn(values)
			}},
			"sort": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) < 1 {
					ctx.Interp.Throw("sort(func): expected at least 1 argument")
				}

				array := ctx.This.(*Array).Elements
				comparator := ctx.Args[0]
				if _, ok := comparator.(*Func); !ok {
					ctx.Interp.Throw("sort(func): expected func to be a function")
				}

				c := make([]Value, len(array))
				copy(c, array)
				sort.Slice(c, func(i, j int) bool {
					a := c[i]
					b := c[j]
					ret := comparator.(*Func).Executor(&FuncContext{
						Interp: ctx.Interp,
						Scope:  ctx.Scope,
						This:   Wrap(nil),
						Args:   []Value{a, b},
					})

					if ret == nil {
						ctx.Interp.Throw("sort(func): expected function to return a value")
						panic(0)
					}

					if _, ok := ret.Value.(*Integer); !ok {
						ctx.Interp.Throw("sort(func): expected function to return a number")
					}

					return ret.Value.(*Integer).Value.Cmp(big.NewInt(0)) == -1
				})

				return NewReturn(c)
			}},
			"map": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) < 1 {
					ctx.Interp.Throw("map(func): expected at least 1 argument")
				}

				array := ctx.This.(*Array).Elements
				mapper := ctx.Args[0]
				if _, ok := mapper.(*Func); !ok {
					ctx.Interp.Throw("map(func): expected func to be a function")
				}

				c := make([]Value, len(array))
				for i, v := range array {
					ret := mapper.(*Func).Executor(&FuncContext{
						Interp: ctx.Interp,
						Scope:  ctx.Scope,
						This:   Wrap(nil),
						Args:   []Value{v, Wrap(i)},
					})

					c[i] = ret.Value
				}

				return NewReturn(c)
			}},
			"join": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) < 1 {
					ctx.Interp.Throw("join(sep): expected at least 1 argument")
				}

				array := ctx.This.(*Array).Elements
				sep := ctx.Args[0].(*String).Value

				var b strings.Builder
				for i, v := range array {
					if i > 0 {
						b.WriteString(sep)
					}
					b.WriteString(ToString(ctx.Interp, ctx.Scope, v))
				}

				return NewReturn(b.String())
			}},
		},
	},
	Operators: Operators{
		token.Eq: OpFunc(func(c *OpContext[*Array, Value]) Value {
			switch o := c.Other.(type) {
			case *Array:
				if len(c.This.Elements) != len(o.Elements) {
					return FalseValue
				}
				for i, e := range c.This.Elements {
					op := GetOperator(e, token.Eq)
					if op == nil {
						c.Interp.Throw("array element is not comparable")
						panic(0)
					}
					ret := op.Executor(&FuncContext{
						Interp: c.Interp,
						Scope:  c.Scope,
						This:   e,
						Args:   []Value{o.Elements[i]},
					})
					if !ret.Value.(*Bool).Value {
						return FalseValue
					}
				}
				return TrueValue
			default:
				return FalseValue
			}
		}),
	},
}
View Source
var BoolFrom = map[bool]*Bool{
	// contains filtered or unexported fields
}
View Source
var BoolPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					if ctx.This.(*Bool).Value {
						return NewReturn(NewString("true"))
					} else {
						return NewReturn(NewString("false"))
					}
				},
			},
		},
	},
}
View Source
var FalseValue = &Bool{false}
View Source
var FloatPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					return NewReturn(NewString(strconv.FormatFloat(ctx.This.(*Float).Value, 'f', -1, 64)))
				},
			},
		},
	},
	Operators: Operators{
		token.Eq: OpFunc(func(c *OpContext[*Float, Value]) Value {
			if _, ok := c.Other.(*Float); ok {
				return BoolFrom[c.This.Value == c.Other.(*Float).Value]
			}
			return FalseValue
		}),
		token.Add: OpFunc(func(c *OpContext[*Float, Value]) Value {
			if c.Other == nil {
				return c.This
			}
			switch o := c.Other.(type) {
			case Numeric:
				return &Float{c.This.Value + o.Float64()}
			case *String:
				return NewString(strconv.FormatFloat(c.This.Value, 'f', -1, 64) + o.Value)
			default:
				c.Interp.Throw(operatorNotDefined("Float", token.Add, o.Type()))
				return nil
			}
		}),
		token.Gt: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			return BoolFrom[c.This.Value > c.Other.Float64()]
		}),
		token.Sub: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			if c.Other == nil {
				return &Float{-c.This.Value}
			}

			return &Float{c.This.Value - c.Other.Float64()}
		}),
		token.Mul: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			return &Float{c.This.Value * c.Other.Float64()}
		}),
		token.Quo: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			return &Float{c.This.Value / c.Other.Float64()}
		}),
		token.Rem: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			return &Float{math.Mod(c.This.Value, c.Other.Float64())}
		}),
		token.Pow: OpFunc(func(c *OpContext[*Float, Numeric]) Value {
			return &Float{math.Pow(c.This.Value, c.Other.Float64())}
		}),
	},
}
View Source
var FuncPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
}
View Source
var IntegerPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					base := 10
					if len(ctx.Args) >= 1 {
						base = int(ctx.Args[0].(*Integer).Value.Int64())
						if base < 2 || base > 62 {
							ctx.Interp.Throw("base must be between 2 and 62")
						}
					}
					return NewReturn(NewString(ctx.This.(*Integer).Value.Text(base)))
				},
			},
		},
	},
	Operators: Operators{
		token.Eq: OpFunc(func(c *OpContext[*Integer, Value]) Value {
			if i, ok := c.Other.(*Integer); ok {
				return BoolFrom[c.This.Value.Cmp(i.Value) == 0]
			}
			return FalseValue
		}),
		token.LogNot: OpFunc(func(c *OpContext[*Integer, Value]) Value {
			return BoolFrom[c.This.Value.Cmp(big.NewInt(0)) == 0]
		}),
		token.Add: OpFunc(func(c *OpContext[*Integer, Value]) Value {
			if c.Other == nil {
				return c.This
			}
			switch o := c.Other.(type) {
			case *Integer:
				res := new(big.Int)
				res.Add(c.This.Value, o.Value)
				return &Integer{res}
			case *Float:
				f, _ := c.This.Value.Float64()
				return &Float{f + o.Value}
			case *String:
				return NewString(c.This.Value.Text(10) + o.Value)
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Add, o.Type()))
				return nil
			}
		}),
		token.Gt: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			switch o := c.Other.(type) {
			case *Integer:
				return BoolFrom[c.This.Value.Cmp(o.Value) > 0]
			case *Float:
				f, _ := c.This.Value.Float64()
				return BoolFrom[f > o.Value]
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Gt, o.Type()))
				return nil
			}
		}),
		token.Sub: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			if c.Other == nil {
				n := new(big.Int)
				n.Neg(c.This.Value)
				return &Integer{n}
			}
			switch o := c.Other.(type) {
			case *Integer:
				res := new(big.Int)
				res.Sub(c.This.Value, o.Value)
				return &Integer{res}
			case *Float:
				f, _ := c.This.Value.Float64()
				return &Float{f - o.Value}
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Sub, o.Type()))
				return nil
			}
		}),
		token.Mul: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			switch o := c.Other.(type) {
			case *Integer:
				res := new(big.Int)
				res.Mul(c.This.Value, o.Value)
				return &Integer{res}
			case *Float:
				f, _ := c.This.Value.Float64()
				return &Float{f * o.Value}
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Mul, o.Type()))
				return nil
			}
		}),
		token.Quo: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			switch o := c.Other.(type) {
			case *Integer:
				if o.Value.Cmp(big.NewInt(0)) == 0 {
					c.Interp.Throw("division by zero")
				}
				res := new(big.Int)
				res.Quo(c.This.Value, o.Value)
				return &Integer{res}
			case *Float:
				if o.Value == 0 {
					c.Interp.Throw("division by zero")
				}
				f, _ := c.This.Value.Float64()
				return &Float{f / o.Value}
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Quo, o.Type()))
				return nil
			}
		}),
		token.BitAnd: OpFunc(func(c *OpContext[*Integer, *Integer]) Value {
			res := new(big.Int)
			res.And(c.This.Value, c.Other.Value)
			return &Integer{res}
		}),
		token.BitOr: OpFunc(func(c *OpContext[*Integer, *Integer]) Value {
			res := new(big.Int)
			res.Or(c.This.Value, c.Other.Value)
			return &Integer{res}
		}),
		token.BitXor: OpFunc(func(c *OpContext[*Integer, *Integer]) Value {
			res := new(big.Int)
			res.Xor(c.This.Value, c.Other.Value)
			return &Integer{res}
		}),
		token.BitNot: OpFunc(func(c *OpContext[*Integer, *Integer]) Value {
			res := new(big.Int)
			res.Not(c.This.Value)
			return &Integer{res}
		}),
		token.Rem: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			switch o := c.Other.(type) {
			case *Integer:
				if o.Value.Cmp(big.NewInt(0)) == 0 {
					c.Interp.Throw("division by zero")
				}
				res := new(big.Int)
				res.Rem(c.This.Value, o.Value)
				return &Integer{res}
			case *Float:
				f, _ := c.This.Value.Float64()
				return &Float{math.Mod(f, o.Value)}
			default:
				c.Interp.Throw(operatorNotDefined(c.This.Type(), token.Rem, o.Type()))
				return nil
			}
		}),
		token.Pow: OpFunc(func(c *OpContext[*Integer, Numeric]) Value {
			f, _ := c.This.Value.Float64()
			return &Float{math.Pow(f, c.Other.Float64())}
		}),
	},
}
View Source
var NullPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					return NewReturn(NewString("null"))
				},
			},
		},
	},
	Operators: Operators{
		token.Eq: OpFunc(func(c *OpContext[Value, Value]) Value {
			_, ok := c.Other.(*Null)
			return BoolFrom[ok]
		}),
		token.LogNot: OpFunc(func(c *OpContext[Value, Value]) Value {
			return TrueValue
		}),
	},
}
View Source
var NullValue = &Null{}
View Source
var Object = &Composite{
	Name:   "Object",
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					proto := ctx.This.Prototype()
					name := ctx.This.Type()
					if proto != nil && proto.Name != "" {
						name = proto.Name
					}
					return &Return{&String{"<object " + name + ">"}}
				},
			},
			"toDebugString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					if _, ok := ctx.This.(*Composite); !ok {
						toString := GetProperty(ctx.This, NewString("toString")).(*Func)

						return toString.Executor(&FuncContext{
							Interp: ctx.Interp,
							Scope:  ctx.Scope,
							This:   ctx.This,
						})
					}
					depth := 0
					if len(ctx.Args) > 0 {
						if _, ok := ctx.Args[0].(*Integer); !ok {
							ctx.Interp.Throw("toDebugString(depth): expected integer as first argument")
						} else {
							depth = int(ctx.Args[0].(*Integer).Value.Int64())
						}
					}
					var sb strings.Builder
					proto := ctx.This.Prototype()
					name := ctx.This.Type()
					if proto != nil {
						name = proto.Name
					}
					indent := strings.Repeat("  ", depth)
					sb.WriteString(name + " {\n")
					for k, v := range ctx.This.(*Composite).Properties[PKString] {
						sb.WriteString(indent + "  " + k + ": " + ToDebugString(ctx.Interp, ctx.Scope, v, depth+1) + ",\n")
					}
					for k, v := range ctx.This.(*Composite).Properties[PKInteger] {
						sb.WriteString(indent + "  [" + k + "]: " + ToDebugString(ctx.Interp, ctx.Scope, v, depth+1) + ",\n")
					}
					for k, v := range ctx.This.(*Composite).Properties[PKSymbol] {
						sb.WriteString(indent + "  [" + k + "]: " + ToDebugString(ctx.Interp, ctx.Scope, v, depth+1) + ",\n")
					}
					sb.WriteString(indent + "}")
					return &Return{&String{sb.String()}}
				},
			},
		},
	},
	Operators: Operators{
		token.Assign: OpFunc(func(c *OpContext[Value, Value]) Value {
			return c.Other
		}),
		token.Eq: OpFunc(func(c *OpContext[Value, Value]) Value {
			return BoolFrom[c.This == c.Other]
		}),
		token.LogNot: OpFunc(func(c *OpContext[Value, Value]) Value {
			return BoolFrom[!IsTruthy(c.This)]
		}),
		token.Question: OpFunc(func(c *OpContext[Value, Value]) Value {
			prop := GetProperty(c.This, NewString("toString"))
			if prop == nil {
				return &String{"<unknown>"}
			}

			if _, ok := prop.(*Func); !ok {
				return &String{"<object Func>"}
			}

			ret := prop.(*Func).Executor(&FuncContext{
				Interp: c.Interp,
				Scope:  c.Scope,
				This:   c.This,
			})

			return ret.Value
		}),
		token.LogAnd: OpFunc(func(c *OpContext[Value, Value]) Value {
			if IsTruthy(c.This) {
				return c.Other
			} else {
				return c.This
			}
		}),
		token.LogOr: OpFunc(func(c *OpContext[Value, Value]) Value {
			if IsTruthy(c.This) {
				return c.This
			} else {
				return c.Other
			}
		}),
		token.LogNull: OpFunc(func(c *OpContext[Value, Value]) Value {
			_, ok := c.This.(*Null)
			if ok {
				return c.Other
			} else {
				return c.This
			}
		}),
		token.Is: OpFunc(func(c *OpContext[Value, Value]) Value {
			p1 := c.This.Prototype()
			p2 := c.Other
			for p2 != nil {
				if p1 == p2 {
					return TrueValue
				}
				switch x := p2.(type) {
				case *Func:
					p2 = x.NewableProto
				case *Composite:
					if x == nil {
						return FalseValue
					}
					p2 = x.Prototype()
				default:
					p2 = p2.Prototype()
				}

			}

			return FalseValue
		}),
	},
}
View Source
var RangePrototype = &Composite{
	Name:   "Range",
	Proto:  Object,
	Frozen: true,
}
View Source
var ReturnFalse = NewReturn(FalseValue)
View Source
var ReturnNull = NewReturn(NullValue)
View Source
var ReturnTrue = NewReturn(TrueValue)
View Source
var StringPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{Executor: func(ctx *FuncContext) *Return {
				return NewReturn(&ctx.This)
			}},
			"split": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					return NewReturn([]Value{ctx.This})
				}
				s := ToString(ctx.Interp, ctx.Scope, ctx.Args[0])
				return NewReturn(strings.Split(ctx.This.(*String).Value, s))
			}},
			"padLeft": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					ctx.Interp.Throw("padLeft(x): expected 1 argument")
				}
				if _, ok := ctx.Args[0].(Numeric); !ok {
					ctx.Interp.Throw("padLeft(x): expected integer as first argument")
				}
				pad := " "
				if len(ctx.Args) == 2 {
					if _, ok := ctx.Args[1].(*String); !ok {
						ctx.Interp.Throw("padLeft(x, y): expected string as second argument")
					}
					pad = ctx.Args[1].(*String).Value
				}

				n := ctx.Args[0].(Numeric).Int()
				needed := n - len(ctx.This.(*String).Value)
				out := ctx.This.(*String).Value
				for needed > 0 {
					out = pad + out
					needed -= len(pad)
				}

				return NewReturn(NewString(out))
			}},
			"padRight": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					ctx.Interp.Throw("padRight(x): expected 1 argument")
				}
				if _, ok := ctx.Args[0].(Numeric); !ok {
					ctx.Interp.Throw("padRight(x): expected integer as first argument")
				}
				n := ctx.Args[0].(Numeric).Int()
				return NewReturn(NewString(fmt.Sprintf("%-*s", n, ctx.This.(*String).Value)))
			}},
			"slice": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) != 1 && len(ctx.Args) != 2 {
					ctx.Interp.Throw("slice(x, y): expected 2 arguments")
				}
				if _, ok := ctx.Args[0].(Numeric); !ok {
					ctx.Interp.Throw("slice(x, y): expected integer as first argument")
				}
				if len(ctx.Args) == 2 && ctx.Args[1] != nil {
					if _, ok := ctx.Args[1].(Numeric); !ok {
						ctx.Interp.Throw("slice(x, y): expected integer as second argument")
					}
				}
				x := ctx.Args[0].(Numeric).Int()
				y := len(ctx.This.(*String).Value)
				if len(ctx.Args) == 2 && ctx.Args[1] != nil {
					y = ctx.Args[1].(Numeric).Int()
				}
				if x < 0 {
					x = len(ctx.This.(*String).Value) + x
				}
				if y < 0 {
					y = len(ctx.This.(*String).Value) + y
				}
				return NewReturn(NewString(ctx.This.(*String).Value[x:y]))
			}},
			"trim": &Func{Executor: func(ctx *FuncContext) *Return {
				return NewReturn(NewString(strings.TrimSpace(ctx.This.(*String).Value)))
			}},
			"endsWith": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					ctx.Interp.Throw("endsWith(x): expected 1 argument")
				}
				if _, ok := ctx.Args[0].(*String); !ok {
					ctx.Interp.Throw("endsWith(x): expected string as first argument")
				}
				return NewReturn(&Bool{strings.HasSuffix(ctx.This.(*String).Value, ctx.Args[0].(*String).Value)})
			}},
			"startsWith": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					ctx.Interp.Throw("startsWith(x): expected 1 argument")
				}
				if _, ok := ctx.Args[0].(*String); !ok {
					ctx.Interp.Throw("startsWith(x): expected string as first argument")
				}
				return NewReturn(&Bool{strings.HasPrefix(ctx.This.(*String).Value, ctx.Args[0].(*String).Value)})
			}},
			"toUpperCase": &Func{Executor: func(ctx *FuncContext) *Return {
				return NewReturn(NewString(strings.ToUpper(ctx.This.(*String).Value)))
			}},
			"toLowerCase": &Func{Executor: func(ctx *FuncContext) *Return {
				return NewReturn(NewString(strings.ToLower(ctx.This.(*String).Value)))
			}},
			"charCodeAt": &Func{Executor: func(ctx *FuncContext) *Return {
				if len(ctx.Args) == 0 {
					ctx.Interp.Throw("charCodeAt(x): expected 1 argument")
				}
				if _, ok := ctx.Args[0].(Numeric); !ok {
					ctx.Interp.Throw("charCodeAt(x): expected integer as first argument")
				}
				i := ctx.Args[0].(Numeric).Int()
				if i < 0 || i >= len(ctx.This.(*String).Value) {
					ctx.Interp.Throw("charCodeAt: index out of bounds")
				}
				return NewReturn(NewInteger(big.NewInt(int64(int32(rune(ctx.This.(*String).Value[i]))))))
			}},
		},
	},
	Operators: Operators{
		token.Eq: OpFunc(func(c *OpContext[*String, Value]) Value {
			switch o := c.Other.(type) {
			case *String:
				return &Bool{c.This.Value == o.Value}
			default:
				return FalseValue
			}
		}),
		token.Add: OpFunc(func(c *OpContext[*String, Value]) Value {
			return NewString(c.This.Value + ToString(c.Interp, c.Scope, c.Other))
		}),
		token.Mul: OpFunc(func(c *OpContext[*String, Value]) Value {
			if n, ok := c.Other.(Numeric); ok {
				return NewString(strings.Repeat(c.This.Value, n.Int()))
			}
			c.Interp.Throw("cannot multiply string by non-integer")
			return nil
		}),
	},
}
View Source
var SymbolPrototype = &Composite{
	Proto:  Object,
	Frozen: true,
	Properties: Properties{
		PKString: {
			"toString": &Func{
				Executor: func(ctx *FuncContext) *Return {
					return NewReturn(NewString(ctx.This.(*Symbol).Name))
				},
			},
		},
	},
}
View Source
var TrueValue = &Bool{true}
View Source
var YieldNull = NewYield(NullValue)

Functions

func IsTruthy

func IsTruthy(v Value) bool

func PrintExpr

func PrintExpr(x ast.Expr) string

func SetProperty

func SetProperty(v Value, key PropertyKey, val Value) error

func ToDebugString

func ToDebugString(i Interpreter, scope *Scope, v Value, depth int) string

func ToString

func ToString(i Interpreter, scope *Scope, v Value) string

Types

type Array

type Array struct {
	Elements []Value
	Frozen   bool
}

func NewArray

func NewArray(values ...Value) *Array

func (*Array) Clone

func (a *Array) Clone() Value

func (*Array) Freeze

func (a *Array) Freeze()

func (*Array) Hash

func (a *Array) Hash() string

func (*Array) Prototype

func (a *Array) Prototype() *Composite

func (*Array) Type

func (*Array) Type() string

func (*Array) Unfreeze

func (a *Array) Unfreeze()

func (*Array) Unwrap

func (a *Array) Unwrap() any

type Bool

type Bool struct{ Value bool }

func (*Bool) Clone

func (b *Bool) Clone() Value

func (*Bool) Freeze

func (b *Bool) Freeze()

func (*Bool) Hash

func (b *Bool) Hash() string

func (*Bool) Prototype

func (b *Bool) Prototype() *Composite

func (*Bool) Type

func (*Bool) Type() string

func (*Bool) Unfreeze

func (b *Bool) Unfreeze()

func (*Bool) Unwrap

func (b *Bool) Unwrap() any

type Break

type Break struct{}

func NewBreak

func NewBreak() *Break

type Composite

type Composite struct {
	Name       string
	Proto      *Composite
	Properties Properties
	Operators  Operators
	Frozen     bool
}

func NewComposite

func NewComposite() *Composite

func (*Composite) Clone

func (c *Composite) Clone() Value

func (*Composite) Freeze

func (c *Composite) Freeze()

func (*Composite) Hash

func (c *Composite) Hash() string

func (*Composite) Prototype

func (c *Composite) Prototype() *Composite

func (*Composite) Type

func (*Composite) Type() string

func (*Composite) Unfreeze

func (c *Composite) Unfreeze()

func (*Composite) Unwrap

func (c *Composite) Unwrap() any

type Continue

type Continue struct{}

func NewContinue

func NewContinue() *Continue

type Decl

type Decl struct {
	Value Value
	Name  string
}

func NewDecl

func NewDecl(value Value, name string) *Decl

type Export

type Export struct {
	Value Value
	Name  string
}

func NewExport

func NewExport(value Value, name string) *Export

type Float

type Float struct{ Value float64 }

func NewFloat

func NewFloat(f float64) *Float

func (*Float) BigInt

func (f *Float) BigInt() *big.Int

func (*Float) Clone

func (f *Float) Clone() Value

func (*Float) Float64

func (f *Float) Float64() float64

func (*Float) Freeze

func (f *Float) Freeze()

func (*Float) Hash

func (f *Float) Hash() string

func (*Float) Int

func (f *Float) Int() int

func (*Float) Int64

func (f *Float) Int64() int64

func (*Float) Prototype

func (f *Float) Prototype() *Composite

func (*Float) Type

func (*Float) Type() string

func (*Float) Unfreeze

func (f *Float) Unfreeze()

func (*Float) Unwrap

func (f *Float) Unwrap() any

type FloatRange

type FloatRange struct {
	Start float64
	Stop  float64
	Step  float64
}

func (*FloatRange) Clone

func (r *FloatRange) Clone() Value

func (*FloatRange) Contains

func (r *FloatRange) Contains(f *Float) bool

func (*FloatRange) Freeze

func (r *FloatRange) Freeze()

func (*FloatRange) Hash

func (r *FloatRange) Hash() string

func (*FloatRange) Prototype

func (r *FloatRange) Prototype() *Composite

func (*FloatRange) Type

func (*FloatRange) Type() string

func (*FloatRange) Unfreeze

func (r *FloatRange) Unfreeze()

func (*FloatRange) Unwrap

func (r *FloatRange) Unwrap() any

type Func

type Func struct {
	Executor     FuncType
	Async        bool
	Memoized     bool
	This         Value
	NewableProto *Composite
	Frozen       bool
}

func (*Func) Clone

func (f *Func) Clone() Value

func (*Func) Freeze

func (f *Func) Freeze()

func (*Func) Hash

func (f *Func) Hash() string

func (*Func) Prototype

func (f *Func) Prototype() *Composite

func (*Func) Type

func (*Func) Type() string

func (*Func) Unfreeze

func (f *Func) Unfreeze()

func (*Func) Unwrap

func (f *Func) Unwrap() any

type FuncContext

type FuncContext struct {
	Interp Interpreter
	Scope  *Scope
	This   Value
	Args   []Value
}

type FuncType

type FuncType func(*FuncContext) *Return

type Generator

type Generator struct {
	Async   bool
	Channel chan GeneratorMessage
	Frozen  bool
}

func (*Generator) Clone

func (g *Generator) Clone() Value

func (*Generator) Freeze

func (g *Generator) Freeze()

func (*Generator) Hash

func (g *Generator) Hash() string

func (*Generator) Prototype

func (g *Generator) Prototype() *Composite

func (*Generator) Type

func (*Generator) Type() string

func (*Generator) Unfreeze

func (g *Generator) Unfreeze()

func (*Generator) Unwrap

func (g *Generator) Unwrap() any

type GeneratorDone

type GeneratorDone struct{}

type GeneratorError

type GeneratorError struct{ Error error }

type GeneratorIsDone

type GeneratorIsDone struct{ Done bool }

type GeneratorMessage

type GeneratorMessage interface {
	// contains filtered or unexported methods
}

type GeneratorNext

type GeneratorNext struct{ Value Value }

type GeneratorReturn

type GeneratorReturn struct{ Value Value }

type GeneratorYield

type GeneratorYield struct{ Value Value }

type IntRange

type IntRange struct {
	Start *big.Int
	Stop  *big.Int
	Step  *big.Int
}

func (*IntRange) Clone

func (r *IntRange) Clone() Value

func (*IntRange) Contains

func (r *IntRange) Contains(i *Integer) bool

func (*IntRange) Freeze

func (r *IntRange) Freeze()

func (*IntRange) Hash

func (r *IntRange) Hash() string

func (*IntRange) Prototype

func (r *IntRange) Prototype() *Composite

func (*IntRange) Type

func (*IntRange) Type() string

func (*IntRange) Unfreeze

func (r *IntRange) Unfreeze()

func (*IntRange) Unwrap

func (r *IntRange) Unwrap() any

type Integer

type Integer struct{ Value *big.Int }

func NewInteger

func NewInteger(i *big.Int) *Integer

func (*Integer) BigInt

func (i *Integer) BigInt() *big.Int

func (*Integer) CanonicalValue

func (i *Integer) CanonicalValue() string

func (*Integer) Clone

func (i *Integer) Clone() Value

func (*Integer) Float64

func (i *Integer) Float64() float64

func (*Integer) Freeze

func (i *Integer) Freeze()

func (*Integer) Hash

func (i *Integer) Hash() string

func (*Integer) Int

func (i *Integer) Int() int

func (*Integer) Int64

func (i *Integer) Int64() int64

func (*Integer) Prototype

func (i *Integer) Prototype() *Composite

func (*Integer) Type

func (*Integer) Type() string

func (*Integer) Unfreeze

func (i *Integer) Unfreeze()

func (*Integer) Unwrap

func (i *Integer) Unwrap() any

type Interpreter

type Interpreter interface {
	Stdin() io.Reader
	Stdout() io.Writer
	Stderr() io.Writer
	Modules() map[string]*Module
	Fset() *token.FileSet
	ExecutionStack() []*Module
	Global() *Scope
	GooseRoot() string

	CurrentModule() *Module

	Run() (exitCode int, err error)

	Throw(format string, args ...interface{})
}

type LoneValue

type LoneValue struct {
	Value Value
}

func NewLoneValue

func NewLoneValue(value Value) *LoneValue

type Module

type Module struct {
	*ast.Module
	Scope   *Scope
	Exports map[string]*Variable
}

type Null

type Null struct{}

func (*Null) Clone

func (n *Null) Clone() Value

func (*Null) Freeze

func (n *Null) Freeze()

func (*Null) Hash

func (n *Null) Hash() string

func (*Null) Prototype

func (n *Null) Prototype() *Composite

func (*Null) Type

func (*Null) Type() string

func (*Null) Unfreeze

func (n *Null) Unfreeze()

func (*Null) Unwrap

func (n *Null) Unwrap() any

type Numeric

type Numeric interface {
	Value

	Int() int
	Int64() int64
	BigInt() *big.Int
	Float64() float64
	// contains filtered or unexported methods
}

type OpContext

type OpContext[T Value, U Value] struct {
	Interp Interpreter
	Scope  *Scope
	This   T
	Other  U
}

type OperatorFunc

type OperatorFunc struct {
	Async    bool
	Builtin  bool
	Executor FuncType
}

func GetOperator

func GetOperator(v Value, tok token.Token) *OperatorFunc

func OpFunc

func OpFunc[T Value, U Value](op func(*OpContext[T, U]) Value) *OperatorFunc

type Operators

type Operators map[token.Token]*OperatorFunc

type Properties

type Properties map[PropertyKeyKind]map[string]Value

type PropertyKey

type PropertyKey interface {
	Value

	CanonicalValue() string
	// contains filtered or unexported methods
}

type PropertyKeyKind

type PropertyKeyKind int
const (
	PKString PropertyKeyKind = iota
	PKInteger
	PKSymbol
	NumPKKinds
)

type Return

type Return struct{ Value Value }

func NewReturn

func NewReturn[T ValueType](value T) *Return

type Scope

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

func NewGlobalScope

func NewGlobalScope(builtins map[string]*Variable) *Scope

func NewScope

func NewScope(owner ScopeOwner) *Scope

func (*Scope) Builtins

func (s *Scope) Builtins() *Scope

func (*Scope) Clone

func (s *Scope) Clone() *Scope

func (*Scope) Fork

func (s *Scope) Fork(owner ScopeOwner) *Scope

func (*Scope) Get

func (s *Scope) Get(name string) *Variable

func (*Scope) GetValue

func (s *Scope) GetValue(name string) Value

func (*Scope) Global

func (s *Scope) Global() *Scope

func (*Scope) Idents

func (s *Scope) Idents() map[string]*Variable

func (*Scope) IsDefined

func (s *Scope) IsDefined(name string) bool

func (*Scope) IsDefinedInCurrentScope

func (s *Scope) IsDefinedInCurrentScope(name string) bool

func (*Scope) Module

func (s *Scope) Module() *Module

func (*Scope) ModuleScope

func (s *Scope) ModuleScope() *Scope

func (*Scope) Owner

func (s *Scope) Owner() ScopeOwner

func (*Scope) Parent

func (s *Scope) Parent() *Scope

func (*Scope) Reparent

func (s *Scope) Reparent(parent *Scope) *Scope

func (*Scope) Set

func (s *Scope) Set(name string, value *Variable)

func (*Scope) SetModule

func (s *Scope) SetModule(module *Module)

func (*Scope) Update

func (s *Scope) Update(name string, value Value)

type ScopeOwner

type ScopeOwner int
const (
	ScopeOwnerFunc ScopeOwner = iota
	ScopeOwnerClosure
	ScopeOwnerDo
	ScopeOwnerArrayInit
	ScopeOwnerRepeat
	ScopeOwnerFor
	ScopeOwnerIf
	ScopeOwnerGlobal
	ScopeOwnerBuiltin
	ScopeOwnerModule
	ScopeOwnerPipeline
	ScopeOwnerBlock
	ScopeOwnerStruct
	ScopeOwnerGenerator
	ScopeOwnerImport
	ScopeOwnerMatch
)

func (ScopeOwner) String

func (s ScopeOwner) String() string

type SpreadValue

type SpreadValue struct {
	Value Value
}

func (*SpreadValue) Elements

func (s *SpreadValue) Elements() []Value

type StmtResult

type StmtResult interface {
	// contains filtered or unexported methods
}

type String

type String struct {
	Value string
}

func NewString

func NewString(s string) *String

func (*String) CanonicalValue

func (s *String) CanonicalValue() string

func (*String) Clone

func (s *String) Clone() Value

func (*String) Freeze

func (s *String) Freeze()

func (*String) Hash

func (s *String) Hash() string

func (*String) Prototype

func (s *String) Prototype() *Composite

func (*String) Type

func (*String) Type() string

func (*String) Unfreeze

func (s *String) Unfreeze()

func (*String) Unwrap

func (s *String) Unwrap() any

type Symbol

type Symbol struct {
	Name string
	Id   int64
}

func (*Symbol) CanonicalValue

func (s *Symbol) CanonicalValue() string

func (*Symbol) Clone

func (s *Symbol) Clone() Value

func (*Symbol) Freeze

func (s *Symbol) Freeze()

func (*Symbol) Hash

func (s *Symbol) Hash() string

func (*Symbol) Prototype

func (s *Symbol) Prototype() *Composite

func (*Symbol) Type

func (*Symbol) Type() string

func (*Symbol) Unfreeze

func (s *Symbol) Unfreeze()

func (*Symbol) Unwrap

func (s *Symbol) Unwrap() any

type Value

type Value interface {
	Type() string
	Prototype() *Composite
	Clone() Value
	Unwrap() any
	Freeze()
	Unfreeze()
	Hash() string
	// contains filtered or unexported methods
}

func GetProperty

func GetProperty(v Value, key PropertyKey) Value

func Wrap

func Wrap(value any) Value

type ValueType

type ValueType interface {
	string | float64 | bool | []any | []Value |
		[]string | []int | []int64 | []float64 | []bool |
		Null | Bool | String | Func | Integer | Float | Array | Composite | Generator | IntRange | FloatRange |
		*Null | *Bool | *String | *Func | *Integer | *Float | *Array | *Composite | *Generator | *IntRange | *FloatRange | *Value
}

type Variable

type Variable struct {
	Constant bool
	Value    Value
	Source   VariableSource
}

type VariableSource

type VariableSource int
const (
	VariableSourceDecl VariableSource = iota
	VariableSourceImport
)

type Void

type Void struct{}

func NewVoid

func NewVoid() *Void

type Yield

type Yield struct{ Value Value }

func NewYield

func NewYield[T ValueType](value T) *Yield

Jump to

Keyboard shortcuts

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