(* Example cool program testing as many aspects of the code generator as possible. *) class A inherits IO { attr_A_1 : Int <- 10; attr_A_2 : Bool <- false; attr_A_3 : A <- self; method_common(x1: Int) : SELF_TYPE { self }; method_common2() : String { "A" }; }; class B inherits A { }; class C inherits A { attr_C_1 : String <- "This is C\n".concat(new A.method_common2()); attr_C_2 : SELF_TYPE; method_common(x1: Int) : SELF_TYPE { self }; method_common2() : String { "C" }; method_1(x1: Int) : Bool { true }; method_3(x1: Int, x2: A, x3: String) : Object { { x1 <- x1 + 00010 - x1 / 10; x2 <- x2.method_common(x1); x3 <- x3.concat("schade"); } }; method_2(x1: Bool, x2: C) : Object { { if (x1) then x2 <- x2.method_common(20) else "hello world" fi; } }; }; class D inherits C { method_common(x1: Int) : SELF_TYPE { self }; }; class E { method_compare(x1: Int, x2: Int) : Bool { x1 < x2 }; method_compare_eq(x1: String, x2: String) : Bool { x1 = x2 }; method_compare_eq2(x1: D, x2: D) : Bool { x1 = x2 }; method_not(x1: Bool) : Bool { not x1 }; method_isvoid(x1: Object) : Bool { isvoid x1 }; method_let1(x1: Int) : Object { let x2 : Int <- x1 + 10 in x2 <- x1 }; method_let2(x1: Int) : Object { let x2 : Int <- x1 in x2 <- x1 + 100 }; }; class Main inherits IO { main():Int { 0 }; };