Skip to content

Instantly share code, notes, and snippets.

@joshz
Created May 4, 2012 15:55
Show Gist options
  • Save joshz/2595709 to your computer and use it in GitHub Desktop.
Save joshz/2595709 to your computer and use it in GitHub Desktop.
Coursera: Compilers: Cool Examples I-III
class Main {
// if you want to print something
// initialize i to new IO object
i : IO <- new IO;
// body of the program is a block of expressions
// the first one executes out_string call to the object
// i which prints "hello world", and second evaluates to 1
// which is the value of the block, which becomes the
// value of the method
main():Int {{i.out_string("Hello World!\n"); 1;}};
};
// compile with coolc 1.cl
// spim -> mips simulator, run:
// spim 1.s <- compiled cool program
// REWRITEs
class Main {
i : IO <- new IO;
// now types don't match, should be string
main():Int {i.out_string("Hello World!\n"); };
};
class Main {
i : IO <- new IO;
// this should work
main():IO {i.out_string("Hello World!\n"); };
};
class Main {
i : IO <- new IO;
// Object is the base class for all types
main():Object {i.out_string("Hello World!\n"); };
};
class Main {
// initialize IO in expression
main():Object {(new IO).out_string("Hello World!\n"); };
};
class Main inherits IO{
// self is the name of the current object
// when the main method runs
main():Object {self.out_string("Hello World!\n"); };
};
class Main inherits IO{
// we don't need to name self, program will default
// to self if it's not declared
main():Object {out_string("Hello World!\n"); };
};
----------------- COOL Ex II ------------------
Factorial
class Main {
main() : Object {
// we need to be able to read and write numbers
// input -> in_string()
// concat -> concatinates new line
// we need to convert to integers, cause
// right now it's strings, look nex ex
(new IO).out_string((new IO).in_string().concat("\n"))
};
};
// to convert between strings and ints, inherit from
// need to get A2I from somewhere
// so at compilation supply the library
// coolc fact.cl atoi.cl
class Main inherits A2I{
main() : Object {
// convert string to integer
// read string, convert to in, add 1, convert to string,
// add new line
(new IO).out_string(i2a(a2i((new IO).in_string())+1).concat("\n"))
};
};
// Factorial function, recursive
class Main inherits A2I{
main() : Object {
(new IO).out_string(i2a(fact(a2i((new IO).in_string()))).concat("\n"))
};
// declare the factorial function, takes one Int parameter,
// returns an Int
fact(i: Int): Int {
// if statements end in fi
if (i=0) then 1 else i * fact(i-1) fi
};
};
// Factorial function, iterative
class Main inherits A2I{
main() : Object {
(new IO).out_string(i2a(fact(a2i((new IO).in_string()))).concat("\n"))
};
fact(i: Int): Int {
// declare a local variable fact of type Int, initialize to 1
// <- initialization and assignment
let fact: Int <- 1 in {
while (not (i=0)) loop
{
// common mistake is using = for assignment
// however in this case it'll run out of heap
// = is the comparison operator
fact <- fact * i;
i <- i-1;
}
// pool closes loop
pool;
// result of the let expression, last statement of the block
// is the value of the block
fact;
}
};
};
// manipulate data
class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
newline: String <- "\n"
in
out_string(hello.concat(world.concat(newline)))
};
};
----------------------
// build a list of strings
// build an abstraction, List, contains function to do concatination
class List {
item: String;
next: List;
// constructor?
init(i: String, n:List): List{
// statement block, initialize members
{
item <- i;
next <- n;
// return object itself
self;
}
};
flatten(): String {
// end of string, isvoid is a function that checks if there's anything
// more in the string, isvoid next checks if next character is void
if (isvoid next) then
// last element in list
item
// not at end of string
else
// concatinate the result of flattening the rest of the list
item.concat(next.flatten())
fi
};
// manipulate data
class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
newline: String <- "\n"
// uninitialized variable, "voic pointer"
nil: List,
list: List <-
(new List).init(hello,
(new List).init(world,
// we need a list object, equivalent of a null pointer
// create an uninitialized variable
(new List).init(newline, nil)))
in
// flatten list containing the string and print
out_string(list.fatten())
};
};
----------------------
// Let's say we want to have an arbitrary list of objects, not just strings
// build a list of strings
// build an abstraction, List, contains function to do concatination
// then have a print representation, but not everything in the list is
// necessarily a string
class List inherits A2I{
item: Object;
next: List;
init(i: Object, n:List): List{
{
item <- i;
next <- n;
// return object itself
self;
}
};
// print representation
// do different things for different types of things
flatten(): String {
// case construct: allows for recovering the type of an object at runtime
let string: String <-
case item of
i: Int => i2a(i);
s: String => s;
// default, abort returns an Object, cast to string, ""
// ~15.40, cool ex III
o: Object => { abort(); ""; };
esac
in
if (isvoid next) then
string
else
string.concat(next.flatten())
fi
};
class Main inherits IO {
main(): Object {
let hello: String <- "Hello ",
world: String <- "World!",
i: Int <- 42,
newline: String <- "\n"
nil: List,
list: List <-
(new List).init(hello,
(new List).init(world,
(new List).int(42,
(new List).init(newline, nil))))
in
out_string(list.fatten())
};
};
// should print Hello World!42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment