eval: Move Bool to eval/types.

This commit is contained in:
Qi Xiao 2018-01-01 15:21:15 +00:00
parent 61bf413954
commit 3efc92b00c
23 changed files with 78 additions and 72 deletions

View File

@ -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])
}
}

View File

@ -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)))
})
}
}

View File

@ -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.

View File

@ -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),
})
}

View File

@ -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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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 {

View File

@ -56,7 +56,7 @@ func wrapNumCompare(cmp func(a, b float64) bool) BuiltinFnImpl {
break
}
}
ec.OutputChan() <- Bool(result)
ec.OutputChan() <- types.Bool(result)
}
}

View File

@ -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]+")

View File

@ -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{},
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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

19
eval/types/bool_test.go Normal file
View File

@ -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)
}

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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")
}