```(*
** 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"

//
//
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 () = ()

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