add code for deleting from rope.sml

This commit is contained in:
2024-03-14 23:05:36 +00:00
parent 8ea6d2c1b7
commit 571b16ba6c
2 changed files with 108 additions and 1 deletions

108
rope.sml
View File

@@ -16,6 +16,8 @@ sig
val append: string * t -> t
val appendLine: string * int vector * t -> t
val delete: int * int * t -> t
(* This below function verifies that line metadata is as expected,
* raising an exception if it is different,
* and returning true if it is the same. *)
@@ -544,6 +546,112 @@ struct
in endInsert (rope, action)
end
fun delLeaf (startIdx, endIdx, str, vec) =
if
startIdx <= 0 andalso endIdx >= String.size str
then
(empty, false)
else if
startIdx > 0 andalso endIdx < String.size str
then
let
val sub1 = String.substring (str, 0, startIdx)
val sub2 = String.substring (str, endIdx, (String.size str - endIdx))
val vecLength = Vector.length vec - 1
val startPoint = binSearch (startIdx, vec, 0, vecLength)
val endPoint = binSearch (endIdx, vec, 0, vecLength)
val difference = endIdx - startIdx
in
if isLessThanTarget (sub1, sub2) then
let
val str = sub1 ^ sub2
val vecDifference = endPoint - startPoint
val vecLength = Vector.length vec - vecDifference
val vec = Vector.tabulate (vecLength, (fn idx =>
let val point = Vector.sub (vec, idx)
in if point < startIdx then point else point - difference
end))
in
(N0 (str, vec), false)
end
else
let
val vec1 =
if Vector.length vec = 0 then
emptyVec
else
Vector.tabulate (startPoint, (fn idx => Vector.sub (vec, idx)))
val vec2 =
if Vector.length vec = 0 then
emptyVec
else
Vector.tabulate (Vector.length vec - startPoint, (fn idx =>
Vector.sub (vec, idx + startPoint) - difference))
in
(L2 (sub1, vec1, sub2, vec2), true)
end
end
else if
startIdx >= 0 andalso startIdx <= String.size str
andalso endIdx >= String.size str
then
let
val str = String.substring (str, 0, startIdx)
val midPoint = binSearch (startIdx, vec, 0, vecLength)
val vec =
if Vector.length vec = 0 then emptyVec
else Vector.tabulate (midPoint, fn idx => Vector.sub (vec, idx))
in
(N0 (str, vec), false)
end
else
let
val str = String.substring (str, endIdx, String.size str - endIdx)
val midPoint = binSearch (endIdx, vec, 0, vecLength)
val vec =
if Vector.length vec = 0 then
emptyVec
else
Vector.tabulate (Vector.length vec - midPoint, fn idx =>
Vector.sub (vec, idx + midPoint))
in
(N0 (str, vec), false)
end
fun del (startIdx, endIdx, rope) =
case rope of
N2 (l, lms, lmv, r) =>
if lms > startIdx andalso lms > endIdx then
let
val (l, didIns) = del (startIdx, endIdx, l)
val rope = if didIns then insN2Left (l, r) else makeN2 (l, r)
in
(rope, didIns)
end
else if lms < startIdx andalso lms < endIdx then
let
val (r, didIns) = del (startIdx - lms, endIdx - lms, r)
val rope = if didIns then insN2Right (l, r) else makeN2 (l, r)
in
(rope, didIns)
end
else
let
val (l, _) = del (startIdx, endIdx, l)
val (r, _) = del (startIdx - lms, endIdx - lms, r)
in
makeN2 (l, r)
end
| N1 t => del (startIdx, endIdx, t)
| N0 (str, vec) => delLeaf (startIdx, endIdx, str, vec)
fun delete (start, length, rope) =
let val (rope, didIns) = del (start, start + length, rope)
in if didIns then insRoot rope else rope
end
fun verifyLines rope =
foldr
( (fn (_, str, vec) =>