//
// Course: BU CAS CS 520, Fall 2010
// Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu)
// Lecture on Tuesday, Nov 2, 2010
//

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

staload "prelude/DATS/pointer.dats"

dataview
charr_v (int(*n*), addr(*l*)) =
  | {l:addr} charr_v_nil (0, l)
  | {n:nat} {l:addr}
     charr_v_cons (n+1, l) of (char @ l, charr_v (n, l+1))
// end of [charr_v]

prfun
charr_v_uncons
  {n:pos} {l:addr} .<>.
  (pf: charr_v (n, l))
  : (char @ l, charr_v (n-1, l+1)) = let
  prval charr_v_cons (pf1, pf2) = pf
in
  (pf1, pf2)
end // end of [charr_v_uncons]

fun charr_getfst
  {n:pos} {l:addr}
  (pf: !charr_v (n, l) | p: ptr l): char = let
  prval (pf1, pf2) = charr_v_uncons (pf)
  val c = ptr_get_t<char> (pf1 | p)
  prval () = pf := charr_v_cons (pf1, pf2)
in
  c
end // end of [charr_getfst]

fun charr_get
  {n,i:nat | i < n} {l:addr} .<n>. (
  pf: !charr_v (n, l) | p: ptr l, i: int i
) : char = let
  prval (pf1, pf2) = charr_v_uncons (pf)
in
  if i = 0 then let
    val c = !p
    prval () = pf := charr_v_cons (pf1, pf2)    
  in
    c
  end else let
    val c = charr_get (pf2 | p+1, i-1)
    prval () = pf := charr_v_cons (pf1, pf2)    
  in
    c
  end // end of [if]
end // end of [charr_get]

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

(* end of [charr.dats] *)