Skip to content

Commit e0ee456

Browse files
authored
Merge pull request #205 from cmsc430/fall-2025
Fall 2025
2 parents 4b2da85 + a42fe81 commit e0ee456

File tree

4 files changed

+188
-13
lines changed

4 files changed

+188
-13
lines changed

www/assignments/6.scrbl

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,98 @@
11
#lang scribble/manual
2-
@(require "../defns.rkt")
3-
@title[#:tag "Assignment 6" #:style 'unnumbered]{Assignment 6: List primitives and n-ary primitives}
2+
@(require "../defns.rkt"
3+
"../notes/ev.rkt")
4+
@title[#:tag "Assignment 6" #:style 'unnumbered]{Assignment 6: List and vector primitives}
45

56
@(require (for-label a86 (except-in racket ...)))
67

8+
@(require racket/port)
9+
710
@bold{Due: @assign-deadline[6]}
811

9-
Details of this assignment will be released later in the semester.
12+
@;{ All this to silence some Makefile output on Linux -- should probably be taken care of at the Makefile level }
13+
@(ev '(begin (define p (current-output-port))
14+
(current-output-port (open-output-string))
15+
(require hoax-plus)
16+
(current-output-port p)))
17+
18+
The goal of this assignment is to gain proficiency with our
19+
representation of memory-allocated values by implementing a number of
20+
list and vector primitives.
21+
22+
@section[#:tag-prefix "a6-" #:style 'unnumbered]{Overview}
23+
24+
For this assignment, you are given a @tt{hoax-plus.zip} file on ELMS
25+
with a starter compiler similar to the @seclink["Hoax"]{Hoax}
26+
language we studied in class.
27+
28+
29+
@section[#:tag-prefix "a6-" #:style 'unnumbered]{Hoax+}
30+
31+
The Hoax+ language extends the Hoax language we studied in class with four
32+
new unary primitives:
33+
34+
@itemlist[
35+
@item{@racket[length]: given a list, computes its length.}
36+
@item{@racket[reverse]: given a list, computes a list with elements in the reverse order of the given list.}
37+
@item{@racket[list->vector]: given a list, computes a vector with elements in the order of the given list.}
38+
@item{@racket[vector->list]: given a vector, computes a list with elements in the order of the given vector.}
39+
]
40+
41+
Unlike past assignments, you do not need to bring forward in any
42+
features from earlier assignments.
43+
44+
@section[#:tag-prefix "a6-" #:style 'unnumbered]{List and vector primitves}
45+
46+
47+
The new primitives have been added to the parser and the interpreter.
48+
The behavior of compiled primitives should be consistent with the
49+
interpreter:
50+
51+
@ex[
52+
(interp (parse '(length '())))
53+
(interp (parse '(length (cons 1 (cons 2 '())))))
54+
(interp (parse '(length #f)))
55+
(interp (parse '(reverse '())))
56+
(interp (parse '(reverse (cons 1 (cons 2 '())))))
57+
(interp (parse '(reverse #f)))
58+
(interp (parse '(list->vector '())))
59+
(interp (parse '(list->vector (cons 1 (cons 2 '())))))
60+
(interp (parse '(list->vector #f)))
61+
(interp (parse '(vector->list (make-vector 0 #t))))
62+
(interp (parse '(vector->list (make-vector 2 #t))))
63+
(interp (parse '(vector->list #f)))
64+
]
65+
66+
The interpreter is consistent with Racket's own behavior, so if you're
67+
unsure about what your compiler should do, you can look to Racket (or
68+
the interpreter) for guidance:
69+
70+
@ex[
71+
(length '())
72+
(length (cons 1 (cons 2 '())))
73+
(eval:error (length #f))
74+
(reverse '())
75+
(reverse (cons 1 (cons 2 '())))
76+
(eval:error (reverse #f))
77+
(list->vector '())
78+
(list->vector (cons 1 (cons 2 '())))
79+
(eval:error (list->vector #f))
80+
(vector->list (make-vector 0 #t))
81+
(vector->list (make-vector 2 #t))
82+
(eval:error (vector->list #f))
83+
]
84+
85+
@subsection[#:tag-prefix "a6-" #:style 'unnumbered]{Testing}
86+
87+
A small number of test cases have been provided in
88+
@tt{test/test-runner.rkt}. There is function called @racket[test]
89+
that contains I/O-free test cases and another called @racket[test/io]
90+
that contains I/O tests. To run these tests, @tt{raco test
91+
test/interp.rkt} will test the interpreter and @tt{raco test
92+
test/compile.rkt} will test the compiler. You are encouraged to add
93+
your own tests.
94+
95+
@section[#:tag-prefix "a6-" #:style 'unnumbered]{Submitting}
96+
97+
To submit, use @tt{make} from within the @tt{hoax-plus} directory to
98+
create a zip file containing your work and submit it to Gradescope.

www/defns.rkt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
"Thursday, September 25, 11:59PM"
6060
"Thursday, October 2, 11:59PM"
6161
"Thursday, October 23, 11:59PM"
62-
"Thursday, October 30, 11:59PM"
63-
"Thursday, November 6, 11:59PM"
62+
"Tuesday, November 4, 11:59PM"
63+
"Tuesday, November 11, 11:59PM"
6464
"Thursday, November 20, 11:59PM"
6565
"Thursday, December 4, 11:59PM")
6666
(sub1 i)))

www/notes/diagrams.rkt

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88

99
(define n 40)
1010

11+
(define (make-str-cells s)
12+
(hc-append
13+
(foldl (λ (c p)
14+
(hc-append p
15+
(cc-superimpose (rectangle (/ n 2) n) ((current-code-tt) (string c)))))
16+
(cc-superimpose (rectangle n n) (code #,(string-length s)))
17+
(string->list s))
18+
(if (even? (string-length s))
19+
(rectangle 0 n)
20+
(cc-superimpose (rectangle (/ n 2) n) (code 0)))))
21+
1122
(define (make-imm-cell i)
1223
(cc-superimpose
1324
(code #,i)
@@ -17,6 +28,9 @@
1728
(cb-superimpose (rectangle n n)
1829
(code cons)))
1930

31+
(define (make-str-cell)
32+
(cb-superimpose (rectangle n n)
33+
(code str)))
2034

2135
(define (make-box-cell)
2236
(cb-superimpose (rectangle n n)
@@ -72,13 +86,16 @@
7286
[`(cons ,_) (make-cons-cell)]
7387
[`(box ,_) (make-box-cell)]
7488
[`(vect ,_) (make-vect-cell)]
89+
[`(str ,_) (make-str-cell)]
90+
[(? string?) (make-str-cells v)]
7591
[_ (make-imm-cell v)]))
7692

7793
(define (add-arrows spec cells p)
7894
;(printf "~a~n" spec)
7995
(match spec
8096
['() p]
81-
[(cons `(_ ,i) s)
97+
[(cons `(,_ ,(? integer? i)) s)
98+
8299
(add-arrows s
83100
cells
84101
(fwd-pts-to (list-ref cells (sub1 (- (length cells) (length s))))
@@ -99,17 +116,62 @@
99116
heap)))
100117

101118
(define heap/arrows/label
102-
(vc-append
103-
0
104-
heap/arrows
105-
(text "heap")))
119+
(vc-append 10
120+
(vc-append
121+
0
122+
heap/arrows
123+
(text "heap"))
124+
(text "← lower addresses, higher addresses →")))
106125

107126
(define rax/label
108-
(vc-append 0 rax (text "rax")))
127+
(vc-append 10 (vc-append 0 rax (text "rax"))
128+
(text " ")))
109129

110130
(inset
111-
(fwd-pts-to rax (list-ref heap i) (hc-append n rax/label heap/arrows/label))
112-
(* n 2))]))
131+
(fwd-pts-to rax (list-ref heap i)
132+
(hc-append n rax/label heap/arrows/label))
133+
0 (* n 2) 0 0)]))
134+
135+
#;
136+
(define cons-quiz
137+
(list (make-heap-diagram
138+
'((cons 4)
139+
3
140+
'()
141+
2
142+
(cons 0)
143+
1
144+
(cons 2)))
145+
(make-heap-diagram
146+
'((cons 0)
147+
1
148+
(cons 2)
149+
2
150+
(cons 4)
151+
3
152+
'()))
153+
(make-heap-diagram
154+
'((cons 4)
155+
'()
156+
3
157+
(cons 0)
158+
2
159+
(cons 2)
160+
1))
161+
(make-heap-diagram
162+
'((cons 0)
163+
(cons 2)
164+
1
165+
(cons 4)
166+
2
167+
'()
168+
3))
169+
))
170+
171+
172+
173+
;(text "← lower addresses, higher addresses →")
174+
113175
#;
114176
(make-heap-diagram
115177
'((cons 0)

www/notes/hoax.scrbl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,18 @@ So, suppose we want to create the string @racket["abc"]:
899899
(Pop rbx)
900900
(Ret))))
901901

902+
This creates a string in memory like this:
903+
904+
@make-heap-diagram['((str 0) "abc")]
905+
906+
907+
In this diagram, we use half-sized boxes to indicate that only 4 bytes
908+
are used per codepoint. Also the contents of the array are not
909+
values, but codepoints (shown as the letters the codepoint encodes).
910+
In odd length strings, we write @racket[0] for the padded element, but
911+
in reality there are arbitrary bits at that memory location, which is
912+
fine because they will never be read.
913+
902914
At first glance, this looks remarkably similar to creating a vector,
903915
however there are some imporant things to notice:
904916

@@ -926,6 +938,18 @@ you are seeing here.}
926938

927939
]
928940

941+
Notice that a string like @racket["fred"] is not represented the same
942+
as a vector of characters @racket[#(#\f #\r #\e #\d)], which uses more
943+
space. Compare:
944+
945+
@make-heap-diagram['((str 0) "fred")]
946+
947+
versus:
948+
949+
@make-heap-diagram['((vect 0) 4 #\f #\r #\e #\d)]
950+
951+
952+
929953
Now let's set things up like we did before to be able to interactively
930954
write examples in order to arrive at the code for
931955
@racket[string-length], @racket[string-ref], and @racket[make-string]:

0 commit comments

Comments
 (0)