Skip to content

Commit 489c43e

Browse files
committed
refactor: range and union refactor
refactor range and union tokens to avoid double loop
1 parent 213d4c0 commit 489c43e

File tree

7 files changed

+1278
-1233
lines changed

7 files changed

+1278
-1233
lines changed

token/range.go

Lines changed: 111 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -54,142 +54,6 @@ func (token *rangeToken) Type() string {
5454

5555
func (token *rangeToken) Apply(root, current interface{}, next []Token) (interface{}, error) {
5656

57-
var fromInt, toInt, stepInt *int64
58-
59-
if token.from != nil {
60-
if script, ok := token.from.(Token); ok {
61-
result, err := script.Apply(root, current, nil)
62-
if err != nil {
63-
return nil, getInvalidTokenError(token.Type(), err)
64-
}
65-
66-
if result == nil {
67-
err := getUnexpectedExpressionResultNilError(reflect.Int)
68-
return nil, getInvalidTokenError(token.Type(), err)
69-
}
70-
71-
if intVal, ok := isInteger(result); ok {
72-
tmp := int64(intVal)
73-
fromInt = &tmp
74-
} else {
75-
kind := reflect.TypeOf(result).Kind()
76-
err := getUnexpectedExpressionResultError(kind, reflect.Int)
77-
return nil, getInvalidTokenError(token.Type(), err)
78-
}
79-
} else if intVal, ok := isInteger(token.from); ok {
80-
tmp := int64(intVal)
81-
fromInt = &tmp
82-
} else {
83-
kind := reflect.TypeOf(token.from).Kind()
84-
return nil, getInvalidTokenArgumentError(token.Type(), kind, reflect.Int)
85-
}
86-
}
87-
88-
if token.to != nil {
89-
if script, ok := token.to.(Token); ok {
90-
result, err := script.Apply(root, current, nil)
91-
if err != nil {
92-
return nil, getInvalidTokenError(token.Type(), err)
93-
}
94-
95-
if result == nil {
96-
err := getUnexpectedExpressionResultNilError(reflect.Int)
97-
return nil, getInvalidTokenError(token.Type(), err)
98-
}
99-
100-
if intVal, ok := isInteger(result); ok {
101-
tmp := int64(intVal)
102-
toInt = &tmp
103-
} else {
104-
kind := reflect.TypeOf(result).Kind()
105-
err := getUnexpectedExpressionResultError(kind, reflect.Int)
106-
return nil, getInvalidTokenError(token.Type(), err)
107-
}
108-
} else if intVal, ok := isInteger(token.to); ok {
109-
toInt = &intVal
110-
} else {
111-
kind := reflect.TypeOf(token.to).Kind()
112-
return nil, getInvalidTokenArgumentError(token.Type(), kind, reflect.Int)
113-
}
114-
}
115-
116-
if token.step != nil {
117-
if script, ok := token.step.(Token); ok {
118-
result, err := script.Apply(root, current, nil)
119-
if err != nil {
120-
return nil, getInvalidTokenError(token.Type(), err)
121-
}
122-
123-
if result == nil {
124-
err := getUnexpectedExpressionResultNilError(reflect.Int)
125-
return nil, getInvalidTokenError(token.Type(), err)
126-
}
127-
128-
if intVal, ok := isInteger(result); ok {
129-
tmp := int64(intVal)
130-
stepInt = &tmp
131-
} else {
132-
kind := reflect.TypeOf(result).Kind()
133-
err := getUnexpectedExpressionResultError(kind, reflect.Int)
134-
return nil, getInvalidTokenError(token.Type(), err)
135-
}
136-
} else if intVal, ok := isInteger(token.step); ok {
137-
stepInt = &intVal
138-
} else {
139-
kind := reflect.TypeOf(token.step).Kind()
140-
return nil, getInvalidTokenArgumentError(token.Type(), kind, reflect.Int)
141-
}
142-
}
143-
144-
rangeResult, err := token.getRange(current, fromInt, toInt, stepInt)
145-
if err != nil {
146-
if isInvalidTokenTargetError(err) {
147-
return nil, err
148-
}
149-
return nil, getInvalidTokenError(token.Type(), err)
150-
}
151-
152-
if substring, ok := rangeResult.(string); ok {
153-
if len(next) > 0 {
154-
return next[0].Apply(root, substring, next[1:])
155-
}
156-
return substring, nil
157-
}
158-
159-
elements := rangeResult.([]interface{})
160-
161-
if len(next) > 0 {
162-
nextToken := next[0]
163-
futureTokens := next[1:]
164-
165-
if indexToken, ok := nextToken.(*indexToken); ok {
166-
// if next is asking for specific index
167-
return indexToken.Apply(current, elements, futureTokens)
168-
}
169-
// any other token type
170-
results := make([]interface{}, 0)
171-
172-
for _, item := range elements {
173-
result, _ := nextToken.Apply(root, item, futureTokens)
174-
if result != nil {
175-
results = append(results, result)
176-
}
177-
}
178-
179-
return results, nil
180-
}
181-
182-
return elements, nil
183-
}
184-
185-
/**
186-
expected responses
187-
1. nil, error - if there is any errors
188-
2. []interface{}, nil - if an array, map, or slice is processed correctly
189-
3. string, nil - if a string is processed correctly
190-
**/
191-
func (token *rangeToken) getRange(obj interface{}, start, end, step *int64) (interface{}, error) {
192-
19357
allowedType := []reflect.Kind{
19458
reflect.Array,
19559
reflect.Slice,
@@ -201,7 +65,7 @@ func (token *rangeToken) getRange(obj interface{}, start, end, step *int64) (int
20165
allowedType = append(allowedType, reflect.String)
20266
}
20367

204-
objType, objVal := getTypeAndValue(obj)
68+
objType, objVal := getTypeAndValue(current)
20569
if objType == nil {
20670
return nil, getInvalidTokenTargetNilError(
20771
token.Type(),
@@ -251,12 +115,15 @@ func (token *rangeToken) getRange(obj interface{}, start, end, step *int64) (int
251115
}
252116

253117
var from int64 = 0
254-
if start != nil {
255-
from = *start
118+
if token.from != nil {
119+
var err error
120+
from, err = token.parseArgument(root, current, token.from)
121+
if err != nil {
122+
return nil, err
123+
}
256124
if from < 0 {
257125
from = length + from
258126
}
259-
260127
if from < 0 {
261128
from = 0
262129
}
@@ -266,8 +133,12 @@ func (token *rangeToken) getRange(obj interface{}, start, end, step *int64) (int
266133
}
267134

268135
to := length
269-
if end != nil {
270-
to = *end
136+
if token.to != nil {
137+
var err error
138+
to, err = token.parseArgument(root, current, token.to)
139+
if err != nil {
140+
return nil, err
141+
}
271142
if to < 0 {
272143
to = length + to
273144
}
@@ -280,52 +151,131 @@ func (token *rangeToken) getRange(obj interface{}, start, end, step *int64) (int
280151
}
281152
}
282153

283-
var stp int64 = 1
284-
if step != nil {
285-
stp = *step
286-
if stp == 0 {
154+
var step int64 = 1
155+
if token.step != nil {
156+
var err error
157+
step, err = token.parseArgument(root, current, token.step)
158+
if err != nil {
159+
return nil, err
160+
}
161+
if step == 0 {
287162
return nil, getInvalidTokenOutOfRangeError(token.Type())
288163
}
289164
}
290165

291-
array := make([]interface{}, 0)
166+
var nextToken Token
167+
var futureTokens []Token
168+
forEach := false
169+
170+
if len(next) > 0 {
171+
nextToken = next[0]
172+
futureTokens = next[1:]
173+
174+
if _, ok := nextToken.(*indexToken); !ok {
175+
forEach = true
176+
}
177+
}
178+
179+
elements := make([]interface{}, 0)
292180

293181
if mapKeys != nil {
294-
if stp < 0 {
295-
for i := to - 1; i >= from; i += stp {
182+
if step < 0 {
183+
for i := to - 1; i >= from; i += step {
296184
key := mapKeys[i]
297-
array = append(array, objVal.MapIndex(key).Interface())
185+
item, add := token.handleNext(root, objVal.MapIndex(key).Interface(), forEach, nextToken, futureTokens)
186+
if add {
187+
elements = append(elements, item)
188+
}
298189
}
299190
} else {
300-
for i := from; i < to; i += stp {
191+
for i := from; i < to; i += step {
301192
key := mapKeys[i]
302-
array = append(array, objVal.MapIndex(key).Interface())
193+
item, add := token.handleNext(root, objVal.MapIndex(key).Interface(), forEach, nextToken, futureTokens)
194+
if add {
195+
elements = append(elements, item)
196+
}
303197
}
304198
}
305199
} else if isString {
306200
substring := ""
307-
if stp < 0 {
308-
for i := to - 1; i >= from; i += stp {
201+
if step < 0 {
202+
for i := to - 1; i >= from; i += step {
309203
value := objVal.Index(int(i)).Uint()
310204
substring += fmt.Sprintf("%c", value)
311205
}
312206
} else {
313-
for i := from; i < to; i += stp {
207+
for i := from; i < to; i += step {
314208
value := objVal.Index(int(i)).Uint()
315209
substring += fmt.Sprintf("%c", value)
316210
}
317211
}
212+
213+
if len(next) > 0 {
214+
return next[0].Apply(root, substring, next[1:])
215+
}
216+
318217
return substring, nil
319218
} else {
320-
if stp < 0 {
321-
for i := to - 1; i >= from; i += stp {
322-
array = append(array, objVal.Index(int(i)).Interface())
219+
if step < 0 {
220+
for i := to - 1; i >= from; i += step {
221+
item, add := token.handleNext(root, objVal.Index(int(i)).Interface(), forEach, nextToken, futureTokens)
222+
if add {
223+
elements = append(elements, item)
224+
}
323225
}
324226
} else {
325-
for i := from; i < to; i += stp {
326-
array = append(array, objVal.Index(int(i)).Interface())
227+
for i := from; i < to; i += step {
228+
item, add := token.handleNext(root, objVal.Index(int(i)).Interface(), forEach, nextToken, futureTokens)
229+
if add {
230+
elements = append(elements, item)
231+
}
327232
}
328233
}
329234
}
330-
return array, nil
235+
236+
if !forEach && nextToken != nil {
237+
return nextToken.Apply(root, elements, futureTokens)
238+
}
239+
240+
return elements, nil
241+
}
242+
243+
func (token *rangeToken) handleNext(root, item interface{}, forEach bool, nextToken Token, futureTokens []Token) (interface{}, bool) {
244+
if !forEach {
245+
return item, true
246+
}
247+
val, err := nextToken.Apply(root, item, futureTokens)
248+
if err != nil {
249+
return nil, false
250+
}
251+
if val == nil {
252+
return nil, false
253+
}
254+
return val, true
255+
}
256+
257+
func (token *rangeToken) parseArgument(root, current interface{}, argument interface{}) (int64, error) {
258+
if script, ok := argument.(Token); ok {
259+
result, err := script.Apply(root, current, nil)
260+
if err != nil {
261+
return 0, getInvalidTokenError(token.Type(), err)
262+
}
263+
264+
if result == nil {
265+
err := getUnexpectedExpressionResultNilError(reflect.Int)
266+
return 0, getInvalidTokenError(token.Type(), err)
267+
}
268+
if intVal, ok := isInteger(result); ok {
269+
return intVal, nil
270+
}
271+
272+
kind := reflect.TypeOf(result).Kind()
273+
err = getUnexpectedExpressionResultError(kind, reflect.Int)
274+
return 0, getInvalidTokenError(token.Type(), err)
275+
} else if intVal, ok := isInteger(argument); ok {
276+
return intVal, nil
277+
}
278+
279+
kind := reflect.TypeOf(argument).Kind()
280+
return 0, getInvalidTokenArgumentError(token.Type(), kind, reflect.Int)
331281
}

0 commit comments

Comments
 (0)