diff --git a/www/assignments.scrbl b/www/assignments.scrbl index 51caaca9..721834a9 100644 --- a/www/assignments.scrbl +++ b/www/assignments.scrbl @@ -4,10 +4,10 @@ @local-table-of-contents[#:style 'immediate-only] @include-section{assignments/1.scrbl} -@include-section{assignments/2.scrbl} -@include-section{assignments/3.scrbl} -@include-section{assignments/4.scrbl} -@include-section{assignments/5.scrbl} +@; @include-section{assignments/2.scrbl} +@; @include-section{assignments/3.scrbl} +@; @include-section{assignments/4.scrbl} +@; @include-section{assignments/5.scrbl} @;include-section{assignments/6.scrbl} @;;include-section{assignments/7.scrbl} diff --git a/www/assignments/1.scrbl b/www/assignments/1.scrbl index 0038f63b..b4d1d229 100644 --- a/www/assignments/1.scrbl +++ b/www/assignments/1.scrbl @@ -1,7 +1,7 @@ #lang scribble/manual @title[#:tag "Assignment 1" #:style 'unnumbered]{Assignment 1: Racket Primer} -@bold{Due: Monday, February 5, 11:59PM} +@bold{Due: Monday, June 3, 11:59PM} The goal of this assignment is to gain practice programming in Racket. diff --git a/www/defns.rkt b/www/defns.rkt index 3ca4b580..195b6cc7 100644 --- a/www/defns.rkt +++ b/www/defns.rkt @@ -1,63 +1,69 @@ #lang racket (provide (all-defined-out)) -(require scribble/core scribble/html-properties scribble/manual) +(require scribble/core scribble/html-properties scribble/manual) ;(define prof1 (link "https://jmct.cc" "José Manuel Calderón Trilla")) ;(define prof1-pronouns "he/him") ;(define prof1-email "jmct@cs.umd.edu") ;(define prof1-initials "JMCT") -(define prof1 (link "https://www.cs.umd.edu/~dvanhorn/" "David Van Horn")) +;; (define prof1 (link "https://www.cs.umd.edu/~dvanhorn/" "David Van Horn")) +;; (define prof1-pronouns "he/him") +;; (define prof1-email "dvanhorn@cs.umd.edu") +;; (define prof1-initials "DVH") + +(define prof1 (link "https://www.cs.umd.edu/~anwar/" "Anwar Mamat")) (define prof1-pronouns "he/him") -(define prof1-email "dvanhorn@cs.umd.edu") -(define prof1-initials "DVH") +(define prof1-email "anwar@cs.umd.edu") +(define prof1-initials "AM") -(define semester "spring") +(define semester "summer") (define year "2024") (define courseno "CMSC 430") (define lecture-dates "" #;"May 30 -- July 7, 2023") -(define IRB "IRB") +(define IRB "IRB") (define AVW "AVW") (define KEY "KEY") -(define m1-date "March 6") -(define m2-date "April 17") +(define m1-date "June 12") +(define m2-date "June 26") (define midterm-hours "24") -(define final-date "May 14") -(define elms-url "https://umd.instructure.com/courses/1359023") +(define final-date "July 5") +(define elms-url "https://umd.instructure.com/courses/1365875") (define racket-version "8.11") (define staff - (list (list "Henry Blanchette" "blancheh@umd.edu") - (list "Pierce Darragh" "pdarragh@umd.edu") - (list "Advait Kushe" "akushe@terpmail.umd.edu") - (list "Deena Postol" "dpostol@umd.edu") - (list "William Wegand" "wwegand@terpmail.umd.edu") - (list "Kazi Tasnim Zinat" "kzintas@umd.edu") - #;(list "Fuxiao Liu" "fl3es@umd.edu") - #;(list "Vivian Chen" "vchen8@terpmail.umd.edu") - #;(list "Ian Morrill" "imorrill@terpmail.umd.edu") - #;(list "Matthew Schneider" "mgl@umd.edu") - #;(list "Rhea Jajodia" "rjajodia@terpmail.umd.edu") - #;(list "Syed Zaidi" "szaidi@umd.edu") - #;(list "William Wegand" "wfweg@verizon.net") - #;(list "Wilson Smith" "smith@umd.edu") - #;(list "Yuhwan Lee" "ylee9251@terpmail.umd.edu") + (list (list "Pierce Darragh" "pdarragh@umd.edu") + (list "Bora Faber" "kfaber@terpmail.umd.edu") + (list "Sriman Selvakumaran" "srimans@umd.edu") + #;(list "Advait Kushe" "akushe@terpmail.umd.edu") + #;(list "Deena Postol" "dpostol@umd.edu") + #;(list "William Wegand" "wwegand@terpmail.umd.edu") + #;(list "Kazi Tasnim Zinat" "kzintas@umd.edu") + #;(list "Fuxiao Liu" "fl3es@umd.edu") + #;(list "Vivian Chen" "vchen8@terpmail.umd.edu") + #;(list "Ian Morrill" "imorrill@terpmail.umd.edu") + #;(list "Matthew Schneider" "mgl@umd.edu") + #;(list "Rhea Jajodia" "rjajodia@terpmail.umd.edu") + #;(list "Syed Zaidi" "szaidi@umd.edu") + #;(list "William Wegand" "wfweg@verizon.net") + #;(list "Wilson Smith" "smith@umd.edu") + #;(list "Yuhwan Lee" "ylee9251@terpmail.umd.edu") )) ;(define lecture-schedule1 "MW, 2:00-3:15pm") -(define lecture-schedule1 "MW, 3:30-4:45pm") +(define lecture-schedule1 "MTuThF, 9:30AM-10:45AM EST") -(define classroom1 "HJP 0226") +(define classroom1 "Virtual") ;(define discord "TBD") -(define piazza "https://piazza.com/class/lrs6masma6h2o1/") -(define gradescope "https://www.gradescope.com/courses/723511") +(define piazza "https://piazza.com/class/lwjac3ritxf1z/") +(define gradescope "https://www.gradescope.com/courses/787806") -(define feedback "https://docs.google.com/forms/d/e/1FAIpQLSc80xQELhHb_Ef-tn0DkpH2b6pYadQiT3aYSEJFNqEqBjzdGg/viewform?usp=sf_link") +#;(define feedback "https://docs.google.com/forms/d/e/1FAIpQLSc80xQELhHb_Ef-tn0DkpH2b6pYadQiT3aYSEJFNqEqBjzdGg/viewform?usp=sf_link") diff --git a/www/main.scrbl b/www/main.scrbl index 67b56f93..8824bb9f 100644 --- a/www/main.scrbl +++ b/www/main.scrbl @@ -40,19 +40,19 @@ implement several related languages. #;(list prof2 prof2-email) staff)] -@bold{Office hours:} AVW 4140 +@bold{Office hours location:} Virtual @tabular[#:style 'boxed #:row-properties '(bottom-border ()) - (list (list @bold{Time} @bold{Monday} @bold{Tuesday} @bold{Wednesday} @bold{Thursday} @bold{Friday}) - (list "9 AM" 'cont "Deena" "Deena" 'cont 'cont) - (list "10 AM" 'cont "Deena" "Deena" 'cont 'cont) - (list "11 AM" "Advait" 'cont "Advait" 'cont 'cont) - (list "12 PM" 'cont 'cont "Pierce" 'cont 'cont) - (list "1 PM" "Kazi" "Kazi" "Pierce" 'cont 'cont) - (list "2 PM" "Kazi" "Kazi" 'cont "Henry" "Henry") - (list "3 PM" 'cont 'cont 'cont "Henry" "Henry") - (list "4 PM" 'cont "William" 'cont "William" 'cont))] + (list (list @bold{Start Time} @bold{Monday} @bold{Tuesday} @bold{Wednesday} @bold{Thursday} @bold{Friday}) + (list "9 AM" 'cont 'cont 'cont 'cont 'cont) + (list "10 AM" 'cont 'cont 'cont 'cont 'cont) + (list "11 AM" 'cont 'cont 'cont 'cont 'cont) + (list "12 PM" 'cont 'cont 'cont 'cont 'cont) + (list "1 PM" "Pierce" "Pierce" "Pierce" "Pierce" "Pierce") + (list "2 PM" 'cont 'cont 'cont 'cont 'cont) + (list "3 PM" 'cont 'cont 'cont 'cont 'cont) + (list "4 PM" 'cont 'cont 'cont 'cont 'cont))] @bold{Communications:} @link[@elms-url]{ELMS}, @link[@piazza]{Piazza} @@ -66,8 +66,8 @@ this material. change. Any substantive change will be accompanied with an announcement to the class via ELMS. -@bold{Feedback:} We welcome anonymous feedback on the course and its -staff using this @link[feedback]{form}. +@; @bold{Feedback:} We welcome anonymous feedback on the course and its +@; staff using this @link[feedback]{form}. @include-section{syllabus.scrbl} @include-section{texts.scrbl} diff --git a/www/midterms.scrbl b/www/midterms.scrbl index 04a07052..112935b1 100644 --- a/www/midterms.scrbl +++ b/www/midterms.scrbl @@ -7,8 +7,10 @@ exams. Exams will be distributed at least @midterm-hours hours before the due date of the midterm. @itemlist[ - @item{@secref["Midterm_1"], due @m1-date} - @item{@secref["Midterm_2"], due @m2-date} + @;@item{@secref["Midterm_1"], due @m1-date} + @item{Midterm 1, due @m1-date} + @;@item{@secref["Midterm_2"], due @m2-date} + @item{Midterm 2, due @m2-date} ] @include-section["midterms/1.scrbl"] diff --git a/www/project.scrbl b/www/project.scrbl index bcb3d327..5060d1cf 100644 --- a/www/project.scrbl +++ b/www/project.scrbl @@ -10,497 +10,6 @@ @title[#:tag "Project" #:style '(unnumbered)]{Project} The final assessment for this course consists of an individually -completed project. - -@bold{Due: Tuesday, May 14, 3:30PM EST} - -@section[#:style 'unnumbered]{Arity Checking, Rest Arguments, Case Functions, and Apply} - - - -@(ev `(current-directory ,(path->string (build-path notes "iniquity-plus")))) -@(for-each (λ (f) (ev `(require (file ,f)))) - '("ast.rkt" "parse.rkt" "interp.rkt")) - - - -The goal of this assignment is to extend a compiler with arity -checking for function calls, to add new kinds of function parameter -features, and to add the @racket[apply] form for applying a function -to a list of arguments. - -You are given a file @tt{iniquity-plus.zip} on ELMS with a starter -compiler similar to the @seclink["Iniquity"]{Iniquity} language we -studied in class. You are tasked with: - -@itemlist[ - -@item{implementing run-time arity checking for function calls,} - -@item{extending function definitions to include ``rest argument'' -parameters for writing variable-arity functions,} - -@item{extending function definitions to include -@racket[case-lambda]-style multiple-arity functions,} - -@item{extending the arity checking features to handle these new forms -of function definitions, and} - -@item{implementing the @racket[apply] mechanism for applying a function -to the elements of a list as arguments.} -] - -Unlike previous assignments, you do not need to bring forward your -past features to this language; there is no need to implement -@racket[cond], @racket[case], etc. - -Be sure to read the entire problem description before starting. There -are a number of @secref[#:tag-prefixes '("proj-")]{Suggestions} on how to -approach the assignment near the end. - - -@section[#:tag-prefix "proj-" #:style 'unnumbered #:tag "arity"]{Checking arity} - -In @seclink["Iniquity"]{Iniquity}, we implemented a language with -function definitions and calls. We noted that bad things can happen -when a function is called with the incorrect number of arguments. -While it's possible to statically check this property of Iniquity -programs, it's not possible in more expressive languages and arity -checking must be done at run-time. You are tasked with implementing -such a run-time arity checking mechanism. - -Here is the basic idea. You need to add a run-time checking mechanism -that will cause the following program to signal an error: - -@#reader scribble/comment-reader -(racketblock -(define (f x y) (+ x y)) -(f 1) -) - -The function call knows how many arguments are given and the function -definition knows how many argument are expected. The generated code -should check that these two quantities match when the function is called. - -A simple way to do this is to pick a designated register that will be -used for communicating arity information. The caller should set the -register to the number of arguments before jumping to the function. -The function should check this number against the expected number and -signal an error when they don't match. - - -You should modify @racket[compile-app] and @racket[compile-define] to -implement this part of the assignment. - -@section[#:tag-prefix "proj-" #:style 'unnumbered #:tag "rest"]{Rest -arguments} - -Many languages including JavaScript, C, and Racket provide facilities -for defining functions that take a ``rest argument'' which allows the -function to be called with more arguments than expected and these -additional arguments will be bound to a single value that collects all -of these arguments. In Iniquity, as in Racket, the obvious way of -collecting these arguments into a single value is to use a list. - -Here are some examples: - -@itemlist[ - -@item{@racket[(define (f . xs) ...)]: this function takes @emph{any} number -of arguments and binds @racket[xs] to a list containing all of them,} - -@item{@racket[(define (f x . xs) ...)]: this function takes @emph{at -least} one argument and binds @racket[x] to the first argument and -@racket[xs] to a list containing the rest. It's an error to call this function -with zero arguments.} - -@item{@racket[(define (f x y z . xs) ...)]: this function takes -@emph{at least} three arguments and binds @racket[x], @racket[y], and -@racket[z] to the first three arguments and @racket[xs] to a list -containing the rest. It's an error to call this function with 0, 1, -or 2 arguments.} -] - -Here are some examples in Racket to get a sense of the behavior: - -@ex[ -(define (f . xs) (list xs)) -(f) -(f 1) -(f 1 2) -(f 1 2 3) -(f 1 2 3 4) -(define (f x . xs) (list x xs)) -(eval:error (f)) -(f 1) -(f 1 2) -(f 1 2 3) -(f 1 2 3 4) -(define (f x y z . xs) (list x y z xs)) -(eval:error (f)) -(eval:error (f 1)) -(eval:error (f 1 2)) -(f 1 2 3) -(f 1 2 4) -] - -The code generated for a function call should not change---other than -what you did for @secref[#:tag-prefixes '("proj-") "arity"]: it should -pass all of the arguments on the stack along with information about -the number of arguments. - -The compilation of function definitions that use a rest argument -should generate code that checks that the given number of arguments is -acceptable and should generate code to pop all ``extra'' arguments off -the stack and construct a list which is then bound to the rest -parameter. - -It is worth remembering that arguments are pushed on the stack in such -a way that the last argument is the element most recently pushed on -the stack. This has the benefit of making it easy to pop off the -extra arguments and to construct a list with the elements in the -proper order. - -HINT: the function definition knows the number of ``required'' -arguments, i.e. the minimum number of arguments the function can be -called with---call this @math{m}---and the caller communicates how -many actual arguments have been supplied---call this @math{n}. The -compiler needs to generate a loop that pops @math{n-m} times, -constructing a list with with popped elements, and then finally pushes -this list in order to bind it to the rest parameter. - -@section[#:tag-prefix "proj-" #:style 'unnumbered #:tag "case-lambda"]{Arity dispatch} - -Some languages such as Java, Haskell, and Racket make it possible to -overload a single function name with multiple definitions where the -dispatch between these different definitions is performed based on the -number (or kind) of arguments given at a function call. - -In Racket, this is accomplished with the @racket[case-lambda] form for -constructing multiple-arity functions. - -Here is an example: - -@ex[ -(define f - (case-lambda - [(x) "got one!"] - [(p q) "got two!"])) - -(f #t) -(f #t #f) -(eval:error (f #t #f 0)) -] - -This function can accept @emph{either} one or two arguments. If given -one argument, it evaluates the right-hand-side of the first clause -with @racket[x] bound to that argument. If given two arguments, it -evaluates the right-hand-side of the second clause with @racket[p] and -@racket[q] bound to the arguments. If given any other number of -arguments, it signals an error. - -A @racket[case-lambda] form can have any number of clauses (including -zero!) and the first clause for which the number of arguments is -acceptable is taken when the function is called. - -Note that @racket[case-lambda] can be combined with rest arguments too. -A clause that accepts any number of arguments is written by simply -listing a parameter name (no parentheses). A clause that accepts some -non-zero minimum number of parameters is written with a dotted -parameter list. - -For example: - -@ex[ -(define f - (case-lambda - [(x y z . r) (length r)] - [(x) "just one!"])) - -(f 1 2 3 4 5 6) -(f #t) -(eval:error (f)) -(eval:error (f 1 2))] - -This function takes three or more arguments @emph{or} one argument. Any -other number of arguments (i.e. zero or two) results in an error. - -@ex[ -(define f - (case-lambda - [(x y z) "three!"] - [xs (length xs)])) - -(f) -(f 1 2) -(f 1 2 3) -(f 1 2 3 4 5 6) -] - -This function takes any number of arguments, but when given three, it -produces @racket["three!"]; in all other cases it produces the number -of arguments. - -@section[#:tag-prefix "proj-" #:style 'unnumbered #:tag "apply"]{Apply} - -Apply is the yin to the yang of rest arguments (or maybe the other way -around). Whereas a rest argument lets a function take arbitrarily -more arguments and packages them up as a list, @racket[apply] will -apply a function to a list as though the elements of the list were -given as arguments. - -@ex[ -(define (f x y) (+ x y)) -(apply f (list 1 2)) -(define (flatten ls) - (apply append ls)) -(flatten (list (list 1 2) (list 3 4 5) (list 6))) -(define (sum ls) - (apply + ls)) -(sum (list 5 6 7 8)) -] - -Here you can see @racket[apply] taking two things: a function and -single argument which is a list. It is calling the function with the -elements of the list as the arguments. - -It turns out, @racket[apply] can also take other arguments in addition -to the list and pass them along to the function. - -@ex[ -(define (f x y) (+ x y)) -(apply f 1 (list 2)) -(apply list 1 2 3 4 (list 5 6 7)) -] - -Note that if the function expects a certain number of arguments and the list has -a different number of elements, it results in an arity error: - -@ex[ -(define (f x y) (+ x y)) -(eval:error (apply f (list 1 2 3))) -] - -A new form of expression has been added to the @tt{Expr} AST type: - -@#reader scribble/comment-reader -(racketblock -;; type Expr = ... -;; | (Apply Id [Listof Expr] Expr) -) - -The parser has been updated to handle concrete syntax of the form: - -@#reader scribble/comment-reader -(racketblock -(apply _f _e0 ... _en) -) - -@ex[ -(parse-e '(apply f x y zs)) -] - -Note that the AST for an @racket[apply] expression has the function -name, an arbitrarily long list of arguments, plus a distinguished last -argument that should produce a list. (It is an error if this expression -produces anything other than a list.) - -While it's allowable to have only the function and the list argument, -it's a syntax error to leave off a list argument altogether: - -@ex[ -(parse-e '(apply f xs)) -(eval:error (parse-e '(apply f))) -] - -The interpreter also handles @racket[apply] expressions: - -@ex[ -(interp (parse '[ (define (f x y) (cons y x)) - (apply f (cons 1 (cons 2 '()))) ])) -] - -Together with rest arguments, @racket[apply] makes it possible to -write many functions you may like to use: - -@#reader scribble/comment-reader -(ex -(interp - (parse - '[;; an append that works on any number of lists - (define (append . xss) - (if (empty? xss) - '() - (if (empty? (car xss)) - (apply append (cdr xss)) - (cons (car (car xss)) - (apply append (cdr (car xss)) (cdr xss)))))) - ;; the list function! - (define (list . xs) xs) - - (append (list 1 2 3) (list 4) (list 5 6 7))]))) - -In @tt{compile.rkt}, the @racket[compile-e] has an added case for -@racket[Apply] AST nodes and calls @racket[compile-apply], which is -stubbed out for you. You will need to implement @racket[apply] there. - -Here is the idea for @racket[apply]: it is doing something similar to -a function call, so it needs to make a label for the return point and -push that on the stack. It then needs to execute all of the given -arguments, pushing them on the stack (again just like a regular -function call). Then it needs to execute the distinguished list -argument and generate code that will traverse the list at run-time, -pushing elements on to the stack until reaching the end of the list. -At this point, all of the arguments, both those given explicitly and -those in the list are on the stack. Jump to the function. - - -@section[#:tag-prefix "proj-" #:style 'unnumbered]{Representing the -syntax of function definitions} - -The @seclink["Iniquity"]{Iniquity} language has a single function -definition form: @racket[(define (_f _x ...) _e)] which is represented -with the following AST type: - -@#reader scribble/comment-reader -(racketblock -;; type Defn = (Defn Id (Listof Id) Expr) -(struct Defn (f xs e) #:prefab) -) - -Because there are three different forms of function definition in -Iniquity+, we use the following AST representation: - -@#reader scribble/comment-reader -(racketblock -;; type Defn = (Defn Id Fun) -(struct Defn (f fun) #:prefab) - -;; type Fun = (FunPlain [Listof Id] Expr) -;; | (FunRest [Listof Id] Id Expr) -;; | (FunCase [Listof FunCaseClause]) -;; type FunCaseClause = (FunPlain [Listof Id] Expr) -;; | (FunRest [Listof Id] Id Expr) -(struct FunPlain (xs e) #:prefab) -(struct FunRest (xs x e) #:prefab) -(struct FunCase (cs) #:prefab) -) - -What used to be represented as @racket[(Defn _f _xs _e)] is now -represented as @racket[(Defn _f (FunPlain _xs _e))]. - - -The parser already works for these new forms of function definitions. -Here are some examples of how function definitions are parsed, but you -are encouraged to try out more to get a better sense: - -@ex[ -(parse-define '(define (f x) x)) -(parse-define '(define (f . xs) xs)) -(parse-define '(define (f x y z . q) q)) -(parse-define - '(define f - (case-lambda - [(x y) 2] - [(z) 1] - [(a b c . d) "3+"] - [q "other"]))) -] - -@section[#:tag-prefix "proj-" #:style 'unnumbered]{Starter code} - -The compiler code given to you is just an implementation of Iniquity, -but updated to parse the new forms of function definitions and -re-organized slightly to match the new AST representation. - -The interpreter code given to you works on the full Iniquity+ -language, so you do not need to update @racket[interp.rkt] and can use -the interpreter to guide your implementation of the compiler. - -@ex[ -(interp - (parse '[(define (f x) x) - (f 1)])) -(interp - (parse '[(define (f . x) x) - (f 1)])) -(interp - (parse '[(define (f . x) x) - (f)])) -(interp - (parse '[(define (f . x) x) - (f 1 2 3 4 5)])) -(interp - (parse '[(define f - (case-lambda - [(x y) 2] - [(z) 1] - [(a b c . d) "3+"] - [q "other"])) - (cons (f 7) - (cons (f 3 4) - (cons (f) - (cons (f 7 8 9 10 11) - '()))))])) -] - - -Thus, you should only need to modify @racket[compile.rkt]. - -A small number of test cases are given as usual. - - -@section[#:tag-prefix "proj-" #:style 'unnumbered]{Suggestions} - -This is a tricky project. The amount of code you have to write is -pretty small, however you may spend a long time slogging through the -project if your approach is to hack first, think later. - -Here are some suggestions for how to approach the project. Make -sure you get each of the pieces working before moving on. - -@itemlist[ - -@item{Start with @secref[#:tag-prefixes '("proj-") "arity"]; this should -be pretty easy. Make sure it works for plain function definitions.} - -@item{Move on to @secref[#:tag-prefixes '("proj-") "rest"]. You could -start by emitting code that checks that the arguments are acceptable, -popping the appropriate number of arguments off (and ignoring the -elements), then pushing the empty list. This will work like a rest arg -in that it should accept any number of arguments beyond the required -minimum, but the rest argument will always be bound to empty. Once -working, try to modify the code to build a list as it pops arguments. -Test that it works.} - -@item{Next you could either tackle @racket[apply] or -@racket[case-lambda].} - -@item{For @secref[#:tag-prefixes '("proj-") -"case-lambda"], remember that you have a compiler for plain and rest -argument functions at this point. That should come in handy. Think -of @racket[case-lambda] as generating a set of function definitions -(with generated names), and then the main work of @racket[case-lambda] -is determing which of the generated functions to call, given the -specific number of arguments passed in by the caller. When you find -the function that fits, jump to it. You might start by only handling -plain function clauses in @racket[case-lambda] before moving on to -handling rest argument functions, too.} - -@item{For @secref[#:tag-prefixes '("proj-") "apply"], at first don't -worry about arity checking and consider the case where there are no -explicit arguments given, i.e. focus on @racket[(apply _f _e)]. Once -you have that working, consider the more general case of -@racket[(apply _f _e0 ... _e)]. Then figure out how to add in the -arity checking part. Finally, make sure you're detecting error cases -such as when @racket[_e] is not a proper list.} - -] - -@section[#:tag-prefix "proj-" #:style 'unnumbered]{Submitting} - -Submit a zip file containing your work to Gradescope. Use @tt{make -submit.zip} from within the @tt{iniquity-plus} directory to create a zip -file with the proper structure. - +completed project. More details will be released later in the semester. +@bold{Due: Friday, July 5, 11:59PM EST} diff --git a/www/schedule.scrbl b/www/schedule.scrbl index a5844237..537018ee 100644 --- a/www/schedule.scrbl +++ b/www/schedule.scrbl @@ -1,5 +1,5 @@ #lang scribble/manual -@(require scribble/core racket/list) +@(require scribble/core scribble/html-properties racket/list) @(require "defns.rkt") @title[#:style 'unnumbered]{Schedule} @@ -17,133 +17,150 @@ @tabular[#:style 'boxed #:sep @hspace[1] #:row-properties '(bottom-border) - (list (list @bold{Week} - @bold{Due} - @bold{Monday} - @bold{Wednesday}) - - (list @wk{1/22} - "" - "No class" - @secref["Intro"]) - - - (list @wk{1/29} - "" - @elem{@secref["OCaml to Racket"]} - @elem{@secref["OCaml to Racket"]}) - - (list @wk{2/5} - @seclink["Assignment 1"]{A1} - @elem{@secref["a86"]} - @elem{@secref["a86"]}) - - (list @wk{2/12} - @seclink["Assignment 2"]{A2} - @itemlist[@item{@secref["Abscond"]} - @item{@secref["Blackmail"]}] - @itemlist[@item{@secref["Con"]} - @item{@secref["Dupe"]}]) - - (list @wk{2/19} - @elem{@seclink["Assignment 2"]{A3} P1} - @itemlist[@item{@secref["Dodger"]} - @item{@secref["Evildoer"]}] - @secref["Evildoer"]) - - (list @wk{2/26} - @elem{@seclink["Assignment 2"]{A3} P2} - @secref{Extort} - @secref{Fraud}) - - (list @wk{3/4} - "" - @secref{Fraud} - @secref["Midterm_1"]) - - (list @wk{3/11} - "" - @secref{Fraud} - @secref{Hustle}) - (list @wk{3/18} - "" - @elem{Spring Break} - @elem{Spring Break}) - (list @wk{3/25} - @elem{@seclink["Assignment 4"]{A4} P1} - @secref{Hustle} - @secref{Hustle}) - - (list @wk{4/1} - @elem{@seclink["Assignment 4"]{A4} P2} - @secref{Hoax} - @secref{Iniquity}) - - (list @wk{4/8} - "" - @secref{Iniquity} - @secref{Iniquity}) - - - (list @wk{4/15} - "" - @secref{Knock} - @secref["Midterm_2"]) - - - (list @wk{4/22} - "" - @secref{Jig} - @secref{Loot}) - - (list @wk{4/29} - @elem{@seclink["Assignment 5"]{A5}} - @secref{Loot} - @secref{Mug}) - - (list @wk{5/6} - "" - @secref{Neerdowell} - @secref{Outlaw}) - -)] - -@;{ -@tabular[#:style 'boxed -#:sep @hspace[1] -#:row-properties '(bottom-border) -(list (list @bold{Date} @bold{Topic} @bold{Due}) -(list @day{5/30} @secref["Intro"] "") -(list @day{5/31} @secref["OCaml to Racket"] "") -(list @day{6/1} @secref["a86"] "") -(list @day{6/2} @secref["Abscond"] @seclink["Assignment 1"]{A1}) -(list @day{6/5} @itemlist[@item{@secref["Blackmail"]} @item{@secref["Con"]}] @seclink["Assignment 2"]{A2}) -(list @day{6/6} @itemlist[@item{@secref["Dupe"]} @item{@secref{Dodger}}] "") -(list @day{6/7} @secref["Evildoer"] "") -(list @day{6/8} @secref["Extort"] "") -(list @day{6/9} @secref["Fraud"] "") -(list @day{6/12} @secref["Hustle"] @seclink["Assignment 3"]{A3}) -(list @day{6/13} @secref["Hoax"] "") -(list @day{6/14} "Midterm 1" @secref["Midterm_1"]) -(list @day{6/15} @secref["Iniquity"] "") -(list @day{6/16} @elem{@secref["Iniquity"], cont.} "") -(list @day{6/19} @elem{Juneteenth Holiday} "") -(list @day{6/20} @secref["Jig"] @seclink["Assignment 4"]{A4}) -(list @day{6/21} @secref["Knock"] "") -(list @day{6/22} @elem{@secref["Knock"], cont.} "") -(list @day{6/23} @secref["Loot"] "") -(list @day{6/26} @elem{@secref["Loot"], cont.} "") -(list @day{6/27} @elem{GC} @seclink["Assignment 5"]{A5}) -(list @day{6/28} @secref["Mug"] "") -(list @day{6/29} "Midterm 2" @secref["Midterm_2"]) -(list @day{6/30} @secref["Mountebank"] "") -(list @day{7/3} @secref["Neerdowell"] @seclink["Assignment 6"]{A6}) -(list @day{7/4} "Independence Day Holiday" "") -(list @day{7/5} @secref["Outlaw"] "") -(list @day{7/6} @elem{@secref["Outlaw"], cont.} "") -(list @day{7/7} "Slack" @secref{Project}) -) -] -} + #:column-properties '(center ()) + + @; TODO: I wanted to make the week indicator stretch multiple rows, + @; but scribble's [tabular] form doesn't seem to support this. + + @; #:cell-properties @append*[(make-list 2 (cons (list (attributes '((rowspan . "5")))) + @; (make-list (sub1 (* 5 4)) '())))] + + @; #:cell-properties @append*[(make-list 2 (list (list (attributes '((rowspan . "5")))) '() '() '() '()))] + + (list (list @bold{Week} @bold{Date} @bold{Topic} @bold{Due}) + + (list @wk{1} + @day{5/27} + "No class." + "") + (list "" + @day{5/28} + @secref{Intro} + "") + (list "" + @day{5/29} + "No class (Wednesday)." + "") + (list "" + @day{5/30} + @elem{@secref{OCaml to Racket}} + "") + (list "" + @day{5/31} + @elem{@secref{a86}} + "") + + (list @wk{2} + @day{6/3} + @secref{Abscond} + @seclink["Assignment 1"]{A1}) + (list "" + @day{6/4} + @itemlist[@item{@secref{Blackmail}} + @item{@secref{Con}}] + "") + (list "" + @day{6/5} + "No class (Wednesday)." + "") + (list "" + @day{6/6} + @itemlist[@item{@secref{Dupe}} + @item{@secref{Dodger}}] + "") + (list "" + @day{6/7} + @secref{Evildoer} + "") + + (list @wk{3} + @day{6/10} + @secref{Extort} + @;@seclink["Assignment 2"]{A2} + "A2") + (list "" + @day{6/11} + @secref{Fraud} + "") + (list "" + @day{6/12} + "No class (midterm, Wednesday)." + @;@seclink["Midterm 1"]{Midterm 1} + "Midterm 1") + (list "" + @day{6/13} + @secref{Hustle} + "") + (list "" + @day{6/14} + @secref{Hoax} + "") + + (list @wk{4} + @day{6/17} + @secref{Iniquity} + @;@seclink["Assignment 3"]{A3} + "A3") + (list "" + @day{6/18} + @elem{@secref{Iniquity}, cont.} + "") + (list "" + @day{6/19} + "No class (Juneteenth, Wednesday)." + "") + (list "" + @day{6/20} + @secref{Jig} + "") + (list "" + @day{6/21} + @secref{Knock} + "") + + (list @wk{5} + @day{6/24} + @elem{@secref{Knock}, cont.} + @;@seclink["Assignment 4"]{A4} + "A4") + (list "" + @day{6/25} + @secref{Loot} + "") + (list "" + @day{6/26} + "No class (midterm, Wednesday)." + @;@seclink["Midterm 2"]{Midterm 2} + "Midterm 2") + (list "" + @day{6/27} + @elem{@secref{Loot}, cont.} + "") + (list "" + @day{6/28} + "Garbage collection." + "") + + (list @wk{6} + @day{7/1} + @secref{Mug} + @;@seclink["Assignment 5"]{A5} + "A5") + (list "" + @day{7/2} + @secref{Mountebank} + "") + (list "" + @day{7/3} + "No class (Wednesday)." + "") + (list "" + @day{7/4} + @secref{Neerdowell} + "") + (list "" + @day{7/5} + @secref{Outlaw} + @secref{Project}))] @bold{Final project assessment: @|final-date|.}