From 3efc92b00c9c717b9e0dbcdbc05223a73cf738c4 Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Mon, 1 Jan 2018 15:21:15 +0000 Subject: [PATCH] eval: Move Bool to eval/types. --- edit/candidate.go | 2 +- edit/matcher.go | 2 +- edit/prompt/prompt.go | 4 ++-- eval/bool_test.go | 15 -------------- eval/builtin_fn.go | 10 +++++----- eval/builtin_fn_cmd.go | 2 +- eval/builtin_fn_container.go | 4 ++-- eval/builtin_fn_fs.go | 2 +- eval/builtin_fn_num.go | 2 +- eval/builtin_fn_str.go | 6 +++--- eval/builtin_ns.go | 6 ++++-- eval/builtin_special.go | 4 ++-- eval/compile_op.go | 2 +- eval/compile_value.go | 2 +- eval/eval_test.go | 2 +- eval/re/re.go | 38 ++++++++++++++++++------------------ eval/testutils.go | 2 +- eval/{ => types}/bool.go | 10 +++++----- eval/types/bool_test.go | 19 ++++++++++++++++++ eval/validator.go | 2 +- eval/value.go | 2 +- eval/value_test.go | 6 +++--- eval/variable_test.go | 6 +++--- 23 files changed, 78 insertions(+), 72 deletions(-) delete mode 100644 eval/bool_test.go rename eval/{ => types}/bool.go (80%) create mode 100644 eval/types/bool_test.go diff --git a/edit/candidate.go b/edit/candidate.go index 1bf6124c..fb3be3a1 100644 --- a/edit/candidate.go +++ b/edit/candidate.go @@ -154,7 +154,7 @@ func filterRawCandidates(ev *eval.Evaler, matcher eval.Fn, var filtered []rawCandidate for i, value := range values { - if eval.ToBool(value) { + if types.ToBool(value) { filtered = append(filtered, collected[i]) } } diff --git a/edit/matcher.go b/edit/matcher.go index 064c3da8..daf64d20 100644 --- a/edit/matcher.go +++ b/edit/matcher.go @@ -84,7 +84,7 @@ func wrapMatcher(matcher func(s, p string) bool) eval.BuiltinFnImpl { if !ok { throw(errMatcherInputMustBeString) } - out <- eval.Bool(matcher(string(s), string(pattern))) + out <- types.Bool(matcher(string(s), string(pattern))) }) } } diff --git a/edit/prompt/prompt.go b/edit/prompt/prompt.go index af830a57..e658807f 100644 --- a/edit/prompt/prompt.go +++ b/edit/prompt/prompt.go @@ -85,12 +85,12 @@ func Rprompt(ed Editor) eval.Callable { // RpromptPersistentVariable returns a variable for $edit:rprompt-persistent. func RpromptPersistentVariable() eval.Variable { - return eval.NewPtrVariableWithValidator(eval.Bool(false), eval.ShouldBeBool) + return eval.NewPtrVariableWithValidator(types.Bool(false), eval.ShouldBeBool) } // RpromptPersistent extracts $edit:rprompt-persistent. func RpromptPersistent(ed Editor) bool { - return bool(ed.Variable("rprompt-persistent").Get().(eval.Bool).Bool()) + return bool(ed.Variable("rprompt-persistent").Get().(types.Bool).Bool()) } // MaxWaitVariable returns a variable for $edit:-prompts-max-wait. diff --git a/eval/bool_test.go b/eval/bool_test.go deleted file mode 100644 index 2493be08..00000000 --- a/eval/bool_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package eval - -import "testing" - -func TestBool(t *testing.T) { - runTests(t, []Test{ - NewTest("kind-of $true").WantOutStrings("bool"), - NewTest("eq $true $true").WantOutBools(true), - NewTest("eq $true true").WantOutBools(false), - NewTest("repr $true").WantBytesOutString("$true\n"), - NewTest("repr $false").WantBytesOutString("$false\n"), - NewTest("bool $true").WantOutBools(true), - NewTest("bool $false").WantOutBools(false), - }) -} diff --git a/eval/builtin_fn.go b/eval/builtin_fn.go index 04f7a883..97944b2b 100644 --- a/eval/builtin_fn.go +++ b/eval/builtin_fn.go @@ -111,7 +111,7 @@ func boolFn(ec *Frame, args []types.Value, opts map[string]types.Value) { ScanArgs(args, &v) TakeNoOpt(opts) - ec.OutputChan() <- Bool(ToBool(v)) + ec.OutputChan() <- types.Bool(types.ToBool(v)) } func not(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -119,7 +119,7 @@ func not(ec *Frame, args []types.Value, opts map[string]types.Value) { ScanArgs(args, &v) TakeNoOpt(opts) - ec.OutputChan() <- Bool(!ToBool(v)) + ec.OutputChan() <- types.Bool(!types.ToBool(v)) } func is(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -131,7 +131,7 @@ func is(ec *Frame, args []types.Value, opts map[string]types.Value) { break } } - ec.OutputChan() <- Bool(result) + ec.OutputChan() <- types.Bool(result) } func eq(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -143,7 +143,7 @@ func eq(ec *Frame, args []types.Value, opts map[string]types.Value) { break } } - ec.OutputChan() <- Bool(result) + ec.OutputChan() <- types.Bool(result) } func notEq(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -155,7 +155,7 @@ func notEq(ec *Frame, args []types.Value, opts map[string]types.Value) { break } } - ec.OutputChan() <- Bool(result) + ec.OutputChan() <- types.Bool(result) } func constantly(ec *Frame, args []types.Value, opts map[string]types.Value) { diff --git a/eval/builtin_fn_cmd.go b/eval/builtin_fn_cmd.go index dd46d779..ada2e30d 100644 --- a/eval/builtin_fn_cmd.go +++ b/eval/builtin_fn_cmd.go @@ -42,7 +42,7 @@ func hasExternal(ec *Frame, args []types.Value, opts map[string]types.Value) { TakeNoOpt(opts) _, err := exec.LookPath(string(cmd)) - ec.OutputChan() <- Bool(err == nil) + ec.OutputChan() <- types.Bool(err == nil) } func searchExternal(ec *Frame, args []types.Value, opts map[string]types.Value) { diff --git a/eval/builtin_fn_container.go b/eval/builtin_fn_container.go index 59e26aa9..d550b200 100644 --- a/eval/builtin_fn_container.go +++ b/eval/builtin_fn_container.go @@ -187,7 +187,7 @@ func hasValue(ec *Frame, args []types.Value, opts map[string]types.Value) { throw(fmt.Errorf("argument of type '%s' is not iterable", container.Kind())) } - ec.ports[1].Chan <- Bool(found) + ec.ports[1].Chan <- types.Bool(found) } func hasKey(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -211,7 +211,7 @@ func hasKey(ec *Frame, args []types.Value, opts map[string]types.Value) { throw(fmt.Errorf("couldn't get key or index of type '%s'", container.Kind())) } - ec.ports[1].Chan <- Bool(found) + ec.ports[1].Chan <- types.Bool(found) } func count(ec *Frame, args []types.Value, opts map[string]types.Value) { diff --git a/eval/builtin_fn_fs.go b/eval/builtin_fn_fs.go index d720ebae..e5e7df4a 100644 --- a/eval/builtin_fn_fs.go +++ b/eval/builtin_fn_fs.go @@ -123,7 +123,7 @@ func isDir(ec *Frame, args []types.Value, opts map[string]types.Value) { path := string(pathv) TakeNoOpt(opts) - ec.OutputChan() <- Bool(isDirInner(path)) + ec.OutputChan() <- types.Bool(isDirInner(path)) } func isDirInner(path string) bool { diff --git a/eval/builtin_fn_num.go b/eval/builtin_fn_num.go index f2fef7a3..28e9e907 100644 --- a/eval/builtin_fn_num.go +++ b/eval/builtin_fn_num.go @@ -56,7 +56,7 @@ func wrapNumCompare(cmp func(a, b float64) bool) BuiltinFnImpl { break } } - ec.OutputChan() <- Bool(result) + ec.OutputChan() <- types.Bool(result) } } diff --git a/eval/builtin_fn_str.go b/eval/builtin_fn_str.go index c5b82645..a3c3962d 100644 --- a/eval/builtin_fn_str.go +++ b/eval/builtin_fn_str.go @@ -64,7 +64,7 @@ func wrapStrCompare(cmp func(a, b string) bool) BuiltinFnImpl { break } } - ec.OutputChan() <- Bool(result) + ec.OutputChan() <- types.Bool(result) } } @@ -187,7 +187,7 @@ func hasPrefix(ec *Frame, args []types.Value, opts map[string]types.Value) { ScanArgs(args, &s, &prefix) TakeNoOpt(opts) - ec.OutputChan() <- Bool(strings.HasPrefix(string(s), string(prefix))) + ec.OutputChan() <- types.Bool(strings.HasPrefix(string(s), string(prefix))) } func hasSuffix(ec *Frame, args []types.Value, opts map[string]types.Value) { @@ -195,7 +195,7 @@ func hasSuffix(ec *Frame, args []types.Value, opts map[string]types.Value) { ScanArgs(args, &s, &suffix) TakeNoOpt(opts) - ec.OutputChan() <- Bool(strings.HasSuffix(string(s), string(suffix))) + ec.OutputChan() <- types.Bool(strings.HasSuffix(string(s), string(suffix))) } var eawkWordSep = regexp.MustCompile("[ \t]+") diff --git a/eval/builtin_ns.go b/eval/builtin_ns.go index 4e4babeb..c127b038 100644 --- a/eval/builtin_ns.go +++ b/eval/builtin_ns.go @@ -4,6 +4,8 @@ import ( "strconv" "strings" "syscall" + + "github.com/elves/elvish/eval/types" ) func makeBuiltinNs() Ns { @@ -11,8 +13,8 @@ func makeBuiltinNs() Ns { "_": BlackholeVariable{}, "pid": NewRoVariable(String(strconv.Itoa(syscall.Getpid()))), "ok": NewRoVariable(OK), - "true": NewRoVariable(Bool(true)), - "false": NewRoVariable(Bool(false)), + "true": NewRoVariable(types.Bool(true)), + "false": NewRoVariable(types.Bool(false)), "paths": &EnvList{envName: "PATH"}, "pwd": PwdVariable{}, } diff --git a/eval/builtin_special.go b/eval/builtin_special.go index 7d130415..f00626f3 100644 --- a/eval/builtin_special.go +++ b/eval/builtin_special.go @@ -260,11 +260,11 @@ func compileOr(cp *compiler, fn *parse.Form) OpFunc { func compileAndOr(cp *compiler, fn *parse.Form, init, stopAt bool) OpFunc { argOps := cp.compoundOps(fn.Args) return func(ec *Frame) { - var lastValue types.Value = Bool(init) + var lastValue types.Value = types.Bool(init) for _, op := range argOps { values := op.Exec(ec) for _, value := range values { - if ToBool(value) == stopAt { + if types.ToBool(value) == stopAt { ec.OutputChan() <- value return } diff --git a/eval/compile_op.go b/eval/compile_op.go index e5974958..9ba6a120 100644 --- a/eval/compile_op.go +++ b/eval/compile_op.go @@ -302,7 +302,7 @@ func (cp *compiler) form(n *parse.Form) OpFunc { func allTrue(vs []types.Value) bool { for _, v := range vs { - if !ToBool(v) { + if !types.ToBool(v) { return false } } diff --git a/eval/compile_value.go b/eval/compile_value.go index d1047d3b..809c110c 100644 --- a/eval/compile_value.go +++ b/eval/compile_value.go @@ -501,7 +501,7 @@ func (cp *compiler) mapPairs(pairs []*parse.MapPair) ValuesOpFunc { keysOps[i] = cp.compoundOp(pair.Key) if pair.Value == nil { p := pair.End() - valuesOps[i] = ValuesOp{literalValues(Bool(true)), p, p} + valuesOps[i] = ValuesOp{literalValues(types.Bool(true)), p, p} } else { valuesOps[i] = cp.compoundOp(pairs[i].Value) } diff --git a/eval/eval_test.go b/eval/eval_test.go index 2e7605e2..bc3f3cc9 100644 --- a/eval/eval_test.go +++ b/eval/eval_test.go @@ -67,7 +67,7 @@ func BenchmarkOutputCaptureBytes(b *testing.B) { func BenchmarkOutputCaptureMixed(b *testing.B) { bytesToWrite := []byte("test") op := Op{func(ec *Frame) { - ec.ports[1].Chan <- Bool(false) + ec.ports[1].Chan <- types.Bool(false) ec.ports[1].File.Write(bytesToWrite) }, 0, 0} benchmarkOutputCapture(op, b.N) diff --git a/eval/re/re.go b/eval/re/re.go index 13e3fa12..9766b3c0 100644 --- a/eval/re/re.go +++ b/eval/re/re.go @@ -30,14 +30,14 @@ func match(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { var ( argPattern eval.String argSource eval.String - optPOSIX eval.Bool + optPOSIX types.Bool ) eval.ScanArgs(args, &argPattern, &argSource) - eval.ScanOpts(opts, eval.OptToScan{"posix", &optPOSIX, eval.Bool(false)}) + eval.ScanOpts(opts, eval.OptToScan{"posix", &optPOSIX, types.Bool(false)}) - pattern := makePattern(argPattern, optPOSIX, eval.Bool(false)) + pattern := makePattern(argPattern, optPOSIX, types.Bool(false)) matched := pattern.MatchString(string(argSource)) - out <- eval.Bool(matched) + out <- types.Bool(matched) } func find(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { @@ -45,14 +45,14 @@ func find(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { var ( argPattern eval.String argSource eval.String - optPOSIX eval.Bool - optLongest eval.Bool + optPOSIX types.Bool + optLongest types.Bool optMax int ) eval.ScanArgs(args, &argPattern, &argSource) eval.ScanOpts(opts, - eval.OptToScan{"posix", &optPOSIX, eval.Bool(false)}, - eval.OptToScan{"longest", &optLongest, eval.Bool(false)}, + eval.OptToScan{"posix", &optPOSIX, types.Bool(false)}, + eval.OptToScan{"longest", &optLongest, types.Bool(false)}, eval.OptToScan{"max", &optMax, eval.String("-1")}) pattern := makePattern(argPattern, optPOSIX, optLongest) @@ -82,15 +82,15 @@ func replace(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { argPattern eval.String argRepl types.Value argSource eval.String - optPOSIX eval.Bool - optLongest eval.Bool - optLiteral eval.Bool + optPOSIX types.Bool + optLongest types.Bool + optLiteral types.Bool ) eval.ScanArgs(args, &argPattern, &argRepl, &argSource) eval.ScanOpts(opts, - eval.OptToScan{"posix", &optPOSIX, eval.Bool(false)}, - eval.OptToScan{"longest", &optLongest, eval.Bool(false)}, - eval.OptToScan{"literal", &optLiteral, eval.Bool(false)}) + eval.OptToScan{"posix", &optPOSIX, types.Bool(false)}, + eval.OptToScan{"longest", &optLongest, types.Bool(false)}, + eval.OptToScan{"literal", &optLiteral, types.Bool(false)}) pattern := makePattern(argPattern, optPOSIX, optLongest) @@ -134,14 +134,14 @@ func split(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { var ( argPattern eval.String argSource eval.String - optPOSIX eval.Bool - optLongest eval.Bool + optPOSIX types.Bool + optLongest types.Bool optMax int ) eval.ScanArgs(args, &argPattern, &argSource) eval.ScanOpts(opts, - eval.OptToScan{"posix", &optPOSIX, eval.Bool(false)}, - eval.OptToScan{"longest", &optLongest, eval.Bool(false)}, + eval.OptToScan{"posix", &optPOSIX, types.Bool(false)}, + eval.OptToScan{"longest", &optLongest, types.Bool(false)}, eval.OptToScan{"max", &optMax, eval.String("-1")}) pattern := makePattern(argPattern, optPOSIX, optLongest) @@ -152,7 +152,7 @@ func split(ec *eval.Frame, args []types.Value, opts map[string]types.Value) { } } -func makePattern(argPattern eval.String, optPOSIX, optLongest eval.Bool) *regexp.Regexp { +func makePattern(argPattern eval.String, optPOSIX, optLongest types.Bool) *regexp.Regexp { var ( pattern *regexp.Regexp err error diff --git a/eval/testutils.go b/eval/testutils.go index 92395b29..67dce5e5 100644 --- a/eval/testutils.go +++ b/eval/testutils.go @@ -51,7 +51,7 @@ func strs(ss ...string) []types.Value { func bools(bs ...bool) []types.Value { vs := make([]types.Value, len(bs)) for i, b := range bs { - vs[i] = Bool(b) + vs[i] = types.Bool(b) } return vs } diff --git a/eval/bool.go b/eval/types/bool.go similarity index 80% rename from eval/bool.go rename to eval/types/bool.go index 0b2d3bd0..029d0dc1 100644 --- a/eval/bool.go +++ b/eval/types/bool.go @@ -1,10 +1,10 @@ -package eval - -import "github.com/elves/elvish/eval/types" +package types // Bool represents truthness. type Bool bool +var _ Value = Bool(false) + func (Bool) Kind() string { return "bool" } @@ -33,8 +33,8 @@ func (b Bool) Bool() bool { // ToBool converts a Value to bool. When the Value type implements Bool(), it // is used. Otherwise it is considered true. -func ToBool(v types.Value) bool { - if b, ok := v.(types.Booler); ok { +func ToBool(v Value) bool { + if b, ok := v.(Booler); ok { return b.Bool() } return true diff --git a/eval/types/bool_test.go b/eval/types/bool_test.go new file mode 100644 index 00000000..bba8330d --- /dev/null +++ b/eval/types/bool_test.go @@ -0,0 +1,19 @@ +package types_test + +import ( + "testing" + + "github.com/elves/elvish/eval" +) + +func TestBool(t *testing.T) { + eval.RunTests(t, []eval.Test{ + eval.NewTest("kind-of $true").WantOutStrings("bool"), + eval.NewTest("eq $true $true").WantOutBools(true), + eval.NewTest("eq $true true").WantOutBools(false), + eval.NewTest("repr $true").WantBytesOutString("$true\n"), + eval.NewTest("repr $false").WantBytesOutString("$false\n"), + eval.NewTest("bool $true").WantOutBools(true), + eval.NewTest("bool $false").WantOutBools(false), + }, eval.NewEvaler) +} diff --git a/eval/validator.go b/eval/validator.go index 8005c76a..38cf866b 100644 --- a/eval/validator.go +++ b/eval/validator.go @@ -45,7 +45,7 @@ func ShouldBeNs(v types.Value) error { } func ShouldBeBool(v types.Value) error { - if _, ok := v.(Bool); !ok { + if _, ok := v.(types.Bool); !ok { return errShouldBeBool } return nil diff --git a/eval/value.go b/eval/value.go index 10041b25..d84de8ac 100644 --- a/eval/value.go +++ b/eval/value.go @@ -49,7 +49,7 @@ func FromJSONInterface(v interface{}) types.Value { } switch v.(type) { case bool: - return Bool(v.(bool)) + return types.Bool(v.(bool)) case float64, string: // TODO Use a numeric type for float64 return String(fmt.Sprint(v)) diff --git a/eval/value_test.go b/eval/value_test.go index 40295ab6..9d3e22e6 100644 --- a/eval/value_test.go +++ b/eval/value_test.go @@ -17,8 +17,8 @@ var reprTests = []struct { {String("a\nb"), `"a\nb"`}, {String("foo bar"), "'foo bar'"}, {String("a\x00b"), `"a\x00b"`}, - {Bool(true), "$true"}, - {Bool(false), "$false"}, + {types.Bool(true), "$true"}, + {types.Bool(false), "$false"}, {&Exception{nil, nil}, "$ok"}, {&Exception{errors.New("foo bar"), nil}, "?(fail 'foo bar')"}, {&Exception{ @@ -26,7 +26,7 @@ var reprTests = []struct { "?(multi-error $ok ?(fail lorem))"}, {&Exception{Return, nil}, "?(return)"}, {types.EmptyList, "[]"}, - {types.MakeList(String("bash"), Bool(false)), "[bash $false]"}, + {types.MakeList(String("bash"), types.Bool(false)), "[bash $false]"}, {types.MakeMap(map[types.Value]types.Value{}), "[&]"}, {types.MakeMap(map[types.Value]types.Value{&Exception{nil, nil}: String("elvish")}), "[&$ok=elvish]"}, // TODO: test maps of more elements diff --git a/eval/variable_test.go b/eval/variable_test.go index e9cde126..9bb5a07f 100644 --- a/eval/variable_test.go +++ b/eval/variable_test.go @@ -9,8 +9,8 @@ import ( ) func TestPtrVariable(t *testing.T) { - v := NewPtrVariable(Bool(true)) - if v.Get() != Bool(true) { + v := NewPtrVariable(types.Bool(true)) + if v.Get() != types.Bool(true) { t.Errorf("PtrVariable.Get doesn't return initial value") } v.Set(String("233")) @@ -18,7 +18,7 @@ func TestPtrVariable(t *testing.T) { t.Errorf("PtrVariable.Get doesn't return altered value") } - v = NewPtrVariableWithValidator(Bool(true), ShouldBeBool) + v = NewPtrVariableWithValidator(types.Bool(true), ShouldBeBool) if util.DoesntThrow(func() { v.Set(String("233")) }) { t.Errorf("PtrVariable.Set doesn't error when setting incompatible value") }