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.


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)


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.

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

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

Back to course home page