types

package
v0.0.0-...-a88034a Latest Latest
Warning

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

Go to latest
Published: Nov 21, 2024 License: GPL-3.0 Imports: 11 Imported by: 107

Documentation

Overview

Package types provides a framework for our mcl language values and types.

Index

Constants

View Source
const (
	// StructTag is the key we use in struct field names for key mapping.
	StructTag = "lang"

	// MaxInt8 is 127. It's max uint8: ^uint8(0), then we >> 1 for max int8.
	MaxInt8 = int((^uint8(0)) >> 1)
)

Variables

View Source
var (
	TypeBool    = NewType("bool")
	TypeStr     = NewType("str")
	TypeInt     = NewType("int")
	TypeFloat   = NewType("float")
	TypeListStr = NewType("[]str")
	TypeVariant = NewType("variant")
)

Basic types defined here as a convenience for use with Type.Cmp(X).

View Source
var (
	// ErrNilValue is returned when ValueOf() attempts to represent a nil
	// pointer as an mcl value. This is not supported in mcl.
	ErrNilValue = errors.New("cannot represent a nil golang value in mcl")

	// ErrInvalidValue is returned when ValueOf() is called on an invalid or
	// zero reflect.Value.
	ErrInvalidValue = errors.New("cannot represent invalid reflect.Value")
)

Functions

func Into

func Into(v Value, rv reflect.Value) error

Into mutates the given reflect.Value with the data represented by the Value.

Container types like map/list (and to a certain extent structs) will be cleared before adding the contained data such that the existing data doesn't affect the outcome, and the output reflect.Value directly maps to the input Value.

In almost every case, it is likely that the reflect.Value will be modified, instantiating nil pointers and even potentially partially filling data before returning an error. It should be assumed that if this returns an error, the reflect.Value passed in has been trashed and should be discarded before reuse.

func IsComparableKind

func IsComparableKind(kind Kind) bool

IsComparableKind returns true if you pass it a comparable kind. These have a Cmp method on the Value interface that won't panic. Notably KindFunc and any other special kinds are not present in this list.

func Iter

func Iter(typ *Type, fn func(*Type) error) error

Iter applies a function to each type in the top-level type. It stops if that function errors, and returns that error to the top-level caller. It panics if it encounters an invalid or partial type struct. This version starts at the top and works its way deeper.

func TypeStructTagToFieldName

func TypeStructTagToFieldName(st reflect.Type) (map[string]string, error)

TypeStructTagToFieldName returns a mapping from recommended alias to actual field name. It returns an error if it finds a collision. It uses the `lang` tags. It must be passed a reflect.Type representation of a struct or it will error. TODO: This is a copy of engineUtil.StructTagToFieldName taking a reflect.Type

Types

type Base

type Base struct{}

Base implements the missing methods that all types need.

func (*Base) Bool

func (obj *Base) Bool() bool

Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.

func (*Base) Float

func (obj *Base) Float() float64

Float represents the value of this type as a float if it is one. If this is not a float, then this panics.

func (*Base) Func

func (obj *Base) Func() interface{}

Func represents the value of this type as a function if it is one. If this is not a function, then this panics.

func (*Base) Int

func (obj *Base) Int() int64

Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.

func (*Base) List

func (obj *Base) List() []Value

List represents the value of this type as a list if it is one. If this is not a list, then this panics.

func (*Base) Map

func (obj *Base) Map() map[Value]Value

Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.

func (*Base) Str

func (obj *Base) Str() string

Str represents the value of this type as a string if it is one. If this is not a string, then this panics.

func (*Base) Struct

func (obj *Base) Struct() map[string]Value

Struct represents the value of this type as a struct if it is one. If this is not a struct, then this panics.

type BoolValue

type BoolValue struct {
	Base
	V bool
}

BoolValue represents a boolean value.

func NewBool

func NewBool() *BoolValue

NewBool creates a new boolean value.

func (*BoolValue) Bool

func (obj *BoolValue) Bool() bool

Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.

func (*BoolValue) Cmp

func (obj *BoolValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*BoolValue) Copy

func (obj *BoolValue) Copy() Value

Copy returns a copy of this value.

func (*BoolValue) Less

func (obj *BoolValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*BoolValue) String

func (obj *BoolValue) String() string

String returns a visual representation of this value.

func (*BoolValue) Type

func (obj *BoolValue) Type() *Type

Type returns the type data structure that represents this type.

func (*BoolValue) Value

func (obj *BoolValue) Value() interface{}

Value returns the raw value of this type.

type Elem

type Elem = disjoint.Elem[*Type]

Elem is the type used for the unification variable in the Uni field of Type. We create this alias here to avoid needing to write *disjoint.Elem[*Type] all over. This is a golang type alias. These should be created with NewElem.

func NewElem

func NewElem() *Elem

NewElem creates a new set with one element and returns the sole element (the representative element) of that set.

type FloatValue

type FloatValue struct {
	Base
	V float64
}

FloatValue represents an integer value.

func NewFloat

func NewFloat() *FloatValue

NewFloat creates a new float value.

func (*FloatValue) Cmp

func (obj *FloatValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*FloatValue) Copy

func (obj *FloatValue) Copy() Value

Copy returns a copy of this value.

func (*FloatValue) Float

func (obj *FloatValue) Float() float64

Float represents the value of this type as a float if it is one. If this is not a float, then this panics.

func (*FloatValue) Less

func (obj *FloatValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*FloatValue) String

func (obj *FloatValue) String() string

String returns a visual representation of this value.

func (*FloatValue) Type

func (obj *FloatValue) Type() *Type

Type returns the type data structure that represents this type.

func (*FloatValue) Value

func (obj *FloatValue) Value() interface{}

Value returns the raw value of this type.

type FuncValue

type FuncValue struct {
	Base
	V func(context.Context, []Value) (Value, error)
	T *Type // contains ordered field types, arg names are a bonus part
}

FuncValue represents a function which takes a list of Value arguments and returns a Value. It can also return an error which could represent that something went horribly wrong. (Think, an internal panic.)

This is not general enough to represent all functions in the language (see the full.FuncValue), but it is a useful common case.

FuncValue is not a Value, but it is a useful building block for implementing Func nodes.

func NewFunc

func NewFunc(t *Type) *FuncValue

NewFunc creates a useless function which will get overwritten by something more useful later.

func (*FuncValue) Call

func (obj *FuncValue) Call(ctx context.Context, args []Value) (Value, error)

Call runs the function value and returns its result. It returns an error if something goes wrong during execution, and panic's if you call this with inappropriate input types, or if it returns an inappropriate output type.

func (*FuncValue) Cmp

func (obj *FuncValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in. In this situation, they can't be compared so we panic.

func (*FuncValue) Copy

func (obj *FuncValue) Copy() Value

Copy returns a copy of this value.

func (*FuncValue) Less

func (obj *FuncValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same. In this situation, they can't be compared so we panic.

func (*FuncValue) String

func (obj *FuncValue) String() string

String returns a visual representation of this value.

func (*FuncValue) Type

func (obj *FuncValue) Type() *Type

Type returns the type data structure that represents this type.

func (*FuncValue) Value

func (obj *FuncValue) Value() interface{}

Value returns the raw value of this type.

type IntValue

type IntValue struct {
	Base
	V int64
}

IntValue represents an integer value.

func NewInt

func NewInt() *IntValue

NewInt creates a new int value.

func (*IntValue) Cmp

func (obj *IntValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*IntValue) Copy

func (obj *IntValue) Copy() Value

Copy returns a copy of this value.

func (*IntValue) Int

func (obj *IntValue) Int() int64

Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.

func (*IntValue) Less

func (obj *IntValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*IntValue) String

func (obj *IntValue) String() string

String returns a visual representation of this value.

func (*IntValue) Type

func (obj *IntValue) Type() *Type

Type returns the type data structure that represents this type.

func (*IntValue) Value

func (obj *IntValue) Value() interface{}

Value returns the raw value of this type.

type Kind

type Kind int // this used to be called Type

The Kind represents the base type of each value.

const (
	// NOTE: Make sure you add entries to stringer.go if you add something.
	KindNil Kind = iota
	KindBool
	KindStr
	KindInt
	KindFloat
	KindList
	KindMap
	KindStruct
	KindFunc
	KindVariant

	KindUnification = Kind(MaxInt8) // keep this last
)

Each Kind represents a type in the language type system.

func (Kind) String

func (obj Kind) String() string

String returns a representation for the kind. These are the strings seen in most type unification errors. We don't use stringer since it would capitalize them.

type ListValue

type ListValue struct {
	Base
	V []Value // all elements must have type T.Val
	T *Type
}

ListValue represents a list value.

func NewList

func NewList(t *Type) *ListValue

NewList creates a new list with the specified list type.

func (*ListValue) Add

func (obj *ListValue) Add(v Value) error

Add adds an element to this list. It errors if the type does not match.

func (*ListValue) Cmp

func (obj *ListValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*ListValue) Contains

func (obj *ListValue) Contains(v Value) (index int, exists bool)

Contains searches for a value in the list. On success it returns the index.

func (*ListValue) Copy

func (obj *ListValue) Copy() Value

Copy returns a copy of this value.

func (*ListValue) Less

func (obj *ListValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*ListValue) List

func (obj *ListValue) List() []Value

List represents the value of this type as a list if it is one. If this is not a list, then this panics.

func (*ListValue) Lookup

func (obj *ListValue) Lookup(index int) (value Value, exists bool)

Lookup looks up a value by index. On success it also returns the Value.

func (*ListValue) String

func (obj *ListValue) String() string

String returns a visual representation of this value.

func (*ListValue) Type

func (obj *ListValue) Type() *Type

Type returns the type data structure that represents this type.

func (*ListValue) Value

func (obj *ListValue) Value() interface{}

Value returns the raw value of this type.

type MapValue

type MapValue struct {
	Base
	// the types of all keys and values are represented inside of T
	V map[Value]Value
	T *Type
}

MapValue represents a dictionary value.

func NewMap

func NewMap(t *Type) *MapValue

NewMap creates a new map with the specified map type.

func (*MapValue) Add

func (obj *MapValue) Add(k, v Value) error

Add adds an element to this map. It errors if the types do not match.

func (*MapValue) Cmp

func (obj *MapValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*MapValue) Copy

func (obj *MapValue) Copy() Value

Copy returns a copy of this value.

func (*MapValue) Less

func (obj *MapValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*MapValue) Lookup

func (obj *MapValue) Lookup(key Value) (value Value, exists bool)

Lookup searches the map for a key. On success it also returns the Value.

func (*MapValue) Map

func (obj *MapValue) Map() map[Value]Value

Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.

func (*MapValue) String

func (obj *MapValue) String() string

String returns a visual representation of this value.

func (*MapValue) Type

func (obj *MapValue) Type() *Type

Type returns the type data structure that represents this type.

func (*MapValue) Value

func (obj *MapValue) Value() interface{}

Value returns the raw value of this type.

type StrValue

type StrValue struct {
	Base
	V string
}

StrValue represents a string value.

func NewStr

func NewStr() *StrValue

NewStr creates a new string value.

func (*StrValue) Cmp

func (obj *StrValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*StrValue) Copy

func (obj *StrValue) Copy() Value

Copy returns a copy of this value.

func (*StrValue) Less

func (obj *StrValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*StrValue) Str

func (obj *StrValue) Str() string

Str represents the value of this type as a string if it is one. If this is not a string, then this panics.

func (*StrValue) String

func (obj *StrValue) String() string

String returns a visual representation of this value.

func (*StrValue) Type

func (obj *StrValue) Type() *Type

Type returns the type data structure that represents this type.

func (*StrValue) Value

func (obj *StrValue) Value() interface{}

Value returns the raw value of this type.

type StructValue

type StructValue struct {
	Base
	V map[string]Value // each field can have a different type
	T *Type            // contains ordered field types
}

StructValue represents a struct value. The keys are ordered. TODO: if all functions require arg names to call, we don't need to order!

func NewStruct

func NewStruct(t *Type) *StructValue

NewStruct creates a new struct with the specified field types.

func (*StructValue) Cmp

func (obj *StructValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*StructValue) Copy

func (obj *StructValue) Copy() Value

Copy returns a copy of this value.

func (*StructValue) Less

func (obj *StructValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same.

func (*StructValue) Lookup

func (obj *StructValue) Lookup(k string) (value Value, exists bool)

Lookup searches the struct for a key. On success it also returns the Value.

func (*StructValue) Set

func (obj *StructValue) Set(k string, v Value) error

Set sets a field to this value. It errors if the types do not match.

func (*StructValue) String

func (obj *StructValue) String() string

String returns a visual representation of this value.

func (*StructValue) Struct

func (obj *StructValue) Struct() map[string]Value

Struct represents the value of this type as a struct if it is one. If this is not a struct, then this panics.

func (*StructValue) Type

func (obj *StructValue) Type() *Type

Type returns the type data structure that represents this type.

func (*StructValue) Value

func (obj *StructValue) Value() interface{}

Value returns the raw value of this type.

type Type

type Type struct {
	Kind Kind

	Val *Type            // if Kind == List, use Val only
	Key *Type            // if Kind == Map, use Val and Key
	Map map[string]*Type // if Kind == Struct, use Map and Ord (for order)
	Ord []string
	Out *Type // if Kind == Func, use Map and Ord for Input, Out for Output
	Var *Type // if Kind == Variant, use Var only

	// unification variable (question mark, eg ?1, ?2)
	Uni *Elem // if Kind == Unification (optional) use Uni only
}

Type is the datastructure representing any type. It can be recursive for container types like lists, maps, and structs. TODO: should we create a `Type` interface?

func ConfigurableTypeOf

func ConfigurableTypeOf(t reflect.Type, opts ...TypeOfOption) (*Type, error)

ConfigurableTypeOf is a configurable version of the TypeOf function to avoid repeating code for the different variants of it that we want.

func NewType

func NewType(s string) *Type

NewType creates the Type from the string representation.

func ResTypeOf

func ResTypeOf(t reflect.Type) (*Type, error)

ResTypeOf is almost identical to TypeOf, except it behaves slightly differently so that it can return what is needed for resources.

func TypeOf

func TypeOf(t reflect.Type) (*Type, error)

TypeOf takes a reflect.Type and returns an equivalent *Type. It removes any pointers since our language does not support pointers. It returns nil if it cannot represent the type in our type system. Common examples of things it cannot express include reflect.Invalid, reflect.Interface, Reflect.Complex128 and more. It is not reversible because some information may be either added or lost. For example, reflect.Array and reflect.Slice are both converted to a Type of KindList, and KindFunc names the arguments of a func sequentially. The lossy inverse of this is Reflect.

func (*Type) Cmp

func (obj *Type) Cmp(typ *Type) error

Cmp compares this type to another.

func (*Type) ComplexCmp

func (obj *Type) ComplexCmp(typ *Type) (string, error)

ComplexCmp tells us if the input type is compatible with the concrete one. It can match against types containing variants, or against partial types. If the two types are equivalent, it will return nil. If the input type is identical, and concrete, the return status will be the empty string. If this match finds a possibility against a partial type, the status will be set to the "partial" string, and if it is compatible with the variant type it will be "variant"... Comparing to a partial can only match "impossible" (error) or possible (nil). This now also supports comparing a partial type to a variant type as well... TODO: Should we support KindUnification somehow?

func (*Type) Copy

func (obj *Type) Copy() *Type

Copy copies this type so that inplace modification won't affect the original.

func (*Type) HasUni

func (obj *Type) HasUni() bool

HasUni tells us if the type contains any unification variables.

func (*Type) HasVariant

func (obj *Type) HasVariant() bool

HasVariant tells us if the type contains any mention of the Variant type.

func (*Type) New

func (obj *Type) New() Value

New creates a new Value of this type. It will represent the "zero" value. It panics if you give it a malformed type.

func (*Type) Reflect

func (obj *Type) Reflect() reflect.Type

Reflect returns a representative type satisfying the golang Type Interface. The lossy inverse of this is TypeOf.

func (*Type) String

func (obj *Type) String() string

String returns the textual representation for this type.

func (*Type) Underlying

func (obj *Type) Underlying() *Type

Underlying returns the underlying type of the type in question. For variants, this unpacks them recursively, for everything else this returns itself.

type TypeOfOption

type TypeOfOption func(*typeOfOptions)

TypeOfOption is a type that can be used to configure the ConfigurableTypeOf function.

func AllowInterfaceTypeOpt

func AllowInterfaceTypeOpt(allowInterfaceType bool) TypeOfOption

AllowInterfaceTypeOpt specifies whether we should allow matching on an interface kind. This is used by ResTypeOf.

func SkipBadStructFieldsOpt

func SkipBadStructFieldsOpt(skipBadStructFields bool) TypeOfOption

SkipBadStructFieldsOpt specifies whether we should skip over struct fields that errored when we tried to find their type. This is used by ResTypeOf.

func SkipPrivateFieldsOpt

func SkipPrivateFieldsOpt(skipPrivateFields bool) TypeOfOption

SkipPrivateFieldsOpt specifies whether we should skip over struct fields that are private or unexported. This is used by ResTypeOf.

func StrictStructTagOpt

func StrictStructTagOpt(strictStructTag bool) TypeOfOption

StrictStructTagOpt specifies whether we require that a struct tag be present to be able to use the field. If false, then the field is skipped if it is missing a struct tag.

func StructTagOpt

func StructTagOpt(structTag string) TypeOfOption

StructTagOpt specifies whether we should skip over struct fields that errored when we tried to find their type. This is used by ResTypeOf.

type UnifiedState

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

UnifiedState stores a mapping of unification variable to unique id. This is most often used for printing consistent unification variables in your logs. It must be built with NewUnifiedState before it can be used or it will panic.

func NewUnifiedState

func NewUnifiedState() *UnifiedState

NewUnifiedState builds a new unified state store.

func (*UnifiedState) String

func (obj *UnifiedState) String(typ *Type) string

String returns a representation of the input type using the specified state.

type Value

type Value interface {
	fmt.Stringer // String() string (for display purposes)
	Type() *Type
	Less(Value) bool // to find the smaller of the two values (for sort)
	Cmp(Value) error // error if the two values aren't the same
	Copy() Value     // returns a copy of this value
	Value() interface{}
	Bool() bool
	Str() string
	Int() int64
	Float() float64
	List() []Value
	Map() map[Value]Value // keys must all have same type, same for values
	Struct() map[string]Value
	Func() interface{} // func(interfaces.Txn, []interfaces.Func) (interfaces.Func, error)
}

Value represents an interface to get values out of each type. It is similar to the reflection interfaces used in the golang standard library.

func ListStrToValue

func ListStrToValue(input []string) Value

ListStrToValue is a simple helper function to convert from a list of strings in golang to the equivalent in our type system.

func ValueOf

func ValueOf(v reflect.Value) (Value, error)

ValueOf takes a reflect.Value and returns an equivalent Value. Remember that the mcl type system currently can't represent certain values that *are* possible in golang. This is intentional. For example, mcl can't represent a *string (pointer to a string) where as this is quite common in golang. This is because mcl has no `nil/null` values. It is designed this way to avoid the well-known expensive "null-pointer-exception" style bugs. A version two of the language might consider an "Optional" type. In the meantime, you can still represent an "undefined" value, but only so far as when it's passed to a resource field. This is done with our "elvis" operator. When using this function, if you pass in something with a nil value, then expect a panic or an error if you're lucky.

func ValueOfGolang

func ValueOfGolang(i interface{}) (Value, error)

ValueOfGolang is a helper that takes a golang value, and produces the mcl equivalent internal representation. This is very useful for writing tests. A reminder that if you pass in a nil value, or something containing a nil value, then you won't get what you want. See our documentation for ValueOf.

type ValueSlice

type ValueSlice []Value

ValueSlice is a linear list of values. It is used for sorting purposes.

func (ValueSlice) Len

func (vs ValueSlice) Len() int

func (ValueSlice) Less

func (vs ValueSlice) Less(i, j int) bool

func (ValueSlice) Swap

func (vs ValueSlice) Swap(i, j int)

type VariantValue

type VariantValue struct {
	Base
	V Value // formerly I experimented with using interface{} instead
	T *Type
}

VariantValue represents a variant value.

func NewVariant

func NewVariant(t *Type) *VariantValue

NewVariant creates a new variant value. TODO: I haven't thought about this thoroughly yet.

func (*VariantValue) Bool

func (obj *VariantValue) Bool() bool

Bool represents the value of this type as a bool if it is one. If this is not a bool, then this panics.

func (*VariantValue) Cmp

func (obj *VariantValue) Cmp(val Value) error

Cmp returns an error if this value isn't the same as the arg passed in.

func (*VariantValue) Copy

func (obj *VariantValue) Copy() Value

Copy returns a copy of this value.

func (*VariantValue) Float

func (obj *VariantValue) Float() float64

Float represents the value of this type as a float if it is one. If this is not a float, then this panics.

func (*VariantValue) Func

func (obj *VariantValue) Func() interface{}

Func represents the value of this type as a function if it is one. If this is not a function, then this panics.

func (*VariantValue) Int

func (obj *VariantValue) Int() int64

Int represents the value of this type as an integer if it is one. If this is not an integer, then this panics.

func (*VariantValue) Less

func (obj *VariantValue) Less(v Value) bool

Less compares to value and returns true if we're smaller. This panics if the two types aren't the same. For variants, the two sub types must be the same.

func (*VariantValue) List

func (obj *VariantValue) List() []Value

List represents the value of this type as a list if it is one. If this is not a list, then this panics.

func (*VariantValue) Map

func (obj *VariantValue) Map() map[Value]Value

Map represents the value of this type as a dictionary if it is one. If this is not a map, then this panics.

func (*VariantValue) Str

func (obj *VariantValue) Str() string

Str represents the value of this type as a string if it is one. If this is not a string, then this panics.

func (*VariantValue) String

func (obj *VariantValue) String() string

String returns a visual representation of this value.

func (*VariantValue) Struct

func (obj *VariantValue) Struct() map[string]Value

Struct represents the value of this type as a struct if it is one. If this is not a struct, then this panics.

func (*VariantValue) Type

func (obj *VariantValue) Type() *Type

Type returns the type data structure that represents this type.

func (*VariantValue) Value

func (obj *VariantValue) Value() interface{}

Value returns the raw value of this type.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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