fully implement substring for line_gap.sml

This commit is contained in:
2024-11-10 11:13:12 +00:00
parent 2cd6605ee4
commit c2e74d89fd

View File

@@ -14,6 +14,7 @@ sig
val fromString: string -> t val fromString: string -> t
val toString: t -> string val toString: t -> string
val substring: int * int * t -> string
val delete: int * int * t -> t val delete: int * int * t -> t
val insert: int * string * t -> t val insert: int * string * t -> t
@@ -1964,7 +1965,7 @@ struct
val acc = accHd :: acc val acc = accHd :: acc
val acc = List.rev acc val acc = List.rev acc
in in
String.concat acc acc
end end
else else
(* nextIdx = finish (* nextIdx = finish
@@ -1973,16 +1974,17 @@ struct
val acc = hd :: acc val acc = hd :: acc
val acc = List.rev acc val acc = List.rev acc
in in
String.concat acc acc
end
end end
| [] => | [] =>
let let
val acc = List.rev acc val acc = List.rev acc
in in
String.concat acc acc
end end
fun moveRightAndSub (start, finish, curIdx, left, right) = fun moveRightAndSub (start, finish, curIdx, right) =
case right of case right of
hd :: tl => hd :: tl =>
let let
@@ -1990,8 +1992,7 @@ struct
in in
if nextIdx < start then if nextIdx < start then
(* continue moving rightwards *) (* continue moving rightwards *)
moveRightAndSub moveRightAndSub (start, finish, nextIdx, tl)
(start, finish, nextIdx, hd :: left, tl)
else if nextIdx > start then else if nextIdx > start then
if nextIdx < finish then if nextIdx < finish then
(* get starting acc, (* get starting acc,
@@ -2000,8 +2001,9 @@ struct
val substart = start - curIdx val substart = start - curIdx
val length = String.size hd - substart val length = String.size hd - substart
val acc = [String.substring (hd, substart, length)] val acc = [String.substring (hd, substart, length)]
val acc = subRightFromHere (nextIdx, finish, tl, acc)
in in
subRightFromHere (nextIdx, finish, tl, acc) String.concat acc
end end
else if nextIdx > finish then else if nextIdx > finish then
(* have to get susbstring from middle of this string *) (* have to get susbstring from middle of this string *)
@@ -2024,7 +2026,11 @@ struct
(* nextIdx = start (* nextIdx = start
* so we have to ignore this string * so we have to ignore this string
* and start building acc from tl *) * and start building acc from tl *)
subRightFromHere (nextIdx, finish, tl, acc) let
val acc = subRightFromHere (nextIdx, finish, tl, [])
in
String.concat acc
end
end end
| [] => | [] =>
(* if there are no strings to the right, (* if there are no strings to the right,
@@ -2032,7 +2038,7 @@ struct
* as we cannot do much else. *) * as we cannot do much else. *)
"" ""
fun subLeftFromHere (start, curIdx, left, right, acc) = fun subLeftFromHere (start, curIdx, left, acc) =
case left of case left of
hd :: tl => hd :: tl =>
let let
@@ -2062,19 +2068,85 @@ struct
end end
end end
| [] => String.concat acc | [] => String.concat acc
fun subFromLeftAndRight (start, finish, curIdx, left, right) =
let
val acc = subRightFromHere (curIdx, finish, right, [])
in in
subLeftFromHere (start, curIdx, left, acc)
end
fun moveLeftAndSub (start, finish, curIdx, left) =
case left of
hd :: tl =>
let
val prevIdx = curIdx - String.size hd
in
if prevIdx > finish then
(* continue *)
moveLeftAndSub (start, finish, prevIdx, tl)
else if prevIdx < finish then
if prevIdx > start then
(* get initial acc
* and continue substring leftwards *)
let
val length = finish - prevIdx
val acc = [String.substring (hd, 0, length)]
in
subLeftFromHere (start, prevIdx, tl, acc)
end
else if prevIdx < start then
(* we want to return a substring
* extracted from the middle of hd *)
let
val substart = start - prevIdx
val subfinish = finish - prevIdx
val length = subfinish - substart
in
String.substring (hd, substart, length)
end
else
(* prevIdx = start
* we want to return a substring starting from 0 *)
let
val subfinish = finish - prevIdx
val length = String.size hd - subfinish
in
String.substring (hd, 0, length)
end
else
(* prevIdx = finish
* so we want to ignore hd and start
* subLeftFromHere with an empty list *)
subLeftFromHere (start, prevIdx, tl, [])
end
| [] => ""
fun sub (start, finish, curIdx, left, right) = fun sub (start, finish, curIdx, left, right) =
if start > curIdx then if start > curIdx then
(* move rightwards to begin getting substring *) (* move rightwards to begin getting substring *)
moveRightAndSub (start, finish, curIdx, left, right) moveRightAndSub (start, finish, curIdx, right)
else if start < curIdx then else if start < curIdx then
if finish <= curIdx then if finish <= curIdx then
moveLeftAndSub (start, finish, curIdx, left, right) moveLeftAndSub (start, finish, curIdx, left)
else else
(* in middle of buffer we want to get substring from *) (* in middle of buffer we want to get substring from *)
subFromLeftAndRight (start, finish, curIdx, left, right) subFromLeftAndRight (start, finish, curIdx, left, right)
else else
subRightFromHere (curIdx, finish, right, []) let
(* start = curIdx so only need to traverse right *)
val acc = subRightFromHere (curIdx, finish, right, [])
in
String.concat acc
end
in
fun substring (start, length, buffer : t) =
let
val finish = start + length
val {idx, leftStrings, rightStrings, ...} = buffer
in
sub (start, finish, idx, leftStrings, rightStrings)
end
end end
fun helpGoToStart fun helpGoToStart