diff options
| author | Mel <einebeere@gmail.com> | 2022-07-28 21:18:09 +0000 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-07-28 21:18:09 +0000 |
| commit | 895120776a0ae4dd121029f1730d29ca886e201e (patch) | |
| tree | 98e4771fd83ec88d559de95f058f724747405f1a /pkg/lang/parser/exprs.go | |
| parent | d79973cb9df8660fe89810507557f5ba86256f30 (diff) | |
| download | jinx-895120776a0ae4dd121029f1730d29ca886e201e.tar.zst jinx-895120776a0ae4dd121029f1730d29ca886e201e.zip | |
Fix nested stacked exprs and parse members
Diffstat (limited to 'pkg/lang/parser/exprs.go')
| -rw-r--r-- | pkg/lang/parser/exprs.go | 113 |
1 files changed, 72 insertions, 41 deletions
diff --git a/pkg/lang/parser/exprs.go b/pkg/lang/parser/exprs.go index 80b0fd6..48d1a8c 100644 --- a/pkg/lang/parser/exprs.go +++ b/pkg/lang/parser/exprs.go @@ -65,7 +65,7 @@ func (p *Parser) parseUnaryExpr() (ast.Expr, error) { func (p *Parser) parsePostfixExpr() (ast.Expr, error) { // PostfixExpr = SubscriptionExpr | CallExpr - obj, err := p.parseUnitExpr() + obj, err := p.parseMemberExpr() if err != nil { return ast.Expr{}, err } @@ -81,42 +81,41 @@ func (p *Parser) parsePostfixExpr() (ast.Expr, error) { } func (p *Parser) parseArrayIndexExpr(obj ast.Expr) (ast.Expr, error) { - // SubscriptionExpr = UnitExpr ( "[" Expr "]" )* + // SubscriptionExpr = MemberExpr ( "[" Expr "]" )* - if _, err := p.expect(token.LBracket); err != nil { - return ast.Expr{}, err - } + for p.peek().Kind == token.LBracket { + p.next() - index, err := p.parseExpr() - if err != nil { - return ast.Expr{}, err - } + index, err := p.parseExpr() + if err != nil { + return ast.Expr{}, err + } - if _, err := p.expect(token.RBracket); err != nil { - return ast.Expr{}, err - } + if _, err := p.expect(token.RBracket); err != nil { + return ast.Expr{}, err + } - return ast.Expr{ - At: obj.At, - Kind: ast.ExprKindSubscription, - Value: ast.ExprSubscription{ - Obj: obj, - Key: index, - }, - }, nil + obj = ast.Expr{ + At: obj.At, + Kind: ast.ExprKindSubscription, + Value: ast.ExprSubscription{ + Obj: obj, + Key: index, + }, + } + } + return obj, nil } func (p *Parser) parseCallExpr(callee ast.Expr) (ast.Expr, error) { - // CallExpr = UnitExpr ( "(" ( Expr ( "," Expr )* )? ")" )* + // CallExpr = MemberExpr ( "(" ( Expr ( "," Expr )* )? ")" )* - if _, err := p.expect(token.LParen); err != nil { - return ast.Expr{}, err - } + for p.peek().Kind == token.LParen { + p.next() - args := []ast.Expr{} - if p.peek().Kind != token.RParen { - for { + args := []ast.Expr{} + for p.peek().Kind != token.RParen { arg, err := p.parseExpr() if err != nil { return ast.Expr{}, err @@ -124,29 +123,61 @@ func (p *Parser) parseCallExpr(callee ast.Expr) (ast.Expr, error) { args = append(args, arg) - if p.peek().Kind == token.RParen { + if p.peek().Kind == token.Comma { + p.next() + } else { break } + } - if _, err := p.expect(token.Comma); err != nil { - return ast.Expr{}, err - } + if _, err := p.expect(token.RParen); err != nil { + return ast.Expr{}, err + } + + callee = ast.Expr{ + At: callee.At, + Kind: ast.ExprKindCall, + Value: ast.ExprCall{ + Callee: callee, + Args: args, + }, } } - if _, err := p.expect(token.RParen); err != nil { + return callee, nil +} + +func (p *Parser) parseMemberExpr() (ast.Expr, error) { + // MemberExpr = UnitExpr ( "." Ident )* + + left, err := p.parseUnitExpr() + if err != nil { return ast.Expr{}, err } - return ast.Expr{ - At: callee.At, - Kind: ast.ExprKindCall, - Value: ast.ExprCall{ - Callee: callee, - Args: args, - }, - }, nil + for { + if p.peek().Kind != token.Dot { + break + } + + p.next() + + node, err := p.parseIdent() + if err != nil { + return ast.Expr{}, err + } + left = ast.Expr{ + At: left.At, + Kind: ast.ExprKindMember, + Value: ast.ExprMember{ + Obj: left, + Key: node, + }, + } + } + + return left, nil } func (p *Parser) parseUnitExpr() (ast.Expr, error) { @@ -176,7 +207,7 @@ func (p *Parser) parseUnitExpr() (ast.Expr, error) { case token.KwTrue, token.KwFalse, token.KwNull, token.KwThis: return p.parseValueLitExpr() default: - panic(fmt.Errorf("unexpected token '%v', wanted unit expression start", p.peek())) + panic(fmt.Errorf("unexpected token '%v', wanted unit expression start", p.peek().Kind)) } } |
