init
This commit is contained in:
183
rope.sml
Normal file
183
rope.sml
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
datatype rope =
|
||||||
|
N0 of string
|
||||||
|
| N1 of rope
|
||||||
|
| N2 of rope * int * int * rope
|
||||||
|
| L2 of string * string
|
||||||
|
| N3 of rope * rope * rope
|
||||||
|
|
||||||
|
val target_length = 1024
|
||||||
|
val empty = N0 ""
|
||||||
|
fun of_string string = N0 string
|
||||||
|
|
||||||
|
fun size rope =
|
||||||
|
case rope of
|
||||||
|
N0 s => String.size s
|
||||||
|
| N1 t => size t
|
||||||
|
| N2(_, lm, rm, _) => lm + rm
|
||||||
|
| N3(t1, t2, t3) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val t3_size = size t3
|
||||||
|
in
|
||||||
|
t1_size + t2_size + t3_size
|
||||||
|
end
|
||||||
|
| _ => raise Empty
|
||||||
|
|
||||||
|
fun root rope =
|
||||||
|
case rope of
|
||||||
|
L2(s1, s2) => N2(N0 s1, String.size s1, String.size s2, N0 s2)
|
||||||
|
| N3(t1, t2, t3) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val left = N2(t1, t1_size, t2_size, t2)
|
||||||
|
val left_size = t1_size + t2_size
|
||||||
|
val t3_size = size t3
|
||||||
|
in
|
||||||
|
N2(left, left_size, t3_size, N1 t3)
|
||||||
|
end
|
||||||
|
| t => t
|
||||||
|
|
||||||
|
fun n1 rope =
|
||||||
|
case rope of
|
||||||
|
L2(s1, s2) =>
|
||||||
|
N2(N0 s1, String.size s1, String.size s2, N0 s2)
|
||||||
|
| N3(t1, t2, t3) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val left = N2(t1, t1_size, t2_size, t2)
|
||||||
|
val left_size = t1_size + t2_size
|
||||||
|
val t3_size = size t3
|
||||||
|
in
|
||||||
|
N2(left, left_size, t3_size, t3)
|
||||||
|
end
|
||||||
|
| t => N1 t
|
||||||
|
|
||||||
|
fun ins_n2_left left right =
|
||||||
|
case (left, right) of
|
||||||
|
(L2(s1, s2), t3) => N3(N0 s1, N0 s2, t3)
|
||||||
|
| (N3(t1, t2, t3), N1 t4) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val left = N2(t1, t1_size, t2_size, t2)
|
||||||
|
val left_size = t1_size + t2_size
|
||||||
|
val t3_size = size t3
|
||||||
|
val t4_size = size t4
|
||||||
|
val right = N2(t3, t3_size, t4_size, t4)
|
||||||
|
val right_size = t3_size + t4_size
|
||||||
|
in
|
||||||
|
N2(left, left_size, right_size, right)
|
||||||
|
end
|
||||||
|
| (N3(t1, t2, t3), t4 as N2 _) =>
|
||||||
|
let
|
||||||
|
val left = N2(t1, size t1, size t2, t2)
|
||||||
|
in
|
||||||
|
N3(left, N1 t3, t4)
|
||||||
|
end
|
||||||
|
| (N3(t1, t2, t3), t4) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val left = N2(t1, t1_size, t2_size, t2)
|
||||||
|
val t3_size = size t3
|
||||||
|
val t4_size = size t4
|
||||||
|
val right = N2(t3, t3_size, t4_size, t4)
|
||||||
|
val left_size = t1_size + t2_size
|
||||||
|
val right_size = t3_size + t4_size
|
||||||
|
in
|
||||||
|
N2(left, left_size, right_size, right)
|
||||||
|
end
|
||||||
|
| (l, r) =>
|
||||||
|
N2(l, size l, size r, r)
|
||||||
|
|
||||||
|
fun ins_n2_right left right =
|
||||||
|
case (left, right) of
|
||||||
|
(t1, L2(s1, s2)) => N3(t1, N0 s1, N0 s2)
|
||||||
|
| (N1 t1, N3(t2, t3, t4)) =>
|
||||||
|
let
|
||||||
|
val t1_size = size t1
|
||||||
|
val t2_size = size t2
|
||||||
|
val left = N2(t1, t1_size, t2_size, t2)
|
||||||
|
val t3_size = size t3
|
||||||
|
val t4_size = size t4
|
||||||
|
val right = N2(t3, t3_size, t4_size, t4)
|
||||||
|
val right_size = t3_size + t4_size
|
||||||
|
val left_size = t1_size + t2_size
|
||||||
|
in
|
||||||
|
N2(left, left_size, right_size, right)
|
||||||
|
end
|
||||||
|
| (t1 as N2 _, N3(t2, t3, t4)) =>
|
||||||
|
let
|
||||||
|
val right = N2(t3, size t3, size t4, t4)
|
||||||
|
in
|
||||||
|
N3(t1, N1 t2, right)
|
||||||
|
end
|
||||||
|
| (l, r) =>
|
||||||
|
N2(l, size l, size r, r)
|
||||||
|
|
||||||
|
fun ins cur_index string rope =
|
||||||
|
case rope of
|
||||||
|
N0 str =>
|
||||||
|
let
|
||||||
|
val old_str_size = String.size str
|
||||||
|
val ins_str_size = String.size string
|
||||||
|
val total_str_size = old_str_size + ins_str_size
|
||||||
|
val left_size = ins_str_size + cur_index
|
||||||
|
val prefer_left = left_size <= target_length
|
||||||
|
val right_size = ins_str_size - cur_index
|
||||||
|
val prefer_right = right_size <= target_length
|
||||||
|
in
|
||||||
|
if cur_index <= 0 then
|
||||||
|
if total_str_size <= target_length then
|
||||||
|
N0(string ^ str)
|
||||||
|
else L2(string, str)
|
||||||
|
else if cur_index >= old_str_size then
|
||||||
|
if total_str_size <= target_length then
|
||||||
|
N0(str ^ string)
|
||||||
|
else L2(str, string)
|
||||||
|
else if total_str_size <= target_length then
|
||||||
|
let
|
||||||
|
val str1 = String.substring(str, 0, cur_index)
|
||||||
|
val str3 = String.substring(str, cur_index, old_str_size - cur_index)
|
||||||
|
in
|
||||||
|
N0(String.concat [str1, string, str3])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val str1 = String.substring(str, 0, cur_index)
|
||||||
|
val str3 = String.substring(str, cur_index, old_str_size - cur_index)
|
||||||
|
in
|
||||||
|
if prefer_left then
|
||||||
|
L2(str1 ^ string, str3)
|
||||||
|
else if prefer_right then
|
||||||
|
L2(str1, string ^ str3)
|
||||||
|
else
|
||||||
|
N3(N0 str1, N0 string, N0 str3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
| N1 t =>
|
||||||
|
let
|
||||||
|
val t = ins cur_index string t
|
||||||
|
in
|
||||||
|
n1 t
|
||||||
|
end
|
||||||
|
| N2(l, lm, _, r) =>
|
||||||
|
if cur_index < lm then
|
||||||
|
let
|
||||||
|
val l = ins cur_index string l
|
||||||
|
in
|
||||||
|
ins_n2_left l r
|
||||||
|
end
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val next_index = cur_index - lm
|
||||||
|
val r = ins next_index string r
|
||||||
|
in
|
||||||
|
ins_n2_right l r
|
||||||
|
end
|
||||||
|
| _ => raise Empty
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user