/
vector.go
136 lines (114 loc) · 2.29 KB
/
vector.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package data
import (
"bytes"
"math/rand"
"slices"
"github.com/kode4food/ale/internal/types"
)
// Vector is a fixed-length array of Values
type Vector []Value
// EmptyVector represents an empty Vector
var (
EmptyVector = Vector{}
vectorHash = rand.Uint64()
// compile-time checks for interface implementation
_ Appender = EmptyVector
_ Caller = EmptyVector
_ Hashed = EmptyVector
_ Prepender = EmptyVector
_ RandomAccess = EmptyVector
_ Reverser = EmptyVector
_ Typed = EmptyVector
)
// NewVector creates a new Vector instance
func NewVector(v ...Value) Vector {
return v
}
func (v Vector) Count() Integer {
return Integer(len(v))
}
func (v Vector) ElementAt(index Integer) (Value, bool) {
if index >= 0 && index < Integer(len(v)) {
return v[index], true
}
return Null, false
}
func (v Vector) IsEmpty() bool {
return len(v) == 0
}
func (v Vector) Car() Value {
if len(v) > 0 {
return v[0]
}
return Null
}
func (v Vector) Cdr() Value {
if len(v) > 1 {
return v[1:]
}
return EmptyVector
}
func (v Vector) Split() (Value, Sequence, bool) {
switch len(v) {
case 0:
return Null, EmptyVector, false
case 1:
return v[0], EmptyVector, true
default:
return v[0], v[1:], true
}
}
func (v Vector) Prepend(e Value) Sequence {
res := make(Vector, 1, len(v)+1)
res[0] = e
return append(res, v...)
}
func (v Vector) Append(e Value) Sequence {
return append(v, e)
}
func (v Vector) Reverse() Sequence {
vl := len(v)
if vl <= 1 {
return v
}
res := make(Vector, vl)
for i, j := 0, vl-1; j >= 0; i, j = i+1, j-1 {
res[i] = v[j]
}
return res
}
func (v Vector) Call(args ...Value) Value {
return indexedCall(v, args)
}
func (v Vector) CheckArity(argCount int) error {
return checkRangedArity(1, 2, argCount)
}
func (v Vector) Equal(other Value) bool {
if o, ok := other.(Vector); ok {
return slices.EqualFunc(v, o, Equal)
}
return false
}
func (v Vector) String() string {
var b bytes.Buffer
b.WriteString("[")
for i, e := range v {
if i > 0 {
b.WriteString(" ")
}
b.WriteString(ToQuotedString(e))
}
b.WriteString("]")
return b.String()
}
func (Vector) Type() types.Type {
return types.BasicVector
}
func (v Vector) HashCode() uint64 {
res := vectorHash
for i, e := range v {
res ^= HashCode(e)
res ^= HashInt(i)
}
return res
}