;;;;;;;;;;;;;;;; chapter 6 tests ;;;;;;;;;;;;;;;;

(load "6-top.scm")

(type-check ;; types, abstract classes/methods, casting, instanceof
"
abstract class tree extends object 
  method int  initialize()1
  abstractmethod int sum()
  abstractmethod bool equal(tree t)
  
class interior_node extends tree 
  field tree left
  field tree right
  method void initialize(tree l, tree r)
   begin
    set left = l; set right = r
   end
  method tree getleft()left
  method tree getright()right
  method int sum()+(send left sum(), send right sum())
  method bool equal(tree t) 
    if instanceof t interior_node
     then if send left equal(send cast t interior_node getleft())
          then send right equal(send cast t interior_node getright())
          else false
     else false 
     
  
class leaf_node extends tree 
  field int value
  method void initialize(int v)set value = v
  method int sum()value
  method int getvalue()value
  method bool equal(tree t) 
   if instanceof t leaf_node
    then zero?(-(value, send cast t leaf_node getvalue()))
    else false
    
  
let o1 = new interior_node (
          new interior_node (
            new leaf_node(3),   
            new leaf_node(4)),
          new leaf_node(5))
in send o1 equal(o1)
")

(type-check ;; non-existent initializer
"
class c extends object  
new c()
"
)

(type-check ;; non-existent method
"
class c extends object
   method int initialize() 1
send new c() m()
"
)

(type-check ;; wrong number of args
"
class c extends object
   method int initialize() 1
   method int m() 2
send new c() m(5)
"
)

(type-check ;; wrong type of args
"
class c extends object
   method int initialize() 1
   method int m(int v) v
send new c() m(true)
"
)

(type-check ;; sending message to non-object
"
send 1 m()
"
)

(type-check ;; can't apply abstract method
"
class c1 extends object 
 method int initialize() 1
 abstractmethod int m()
 
let o = new c1() in send o m()
"
)

(type-check ;; equal by double dispatch
"
abstract class tree extends object 
  method int  initialize()1
  abstractmethod int sum()
  abstractmethod bool equal(tree t)
  abstractmethod bool equal_int(tree l, tree r)
  abstractmethod bool equal_leaf(int val)
  
class interior_node extends tree 
  field tree left
  field tree right
  method void initialize(tree l, tree r)
   begin
    set left = l; set right = r
   end
  method int sum()+(send left sum(), send right sum())
  method bool equal(tree t) send t equal_int(left, right)
  method bool equal_int(tree l, tree r) 
     if send left equal(l)
     then send right equal(r)
     else false
     
  method bool equal_leaf(int v) false
  
class leaf_node extends tree 
  field int value
  method void initialize(int v)set value = v
  method int sum()value
  method bool equal(tree t) send t equal_leaf(value)
  method bool equal_int(tree l, tree r) false
  method bool equal_leaf(int otherval) zero?(-(value, otherval))
  
let o1 = new interior_node (
          new interior_node (
            new leaf_node(3),   
            new leaf_node(4)),
          new leaf_node(5))
in send o1 equal(o1)
"
)

;; Exercise 1: try using subtype polymorphism to implement equal.

;; Exercise 2: write sample programs for all errors produced by type checker.
