@@ -164,10 +164,66 @@ if-expressions.
164164
165165Suppose we want to compile @racket['(if (zero? 8 ) 2 3 )]...
166166
167- We already know how to compile the @racket[' 8 ], @racket[' 2 ], and
168- @racket[' 3 ] part.
167+ We already know how to compile the @racket[8 ], @racket[2 ], and
168+ @racket[3 ] part.
169169
170- What needs to happen? ...
170+ What needs to happen?
171+
172+ @itemlist[
173+ @item{Execute the code for @racket[8 ] leaving the result in @racket['rax ],}
174+ @item{check whether @racket['rax ] holds zero,}
175+ @item{if it does, execute the code for @racket[2 ],}
176+ @item{if it doesn't , execute the code for @racket[3 ].}
177+ ]
178+
179+ We can determine whether @racket[8 ] evaluates to @racket[0 ] using a
180+ comparison instruction: @racket['(cmp rax 0 )]. To do the conditional
181+ execution, we will need to jump to different parts of the code to
182+ either execute the code for @racket[2 ] or @racket[3 ]. There are
183+ several ways we could accomplish this , but we take the following
184+ approach: immediately after the comparison, do a conditional jump to
185+ the code for the else branch when non-zero. Should the jump not occur,
186+ the next instructions will carry out the evaluation of the then
187+ branch, then (unconditionally) jump over the else branch code.
188+
189+ To accomplish this , we will need two new labels: one for the else
190+ branch code and one for the end of the else branch code. The
191+ @racket[gensym] function can be used to generate symbols that have not
192+ appeared before.
193+
194+ In total, the code for this example would look like:
195+
196+ @racketblock[
197+ '((mov rax 8 )
198+ (cmp rax 0 )
199+ (jne if-else-begin)
200+ (mov rax 2 )
201+ (jmp if-else-end)
202+ if-else-begin
203+ (mov rax 3 )
204+ if-else-end)
205+ ]
206+
207+ Notice that the @racket['(mov rax 8 )], @racket['(mov rax 3 )] and
208+ @racket['(mov rax 2 )] parts are just the instructions generated by
209+ compiling @racket[8 ], @racket[2 ] and @racket[3 ]. Generalizing from
210+ this , we arrive at the following code for the compiler:
211+
212+ @racketblock[
213+ (let ((c0 (compile-e e0))
214+ (c1 (compile-e e1))
215+ (c2 (compile-e e2))
216+ (l0 (gensym "if-else-begin " ))
217+ (l1 (gensym "if-else-end " )))
218+ '(,@c0
219+ (cmp rax 0 )
220+ (jne ,l0)
221+ ,@c1
222+ (jmp ,l1)
223+ ,l0
224+ ,@c2
225+ ,l1))
226+ ]
171227
172228
173229@ex[
0 commit comments