pkg/eval: Return bool instead error from (*Evaler)'s PurelyEval* methods.

This commit is contained in:
Qi Xiao 2021-01-09 16:05:04 +00:00
parent 9991b08fe0
commit 02d9252b5d
6 changed files with 27 additions and 31 deletions

View File

@ -59,8 +59,8 @@ type PureEvaler interface {
EachNs(func(string))
EachVariableInNs(string, func(string))
PurelyEvalPrimary(pn *parse.Primary) interface{}
PurelyEvalCompound(*parse.Compound) (string, error)
PurelyEvalPartialCompound(*parse.Compound, int) (string, error)
PurelyEvalCompound(*parse.Compound) (string, bool)
PurelyEvalPartialCompound(*parse.Compound, int) (string, bool)
}
// CodeBuffer is the same the type in github.com/elves/elvish/pkg/el/codearea,

View File

@ -40,11 +40,11 @@ func (ev testEvaler) EachVariableInNs(ns string, f func(string)) {
feed(f, ev.variables[ns])
}
func (ev testEvaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, error) {
func (ev testEvaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, bool) {
return (*eval.Evaler)(nil).PurelyEvalPartialCompound(cn, upto)
}
func (ev testEvaler) PurelyEvalCompound(cn *parse.Compound) (string, error) {
func (ev testEvaler) PurelyEvalCompound(cn *parse.Compound) (string, bool) {
return (*eval.Evaler)(nil).PurelyEvalCompound(cn)
}

View File

@ -33,8 +33,8 @@ func primaryInSimpleCompound(pn *parse.Primary, ev PureEvaler) (*parse.Compound,
if !ok {
return nil, ""
}
head, err := ev.PurelyEvalPartialCompound(compound, indexing.To)
if err != nil {
head, ok := ev.PurelyEvalPartialCompound(compound, indexing.To)
if !ok {
return nil, ""
}
return compound, head
@ -49,7 +49,7 @@ func purelyEvalForm(form *parse.Form, seed string, upto int, ev PureEvaler) []st
if compound.Range().From >= upto {
break
}
if arg, err := ev.PurelyEvalCompound(compound); err == nil {
if arg, ok := ev.PurelyEvalCompound(compound); ok {
// TODO(xiaq): Arguments that are not simple compounds are simply ignored.
words = append(words, arg)
}

View File

@ -524,10 +524,10 @@ func (pe pureEvaler) PurelyEvalPrimary(pn *parse.Primary) interface{} {
return pe.ev.PurelyEvalPrimary(pn)
}
func (pe pureEvaler) PurelyEvalCompound(cn *parse.Compound) (string, error) {
func (pe pureEvaler) PurelyEvalCompound(cn *parse.Compound) (string, bool) {
return pe.ev.PurelyEvalCompound(cn)
}
func (pe pureEvaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, error) {
func (pe pureEvaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, bool) {
return pe.ev.PurelyEvalPartialCompound(cn, upto)
}

View File

@ -1,25 +1,22 @@
package eval
import (
"errors"
"strings"
"github.com/elves/elvish/pkg/fsutil"
"github.com/elves/elvish/pkg/parse"
)
var ErrImpure = errors.New("expression is impure")
func (ev *Evaler) PurelyEvalCompound(cn *parse.Compound) (string, error) {
func (ev *Evaler) PurelyEvalCompound(cn *parse.Compound) (string, bool) {
return ev.PurelyEvalPartialCompound(cn, -1)
}
func (ev *Evaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, error) {
func (ev *Evaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (string, bool) {
tilde := false
head := ""
for _, in := range cn.Indexings {
if len(in.Indicies) > 0 {
return "", ErrImpure
return "", false
}
if upto >= 0 && in.To > upto {
break
@ -31,16 +28,16 @@ func (ev *Evaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (strin
head += in.Head.Value
case parse.Variable:
if ev == nil {
return "", ErrImpure
return "", false
}
v := ev.PurelyEvalPrimary(in.Head)
if s, ok := v.(string); ok {
head += s
} else {
return "", ErrImpure
return "", false
}
default:
return "", ErrImpure
return "", false
}
}
if tilde {
@ -51,11 +48,11 @@ func (ev *Evaler) PurelyEvalPartialCompound(cn *parse.Compound, upto int) (strin
uname := head[:i]
home, err := fsutil.GetHome(uname)
if err != nil {
return "", err
return "", false
}
head = home + head[i:]
}
return head, nil
return head, true
}
// PurelyEvalPrimary evaluates a primary node without causing any side effects.

View File

@ -1,7 +1,6 @@
package eval_test
import (
"reflect"
"testing"
. "github.com/elves/elvish/pkg/eval"
@ -20,7 +19,7 @@ func TestPurelyEvalCompound(t *testing.T) {
code string
upto int
wantValue string
wantErr error
wantBad bool
}{
{code: "foobar", wantValue: "foobar"},
{code: "'foobar'", wantValue: "foobar"},
@ -32,13 +31,13 @@ func TestPurelyEvalCompound(t *testing.T) {
{code: "~/foo", wantValue: home + "/foo"},
{code: "$ns:x", wantValue: "foo"},
{code: "$bad", wantErr: ErrImpure},
{code: "$ns:bad", wantErr: ErrImpure},
{code: "$bad", wantBad: true},
{code: "$ns:bad", wantBad: true},
{code: "[abc]", wantErr: ErrImpure},
{code: "$y", wantErr: ErrImpure},
{code: "a[0]", wantErr: ErrImpure},
{code: "$@x", wantErr: ErrImpure},
{code: "[abc]", wantBad: true},
{code: "$y", wantBad: true},
{code: "a[0]", wantBad: true},
{code: "$@x", wantBad: true},
}
ev := NewEvaler()
@ -63,13 +62,13 @@ func TestPurelyEvalCompound(t *testing.T) {
if upto == 0 {
upto = -1
}
value, err := ev.PurelyEvalPartialCompound(n, upto)
value, ok := ev.PurelyEvalPartialCompound(n, upto)
if value != test.wantValue {
t.Errorf("got value %q, want %q", value, test.wantValue)
}
if !reflect.DeepEqual(err, test.wantErr) {
t.Errorf("got error %v, want %q", err, test.wantErr)
if ok != !test.wantBad {
t.Errorf("got ok %v, want %v", ok, !test.wantBad)
}
})
}