CS140 -- Lab 8

This lab is designed to give you practice with:

  1. using stacks and lists, and
  2. working with information hiding using void *'s.
The lab is divided into two parts. In the first part you are going to use the stack library to help you simulate the execution of a program using a call stack. A call stack in an actual program represents a stack of the currently executing functions. The function that is currently executing is the top function on the stack, the function which called it is the next to top function, and so on. In your simulation you will be given a list of the functions called by each function and will simulate each of the calls.

In the second part you will have an opportunity to redo one of your previous labs to get 3/4 credit back. Unlike last time, you will not be able to get back late points, only points lost due to incorrectness.


Part 1 -- Call Stack Simulator

In this part of the program you are going to write an interpreter that reads a very simple program and executes it. An interpreter is a program that reads instructions and executes them. Your interpreter will be given input lines of the form:

fct-name fct-call fct-call ... fct-call
For example:
B C print_stack D
will define a function named B that calls the functions C, print_stack and D. There are only two types of instructions:

  1. user defined function call: This instruction should cause your interpreter to push a record for that function onto the call stack and start "executing" that function. When the function finishes executing, its record will be popped off the call stack and the function that called it will resume its execution. For example, suppose your input has four functions defined as follows:
    main B
    B C D
    C D
    D
    
    Initially you will place a record for main on the call stack:
    main
    
    main calls B, thus placing a record of B on the stack, and B begins execution:
    B
    main
    
    B then calls C, which in turn calls D, resulting in the following stack:
    D
    C
    B
    main
    
    D makes no function calls so it exits immediately, and pops itself off the stack:
    C
    B
    main
    
    C is also finished with calling functions so it exits and pops itself off the stack:
    B
    main
    
    B now calls D and pushes it on the stack:
    D
    B
    main
    
    Hopefully you get the picture of how things work.

  2. print_stack: This instruction should cause your interpreter to print the call stack. Your interpreter should first print a header of the form:
    **** stack %d ****
    
    where %d will be replaced with a count of the number of times you have printed the stack thus far. Your interpreter will then print the call stack from top to bottom. For each function on the call stack your interpreter will print the function's name in a 10 character wide, left justified field. Your interpreter will then print a space separated list of the functions it calls. Finally your interpreter should place an asterisk after the function that it is currently calling. For example, given the input:
    main A C D
    A B
    B C print_stack D
    C D
    D print_stack
    
    your program should produce the output:
    **** stack 0 ****
    D          print_stack*
    C          D*
    B          C* print_stack D
    A          B*
    main       A* C D
    **** stack 1 ****
    B          C print_stack* D
    A          B*
    main       A* C D
    **** stack 2 ****
    D          print_stack*
    B          C print_stack D*
    A          B*
    main       A* C D
    **** stack 3 ****
    D          print_stack*
    C          D*
    main       A C* D
    **** stack 4 ****
    D          print_stack*
    main       A C D*
    

Program Execution

Your program will begin by reading the function definitions and storing them. Once it has read all the function definitions, it will push main onto the call stack and start executing the "program" that the user just entered.

Input Assumptions and Program Format

  1. Place your code in a file named call_stack.c and your structs/typedefs in a file named call_stack.h.
  2. You must use the stack library, stack.h, that Thomas Hooper demonstrated for you in class. You can find the .h file in /home/bvz/cs140/include, the .o file in /home/bvz/cs140/objs, and the .c file in /home/bvz/cs140/src. Notice that you do not need to know whether the .o file is implemented using arrays or lists, since the interface is the same in both cases.
  3. Your program will take one command line argument, which is the name of the input file. You must use the fields library to read and process the input file.
  4. The input should always contain a function named main, which will be your starting function.
  5. You can find an executable at /home/bvz/cs140/labs/lab8/call_stack. If you have questions about how your program should behave or how it should format its output, check the executable.
  6. There are a number of test files in /home/bvz/cs140/labs/lab8, all starting with the prefix "test". Do not assume that these files represent an exhaustive list of tests.


Part 2 (Optional) -- Rework an Old Lab

Rework one of labs 1-7 and resubmit it. You may get up to 3/4 the points back that you lost due to incorrectness on the lab. Unlike last time you cannot get back late points. If you don't think that it's worth your time to do so, then you may skip this part of the lab.


Design Document

You should prepare a design document with the following features:

  1. the set of error conditions you plan to check for.
  2. the normal conditions you will test (e.g., main calling functions, but these functions not calling any functions themselves, main not calling any functions, etc.)
  3. the data structures you will use (you can draw pictures)
  4. the incremental program steps you will use to design your program.


What to Submit

  1. Your design document when the TA calls for it.
  2. A source file for part 1 named call_stack.c and a header file with your structs/typedefs named call_stack.h.
  3. The source files for the lab you wish to re-submit and a file named README in which you tell the TA which lab you are asking to be re-graded.