add function to extend an existing match, and add tests for it

This commit is contained in:
2026-02-07 00:29:58 +00:00
parent b02b2f53da
commit 0ea0d44da3
2 changed files with 119 additions and 2 deletions

View File

@@ -807,7 +807,7 @@ struct
val matchAfterFinish = nextMatch (finish, tree, 1)
in
if matchAfterFinish <= finish then
(* no match after the 'finish', so we just append *)
(* no match after the 'finish', so we can just append to 'tree' *)
append (start, finish, tree)
else
let
@@ -825,6 +825,31 @@ struct
end
end
fun extendExistingMatch (start, newFinish, tree) =
let
val matchAfterFinish = nextMatch (newFinish, tree, 1)
val left = splitLeft (start, tree)
val left = append (start, newFinish, left)
in
if matchAfterFinish <= newFinish then
(* no match after newFinish, so we can return 'left'
* which has the newFinish appended *)
left
else
let
val right = splitRight (newFinish, tree)
val leftFinish = getFinishIdx left
val rightStartRelative = getStartIdx right
val rightStartAbsolute = rightStartRelative + leftFinish
val difference = rightStartAbsolute - matchAfterFinish
val right = decrementBy (difference, right)
in
merge (left, right)
end
end
(* functions only for testing *)
fun childrenHaveSameDepth (pos, nodes, expectedDepth) =
if pos = Vector.length nodes then

View File

@@ -45,6 +45,19 @@ struct
loopInRange lst
end
fun printVec pv =
let
val outputList = PersistentVector.toList pv
val str =
List.map
(fn {start, finish} =>
"{start = " ^ Int.toString start ^ ", finish = "
^ Int.toString finish ^ "}") outputList
val str = String.concatWith "\n " str ^ "\n"
in
print str
end
val appendTests = describe "PersistentVector.append"
[ test "contains appended values in range" (fn _ =>
let
@@ -508,5 +521,84 @@ struct
end)
]
val tests = [appendTests, toListTests, splitLeftTests, deleteTests]
val extendExistingMatchTests = describe "PersistentVector.extendExistingMatch"
[ test
"leaves subsequent matches untouched \
\if their 'finish' is greater than the extended finish"
(fn _ =>
let
(* arrange *)
val inputList =
[ {start = 1, finish = 1}
, {start = 2, finish = 2}
, {start = 3, finish = 3}
, {start = 4, finish = 4}
, {start = 5, finish = 5}
, {start = 60, finish = 60}
, {start = 70, finish = 70}
, {start = 80, finish = 80}
]
val pv = PersistentVector.fromList inputList
(* act *)
val pv = PersistentVector.extendExistingMatch (5, 50, pv)
(* assert *)
val outputList = PersistentVector.toList pv
val expectedOutput =
[ {start = 1, finish = 1}
, {start = 2, finish = 2}
, {start = 3, finish = 3}
, {start = 4, finish = 4}
, {start = 5, finish = 50}
, {start = 60, finish = 60}
, {start = 70, finish = 70}
, {start = 80, finish = 80}
]
in
Expect.isTrue (outputList = expectedOutput)
end)
, test
"removes subsequent matches whose 'finish' is less than \
\the newly extended element's 'finish'"
(fn _ =>
let
(* arrange *)
val inputList =
[ {start = 1, finish = 1}
, {start = 2, finish = 2}
, {start = 3, finish = 3}
, {start = 4, finish = 4}
, {start = 5, finish = 5}
, {start = 60, finish = 60}
, {start = 70, finish = 70}
, {start = 80, finish = 80}
]
val pv = PersistentVector.fromList inputList
(* act *)
val pv = PersistentVector.extendExistingMatch (5, 75, pv)
(* assert *)
val outputList = PersistentVector.toList pv
val expectedOutput =
[ {start = 1, finish = 1}
, {start = 2, finish = 2}
, {start = 3, finish = 3}
, {start = 4, finish = 4}
, {start = 5, finish = 75}
, {start = 80, finish = 80}
]
in
Expect.isTrue (outputList = expectedOutput)
end)
]
val tests =
[ appendTests
, toListTests
, splitLeftTests
, deleteTests
, extendExistingMatchTests
]
end