# Homework #4

**Due: Wed, Aug 2, 23:59**

## How to Submit

Submit one solution per team (each team can have 1–3 members), through TEACH. Put the names and ONID IDs of all team members as a comment at the top of the file.

Your submission should consist of two files named

`StackRank.<your-username>.hs`

, whereis the ONID ID of the team member who submitted the file. These files

*must compile without errors*in GHCi. Put all non-working parts of your solution in comments! If your file does not compile, the TA will not evaluate it.If you can’t solve a problem, you can get partial credit by describing in comments what you tried and where you got stuck.

Late submissions will not be accepted. Do not send solutions by email.

## Description

In this assignment you will be implementing a type system for a stack language. The grammar for the language is defined by the following Haskel type definitions:

```
type Prog = [Cmd]
data Cmd = Push Int
| Pop Int
| Add
| Mul
| Dup
| Inc
| Swap
```

A program in this language manipulates an implicit stack of integers. A program is a sequence of commands, where each command modifies the stack.

`Push i`

– pushes the integer`i`

to the top of the stack`Pop i`

– removes`i`

elements from the top of the stack`Add`

– adds the two topmost values on the stack, popping the arguments and pushing their sum`Mul`

– multiplies the two topmost values on the stack, popping the arguments and pushing their product`Dup`

– makes a copy of the topmost value on the stack, and pushes the copy`Inc`

– increments the topmost element of the stack (i.e. adds one)`Swap`

– swaps the order of the two topmost values on the stack

The rank of a stack is given by the number of its elements. The rank of a single stack operation is given by a pair of numbers `(n,m)`

where `n`

indicates the number of elements the operation pops from the top of the stack and `m`

is the number of elements the operation pushes to the top of the stack. The rank for a stack program is defined to be the rank of the stack that would be obtained if the program were run on an empty stack. A *rank error* occurs in a stack program when an operation with rank `(n,m)`

is executed on a stack with rank `k < n`

. In other words, a rank error indicates a stack *underflow*.

Use the following types to represent stack and operation ranks.

```
type Rank = Int
type CmdRank = (Int,Int)
```

## Tasks

Template: StackRank.template.hs

### Part 1

Define a function

`rankC`

that maps each stack operation to its rank.Define an auxiliary function

`rankP`

that computes the rank of a program. The`Maybe`

data type is used to capture rank errors (i.e. a program containing a rank error should be mapped to`Nothing`

, whereas a program with no rank error should be wrapped by`Just`

).*Hint*: you may need to define an auxiliary function`rank :: Prog -> Rank -> Maybe Rank`

and define`rankP`

using`rank`

.Define a function

`semStatTC`

for evaluation stack programs that first calls the function`rankP`

to check whether the stack program is type correct and evaluates the program only in the case it is. For performing the actual evaluation`semStatTc`

calls the function`prog`

.

### Bonus Problems

Notice that the function `prog`

called by `semStatTC`

can be simplified (both its type and its definition). In order to get extra credit you must complete **both** of the following:

Provide the new type of the function

`prog`

and explain why the function can be simplified to have this type (use comments for your explanation).Redefine the

`prog'`

function using this new data type.

### Part 2

Consider the following block of code.

```
{ int x;
int y;
y := 1;
{ int f(int x) {
if x = 0 then {
y := 1 }
else {
y := f(x - 1) * y + 1 };
return y;
}
x := f(2);
};
}
```

- Illustrate the computations that take place during the evaluation of this block, that is, draw a sequence of pictures each showing the complete runtime stack with all activation records after each statement or function call.

**Note**: please place the answer to this exercise in comments.

### Part 3

Consider the following block (assume call-by-value parameter passing).

```
{ int x;
int y;
int z;
x := 3;
y := 7;
{ int f(int y) { return x * y };
int y;
y := 11;
{ int g(int x) { return f(y) };
{ int y;
y := 13;
z := g(2);
};
};
};
}
```

Determine which value will be assigned to

`z`

in line 12 under*static scoping*.Determine which value will be assigned to

`z`

in line 12 under*dynamic scoping*

You may want to draw the runtime stack for this execution, though this is not required for the assignment.

**Note**: please place the answers to this exercise in comments.