mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-12 17:27:50 +08:00
eval: Name functions related to variable references consistently.
This commit is contained in:
parent
78c4a4fb3a
commit
926ccdd13d
|
@ -72,13 +72,13 @@ func complFormHeadInner(head string, ev *eval.Evaler, rawCands chan<- rawCandida
|
|||
for special := range eval.IsBuiltinSpecial {
|
||||
got(special)
|
||||
}
|
||||
explode, ns, _ := eval.ParseVariable(head)
|
||||
explode, ns, _ := eval.ParseVariableRef(head)
|
||||
if !explode {
|
||||
ev.EachVariableInTop(ns, func(varname string) {
|
||||
if strings.HasSuffix(varname, eval.FnSuffix) {
|
||||
got(eval.MakeVariableName(false, ns, varname[:len(varname)-len(eval.FnSuffix)]))
|
||||
got(eval.MakeVariableRef(false, ns, varname[:len(varname)-len(eval.FnSuffix)]))
|
||||
} else {
|
||||
name := eval.MakeVariableName(false, ns, varname)
|
||||
name := eval.MakeVariableRef(false, ns, varname)
|
||||
rawCands <- &complexCandidate{name, " = ", " = ", ui.Styles{}}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -17,7 +17,7 @@ func (*variableComplContext) name() string { return "variable" }
|
|||
func findVariableComplContext(n parse.Node, _ pureEvaler) complContext {
|
||||
primary := parse.GetPrimary(n)
|
||||
if primary != nil && primary.Type == parse.Variable {
|
||||
explode, nsPart, nameSeed := eval.SplitVariable(primary.Value)
|
||||
explode, nsPart, nameSeed := eval.SplitVariableRef(primary.Value)
|
||||
// Move past "$", "@" and "<ns>:".
|
||||
begin := primary.Begin() + 1 + len(explode) + len(nsPart)
|
||||
ns := nsPart
|
||||
|
|
|
@ -25,7 +25,7 @@ func goodFormHead(head string, ed *Editor) bool {
|
|||
return util.IsExecutable(head) || isDir(head)
|
||||
} else {
|
||||
ev := ed.evaler
|
||||
explode, ns, name := eval.ParseVariable(head)
|
||||
explode, ns, name := eval.ParseVariableRef(head)
|
||||
if !explode {
|
||||
switch ns {
|
||||
case "":
|
||||
|
|
|
@ -87,7 +87,7 @@ func compileDel(cp *compiler, fn *parse.Form) OpBody {
|
|||
continue
|
||||
}
|
||||
|
||||
explode, ns, name := ParseVariable(head.Value)
|
||||
explode, ns, name := ParseVariableRef(head.Value)
|
||||
if explode {
|
||||
cp.errorf("arguments to del may be have a leading @")
|
||||
continue
|
||||
|
|
|
@ -98,7 +98,7 @@ func (cp *compiler) lvaluesMulti(nodes []*parse.Compound) (LValuesOp, LValuesOp)
|
|||
|
||||
func (cp *compiler) lvalueBase(n *parse.Indexing, msg string) (bool, LValuesOpBody) {
|
||||
qname := cp.literal(n.Head, msg)
|
||||
explode, ns, name := ParseVariable(qname)
|
||||
explode, ns, name := ParseVariableRef(qname)
|
||||
if len(n.Indicies) == 0 {
|
||||
cp.registerVariableSet(ns, name)
|
||||
return explode, varOp{ns, name}
|
||||
|
|
|
@ -198,7 +198,7 @@ func (cp *compiler) form(n *parse.Form) OpBody {
|
|||
specialOpFunc = compileForm(cp, n)
|
||||
} else {
|
||||
var headOpFunc ValuesOpBody
|
||||
explode, ns, name := ParseVariable(headStr)
|
||||
explode, ns, name := ParseVariableRef(headStr)
|
||||
if !explode && cp.registerVariableGet(ns, name+FnSuffix) {
|
||||
// $head~ resolves.
|
||||
headOpFunc = variableOp{false, ns, name + FnSuffix}
|
||||
|
|
|
@ -252,7 +252,7 @@ func (cp *compiler) primary(n *parse.Primary) ValuesOpBody {
|
|||
case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted:
|
||||
return literalStr(n.Value)
|
||||
case parse.Variable:
|
||||
explode, ns, name := ParseVariable(n.Value)
|
||||
explode, ns, name := ParseVariableRef(n.Value)
|
||||
if !cp.registerVariableGet(ns, name) {
|
||||
cp.errorf("variable $%s not found", n.Value)
|
||||
}
|
||||
|
@ -422,7 +422,7 @@ func (cp *compiler) lambda(n *parse.Primary) ValuesOpBody {
|
|||
argNames = make([]string, len(n.Elements))
|
||||
for i, arg := range n.Elements {
|
||||
qname := mustString(cp, arg, "argument name must be literal string")
|
||||
explode, ns, name := ParseVariable(qname)
|
||||
explode, ns, name := ParseVariableRef(qname)
|
||||
if ns != "" {
|
||||
cp.errorpf(arg.Begin(), arg.End(), "argument name must be unqualified")
|
||||
}
|
||||
|
@ -445,7 +445,7 @@ func (cp *compiler) lambda(n *parse.Primary) ValuesOpBody {
|
|||
optDefaultOps = make([]ValuesOp, len(n.MapPairs))
|
||||
for i, opt := range n.MapPairs {
|
||||
qname := mustString(cp, opt.Key, "option name must be literal string")
|
||||
_, ns, name := ParseVariable(qname)
|
||||
_, ns, name := ParseVariableRef(qname)
|
||||
if ns != "" {
|
||||
cp.errorpf(opt.Key.Begin(), opt.Key.End(), "option name must be unqualified")
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ func (cp *compiler) popScope() {
|
|||
}
|
||||
|
||||
func (cp *compiler) registerVariableGetQname(qname string) bool {
|
||||
_, ns, name := ParseVariable(qname)
|
||||
_, ns, name := ParseVariableRef(qname)
|
||||
return cp.registerVariableGet(ns, name)
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ func (cp *compiler) registerVariableGet(ns, name string) bool {
|
|||
}
|
||||
|
||||
func (cp *compiler) registerVariableSetQname(qname string) bool {
|
||||
_, ns, name := ParseVariable(qname)
|
||||
_, ns, name := ParseVariableRef(qname)
|
||||
return cp.registerVariableSet(ns, name)
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ func (ev *Evaler) PurelyEvalPrimary(pn *parse.Primary) types.Value {
|
|||
case parse.Bareword, parse.SingleQuoted, parse.DoubleQuoted:
|
||||
return pn.Value
|
||||
case parse.Variable:
|
||||
explode, ns, name := ParseVariable(pn.Value)
|
||||
explode, ns, name := ParseVariableRef(pn.Value)
|
||||
if explode {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ func resolve(s string, ec *Frame) Fn {
|
|||
// (*compiler).form.
|
||||
|
||||
// Try variable
|
||||
explode, ns, name := ParseVariable(s)
|
||||
explode, ns, name := ParseVariableRef(s)
|
||||
if !explode {
|
||||
if v := ec.ResolveVar(ns, name+FnSuffix); v != nil {
|
||||
if caller, ok := v.Get().(Fn); ok {
|
||||
|
|
40
eval/util.go
40
eval/util.go
|
@ -4,7 +4,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/elves/elvish/eval/types"
|
||||
"github.com/elves/elvish/parse"
|
||||
|
@ -33,45 +32,6 @@ func mustGetHome(uname string) string {
|
|||
return dir
|
||||
}
|
||||
|
||||
// ParseVariable parses a variable reference.
|
||||
func ParseVariable(text string) (explode bool, ns string, name string) {
|
||||
explodePart, nsPart, name := SplitVariable(text)
|
||||
ns = nsPart
|
||||
if len(ns) > 0 {
|
||||
ns = ns[:len(ns)-1]
|
||||
}
|
||||
return explodePart != "", ns, name
|
||||
}
|
||||
|
||||
// SplitVariable splits a variable reference into three parts: an optional
|
||||
// explode operator (either "" or "@"), a namespace part, and a name part.
|
||||
func SplitVariable(text string) (explodePart, nsPart, name string) {
|
||||
if text == "" {
|
||||
return "", "", ""
|
||||
}
|
||||
e, qname := "", text
|
||||
if text[0] == '@' {
|
||||
e = "@"
|
||||
qname = text[1:]
|
||||
}
|
||||
if qname == "" {
|
||||
return e, "", ""
|
||||
}
|
||||
i := strings.LastIndexByte(qname, ':')
|
||||
return e, qname[:i+1], qname[i+1:]
|
||||
}
|
||||
|
||||
func MakeVariableName(explode bool, ns string, name string) string {
|
||||
prefix := ""
|
||||
if explode {
|
||||
prefix = "@"
|
||||
}
|
||||
if ns != "" {
|
||||
prefix += ns + ":"
|
||||
}
|
||||
return prefix + name
|
||||
}
|
||||
|
||||
func makeFlag(m parse.RedirMode) int {
|
||||
switch m {
|
||||
case parse.Read:
|
||||
|
|
43
eval/variable_ref.go
Normal file
43
eval/variable_ref.go
Normal file
|
@ -0,0 +1,43 @@
|
|||
package eval
|
||||
|
||||
import "strings"
|
||||
|
||||
// ParseVariableRef parses a variable reference.
|
||||
func ParseVariableRef(text string) (explode bool, ns string, name string) {
|
||||
explodePart, nsPart, name := SplitVariableRef(text)
|
||||
ns = nsPart
|
||||
if len(ns) > 0 {
|
||||
ns = ns[:len(ns)-1]
|
||||
}
|
||||
return explodePart != "", ns, name
|
||||
}
|
||||
|
||||
// SplitVariableRef splits a variable reference into three parts: an optional
|
||||
// explode operator (either "" or "@"), a namespace part, and a name part.
|
||||
func SplitVariableRef(text string) (explodePart, nsPart, name string) {
|
||||
if text == "" {
|
||||
return "", "", ""
|
||||
}
|
||||
e, qname := "", text
|
||||
if text[0] == '@' {
|
||||
e = "@"
|
||||
qname = text[1:]
|
||||
}
|
||||
if qname == "" {
|
||||
return e, "", ""
|
||||
}
|
||||
i := strings.LastIndexByte(qname, ':')
|
||||
return e, qname[:i+1], qname[i+1:]
|
||||
}
|
||||
|
||||
// MakeVariableRef builds a variable reference.
|
||||
func MakeVariableRef(explode bool, ns string, name string) string {
|
||||
prefix := ""
|
||||
if explode {
|
||||
prefix = "@"
|
||||
}
|
||||
if ns != "" {
|
||||
prefix += ns + ":"
|
||||
}
|
||||
return prefix + name
|
||||
}
|
Loading…
Reference in New Issue
Block a user