# 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`, where is 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
| 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)``````

Template: StackRank.template.hs

### Part 1

1. Define a function `rankC` that maps each stack operation to its rank.

2. 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`.

3. 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:

1. 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).

2. 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);
};
}``````
1. 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.

### 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);
};
};
};
}``````
1. Determine which value will be assigned to `z` in line 12 under static scoping.

2. 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.