From c648a7030f2b2ef172ef7d30bb9009082b685ea8 Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Wed, 28 Jun 2017 09:50:04 -0400 Subject: [PATCH] Implement ar.first, ar.list --- expressions/evaluator_test.go | 8 ++++---- expressions/interpreter.go | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/expressions/evaluator_test.go b/expressions/evaluator_test.go index 04fd3c5..df4b486 100644 --- a/expressions/evaluator_test.go +++ b/expressions/evaluator_test.go @@ -29,10 +29,10 @@ var evaluatorTests = []struct { {"ar[100]", nil}, {"obj[1]", nil}, {"obj.c[0]", "r"}, - // {`fruits.first`, "apples"}, - // {`fruits.last`, "plums"}, - // {`empty_list.first`, ""}, - // {`empty_list.last`, ""}, + {`fruits.first`, "apples"}, + {`fruits.last`, "plums"}, + {`empty_list.first`, nil}, + {`empty_list.last`, nil}, // Operators {"1 == 1", true}, diff --git a/expressions/interpreter.go b/expressions/interpreter.go index f566431..90a6828 100644 --- a/expressions/interpreter.go +++ b/expressions/interpreter.go @@ -8,6 +8,16 @@ func makeObjectPropertyEvaluator(obj func(Context) interface{}, attr string) fun return func(ctx Context) interface{} { ref := reflect.ValueOf(obj(ctx)) switch ref.Kind() { + case reflect.Array, reflect.Slice: + if ref.Len() == 0 { + return nil + } + switch attr { + case "first": + return ref.Index(0).Interface() + case "last": + return ref.Index(ref.Len() - 1).Interface() + } case reflect.Map: value := ref.MapIndex(reflect.ValueOf(attr)) if value.Kind() != reflect.Invalid { @@ -18,15 +28,15 @@ func makeObjectPropertyEvaluator(obj func(Context) interface{}, attr string) fun } } -func makeIndexEvaluator(obj, indexfn func(Context) interface{}) func(Context) interface{} { +func makeIndexEvaluator(obj, index func(Context) interface{}) func(Context) interface{} { return func(ctx Context) interface{} { ref := reflect.ValueOf(obj(ctx)) - index := reflect.ValueOf(indexfn(ctx)) + i := reflect.ValueOf(index(ctx)) switch ref.Kind() { case reflect.Array, reflect.Slice: - switch index.Kind() { + switch i.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n := int(index.Int()) + n := int(i.Int()) if n < 0 { n = ref.Len() + n }