CS140 -- Lab 8
This lab is designed to give you practice with:
- using stacks and lists, and
- 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:
- 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.
- 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
- Place your code in a file named call_stack.c and your
structs/typedefs in a file named call_stack.h.
- 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.
- 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.
- The input should always contain a function named main,
which will be your starting function.
- 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.
- 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:
- the set of error conditions you plan to check for.
- 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.)
- the data structures you will use (you can draw pictures)
- the incremental program steps you will use to design your program.
What to Submit
- Your design document when the TA calls for it.
- A source file for part 1 named call_stack.c and
a header file with your structs/typedefs named call_stack.h.
- 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.