TC-5 FAQ

‘$fp’ or ‘fp’?

Andrew Appel clearly has his HIR/LIR depend on the target in three different ways: the names of the frame pointer and result registers, and the machine word size.

That would mean that the target module (see src/target) would be given during TC-5, which seemed too difficult and anti-pedagogical, so we used fp and rv where he uses $fp and $v0. While this does make TC-5 more target independent and TC-5 code base lighter, it slightly complicates the rest of the compiler.

There remains one target dependent information wired in hard: the word size is set to 4.

‘$x13’ or ‘t13’?

Anonymous temporaries should be output as ‘t13’ for HAVM at stages 5 and 6, and as ‘$x13’ for Nolimips, stage 7. The code provided does not support (yet) this double standard, so it always outputs ‘t13’, although the samples provided here use ‘$x13’. Fortunately HAVM supports both standards, so this does not matter for TC-5 and TC-6. We recommend ‘t13’ though, contrary to our samples, generated with a tc that needs more work.

How to perform the allocation of the static link in a level?

The constructor of translate::Level reads:

  // Install a slot for the static link if needed.
  Level::Level(const misc::symbol& name,
               const Level* parent,
               frame::bool_list_type formal_escapes)
    : parent_(parent)
    , frame_(new frame::Frame(name))
  {
// FIXME: Some code was deleted here (Allocate a formal for the static link).

    // Install translate::Accesses for all the formals.
    for (const bool b : formal_escapes)
      formal_alloc(b);
  }

To allocate a formal for the static link, look at how other formals are allocated, and take these into account:

  • there is always a formal attribute allocated for the static link in translate::Level

  • this formal always escapes.

Obviously, this won’t hold if you plan to optimize the static links (see TC-5 Optimizing Static Links); you’ll have to tweak translate::Level’s constructor.

Why var i := 0 function _main() = (i, ()) won’t compile?

If you try to compute the intermediate representation for a single variable declaration, you’ll probably run into a SIGSEGV or a failed assertion. For instance, the following command probably won’t work: echo 'var i := 0 function _main() = (i, ())' | tc --hir-compute -.

Variables must be allocated in a level (see translate::Translator::operator()(const ast::VarDec&)). However, there is no level for global variable declarations (outside _main). The current language specification does not address this case, so you are free to handle it as you wish, though an assertion on the presence of an enclosing level is probably the easiest solution.