|
1 | 1 | package vibes |
2 | 2 |
|
3 | | -import ( |
4 | | - "fmt" |
5 | | -) |
6 | | - |
7 | 3 | func (p *parser) parseStatement() Statement { |
8 | 4 | switch p.curToken.Type { |
9 | 5 | case tokenDef: |
@@ -62,172 +58,6 @@ func (p *parser) parseRaiseStatement() Statement { |
62 | 58 | return &RaiseStmt{Value: value, position: pos} |
63 | 59 | } |
64 | 60 |
|
65 | | -func (p *parser) parseIfStatement() Statement { |
66 | | - pos := p.curToken.Pos |
67 | | - p.nextToken() |
68 | | - condition := p.parseExpression(lowestPrec) |
69 | | - |
70 | | - p.nextToken() |
71 | | - consequent := p.parseBlock(tokenEnd, tokenElse, tokenElsif) |
72 | | - |
73 | | - var elseifClauses []*IfStmt |
74 | | - for p.curToken.Type == tokenElsif { |
75 | | - p.nextToken() |
76 | | - cond := p.parseExpression(lowestPrec) |
77 | | - p.nextToken() |
78 | | - body := p.parseBlock(tokenEnd, tokenElse, tokenElsif) |
79 | | - clause := &IfStmt{Condition: cond, Consequent: body, position: cond.Pos()} |
80 | | - elseifClauses = append(elseifClauses, clause) |
81 | | - } |
82 | | - |
83 | | - var alternate []Statement |
84 | | - if p.curToken.Type == tokenElse { |
85 | | - p.nextToken() |
86 | | - alternate = p.parseBlock(tokenEnd) |
87 | | - } |
88 | | - |
89 | | - if p.curToken.Type != tokenEnd { |
90 | | - p.errorExpected(p.curToken, "end") |
91 | | - } |
92 | | - |
93 | | - return &IfStmt{Condition: condition, Consequent: consequent, ElseIf: elseifClauses, Alternate: alternate, position: pos} |
94 | | -} |
95 | | - |
96 | | -func (p *parser) parseForStatement() Statement { |
97 | | - pos := p.curToken.Pos |
98 | | - if !p.expectPeek(tokenIdent) { |
99 | | - return nil |
100 | | - } |
101 | | - iterator := p.curToken.Literal |
102 | | - |
103 | | - if !p.expectPeek(tokenIn) { |
104 | | - return nil |
105 | | - } |
106 | | - |
107 | | - p.nextToken() |
108 | | - iterable := p.parseExpression(lowestPrec) |
109 | | - |
110 | | - p.nextToken() |
111 | | - body := p.parseBlock(tokenEnd) |
112 | | - |
113 | | - if p.curToken.Type != tokenEnd { |
114 | | - p.errorExpected(p.curToken, "end") |
115 | | - } |
116 | | - |
117 | | - return &ForStmt{Iterator: iterator, Iterable: iterable, Body: body, position: pos} |
118 | | -} |
119 | | - |
120 | | -func (p *parser) parseWhileStatement() Statement { |
121 | | - pos := p.curToken.Pos |
122 | | - p.nextToken() |
123 | | - condition := p.parseExpression(lowestPrec) |
124 | | - |
125 | | - p.nextToken() |
126 | | - body := p.parseBlock(tokenEnd) |
127 | | - |
128 | | - if p.curToken.Type != tokenEnd { |
129 | | - p.errorExpected(p.curToken, "end") |
130 | | - } |
131 | | - |
132 | | - return &WhileStmt{Condition: condition, Body: body, position: pos} |
133 | | -} |
134 | | - |
135 | | -func (p *parser) parseUntilStatement() Statement { |
136 | | - pos := p.curToken.Pos |
137 | | - p.nextToken() |
138 | | - condition := p.parseExpression(lowestPrec) |
139 | | - |
140 | | - p.nextToken() |
141 | | - body := p.parseBlock(tokenEnd) |
142 | | - |
143 | | - if p.curToken.Type != tokenEnd { |
144 | | - p.errorExpected(p.curToken, "end") |
145 | | - } |
146 | | - |
147 | | - return &UntilStmt{Condition: condition, Body: body, position: pos} |
148 | | -} |
149 | | - |
150 | | -func (p *parser) parseBreakStatement() Statement { |
151 | | - return &BreakStmt{position: p.curToken.Pos} |
152 | | -} |
153 | | - |
154 | | -func (p *parser) parseNextStatement() Statement { |
155 | | - return &NextStmt{position: p.curToken.Pos} |
156 | | -} |
157 | | - |
158 | | -func (p *parser) parseBeginStatement() Statement { |
159 | | - pos := p.curToken.Pos |
160 | | - p.nextToken() |
161 | | - body := p.parseBlock(tokenRescue, tokenEnsure, tokenEnd) |
162 | | - |
163 | | - var rescueTy *TypeExpr |
164 | | - var rescueBody []Statement |
165 | | - if p.curToken.Type == tokenRescue { |
166 | | - rescuePos := p.curToken.Pos |
167 | | - if p.peekToken.Type == tokenLParen && p.peekToken.Pos.Line == rescuePos.Line { |
168 | | - p.nextToken() |
169 | | - p.nextToken() |
170 | | - rescueTy = p.parseTypeExpr() |
171 | | - if rescueTy == nil { |
172 | | - return nil |
173 | | - } |
174 | | - if !p.validateRescueTypeExpr(rescueTy, rescuePos) { |
175 | | - return nil |
176 | | - } |
177 | | - if !p.expectPeek(tokenRParen) { |
178 | | - return nil |
179 | | - } |
180 | | - } |
181 | | - p.nextToken() |
182 | | - rescueBody = p.parseBlock(tokenEnsure, tokenEnd) |
183 | | - } |
184 | | - |
185 | | - var ensureBody []Statement |
186 | | - if p.curToken.Type == tokenEnsure { |
187 | | - p.nextToken() |
188 | | - ensureBody = p.parseBlock(tokenEnd) |
189 | | - } |
190 | | - |
191 | | - if p.curToken.Type != tokenEnd { |
192 | | - p.errorExpected(p.curToken, "end") |
193 | | - return nil |
194 | | - } |
195 | | - |
196 | | - if len(rescueBody) == 0 && len(ensureBody) == 0 { |
197 | | - p.addParseError(pos, "begin requires rescue and/or ensure") |
198 | | - return nil |
199 | | - } |
200 | | - |
201 | | - return &TryStmt{Body: body, RescueTy: rescueTy, Rescue: rescueBody, Ensure: ensureBody, position: pos} |
202 | | -} |
203 | | - |
204 | | -func (p *parser) validateRescueTypeExpr(ty *TypeExpr, pos Position) bool { |
205 | | - if ty == nil { |
206 | | - p.addParseError(pos, "rescue type cannot be empty") |
207 | | - return false |
208 | | - } |
209 | | - |
210 | | - if ty.Kind == TypeUnion { |
211 | | - ok := true |
212 | | - for _, option := range ty.Union { |
213 | | - if !p.validateRescueTypeExpr(option, option.position) { |
214 | | - ok = false |
215 | | - } |
216 | | - } |
217 | | - return ok |
218 | | - } |
219 | | - |
220 | | - if len(ty.TypeArgs) > 0 || len(ty.Shape) > 0 { |
221 | | - p.addParseError(pos, fmt.Sprintf("rescue type must be an error class, got %s", formatTypeExpr(ty))) |
222 | | - return false |
223 | | - } |
224 | | - if _, ok := canonicalRuntimeErrorType(ty.Name); !ok { |
225 | | - p.addParseError(pos, fmt.Sprintf("unknown rescue error type %s", ty.Name)) |
226 | | - return false |
227 | | - } |
228 | | - return true |
229 | | -} |
230 | | - |
231 | 61 | func (p *parser) parseBlock(stop ...TokenType) []Statement { |
232 | 62 | stmts := []Statement{} |
233 | 63 | stopSet := make(map[TokenType]struct{}, len(stop)) |
|
0 commit comments