Homework 10b
MUST BE DONE WITH YOUR (NEW) PARTNER
MUST USE CHECKED-SIGNATURES!
Due Date Thu at 9:00pm (Week 10)
Purpose Add input & memory to calculator
Exercises
We strongly recommend keeping the board code close at hand!
Adding Input
Last time, your eval function accepted a placeholder input. This time, eval should not accept any input up front; instead, it should suspend the computation and prompt the user for input before continuing. This means that eval will not always return a number; it will instead return a Result, which can be either a number (i.e., the final answer, as before) or a suspended computation.
(define-struct input [resume]) ; AInput is a (define AInput (signature [InputOf (Number -> Result)])) ; representing a suspended calculator computation awaiting user input ; a Result is a (define Result (signature (mixed Number AInput))) ; where a Number is a final answer and a AInput is awaiting user input
Exercise 1 Design a function (: resume (AInput Number -> Result)) that continues the computation with the given input.
You can try this out as a thought experiment. What would you return in the e-in case?
; A Cont is a (define Cont (signature (Number -> Result))) ; where the Number is the answer of the previous computation
Exercise 2 Unlike the previous assignment, the order in which you evaluate the program matters. In this assignment, you will evaluate expressions from left to right. In a comment, provide an example program using input where the answer is different if one evaluates left-to-right vs. right-to-left, and say what these answers are.
Exercise 3 Write a helper function (: eval/aux (Exp -> (Cont -> Result))). You should evaluate expressions left-to-right. Take some time to digest this signature; make sure you understand it before diving into the code! Refer to the lecture code if you are stuck.
Exercise 4 Revise eval so that it has the signature (: eval (Exp -> Result)), and revise run so that it has the signature (: run (S-Exp -> Result)) (you needn’t include simplify and compact). You should use run and resume to write tests.
Parsing New Expressions
Now you will add support for memory operations. Extend your Exp grammar to include the follow constructs.
; an (EM+Of Exp) ; represents a program that computes its argument and adds it to the value in memory (define-struct e-m+ [arg]) ; an EMr represents a program that recalls a value from memory (define-struct e-mr []) ; an EMc represents a program that clears the value in memory (sets it to zero) (define-struct e-mc []) ; an Exp is a (define Exp (signature (mixed Number (EOpOf Op Exp Exp) (EM+Of Exp) EMr EMc EIn))) ; representing a calculator program that can prompt for input and manipulate state
'(+ (m+ 5) (+ (mc) (mr)))
Exercise 5 Revise your parse function to handle these new expressions. As before, it should fail gracefully (i.e., with an appropriate error message) if the input is invalid. You should also use this opportunity to fix any bugs in parse from the previous assignment.
Evaluating Memory Operations
Finally, you will add support for evaluating memory operations. As before, you should evaluate expressions left-to-right. Initially, the memory cell has value 0.
Exercise 6 The signatures for eval and run will not change, but the signatures for eval/aux and Cont will change in a significant way. Revise these signatures so that they support threading the current memory cell through the computation. Then revise the existing cases in eval/aux to be consistent with its new signature. Finally, revise eval to provide the initial value of the memory cell, which is 0.
Exercise 7 Revise eval/aux to include support for m+. It adds its argument to the current value of the memory cell, but returns 0 as the answer. For example,(check-expect (run '(+ (m+ 5) (+ (m+ 2) (mr)))) 7)
Exercise 8 Revise eval/aux to include support for mr. It does not change the current value of the memory cell and returns the memory’s value as the answer.
Exercise 9 Revise eval/aux to include support for mc. It clears the current value of the memory cell and returns 0 as the answer. For example, (check-expect (run ’(+ (m+ 5) (+ (mc) (mr)))) 0)
Exercise 10 Write lots of tests! You should use all of the helper functions at your disposal, and also use quasiquoting to build larger examples out of smaller ones.