// A program consists of a number of classes, followed by an expression class A {} class B {} 1 // evaluates to 1 // Classes may contain instance variable declarations class E { :x :y :z } // Classes may contain method declarations; always one arg, name 'arg' class C { foo(arg) {} bar(arg) {} } (new C).foo(2) // evaluates to nil // Method bodies are lists of expressions class D { :x baz(arg) { 2; x; 4 } } (new D).baz(3) // evaluates to 4 // Expressions can have various forms class E { :x zop(arg) { self; // enclosing object arg; // given argument 3; // literal integer x; // name of instance variable self.fap(arg); // message send new E; // object creation x := arg; // assignment } fap(arg) {} } (new E).zop(new E) // evaluates to the 2nd new E // We may even be able to write a program class Truth { :true :false setTrue(arg) { true := arg } setFalse(arg) { false := arg } ifTrue(arg) { true.run() } ifFalse(arg) { false.run() } if(arg) { (cond True False arg).on(self) } } class True { on(arg) { arg.ifTrue() } } class False { on(arg) { arg.ifFalse() } } class Run { :target :argt on(arg) { target := arg; self } with(arg) { argt := arg; self } run(arg) { target.main(argt) } } class Noop { run(arg) {} } class Count { :if :t :f main(arg) { if := new Truth; t := (new Run).on(self).with(arg.pred()); f := new Noop; if.setTrue(t); if.setFalse(f); if.if(arg); } } (new Count).main(3)