@@ -113,7 +113,7 @@ the Lox programming language.'>
113113 ].
114114 ^ false .
115115 ]
116-
116+
117117 parse [
118118 " Parse the source tokens into a list of statements"
119119
@@ -152,11 +152,73 @@ the Lox programming language.'>
152152 " Grammar rule for a statement"
153153
154154 < category: ' rule' >
155+ (self match: #(#For) ) ifTrue: [ ^ self forStatement ].
156+ (self match: #(#If) ) ifTrue: [ ^ self ifStatement ].
155157 (self match: #(#Print) ) ifTrue: [ ^ self printStatement ].
158+ (self match: #(#While) ) ifTrue: [ ^ self whileStatement ].
156159 (self match: #(#LeftBrace) ) ifTrue: [ ^ StmtBlock statements: self block ].
157160 ^ self expressionStatement.
158161 ]
159162
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+
160222 printStatement [
161223 " Grammar rule for a print statement"
162224
@@ -167,6 +229,18 @@ the Lox programming language.'>
167229 ^ StmtPrint expression: value.
168230 ]
169231
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+
170244 expressionStatement [
171245 " Grammar rule for an expression statement"
172246
@@ -202,7 +276,7 @@ the Lox programming language.'>
202276
203277 < category: ' rule' >
204278 | expr equals value name |
205- expr := self equality .
279+ expr := self or .
206280
207281 (self match: #(#Equal) ) ifTrue: [
208282 equals := self previous.
@@ -219,6 +293,36 @@ the Lox programming language.'>
219293 ^ expr.
220294 ]
221295
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+
222326 equality [
223327 " Grammar rule for an equality"
224328
@@ -296,7 +400,7 @@ the Lox programming language.'>
296400 (self match: #(#False) ) ifTrue: [ ^ ExprLiteral value: false ].
297401 (self match: #(#True) ) ifTrue: [ ^ ExprLiteral value: true ].
298402 (self match: #(#Nil) ) ifTrue: [ ^ ExprLiteral value: nil ].
299-
403+
300404 (self match: #(#Number #String) ) ifTrue: [
301405 ^ ExprLiteral value: (self previous literal)
302406 ].
@@ -310,7 +414,7 @@ the Lox programming language.'>
310414 self consume: #RightParen expect: ' Expect ' ' )' ' after expression' .
311415 ^ ExprGrouping expression: expr
312416 ].
313-
417+
314418 ^ ParseError error: (self peek) message: ' Expected expression' .
315419 ]
316420]
0 commit comments