diff --git a/internal/rosa/azalea/evaluate.go b/internal/rosa/azalea/evaluate.go index 3658ad6d..32c4f066 100644 --- a/internal/rosa/azalea/evaluate.go +++ b/internal/rosa/azalea/evaluate.go @@ -11,7 +11,7 @@ import ( // Value are types supported by the language. type Value interface { - bool | int64 | string | []string | [][2]string + bool | int64 | string | []string | []int64 | [][2]string } type ( @@ -85,6 +85,18 @@ func evaluate[T Value](d PF, s []Frame, expr any, rp *T) bool { return evaluateAny(d, s, expr, rp) } +// evaluateArray evaluates expr and returns its values as a slice. +func evaluateArray[T Value](d PF, s []Frame, expr Array) []T { + r := make([]T, 0, len(expr)) + for i := range expr { + var _r T + if evaluate(d, s, expr[i], &_r) { + r = append(r, _r) + } + } + return r +} + // TypeError is an unexpected type during evaluation. type TypeError struct { Concrete, Asserted reflect.Type @@ -232,14 +244,13 @@ func evaluateAny(d PF, s []Frame, expr, rp any) bool { return true case Array: - r := make([]string, 0, len(e)) - for i := range e { - var _r string - if evaluate(d, s, e[i], &_r) { - r = append(r, _r) + if len(e) > 0 && len(e[0]) == 1 { + if _, ok := e[0][0].(Int); ok { + store(rp, evaluateArray[int64](d, s, e)) + return true } } - store(rp, r) + store(rp, evaluateArray[string](d, s, e)) return true case []KV: diff --git a/internal/rosa/azalea/evaluate_test.go b/internal/rosa/azalea/evaluate_test.go index b4fa4802..7625db62 100644 --- a/internal/rosa/azalea/evaluate_test.go +++ b/internal/rosa/azalea/evaluate_test.go @@ -25,6 +25,17 @@ func makeStackCheck(check func(args FArgs) (any, error)) []Frame { }}} } +// checkArgs is like makeStackCheck, but the resulting function asserts that its +// args match the expected value. +func checkArgs(want FArgs) []Frame { + return makeStackCheck(func(args FArgs) (any, error) { + if !reflect.DeepEqual(args, want) { + return nil, fmt.Errorf("%#v, want %#v", args, want) + } + return "\xfd", nil + }) +} + func TestEvaluate(t *testing.T) { t.Parallel() @@ -164,6 +175,11 @@ func TestEvaluate(t *testing.T) { {"source handle", `package name { source = name; }`, nil, FArgs{ {K: unique.Make(Ident("source")), V: Ident("name")}, }, nil}, + + {"integer array", `f { v = [ 0 ]; _v = [ 0, 9 ]; }`, checkArgs(FArgs{ + {K: unique.Make(Ident("v")), V: []int64{0}}, + {K: unique.Make(Ident("_v")), V: []int64{0, 9}}, + }), "\xfd", nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) {