diff options
| author | Mel <einebeere@gmail.com> | 2022-07-04 13:09:18 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2022-07-04 13:09:18 +0200 |
| commit | e29ee3e310044ddb2356513808554a46de957659 (patch) | |
| tree | eef9b4b0ba523918beee7d0da5e49d9e02a97969 /pkg/lang/parser/stmts.go | |
| parent | ed9a0c8f0f3c1eed3582d722935cd1df1d055afd (diff) | |
| download | jinx-e29ee3e310044ddb2356513808554a46de957659.tar.zst jinx-e29ee3e310044ddb2356513808554a46de957659.zip | |
Parse For Stmts
Diffstat (limited to 'pkg/lang/parser/stmts.go')
| -rw-r--r-- | pkg/lang/parser/stmts.go | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/pkg/lang/parser/stmts.go b/pkg/lang/parser/stmts.go index 4b1077e..2a32906 100644 --- a/pkg/lang/parser/stmts.go +++ b/pkg/lang/parser/stmts.go @@ -18,6 +18,8 @@ func (p *Parser) parseStmt() (ast.Stmt, error) { return p.parseVarDeclStmt() case token.KwIf: return p.parseIfStmt() + case token.KwFor: + return p.parseForStmt() case token.KwTry: return p.parseTryStmt() case token.KwReturn: @@ -192,7 +194,6 @@ func (p *Parser) parseIfStmt() (ast.Stmt, error) { }) } - if p.peek().Kind == token.KwElse { elseTok, err := p.expect(token.KwElse) if err != nil { @@ -205,7 +206,7 @@ func (p *Parser) parseIfStmt() (ast.Stmt, error) { } conds = append(conds, ast.CondNode{ - At: elseTok.At, + At: elseTok.At, Cond: ast.Expr{}, Then: elseThen, }) @@ -220,6 +221,67 @@ func (p *Parser) parseIfStmt() (ast.Stmt, error) { }, nil } +func (p *Parser) parseForStmt() (ast.Stmt, error) { + // ForStmt = ForCondStmt | ForInStmt + // ForCondStmt = "for" Expr? Block + // ForInStmt = "for" Ident "in" Expr Block + + forTok, err := p.expect(token.KwFor) + if err != nil { + return ast.Stmt{}, err + } + + expr, err := p.parseExpr() + if err != nil { + return ast.Stmt{}, err + } + + // ForInStmt + if expr.Kind == ast.ExprKindIdent && p.peek().Kind == token.KwIn { + _, err := p.expect(token.KwIn) + if err != nil { + return ast.Stmt{}, err + } + + collection, err := p.parseExpr() + if err != nil { + return ast.Stmt{}, err + } + + do, err := p.parseBlock() + if err != nil { + return ast.Stmt{}, err + } + + return ast.Stmt{ + At: forTok.At, + Kind: ast.StmtKindForIn, + Value: ast.StmtForIn{ + Name: expr.Value.(ast.ExprIdent).Value, + Collection: collection, + Do: do, + }, + }, nil + } + + // ForCondStmt + cond := expr + + do, err := p.parseBlock() + if err != nil { + return ast.Stmt{}, err + } + + return ast.Stmt{ + At: forTok.At, + Kind: ast.StmtKindForCond, + Value: ast.StmtForCond{ + Cond: cond, + Do: do, + }, + }, nil +} + func (p *Parser) parseTryStmt() (ast.Stmt, error) { // TryStmt = "try" Block "catch" Ident ("finally" Block)? |
