add basic support for tuples
This commit is contained in:
parent
7bb277045c
commit
e03d18c7db
7 changed files with 339 additions and 18 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue