//
// How to compile:
//   atscc -o bintree bintree-2008-09-05.dats
//

staload "prelude/SATS/file.sats"

//

datatype bt = E | B of (bt, bt)

//

extern fun fprint_bintree (out: FILEref, t: bt): void
overload fprint with fprint_bintree

implement fprint_bintree (out, t) = begin case+ t of
  | B (t1, t2) => begin
      fprint (out, "B(");
      fprint (out, t1); fprint (out, ", "); fprint (out, t2);
      fprint (out, ")")
    end
  | E () => fprint (out, "E()")
end // end of [fprint_bintree]

extern fun print_bintree (t: bt): void
overload print with print_bintree

implement print_bintree (t) = fprint (stdout_ref, t)

//

extern fun Bcount (t: bt): int
extern fun Ecount (t: bt): int

implement Bcount (t) = case+ t of
  | B (t1, t2) => 1 + Bcount (t1) + Bcount (t2)
  | E () => 0

implement Ecount (t) = case+ t of
  | B (t1, t2) => Ecount (t1) + Ecount (t2)
  | E () => 1

//

implement main () = let
  val t0 = E ()
  val t1 = B (t0, t0)
  val t2 = B (t0, t1)
  val t3 = B (t1, t2)
  val t4 = B (t2, t2)
in
  print ("t0 = "); print t0; print_newline ();
  printf ("Bcount (t0) = %i\n", @(Bcount t0));
  printf ("Ecount (t0) = %i\n", @(Ecount t0));
  print ("t1 = "); print t1; print_newline ();
  printf ("Bcount (t1) = %i\n", @(Bcount t1));
  printf ("Ecount (t1) = %i\n", @(Ecount t1));
  print ("t2 = "); print t2; print_newline ();
  printf ("Bcount (t2) = %i\n", @(Bcount t2));
  printf ("Ecount (t2) = %i\n", @(Ecount t2));
  print ("t3 = "); print t3; print_newline ();
  printf ("Bcount (t3) = %i\n", @(Bcount t3));
  printf ("Ecount (t3) = %i\n", @(Ecount t3));
  print ("t4 = "); print t4; print_newline ();
  printf ("Bcount (t4) = %i\n", @(Bcount t4));
  printf ("Ecount (t4) = %i\n", @(Ecount t4));
end // end of [main]

(* ****** ****** *)

(* end of [bintree-2008-09-05.dats] *)