add basic support for tuples

This commit is contained in:
Neemek 2026-07-11 12:37:15 +02:00
parent 7bb277045c
commit e03d18c7db
Signed by: neemek
GPG key ID: 84FFE4D7D40AB25E
7 changed files with 339 additions and 18 deletions

View file

@ -6,6 +6,7 @@ import (
"math/big"
"reflect"
"strconv"
"strings"
)
type ValueType int
@ -17,6 +18,7 @@ const (
IntegerValueType
StringValueType
ListValueType
TupleValueType
ObjectValueType
FunctionValueType
BuiltinFunctionValueType
@ -39,6 +41,8 @@ func (v ValueType) String() string {
return "string"
case ListValueType:
return "list"
case TupleValueType:
return "tuple"
case FunctionValueType:
return "function"
case BuiltinFunctionValueType:
@ -278,7 +282,12 @@ func (v *FloatValue) Type() ValueType {
}
func (v *FloatValue) String() string {
return strconv.FormatFloat(v.Number, 'g', -1, FloatSize)
s := strconv.FormatFloat(v.Number, 'g', -1, FloatSize)
if strings.Index(s, ".") == -1 {
s += ".0"
}
return s
}
func (v *FloatValue) DebugString() string {
@ -597,6 +606,88 @@ func (v *ListValue) Clone() Value {
}
}
type TupleValue struct {
Items []Value
}
func (v *TupleValue) Type() ValueType {
return TupleValueType
}
func (v *TupleValue) String() string {
out := "("
for i, item := range v.Items {
if i != 0 {
out += ", "
}
out += item.DebugString()
}
if len(v.Items) <= 1 {
out += ","
}
out += ")"
return out
}
func (v *TupleValue) DebugString() string {
return v.String()
}
func (v *TupleValue) Clone() Value {
n := make([]Value, len(v.Items))
for i, item := range v.Items {
n[i] = item.Clone()
}
return &TupleValue{
n,
}
}
func (v *TupleValue) Equals(other Value) bool {
if other.Type() != TupleValueType {
return false
}
t := other.(*TupleValue).Items
for i, item := range v.Items {
if !item.Equals(t[i]) {
return false
}
}
return true
}
var TuplePrototype = map[string]*BuiltinFunctionValue{
"at": &BuiltinFunctionValue{
"at",
&FunctionSignature{
[]TypeSignature{&IntegerSignature{}},
&InnerSignature{},
},
func(vm *VM, this Value, args []Value) (Value, error) {
i := args[0].(*IntegerValue).Number.Int64()
if i < 0 || i >= int64(len(this.(*TupleValue).Items)) {
return nil, errors.New(fmt.Sprintf("index %x out of range", i))
}
return this.(*TupleValue).Items[i], nil
},
nil,
true,
},
}
func (v *TupleValue) Get(key string) (Value, error) {
if prop, ok := TuplePrototype[key]; ok {
return prop, nil
}
return nil, errors.New(fmt.Sprintf("tuple has no property \"%s\"", key))
}
type FunctionValue struct {
Name string
Params []FunctionParameter