Skip to content

Commit 5cb9b5d

Browse files
authored
Merge pull request #13 from dvanhorn/next
Update schedule to reflect reality.
2 parents 3f64098 + 0d605e5 commit 5cb9b5d

4 files changed

Lines changed: 105 additions & 50 deletions

File tree

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ env:
88
- PANDOC=~/.pandoc
99
- PANDOC_DEB="https://github.com/jgm/pandoc/releases/download/2.7.3/pandoc-2.7.3-1-amd64.deb"
1010
matrix:
11-
- RACKET_VERSION=7.3
11+
- RACKET_VERSION=7.4
1212
cache:
1313
directories:
1414
- $PANDOC
@@ -46,4 +46,4 @@ deploy:
4646
script: rsync -rvzp $TRAVIS_BUILD_DIR/www/cmsc430 dvanhorn@junkfood.cs.umd.edu:$WWW_DIR/fall2019
4747
on:
4848
branch: master
49-
condition: "$RACKET_VERSION='7.3'"
49+

www/notes/con.scrbl

Lines changed: 82 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,17 @@ Let's consider some examples:
5656

5757
@itemlist[
5858

59-
@item{...}
59+
@item{@racket['(if (zero? 0) (add1 2) 4)] means @racket[3].}
60+
@item{@racket['(if (zero? 1) (add1 2) 4)] means @racket[4].}
61+
@item{@racket['(if (zero? (if (zero? (sub1 1)) 1 0)) (add1 2) 4)] means @racket[4].}
62+
@item{@racket['(if (zero? (add1 0)) (add1 2) (if (zero? (sub1 1)) 1 0))] means @racket[1].}
6063

6164
]
6265

6366

64-
The semantics...
67+
The semantics is inductively defined as before. There are @emph{two}
68+
new rules added for handling if-expressions: one for when the test
69+
expression means @racket[0] and one for when it doesn't.
6570

6671
@(define ((rewrite s) lws)
6772
(define lhs (list-ref lws 2))
@@ -135,33 +140,96 @@ according to @render-term[C 𝑪𝒓]:
135140
@(show-judgment 𝑪 0 1)
136141
}
137142

138-
The interpreter ...
143+
The interpreter has an added case for if-expressions, which
144+
recursively evaluates the test expression and branches based on its
145+
value.
139146

140147
@codeblock-include["con/interp.rkt"]
141148

142149
We can confirm the interpreter computes the right result for the
143150
examples given earlier:
144151

145152
@ex[
146-
'...
153+
(interp '(if (zero? 0) (add1 2) 4))
154+
(interp '(if (zero? 1) (add1 2) 4))
155+
(interp '(if (zero? (if (zero? (sub1 1)) 1 0)) (add1 2) 4))
156+
(interp '(if (zero? (add1 0)) (add1 2) (if (zero? (sub1 1)) 1 0)))
147157
]
148158

149-
Correctness...
150-
@;{
151-
@bold{Interpreter Correctness}: @emph{For all Con expressions
152-
@racket[e] and integers @racket[i], if (@racket[e],@racket[i]) in
153-
@render-term[C 𝑪], then @racket[(interp e)] equals
154-
@racket[i].}
155-
}
159+
The argument for the correctness of the interpreter follows the same
160+
structure as for @seclink["Blackmail"]{Blackmail}, but with an added case for
161+
if-expressions.
156162

157163
@section{An Example of Con compilation}
158164

159165
Suppose we want to compile @racket['(if (zero? 8) 2 3)]...
160166

161-
We already know how to compile the @racket['8], @racket['2], and
162-
@racket['3] part.
167+
We already know how to compile the @racket[8], @racket[2], and
168+
@racket[3] part.
169+
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+
]
227+
228+
229+
@ex[
230+
(asm-display (compile '(if (zero? 8) 2 3)))
231+
]
163232

164-
What needs to happen? ...
165233

166234
@codeblock-include["con/asm/ast.rkt"]
167235

www/notes/con/compile.rkt

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,14 @@
2222
[`(if (zero? ,e0) ,e1 ,e2)
2323
(let ((c0 (compile-e e0))
2424
(c1 (compile-e e1))
25-
(c2 (compile-e e2)))
26-
(match (gen-if-labels)
27-
[(list if-f if-x)
28-
`(,@c0
29-
(cmp rax 0)
30-
(jne ,if-f)
31-
,@c1
32-
(jmp ,if-x)
33-
,if-f
34-
,@c2
35-
,if-x)]))]))
36-
37-
;; -> [List Label Label]
38-
;; Guaranteed to be unique on each call
39-
(define gen-if-labels
40-
(let ((i 0))
41-
(λ ()
42-
(set! i (add1 i))
43-
(list (lab "f" i)
44-
(lab "x" i)))))
45-
46-
;; String Integer -> Symbol
47-
(define (lab s i)
48-
(string->symbol (string-append "if_" s "_" (number->string i))))
25+
(c2 (compile-e e2))
26+
(l0 (gensym "if"))
27+
(l1 (gensym "if")))
28+
`(,@c0
29+
(cmp rax 0)
30+
(jne ,l0)
31+
,@c1
32+
(jmp ,l1)
33+
,l0
34+
,@c2
35+
,l1))]))

www/schedule.scrbl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,26 @@
2121
(list @wk{9/3}
2222
@seclink["Assignment 1"]{A1}
2323
@elem{@secref["OCaml to Racket"] (cont.)}
24-
@secref["Abscond"])
24+
@itemlist[@item{@secref["Abscond"]} @item{@secref["Blackmail"]}])
2525

2626
(list @wk{9/10}
27-
"A2" @;seclink["Assignment 2"]{A2}
28-
@secref["Blackmail"]
29-
@secref["Con"])
27+
@seclink["Assignment 2"]{A2}
28+
@secref["Con"]
29+
@secref["Dupe"])
3030

3131
(list @wk{9/17}
32-
"A3" @;seclink["Assignment 3"]{A3}
33-
@secref["Dupe"]
34-
@secref["Extort"])
32+
"A3" @;seclink["Assignment 3"]{A3}
33+
@secref["Extort"]
34+
@secref["Fraud"])
3535

3636
(list @wk{9/24}
3737
"A4" @;seclink["Assignment 4"]{A4}
38-
@secref["Fraud"]
39-
@secref["Grift"])
38+
@secref["Grift"]
39+
@secref["Hustle"])
4040

4141
(list @wk{10/1}
4242
"A5" @;seclink["Assignment 5"]{A5}
43-
@secref["Hustle"]
43+
@elem{TBD}
4444
'cont)
4545

4646
(list @wk{10/8}

0 commit comments

Comments
 (0)