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 {
|
func (cp *compiler) lambda(n *parse.Primary) valuesOp {
|
||||||
// Collect argument names
|
// Collect argument names
|
||||||
argNames := make([]string, len(n.List.Compounds))
|
var argNames []string
|
||||||
for i, arg := range n.List.Compounds {
|
if n.List != nil {
|
||||||
name := mustString(cp, arg, "expect string")
|
argNames = make([]string, len(n.List.Compounds))
|
||||||
argNames[i] = name
|
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.
|
// XXX The fiddlings with cp.capture is likely wrong.
|
||||||
|
|
|
@ -475,21 +475,12 @@ func (pn *Primary) lbracket(ps *parser) {
|
||||||
ps.error = shouldBeRBracket
|
ps.error = shouldBeRBracket
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !parseSep(pn, ps, '{') {
|
if parseSep(pn, ps, '{') {
|
||||||
// List
|
pn.lambda(ps)
|
||||||
|
} else {
|
||||||
pn.Type = List
|
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 == '&':
|
case r == '&':
|
||||||
pn.Type = Map
|
pn.Type = Map
|
||||||
// parseSep(pn, ps, '&')
|
// parseSep(pn, ps, '&')
|
||||||
|
@ -527,9 +518,16 @@ var (
|
||||||
|
|
||||||
// Braced = '{' Compound { (','|'-') Compounds } '}'
|
// Braced = '{' Compound { (','|'-') Compounds } '}'
|
||||||
// Comma = { Space } [ ',' ] { Space }
|
// Comma = { Space } [ ',' ] { Space }
|
||||||
func (pn *Primary) braced(ps *parser) {
|
func (pn *Primary) lbrace(ps *parser) {
|
||||||
pn.Type = Braced
|
|
||||||
parseSep(pn, ps, '{')
|
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.
|
// XXX: we don't actually know what happens with an empty Compound.
|
||||||
pn.addToBraced(parseCompound(ps, isBracedSep))
|
pn.addToBraced(parseCompound(ps, isBracedSep))
|
||||||
for isBracedSep(ps.peek()) {
|
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 {
|
func startsPrimary(r rune, cut runePred) bool {
|
||||||
if cut.matches(r) {
|
if cut.matches(r) {
|
||||||
return false
|
return false
|
||||||
|
@ -584,7 +595,7 @@ func (pn *Primary) parse(ps *parser, cut runePred) {
|
||||||
case '[':
|
case '[':
|
||||||
pn.lbracket(ps)
|
pn.lbracket(ps)
|
||||||
case '{':
|
case '{':
|
||||||
pn.braced(ps)
|
pn.lbrace(ps)
|
||||||
default:
|
default:
|
||||||
pn.bareword(ps, cut)
|
pn.bareword(ps, cut)
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ var goodCases = []struct {
|
||||||
ast{"Compound/Indexing/Primary", fs{"Type": Map, "text": "[ & ]"}},
|
ast{"Compound/Indexing/Primary", fs{"Type": Map, "text": "[ & ]"}},
|
||||||
)},
|
)},
|
||||||
// Lambda
|
// 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{
|
ast{"Compound/Indexing/Primary", fs{
|
||||||
"Type": Lambda,
|
"Type": Lambda,
|
||||||
}},
|
}},
|
||||||
|
@ -142,6 +142,10 @@ var goodCases = []struct {
|
||||||
"List": "$x $y ",
|
"List": "$x $y ",
|
||||||
"Chunk": "puts $x $y",
|
"Chunk": "puts $x $y",
|
||||||
}},
|
}},
|
||||||
|
ast{"Compound/Indexing/Primary", fs{
|
||||||
|
"Type": Lambda,
|
||||||
|
"Chunk": " put $1",
|
||||||
|
}},
|
||||||
)},
|
)},
|
||||||
// Output capture
|
// Output capture
|
||||||
{"a () (b;c)", a(
|
{"a () (b;c)", a(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user