Due by class time Tuesday, October 12
In class, we included support in our interpreter for the equality and inequality operators == and !=. For example:
(meaning '(c == 3)) → #t (meaning '((1 + 1) == 2)) → #t (meaning '((c + c) == (2 * c))) → #t (meaning '(pi == 3)) → #f (meaning '((1 + 1) != 2)) → #f (meaning '((1 + 1) != 3)) → #t (meaning '(pi != 3)) → #t
Add support for the comparison operators > and < to the interpreter. For example:
(meaning '(pi < 3)) → #f (meaning '((2 + 3) < (2 * 3))) → #t (meaning '(pi > 3)) → #t (meaning '((2 + 2) > 4)) → #f
We also added the boolean constants True and False to the initial environment. However, what happens when we try to compare these values directly using our == and != operators?
(meaning '(True == True)) (meaning '(False == False)) (meaning '(True != False)) (meaning '(True != True))
Fix the interpreter so that the == and != operators can be used to compare values of any type.
The version of extend that we wrote in class creates a list of (symbol value) bindings to represent an environment. For example:
(define env1 (extend '(a b c) '(5 4 0) (extend '(x y) '(15 3) empty-env))) env1 → ((a 5) (b 4) (c 0) (x 15) (y 3))However, a more useful approach is to represent an environment as a list of frames, where each frame is a list containing a list of variables and a corresponding list of values. Replace your extend function with the new version shown below, which supports this new representation of environments:
(define extend (lambda (new-vars new-vals env) (let ([new-frame (list new-vars new-vals)]) (cons new-frame env))))Redefining the environment env1 as shown above will now build a list containing two frames (the first frame is highlighted in red and the second frame in blue):
env1 → (((a b c) (5 4 0)) ((x y) (15 3)))
Using this new representation of environments, write the functions (first-frame-vars env) and (first-frame-vals env), each of which takes an environment and retrieves the list of variables or values from the first frame of the environment. For example:
(first-frame-vars env1) → (a b c) (first-frame-vals env1) → (5 4 0)
Write the function (retrieve var frame-vars frame-vals), which takes a variable var, a list of frame variables frame-vars, and a list of frame values frame-vals, and retrieves the value corresponding to var from frame-vals. You may assume that var will appear somewhere in frame-vars, and that frame-vars and frame-vals will be lists of the same length. For example:
(retrieve 'b '(a b c d) '(1 2 3 4)) → 2 (retrieve 'd '(a b c d) '(1 2 3 4)) → 4 (retrieve 'z '(z y x) '(30 20 10)) → 30 (retrieve 'x '(z y x) '(30 20 10)) → 10 (retrieve 's '(p q r s t) '(6 2 9 0 5)) → 0
Using your functions first-frame-vars, first-frame-vals, and retrieve as helper functions, write a new version of (lookup var env) that works with this new representation of environments. Hint: member? will also be useful as a helper. For example:
(lookup 'c env1) → 0 (lookup 'a env1) → 5 (lookup 'x env1) → 15 (lookup 'y env1) → 3
Write the function (frame-index var env), which returns the zero-based index number of the first frame of env that contains variable var. Use your helper functions to improve the readability of your code. For example:
(define env2 (extend '(a b) '(1 2) (extend '(x y z) '(10 20 30) (extend '(p q r s t) '(6 2 9 0 5) empty-env)))) (frame-index 'b env2) → 0 (frame-index 'x env2) → 1 (frame-index 's env2) → 2 (frame-index 'p env2) → 2 (frame-index 'z env2) → 1
Save all of your function definitions in a single Scheme file called assign9.scm and submit it using the Homework Upload Site. Make sure to include your name and the assignment number in a comment at the top of your file.
If you have questions about anything, don't hesitate to ask!