Skip to content

Commit ea42743

Browse files
committed
Update Con notes.
1 parent babccf0 commit ea42743

1 file changed

Lines changed: 65 additions & 13 deletions

File tree

www/notes/con.scrbl

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,23 @@
1616
@(define codeblock-include (make-codeblock-include #'h))
1717

1818
@(for-each (λ (f) (ev `(require (file ,(path->string (build-path notes "con" f))))))
19-
'("interp.rkt" "compile.rkt" "asm/interp.rkt" "asm/printer.rkt"))
19+
'("interp.rkt" "compile.rkt" "asm/interp.rkt" "asm/printer.rkt" "random.rkt"))
2020

2121

2222
@title[#:tag "Con"]{Con: branching with conditionals}
2323

24+
@emph{When you come to a fork in the road, take it.}
25+
26+
@table-of-contents[]
27+
28+
@section{Conditional execution}
29+
2430
Let's now consider add a notion of @bold{conditionals} to our target
2531
language.
2632

2733
We'll call it @bold{Con}.
2834

29-
We will use the following syntax...
35+
We will use the following syntax: @racket[(if (zero? _e0) _e1 _e2)].
3036

3137
Together this leads to the following grammar for Con:
3238

@@ -46,9 +52,9 @@ the new form is an if-expression.
4652

4753
@itemlist[
4854

49-
@item{the meaning of a if expression @tt{(if (zero? e0) e1 e2)} is the
50-
meaning of @math{e1} if the meaning of @tt{e1} if the meaning of
51-
@tt{e0} is 0 and is the meaning of @math{e2} otherwise.}
55+
@item{the meaning of a if expression @racket[(if (zero? _e0) _e1 _e2)] is the
56+
meaning of @racket[_e1] if the meaning of @racket[_e1] if the meaning of
57+
@racket[_e0] is 0 and is the meaning of @racket[_e2] otherwise.}
5258

5359
]
5460

@@ -204,6 +210,9 @@ In total, the code for this example would look like:
204210
if-else-end)
205211
]
206212

213+
214+
@section{A Compiler for Con}
215+
207216
Notice that the @racket['(mov rax 8)], @racket['(mov rax 3)] and
208217
@racket['(mov rax 2)] parts are just the instructions generated by
209218
compiling @racket[8], @racket[2] and @racket[3]. Generalizing from
@@ -213,9 +222,9 @@ this, we arrive at the following code for the compiler:
213222
(let ((c0 (compile-e e0))
214223
(c1 (compile-e e1))
215224
(c2 (compile-e e2))
216-
(l0 (gensym "if-else-begin"))
217-
(l1 (gensym "if-else-end")))
218-
'(,@c0
225+
(l0 (gensym "if"))
226+
(l1 (gensym "if")))
227+
`(,@c0
219228
(cmp rax 0)
220229
(jne ,l0)
221230
,@c1
@@ -226,22 +235,65 @@ this, we arrive at the following code for the compiler:
226235
]
227236

228237

229-
@ex[
230-
(asm-display (compile '(if (zero? 8) 2 3)))
231-
]
232-
238+
This will require extending our representation of x86 instructions; in
239+
particular, we add @racket['jmp], @racket['jne], and @racket['cmp]
240+
instructions:
233241

234242
@codeblock-include["con/asm/ast.rkt"]
235243

236244
We omit the printer code, which is mundane. See
237245
@link["con/asm/printer.rkt"]{@tt{asm/printer.rkt}} for details.
238246

247+
The complete compiler code is:
248+
239249
@codeblock-include["con/compile.rkt"]
240250

251+
Let's take a look at a few examples:
252+
@ex[
253+
(asm-display (compile '(if (zero? 8) 2 3)))
254+
(asm-display (compile '(if (zero? 0) 1 2)))
255+
(asm-display (compile '(if (zero? 0) (if (zero? 0) 8 9) 2)))
256+
(asm-display (compile '(if (zero? (if (zero? 2) 1 0)) 4 5)))
257+
]
241258

259+
And confirm they are running as expected:
242260
@ex[
261+
(asm-interp (compile '(if (zero? 8) 2 3)))
243262
(asm-interp (compile '(if (zero? 0) 1 2)))
244-
(asm-interp (compile '(if (zero? 3) 1 2)))
245263
(asm-interp (compile '(if (zero? 0) (if (zero? 0) 8 9) 2)))
246264
(asm-interp (compile '(if (zero? (if (zero? 2) 1 0)) 4 5)))
247265
]
266+
267+
268+
@section[#:tag-prefix "con"]{Correctness and random testing}
269+
270+
The statement of correctness follows the same outline as before:
271+
272+
@bold{Compiler Correctness}: @emph{For all expressions @racket[e] and
273+
integers @racket[i], if (@racket[e],@racket[i]) in @render-term[C 𝑪],
274+
then @racket[(asm-interp (compile e))] equals @racket[i].}
275+
276+
Again, we formulate correctness as a property that can be tested:
277+
278+
@ex[
279+
(define (check-compiler e)
280+
(check-equal? (asm-interp (compile e))
281+
(interp e)
282+
e))]
283+
284+
Generating random Con programs is essentially the same as Blackmail
285+
programs, and are provided in a @link["con/random.rkt"]{random.rkt}
286+
module.
287+
288+
@ex[
289+
(eval:alts (require "random.rkt") (void))
290+
(random-expr)
291+
(random-expr)
292+
(random-expr)
293+
(random-expr)
294+
(for ([i (in-range 10)])
295+
(check-compiler (random-expr)))
296+
]
297+
298+
299+

0 commit comments

Comments
 (0)