(*
** Course: Concepts of Programming Languages (BU CAS CS 320)
** Semester: Summer I, 2009
** Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
*)

//
// Author: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Time: June 8, 2009
//

#include "BUCASCS320.hats"

//
// for linked lists
// 
datatype llist (a:t@ype) =
  | llist_cons (a) of (a, ref (llist a)) | llist_nil (a) of ()
// end of [llist]

fun{a:t@ype} llist_length (xs: llist a): int =
  case+ xs of
  | llist_cons (x, r_xs) => 1 + llist_length (!r_xs)
  | llist_nil () => 0

fun{a:t@ype} llist_foreach
  (xs: llist a, f: a -<cloref1> void): void =
  case+ xs of
  | llist_cons (x, r_xs) => (f x; llist_foreach (!r_xs, f))
  | llist_nil () => ()
// end of [llist_foreach]

fun{a:t@ype} llist_reverse
  (xs: llist a): llist a = loop (xs, llist_nil) where {
  fun loop (xs: llist a, ys: llist a): llist a =
    case+ xs of
    | llist_cons (x, r_xs) => let
        val xs_nxt = !r_xs in !r_xs := ys; loop (xs_nxt, xs)
      end // end of [llist_cons]   
    | llist_nil () => ys
  // end of [loop]
} // end of [llist_reverse]

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

val xs1 = llist_cons (1, ref (llist_cons (2, ref (llist_cons (3, ref llist_nil)))))
val () = print "xs1=\n"
val () = llist_foreach<int> (xs1, lam x => (print_int x; print_newline ())  )
val () = print "xs2=\n"
val xs2 = llist_reverse (xs1)
val () = llist_foreach<int> (xs2, lam x => (print_int x; print_newline ())  )
val () = print "xs1=\n"
val () = llist_foreach<int> (xs1, lam x => (print_int x; print_newline ())  )

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

implement main () = ()

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

(* end of [linkedlist.dats] *)