diff --git a/evaldo/builtins.go b/evaldo/builtins.go index 1711b336..5fa3b2ad 100644 --- a/evaldo/builtins.go +++ b/evaldo/builtins.go @@ -4709,6 +4709,7 @@ var builtins = map[string]*env.Builtin{ Pure: true, Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s1 := arg0.(type) { + //contains with string case env.String: switch s2 := arg1.(type) { case env.String: @@ -4720,9 +4721,39 @@ var builtins = map[string]*env.Builtin{ default: return MakeArgError(ps, 2, []env.Type{env.StringType}, "contains") } - // TODO-FIX1 .. add for block and list (use util.containsVal for block) + //contains block + case env.Block: + switch value := arg1.(type) { + case env.Integer: + if util.ContainsVal(ps, s1.Series.S, value) { + return *env.NewInteger(1) + } else { + return *env.NewInteger(0) + } + default: + return MakeArgError(ps, 2, []env.Type{env.IntegerType}, "contains") + } + // contains list + case env.List: + switch value := arg1.(type) { + case env.Integer: + isListContains := false + for i := 0; i < len(s1.Data); i++ { + if s1.Data[i] == value.Value { + isListContains = true + break + } + } + if isListContains { + return *env.NewInteger(1) + } else { + return *env.NewInteger(0) + } + default: + return MakeArgError(ps, 2, []env.Type{env.IntegerType}, "contains") + } default: - return MakeArgError(ps, 1, []env.Type{env.StringType}, "contains") + return MakeArgError(ps, 1, []env.Type{env.StringType, env.BlockType, env.ListType}, "contains") } }, }, diff --git a/tests/builtins.rye b/tests/builtins.rye index babbce70..2328c2c0 100644 --- a/tests/builtins.rye +++ b/tests/builtins.rye @@ -507,6 +507,14 @@ section "Working with blocks and lists" equal { { 3 2 3 5 3 2 } .list .unique .length? } 3 ; result order is not deterministic list { 3 2 5 } } + group "contains" + mold\nowrap ?contains + { { block string list } } + { + equal { contains "abbaca" "b" } 1 + equal { contains { 1 2 3 } 2 } 1 + equal { contains list { 1 2 3 } 2 } 1 + } }