Classroom Object Oriented Language (COOL): for teaching, designed to be easily implementable. There are more COOL compiler than programs. It will compile COOL to MIPS
assembly language (real instruction set).
In COOL, we do:
abstraction
static typing
reuse (inheritance)
memory management
...
Many things are left out
Cool file: any file with .cl
extension.
class Main {
main():Int { // Int (and all other objects) inherits Object
1
}; // method
};
To compile, you run coolc name.cl
, it will generate name.s
that is the assembly code. We can run it using MIPS
simulator by running spim name.s
.
If you want to print out something
class Main {
i : IO <- new IO; // built-in class, IO attribute, and initialize to IO object
main():Int { // enter method, the body is a block of expression
{ // enter statement block
i.out_stream("Hello World!"); // this will print and return an IO object
1; // 1 will be returned
}
};
};
statement (expression) block: evaluated in order and the value of the block is the value of the last expression.
To optimize a bit, we could also do:
class Main {
main():Object {
(new IO).out_string("Hello World!\n)
};
};
or to do
class Main inherits IO {
main():Object {
self.out_string("Hello World!\n)
};
};
We can remove self
and it will work too
class Main inherits IO {
main():Object {
out_string("Hello World!\n)
};
};
We program a factorizal program
class Main inherits A2I { // string to integer
main() : Object {
(new IO).out_string(
i2a(
fact(
a2i((new IO).in_string())
)
).concat("\n")
)
};
fact(i : Int) : Int {
if (i = 0) then 1 else i * fact(i - 1) fi // end if
}; // recursive
fact(i : Int) : Int {
let fact : Int <- 1 in { // declear new variable, follow by a block
while (not (i = 0)) loop
{
fact <- fact * 1;
i <- i - 1
} // a block of two statements
pool; // end statement
fact; // the last statement in statement block is evaluated
} // the body of let is the result of let
};
};
To compile you need additional library: coolc fact.cl atoi.cl
class Main inherits IO {
main() : Object {
let hello : String <- "Hello ",
world : String <- "World!",
newline : String <- "\n"
in
out_string(hello.concat(world.concat(newline)))
};
};
We can instead use list to automatically concat strings:
class List {
item : String; // fields
next : List;
init(i : String, n : List) : List {
item <- i;
next <- n;
self;
};
flatten() : String {
if (isvoid next) then
item
else
item.concat(next.flatten())
fi
};
};
class Main inherits IO {
main() : Object {
let hello : String <- "Hello ",
world : String <- "World!",
newline : String <- "\n",
nil : List,
list List <- (new List).init(
hello, (new List).init(
world, (new List).init(
newline, nil // notice that nil is already avaliable here
)
)
)
in
out_string(
list.flatten()
)
};
};
If we want to generalize the List
operation to any arbitrary type, we do:
class List inherits A2I {
item : Object;
next : List;
init(i : Object, n : List) : List {
item <- i;
next <- n;
self;
};
flatten() : Object {
let string : String <-
case item of
i : Int => i2a(i);
s : String => s;
c : Object => {abort(); "";}; // make it type check, since abort is not any type
esac
in
if (isvoid next) then
string
else
string.concat(next.flatten())
fi
};
};
Table of Content