mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-05 03:17:50 +08:00
parse and compile argumentless lambdas
This commit is contained in:
parent
6a5f6bf244
commit
3e0dc9c57b
|
@ -600,10 +600,15 @@ func (cp *compiler) popScope() {
|
|||
|
||||
func (cp *compiler) lambda(n *parse.Primary) valuesOp {
|
||||
// Collect argument names
|
||||
argNames := make([]string, len(n.List.Compounds))
|
||||
for i, arg := range n.List.Compounds {
|
||||
name := mustString(cp, arg, "expect string")
|
||||
argNames[i] = name
|
||||
var argNames []string
|
||||
if n.List != nil {
|
||||
argNames = make([]string, len(n.List.Compounds))
|
||||
for i, arg := range n.List.Compounds {
|
||||
name := mustString(cp, arg, "expect string")
|
||||
argNames[i] = name
|
||||
}
|
||||
} else {
|
||||
argNames = []string{}
|
||||
}
|
||||
|
||||
// XXX The fiddlings with cp.capture is likely wrong.
|
||||
|
|
|
@ -475,21 +475,12 @@ func (pn *Primary) lbracket(ps *parser) {
|
|||
ps.error = shouldBeRBracket
|
||||
return
|
||||
}
|
||||
if !parseSep(pn, ps, '{') {
|
||||
// List
|
||||
if parseSep(pn, ps, '{') {
|
||||
pn.lambda(ps)
|
||||
} else {
|
||||
pn.Type = List
|
||||
return
|
||||
}
|
||||
pn.Type = Lambda
|
||||
if !startsChunk(ps.peek(), nil) && ps.peek() != '}' {
|
||||
ps.error = shouldBeChunk
|
||||
return
|
||||
}
|
||||
pn.setChunk(parseChunk(ps, nil))
|
||||
if !parseSep(pn, ps, '}') {
|
||||
ps.error = shouldBeRBrace
|
||||
return
|
||||
}
|
||||
|
||||
case r == '&':
|
||||
pn.Type = Map
|
||||
// parseSep(pn, ps, '&')
|
||||
|
@ -527,9 +518,16 @@ var (
|
|||
|
||||
// Braced = '{' Compound { (','|'-') Compounds } '}'
|
||||
// Comma = { Space } [ ',' ] { Space }
|
||||
func (pn *Primary) braced(ps *parser) {
|
||||
pn.Type = Braced
|
||||
func (pn *Primary) lbrace(ps *parser) {
|
||||
parseSep(pn, ps, '{')
|
||||
|
||||
if r := ps.peek(); r == ';' || r == '\n' || isSpace(r) {
|
||||
pn.lambda(ps)
|
||||
return
|
||||
}
|
||||
|
||||
pn.Type = Braced
|
||||
|
||||
// XXX: we don't actually know what happens with an empty Compound.
|
||||
pn.addToBraced(parseCompound(ps, isBracedSep))
|
||||
for isBracedSep(ps.peek()) {
|
||||
|
@ -550,6 +548,19 @@ func (pn *Primary) braced(ps *parser) {
|
|||
}
|
||||
}
|
||||
|
||||
// lambda parses a lambda expression. The opening brace has been seen.
|
||||
func (pn *Primary) lambda(ps *parser) {
|
||||
pn.Type = Lambda
|
||||
if !startsChunk(ps.peek(), nil) && ps.peek() != '}' {
|
||||
ps.error = shouldBeChunk
|
||||
return
|
||||
}
|
||||
pn.setChunk(parseChunk(ps, nil))
|
||||
if !parseSep(pn, ps, '}') {
|
||||
ps.error = shouldBeRBrace
|
||||
}
|
||||
}
|
||||
|
||||
func startsPrimary(r rune, cut runePred) bool {
|
||||
if cut.matches(r) {
|
||||
return false
|
||||
|
@ -584,7 +595,7 @@ func (pn *Primary) parse(ps *parser, cut runePred) {
|
|||
case '[':
|
||||
pn.lbracket(ps)
|
||||
case '{':
|
||||
pn.braced(ps)
|
||||
pn.lbrace(ps)
|
||||
default:
|
||||
pn.bareword(ps, cut)
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ var goodCases = []struct {
|
|||
ast{"Compound/Indexing/Primary", fs{"Type": Map, "text": "[ & ]"}},
|
||||
)},
|
||||
// Lambda
|
||||
{"a []{} [ ]{ } []{ echo 233 } [ $x $y ]{puts $x $y}", a(
|
||||
{"a []{} [ ]{ } []{ echo 233 } [ $x $y ]{puts $x $y} { put $1}", a(
|
||||
ast{"Compound/Indexing/Primary", fs{
|
||||
"Type": Lambda,
|
||||
}},
|
||||
|
@ -142,6 +142,10 @@ var goodCases = []struct {
|
|||
"List": "$x $y ",
|
||||
"Chunk": "puts $x $y",
|
||||
}},
|
||||
ast{"Compound/Indexing/Primary", fs{
|
||||
"Type": Lambda,
|
||||
"Chunk": " put $1",
|
||||
}},
|
||||
)},
|
||||
// Output capture
|
||||
{"a () (b;c)", a(
|
||||
|
|
Loading…
Reference in New Issue
Block a user