Project #9: μOO

Submit: Turn in two Scheme source files called hw9.scm and hw9-test.scm using the turnin command on morbius.mscsnet.mu.edu or one of the other Systems Lab machines.

Work is to be completed in teams of two. Be certain to include both teammates names in the file. You may submit multiple times, but only the last turnin will be kept. The automatic submission system will not accept work after the deadline. (If both partners are submitting work to TA-Bot -- which isn't a bad idea to get twice as much automated testing done during the week -- please be sure that one partner overwrites with a blank submission, or at least that the versions are identical. If the TA has to grade two separate versions of the project from a team, she is authorized to enter the lower of the two grades into the gradebook for that team!)

Include a comment block at the very top of each file that contains the following:

  ; COSC 3410 - Project [#]
  ; Explain briefly the functionality of the program.
  ; @authors [your names]
  ; Instructor [your instructor]
  ; TA-BOT:MAILTO [your email addresses]

Your source file should be in the EoPL dialect ("#lang eopl" at top of file) supported by DrRacket, and should not make use of non-standard features like comment boxes that produce an XML file rather than a flat text .scm file.

At the bottom of your hw9.scm, please include the line:

(provide scan&parse run)

Your hw9-test.scm file should be a SchemeUnit testsuite, as shown in class.

The Grammar

Extend your grammar from μ; (the assignment before type checking) to include syntax for classes and objects:

<program>    ::=    {<class-decl>}* <statement>
    a-program (class-decls body)
<class-decl>    ::=    class <identifier> extends <identifier> { { field <identifier> ; }* { <method-decl> }* }
    a-class-decl (class-name super-name field-names method-decls)
<method-decl>    ::=    method <identifier> ( { <identifier> }*(,) ) { { <statement> ; }* return <expression> ; }
    a-method-decl (method-name vars body return-exp)

The grammar for statements and expressions will remain the same as in our statement language, μ;, with the following four new expression productions:

<expression>    ::=    new <identifier> ( { <expression> }*(,) )
    new-object-exp (class-name rands)
     |    send <expression> . <identifier> ( { <expression> }*(,) )
    method-call-exp (obj-exp method-name rands)
     |    super . <identifier> ( { <expression> }*(,) )
    super-call-exp (method-name rands)
     |    this
    self-exp ()

This language is a close relative to the CLASSES language of EoPL Chapter 9.

Interpreter

Add the code from EoPL section 9.4 for representing objects, classes, and methods. You will also need the new environments described for looking up information about classes and methods. Adapt your interpreter to run programs in the new language.

All of your existing testcases from μ; are still legal in this language -- they are μOO programs with an empty list of class declarations.

The textbook contains several excellent examples that will work as testcases for the new object-oriented language with only minor syntax changes to match our more Java- and Scheme-like syntax. Here is the example from Figure 9.1 (EoPL p.327) recast in our dialect:

class c1 extends object
{
  field i;
  field j;
  method initialize (x) { i = x; j = (sub 0 x); return j; }
  method countup (d) { i = (add i d); j = (sub j d); return j; }
  method getstate () { return (list i j); }
}
  var t1 = 0,
   t2 = 0,
   t3 = 0,
   o1 = new c1(3);
  {
   t1 = send o1.getstate();
   t3 = send o1.countup(2);
   t2 = send o1.getstate();
   print t1;
   print t2
  }

This program should produce the following output when run:

(3 -3)
(5 -5)

Here is the example from Figure 9.2 (EoPL p.328) for summing the leaves of a tree:

class interior_node extends object
{
  field left;
  field right;
  method initialize (l, r)
  {
   left = l;
   right = r;
   return r;
  }
  method sum ()
  {
   return (add send left.sum() send right.sum());
  }
}
class leaf_node extends object
{
  field value;
  method initialize (v)
  {
   value = v;
   return v;
  }
  method sum ()
  {
   return value;
  }
}
  var o1 = new interior_node(new interior_node(new leaf_node(3), new leaf_node(4)), new leaf_node(5));
   print send o1.sum()

The answer is 12.

Finally, here is Figure 9.6 (EoPL p. 334) demonstrating the interaction of super calls with this expressions:

class c1 extends object
{
  method initialize () { return 1; }
  method m1() { return send this.m2(); }
  method m2() { return 13; }
}
class c2 extends c1
{
  method m1() { return 22; }
  method m2() { return 23; }
  method m3() { return super.m1(); }
}
class c3 extends c2
{
  method m1() { return 32; }
  method m2() { return 33; }
}
  var o3 = new c3();
   print send o3.m3()

The result of running this program is 33.


[back]

[Revised 2021 Apr 16 13:54 DWB]