Problem Set 07
Last updated: Tue, 3 Mar 2015 10:47:20 -0500
DUE: Monday 3/2/2015, 9pm EST
Preliminaries
You must use the Intermediate Student with lambda language to complete this assignment. Select it via the Choose Language... menu located at the bottom-left of the DrRacket window.
Put all your solution files in a directory named set07 in your repository.
Download extras.rkt to this directory (right-click and choose "Save As"; don’t copy and paste) and commit it as well.
Use begin-for-test and rackunit to define your examples and tests.
- Don’t forget to tell us how many hours you spent working on the assignment. This should be a global variable called TIME-ON-TASK in each file. For example:
(define TIME-ON-TASK 10.5) ; hours
- So each solution file must have at least the following at the top:
(require "extras.rkt") (require rackunit) (define TIME-ON-TASK <number-of-hours-you-spent>) - After you’ve submitted your solution, use a web browser to go to https://github.ccs.neu.edu/ and check that your repository contains the following files:
set07/pretty.rkt
set07/extras.rkt
Git Commit Requirement: For this assignment, you must have at least three well-labeled git commits (including the final commit). A well-labeled git commit accurately and succinctly describes the changes since the previous commit. Something like "commit2", or "home work 3" is not an acceptable git commit label. Failure to meet this requirement will result in loss of points.
Make sure to satisfy the requirements for Accumulators if you use any.
1 Pretty Printing
1.1 Additional Preliminaries
(check-location "07" "pretty.rkt")
1.2 Problem Description
; An Expr is one of: ; - Integer ; - (make-add (cons Expr NEListOf<Expr>) Boolean) ; - (make-mul (cons Expr NEListOf<Expr>) Boolean) ; Represents a numeric expression that is either an integer, or an addition ; or multiplication of two or more expressions. ; The Boolean flag indicates whether the expression uses infix or prefix notation. (define-struct add (exprs infix?)) (define-struct mul (exprs infix?))
; expr->strings : Expr Natural -> ListOf<String> ; Returns a rendering of exp as a sequence of lines, ; where each line is a string not longer than width characters. ; EFFECT: errors if expr cannot fit width (define (expr->strings expr width) ...)
Numbers are rendered with number->string.
Compound expressions are rendered with surrounding parentheses.
There are no spaces immediately inside open and closing parentheses.
An expression is rendered as a single line if it fits within the specified width.
- Infix expressions are rendered with an operator between each expression and a space between an operator and each subexpression.
(check-equal? (expr->strings (make-add (list 1 2 3) true) 11) (list "(1 + 2 + 3)") "infix, single line") - Prefix expressions are rendered with only one operator at the beginning and a space separating each subexpression, like in Racket.
(check-equal? (expr->strings (make-add (list 1 2 3) false) 100) (list "(+ 1 2 3)") "prefix, single line") - If an expression cannot be rendered on one line, it should be stacked across multiple lines.
There are no spaces before a new line.
Parentheses should never go on their own line.
- Infix expressions are stacked with each operator on its own line and subexpressions and operators of that expression at the same left alignment. This may require indenting subexpressions with spaces, depending on how many surrounding parentheses there are.
(check-equal? (expr->strings (make-add (list 10 20 30) true) 7) (list "(10" " +" " 20" " +" " 30)") "infix stacking") - Prefix expressions are stacked such that the first line has the operator and the first subexpression. All other subexpressions should be on their own line, indented with spaces to align with the first subexpression.
(check-equal? (expr->strings (make-add (list 10 20 30) false) 7) (list "(+ 10" " 20" " 30)") "prefix stacking") - An expression may have mixed infix and prefix notation expressions.
(define EXAMPLE (make-add (list (make-mul (list 1 2) true) (make-add (list 3 4) false)) true)) (begin-for-test (check-equal? (expr->strings EXAMPLE 100) (list "((1 * 2) + (+ 3 4))") "unstacked") (check-equal? (expr->strings EXAMPLE 9) (list "((1 * 2)" " +" " (+ 3 4))") "one level stacking") (check-equal? (expr->strings EXAMPLE 8) (list "((1 * 2)" " +" " (+ 3" " 4))") "two level stacking (1 subexpression)") (check-equal? (expr->strings EXAMPLE 7) (list "((1" " *" " 2)" " +" " (+ 3" " 4))") "two level stacking (2 subexpressions)"))
- If an expression cannot be rendered, even with stacking, then the function should report an appropriate error message. Use the error function to report an error. To test erroring function calls, use check-error.
(check-error (expr->strings EXAMPLE 4) "doesn't fit")
; display-strings! : ListOf<String> -> Void ; EFFECT: Prints the given list of strings, one per line.