For this assignment, you will add state to the Paret language by allowing variable mutation. Please assume left-to-right evaluation order throughout.

The grammar and the abstract syntax have been extended with three new forms:
`set`

, `do`

, and `rec-lam`

.

`set`

takes an identifier and an expression, evaluates the expression to a value, and assigns that value to the identifier by changing its value in the store. The result of a `set`

expression is the *new value* of the identifier. For instance, the Paret program

` (let (x 1) (set x 2))`

should evaluate to `2`

.

If the identifier in a `set`

expression is not in scope, you should raise an `err-unbound-id`

exception – it doesn't make sense to change the value of an identifier not bound in the environment!

`do`

takes a sequence of expressions and evaluates them in order. It returns the value of the *last* expression in the sequence. `do`

always has at least one subexpression. (The parser will enforce this.)

`rec-lam`

is a new piece of syntactic sugar that defines a recursive
function. It's very similar to `lam`

, except that it also takes a function
name which can be used in its body. More precisely,

` (rec-lam f v b)`

constructs a function with name `f`

, arguments `v`

, and body `b`

,
where the function name `f`

is bound inside the body.

To adapt an example from the book, you could define a function `S`

that
sums the numbers from `0`

to `n`

by writing:

```
(rec-lam S n (if (num= n 0)
0
(+ n (S (+ n -1)))))
```

This simply defines the function. To call it, you could write:

```
((rec-lam S n (if (num= n 0)
0
(+ n (S (+ n -1))))) 3)
```

which should evaluate to 3+2+1 = 6.

You can also easily write infinite loops using `rec-lam`

:

` ((rec-lam forever x (forever x)) "dummy")`

Please *do not* submit tests that run forever, though.

You will define a desugaring for `rec-lam`

in your `desugar`

function. It can be desugared to first let-bind the function name to a dummy value
(which will never be seen), then set it to the function it should be, and
finally return the function. So the first example:

```
(rec-lam S n (if (num= n 0)
0
(+ n (S (+ n -1)))))
```

could desugar to:

```
(let (S "dummy")
(set S (lam n (if (num= n 0)
0
(+ n (S (+ n -1)))))))
```

There's a problem, though: this expression has `let`

in it, which is
itself syntactic sugar. You can get around this by expanding the `let`

expression with a recursive call to `desugar`

. (This kind of recursion,
where instead of just recurring on your arguments you build up a new thing
and then recur on that, is called *generative recursion*.)

Your task is to add state to Paret. You should follow the store-passing style we studied in class and that is presented in the book. We have added the following definition for the store:

` type Store = StringDict<Value>`

That is, a `Store`

is a map from store location to
`Value`

. With this, we change the environment to be a map
from identifier to store location instead, which is reflected by the
following definition:

` type Env = StringDict<String>`

You will need to generate store locations, and can use the built-in
`gensym`

function to do so. For example, you can call `gensym("loc")`

to obtain a fresh
name that starts with "loc" (e.g., `"loc379"`

)

As you will use the store-passing style, your `interp`

should
produce a `Result`

which is simply a type synonym for a
pair of a `Value`

and `Store`

:

` type Result = {Value; Store}`

Please see below for a guide on how to work with pair values.

To create a pair of `a`

and `b`

, write `{a; b}`

.
For example, `{1; "a"}`

is a pair of `1`

and `"a"`

, and it has type `{Number; String}`

.

Given a pair `p`

, you can destruct it using let-binding:

```
check:
p = {1; "a"}
{first; second} = p
first is 1
second is "a"
end
```

Here is the extended grammar:

```
<expr> ::= | <num>
| true | false
| <string>
| (+ <expr> <expr>)
| (++ <expr> <expr>)
| (num= <expr> <expr>)
| (str= <expr> <expr>)
| (if <expr> <expr> <expr>)
| (and <expr> <expr>)
| (or <expr> <expr>)
| (let (<id> <expr>) <expr>)
| <id>
| (lam <id> <expr>)
| (<expr> <expr>)
| (set <id> <expr>)
| (do <expr> <expr> ...)
| (rec-lam <id> <id> <expr>)
```

```
type Env = StringDict<String>
type Store = StringDict<Value>
type Result = {Value; Store}
data Value:
| v-num(value :: Number)
| v-str(value :: String)
| v-bool(value :: Boolean)
| v-fun(param :: String, body :: Expr, env :: Env)
end
data Expr:
| e-num(value :: Number)
| e-str(value :: String)
| e-bool(value :: Boolean)
| e-op(op :: Operator, left :: Expr, right :: Expr)
| e-if(cond :: Expr, consq :: Expr, altern :: Expr)
| e-lam(param :: String, body :: Expr)
| e-app(func :: Expr, arg :: Expr)
| e-id(name :: String)
| e-set(name :: String, val :: Expr)
| e-do(stmts :: List<Expr>)
| sugar-and(left :: Expr, right :: Expr)
| sugar-or(left :: Expr, right :: Expr)
| sugar-let(name :: String, expr :: Expr, body :: Expr)
| sugar-rec-lam(fun-name :: String, param :: String, body :: Expr)
end
data Operator:
| op-plus
| op-append
| op-str-eq
| op-num-eq
end
data InterpError:
| err-if-got-non-boolean(val :: Value)
| err-bad-arg-to-op(op :: Operator, val :: Value)
| err-unbound-id(name :: String)
| err-not-a-function(val :: Value)
end
```

(For reference, feel free to look at the definitions file.)

To get started, you can open the code stencil and the test stencil in code.pyret.org.

Please read the test guidelines