@@ -33,14 +33,16 @@ type Interpreter interface {
33
33
}
34
34
35
35
type interperterImpl struct {
36
- env * EvaluationEnvironment
37
- config Config
36
+ env * EvaluationEnvironment
37
+ config Config
38
+ bytesRead int
38
39
}
39
40
40
41
func NewInterpeter (env * EvaluationEnvironment , config Config ) Interpreter {
41
42
return & interperterImpl {
42
- env : env ,
43
- config : config ,
43
+ env : env ,
44
+ config : config ,
45
+ bytesRead : 0 ,
44
46
}
45
47
}
46
48
@@ -51,29 +53,38 @@ func (impl *interperterImpl) Evaluate(input string) (interface{}, int, error) {
51
53
return nil , 0 , fmt .Errorf ("Failed to parse: %s" , err .Message )
52
54
}
53
55
56
+ impl .bytesRead = exprNode .Token ().Offset
57
+
54
58
result , err2 := impl .evaluateNode (exprNode )
55
59
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 )
60
61
61
- return result , len ( exprNode . Token (). Value ) , err2
62
+ return result , impl . bytesRead , err2
62
63
}
63
64
64
65
func (impl * interperterImpl ) evaluateNode (exprNode actionlint.ExprNode ) (interface {}, error ) {
65
66
switch node := exprNode .(type ) {
66
67
case * actionlint.VariableNode :
67
68
return impl .evaluateVariable (node )
68
69
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
+ }
69
76
return node .Value , nil
70
77
case * actionlint.NullNode :
78
+ impl .bytesRead += 4
71
79
return nil , nil
72
80
case * actionlint.IntNode :
81
+ impl .bytesRead += len (fmt .Sprint (node .Value ))
73
82
return node .Value , nil
74
83
case * actionlint.FloatNode :
84
+ impl .bytesRead += len (fmt .Sprint (node .Value ))
75
85
return node .Value , nil
76
86
case * actionlint.StringNode :
87
+ impl .bytesRead += len (node .Value ) + 2
77
88
return node .Value , nil
78
89
case * actionlint.IndexAccessNode :
79
90
return impl .evaluateIndexAccess (node )
@@ -98,28 +109,40 @@ func (impl *interperterImpl) evaluateNode(exprNode actionlint.ExprNode) (interfa
98
109
func (impl * interperterImpl ) evaluateVariable (variableNode * actionlint.VariableNode ) (interface {}, error ) {
99
110
switch strings .ToLower (variableNode .Name ) {
100
111
case "github" :
112
+ impl .bytesRead += len ("github" )
101
113
return impl .env .Github , nil
102
114
case "env" :
115
+ impl .bytesRead += len ("env" )
103
116
return impl .env .Env , nil
104
117
case "job" :
118
+ impl .bytesRead += len ("job" )
105
119
return impl .env .Job , nil
106
120
case "steps" :
121
+ impl .bytesRead += len ("steps" )
107
122
return impl .env .Steps , nil
108
123
case "runner" :
124
+ impl .bytesRead += len ("runner" )
109
125
return impl .env .Runner , nil
110
126
case "secrets" :
127
+ impl .bytesRead += len ("secrets" )
111
128
return impl .env .Secrets , nil
112
129
case "strategy" :
130
+ impl .bytesRead += len ("strategy" )
113
131
return impl .env .Strategy , nil
114
132
case "matrix" :
133
+ impl .bytesRead += len ("matrix" )
115
134
return impl .env .Matrix , nil
116
135
case "needs" :
136
+ impl .bytesRead += len ("needs" )
117
137
return impl .env .Needs , nil
118
138
case "inputs" :
139
+ impl .bytesRead += len ("inputs" )
119
140
return impl .env .Inputs , nil
120
141
case "infinity" :
142
+ impl .bytesRead += len ("infinity" )
121
143
return math .Inf (1 ), nil
122
144
case "nan" :
145
+ impl .bytesRead += len ("nan" )
123
146
return math .NaN (), nil
124
147
default :
125
148
// TODO better error message
@@ -142,6 +165,8 @@ func (impl *interperterImpl) evaluateIndexAccess(indexAccessNode *actionlint.Ind
142
165
143
166
rightValue := reflect .ValueOf (right )
144
167
168
+ impl .bytesRead += 2
169
+
145
170
switch rightValue .Kind () {
146
171
// TODO: is property access the only valid kind where rightValue is a string?
147
172
case reflect .String :
@@ -168,6 +193,8 @@ func (impl *interperterImpl) evaluateObjectDeref(objectDerefNode *actionlint.Obj
168
193
return nil , err
169
194
}
170
195
196
+ impl .bytesRead += 1
197
+
171
198
return impl .getPropertyValue (reflect .ValueOf (left ), objectDerefNode .Property )
172
199
}
173
200
@@ -177,6 +204,8 @@ func (impl *interperterImpl) evaluateArrayDeref(arrayDerefNode *actionlint.Array
177
204
return nil , err
178
205
}
179
206
207
+ impl .bytesRead += 1
208
+
180
209
return reflect .ValueOf (left ).Interface (), nil
181
210
}
182
211
@@ -259,6 +288,8 @@ func (impl *interperterImpl) evaluateNot(notNode *actionlint.NotOpNode) (interfa
259
288
return nil , err
260
289
}
261
290
291
+ impl .bytesRead += 1
292
+
262
293
return ! impl .isTruthy (reflect .ValueOf (operand )), nil
263
294
}
264
295
@@ -370,16 +401,22 @@ func (impl *interperterImpl) coerceToString(value reflect.Value) reflect.Value {
370
401
func (impl * interperterImpl ) compareString (left string , right string , kind actionlint.CompareOpNodeKind ) (bool , error ) {
371
402
switch kind {
372
403
case actionlint .CompareOpNodeKindLess :
404
+ impl .bytesRead += 1
373
405
return left < right , nil
374
406
case actionlint .CompareOpNodeKindLessEq :
407
+ impl .bytesRead += 2
375
408
return left <= right , nil
376
409
case actionlint .CompareOpNodeKindGreater :
410
+ impl .bytesRead += 1
377
411
return left > right , nil
378
412
case actionlint .CompareOpNodeKindGreaterEq :
413
+ impl .bytesRead += 2
379
414
return left >= right , nil
380
415
case actionlint .CompareOpNodeKindEq :
416
+ impl .bytesRead += 2
381
417
return left == right , nil
382
418
case actionlint .CompareOpNodeKindNotEq :
419
+ impl .bytesRead += 2
383
420
return left != right , nil
384
421
default :
385
422
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
389
426
func (impl * interperterImpl ) compareNumber (left float64 , right float64 , kind actionlint.CompareOpNodeKind ) (bool , error ) {
390
427
switch kind {
391
428
case actionlint .CompareOpNodeKindLess :
429
+ impl .bytesRead += 1
392
430
return left < right , nil
393
431
case actionlint .CompareOpNodeKindLessEq :
432
+ impl .bytesRead += 2
394
433
return left <= right , nil
395
434
case actionlint .CompareOpNodeKindGreater :
435
+ impl .bytesRead += 1
396
436
return left > right , nil
397
437
case actionlint .CompareOpNodeKindGreaterEq :
438
+ impl .bytesRead += 2
398
439
return left >= right , nil
399
440
case actionlint .CompareOpNodeKindEq :
441
+ impl .bytesRead += 2
400
442
return left == right , nil
401
443
case actionlint .CompareOpNodeKindNotEq :
444
+ impl .bytesRead += 2
402
445
return left != right , nil
403
446
default :
404
447
return false , fmt .Errorf ("TODO: not implemented to compare '%+v'" , kind )
@@ -466,6 +509,10 @@ func (impl *interperterImpl) evaluateLogicalCompare(compareNode *actionlint.Logi
466
509
467
510
rightValue := reflect .ValueOf (right )
468
511
512
+ impl .bytesRead += 2
513
+
514
+ fmt .Printf ("logical compare, left: %+v, right: %+v, offset: %d\n " , left , right , compareNode .Token ().Offset )
515
+
469
516
switch compareNode .Kind {
470
517
case actionlint .LogicalOpNodeKindAnd :
471
518
if impl .isTruthy (leftValue ) {
@@ -499,28 +546,40 @@ func (impl *interperterImpl) evaluateFuncCall(funcCallNode *actionlint.FuncCallN
499
546
500
547
switch strings .ToLower (funcCallNode .Callee ) {
501
548
case "contains" :
549
+ impl .bytesRead += len ("contains()" )
502
550
return impl .contains (args [0 ], args [1 ])
503
551
case "startswith" :
552
+ impl .bytesRead += len ("startswith()" )
504
553
return impl .startsWith (args [0 ], args [1 ])
505
554
case "endswith" :
555
+ impl .bytesRead += len ("endswith()" )
506
556
return impl .endsWith (args [0 ], args [1 ])
507
557
case "format" :
558
+ impl .bytesRead += len ("format()" )
508
559
return impl .format (args [0 ], args [1 :]... )
509
560
case "join" :
561
+ impl .bytesRead += len ("join()" )
510
562
return impl .join (args [0 ], args [1 ])
511
563
case "tojson" :
564
+ impl .bytesRead += len ("tojson()" )
512
565
return impl .toJSON (args [0 ])
513
566
case "fromjson" :
567
+ impl .bytesRead += len ("fromjson()" )
514
568
return impl .fromJSON (args [0 ])
515
569
case "hashfiles" :
570
+ impl .bytesRead += len ("hashfiles()" )
516
571
return impl .hashFiles (args ... )
517
572
case "always" :
573
+ impl .bytesRead += len ("always()" )
518
574
return impl .always ()
519
575
case "success" :
576
+ impl .bytesRead += len ("success()" )
520
577
return impl .success ()
521
578
case "failure" :
579
+ impl .bytesRead += len ("failure()" )
522
580
return impl .failure ()
523
581
case "cancelled" :
582
+ impl .bytesRead += len ("cancelled()" )
524
583
return impl .cancelled ()
525
584
default :
526
585
return nil , fmt .Errorf ("TODO: '%s' not implemented" , funcCallNode .Callee )
0 commit comments