Skip to content

Commit

Permalink
added a has-key and has-value builtin to test the existence of an ele…
Browse files Browse the repository at this point in the history
…ment.

fixes #407 #398
  • Loading branch information
HeavyHorst committed Jul 12, 2017
1 parent 4b72779 commit 860897e
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions eval/builtin_fn.go
Expand Up @@ -112,6 +112,8 @@ func init() {
{"take", take},
{"range", rangeFn},
{"count", count},
{"has-key", hasKey},
{"has-value", hasValue},

// String
{"joins", joins},
Expand Down Expand Up @@ -780,6 +782,57 @@ func rangeFn(ec *EvalCtx, args []Value, opts map[string]Value) {
}
}

func hasValue(ec *EvalCtx, args []Value, opts map[string]Value) {
TakeNoOpt(opts)

var found bool
if len(args) == 2 {
v := args[0]
if iterator, ok := v.(Iterable); ok {
iterator.Iterate(func(v Value) bool {
if v == args[1] {
found = true
return false
}
return true
})
} else {
throw(fmt.Errorf("argument of type '%s' is not iterable", v.Kind()))
}
} else {
throw(errors.New("want 2 arguments"))
}

ec.ports[1].Chan <- Bool(found)
}

func hasKey(ec *EvalCtx, args []Value, opts map[string]Value) {
TakeNoOpt(opts)

var found bool
if len(args) == 2 {
v := args[0]
switch val := v.(type) {
case HasKeyer:
if val.HasKey(args[1]) {
found = true
}
case Lener:
if err := util.PCall(func() {
ParseAndFixListIndex(ToString(args[1]), val.Len())
}); err == nil {
found = true
}
default:
throw(fmt.Errorf("couldn't get key or index of type '%s'", v.Kind()))
}
} else {
throw(errors.New("want 2 arguments"))
}

ec.ports[1].Chan <- Bool(found)
}

func count(ec *EvalCtx, args []Value, opts map[string]Value) {
TakeNoOpt(opts)

Expand Down

0 comments on commit 860897e

Please sign in to comment.