Skip to content

Commit 600e710

Browse files
committed
Assign 5.
1 parent a8e51d3 commit 600e710

3 files changed

Lines changed: 255 additions & 1 deletion

File tree

www/assignments.scrbl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
@include-section{assignments/2.scrbl}
88
@include-section{assignments/3.scrbl}
99
@include-section{assignments/4.scrbl}
10+
@include-section{assignments/5.scrbl}

www/assignments/5.scrbl

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#lang scribble/manual
2+
@title[#:tag "Assignment 5" #:style 'unnumbered]{Assignment 5: A Heap of Characters}
3+
4+
@(require (for-label (except-in racket ...)))
5+
@(require "../notes/fraud-plus/semantics.rkt")
6+
@(require redex/pict)
7+
8+
@(require "../notes/ev.rkt")
9+
10+
@bold{Due: Thurs, Oct 3, 11:59PM}
11+
12+
@(define repo "https://classroom.github.com/a/Qsw0mqpL")
13+
14+
The goal of this assignment is to extend a compiler with data types
15+
that require memory allocation and dereferencing.
16+
17+
Assignment repository:
18+
@centered{@link[repo repo]}
19+
20+
You are given a repository with a starter compiler similar to the
21+
@seclink["Hustle"]{Hustle} language we studied in class. You are tasked
22+
with:
23+
24+
@itemlist[
25+
26+
@item{incorporating the Fraud+ features you added in
27+
@seclink["Assignment 4"]{Assignment 4},}
28+
29+
@item{extending the language to include a string data type,}
30+
31+
@item{implementing a number of primitives,}
32+
33+
@item{updating the parser to work for Hustle+.}
34+
35+
]
36+
37+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{From Fraud+ to Hustle+}
38+
39+
Implement all the features of Fraud+, extended to Hustle+.
40+
41+
42+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{Strung out}
43+
44+
In the last assignment, you implemented a character data type for
45+
representing single letters. In this assignment, you will implement a
46+
String data type for representing arbitrarily long sequences of
47+
characters.
48+
49+
Strings are disjoint from all other data types and are essentially a
50+
fixed-size array of characters. Literal strings are written by
51+
enclosing the characters within the string in double quotes (@tt{"}).
52+
Strings can include double quotes by using the escape sequence
53+
@tt{\"}.
54+
55+
You must add the following operations to Hustle+:
56+
57+
@itemlist[
58+
@item{@code[#:lang "racket"]{string? ; Any -> Boolean}, which determines if its argument is a string.}
59+
@item{@code[#:lang "racket"]{string-ref ; String Natural -> Char}, which
60+
extracts the character at the given index (using 0-based counting). An error is signalled if
61+
the index is out of bounds for the given string.}
62+
@item{@code[#:lang "racket"]{string-length ; String -> Natural}, which computes the length of the string.}
63+
@item{@code[#:lang "racket"]{make-string ; Natural Char -> Natural}, which constructs a string of the given
64+
length, filled with the given character.}
65+
]
66+
67+
The run-time system has been updated to account for a string type. It
68+
assumes a representation where the length of the string is stored in
69+
memory, followed by the characters of the string, in order. You are
70+
free to change the representation if you'd like, but you will have to
71+
update the run-time system to properly print strings. Otherwise, no
72+
changes to the run-time system should be necessary.
73+
74+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{More operations}
75+
76+
Add the following operations to the Hustle+ language:
77+
78+
@itemize[
79+
80+
@item{@code[#:lang "racket"]{box? ; Any -> Boolean}, which determines
81+
if a value is a box.}
82+
83+
@item{@code[#:lang "racket"]{empty? ; Any -> Boolean}, which
84+
determines if a value is the empty list.}
85+
86+
@item{@code[#:lang "racket"]{cons? ; Any -> Boolean}, which determines
87+
if a value is a pair.}
88+
89+
@item{@code[#:lang "racket"]{= ; Number Number -> Boolean}, which determines if
90+
two numbers are equal.}
91+
92+
@item{@code[#:lang "racket"]{< ; Number Number -> Boolean}, which determines if
93+
the first number is less than the second.}
94+
95+
@item{@code[#:lang "racket"]{<= ; Number Number -> Boolean}, which determines if
96+
the first number is less than or equal to the second.}
97+
98+
@item{@code[#:lang "racket"]{char=? ; Number Number -> Boolean}, which determines if
99+
two characters are equal.}
100+
101+
@item{@code[#:lang "racket"]{boolean=? ; Boolean Boolean -> Boolean}, which determines if
102+
two booleans are equal.}
103+
104+
]
105+
106+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{Extending your Parser, yet again!}
107+
108+
109+
Extend your Fraud+ parser for the Hustle+ language based on the following
110+
grammar:
111+
112+
@verbatim{
113+
<expr> ::= integer
114+
| character
115+
| boolean
116+
| variable
117+
| string
118+
| ( <compound> )
119+
| [ <compound> ]
120+
121+
<compound> ::= <prim1> <expr>
122+
| <prim2> <expr> <expr>
123+
| if <expr> <expr> <expr>
124+
| cond <clause>* <else>
125+
| let <bindings> <expr>
126+
127+
<prim1> ::= add1 | sub1 | abs | - | zero? | integer->char | char->integer
128+
| char? | integer? | boolean? | string? | box? | empty? | cons?
129+
| box | unbox | car | cdr | string-length
130+
131+
<prim2> ::= make-string | string-ref | = | < | <=
132+
| char=? | boolean=? | +
133+
134+
<clause> ::= ( <expr> <expr> )
135+
| [ <expr> <expr> ]
136+
137+
<else> ::= ( else <expr> )
138+
| [ else <expr> ]
139+
140+
<bindings> ::= ( <binding>* )
141+
| [ <binding>* ]
142+
143+
<binding> ::= ( variable <expr> )
144+
| [ variable <expr> ]
145+
}
146+
147+
There is a lexer given to you in @tt{lex.rkt}, which provides two
148+
functions: @racket[lex-string] and @racket[lex-port], which consume a
149+
string or an input port, respectively, and produce a list of tokens,
150+
which are defined as follows (only the new parts are shown):
151+
152+
@#reader scribble/comment-reader
153+
(racketblock
154+
; type Token =
155+
; ...
156+
; | `(prim1 ,Prim1)
157+
; | `(prim2 ,Prim2)
158+
; | String
159+
160+
; type Prim1 =
161+
; | 'add1
162+
; | 'sub1
163+
; | 'zero?
164+
; | 'abs
165+
; | '-
166+
; | 'integer->char
167+
; | 'char->integer
168+
; | 'char?
169+
; | 'boolean?
170+
; | 'integer?
171+
; | 'string?
172+
; | 'box?
173+
; | 'empty?
174+
; | 'cons?
175+
; | 'box
176+
; | 'unbox
177+
; | 'car
178+
; | 'cdr
179+
; | 'string-length
180+
181+
; type Prim2 =
182+
; | 'make-string
183+
; | 'string-ref
184+
; | '=
185+
; | '<
186+
; | '<=
187+
; | 'char=?
188+
; | 'boolean=?
189+
; | '+
190+
; | '-
191+
)
192+
193+
The lexer will take care of reading the @tt{#lang racket} header and
194+
remove any whitespace.
195+
196+
You must complete the code in @tt{parse.rkt} to implement the parser
197+
which constructs an s-expression representing a valid Hustle+
198+
expression, if possible, from a list of tokens. The @racket[parse]
199+
function should have the following signature and must be provided by
200+
the module:
201+
202+
@#reader scribble/comment-reader
203+
(racketblock
204+
;; parse : [Listof Token] -> Expr
205+
)
206+
207+
As an example, @racket[parse] should produce @racket['(add1 (sub1 7))]
208+
if given
209+
210+
@racketblock['(lparen (prim1 add1) lparen (prim1 sub1) 7 rparen rparen eof)]
211+
212+
You should not need to make any changes to @tt{lex.rkt}.
213+
214+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{Testing}
215+
216+
You can test your code in several ways:
217+
218+
@itemlist[
219+
220+
@item{Using the command line @tt{raco test .} from
221+
the directory containing the repository to test everything.}
222+
223+
@item{Using the command line @tt{raco test <file>} to
224+
test only @tt{<file>}.}
225+
226+
@item{Pushing to github. You can
227+
see test reports at:
228+
@centered{@link["https://travis-ci.com/cmsc430/"]{
229+
https://travis-ci.com/cmsc430/}}
230+
231+
(You will need to be signed in in order see results for your private repo.)}]
232+
233+
Note that only a small number of tests are given to you, so you should
234+
write additional test cases.
235+
236+
@bold{There is separate a repository for tests!} The testing set-up
237+
is slightly different for this assignment. There is a whole other
238+
repository that contains tests. When you push your code, Travis will
239+
automatically run your code against the tests. If you would like to
240+
run the tests locally, clone the following repository into the
241+
directory that contains your compiler and run @tt{raco test .} to test
242+
everything:
243+
244+
@centered{@tt{https://github.com/cmsc430/assign05-test.git}}
245+
246+
This repository will evolve as the week goes on, but any time there's
247+
a significant update it will be announced on Piazza.
248+
249+
@section[#:tag-prefix "a5-" #:style 'unnumbered]{Submitting}
250+
251+
Pushing your local repository to github ``submits'' your work. We
252+
will grade the latest submission that occurs before the deadline.
253+

www/schedule.scrbl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
@secref["Hustle"])
4040

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

0 commit comments

Comments
 (0)