Skip to content

Commit 031483a

Browse files
authored
Merge pull request #36 from dvanhorn/next
Next
2 parents 32b4696 + 9c2919f commit 031483a

5 files changed

Lines changed: 228 additions & 26 deletions

File tree

www/midterms.scrbl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ date of the midterm.
1111
@item{Midterm 2: @bold{@m2-date}}
1212
]
1313

14+
@include-section["midterms/1.scrbl"]

www/midterms/1.scrbl

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
#lang scribble/manual
2+
3+
@(require (for-label racket))
4+
5+
@title{Midterm 1}
6+
7+
@bold{Due: Tues, Oct 8, 11:59PM}
8+
9+
@(define repo "https://classroom.github.com/a/-N-q7mJ7")
10+
11+
Midterm repository:
12+
@centered{@link[repo repo]}
13+
14+
The repository contains a single plaintext file @tt{m1.txt}, which you
15+
can edit to submit your answers to the following questions. Your
16+
submision must be pushed by midnight on Tuesday.
17+
18+
During the 48 hours of the exam period, you may only ask private
19+
questions on Piazza if you need assistance for the course staff. You
20+
may not comminicate or collaborate with any one else about the content
21+
of this exam.
22+
23+
@section{Short answer}
24+
25+
@bold{Question 1}
26+
27+
[10 points]
28+
29+
Briefly describe the difference, if any, between these two Asm instructions:
30+
31+
@verbatim{
32+
(mov rax rbx)
33+
}
34+
35+
@verbatim{
36+
(mov rax (offset rbx 0))
37+
}
38+
39+
@bold{Question 2}
40+
41+
[10 points]
42+
43+
Briefly describe the difference, if any, between these two Asm instructions:
44+
45+
@verbatim{
46+
(mov rax (offset rbx 0))
47+
}
48+
49+
@verbatim{
50+
(mov (offset rbx 0) rax)
51+
}
52+
53+
@section{Representation}
54+
55+
@bold{Question 3}
56+
57+
[20 points]
58+
59+
When studying the @secref{Dupe} language, we used the least
60+
significant bit of a 64-bit integer to indicate whether the value
61+
being represented was an integer (tagged with @code[#:lang
62+
"racket"]{#b0}) or a boolean (tagged with @code[#:lang
63+
"racket"]{#b1}).
64+
65+
Cosider the following alternative design: @racket[#t] is represented
66+
by the number 0, @racket[#f] is represented by the number 1. All other
67+
numbers beside 0 and 1 are used to represent integers.
68+
69+
@itemlist[
70+
71+
@item{Describe one way in which this design is worse that the tagging
72+
approach.}
73+
74+
@item{Describe on way in which this design is better.}
75+
76+
@item{Describe, at a high-level in English, how you could implement
77+
@racket[add1] using this design.}
78+
79+
]
80+
81+
@section{Interpreting Boolean connectives}
82+
83+
@bold{Question 4}
84+
85+
[25 points]
86+
87+
Consider the following interpreter from @secref{Extort}.
88+
89+
@#reader scribble/comment-reader
90+
(racketblock
91+
;; type Answer = Value | 'err
92+
93+
;; Expr -> Answer
94+
(define (interp e)
95+
(match e
96+
[(? integer? i) i]
97+
[(? boolean? b) b]
98+
[`(add1 ,e0)
99+
(match (interp e0)
100+
[(? integer? i) (add1 i)]
101+
[_ 'err])]
102+
[`(sub1 ,e0)
103+
(match (interp e0)
104+
[(? integer? i) (sub1 i)]
105+
[_ 'err])]
106+
[`(zero? ,e0)
107+
(match (interp e0)
108+
[(? integer? i) (zero? i)]
109+
[_ 'err])]
110+
[`(if ,e0 ,e1 ,e2)
111+
(match (interp e0)
112+
['err 'err]
113+
[v
114+
(if v
115+
(interp e1)
116+
(interp e2))])]))
117+
118+
)
119+
120+
Now extend the interpreter to include @racket[and] and @racket[or]
121+
connectives similar to those found in Racket.
122+
123+
The @racket[or] form takes any number of subexpressions. The
124+
subexpressions are evaluated from left to right until a subexpression
125+
evaluates to a non-@racket[#f] value, which is produces by the
126+
@racket[or]. If no such subexpression exists, then @racket[#f] is
127+
produced.
128+
129+
The @racket[and] form is similar. It takes any number of
130+
subexpressions. The subexpressions are evaluated from left to right
131+
until a subexpression evaluates to a @racket[#f] value, which is
132+
produced by @racket[and]. Otherwise, @racket[and] produces the value
133+
of the last subexpression. If there are no subexpressions, then
134+
@racket[#f] is produced.
135+
136+
To make things interesting, you should not use Racket's @racket[and]
137+
and @racket[or] in @racket[interp].
138+
139+
@section{Compiling a new primitive operation}
140+
141+
@bold{Question 5}
142+
143+
[35 points]
144+
145+
Consider the following excerpt of a compiler that is able to compile
146+
the @racket[cons] primitive and empty lists @racket['()]. The
147+
relevant representation information is given as is the function for
148+
compiling @racket[cons]:
149+
150+
@#reader scribble/comment-reader
151+
(racketblock
152+
153+
(define result-shift 3)
154+
(define result-type-mask (sub1 (arithmetic-shift 1 result-shift)))
155+
(define type-imm #b000)
156+
(define type-pair #b010)
157+
158+
(define imm-shift (+ 2 result-shift))
159+
(define imm-type-empty (arithmetic-shift #b11 result-shift))
160+
161+
;; Expr Expr CEnv -> Asm
162+
(define (compile-cons e0 e1 c)
163+
(let ((c0 (compile-e e0 c))
164+
(c1 (compile-e e1 (cons #f c))))
165+
`(,@c0
166+
(mov (offset rsp ,(- (add1 (length c)))) rax)
167+
,@c1
168+
(mov (offset rdi 0) rax)
169+
(mov rax (offset rsp ,(- (add1 (length c)))))
170+
(mov (offset rdi 1) rax)
171+
(mov rax rdi)
172+
(or rax ,type-pair)
173+
(add rdi 16))))
174+
)
175+
176+
Now suppose a @racket[map-add1] operation is added to the language
177+
which takes a single argument, which must be a list of numbers. The
178+
operation adds one to each element of the list and produces a list of
179+
the results. In other words, @racket[(map-add1 _xs)] should produce
180+
what @racket[(map add1 _xs)] produces in Racket.
181+
182+
Write a @racket[compile-map-add1] function that compiles an expression
183+
of the form @racket[(map-add1 _e0)]:
184+
185+
@#reader scribble/comment-reader
186+
(racketblock
187+
188+
;; Expr CEnv -> Asm
189+
(define (compile-map-add1 e0 c)
190+
...)
191+
)
192+
193+
You may use any of the x86 registers as scratch registers, with the
194+
exception of @racket['rsp] and @racket['rdi] which need to point to
195+
the stack and heap, respectively.
196+

www/notes/iniquity.scrbl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ Using this function, we can touch up our code:
398398
ret)))
399399
)
400400

401+
402+
@section[#:tag-prefix "iniquity"]{A Compiler for Iniquity}
403+
401404
The last piece of the puzzle is the function for emitting code for a
402405
complete program:
403406

www/notes/iniquity/compile.rkt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
(match p
3838
[(list 'begin `(define (,fs . ,xss) ,es) ... e0)
3939
(let ((ds (compile-defines fs xss es))
40-
(c0 (compile-l e0)))
40+
(c0 (compile-entry e0)))
4141
`(,@c0
4242
,@ds))]
43-
[e (compile-l e)]))
43+
[e (compile-entry e)]))
4444

4545
;; Expr -> Asm
46-
(define (compile-l e)
46+
;; Compile e as the entry point
47+
(define (compile-entry e)
4748
`(entry
4849
,@(compile-e e '())
4950
ret
@@ -330,5 +331,3 @@
330331
"_"
331332
(number->string (eq-hash-code s) 16))))
332333

333-
334-

www/notes/iniquity/interp.rkt

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
(interp-env e '() ds)]
1515
[e (interp-env e '() '())]))
1616

17-
;; Expr REnv (Listof Defn) -> Integer
17+
;; Expr REnv (Listof Defn) -> Answer
1818
(define (interp-env e r ds)
1919
(match e
2020
[''() '()]
2121
[(? value? v) v]
2222
[(list (? prim? p) es ...)
23-
(let ((as (interp-env* es r ds)))
24-
(interp-prim p as))]
23+
(match (interp-env* es r ds)
24+
[(list vs ...) (interp-prim p vs)]
25+
[_ 'err])]
2526
[`(if ,e0 ,e1 ,e2)
2627
(match (interp-env e0 r ds)
2728
['err 'err]
@@ -50,16 +51,17 @@
5051

5152
;; (Listof Defn) Symbol -> Defn
5253
(define (defns-lookup ds f)
53-
(findf (λ (d) (eq? (first (second d)) f))
54+
(findf (match-lambda [`(define (,g . ,_) ,_) (eq? f g)])
5455
ds))
5556

56-
;; [Listof Expr] REnv -> [Listof Answer]
57+
;; (Listof Expr) REnv -> (Listof Value) | 'err
5758
(define (interp-env* es r ds)
5859
(match es
5960
['() '()]
6061
[(cons e es)
61-
(cons (interp-env e r ds)
62-
(interp-env* es r ds))]))
62+
(match (interp-env e r ds)
63+
['err 'err]
64+
[v (cons v (interp-env* es r ds))])]))
6365

6466
;; Any -> Boolean
6567
(define (prim? x)
@@ -76,21 +78,22 @@
7678
(value? (car x))
7779
(value? (cdr x)))))
7880

79-
;; Prim [Listof Answer] -> Answer
80-
(define (interp-prim p as)
81-
(match (cons p as)
82-
[(list p (? value?) ... 'err _ ...) 'err]
83-
[(list 'add1 (? integer? i0)) (+ i0 1)]
84-
[(list 'sub1 (? integer? i0)) (- i0 1)]
81+
;; Prim (Listof Value) -> Answer
82+
(define (interp-prim p vs)
83+
(match (cons p vs)
84+
[(list 'add1 (? integer? i0)) (add1 i0)]
85+
[(list 'sub1 (? integer? i0)) (sub1 i0)]
8586
[(list 'zero? (? integer? i0)) (zero? i0)]
86-
[(list '+ (? integer? i0) (? integer? i1)) (+ i0 i1)]
87-
[(list '- (? integer? i0) (? integer? i1)) (- i0 i1)]
88-
[(list 'box v0) (box v0)]
89-
[(list 'unbox (? box? v0)) (unbox v0)]
90-
[(list 'empty? v0) (empty? v0)]
91-
[(list 'cons v0 v1) (cons v0 v1)]
92-
[(list 'car (cons v0 v1)) v0]
93-
[(list 'cdr (cons v0 v1)) v1]
87+
[(list 'box v0) (box v0)]
88+
[(list 'unbox (? box? v0)) (unbox v0)]
89+
[(list 'empty? v0) (empty? v0)]
90+
[(list 'cons v0 v1) (cons v0 v1)]
91+
[(list 'car (cons v0 v1)) v0]
92+
[(list 'cdr (cons v0 v1)) v1]
93+
[(list '+ (? integer? i0) (? integer? i1))
94+
(+ i0 i1)]
95+
[(list '- (? integer? i0) (? integer? i1))
96+
(- i0 i1)]
9497
[_ 'err]))
9598

9699
;; Env Variable -> Answer

0 commit comments

Comments
 (0)