-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathiterator.go
179 lines (146 loc) · 3.38 KB
/
iterator.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
// Copyright (c) 2020-2023 Ozan Hacıbekiroğlu.
// Use of this source code is governed by a MIT License
// that can be found in the LICENSE file.
package ugo
import (
"sync"
"unicode/utf8"
)
// Iterator wraps the methods required to iterate Objects in VM.
type Iterator interface {
// Next returns true if there are more elements to iterate.
Next() bool
// Key returns the key or index value of the current element.
Key() Object
// Value returns the value of the current element.
Value() Object
}
// iteratorObject is used in VM to make an iterable Object.
type iteratorObject struct {
ObjectImpl
Iterator
}
var _ Object = (*iteratorObject)(nil)
// ArrayIterator represents an iterator for the array.
type ArrayIterator struct {
V Array
i int
}
var _ Iterator = (*ArrayIterator)(nil)
// Next implements Iterator interface.
func (it *ArrayIterator) Next() bool {
it.i++
return it.i-1 < len(it.V)
}
// Key implements Iterator interface.
func (it *ArrayIterator) Key() Object {
return Int(it.i - 1)
}
// Value implements Iterator interface.
func (it *ArrayIterator) Value() Object {
i := it.i - 1
if i > -1 && i < len(it.V) {
return it.V[i]
}
return Undefined
}
// BytesIterator represents an iterator for the bytes.
type BytesIterator struct {
V Bytes
i int
}
var _ Iterator = (*BytesIterator)(nil)
// Next implements Iterator interface.
func (it *BytesIterator) Next() bool {
it.i++
return it.i-1 < len(it.V)
}
// Key implements Iterator interface.
func (it *BytesIterator) Key() Object {
return Int(it.i - 1)
}
// Value implements Iterator interface.
func (it *BytesIterator) Value() Object {
i := it.i - 1
if i > -1 && i < len(it.V) {
return Int(it.V[i])
}
return Undefined
}
// MapIterator represents an iterator for the map.
type MapIterator struct {
V Map
keys []string
i int
}
var _ Iterator = (*MapIterator)(nil)
// Next implements Iterator interface.
func (it *MapIterator) Next() bool {
it.i++
return it.i-1 < len(it.keys)
}
// Key implements Iterator interface.
func (it *MapIterator) Key() Object {
return String(it.keys[it.i-1])
}
// Value implements Iterator interface.
func (it *MapIterator) Value() Object {
v, ok := it.V[it.keys[it.i-1]]
if !ok {
return Undefined
}
return v
}
// SyncIterator represents an iterator for the SyncMap.
type SyncIterator struct {
mu sync.Mutex
Iterator
}
// Next implements Iterator interface.
func (it *SyncIterator) Next() bool {
it.mu.Lock()
defer it.mu.Unlock()
return it.Iterator.Next()
}
// Key implements Iterator interface.
func (it *SyncIterator) Key() Object {
it.mu.Lock()
defer it.mu.Unlock()
return it.Iterator.Key()
}
// Value implements Iterator interface.
func (it *SyncIterator) Value() Object {
it.mu.Lock()
defer it.mu.Unlock()
return it.Iterator.Value()
}
// StringIterator represents an iterator for the string.
type StringIterator struct {
V String
i int
k int
r rune
}
var _ Iterator = (*StringIterator)(nil)
// Next implements Iterator interface.
func (it *StringIterator) Next() bool {
if it.i > len(it.V)-1 {
return false
}
r, s := utf8.DecodeRuneInString(string(it.V)[it.i:])
if r == utf8.RuneError || s == 0 {
return false
}
it.k = it.i
it.r = r
it.i += s
return true
}
// Key implements Iterator interface.
func (it *StringIterator) Key() Object {
return Int(it.k)
}
// Value implements Iterator interface.
func (it *StringIterator) Value() Object {
return Char(it.r)
}