TC-2 Pretty-Printing Samples¶
Warning
The ASTs outputed below are generated with the -X option to
avoid useless repetition.
Do not forget to test your pretty-printer without the option.
print("Hello, World!")
$ tc -A hello-world.tig
/* == Abstract Syntax Tree. == */
primitive print(string : string)
primitive print_err(string : string)
primitive print_int(int : int)
primitive flush()
primitive getchar() : string
primitive ord(string : string) : int
primitive chr(code : int) : string
primitive size(string : string) : int
primitive streq(s1 : string, s2 : string) : int
primitive strcmp(s1 : string, s2 : string) : int
primitive substring(string : string, start : int, length : int) : string
primitive concat(fst : string, snd : string) : string
primitive not(boolean : int) : int
primitive exit(status : int)
function _main() =
(
print("Hello, World!");
()
)
$ echo $?
0
$ tc -XA hello-world.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
print("Hello, World!");
()
)
$ echo $?
0
The parser builds ASTs that can be output by a pretty-printing module.
/* Define a recursive function. */
let
/* Calculate n!. */
function fact (n : int) : int =
if n = 0
then 1
else n * fact (n - 1)
in
fact (10)
end
$ tc -XA simple-fact.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
let
function fact(n : int) : int =
(if (n = 0)
then 1
else (n * fact((n - 1))))
in
fact(10)
end;
()
)
$ echo $?
0
The pretty-printed output must be valid and equivalent.
Valid means that any Tiger compiler must be able to parse with success
your output.
Pay attention to the banners such as == Abstract...: you should
use comments: /* == Abstract... */.
Pay attention to special characters too.
print("\"\x45\x50ITA\"\n")
$ tc -XA string-escapes.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
print("\"EPITA\"\n");
()
)
$ echo $?
0
Equivalent means that, except for syntactic sugar, the output and the
input are equal.
Syntactic sugar refers to &, |, unary -, etc.
1 = 1 & 2 = 2
$ tc -XA 1s-and-2s.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
(if (1 = 1)
then ((2 = 2) <> 0)
else 0);
()
)
$ echo $?
0
$ tc -XA 1s-and-2s.tig > output.tig
$ echo $?
0
$ tc -XA output.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
(if (1 = 1)
then ((2 = 2) <> 0)
else 0);
()
)
$ echo $?
0
Beware that for loops are encoded using a ast::VarDec:
do not display the var.
for i := 0 to 100 do
(print_int (i))
$ tc -XA for-loop.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
(for i := 0 to 100 do
print_int(i));
()
)
$ echo $?
0
Parentheses must not stack for free; you must even remove them as the following example demonstrates.
((((((((((0))))))))))
$ tc -XA parens.tig
/* == Abstract Syntax Tree. == */
function _main() =
(
0;
()
)
$ echo $?
0
This is not a pretty-printer trick: the AST of this program and that of
0 are exactly the same: a single ast::IntExp.
Objects constructs in Tiger can be pretty-printed when enabled with the
-o/--object option.
simple-class.tig¶let class B { var a := 42 method m() : int = self.a } var b := new B in b.a := 51 endtc -XoA simple-class.tig¶$ tc -XoA simple-class.tig /* == Abstract Syntax Tree. == */ function _main() = ( let type B = class extends Object { var a := 42 method m() : int = self.a } var b := new B in (b.a := 51) end; () ) $ echo $? 0
As a result, anything output by tc -A is equal to what
tc -A | tc -XA displays!