TC-5 Samples with Variables

The following example demonstrates the usefulness of information regarding escaping variables: when not computed, all the variables are stored on the stack.

vars.tig
let
  var a := 1
  var b := 2
  var c := 3
in
  a := 2;
  c := a + b + c;
  print_int(c);
  print("\n")
end
tc -H vars.tig
$ tc -H vars.tig
/* == High Level Intermediate representation. == */
label l0
	"\n"
# Routine: _main
label main
# Prologue
move
  temp t0
  temp fp
move
  temp fp
  temp sp
move
  temp sp
  binop sub
    temp sp
    const 12
# Body
seq
  seq
    move
      mem
        temp fp
      const 1
    move
      mem
        binop add
          temp fp
          const -4
      const 2
    move
      mem
        binop add
          temp fp
          const -8
      const 3
    seq
      move
        mem
          temp fp
        const 2
      move
        mem
          binop add
            temp fp
            const -8
        binop add
          binop add
            mem
              temp fp
            mem
              binop add
                temp fp
                const -4
          mem
            binop add
              temp fp
              const -8
      sxp
        call
          name print_int
          mem
            binop add
              temp fp
              const -8
        call end
      sxp
        call
          name print
          name l0
        call end
    seq end
  seq end
  sxp
    const 0
seq end
# Epilogue
move
  temp sp
  temp fp
move
  temp fp
  temp t0
label end
$ echo $?
0

Once escaping variables computation implemented, we know none escape in this example, hence they can be stored in temporaries.

tc -eH vars.tig
$ tc -eH vars.tig
/* == High Level Intermediate representation. == */
label l0
	"\n"
# Routine: _main
label main
# Prologue
# Body
seq
  seq
    move
      temp t0
      const 1
    move
      temp t1
      const 2
    move
      temp t2
      const 3
    seq
      move
        temp t0
        const 2
      move
        temp t2
        binop add
          binop add
            temp t0
            temp t1
          temp t2
      sxp
        call
          name print_int
          temp t2
        call end
      sxp
        call
          name print
          name l0
        call end
    seq end
  seq end
  sxp
    const 0
seq end
# Epilogue
label end
$ echo $?
0
tc -eH vars.tig > vars.hir
$ tc -eH vars.tig > vars.hir

$ echo $?
0
havm vars.hir
$ havm vars.hir
7
$ echo $?
0

Then, you should implement the declaration of functions.

fact15.tig
let
  function fact(i: int) : int =
    if i = 0 then 1
             else i * fact(i - 1)
in
  print_int(fact(15));
  print("\n")
end
tc -H fact15.tig
$ tc -H fact15.tig
/* == High Level Intermediate representation. == */
# Routine: fact
label l0
# Prologue
move
  temp t1
  temp fp
move
  temp fp
  temp sp
move
  temp sp
  binop sub
    temp sp
    const 8
move
  mem
    temp fp
  temp i0
move
  mem
    binop add
      temp fp
      const -4
  temp i1
# Body
move
  temp rv
  eseq
  seq
    cjump eq
      mem
        binop add
          temp fp
          const -4
      const 0
      name l1
      name l2
    label l1
    move
      temp t0
      const 1
    jump
      name l3
    label l2
    move
      temp t0
      binop mul
        mem
          binop add
            temp fp
            const -4
        call
          name l0
          mem
            temp fp
          binop sub
            mem
              binop add
                temp fp
                const -4
            const 1
        call end
    label l3
  seq end
    temp t0
# Epilogue
move
  temp sp
  temp fp
move
  temp fp
  temp t1
label end

label l4
	"\n"
# Routine: _main
label main
# Prologue
# Body
seq
  seq
    sxp
      call
        name print_int
        call
          name l0
          temp fp
          const 15
        call end
      call end
    sxp
      call
        name print
        name l4
      call end
  seq end
  sxp
    const 0
seq end
# Epilogue
label end
$ echo $?
0
tc -H fact15.tig > fact15.hir
$ tc -H fact15.tig > fact15.hir

$ echo $?
0
havm fact15.hir
$ havm fact15.hir
2004310016
$ echo $?
0

Note that the result of 15! (1307674368000) does not fit on a signed 32-bit integer, and is therefore wrapped (to 2004310016).

And finally, you should support escaping variables (see variable-escapes.tig).

tc -eH variable-escapes.tig
$ tc -eH variable-escapes.tig
/* == High Level Intermediate representation. == */
# Routine: incr
label l0
# Prologue
move
  temp t2
  temp fp
move
  temp fp
  temp sp
move
  temp sp
  binop sub
    temp sp
    const 4
move
  mem
    temp fp
  temp i0
move
  temp t1
  temp i1
# Body
move
  temp rv
  binop add
    temp t1
    mem
      mem
        temp fp
# Epilogue
move
  temp sp
  temp fp
move
  temp fp
  temp t2
label end

# Routine: _main
label main
# Prologue
move
  temp t3
  temp fp
move
  temp fp
  temp sp
move
  temp sp
  binop sub
    temp sp
    const 4
# Body
seq
  sxp
    eseq
    seq
      move
        mem
          temp fp
        const 1
      move
        temp t0
        const 2
    seq end
      call
        name l0
        temp fp
        temp t0
      call end
  sxp
    const 0
seq end
# Epilogue
move
  temp sp
  temp fp
move
  temp fp
  temp t3
label end
$ echo $?
0