Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 13 additions & 45 deletions www/assignments/3.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -110,66 +110,34 @@ ASTs using this representation:
(Lit 4)) (Lit 5))],}
]

@subsection[#:tag-prefix "a3-" #:style 'unnumbered]{Implementing primitives}
@section[#:tag-prefix "a3-" #:style 'unnumbered]{Steps toward Dupe+}

Implement the primitives as described earlier.
Implement the new expression forms as described earlier, both for the
interpreter and compiler.

There are many ways to implement these at the assembly level. You should try implementing
these using the limited a86 instruction set.

To do this, you should:
@itemlist[
@item{Study @tt{ast.rkt} to understand how these new forms of expression are represented.}

@item{Study @tt{parse.rkt} and add support for parsing these
expressions. (See @secref[#:tag-prefixes '("a3-")]{parse} for guidance.)}

@item{Update @tt{interp-prim.rkt} and @tt{interp.rkt} to correctly interpret these expressions.}

@item{Make examples of these primitives and potential translations of them
to assembly.}

@item{Update @tt{compile.rkt} to correctly compile these expressions.}

@item{Check your implementation by running the tests in @tt{test/all.rkt}.}
]

@section[#:tag-prefix "a3-" #:style 'unnumbered]{Implementing cond}

Implement the @racket[cond] expression form as described earlier.
To do this, you should:

@itemlist[
@item{Study @tt{ast.rkt} to understand how these new forms of
expression are represented.}

@item{Update @tt{interp-prim.rkt} and @tt{interp.rkt} to correctly interpret @racket[cond] expressions.}

@item{Make examples of @racket[cond]-expressions and potential translations of them
to assembly.}

@item{Update @tt{compile.rkt} to correctly compile @racket[cond]
expressions based on your examples.}
@item{Add test cases to @tt{test/test-runner.rkt}. These will be
tested with both the interpreter and compiler.}

@item{Check your implementation by running the tests in @tt{test/all.rkt}.}
]

@section[#:tag-prefix "a3-" #:style 'unnumbered]{Testing}
@item{Update @tt{interp-prim.rkt} and @tt{interp.rkt} to correctly
interpret @racket[cond] expressions and new primitives.}

You can test your code in several ways:
@item{Test your interpreter with @tt{raco test test/interp.rkt}.}

@itemlist[
@item{Make examples of @racket[cond]-expressions and primitives and
potential translations of them to assembly.}

@item{Using the command line @tt{raco test .} from
the directory containing the repository to test everything.}
@item{Update @tt{compile.rkt} and @tt{compile-prim.rkt} to correctly
compile these expressions based on your examples.}

@item{Using the command line @tt{raco test <file>} to
test only @tt{<file>}.}
@item{Test your compiler with @tt{raco test test/compile.rkt}.}
]

Note that only a small number of tests are given to you, so you should
write additional test cases.

@section[#:tag-prefix "a3-" #:style 'unnumbered]{Submitting}

To submit, use @tt{make} from within the @tt{dupe-plus} directory to
Expand Down
57 changes: 22 additions & 35 deletions www/assignments/4.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -76,48 +76,41 @@ For that reason, let us give you a strong hint for a potential design
of the ASTs and examples of how parsing could work. You are not
required to follow this design, but you certainly may.

Here's a potential AST definition for the added primitives,
@racket[cond], and @racket[case]:
Here's the AST definition for @racket[case]:

@#reader scribble/comment-reader
(racketblock
;; type Expr =
;; ...
;; | (Case Expr [Listof CaseClause] Expr)

;; type CaseClause = (Clause [Listof Datum] Expr)
;; type Expr = ...
;; | (Case Expr [Listof [Listof Datum]] [Listof Expr] Expr)

;; type Datum = Integer | Boolean

(struct Case (e cs el) #:prefab)
(struct Case (e ds cs el) #:prefab)
)

There is one new kind of expression constructor: @racket[Case]. A
@racket[Case] AST node contains three things: an expression that is
the subject of the dispatch (i.e. the expression that is evaluated to
determine which clause should be taken), a list of case-clauses (not
to be confused with cond-clauses), and an @racket[else]-clause
expression. Each case-clause, like a cond-clause, consists of two
things. Hence we re-use the @racket[Clause] structure, but with
different types of elements. The first element is a list of
@emph{datums}, each being either an integer or a boolean.
@racket[Case] AST node contains four things: an expression that is the
subject of the dispatch (i.e. the expression that is evaluated to
determine which clause should be taken), a list of lists of datums, an
equal length list of expressions, and an @racket[else]-clause
expression. A @emph{datum} is either an integer or a boolean.

Here are some examples of how concrete expressions are parsed into
ASTs using this representation:

@itemlist[

@item{@racket[(case (add1 3) [else 2])] parses as @racket[(Case (Prim1
'add1 (Lit 3)) '() (Lit 2))].}
'add1 (Lit 3)) '() '() (Lit 2))].}

@item{@racket[(case 4 [(4) 1] [else 2])] parses as @racket[(Case (Lit
4) (list (Clause (list 4) (Lit 1))) (Lit 2))],}
4) (list (list 4)) (list (Lit 1)) (Lit 2))],}

@item{@racket[(case 4 [(4 5 6) 1] [else 2])] parses as @racket[(Case (Lit
4) (list (Clause (list 4 5 6) (Lit 1))) (Lit 2))], and}
4) (list (list 4 5 6)) (list (Lit 1)) (Lit 2))], and}

@item{@racket[(case 4 [(4 5 6) 1] [(#t #f) 7] [else 2])] parses as @racket[(Case (Lit
4) (list (Clause (list 4 5 6) (Lit 1)) (Clause (list #t #f) (Lit 7))) (Lit 2))].}
4) (list (list 4 5 6) (list #t #f)) (list (Lit 1) (Lit 7)) (Lit 2))].}
]


Expand All @@ -129,30 +122,24 @@ To do this, you should:
@itemlist[
@item{Study @tt{ast.rkt} to understand how this new form of expression is represented.}

@item{Add test cases to @tt{test/test-runner.rkt}. These will be
tested with both the interpreter and compiler.}

@item{Update @tt{interp.rkt} to correctly interpret @racket[case] expressions.}

@item{Bring forward all of the changes you made to the interpreter from @secref{a3-dupe-plus}.}

@item{Test your interpreter with @tt{raco test test/interp.rkt}.}

@item{Make examples of @racket[case]-expressions and potential translations of them
to assembly.}

@item{Update @tt{compile.rkt} to correctly compile @racket[case] expressions based on your examples.}

@item{Bring forward all the changes you made for @secref{a3-dupe-plus}.}

@item{Check your implementation by running the tests in @tt{test/all.rkt}.}
]


@section[#:tag-prefix "a4-" #:style 'unnumbered]{Testing}

You can test your code in several ways:

@itemlist[
@item{Bring forward all of the changes you made to the compiler from @secref{a3-dupe-plus}.}

@item{Using the command line @tt{raco test .} from
the directory containing the repository to test everything.}
@item{Test your interpreter with @tt{raco test test/compile.rkt}.}

@item{Using the command line @tt{raco test <file>} to
test only @tt{<file>}.}
]

Note that only a small number of tests are given to you, so you should
Expand Down