mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
pkg/eval: Return bool instead error from (*Evaler)'s PurelyEval* methods.
This commit is contained in:
parent
9991b08fe0
commit
02d9252b5d
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user