add code for deleting from rope.sml
This commit is contained in:
108
rope.sml
108
rope.sml
@@ -16,6 +16,8 @@ sig
|
|||||||
val append: string * t -> t
|
val append: string * t -> t
|
||||||
val appendLine: string * int vector * 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,
|
(* This below function verifies that line metadata is as expected,
|
||||||
* raising an exception if it is different,
|
* raising an exception if it is different,
|
||||||
* and returning true if it is the same. *)
|
* and returning true if it is the same. *)
|
||||||
@@ -544,6 +546,112 @@ struct
|
|||||||
in endInsert (rope, action)
|
in endInsert (rope, action)
|
||||||
end
|
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 =
|
fun verifyLines rope =
|
||||||
foldr
|
foldr
|
||||||
( (fn (_, str, vec) =>
|
( (fn (_, str, vec) =>
|
||||||
|
|||||||
@@ -306,7 +306,6 @@ struct
|
|||||||
end
|
end
|
||||||
else if startIdx >= 0 andalso endIdx >= String.size str then
|
else if startIdx >= 0 andalso endIdx >= String.size str then
|
||||||
let
|
let
|
||||||
val start = Int.toString startIdx
|
|
||||||
val str = String.substring (str, 0, startIdx)
|
val str = String.substring (str, 0, startIdx)
|
||||||
in
|
in
|
||||||
(N0 str, false)
|
(N0 str, false)
|
||||||
|
|||||||
Reference in New Issue
Block a user