Add value-returning match expressions
This commit is contained in:
parent
b0a52de4ea
commit
ab783c33ed
12 changed files with 384 additions and 14 deletions
|
|
@ -793,6 +793,68 @@ func (p *parser) parseMatch() (Stmt, error) {
|
|||
return MatchStmt{Value: value, Cases: cases}, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseMatchExpr() (Expr, error) {
|
||||
if _, err := p.expect(tokenLParen, "expected '(' after match"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value, err := p.parseExpr(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := p.expect(tokenRParen, "expected ')' after match value"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := p.expect(tokenLBrace, "expected '{' after match value"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cases []MatchExprCase
|
||||
for !p.check(tokenRBrace) && !p.check(tokenEOF) {
|
||||
enumName, err := p.expect(tokenIdent, "expected enum name in match case")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := p.expect(tokenDoubleColon, "expected '::' in match case"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
variant, err := p.expect(tokenIdent, "expected variant name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var bindings []string
|
||||
if p.match(tokenLParen) {
|
||||
if !p.check(tokenRParen) {
|
||||
for {
|
||||
binding, err := p.expect(tokenIdent, "expected variant binding")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bindings = append(bindings, binding.lexeme)
|
||||
if !p.match(tokenComma) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := p.expect(tokenRParen, "expected ')' after variant bindings"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if _, err := p.expect(tokenArrow, "expected '->' after match pattern"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := p.parseExpr(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cases = append(cases, MatchExprCase{EnumName: enumName.lexeme, VariantName: variant.lexeme, Bindings: bindings, Value: result})
|
||||
p.match(tokenComma)
|
||||
p.match(tokenSemicolon)
|
||||
}
|
||||
if _, err := p.expect(tokenRBrace, "expected '}' after match"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return MatchExpr{Value: value, Cases: cases}, nil
|
||||
}
|
||||
|
||||
func (p *parser) parseSelect() (Stmt, error) {
|
||||
if _, err := p.expect(tokenLBrace, "expected '{' after select"); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -1016,6 +1078,8 @@ func (p *parser) parsePrefix() (Expr, error) {
|
|||
return p.parsePostfix(expr)
|
||||
case tokenLBrace:
|
||||
return p.parseLambdaExpr()
|
||||
case tokenMatch:
|
||||
return p.parseMatchExpr()
|
||||
case tokenBang, tokenMinus, tokenAmp, tokenStar:
|
||||
value, err := p.parseExpr(7)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue