Skip to content

Commit 67b9bed

Browse files
committed
wip: count bytes read
doing this as a wip commit, because we probably don't want to count ourselves, but rather send a PR to do the counting in the ExprLexer, because currently this approach feels rather hacky and also doesn't work in all cases..
1 parent 12d6674 commit 67b9bed

File tree

2 files changed

+75
-15
lines changed

2 files changed

+75
-15
lines changed

pkg/exprparser/interpreter.go

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ type Interpreter interface {
3333
}
3434

3535
type interperterImpl struct {
36-
env *EvaluationEnvironment
37-
config Config
36+
env *EvaluationEnvironment
37+
config Config
38+
bytesRead int
3839
}
3940

4041
func NewInterpeter(env *EvaluationEnvironment, config Config) Interpreter {
4142
return &interperterImpl{
42-
env: env,
43-
config: config,
43+
env: env,
44+
config: config,
45+
bytesRead: 0,
4446
}
4547
}
4648

@@ -51,29 +53,38 @@ func (impl *interperterImpl) Evaluate(input string) (interface{}, int, error) {
5153
return nil, 0, fmt.Errorf("Failed to parse: %s", err.Message)
5254
}
5355

56+
impl.bytesRead = exprNode.Token().Offset
57+
5458
result, err2 := impl.evaluateNode(exprNode)
5559

56-
// todo: this does not work and we need to calculate/track the
57-
// node end position
58-
fmt.Printf("read text: %s offset: %d line %d column %d\n",
59-
exprNode.Token().Value, exprNode.Token().Offset, exprNode.Token().Line, exprNode.Token().Column)
60+
fmt.Printf("initial bytes read: %d, kind: %+v\n", impl.bytesRead, exprNode)
6061

61-
return result, len(exprNode.Token().Value), err2
62+
return result, impl.bytesRead, err2
6263
}
6364

6465
func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interface{}, error) {
6566
switch node := exprNode.(type) {
6667
case *actionlint.VariableNode:
6768
return impl.evaluateVariable(node)
6869
case *actionlint.BoolNode:
70+
if node.Value {
71+
impl.bytesRead += 4
72+
} else {
73+
fmt.Printf("current bytes read: %d, offset: %d\n", impl.bytesRead, node.Token().Offset)
74+
impl.bytesRead += 5
75+
}
6976
return node.Value, nil
7077
case *actionlint.NullNode:
78+
impl.bytesRead += 4
7179
return nil, nil
7280
case *actionlint.IntNode:
81+
impl.bytesRead += len(fmt.Sprint(node.Value))
7382
return node.Value, nil
7483
case *actionlint.FloatNode:
84+
impl.bytesRead += len(fmt.Sprint(node.Value))
7585
return node.Value, nil
7686
case *actionlint.StringNode:
87+
impl.bytesRead += len(node.Value) + 2
7788
return node.Value, nil
7889
case *actionlint.IndexAccessNode:
7990
return impl.evaluateIndexAccess(node)
@@ -98,28 +109,40 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
98109
func (impl *interperterImpl) evaluateVariable(variableNode *actionlint.VariableNode) (interface{}, error) {
99110
switch strings.ToLower(variableNode.Name) {
100111
case "github":
112+
impl.bytesRead += len("github")
101113
return impl.env.Github, nil
102114
case "env":
115+
impl.bytesRead += len("env")
103116
return impl.env.Env, nil
104117
case "job":
118+
impl.bytesRead += len("job")
105119
return impl.env.Job, nil
106120
case "steps":
121+
impl.bytesRead += len("steps")
107122
return impl.env.Steps, nil
108123
case "runner":
124+
impl.bytesRead += len("runner")
109125
return impl.env.Runner, nil
110126
case "secrets":
127+
impl.bytesRead += len("secrets")
111128
return impl.env.Secrets, nil
112129
case "strategy":
130+
impl.bytesRead += len("strategy")
113131
return impl.env.Strategy, nil
114132
case "matrix":
133+
impl.bytesRead += len("matrix")
115134
return impl.env.Matrix, nil
116135
case "needs":
136+
impl.bytesRead += len("needs")
117137
return impl.env.Needs, nil
118138
case "inputs":
139+
impl.bytesRead += len("inputs")
119140
return impl.env.Inputs, nil
120141
case "infinity":
142+
impl.bytesRead += len("infinity")
121143
return math.Inf(1), nil
122144
case "nan":
145+
impl.bytesRead += len("nan")
123146
return math.NaN(), nil
124147
default:
125148
// TODO better error message
@@ -142,6 +165,8 @@ func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.Ind
142165

143166
rightValue := reflect.ValueOf(right)
144167

168+
impl.bytesRead += 2
169+
145170
switch rightValue.Kind() {
146171
// TODO: is property access the only valid kind where rightValue is a string?
147172
case reflect.String:
@@ -168,6 +193,8 @@ func (impl *interperterImpl) evaluateObjectDeref(objectDerefNode *actionlint.Obj
168193
return nil, err
169194
}
170195

196+
impl.bytesRead += 1
197+
171198
return impl.getPropertyValue(reflect.ValueOf(left), objectDerefNode.Property)
172199
}
173200

@@ -177,6 +204,8 @@ func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.Array
177204
return nil, err
178205
}
179206

207+
impl.bytesRead += 1
208+
180209
return reflect.ValueOf(left).Interface(), nil
181210
}
182211

@@ -259,6 +288,8 @@ func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (interfa
259288
return nil, err
260289
}
261290

291+
impl.bytesRead += 1
292+
262293
return !impl.isTruthy(reflect.ValueOf(operand)), nil
263294
}
264295

@@ -370,16 +401,22 @@ func (impl *interperterImpl) coerceToString(value reflect.Value) reflect.Value {
370401
func (impl *interperterImpl) compareString(left string, right string, kind actionlint.CompareOpNodeKind) (bool, error) {
371402
switch kind {
372403
case actionlint.CompareOpNodeKindLess:
404+
impl.bytesRead += 1
373405
return left < right, nil
374406
case actionlint.CompareOpNodeKindLessEq:
407+
impl.bytesRead += 2
375408
return left <= right, nil
376409
case actionlint.CompareOpNodeKindGreater:
410+
impl.bytesRead += 1
377411
return left > right, nil
378412
case actionlint.CompareOpNodeKindGreaterEq:
413+
impl.bytesRead += 2
379414
return left >= right, nil
380415
case actionlint.CompareOpNodeKindEq:
416+
impl.bytesRead += 2
381417
return left == right, nil
382418
case actionlint.CompareOpNodeKindNotEq:
419+
impl.bytesRead += 2
383420
return left != right, nil
384421
default:
385422
return false, fmt.Errorf("TODO: not implemented to compare '%+v'", kind)
@@ -389,16 +426,22 @@ func (impl *interperterImpl) compareString(left string, right string, kind actio
389426
func (impl *interperterImpl) compareNumber(left float64, right float64, kind actionlint.CompareOpNodeKind) (bool, error) {
390427
switch kind {
391428
case actionlint.CompareOpNodeKindLess:
429+
impl.bytesRead += 1
392430
return left < right, nil
393431
case actionlint.CompareOpNodeKindLessEq:
432+
impl.bytesRead += 2
394433
return left <= right, nil
395434
case actionlint.CompareOpNodeKindGreater:
435+
impl.bytesRead += 1
396436
return left > right, nil
397437
case actionlint.CompareOpNodeKindGreaterEq:
438+
impl.bytesRead += 2
398439
return left >= right, nil
399440
case actionlint.CompareOpNodeKindEq:
441+
impl.bytesRead += 2
400442
return left == right, nil
401443
case actionlint.CompareOpNodeKindNotEq:
444+
impl.bytesRead += 2
402445
return left != right, nil
403446
default:
404447
return false, fmt.Errorf("TODO: not implemented to compare '%+v'", kind)
@@ -466,6 +509,10 @@ func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.Logi
466509

467510
rightValue := reflect.ValueOf(right)
468511

512+
impl.bytesRead += 2
513+
514+
fmt.Printf("logical compare, left: %+v, right: %+v, offset: %d\n", left, right, compareNode.Token().Offset)
515+
469516
switch compareNode.Kind {
470517
case actionlint.LogicalOpNodeKindAnd:
471518
if impl.isTruthy(leftValue) {
@@ -499,28 +546,40 @@ func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallN
499546

500547
switch strings.ToLower(funcCallNode.Callee) {
501548
case "contains":
549+
impl.bytesRead += len("contains()")
502550
return impl.contains(args[0], args[1])
503551
case "startswith":
552+
impl.bytesRead += len("startswith()")
504553
return impl.startsWith(args[0], args[1])
505554
case "endswith":
555+
impl.bytesRead += len("endswith()")
506556
return impl.endsWith(args[0], args[1])
507557
case "format":
558+
impl.bytesRead += len("format()")
508559
return impl.format(args[0], args[1:]...)
509560
case "join":
561+
impl.bytesRead += len("join()")
510562
return impl.join(args[0], args[1])
511563
case "tojson":
564+
impl.bytesRead += len("tojson()")
512565
return impl.toJSON(args[0])
513566
case "fromjson":
567+
impl.bytesRead += len("fromjson()")
514568
return impl.fromJSON(args[0])
515569
case "hashfiles":
570+
impl.bytesRead += len("hashfiles()")
516571
return impl.hashFiles(args...)
517572
case "always":
573+
impl.bytesRead += len("always()")
518574
return impl.always()
519575
case "success":
576+
impl.bytesRead += len("success()")
520577
return impl.success()
521578
case "failure":
579+
impl.bytesRead += len("failure()")
522580
return impl.failure()
523581
case "cancelled":
582+
impl.bytesRead += len("cancelled()")
524583
return impl.cancelled()
525584
default:
526585
return nil, fmt.Errorf("TODO: '%s' not implemented", funcCallNode.Callee)

pkg/runner/expression.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,21 +177,22 @@ func (ee expressionEvaluator) InterpolateWithStringCheck(in string) (string, boo
177177
}
178178

179179
case expressionStartBracket2:
180+
fmt.Printf("index: %d, character: %c, skip: %d\n", i, character, skip)
180181
if skip == 0 {
181-
result, pos, err := ee.interpreter.Evaluate(in[i:])
182+
result, bytesRead, err := ee.interpreter.Evaluate(in[i:])
182183
if err != nil {
183184
fmt.Printf("Failed to eval: %s\n", err)
184185
return "", false
185186
}
186187

187188
output += ee.toString(result)
188189

189-
fmt.Printf("read %d in '%s'\n", pos, in[i:pos])
190+
fmt.Printf("input: \"%s\", input to evaluate: \"%s\", index: %d, bytesRead: %d, consumed: \"%s\"\n", in, in[i:], i, bytesRead, in[i:i+bytesRead])
190191

191-
if (pos - 1) == 0 {
192+
if (bytesRead - 1) == 0 {
192193
state = expressionEndBracket1
193194
} else {
194-
skip = i + pos - 1
195+
skip = i + bytesRead - 1
195196
}
196197
} else if i < skip {
197198
// ignore
@@ -204,14 +205,14 @@ func (ee expressionEvaluator) InterpolateWithStringCheck(in string) (string, boo
204205
// todo: handle error
205206
switch character {
206207
case '}':
207-
fmt.Printf("first closing bracket\n")
208+
fmt.Printf("first closing bracket %d\n", i)
208209
state = expressionEndBracket2
209210
}
210211
case expressionEndBracket2:
211212
// todo: handle error
212213
switch character {
213214
case '}':
214-
fmt.Printf("second closing bracket\n")
215+
fmt.Printf("second closing bracket %d\n", i)
215216
state = passThrough
216217
}
217218
}

0 commit comments

Comments
 (0)