Computer Science 301 - 2002


Tutorial for week 13 - Multifunction programs in Parva

In this week's practical we shall be extending the Parva compiler to recognise and compile code for programs with more than one void function. Although these will not allow for parameters, inter-function communication can be achieved through the use of global variables, as exemplified by

      int global1, global2;

      void routine () {
        int local1, local2;
        local1 = global1 + local2;
      }

      void main () {
        int x;
        routine();
      }

where, to make it simple, all global declarations are to be made before any functions are defined, and where it is intended that the run time organisation will be on the lines of

              Stack frame for routine                           Globals
      .-----------------------------------.        .--------------------------.
      |        |        |        |        |  ....  |        |        |        |
      `-----------------------------------'        `--------------------------'
                                          ^                                   ^
                                       CPU.BP                              CPU.GP

with addressing opcodes extended so that ADR -Local will push a local address (computed relative to CPU.BP) onto the stack and GAD -Global will push a global variable address (computed relative to CPU.GP) onto the stack. This tutorial explores some of the aspects of the system that you will need to incorporate into the compiler.

(a) The first Parva compiler had productions like

     Parva      = "void" "main" "(" [ "void" ] ")" Block .
     Block      = "{" { Statement } "}" .
     Statement  = ConstDeclaration | VarDeclarations | Assignment ...
     Assignment = Variable ( "=" Expression | "++" | "--" ) ";"

How would these have to be altered to handle multi-function programs?

(b) Suggest what the runtime arrangement would be for the above program at the instant where main has started execution.

(c) What would the runtime arrangement be at the instant where main has called routine and routine has just started execution?

(d) Suggest what sort of code you should generate for the above program. You will clearly need to have two new opcodes, say CAL X to call a routine whose code begins at location X, and RET, to be able to return from a routine back to the caller.

(e) Suggest how an emulator might handle the CAL and RET opcodes.

(f) What modifications would be needed to the symbol table handler to deal with such programs?

(g) To deal with the problem of mutually recursive functions one could introduce the concept of the "function prototype", as exemplified by

      void routine2 ();  // prototype, header only

      void routine1 () { routine2(); }

      void routine2 () { routine1(); }

      void main () { routine1(); }

What implications does this have for the grammar and the compiler, and how do you handle these?


Home  © P.D. Terry