diff --git a/www/assignments/3.scrbl b/www/assignments/3.scrbl index 725d49a6..331409e3 100644 --- a/www/assignments/3.scrbl +++ b/www/assignments/3.scrbl @@ -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 } to - test only @tt{}.} +@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 diff --git a/www/assignments/4.scrbl b/www/assignments/4.scrbl index 4babf9ef..fd9bc46a 100644 --- a/www/assignments/4.scrbl +++ b/www/assignments/4.scrbl @@ -76,31 +76,24 @@ 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: @@ -108,16 +101,16 @@ 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))].} ] @@ -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 } to - test only @tt{}.} ] Note that only a small number of tests are given to you, so you should