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.
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
/* == 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
/* == 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
$ echo $?
0
$ havm vars.hir
7
$ echo $?
0
Then, you should implement the declaration of functions.
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
/* == 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
$ echo $?
0
$ 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
/* == 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