CS 2135: Lab 6

Either continue working on lab 5 or try the following problem on the web programming material.


Rewrite this program so that prompt-read, prompt-read-many, request-toppings, display-order, and order-pizza can be implemented as scripts. In other words, move all calls to these into script position.

Include the define-script macro in your file so you can test your solution.

(define abort #f) 
(let/cc grab-abort 
  (set! abort grab-abort))
(define-syntax define-script 
  (syntax-rules () 
    [(define-script (script-name arg ...) body)
     (define (script-name arg ...) 
       (abort body))]))

(When you have finished this exercise, return to lab 5).

;;;;; some random helper functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (prompt-read promptstr)
  (begin (printf "~a " promptstr) (read)))

(define (prompt-read-many plist) (map prompt-read plist))

(define (display-many strlist) (for-each printf strlist))
(define (sum alon) (foldl + 0 alon))

;;;;; the pizza helper functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; base-pizza-cost : symbol symbol -> number
;; compute cost of pizza without toppings 
(define (base-pizza-cost style size)
  (cond [(eq? style 'thin) (cond [(eq? size 'small) 8]
				 [(eq? size 'medium) 10]
				 [(eq? size 'large) 12])]
        [(eq? style 'stuffed) (cond [(eq? size 'medium) 12]
				    [(eq? size 'large) 14])]))
;; topping-cost : list[symbol] -> number
;; calculates total charge for the given toppings
(define (topping-cost toppings)
  (sum (map (lambda (topping)
         (cond [(memq topping '(chicken sausage pepperoni)) 1.25]
               [else .75])) toppings)))

;; request-toppings : -> list[symbol]
;; prompts user to enter any number of pizza toppings
(define (request-toppings)
  (local ((define reply (prompt-read "Enter a topping [or none to quit]")))
     (cond [(symbol=? reply 'none) empty]
	   [else (cons reply (request-toppings))])))

;; display-order : list[symbol] list[symbol] list[symbol] -> void
;; prints order summary from entered information
(define (display-order contact order toppings)
  (let ([name (first contact)]
        [address (second contact)]
        [pickdel (third contact)]
        [style (first order)]
        [size (second order)])
    (display-many (list (format "You ordered a ~a ~a pizza with ~a~n" size style toppings)
			(cond [(eq? pickdel 'pickup) (format "You will pick up your pizza~n")]
			      [(eq? pickdel 'delivery)
			       (format "We will deliver your pizza to ~a~n" address)])
			(format "Your total cost is $~a ~n"
				(+ (base-pizza-cost style size)
				   (topping-cost toppings)))))))
;; order-pizza : -> void
;; runs the pizza program
(define (order-pizza)
  (display-order (prompt-read-many (list "Enter your name:"
					 "Enter your address:"
					 "Pickup or Delivery?:"))
		 (prompt-read-many (list "Do you want thin or stuffed pizza?"
					 "What size do you want (small, medium, large)?"))