Lecture 002

COOL Overview

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:

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)
  };
};

COOL Example: Factorial

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

COOL Example:

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