aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-21 22:47:41 +0900
committerOphestra <cat@gensokyo.uk>2026-05-21 22:47:41 +0900
commitcdd31dd27b79bf997b73325cf31e8bba66a81117 (patch)
tree829b2bc9a022d5a12dbb6bb572b329e5c101391f
parent0615899e5666aa3a4c8aa9fb69622be411f33dab (diff)
internal/rosa/azalea: integer arrays
This is useful for some helper functions. Performance is unaffected. Before: BenchmarkStage3-128 8308 1960687 ns/op 1023794 B/op 14755 allocs/op BenchmarkAll-128 3331 5518571 ns/op 2902320 B/op 37993 allocs/op After: BenchmarkStage3-128 8330 1946273 ns/op 1023046 B/op 14750 allocs/op BenchmarkAll-128 3296 5585805 ns/op 2901746 B/op 37991 allocs/op Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--internal/rosa/azalea/evaluate.go25
-rw-r--r--internal/rosa/azalea/evaluate_test.go16
2 files changed, 34 insertions, 7 deletions
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) {