core

package
v0.7.1 Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Pos constants
	NoPos Pos = 0

	// Builtin module/function slot constants
	ModuleSlotSize = 128
	MaxModules     = 32
)
View Source
const KindUser = "user"
View Source
const MaxSequenceLen = 1 << 32

MaxSequenceLen bounds every count-driven sequence allocation (`repeat`, the `*` operator, `pad_start` and `pad_end`). Go's makeslice PANICS — not raises — for a length it cannot represent, and a Go panic escaping into the host is exactly what the error model forbids, so the count is checked against this ceiling first and answers a catchable error instead. The value is far past any real script and below makeslice's own limit for every element type Kavun has (byte, rune, Value), which makes that panic unreachable through these paths.

Variables

View Source
var (
	Undefined   = Value{}
	True        = Value{Type: value.Bool, Immutable: true, Data: 1}
	False       = Value{Type: value.Bool, Immutable: true, Data: 0}
	EmptyString = Value{Type: value.String, Immutable: true, Ptr: unsafe.Pointer(&emptyString)}
)

Builtin module/function registry

View Source
var DefaultValueType = ValueTypeDescr{
	Name:         func(v Value) string { return fmt.Sprintf("<unknown:%d>", v.Type) },
	String:       func(v Value) string { return v.TypeName() },
	Format:       defaultFormat,
	Interface:    func(_ Value) any { return nil },
	EncodeJSON:   func(v Value) ([]byte, error) { return nil, errs.NewJSONEncodingError(v.TypeName()) },
	EncodeBinary: func(v Value) ([]byte, error) { return nil, errs.NewBinaryEncodingError(v.TypeName()) },
	DecodeBinary: func(v *Value, _ []byte) error { return errs.NewBinaryEncodingError(v.TypeName()) },
	IsTrue:       Const2Hook[bool, error](false, nil),
	Copy:         func(v Value, _ bool) (Value, error) { return v, nil },
	Equal:        defaultEqual,
	BinaryOp:     defaultBinaryOp,
	UnaryOp:      defaultUnaryOp,

	MethodCall: defaultMethodCall,

	IsIterable: ConstHook(false),
	Contains: func(v Value, e Value) (bool, error) {
		return false, errs.NewInvalidBinaryOperatorError("in", e.TypeName(), v.TypeName())
	},
	Len:      ConstHook(int64(0)),
	Iterator: ValueHook(Undefined, nil),
	Assign:   func(v Value, _, _ Value, _ bc.Opcode) error { return errs.NewNotAssignableError(v.TypeName()) },
	Delete:   defaultDelete,

	Access:    defaultAccess,
	Append:    defaultAppend,
	Slice:     defaultSlice,
	SliceStep: defaultSliceStep,

	IsCallable: ConstHook(false),
	IsVariadic: ConstHook(false),
	Arity:      ConstHook(0),

	Call: defaultCall,

	Next:  ConstHook(false),
	Key:   ValueHook(Undefined, nil),
	Value: ValueHook(Undefined, nil),
	Elem: func(v Value) (Value, error) {
		return ValueTypes[v.Type].Value(v)
	},

	AsBool:     Const2Hook(false, false),
	AsByte:     Const2Hook(byte(0), false),
	AsRune:     Const2Hook(rune(0), false),
	AsInt:      Const2Hook(int64(0), false),
	AsFloat:    Const2Hook(float64(0), false),
	AsDecimal:  Const2Hook(dec128.Decimal0, false),
	AsTime:     Const2Hook(time.Time{}, false),
	AsString:   Const2Hook("", false),
	AsBytes:    Const2Hook[[]byte](nil, false),
	AsArray:    func(Value) ([]Value, bool) { return nil, false },
	AsDict:     func(Value) (map[string]Value, bool) { return nil, false },
	AsRunes:    defaultAsRunes,
	AsIntRange: Const2Hook(IntRange{}, false),

	IsMethodPure: func(string) bool { return false },
}

DefaultValueType provides default implementations for all ValueType hooks.

View Source
var TypeArray = ValueTypeDescr{
	Name:         SeqNameHook(arrayTypeName, immutableArrayTypeName),
	String:       arrayTypeString,
	Format:       arrayTypeFormat,
	Interface:    arrayTypeInterface,
	EncodeJSON:   arrayTypeEncodeJSON,
	EncodeBinary: arrayTypeEncodeBinary,
	DecodeBinary: arrayTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return len((*Array)(v.Ptr).Elements) > 0, nil },
	IsIterable:   ConstHook(true),
	Iterator:     arrayTypeIterator,
	Equal:        arrayTypeEqual,
	BinaryOp:     arrayTypeBinaryOp,
	Copy:         arrayTypeCopy,
	Len:          func(v Value) int64 { return int64(len((*Array)(v.Ptr).Elements)) },
	MethodCall:   arrayTypeMethodCall,
	Access:       SeqAccessHook(RefValue, arrayTypeResolve),
	Assign:       SeqAssignHook(arrayTypeResolve, Value.AsValue, anyTypeName),
	Contains:     arrayTypeContains,
	Append:       arrayTypeAppend,
	Slice:        SeqSliceHook(NewArrayValue, arrayTypeResolve),
	SliceStep:    SeqSliceStepHook(NewArrayValue, arrayTypeResolve),
	AsBool:       func(v Value) (bool, bool) { return len((*Array)(v.Ptr).Elements) > 0, true },

	AsRunes: arrayTypeAsRunes,
	AsBytes: arrayTypeAsBytes,
	AsArray: func(v Value) ([]Value, bool) { return (*Array)(v.Ptr).Elements, true },

	IsMethodPure: func(name string) bool { return !strings.HasSuffix(name, "_in_place") },
}
View Source
var TypeArrayIterator = ValueTypeDescr{
	Name:   ConstHook(arrayIteratorTypeName),
	String: SeqIterStringHook[Value](arrayIteratorTypeName, arrayIteratorResolve),
	Next:   SeqIterNextHook[Value](arrayIteratorResolve),
	Key:    SeqIterKeyHook[Value](arrayIteratorResolve),
	Value:  SeqIterValueHook(RefValue, arrayIteratorResolve),
}
View Source
var TypeBool = ValueTypeDescr{
	Name:         ConstHook(boolTypeName),
	String:       boolTypeString,
	Format:       boolTypeFormat,
	Interface:    func(v Value) any { return v.Data != 0 },
	EncodeJSON:   boolTypeEncodeJSON,
	EncodeBinary: boolTypeEncodeBinary,
	DecodeBinary: boolTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return v.Data != 0, nil },
	Equal:        boolTypeEqual,
	BinaryOp:     boolTypeBinaryOp,
	UnaryOp:      boolTypeUnaryOp,
	MethodCall:   boolTypeMethodCall,
	Len:          ConstHook(int64(1)),
	AsString:     boolTypeAsString,
	AsInt:        boolTypeAsInt,
	AsBool:       func(v Value) (bool, bool) { return v.Data != 0, true },
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeBuiltinClosure = ValueTypeDescr{
	Name:         builtinClosureTypeName,
	String:       func(v Value) string { return builtinClosureTypeName(v) },
	Format:       callableFormat,
	IsTrue:       Const2Hook[bool, error](true, nil),
	IsCallable:   ConstHook(true),
	IsVariadic:   builtinClosureTypeIsVariadic,
	Arity:        builtinClosureTypeArity,
	Call:         builtinClosureTypeCall,
	MethodCall:   builtinClosureTypeMethodCall,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeBuiltinFunction = ValueTypeDescr{
	Name:         builtinFunctionTypeName,
	String:       func(v Value) string { return builtinFunctionTypeName(v) },
	Format:       callableFormat,
	EncodeBinary: builtinFunctionTypeEncodeBinary,
	DecodeBinary: builtinFunctionTypeDecodeBinary,
	IsTrue:       Const2Hook[bool, error](true, nil),
	IsCallable:   ConstHook(true),
	IsVariadic:   builtinFunctionTypeIsVariadic,
	Arity:        builtinFunctionTypeArity,
	Call:         builtinFunctionTypeCall,
	MethodCall:   builtinFunctionTypeMethodCall,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeByte = ValueTypeDescr{
	Name:         ConstHook(byteTypeName),
	String:       func(v Value) string { return fmt.Sprintf("byte(%d)", v.Data) },
	Format:       byteTypeFormat,
	Interface:    func(v Value) any { return byte(v.Data) },
	EncodeJSON:   byteTypeEncodeJSON,
	EncodeBinary: byteTypeEncodeBinary,
	DecodeBinary: byteTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return v.Data != 0, nil },
	Len:          ConstHook(int64(1)),
	Equal:        byteTypeEqual,
	BinaryOp:     byteTypeBinaryOp,
	UnaryOp:      byteTypeUnaryOp,
	MethodCall:   byteTypeMethodCall,

	AsString:     func(v Value) (string, bool) { return ByteSymbolString(byte(v.Data)) },
	AsInt:        func(v Value) (int64, bool) { return int64(v.Data), true },
	AsRune:       byteTypeAsRune,
	AsByte:       func(v Value) (byte, bool) { return byte(v.Data), true },
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeBytes = ValueTypeDescr{
	Name:         SeqNameHook(bytesTypeName, immutableBytesTypeName),
	String:       bytesTypeString,
	Format:       bytesTypeFormat,
	Interface:    func(v Value) any { return (*Bytes)(v.Ptr).Elements },
	EncodeJSON:   bytesTypeEncodeJSON,
	EncodeBinary: bytesTypeEncodeBinary,
	DecodeBinary: bytesTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return len((*Bytes)(v.Ptr).Elements) > 0, nil },
	IsIterable:   ConstHook(true),
	Iterator:     bytesTypeIterator,
	Equal:        bytesTypeEqual,
	BinaryOp:     bytesTypeBinaryOp,
	Copy:         bytesTypeCopy,
	Len:          func(v Value) int64 { return int64(len((*Bytes)(v.Ptr).Elements)) },
	MethodCall:   bytesTypeMethodCall,
	Access:       SeqAccessHook(ByteValue, bytesTypeResolve),
	Assign:       SeqAssignHook(bytesTypeResolve, Value.AsByte, byteTypeName),
	Append:       bytesTypeAppend,
	Contains:     bytesTypeContains,
	Slice:        SeqSliceHook(NewBytesValue, bytesTypeResolve),
	SliceStep:    SeqSliceStepHook(NewBytesValue, bytesTypeResolve),
	AsBool:       func(v Value) (bool, bool) { return conv.ParseBool(string((*Bytes)(v.Ptr).Elements)) },
	AsString:     func(v Value) (string, bool) { return string((*Bytes)(v.Ptr).Elements), true },
	AsBytes:      func(v Value) ([]byte, bool) { return (*Bytes)(v.Ptr).Elements, true },
	AsArray:      bytesTypeAsArray,

	IsMethodPure: func(name string) bool { return !strings.HasSuffix(name, "_in_place") },
}
View Source
var TypeBytesIterator = ValueTypeDescr{
	Name:   ConstHook(bytesIteratorTypeName),
	String: SeqIterStringHook[byte](bytesIteratorTypeName, bytesIteratorResolve),
	Next:   SeqIterNextHook[byte](bytesIteratorResolve),
	Key:    SeqIterKeyHook[byte](bytesIteratorResolve),
	Value:  SeqIterValueHook(ByteValue, bytesIteratorResolve),
}
View Source
var TypeCompiledFunction = ValueTypeDescr{
	Name:         compiledFunctionTypeName,
	String:       func(v Value) string { return compiledFunctionTypeName(v) },
	Format:       callableFormat,
	EncodeBinary: compiledFunctionTypeEncodeBinary,
	DecodeBinary: compiledFunctionTypeDecodeBinary,
	IsTrue:       Const2Hook[bool, error](true, nil),
	IsCallable:   ConstHook(true),
	IsVariadic:   compiledFunctionTypeIsVariadic,
	Arity:        compiledFunctionTypeArity,
	Call:         compiledFunctionTypeCall,
	MethodCall:   compiledFunctionTypeMethodCall,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeDecimal = ValueTypeDescr{
	Name:         ConstHook(decimalTypeName),
	String:       decimalTypeString,
	Format:       decimalTypeFormat,
	Interface:    func(v Value) any { return *(*dec128.Dec128)(v.Ptr) },
	EncodeJSON:   func(v Value) ([]byte, error) { return (*dec128.Dec128)(v.Ptr).MarshalJSON() },
	EncodeBinary: decimalTypeEncodeBinary,
	DecodeBinary: decimalTypeDecodeBinary,
	IsTrue:       decimalTypeIsTrue,
	Equal:        decimalTypeEqual,
	BinaryOp:     decimalTypeBinaryOp,
	UnaryOp:      decimalTypeUnaryOp,
	Len:          ConstHook(int64(1)),
	MethodCall:   decimalTypeMethodCall,
	AsString:     func(v Value) (string, bool) { return (*dec128.Dec128)(v.Ptr).String(), true },
	AsInt:        decimalTypeAsInt,
	AsFloat:      decimalTypeAsFloat,
	AsDecimal:    func(v Value) (dec128.Dec128, bool) { return *(*dec128.Dec128)(v.Ptr), true },
	AsTime:       decimalTypeAsTime,
	AsBool:       decimalTypeAsBool,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeDict = ValueTypeDescr{
	Name:         SeqNameHook(dictTypeName, immutableDictTypeName),
	String:       dictTypeString,
	Format:       dictTypeFormat,
	Interface:    dictTypeInterface,
	EncodeJSON:   dictTypeEncodeJSON,
	EncodeBinary: dictTypeEncodeBinary,
	DecodeBinary: dictTypeDecodeBinary,
	IsTrue:       dictTypeIsTrue,
	IsIterable:   ConstHook(true),
	Iterator:     dictTypeIterator,
	Equal:        dictTypeEqual,
	BinaryOp:     dictTypeBinaryOp,
	Copy:         dictTypeCopy,
	Len:          dictTypeLen,
	MethodCall:   dictTypeMethodCall,
	Access:       dictTypeAccess,
	Assign:       dictTypeAssign,
	Contains:     dictTypeContains,
	Delete:       dictTypeDelete,
	AsBool:       dictTypeAsBool,
	AsDict:       dictTypeAsDict,

	IsMethodPure: func(name string) bool { return !strings.HasSuffix(name, "_in_place") },
}
View Source
var TypeDictIterator = ValueTypeDescr{
	Name:   ConstHook(dictIteratorTypeName),
	String: dictIteratorTypeString,
	Next:   dictIteratorTypeNext,
	Key:    dictIteratorTypeKey,
	Value:  dictIteratorTypeValue,
	Elem:   dictIteratorTypeKey,
}
View Source
var TypeError = ValueTypeDescr{
	Name:         ConstHook(errorTypeName),
	String:       errorTypeString,
	Format:       errorTypeFormat,
	Interface:    func(v Value) any { return errors.New(v.String()) },
	EncodeJSON:   errorTypeEncodeJSON,
	EncodeBinary: errorTypeEncodeBinary,
	DecodeBinary: errorTypeDecodeBinary,
	IsTrue:       Const2Hook[bool, error](true, nil),
	Copy:         errorTypeCopy,
	Equal:        errorTypeEqual,
	BinaryOp:     errorTypeBinaryOp,
	UnaryOp:      errorTypeUnaryOp,
	MethodCall:   errorTypeMethodCall,
	AsString:     errorTypeAsString,
	AsBool:       Const2Hook(true, true),
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeFloat = ValueTypeDescr{
	Name:         ConstHook(floatTypeName),
	String:       floatTypeString,
	Format:       floatTypeFormat,
	Interface:    func(v Value) any { return math.Float64frombits(v.Data) },
	EncodeJSON:   floatTypeEncodeJSON,
	EncodeBinary: floatTypeEncodeBinary,
	DecodeBinary: floatTypeDecodeBinary,
	IsTrue:       floatTypeIsTrue,
	Len:          ConstHook(int64(1)),
	Equal:        floatTypeEqual,
	BinaryOp:     floatTypeBinaryOp,
	UnaryOp:      floatTypeUnaryOp,
	MethodCall:   floatTypeMethodCall,
	AsInt:        floatTypeAsInt,
	AsFloat:      floatTypeAsFloat,
	AsDecimal:    floatTypeAsDecimal,
	AsBool:       floatTypeAsBool,
	AsString:     floatTypeAsString,
	AsTime:       floatTypeAsTime,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeFormatSpec = ValueTypeDescr{
	Name:   ConstHook(formatSpecTypeName),
	String: formatSpecTypeString,
}
View Source
var TypeInt = ValueTypeDescr{
	Name:         ConstHook(intTypeName),
	String:       func(v Value) string { return strconv.FormatInt(int64(v.Data), 10) },
	Format:       intTypeFormat,
	Interface:    func(v Value) any { return int64(v.Data) },
	EncodeJSON:   intTypeEncodeJSON,
	EncodeBinary: intTypeEncodeBinary,
	DecodeBinary: intTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return v.Data != 0, nil },
	Len:          ConstHook(int64(1)),
	Equal:        intTypeEqual,
	BinaryOp:     intTypeBinaryOp,
	UnaryOp:      intTypeUnaryOp,
	MethodCall:   intTypeMethodCall,
	AsString:     func(v Value) (string, bool) { return strconv.FormatInt(int64(v.Data), 10), true },
	AsInt:        func(v Value) (int64, bool) { return int64(v.Data), true },
	AsFloat:      func(v Value) (float64, bool) { return float64(int64(v.Data)), true },
	AsDecimal:    func(v Value) (dec128.Dec128, bool) { return dec128.FromInt64(int64(v.Data)), true },
	AsBool:       func(v Value) (bool, bool) { return v.Data != 0, true },
	AsRune:       intTypeAsRune,
	AsTime:       func(v Value) (time.Time, bool) { return time.Unix(int64(v.Data), 0).UTC(), true },
	AsByte:       intTypeAsByte,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeIntRange = ValueTypeDescr{
	Name:         ConstHook(intRangeTypeName),
	EncodeBinary: intRangeTypeEncodeBinary,
	DecodeBinary: intRangeTypeDecodeBinary,
	String:       intRangeTypeString,
	Format:       intRangeTypeFormat,
	IsTrue:       intRangeTypeIsTrue,
	IsIterable:   ConstHook(true),
	Iterator:     intRangeTypeIterator,
	Equal:        intRangeTypeEqual,
	Len:          intRangeTypeLen,
	MethodCall:   intRangeTypeMethodCall,
	Access:       intRangeTypeAccess,
	Contains:     intRangeTypeContains,
	AsBool:       intRangeTypeAsBool,
	AsArray:      intRangeTypeAsArray,
	AsIntRange:   intRangeTypeAsIntRange,

	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeIntRangeIterator = ValueTypeDescr{
	Name:   ConstHook(intRangeIteratorTypeName),
	String: intRangeIteratorTypeString,
	Next:   intRangeIteratorTypeNext,
	Key:    intRangeIteratorTypeKey,
	Value:  intRangeIteratorTypeValue,
}
View Source
var TypeRecord = ValueTypeDescr{
	Name:         SeqNameHook(recordTypeName, immutableRecordTypeName),
	String:       recordTypeString,
	Format:       recordTypeFormat,
	Interface:    recordTypeInterface,
	EncodeJSON:   recordTypeEncodeJSON,
	EncodeBinary: recordTypeEncodeBinary,
	DecodeBinary: recordTypeDecodeBinary,
	IsTrue:       recordTypeIsTrue,
	IsIterable:   ConstHook(true),
	Iterator:     recordTypeIterator,
	Copy:         recordTypeCopy,
	Len:          recordTypeLen,
	Equal:        recordTypeEqual,
	BinaryOp:     recordTypeBinaryOp,
	MethodCall:   recordTypeMethodCall,
	Access:       recordTypeAccess,
	Assign:       recordTypeAssign,
	Contains:     recordTypeContains,
	Delete:       recordTypeDelete,
	AsBool:       recordTypeAsBool,
	AsDict:       recordTypeAsDict,
	IsMethodPure: func(string) bool { return false },
}
View Source
var TypeRune = ValueTypeDescr{
	Name:         ConstHook(runeTypeName),
	String:       func(v Value) string { return fmt.Sprintf("%q", rune(v.Data)) },
	Format:       runeTypeFormat,
	Interface:    func(v Value) any { return rune(v.Data) },
	EncodeJSON:   runeTypeEncodeJSON,
	EncodeBinary: runeTypeEncodeBinary,
	DecodeBinary: runeTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return v.Data != 0, nil },
	Len:          ConstHook(int64(1)),
	Equal:        runeTypeEqual,
	BinaryOp:     runeTypeBinaryOp,
	MethodCall:   runeTypeMethodCall,
	AsString:     func(v Value) (string, bool) { return EncodeRuneText(rune(v.Data)), true },
	AsInt:        func(v Value) (int64, bool) { return int64(v.Data), true },
	AsBool:       func(v Value) (bool, bool) { return v.Data != 0, true },
	AsRune:       func(v Value) (rune, bool) { return rune(v.Data), true },
	AsByte:       runeTypeAsByte,
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeRunes = ValueTypeDescr{
	Name:         SeqNameHook(runesTypeName, immutableRunesTypeName),
	String:       func(v Value) string { return "u" + strconv.Quote(EncodeText((*Runes)(v.Ptr).Elements)) },
	Format:       runesTypeFormat,
	Interface:    func(v Value) any { return (*Runes)(v.Ptr).Elements },
	EncodeJSON:   runesTypeEncodeJSON,
	EncodeBinary: runesTypeEncodeBinary,
	DecodeBinary: runesTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return len((*Runes)(v.Ptr).Elements) > 0, nil },
	IsIterable:   ConstHook(true),
	Iterator:     runesTypeIterator,
	Copy:         runesTypeCopy,
	Len:          func(v Value) int64 { return int64(len((*Runes)(v.Ptr).Elements)) },
	Equal:        runesTypeEqual,
	BinaryOp:     runesTypeBinaryOp,
	MethodCall:   runesTypeMethodCall,
	Access:       SeqAccessHook(RuneValue, runesTypeResolve),
	Assign:       SeqAssignHook(runesTypeResolve, Value.AsRune, runeTypeName),
	Append:       runesTypeAppend,
	Contains:     runesTypeContains,
	Slice:        SeqSliceHook(NewRunesValue, runesTypeResolve),
	SliceStep:    SeqSliceStepHook(NewRunesValue, runesTypeResolve),
	AsBool:       runesTypeAsBool,
	AsInt:        runesTypeAsInt,
	AsFloat:      runesTypeAsFloat,
	AsDecimal:    runesTypeAsDecimal,
	AsTime:       runesTypeAsTime,
	AsString:     func(v Value) (string, bool) { return EncodeText((*Runes)(v.Ptr).Elements), true },
	AsRunes:      func(v Value) ([]rune, bool) { return (*Runes)(v.Ptr).Elements, true },
	AsBytes:      runesTypeAsBytes,
	AsArray:      runesTypeAsArray,

	IsMethodPure: func(name string) bool { return !strings.HasSuffix(name, "_in_place") },
}
View Source
var TypeRunesIterator = ValueTypeDescr{
	Name:   ConstHook(runesIteratorTypeName),
	String: SeqIterStringHook[rune](runesIteratorTypeName, runesIteratorResolve),
	Next:   SeqIterNextHook[rune](runesIteratorResolve),
	Key:    SeqIterKeyHook[rune](runesIteratorResolve),
	Value:  SeqIterValueHook(RuneValue, runesIteratorResolve),
}
View Source
var TypeString = ValueTypeDescr{
	Name:         ConstHook(stringTypeName),
	String:       func(v Value) string { return strconv.Quote(*(*string)(v.Ptr)) },
	Format:       stringTypeFormat,
	Interface:    func(v Value) any { return *(*string)(v.Ptr) },
	EncodeJSON:   stringTypeEncodeJSON,
	EncodeBinary: stringTypeEncodeBinary,
	DecodeBinary: stringTypeDecodeBinary,
	IsTrue:       func(v Value) (bool, error) { return len(*(*string)(v.Ptr)) > 0, nil },
	IsIterable:   ConstHook(true),
	Iterator:     stringTypeIterator,
	Len:          func(v Value) int64 { return int64(v.Data) },
	Equal:        stringTypeEqual,
	BinaryOp:     stringTypeBinaryOp,
	MethodCall:   stringTypeMethodCall,
	Access:       stringTypeAccess,
	Contains:     stringTypeContains,
	Slice:        stringTypeSlice,
	SliceStep:    stringTypeSliceStep,
	AsBool:       func(v Value) (bool, bool) { return conv.ParseBool(*(*string)(v.Ptr)) },
	AsInt:        stringTypeAsInt,
	AsFloat:      stringTypeAsFloat,
	AsDecimal:    stringTypeAsDecimal,
	AsTime:       stringTypeAsTime,
	AsString:     func(v Value) (string, bool) { return *(*string)(v.Ptr), true },
	AsRunes:      func(v Value) ([]rune, bool) { return DecodeText(*(*string)(v.Ptr)), true },
	AsBytes:      func(v Value) ([]byte, bool) { return []byte(*(*string)(v.Ptr)), true },
	AsArray:      stringTypeAsArray,
	IsMethodPure: func(string) bool { return true },
}

TypeString is a string type descriptor.

View Source
var TypeTime = ValueTypeDescr{
	Name:         ConstHook(timeTypeName),
	String:       timeTypeString,
	Format:       timeTypeFormat,
	Interface:    timeTypeInterface,
	EncodeJSON:   timeTypeEncodeJSON,
	EncodeBinary: timeTypeEncodeBinary,
	DecodeBinary: timeTypeDecodeBinary,
	IsTrue:       timeTypeIsTrue,
	Len:          ConstHook(int64(1)),
	Equal:        timeTypeEqual,
	BinaryOp:     timeTypeBinaryOp,
	MethodCall:   timeTypeMethodCall,
	AsString:     timeTypeAsString,
	AsInt:        timeTypeAsInt,
	AsFloat:      timeTypeAsFloat,
	AsDecimal:    timeTypeAsDecimal,
	AsTime:       timeTypeAsTime,
	IsMethodPure: timeTypeIsMethodPure,
}

TypeTime is a time type descriptor.

View Source
var TypeUndefined = ValueTypeDescr{
	Name:         ConstHook(undefinedTypeName),
	Interface:    func(Value) any { return nil },
	String:       func(Value) string { return undefinedTypeName },
	Format:       undefinedTypeFormat,
	EncodeJSON:   func(Value) ([]byte, error) { return []byte("null"), nil },
	EncodeBinary: func(Value) ([]byte, error) { return []byte{}, nil },
	DecodeBinary: func(v *Value, _ []byte) error { *v = Undefined; return nil },
	IsTrue:       Const2Hook[bool, error](false, nil),

	IsIterable:   ConstHook(false),
	Equal:        undefinedTypeEqual,
	BinaryOp:     undefinedTypeBinaryOp,
	UnaryOp:      undefinedTypeUnaryOp,
	MethodCall:   undefinedTypeMethodCall,
	Access:       func(Value, Value, bc.Opcode) (Value, error) { return Undefined, nil },
	Slice:        func(Value, Value, Value) (Value, error) { return Undefined, nil },
	SliceStep:    func(Value, Value, Value, Value) (Value, error) { return Undefined, nil },
	AsBool:       func(Value) (bool, bool) { return false, true },
	IsMethodPure: func(string) bool { return true },
}
View Source
var TypeValuePtr = ValueTypeDescr{
	Name: func(v Value) string { return fmt.Sprintf("<%s:%s>", valuePtrTypeName, v.TypeName()) },
}
View Source
var ValueTypes [256]ValueTypeDescr

ValueTypes is the global registry of value type descriptors, indexed by type ID.

Functions

func ByteSymbolString added in v0.7.1

func ByteSymbolString(b byte) (string, bool)

ByteSymbolString is a byte's TEXT CONTENT — the one-octet text that holds it. TOTAL: below 0x80 that text is the octet's ASCII symbol, and at or above it the text holds the octet itself, which reads back as the octet's escape and converts back to this same byte. The old Latin-1 leak the partial version guarded against (equality reading "\xFF" as "ÿ") cannot happen now: "\xFF" is one ESCAPE symbol, never U+00FF, so b'\xff' == "\xff" is true and b'\xff' == "ÿ" is false, which is what both should be. The RENDER of a byte stays its number (format(b) -> "65").

func Const2Hook added in v0.3.2

func Const2Hook[C1 any, C2 any](c1 C1, c2 C2) func(Value) (C1, C2)

func ConstHook added in v0.3.2

func ConstHook[C any](c C) func(Value) C

func DecodeOctets added in v0.7.1

func DecodeOctets(b []byte) []rune

DecodeOctets is DecodeText over a byte slice. PURE by contract.

func DecodeText added in v0.7.1

func DecodeText(s string) []rune

DecodeText is `[]rune(s)` with the escape: it never substitutes U+FFFD and never loses an octet. PURE by contract.

func ElementsToBytes added in v0.7.1

func ElementsToBytes(elems []Value) ([]byte, bool)

ElementsToBytes is ElementsToRunes' octet twin.

func ElementsToEntries added in v0.7.1

func ElementsToEntries(elems []Value) (map[string]Value, bool)

ElementsToEntries reads a sequence as a map: each element must be EXACTLY a 2-element array (an entry) — any other element fails, including a 2-element text sequence, so a misread never silently becomes a map. The key goes through its own string conversion (absent on undefined/dict/record/callables, which therefore fail) and later entries overwrite earlier ones, the same last-wins rule as merging maps.

func ElementsToRunes added in v0.7.1

func ElementsToRunes(elems []Value) ([]rune, bool)

ElementsToRunes converts an element container's content to symbols: each element through its own rune conversion, all-or-nothing — a failing element fails the whole conversion, with no partial result and no substituted placeholder (the silent NUL/U+FFFD corruption this replaces).

func EncodeOctets added in v0.7.1

func EncodeOctets(rs []rune) []byte

EncodeOctets is EncodeText answering the octets directly. PURE by contract.

func EncodeRuneText added in v0.7.1

func EncodeRuneText(r rune) string

EncodeRuneText is `string(r)` with the escape — one symbol, or the one octet an escape stands for. PURE by contract.

func EncodeString

func EncodeString(b []byte, val string) []byte

EncodeString encodes given string as JSON string according to https://www.json.org/img/string.png Implementation is inspired by https://github.com/json-iterator/go

func EncodeText added in v0.7.1

func EncodeText(rs []rune) string

EncodeText is `string(rs)` with the escape: an escape rune contributes the single octet it stands for, so a value that came from DecodeText round-trips exactly. A rune outside the domain cannot reach here — see RuneInDomain — but is written as U+FFFD rather than panicking if one ever does. PURE by contract.

func EscapeRuneOctet added in v0.7.1

func EscapeRuneOctet(r rune) byte

EscapeRuneOctet returns the octet an escape rune stands for. Meaningless for any other rune. PURE by contract.

func IntAddChecked added in v0.7.1

func IntAddChecked(l, r int64) (int64, bool)

PURE by contract IntAddChecked / IntSubChecked / IntMulChecked / IntShlChecked are int's checked arithmetic — ok=false means the mathematical result does not fit int64 and the operation must raise instead of wrapping. Shared by the operator implementations here and the VM's integer fast paths.

func IntInRuneDomain added in v0.7.1

func IntInRuneDomain(i int64) bool

IntInRuneDomain is RuneInDomain over an int64, checking the wider range before the narrowing conversion — rune(1<<32 + 65) would otherwise truncate to 'A' and pass. PURE by contract.

func IntMulChecked added in v0.7.1

func IntMulChecked(l, r int64) (int64, bool)

func IntShlChecked added in v0.7.1

func IntShlChecked(l, r int64) (int64, bool)

func IntSubChecked added in v0.7.1

func IntSubChecked(l, r int64) (int64, bool)

func IsASCIIText added in v0.7.1

func IsASCIIText(s string) bool

IsASCIIText reports whether every octet is ASCII. This is the fast-path test for the text types: it implies well-formed, one octet per symbol, and byte offsets equal symbol offsets. Note what it is NOT: a rune count equal to the octet count, which an undecodable octet also satisfies while being none of those things. PURE by contract.

func IsBlankByte added in v0.7.1

func IsBlankByte(b byte) bool

IsBlankByte is the octet projection of the same notion: NUL plus ASCII whitespace, a fixed set of literal octets — deciding anything wider would require decoding, which octets never get.

func IsBlankElement added in v0.7.1

func IsBlankElement(e Value) bool

IsBlankElement reports whether e is "insignificant content" for a general container: undefined, or the element type's own zero value. Match-taking members called with NO argument act on this set (count() counts the significant elements, keep() answers exactly those, remove() drops the blanks, index() locates the first significant one). Each verb reads against the set the way its own name implies, which is why keep() and remove() land on the same answer with no argument: two different actions (keep the significant / remove the blank), not one operation under two names. It is a DEFAULT, not a policy — the argument forms override it at any call site, and a script that means "zeros are data" passes its own set. The text triple uses whitespace sets instead (IsBlankRune/IsBlankByte): these members are about separators and filler, and whitespace is text's filler.

func IsBlankRune added in v0.7.1

func IsBlankRune(r rune) bool

IsBlankRune: the symbol types' blank set — NUL plus Unicode whitespace. The blank set is one notion, NUL ∪ whitespace, projected into each receiver's ELEMENT DOMAIN: symbols (string/runes) take the Unicode White_Space class, octets (bytes) the ASCII subset — all the whitespace an octet can express — so the two sets agree everywhere both domains overlap and neither type imports the other's limitation.

func IsEscapeRune added in v0.7.1

func IsEscapeRune(r rune) bool

IsEscapeRune reports whether r is one of the 128 reserved octet escapes. PURE by contract.

func NormalizeIndex added in v0.3.2

func NormalizeIndex(index int64, length int64) (int64, bool)

NormalizeIndex normalizes index (-1 = last element, -2 = second to last, etc.) and checks if it's within bounds.

func NormalizeSliceBounds added in v0.3.2

func NormalizeSliceBounds(start int64, hasStart bool, end int64, hasEnd bool, length int64) (int64, int64)

NormalizeSliceBounds normalizes slice bounds (negative values count from the end, missing start defaults to 0, missing end defaults to length) and clamps them to [0, length]. If start > end after normalization, start is set to end.

func NormalizeSliceBoundsStep added in v0.3.2

func NormalizeSliceBoundsStep(si int64, hasStart bool, ei int64, hasEnd bool, step int64, length int64) (int64, int64)

NormalizeSliceBoundsStep returns the effective start and end for a step-based slice. Caller must ensure step != 0. For step > 0 the iteration is start..end (exclusive). For step < 0 the iteration is start..end (exclusive, with end possibly -1 to include index 0).

func OctetEscapeRune added in v0.7.1

func OctetEscapeRune(b byte) rune

OctetEscapeRune returns the escape rune reserved for an undecodable octet. PURE by contract.

func OctetsAreASCII added in v0.7.1

func OctetsAreASCII(b []byte) bool

OctetsAreASCII reports whether every octet is ASCII. PURE by contract.

func RuneInDomain added in v0.7.1

func RuneInDomain(r rune) bool

RuneInDomain reports whether r may exist as a `rune` value at all: a scalar value, or an escape. Everything else — a high surrogate, a negative, anything past U+10FFFF — has no octets to be and is refused where it would enter, so that every rune that exists can be encoded and no conversion out of `rune`/`runes` can fail. PURE by contract.

func RuneIsValid added in v0.7.1

func RuneIsValid(r rune) bool

RuneIsValid reports whether r is a real symbol — a Unicode scalar value. An escape is deliberately NOT valid: it stands for an octet that is not a symbol, which is exactly what a script needs to test for. PURE by contract.

func RunesAreASCII added in v0.7.1

func RunesAreASCII(rs []rune) bool

RunesAreASCII reports whether every element is an ASCII symbol. PURE by contract.

func RunesAreValid added in v0.7.1

func RunesAreValid(rs []rune) bool

RunesAreValid reports whether every element is a real symbol (no escapes). PURE by contract.

func SeqAccessHook added in v0.3.2

func SeqAccessHook[T any](
	t2v func(T) Value,
	resolve func(Value) *Seq[T],
) func(Value, Value, bc.Opcode) (Value, error)

SeqAccessHook returns a hook function that allows accessing an element of the sequence at a specified index. PURE by contract.

func SeqAssignHook added in v0.3.2

func SeqAssignHook[T any](
	resolve func(Value) *Seq[T],
	as func(Value) (T, bool),
	tn string,
) func(Value, Value, Value, bc.Opcode) error

IMPURE: returned Assign hook writes into the receiver. Not folded by the optimizer. See docs/purity.md.

SeqAssignHook returns a hook function that allows assigning a value to an element of the sequence at a specified index.

func SeqIndexRun added in v0.7.1

func SeqIndexRun[T any](elems []T, run []T, t2v func(T) Value, last bool) (int64, bool)

SeqIndexRun searches for a contiguous run by element equality — leftmost (or rightmost) match of the whole run, non-overlapping being irrelevant for a single locator.

func SeqIterKeyHook added in v0.4.1

func SeqIterKeyHook[T any](
	resolve func(v Value) *SeqIter[T],
) func(Value) (Value, error)

PURE: returned Key hook reads the iterator's current cursor without advancing it. See docs/purity.md.

func SeqIterNextHook added in v0.4.1

func SeqIterNextHook[T any](
	resolve func(v Value) *SeqIter[T],
) func(Value) bool

LOCALISED-STATE: returned Next hook advances the iterator's internal cursor. Iterators are expected to be held by a single consumer for the duration of iteration; the optimizer never speculatively evaluates iterator advancement. See docs/purity.md.

func SeqIterStringHook added in v0.4.1

func SeqIterStringHook[T any](
	tn string,
	resolve func(v Value) *SeqIter[T],
) func(Value) string

func SeqIterValueHook added in v0.4.1

func SeqIterValueHook[T any](
	t2v func(T) Value,
	resolve func(v Value) *SeqIter[T],
) func(Value) (Value, error)

PURE: returned Value hook reads the iterator's current element without advancing it. See docs/purity.md.

func SeqNameHook added in v0.4.1

func SeqNameHook(
	name string,
	immutableName string,
) func(Value) string

SeqNameHook returns a hook function that provides the type name for the sequence based on its mutability.

func SeqPadWidth added in v0.7.1

func SeqPadWidth(name string, n int64) (int, error)

SeqPadWidth reads a pad's target WIDTH as an allocation size, raising rather than panicking. It is the same ceiling as `repeat`'s, checked directly instead of as a product: a pad's width IS the resulting element count. The caller must have handled the no-op case (a width at or below the length) first, so what reaches here is always a real allocation. PURE by contract.

func SeqRepeatOperand added in v0.7.1

func SeqRepeatOperand(other Value) (int, bool, error)

SeqRepeatOperand reads the right operand of a sequence's `*` as a repeat count, so `x * n` is exactly `x.repeat(n)`. Only a numeric operand is a count: anything else is not a `*` at all and the caller must fall through to its ordinary invalid-operator path (a `false` second result), so `[1] * "ab"` reads as `invalid_binary_operator` rather than a count that failed to parse. A numeric one is held to the member's contract — whole-valued and non-negative — and its failures are catchable, named for the operator. PURE by contract.

func SeqRepeatTotal added in v0.7.1

func SeqRepeatTotal(name string, n, elems int) (int, error)

SeqRepeatTotal computes len(receiver) * count for a repeat, raising rather than overflowing or panicking. PURE by contract.

func SeqSliceHook added in v0.3.2

func SeqSliceHook[T any](
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
) func(Value, Value, Value) (Value, error)

SeqSliceHook returns a hook function that allows slicing the sequence using start and end indices. Always returns an independently-owned copy of the selected range (P4-002, closing P01/P02) — sharing backing storage with the source is SeqSliceView's job now (the explicit `_view` twin), not this hook's. PURE by contract.

func SeqSliceStepHook added in v0.3.2

func SeqSliceStepHook[T any](
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
) func(Value, Value, Value, Value) (Value, error)

SeqSliceStepHook returns a hook function that allows slicing the sequence using start and end indices with a specified step. PURE by contract.

func SetValueType

func SetValueType(t uint8, f ValueTypeDescr) error

SetValueType registers a user-defined value type descriptor for the given type ID.

func TextIsValid added in v0.7.1

func TextIsValid(s string) bool

TextIsValid reports whether s decodes with no escapes — i.e. it is well-formed UTF-8. PURE by contract.

func TextRuneCount added in v0.7.1

func TextRuneCount(s string) int

TextRuneCount counts symbols the way DecodeText produces them: one per symbol, one per undecodable octet. utf8.RuneCountInString already counts each bad octet as one, so the two agree by construction. PURE by contract.

func TimeFromComponents added in v0.7.1

func TimeFromComponents(m map[string]Value) (time.Time, error)

TimeFromComponents rebuilds an instant from its constitutive parts. Every key is optional and defaults to the zero time's part, so an empty map is the zero time; an UNKNOWN key raises, so a typo is an error rather than silently year 1. The way back from t.components().

func ValueHook added in v0.3.2

func ValueHook(v Value, e error) func(Value) (Value, error)

Types

type Array

type Array = Seq[Value]

type ArrayIterator

type ArrayIterator = SeqIter[Value]

type BuiltinClosure added in v0.4.1

type BuiltinClosure struct {
	Func     NativeFunc
	Name     string
	Arity    int
	Variadic bool
}

func (*BuiltinClosure) Set added in v0.4.1

func (f *BuiltinClosure) Set(fn NativeFunc, name string, arity int, variadic bool)

type BuiltinFunction

type BuiltinFunction struct {
	Func     NativeFunc
	Module   string
	Name     string
	Arity    int
	Variadic bool
	Pure     bool
}

func NewBuiltinFunction added in v0.4.1

func NewBuiltinFunction(name string, fn NativeFunc, arity int, variadic bool, pure bool) *BuiltinFunction

NewBuiltinFunction creates a new builtin function object. name is the name of the function. fn is the native function to be called. arity is the number of arguments the function takes. variadic is true if the function takes a variable number of arguments, in which case arity is the minimum number of arguments required. pure is true if the function does not have side effects, does not rely on external state, and always returns the same output for the same input.

type Bytes

type Bytes = Seq[byte]

type BytesIterator

type BytesIterator = SeqIter[byte]

type CompiledFunction

type CompiledFunction struct {
	Instructions  bc.Instructions
	Free          []*Value
	SourceMap     map[int]Pos
	NumLocals     int // number of local variables (including function parameters)
	MaxStack      int // estimated maximum operand-stack depth which can be reached during execution
	NumParameters int
	NamedResult   int // local-slot index of function's named result: 0 = no named result, N > 0 means slot N-1
	VarArgs       bool
}

func (*CompiledFunction) DecodeBinary added in v0.4.1

func (o *CompiledFunction) DecodeBinary(data []byte) error

func (*CompiledFunction) EncodeBinary added in v0.4.1

func (o *CompiledFunction) EncodeBinary() ([]byte, error)

func (*CompiledFunction) GobDecode added in v0.4.1

func (o *CompiledFunction) GobDecode(data []byte) error

GobDecode wraps binary decoding to mirror GobEncode.

func (CompiledFunction) GobEncode added in v0.4.1

func (o CompiledFunction) GobEncode() ([]byte, error)

GobEncode wraps binary encoding so gob does not reflect over fields like Free []*Value (which include unsafe.Pointer).

func (*CompiledFunction) HasNamedResult added in v0.2.1

func (o *CompiledFunction) HasNamedResult() bool

func (*CompiledFunction) NamedResultSlot added in v0.2.1

func (o *CompiledFunction) NamedResultSlot() int

NamedResultSlot returns the local-slot index of the named result. Caller should check HasNamedResult first.

func (*CompiledFunction) Set

func (o *CompiledFunction) Set(instructions bc.Instructions, free []*Value, sourceMap map[int]Pos, numLocals, maxStack int, numParameters int, namedResult int, varArgs bool)

func (*CompiledFunction) Size

func (o *CompiledFunction) Size() int64

func (*CompiledFunction) SourcePos

func (o *CompiledFunction) SourcePos(ip int) Pos

type Dict added in v0.0.8

type Dict struct {
	Elements map[string]Value
	// IsView reports whether Elements is shared with another value (a record it
	// was viewed from); set only by the explicit _view constructors
	IsView bool
}

func (*Dict) Set added in v0.0.8

func (o *Dict) Set(elements map[string]Value)

type DictIterator added in v0.0.8

type DictIterator struct {
	Elements map[string]Value
	Keys     []string
	// contains filtered or unexported fields
}

func (*DictIterator) Set added in v0.0.8

func (o *DictIterator) Set(m map[string]Value)

Set snapshots the map's keys in sorted order. Iteration over a map is ORDERED: `for k in d` and `for k, v in d` visit keys lexically, on a `record` as much as a `dict` (both types iterate through this one iterator). The order is part of the contract, not an accident of the Go map — a script that folds, prints or accumulates over a map is reproducible run to run, and agrees with `keys()`/`values()`/`array()` and every other member, all of which sort too.

type Error

type Error struct {
	Payload Value
	Kind    string
	Fatal   bool
}

func (*Error) Set

func (e *Error) Set(payload Value, kind string, fatal bool)

type FormatSpec added in v0.4.1

type FormatSpec struct {
	Spec fspec.FormatSpec
	Text string // original mini-language text (without the leading ':')
}

FormatSpec wraps a fully parsed fspec.FormatSpec together with its original textual form. It is an internal value kind: it lives only in the constant pool (referenced by OpFormat) and is never visible to user code.

func (FormatSpec) Equal added in v0.4.1

func (f FormatSpec) Equal(other FormatSpec) bool

func (*FormatSpec) Set added in v0.4.1

func (f *FormatSpec) Set(spec fspec.FormatSpec, text string)

type IntRange

type IntRange struct {
	Start int64
	Stop  int64
	Step  int64
}

func (*IntRange) Contains

func (o *IntRange) Contains(i int64) bool

func (*IntRange) Empty

func (o *IntRange) Empty() bool

func (*IntRange) Get

func (o *IntRange) Get(i int64) (int64, bool)

func (*IntRange) Len

func (o *IntRange) Len() int64

func (*IntRange) Set

func (o *IntRange) Set(start, stop, step int64)

type IntRangeIterator

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

func (*IntRangeIterator) Set

func (i *IntRangeIterator) Set(start, stop, step int64)

type NativeFunc

type NativeFunc = func(VM, []Value) (Value, error)

type Pos

type Pos int

func (Pos) IsValid

func (p Pos) IsValid() bool

type Primitive added in v0.4.1

type Primitive struct {
	Type uint8
	Data uint64
}

Primitive value (used in static storage)

func (Primitive) Value added in v0.4.1

func (p Primitive) Value() Value

type Record added in v0.4.1

type Record struct {
	Elements map[string]Value
	// IsView reports whether Elements is shared with another value (a dict it
	// was viewed from); set only by the explicit _view constructors
	IsView bool
}

func (*Record) Set added in v0.4.1

func (o *Record) Set(elements map[string]Value)

type Runes added in v0.0.6

type Runes = Seq[rune]

type RunesIterator added in v0.0.6

type RunesIterator = SeqIter[rune]

type Seq added in v0.3.2

type Seq[T any] struct {
	Elements []T
	// IsView reports whether Elements shares backing storage with some other Value, rather than being an
	// independently-owned allocation. Set only by the explicit `_view` constructors (slice_view/chunk_view);
	// every other constructor path leaves it at its zero value (false), including today's still-sharing
	// `slice`/`chunk` default — that default hasn't been renamed to `_view` yet (see P4-002), so it isn't
	// tagged as one. Read by the `is_view()` member predicate.
	IsView bool
}

func (*Seq[T]) Set added in v0.3.2

func (o *Seq[T]) Set(elements []T)

type SeqIter added in v0.4.1

type SeqIter[T any] struct {
	Elements []T
	// contains filtered or unexported fields
}

func (*SeqIter[T]) Set added in v0.4.1

func (i *SeqIter[T]) Set(v []T)

type Static added in v0.4.1

type Static struct {
	Primitives        []Primitive
	Decimals          []dec128.Dec128
	Strings           []string
	StringLens        []int64 // rune count per static string — always len(Strings) entries, see BuildStringLens
	Runes             []Runes
	Bytes             []Bytes
	Times             []time.Time
	FormatSpecs       []FormatSpec
	CompiledFunctions []CompiledFunction
	NameLists         [][]string
	Ranges            []IntRange
}

Static variables

func (*Static) BuildStringLens added in v0.7.1

func (s *Static) BuildStringLens()

BuildStringLens populates StringLens with the rune count of each static string. It must run at every point a Static is finalized (compiler build, bytecode decode) so the VM's LoadStaticString never recounts on the hot path. Idempotent.

type VM

type VM interface {
	Abort()                             // aborts execution of the current script
	IsStackEmpty() bool                 // returns true if there are no frames on the call stack
	Call(Value, []Value) (Value, error) // calls a compiled function
	Run() error                         // runs the VM until completion
	Recover() Value                     // returns the in-flight error if in "deferred-for" frame
}

type Value

type Value struct {
	Type      uint8
	Immutable bool
	Data      uint64
	Ptr       unsafe.Pointer
}

Value represents a boxed Kavun value.

func BoolValue

func BoolValue(b bool) Value

func BuiltinFunctionValue

func BuiltinFunctionValue(id uint64) Value

BuiltinFunctionValue creates new boxed builtin function value.

func ByteValue added in v0.0.10

func ByteValue(v byte) Value

func DictToRecord added in v0.7.1

func DictToRecord(v Value, share bool) Value

DictToRecord converts a dict to a record. share=true reuses the dict's own map directly (record_view() / record_view(dict_val) — the explicit performance opt-in, today's original dict.record() behavior preserved under the new name); share=false (record() / dict_val.record()) builds an independent shallow copy — a new top-level map, elements copied by reference (not recursively cloned), matching every other type's own `.record()` conversion (array/bytes/runes/string/range all shallow-copy the same way). Used by both the dict.record()/dict.record_view() member cases and the free record()/record_view() constructors.

func FloatValue

func FloatValue(f float64) Value

func ForEachCallback added in v0.3.2

func ForEachCallback(args []Value) (Value, error)

ForEachCallback validates that the only argument is a callback (non-variadic function of arity 1 or 2) and returns it as a Value.

func IntValue

func IntValue(i int64) Value

func MapToSortedEntries added in v0.7.1

func MapToSortedEntries(m map[string]Value) []Value

MapToSortedEntries materializes a map's conversion elements — its entries — as [[k, v], ...] in canonical key-sorted order, so the two directions of the sequence<->map boundary round-trip up to that ordering.

func NewArrayIteratorValue

func NewArrayIteratorValue(arr []Value) Value

func NewArrayValue

func NewArrayValue(arr []Value, immutable bool) Value

func NewBuiltinClosureValue added in v0.4.1

func NewBuiltinClosureValue(name string, fn NativeFunc, arity int, variadic bool) Value

func NewBytesIteratorValue

func NewBytesIteratorValue(b []byte) Value

func NewBytesValue

func NewBytesValue(b []byte, immutable bool) Value

func NewCompiledFunctionValue

func NewCompiledFunctionValue(
	instructions bc.Instructions,
	free []*Value,
	sourceMap map[int]Pos,
	numLocals int,
	maxStack int,
	numParameters int,
	namedResult int,
	varArgs bool,
) Value

func NewDecimalValue

func NewDecimalValue(d dec128.Dec128) Value

func NewDictIteratorValue added in v0.0.8

func NewDictIteratorValue(m map[string]Value) Value

func NewDictValue added in v0.0.8

func NewDictValue(m map[string]Value, immutable bool) Value

func NewErrorValue

func NewErrorValue(payload Value, kind string, fatal bool) Value

func NewIntRangeIteratorValue

func NewIntRangeIteratorValue(start, stop, step int64) Value

func NewIntRangeValue

func NewIntRangeValue(start, stop, step int64) Value

func NewRecordValue

func NewRecordValue(m map[string]Value, immutable bool) Value

func NewRunesIteratorValue added in v0.0.6

func NewRunesIteratorValue(s []rune) Value

func NewRunesValue added in v0.0.6

func NewRunesValue(r []rune, immutable bool) Value

func NewRuntimeErrorValue added in v0.2.1

func NewRuntimeErrorValue(kind string, fatal bool, message string) Value

func NewStaticBytesValue added in v0.5.1

func NewStaticBytesValue(b *Bytes) Value

func NewStaticCompiledFunctionValue added in v0.4.1

func NewStaticCompiledFunctionValue(cf *CompiledFunction) Value

func NewStaticDecimalValue added in v0.4.1

func NewStaticDecimalValue(d *dec128.Dec128) Value

func NewStaticFormatSpecValue added in v0.4.1

func NewStaticFormatSpecValue(fs *FormatSpec) Value

func NewStaticIntRangeValue added in v0.6.3

func NewStaticIntRangeValue(o *IntRange) Value

NewStaticIntRangeValue wraps a range backed by the compiler's static pool (see compiler/static.go), sharing the pool's storage directly instead of allocating a fresh IntRange. Safe because IntRange is always immutable and has no reachable mutable substructure — mirrors NewStaticDecimalValue/NewStaticTimeValue.

func NewStaticRunesValue added in v0.4.1

func NewStaticRunesValue(r *Runes) Value

func NewStaticStringValue added in v0.4.1

func NewStaticStringValue(s *string) Value

func NewStaticStringValueCounted added in v0.7.1

func NewStaticStringValueCounted(s *string, runeLen int64) Value

NewStaticStringValueCounted is NewStaticStringValue with a precomputed rune count

func NewStaticTimeValue added in v0.5.1

func NewStaticTimeValue(t *time.Time) Value

func NewStringValue

func NewStringValue(s string) Value

func NewTimeValue

func NewTimeValue(t time.Time) Value

func NewValuePtrValue added in v0.4.1

func NewValuePtrValue(p *Value) Value

func RangeFromComponents added in v0.7.1

func RangeFromComponents(m map[string]Value) (Value, error)

RangeFromComponents rebuilds a range from {start, stop[, step]}: start and stop are required, step defaults to 1, an unknown key raises. The way back from r.components().

func RecordToDict added in v0.7.1

func RecordToDict(v Value, share bool) Value

RecordToDict converts a record to a dict. share=true reuses the record's own map directly (dict_view(record_val) — the explicit performance opt-in, today's original dict(record_val) behavior preserved under the new name); share=false (dict(record_val)) builds an independent shallow copy — a new top-level map, elements copied by reference (not recursively cloned), matching every other type's own `.dict()` conversion. Only ever reached via the free `dict`/`dict_view` constructors: record has no `MethodCall` switch (see P14), so there is no `record_val.dict()` member form and never was.

func RefValue added in v0.3.2

func RefValue(v Value) Value

RefValue is a dummy constructor used in internal generics.

func RuneValue added in v0.0.6

func RuneValue(c rune) Value

func SeqAnchoredMember added in v0.7.1

func SeqAnchoredMember[T any](
	name string,
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
	suffix bool,
	remove bool,
) (Value, error)

SeqAnchoredMember implements has_prefix/has_suffix (a bool: is any run in the set anchored there?) and remove_prefix/remove_suffix (remove one exact anchored run, ONCE; absent from the receiver → unchanged; the longest matching run in a variadic set wins, keeping the set order-independent). Element | run | homogeneous set; no predicate ("the first element satisfies f" is index(f) == 0) and no no-argument form. The empty run is anchored everywhere: has_prefix on it answers true, remove_prefix on it removes nothing.

func SeqChunk added in v0.3.2

func SeqChunk[T any](
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqChunk divides the sequence into chunks of the specified size and returns a new sequence containing the chunks — always independently-owned copies (P4-002: the `copy` bool parameter is retired; chunk_view() is the explicit opt-in for sharing now, not a second argument here).

func SeqChunkView added in v0.7.1

func SeqChunkView[T any](
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqChunkView is the `_view` twin of chunk(): always shares backing storage with the source (today's chunk(size, false) behavior), and marks every resulting chunk as a view via IsView.

func SeqForEach added in v0.3.2

func SeqForEach[T any](
	vm VM,
	v Value,
	args []Value,
	t2v func(T) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqForEach iterates over the elements of the sequence and calls the provided callback function for each element.

func SeqIndex added in v0.7.1

func SeqIndex[T any](
	vm VM,
	v Value,
	args []Value,
	last bool,
	t2v func(T) Value,
	resolve func(Value) *Seq[T],
	isRun func(Value) bool,
	matchRun func(elems []T, run Value, last bool) (int64, bool, error),
	checkElem func(name string, a Value) error,
	isBlank func(T) bool,
) (Value, error)

SeqIndex is the locator: index([x[, default]]) / index_last([x[, default]]). One name, and the argument's type selects the reading — a function is a predicate, an argument of the receiver's own kind is a contiguous run (the caller supplies matchRun for that; nil means the reading is not available), no argument means the first/last SIGNIFICANT element (the blank set), anything else is one element compared with ==. Never variadic: the trailing slot is the default, and no type test could tell a second needle from a fallback.

func SeqMap added in v0.3.2

func SeqMap[T any](
	vm VM,
	v Value,
	args []Value,
	t2v func(T) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqMap applies a given function to each element in the sequence and returns a new sequence containing the results.

func SeqMatchMember added in v0.7.1

func SeqMatchMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	toElem func(Value) (T, bool, error),
	isRunArg func(Value) bool,
	toRun func(Value) ([]T, error),
	eq func(T, T) bool,
	isBlank func(T) bool,
) (Value, error)

SeqMatchMember implements contains/count/keep/remove/any/all over one dispatch. any/all refuse a run PERMANENTLY (the contiguous-run query is contains's, and "every element is this subsequence" has no universal reading); remove's no-argument form drops the blanks (the one destructive no-arg cell — documented, not guarded).

func SeqPadMember added in v0.7.1

func SeqPadMember[T any](
	name string,
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	fill func(name string, a Value) (T, error),
	defaultFill T,
	start bool,
) (Value, error)

SeqPadMember implements pad_start(n[, fill]) / pad_end(n[, fill]): n counts ELEMENTS, the fill is exactly one element — a run fill raises, because cycling a multi-element fill hides a truncation rule — and its default is the blank set's canonical member. A width at or below the length is a no-op; one past MaxSequenceLen raises rather than panicking the host in makeslice.

func SeqPartitionMember added in v0.7.1

func SeqPartitionMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
	isBlank func(T) bool,
) (Value, error)

SeqPartitionMember implements partition(...seps): the one-split form — [before, separator, after], the separator as matched; a miss answers [receiver, empty, empty]. Same separator menu as split; the leftmost hit wins, the longest at that position (the set stays order-independent). The blank no-argument form takes the whole maximal run of filler as the separator, exactly the run split's derivation collapses on one hit.

func SeqReduce added in v0.3.2

func SeqReduce[T any](
	vm VM,
	v Value,
	args []Value,
	t2v func(T) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqReduce reduces the sequence to a single value by applying a given binary function cumulatively to the elements of the sequence, from left to right. The function can have arity 2 (accumulator, element) or 3 (accumulator, index, element).

func SeqReplaceMember added in v0.7.1

func SeqReplaceMember[T any](
	name string,
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
) (Value, error)

SeqReplaceMember implements replace(old, new): element or run in BOTH positions, each argument read by its own type (the two slots have different roles, so no homogeneity constraint applies between them); every occurrence, leftmost non-overlapping. Never variadic — position 2 is the replacement — and never a predicate. An empty old run matches nothing: the receiver comes back unchanged.

func SeqSlice added in v0.7.1

func SeqSlice(v Value, args []Value) (Value, error)

SeqSlice is the member-call form of two-part slicing (`x.slice(start, end)`), reusing the same (now always-copying, per P4-002) Slice hook the `a[i:j]` operator uses — same operation, second spelling, per Rule 10. Accepts 0, 1, or 2 args, mirroring the operator's own optional start/end.

func SeqSliceView added in v0.7.1

func SeqSliceView[T any](
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
) (Value, error)

SeqSliceView is the `_view` twin of two-part slicing: shares backing storage with the source via a raw re-slice — the sharing behavior `a[i:j]` itself had before P4-002, preserved here as the explicit opt-in. Marked as a view via IsView. Accepts 0, 1, or 2 args, mirroring the operator's own optional start/end.

func SeqSplice added in v0.7.1

func SeqSplice[T any](
	args []Value,
	mutate bool,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	convertItems func(args []Value, methodName string) ([]T, error),
	typeName string,
) (Value, error)

SeqSplice implements splice()/splice_in_place() for any Seq[T]-backed type (array/bytes/runes). args[0] is the receiver value — kept as the first positional arg (rather than a separate v Value parameter) so the "argument first/second/third" error wording, established when array was the only type this ran for, stays identical now that bytes/runes share this same function (P5-002). convertItems turns the trailing variadic args (from index 3 on) into []T: array's is a plain identity (elements are already Values, no conversion or flattening), while bytes'/runes' reuse the same flattening-and-type-checking logic append() already uses (bytesAppendItems/runesAppendItems), so passing a bytes/runes value as one of splice's insert items spreads it exactly like it does for append(), rather than erroring or nesting it as a single opaque element. mutate=true: IMPURE, mutates the receiver in place and returns the deleted items (splice_in_place()) — rejects an immutable receiver. mutate=false: PURE, returns the modified sequence instead of the deleted items (splice()), never touching the receiver — works regardless of the receiver's mutability. See docs/purity.md.

func SeqSplitMember added in v0.7.1

func SeqSplitMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
	isBlank func(T) bool,
) (Value, error)

SeqSplitMember implements split(...seps): separator element | run | homogeneous set | element-level predicate | absent = the blank set. Explicit separators keep empty pieces between adjacent hits (n matches answer n+1 pieces, so an empty receiver splits into one empty piece); the blank form answers the maximal runs of SIGNIFICANT content — the blanks are filler, and there is no piece between two of them — which is what preserves the classic no-argument whitespace split. Runs match leftmost-longest, non-overlapping; an empty separator run matches nothing.

func SeqStructuralMember added in v0.7.1

func SeqStructuralMember[T any](
	name string,
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	fill func(name string, a Value) (T, error),
	defaultFill T,
	eq func(T, T) bool,
	isBlank func(T) bool,
) (Value, error)

SeqStructuralMember routes one structural member — or the pure half of its _in_place twin — by verb. The caller strips nothing: the full member name reaches every error message; only the verb switch ignores the suffix. has_prefix/has_suffix answer a bool and so have no twins; the caller's case list enforces that.

func SeqTrimMember added in v0.7.1

func SeqTrimMember[T any](
	name string,
	v Value,
	args []Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
	isBlank func(T) bool,
	start bool,
	end bool,
) (Value, error)

SeqTrimMember implements trim(...set) / trim_start / trim_end: drop leading/trailing elements while they belong to the set — repeat-while, ELEMENTS only. A run argument raises (the anchored exact-run form is remove_prefix/remove_suffix — people who write trim(run) mean that), and so does a predicate; no argument means the blank set.

func TripleFlatMapMember added in v0.7.1

func TripleFlatMapMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
) (Value, error)

TripleFlatMapMember: flat_map on a text receiver — each callback result is text content read as a run (a single element is a length-1 run), undefined contributes nothing.

func TripleMapMember added in v0.7.1

func TripleMapMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
) (Value, error)

TripleMapMember: map on a text receiver — strictly 1:1, answering the receiver's type.

func TripleMatchMember added in v0.7.1

func TripleMatchMember[T any](
	vm VM,
	name string,
	v Value,
	args []Value,
	t2v func(T) Value,
	alloc func([]T, bool) Value,
	resolve func(Value) *Seq[T],
	encode func(name string, a Value) (run []T, elementClass bool, err error),
	eq func(T, T) bool,
	isBlank func(T) bool,
) (Value, error)

TripleMatchMember is the match engine for the text triple, where acceptance collapses: every accepted argument is TEXT CONTENT, encoded into the receiver's representation and read as a run (a length-1 run is the element case). The element/run classes survive only for the homogeneity check of a variadic set, decided by argument TYPE (byte/rune/in-range int = element class; string/runes/bytes = run class), never by length.

func (Value) Access

func (v Value) Access(index Value, mode bc.Opcode) (Value, error)

PURE by contract

func (Value) Append

func (v Value) Append(args []Value, mutate bool) (Value, error)

MUTATE-DEPENDENT by contract: mutate=true mutates the receiver in place (append_in_place()); mutate=false returns an independent value with the items appended (append()).

func (Value) Arity

func (v Value) Arity() int

PURE by contract

func (Value) AsArray

func (v Value) AsArray() ([]Value, bool)

PURE by contract

func (Value) AsBool

func (v Value) AsBool() (bool, bool)

PURE by contract

func (Value) AsByte

func (v Value) AsByte() (byte, bool)

PURE by contract

func (Value) AsBytes

func (v Value) AsBytes() ([]byte, bool)

PURE by contract

func (Value) AsDecimal

func (v Value) AsDecimal() (dec128.Dec128, bool)

PURE by contract

func (Value) AsDict added in v0.0.8

func (v Value) AsDict() (map[string]Value, bool)

PURE by contract

func (Value) AsFloat

func (v Value) AsFloat() (float64, bool)

PURE by contract

func (Value) AsInt

func (v Value) AsInt() (int64, bool)

PURE by contract

func (Value) AsIntRange added in v0.6.3

func (v Value) AsIntRange() (IntRange, bool)

PURE by contract

func (Value) AsRune added in v0.0.6

func (v Value) AsRune() (rune, bool)

PURE by contract

func (Value) AsRunes added in v0.0.6

func (v Value) AsRunes() ([]rune, bool)

PURE by contract

func (Value) AsString

func (v Value) AsString() (string, bool)

PURE by contract

func (Value) AsTime

func (v Value) AsTime() (time.Time, bool)

PURE by contract

func (Value) AsValue added in v0.3.2

func (v Value) AsValue() (Value, bool)

PURE by contract

func (Value) Assign

func (v Value) Assign(idx Value, val Value, mode bc.Opcode) error

IMPURE by contract (mutates target)

func (Value) BinaryOp

func (v Value) BinaryOp(op token.Token, rhs Value) (Value, error)

PURE by contract.

func (Value) Call

func (v Value) Call(vm VM, args []Value) (Value, error)

CALLABLE-DEPENDENT by contract

func (Value) Contains

func (v Value) Contains(e Value) (bool, error)

PURE by contract Contains is the `in` operator: exactly the contains member's VALUE readings — element | run | family, full member acceptance — raising on an unacceptable operand. A callable operand raises too: an operator operand is always a value; the predicate reading is the member's (contains(f) ≡ any(f)).

func (*Value) Copy

func (v *Value) Copy(deep bool) (Value, error)

PURE by contract: deep=true recursively copies nested Values (copy()); deep=false copies only the top-level container/wrapper, sharing nested structure (copy_shallow()).

func (*Value) DecodeBinary

func (v *Value) DecodeBinary(data []byte) error

IMPURE by contract (mutates target)

func (Value) Delete

func (v Value) Delete(key Value, mutate bool) (Value, error)

MUTATE-DEPENDENT by contract: mutate=true mutates the receiver in place (delete_in_place()); mutate=false returns an independent container without the key (delete()).

func (Value) Elem added in v0.7.1

func (v Value) Elem() (Value, error)

LOCALISED-STATE by contract (reads iterator cursor) Elem is the single-variable for-in binding: the container's ELEMENT — the Value hook everywhere except map iterators, whose element is the KEY (the value is the attachment; the two-variable form reads both).

func (Value) EncodeBinary

func (v Value) EncodeBinary() ([]byte, error)

PURE by contract

func (Value) EncodeJSON

func (v Value) EncodeJSON() ([]byte, error)

PURE by contract

func (Value) Equal

func (v Value) Equal(rhs Value) bool

PURE by contract.

func (Value) Format added in v0.1.3

func (v Value) Format(sp fspec.FormatSpec) (string, error)

PURE by contract

func (Value) Freeze added in v0.7.1

func (v Value) Freeze() (Value, error)

PURE by contract: never mutates the receiver or affects any existing alias into it. Deep-copies first (Copy(true)), then marks only the fresh, not-yet-observable clone immutable throughout (MarkImmutableDeep) — safe for the same reason export's codegen is (see MarkImmutableDeep's own precondition): nothing outside this call can reach the clone yet. This is freeze()'s definition; freeze_shallow() is ToImmutable() by another name — the explicit twin that skips the detach and so does NOT protect against another live, still-mutable alias into the same body.

func (*Value) GobDecode

func (v *Value) GobDecode(data []byte) error

GobDecode wraps binary decoding to mirror GobEncode.

func (Value) GobEncode

func (v Value) GobEncode() ([]byte, error)

GobEncode wraps binary encoding so gob does not reflect over unsafe.Pointer field.

func (Value) Interface

func (v Value) Interface() any

PURE by contract

func (Value) IsCallable

func (v Value) IsCallable() bool

PURE by contract

func (Value) IsIterable

func (v Value) IsIterable() bool

PURE by contract

func (Value) IsPrimitive added in v0.4.1

func (v Value) IsPrimitive() bool

PURE by contract

func (Value) IsTrue

func (v Value) IsTrue() (bool, error)

PURE by contract

func (Value) IsUserDefined

func (v Value) IsUserDefined() bool

PURE by contract

func (Value) IsVariadic

func (v Value) IsVariadic() bool

PURE by contract

func (Value) Iterator

func (v Value) Iterator() (Value, error)

PURE by contract (constructs new iterator)

func (Value) Key

func (v Value) Key() (Value, error)

LOCALISED-STATE by contract (reads iterator cursor)

func (Value) Len

func (v Value) Len() int64

PURE by contract

func (*Value) MarkImmutableDeep added in v0.7.1

func (v *Value) MarkImmutableDeep()

IMPURE by contract (mutates target)

MarkImmutableDeep flips Immutable to true on v and, recursively, on every Value reachable through it — array/dict/record elements and an error's payload — without cloning anything. Unlike ToImmutable, which only ever flips the top-level flag, this walks into containers so that no reachable nested Value keeps looking mutable after the top-level one no longer is. Only safe to call when nothing outside the caller can still observe v (or anything under it) as mutable. Deliberately does not recurse into a compiled function's closed-over free variables (CompiledFunction.Free) or ValuePtr indirection: those are variable-capture aliasing, a different mechanism from container nesting, and out of scope here. Does not guard against cyclic containers, matching every other recursive Value walk in this package (e.g. arrayTypeCopy) — Kavun's shared-by-default container model doesn't defend against that anywhere today.

func (Value) MethodCall

func (v Value) MethodCall(vm VM, name string, args []Value) (Value, error)

METHOD-DEPENDENT by contract: purity varies per method name, reported by IsMethodPure (see docs/purity.md)

func (Value) Next

func (v Value) Next() bool

LOCALISED-STATE by contract (advances iterator cursor)

func (*Value) Set

func (v *Value) Set(val Value)

func (Value) Slice

func (v Value) Slice(s Value, e Value) (Value, error)

PURE by contract

func (Value) SliceStep added in v0.0.10

func (v Value) SliceStep(s Value, e Value, step Value) (Value, error)

PURE by contract

func (Value) String

func (v Value) String() string

PURE by contract

func (Value) ToImmutable added in v0.3.2

func (v Value) ToImmutable() (Value, error)

PURE by contract: exposed to scripts as freeze_shallow() (member call and free builtin). Despite the naming symmetry with freeze()'s "_shallow"/deep split, this never mutates any shared storage — it returns a new header (Immutable flag flipped) pointing at the same body, so it's a genuinely pure operation like copy() or copy_shallow(), not an "_in_place"-style body mutation: the caller must capture and reassign the result (`x = x.freeze_shallow()` / `x = freeze_shallow(x)`) to see any effect on their own variable, and a pre-existing sibling binding into the same body is unaffected and stays independently mutable. Renamed from freeze_in_place 2026-08-17 — that name wrongly implied the same "mutates without reassignment" behavior as append_in_place/splice_in_place/delete_in_place, which this operation structurally cannot do (Immutable lives on the header, not the body).

func (Value) TypeName

func (v Value) TypeName() string

PURE by contract

func (Value) UnaryOp

func (v Value) UnaryOp(op token.Token) (Value, error)

PURE by contract

func (Value) Value

func (v Value) Value() (Value, error)

type ValueTypeDescr added in v0.4.1

type ValueTypeDescr struct {
	Name         func(v Value) string                                                      // PURE by contract
	String       func(v Value) string                                                      // PURE by contract
	Format       func(v Value, sp fspec.FormatSpec) (string, error)                        // PURE by contract
	Interface    func(v Value) any                                                         // PURE by contract
	EncodeJSON   func(v Value) ([]byte, error)                                             // PURE by contract
	EncodeBinary func(v Value) ([]byte, error)                                             // PURE by contract
	DecodeBinary func(v *Value, data []byte) error                                         // IMPURE by contract (mutates target)
	IsTrue       func(v Value) (bool, error)                                               // PURE by contract
	Copy         func(v Value, deep bool) (Value, error)                                   // PURE by contract: deep=true recursively copies nested Values (copy()); deep=false copies only the top-level container/wrapper, sharing nested structure (copy_shallow())
	Equal        func(v Value, other Value, final bool) bool                               // PURE by contract
	BinaryOp     func(v Value, other Value, op token.Token, reflected bool) (Value, error) // PURE by contract
	UnaryOp      func(v Value, op token.Token) (Value, error)                              // PURE by contract
	MethodCall   func(vm VM, v Value, name string, args []Value) (Value, error)            // METHOD-DEPENDENT by contract: purity varies per method name, reported by IsMethodPure (see docs/purity.md)

	IsIterable func(v Value) bool                                         // PURE by contract
	Contains   func(v Value, e Value) (bool, error)                       // PURE by contract — the `in` operator: contains' VALUE readings (element | run | family), raising on an unacceptable operand; a callable raises, an operator operand is always a value
	Len        func(v Value) int64                                        // PURE by contract
	Iterator   func(v Value) (Value, error)                               // PURE by contract (constructs fresh iterator)
	Access     func(v Value, index Value, mode bc.Opcode) (Value, error)  // PURE by contract
	Assign     func(v Value, index Value, r Value, mode bc.Opcode) error  // IMPURE by contract (mutates target); mode is AccessIndex or AccessSelector — the spelling the assignment used
	Append     func(v Value, args []Value, mutate bool) (Value, error)    // MUTATE-DEPENDENT by contract: mutate=true mutates the receiver in place (append_in_place()); mutate=false returns an independent value with the items appended (append())
	Slice      func(v Value, s Value, e Value) (Value, error)             // PURE by contract
	Delete     func(v Value, key Value, mutate bool) (Value, error)       // MUTATE-DEPENDENT by contract: mutate=true mutates the receiver in place (delete_in_place()); mutate=false returns an independent container without the key (delete())
	SliceStep  func(v Value, s Value, e Value, step Value) (Value, error) // PURE by contract

	IsCallable func(v Value) bool                                // PURE by contract
	IsVariadic func(v Value) bool                                // PURE by contract
	Arity      func(v Value) int                                 // PURE by contract
	Call       func(vm VM, v Value, args []Value) (Value, error) // CALLABLE-DEPENDENT by contract

	Next  func(v Value) bool           // LOCALISED-STATE by contract (advances iterator cursor)
	Key   func(v Value) (Value, error) // LOCALISED-STATE by contract (reads iterator cursor)
	Value func(v Value) (Value, error) // LOCALISED-STATE by contract (reads iterator cursor)
	Elem  func(v Value) (Value, error) // LOCALISED-STATE by contract: the single-variable for-in binding — the container's ELEMENT. Defaults to the Value hook; a map iterator answers the KEY, because a map's element is its key

	AsBool     func(v Value) (bool, bool)             // PURE by contract
	AsByte     func(v Value) (byte, bool)             // PURE by contract
	AsRune     func(v Value) (rune, bool)             // PURE by contract
	AsInt      func(v Value) (int64, bool)            // PURE by contract
	AsFloat    func(v Value) (float64, bool)          // PURE by contract
	AsDecimal  func(v Value) (dec128.Dec128, bool)    // PURE by contract
	AsTime     func(v Value) (time.Time, bool)        // PURE by contract
	AsString   func(v Value) (string, bool)           // PURE by contract
	AsRunes    func(v Value) ([]rune, bool)           // PURE by contract
	AsBytes    func(v Value) ([]byte, bool)           // PURE by contract
	AsArray    func(v Value) ([]Value, bool)          // PURE by contract
	AsDict     func(v Value) (map[string]Value, bool) // PURE by contract
	AsIntRange func(v Value) (IntRange, bool)         // PURE by contract

	IsMethodPure func(name string) bool
}

ValueTypeDescr is a Kavun data type descriptor structure. See docs/purity.md for purity contract.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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