CS 131 Homework 6

Due by the beginning of class Wednesday, March 8

For this assignment, you should use parser-with-define.ss, interpreter-with-define.ss, and environments-with-references.ss as your starting point. You can ignore the string parser.

  1. Read sections 3.7-3.9 (pages 98-123) of the textbook.

  2. Study the list-structure parser, interpreter, and environment code we developed in class this week and last week. Our current version of the interpreter supports variable assignments and definitions, as well as begin and collect expressions.

  3. Modify the list-structure parser to handle let, letrec, and fun expressions containing multiple bodies. In a multi-body let, letrec, or fun, the body expressions are evaluated sequentially, and the value of the last expression is returned. The easiest approach is to just have the parser create a single begin-exp record to hold the body expressions. This way the interpreter doesn't need to change, since it already handles begin. For a letrec, you'll also need to allow for multi-body function declarations. Examples:

    > (start)
    
    Welcome to the CS 131 Scheme interpreter
    
    ==> (let ((x 1) (y 2))
          (print x)
          (print y)
          (x + y))
    1
    2
    3
    
    ==> (let ((x 0))
          (letrec
    	 ((fact (n) ->
                (print n)
                (if (n = 0) 1 (n * (fact (n - 1))))))
            (print x)
            (x := 5)
            (fact x)))
    0
    5
    4
    3
    2
    1
    0
    120
    
  4. Add support for a new primitive called range to the interpreter. Range can take one or two arguments:

    Do not change the parser for this problem. Instead, add range to the initial environment as a new primitive function, like sqrt, print, etc. Examples:

    ==> (range 10)
    (0 1 2 3 4 5 6 7 8 9)
    
    ==> (range 5 10)
    (5 6 7 8 9)
    
    ==> (range 10 5)
    ()
    
  5. In class we added collect expressions to our language, which are like the list-comprehension feature of Python:

    ==> (collect (n * n) for n in (range 10))
    (0 1 4 9 16 25 36 49 64 81)
    

    Extend the interpreter to handle collect expressions with an optional if-condition, using the following syntax:

    (collect exp1 for var in exp2 if condition)
    

    For example:

    ==> (define odd ...)
    ==> (collect (n * n) for n in (range 10) if (odd n))
    (1 9 25 49 81)
    

  6. Add support for while-loops and for-loops to your interpreter, with the following syntax:

    (while condition do expression ...)
    
    (for var in expression1 do expression2 ...)
    

    To evaluate a while, the condition is first evaluated in the current environment. If the result is true, each expression is evaluated in sequence, and then the cycle repeats, until condition becomes false, at which point the loop terminates and returns the symbol ok.

    To evaluate a for loop, expression1 is first evaluated. The result should be a list. Then, on each cycle of the loop, var is bound to the next element of the list and the body expressions are evaluated in sequence. The final value returned is the symbol ok. Examples:

    ==> (let ((x 3))
          (while (x > 0) do
            (print x)
            (x := (x - 1))))
    3
    2
    1
    ok
    
    ==> (let ((total 0))
          (for x in (range 1 5) do
            (print x)
            (total := (total + x)))
          (print total))
    1
    2
    3
    4
    10
    ok
    
  7. Add dynamic assignment to your interpreter, with the following syntax:

    (var := rhs-exp during exp1 exp2 ...)
    

    The rhs-exp expression is first evaluated, then the binding for var is temporarily changed to the resulting value, after which the remaining expressions are evaluated in order. After all of the expressions have been evaluated, the var binding is restored to its original value, and the value of the last expression is returned as the value of the dynamic assignment. If no binding exists for var, an error should occur. Example:

    ==> (let ((a 3))
          (let ((p (fun (x) -> (x + a))))
            (print a)
            (print (a := 5 during (p 2)))
            a))
    3
    7
    3
    

Extra Credit

Turning in your homework

Name your files

and submit them using /common/cs/submit/cs131-submit.

If you have questions about anything, just ask!