@@ -113,7 +113,7 @@ the Lox programming language.'>
113
113
].
114
114
^ false .
115
115
]
116
-
116
+
117
117
parse [
118
118
" Parse the source tokens into a list of statements"
119
119
@@ -152,11 +152,73 @@ the Lox programming language.'>
152
152
" Grammar rule for a statement"
153
153
154
154
< category: ' rule' >
155
+ (self match: #(#For) ) ifTrue: [ ^ self forStatement ].
156
+ (self match: #(#If) ) ifTrue: [ ^ self ifStatement ].
155
157
(self match: #(#Print) ) ifTrue: [ ^ self printStatement ].
158
+ (self match: #(#While) ) ifTrue: [ ^ self whileStatement ].
156
159
(self match: #(#LeftBrace) ) ifTrue: [ ^ StmtBlock statements: self block ].
157
160
^ self expressionStatement.
158
161
]
159
162
163
+ forStatement [
164
+ " Grammar rule for desugaring a for statement"
165
+
166
+ < category: ' rule' >
167
+ | ini cond incr body stmts |
168
+ self consume: #LeftParen expect: ' Expect ' ' (' ' after ' ' for' ' .' .
169
+
170
+ (self match: #(#Semicolon) ) ifTrue: [ ini := nil ].
171
+ (self match: #(#Var) ) ifTrue: [
172
+ ini := self varDeclaration
173
+ ] ifFalse: [
174
+ ini := self expressionStatement
175
+ ].
176
+
177
+ cond := nil .
178
+ (self check: #Semicolon ) ifFalse: [ cond := self expression ].
179
+ self consume: #Semicolon expect: ' Expect ' ' ;' ' after loop condition.' .
180
+
181
+ incr := nil .
182
+ (self check: #RightParen ) ifFalse: [ incr := self expression ].
183
+ self consume: #RightParen expect: ' Expect ' ' )' ' after for clauses.' .
184
+ body := self statement.
185
+
186
+ incr ifNotNil: [
187
+ stmts := OrderedCollection new .
188
+ stmts
189
+ add: body;
190
+ add: (StmtExpression expression: incr).
191
+ body := StmtBlock statements: stmts
192
+ ].
193
+
194
+ cond ifNil: [ cond := ExprLiteral value: true ].
195
+ body := StmtWhile condition: cond body: body.
196
+
197
+ ini ifNotNil: [
198
+ stmts := OrderedCollection new .
199
+ stmts
200
+ add: ini;
201
+ add: body.
202
+ body := StmtBlock statements: stmts
203
+ ].
204
+
205
+ ^ body.
206
+ ]
207
+
208
+ ifStatement [
209
+ " Grammar rule for an if statement"
210
+
211
+ < category: ' rule' >
212
+ | cond then else |
213
+ self consume: #LeftParen expect: ' Expect ' ' (' ' after ' ' if' ' .' .
214
+ cond := self expression.
215
+ self consume: #RightParen expect: ' Expect ' ' )' ' after if condition.' .
216
+ then := self statement.
217
+ else := nil .
218
+ (self match: #(#Else) ) ifTrue: [ else := self statement ].
219
+ ^ StmtIf condition: cond thenBranch: then elseBranch: else.
220
+ ]
221
+
160
222
printStatement [
161
223
" Grammar rule for a print statement"
162
224
@@ -167,6 +229,18 @@ the Lox programming language.'>
167
229
^ StmtPrint expression: value.
168
230
]
169
231
232
+ whileStatement [
233
+ " Grammar rule for a while statement"
234
+
235
+ < category: ' rule' >
236
+ | cond body |
237
+ self consume: #LeftParen expect: ' Expect ' ' (' ' after ' ' while' ' .' .
238
+ cond := self expression.
239
+ self consume: #RightParen expect: ' Expect ' ' )' ' after condition.' .
240
+ body := self statement.
241
+ ^ StmtWhile condition: cond body: body.
242
+ ]
243
+
170
244
expressionStatement [
171
245
" Grammar rule for an expression statement"
172
246
@@ -202,7 +276,7 @@ the Lox programming language.'>
202
276
203
277
< category: ' rule' >
204
278
| expr equals value name |
205
- expr := self equality .
279
+ expr := self or .
206
280
207
281
(self match: #(#Equal) ) ifTrue: [
208
282
equals := self previous.
@@ -219,6 +293,36 @@ the Lox programming language.'>
219
293
^ expr.
220
294
]
221
295
296
+ or [
297
+ " Grammar rule for an or expression"
298
+
299
+ < category: ' rule' >
300
+ | expr operator right |
301
+ expr := self and .
302
+
303
+ [ self match: #(#Or) ] whileTrue: [
304
+ operator := self previous.
305
+ right := self and .
306
+ expr := ExprLogical left: expr operator: operator right: right
307
+ ].
308
+ ^ expr.
309
+ ]
310
+
311
+ and [
312
+ " Grammar rule for an and expression"
313
+
314
+ < category: ' rule' >
315
+ | expr operator right |
316
+ expr := self equality.
317
+
318
+ [ self match: #(#And) ] whileTrue: [
319
+ operator := self previous.
320
+ right := self equality.
321
+ expr := ExprLogical left: expr operator: operator right: right
322
+ ].
323
+ ^ expr.
324
+ ]
325
+
222
326
equality [
223
327
" Grammar rule for an equality"
224
328
@@ -296,7 +400,7 @@ the Lox programming language.'>
296
400
(self match: #(#False) ) ifTrue: [ ^ ExprLiteral value: false ].
297
401
(self match: #(#True) ) ifTrue: [ ^ ExprLiteral value: true ].
298
402
(self match: #(#Nil) ) ifTrue: [ ^ ExprLiteral value: nil ].
299
-
403
+
300
404
(self match: #(#Number #String) ) ifTrue: [
301
405
^ ExprLiteral value: (self previous literal)
302
406
].
@@ -310,7 +414,7 @@ the Lox programming language.'>
310
414
self consume: #RightParen expect: ' Expect ' ' )' ' after expression' .
311
415
^ ExprGrouping expression: expr
312
416
].
313
-
417
+
314
418
^ ParseError error: (self peek) message: ' Expected expression' .
315
419
]
316
420
]
0 commit comments