refactor many functions in cursor.sml so they don't need to be mutually recursive

This commit is contained in:
2024-10-25 15:25:39 +01:00
parent 8b3bd97af3
commit b79a8696f5
2 changed files with 109 additions and 149 deletions

View File

@@ -1,27 +1,19 @@
structure Cursor = structure Cursor =
struct struct
fun helpVi0String (strPos, str, absIdx, strTl, lineTl) = fun helpVi0 (strPos, str, absIdx, strTl, lineTl) =
if strPos < 0 then if strPos < 0 then
helpVi0List (strTl, lineTl, absIdx) case (strTl, lineTl) of
(shd :: stl, lhd :: ltl) =>
helpVi0
(String.size shd - 1, shd, absIdx, stl, ltl)
| (_, _) =>
0
else else
case String.sub (str, strPos) of case String.sub (str, strPos) of
#"\n" => #"\n" =>
absIdx + 1 absIdx + 1
| _ => | _ =>
helpVi0String (strPos - 1, str, absIdx - 1, strTl, lineTl) helpVi0 (strPos - 1, str, absIdx - 1, strTl, lineTl)
and helpVi0List (strings, lines, absIdx) =
case (strings, lines) of
(strHd::strTl, lineHd::lineTl) =>
helpVi0String
( String.size strHd - 1, strHd, absIdx
, strTl, lineTl
)
| (_, _) =>
(* this case means strings and lines are empty
* and empty means we are at first line
* so we can return 0 *)
0
fun vi0 (lineGap: LineGap.t, cursorIdx) = fun vi0 (lineGap: LineGap.t, cursorIdx) =
let let
@@ -43,7 +35,7 @@ struct
cursorIdx cursorIdx
else else
(* not at newline so start iterating *) (* not at newline so start iterating *)
helpVi0String helpVi0
( strIdx - 1, strHd, cursorIdx - 1 ( strIdx - 1, strHd, cursorIdx - 1
, strTl, lnTl , strTl, lnTl
) )
@@ -59,7 +51,7 @@ struct
cursorIdx cursorIdx
else else
(* not in linebreak *) (* not in linebreak *)
helpVi0String helpVi0
( strIdx - 1, nestStrHd, cursorIdx - 1 ( strIdx - 1, nestStrHd, cursorIdx - 1
, strHd :: leftStrings, lnHd :: leftLines , strHd :: leftStrings, lnHd :: leftLines
) )
@@ -71,28 +63,22 @@ struct
cursorIdx cursorIdx
end end
fun helpViDlrString (strPos, str, absIdx, strTl, lineTl) = fun helpViDlr (strPos, str, absIdx, strTl, lineTl) =
if strPos = String.size str then if strPos = String.size str then
helpViDlrList (strTl, lineTl, absIdx) case (strTl, lineTl) of
(shd :: stl, lhd :: ltl) =>
helpViDlr
(0, shd, absIdx, stl, ltl)
| (_, _) =>
absIdx - 1
else else
case String.sub (str, strPos) of case String.sub (str, strPos) of
#"\n" => #"\n" =>
absIdx - 1 absIdx - 1
| _ => | _ =>
helpViDlrString (strPos + 1, str, absIdx + 1, strTl, lineTl) helpViDlr (strPos + 1, str, absIdx + 1, strTl, lineTl)
and helpViDlrList (strings, lines, absIdx) = fun viDlr (lineGap: LineGap.t, cursorIdx) =
case (strings, lines) of
(strHd::strTl, lineHd::lineTl) =>
helpViDlrString
(0, strHd, absIdx , strTl, lineTl)
| (_, _) =>
(* this case means strings and lines are empty
* and empty means we have reached end of lineGap
* so we can return last chr *)
absIdx - 1
fun viDlr(lineGap: LineGap.t, cursorIdx) =
let let
val val
{rightStrings, idx = bufferIdx, rightLines, leftStrings, leftLines, ...} = {rightStrings, idx = bufferIdx, rightLines, leftStrings, leftLines, ...} =
@@ -107,7 +93,7 @@ struct
if strIdx < String.size strHd then if strIdx < String.size strHd then
if String.sub (strHd, strIdx) <> #"\n" then if String.sub (strHd, strIdx) <> #"\n" then
(* not in double linebreak *) (* not in double linebreak *)
helpViDlrString helpViDlr
(strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl)
else else
(* check if we are in double linebreak *) (* check if we are in double linebreak *)
@@ -117,7 +103,7 @@ struct
cursorIdx cursorIdx
else else
(* not in double linebreak, so iterate *) (* not in double linebreak, so iterate *)
helpViDlrString helpViDlr
(strIdx + 1, strHd, cursorIdx + 1 , strTl, lnTl) (strIdx + 1, strHd, cursorIdx + 1 , strTl, lnTl)
else else
(* check if double linebreak in strTl *) (* check if double linebreak in strTl *)
@@ -126,7 +112,7 @@ struct
if String.sub (nestStrHd, 0) = #"\n" then if String.sub (nestStrHd, 0) = #"\n" then
cursorIdx cursorIdx
else else
helpViDlrString helpViDlr
(strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl) (strIdx + 1, strHd, cursorIdx + 1, strTl, lnTl)
| [] => cursorIdx) | [] => cursorIdx)
else else
@@ -136,7 +122,7 @@ struct
let let
val strIdx = strIdx - String.size strHd val strIdx = strIdx - String.size strHd
in in
helpViDlrString helpViDlr
(strIdx + 1, nestStrHd, cursorIdx + 1, nestStrTl, nestLnTl) (strIdx + 1, nestStrHd, cursorIdx + 1, nestStrTl, nestLnTl)
end end
| (_, _) => cursorIdx) | (_, _) => cursorIdx)
@@ -438,14 +424,28 @@ struct
| (_, _) => helpGetCursorColumn (0, leftStrings, leftLines) | (_, _) => helpGetCursorColumn (0, leftStrings, leftLines)
end end
fun helpViJString fun helpViJ
( strPos, str, absIdx ( strPos, str, absIdx
, lineColumn, preferredColumn, hasPassedLine , lineColumn, preferredColumn, hasPassedLine
, strTl, lineTl , strTl, lineTl
) = ) =
if strPos = String.size str then if strPos = String.size str then
helpViJList case (strTl, lineTl) of
(absIdx, lineColumn, preferredColumn, hasPassedLine, strTl, lineTl) (shd :: stl, lhd :: ltl) =>
(* todo: possibly check if we have passed line,
* and if so, if there are any line breaks in the lineHd
* which we could use to skip searching part of the string.
* However, this will likely have worse cache locality
* as we switch to searching in string to searcing in line vector
* so perhaps not. *)
helpViJ
( 0, shd, absIdx
, lineColumn, preferredColumn, hasPassedLine
, stl, ltl
)
| (_, _) =>
(* empty, so return end of previous string *)
absIdx - 1
else else
case String.sub (str, strPos) of case String.sub (str, strPos) of
#"\n" => #"\n" =>
@@ -484,7 +484,7 @@ struct
if String.sub (str, strPos + 1) = #"\n" then if String.sub (str, strPos + 1) = #"\n" then
absIdx + 1 absIdx + 1
else else
helpViJString helpViJ
( strPos + 1, str, absIdx + 1 ( strPos + 1, str, absIdx + 1
, 0, preferredColumn, true , 0, preferredColumn, true
, strTl, lineTl , strTl, lineTl
@@ -498,7 +498,7 @@ struct
absIdx + 1 absIdx + 1
else else
(* not in double linebreak *) (* not in double linebreak *)
helpViJString helpViJ
( strPos + 1, str, absIdx + 1 ( strPos + 1, str, absIdx + 1
, 0, preferredColumn, true , 0, preferredColumn, true
, strTl, lineTl , strTl, lineTl
@@ -512,31 +512,12 @@ struct
absIdx absIdx
else else
(* we're not in the preferred column, so keep iterating *) (* we're not in the preferred column, so keep iterating *)
helpViJString helpViJ
( strPos + 1, str, absIdx + 1 ( strPos + 1, str, absIdx + 1
, lineColumn + 1, preferredColumn, hasPassedLine , lineColumn + 1, preferredColumn, hasPassedLine
, strTl, lineTl , strTl, lineTl
) )
and helpViJList
(absIdx, lineColumn, preferredColumn, hasPassedLine, strings, lines) =
case (strings, lines) of
(strHd :: strTl, lineHd :: lineTl) =>
(* todo: possibly check if we have passed line,
* and if so, if there are any line breaks in the lineHd
* which we could use to skip searching part of the string.
* However, this will likely have worse cache locality
* as we switch to searching in string to searcing in line vector
* so perhaps not. *)
helpViJString
( 0, strHd, absIdx
, lineColumn, preferredColumn, hasPassedLine
, strTl, lineTl
)
| (_, _) =>
(* empty, so return end of previous string *)
absIdx - 1
fun viJ (lineGap: LineGap.t, cursorIdx) = fun viJ (lineGap: LineGap.t, cursorIdx) =
let let
val val
@@ -559,7 +540,7 @@ struct
* for that condition at the end. * for that condition at the end.
* So there is no way at the start of a navigation function * So there is no way at the start of a navigation function
* that cursor is in a double linebreak incorrectly. *) * that cursor is in a double linebreak incorrectly. *)
helpViJString helpViJ
(strIdx + 1, strHd, cursorIdx + 1, 0, 0, true, strTl, lnTl) (strIdx + 1, strHd, cursorIdx + 1, 0, 0, true, strTl, lnTl)
else else
(* not at newline (* not at newline
@@ -567,7 +548,7 @@ struct
let let
val lineColumn = getCursorColumn (lineGap, cursorIdx) val lineColumn = getCursorColumn (lineGap, cursorIdx)
in in
helpViJString helpViJ
( strIdx + 1, strHd, cursorIdx + 1 ( strIdx + 1, strHd, cursorIdx + 1
, lineColumn, lineColumn, false , lineColumn, lineColumn, false
, strTl, lnTl , strTl, lnTl
@@ -581,7 +562,7 @@ struct
val strIdx = strIdx - String.size strHd val strIdx = strIdx - String.size strHd
in in
if String.sub (nestStrHd, strIdx) = #"\n" then if String.sub (nestStrHd, strIdx) = #"\n" then
helpViJString helpViJ
( strIdx + 1, nestStrHd, cursorIdx + 1 ( strIdx + 1, nestStrHd, cursorIdx + 1
, 0, 0, true , 0, 0, true
, nestStrTl, nestLnTl , nestStrTl, nestLnTl
@@ -591,7 +572,7 @@ struct
let let
val lineColumn = getCursorColumn (lineGap, cursorIdx) val lineColumn = getCursorColumn (lineGap, cursorIdx)
in in
helpViJString helpViJ
( strIdx + 1, nestStrHd, cursorIdx + 1 ( strIdx + 1, nestStrHd, cursorIdx + 1
, lineColumn, lineColumn, false , lineColumn, lineColumn, false
, nestStrTl, nestStrTl , nestStrTl, nestStrTl
@@ -605,14 +586,22 @@ struct
cursorIdx cursorIdx
end end
fun helpViKString fun helpViK
( strPos, str, absIdx ( strPos, str, absIdx
, lineColumn, preferredColumn, hasPassedLine , lineColumn, preferredColumn, hasPassedLine
, strTl, lineHd, lineTl , strTl, lineHd, lineTl
) = ) =
if strPos < 0 then if strPos < 0 then
helpViKList case (strTl, lineTl) of
(absIdx, lineColumn, preferredColumn, hasPassedLine, strTl, lineTl) (shd :: stl, lhd :: ltl) =>
helpViK
( String.size shd - 1, shd, absIdx
, lineColumn, preferredColumn, hasPassedLine
, stl, lhd, ltl
)
| (_, _) =>
(* empty, so return start of previous string *)
absIdx + 1
else else
case String.sub (str, strPos) of case String.sub (str, strPos) of
#"\n" => #"\n" =>
@@ -659,7 +648,7 @@ struct
helpGetCursorColumnBranch helpGetCursorColumnBranch
(strPos - 1, str, lineHd, strTl, lineTl) (strPos - 1, str, lineHd, strTl, lineTl)
in in
helpViKString helpViK
( strPos - 1, str, absIdx - 1 ( strPos - 1, str, absIdx - 1
, lineColumn, preferredColumn, true , lineColumn, preferredColumn, true
, strTl, lineHd, lineTl , strTl, lineHd, lineTl
@@ -679,7 +668,7 @@ struct
helpGetCursorColumnBranch helpGetCursorColumnBranch
(strPos - 1, str, lineHd, strTl, lineTl) (strPos - 1, str, lineHd, strTl, lineTl)
in in
helpViKString helpViK
( strPos - 1, str, absIdx - 1 ( strPos - 1, str, absIdx - 1
, lineColumn, preferredColumn, true , lineColumn, preferredColumn, true
, strTl, lineHd, lineTl , strTl, lineHd, lineTl
@@ -698,31 +687,12 @@ struct
absIdx absIdx
else else
(* we're not in the preferred column, so keep iterating *) (* we're not in the preferred column, so keep iterating *)
helpViKString helpViK
( strPos - 1, str, absIdx - 1 ( strPos - 1, str, absIdx - 1
, lineColumn - 1, preferredColumn, hasPassedLine , lineColumn - 1, preferredColumn, hasPassedLine
, strTl, lineHd, lineTl , strTl, lineHd, lineTl
) )
and helpViKList
(absIdx, lineColumn, preferredColumn, hasPassedLine, strings, lines) =
case (strings, lines) of
(strHd :: strTl, lineHd :: lineTl) =>
(* todo: possibly check if we have passed line,
* and if so, if there are any line breaks in the lineHd
* which we could use to skip searching part of the string.
* However, this will likely have worse cache locality
* as we switch to searching in string to searcing in line vector
* so perhaps not. *)
helpViKString
( String.size strHd - 1, strHd, absIdx
, lineColumn, preferredColumn, hasPassedLine
, strTl, lineHd, lineTl
)
| (_, _) =>
(* empty, so return start of previous string *)
absIdx + 1
fun viK (lineGap: LineGap.t, cursorIdx) = fun viK (lineGap: LineGap.t, cursorIdx) =
let let
val val
@@ -742,11 +712,11 @@ struct
if strIdx > 0 then if strIdx > 0 then
if String.sub (strHd, strIdx - 1) = #"\n" then if String.sub (strHd, strIdx - 1) = #"\n" then
(* if in double linebreak *) (* if in double linebreak *)
helpVi0String helpVi0
(strIdx - 2, strHd, cursorIdx - 2, leftStrings, leftLines) (strIdx - 2, strHd, cursorIdx - 2, leftStrings, leftLines)
else else
(* not in double linebreak *) (* not in double linebreak *)
helpVi0String helpVi0
(strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines) (strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines)
else else
(* check leftStrings to see if we are in a double linebreak *) (* check leftStrings to see if we are in a double linebreak *)
@@ -754,14 +724,14 @@ struct
(lStrHd :: lStrTl, lLnHd :: lLnTl) => (lStrHd :: lStrTl, lLnHd :: lLnTl) =>
if String.sub (lStrHd, String.size lStrHd - 1) = #"\n" then if String.sub (lStrHd, String.size lStrHd - 1) = #"\n" then
(* in double linebreak *) (* in double linebreak *)
helpVi0String helpVi0
(String.size lStrHd - 2, lStrHd, cursorIdx - 2, lStrTl, lLnTl) (String.size lStrHd - 2, lStrHd, cursorIdx - 2, lStrTl, lLnTl)
else else
(* in single linebreak *) (* in single linebreak *)
helpVi0String helpVi0
(strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines) (strIdx - 1, strHd, cursorIdx - 1, leftStrings, leftLines)
| (_, _) => | (_, _) =>
helpViKString helpViK
( strIdx - 1, strHd, cursorIdx - 1 ( strIdx - 1, strHd, cursorIdx - 1
, 0, 0, true, leftStrings, lnHd, leftLines , 0, 0, true, leftStrings, lnHd, leftLines
)) ))
@@ -771,7 +741,7 @@ struct
let let
val lineColumn = getCursorColumn (lineGap, cursorIdx) val lineColumn = getCursorColumn (lineGap, cursorIdx)
in in
helpViKString helpViK
( strIdx - 1, strHd, cursorIdx - 1 ( strIdx - 1, strHd, cursorIdx - 1
, lineColumn, lineColumn, false , lineColumn, lineColumn, false
, leftStrings, lnHd, leftLines , leftStrings, lnHd, leftLines
@@ -793,14 +763,14 @@ struct
val leftStrings = strHd :: leftStrings val leftStrings = strHd :: leftStrings
val leftLines = lnHd :: leftLines val leftLines = lnHd :: leftLines
in in
helpVi0String helpVi0
( strIdx - 2, nestStrHd, cursorIdx - 2 ( strIdx - 2, nestStrHd, cursorIdx - 2
, leftStrings, leftLines , leftStrings, leftLines
) )
end end
else else
(* is in single linebreak *) (* is in single linebreak *)
helpVi0String helpVi0
( strIdx - 1, nestStrHd, cursorIdx - 1 ( strIdx - 1, nestStrHd, cursorIdx - 1
, leftStrings, leftLines , leftStrings, leftLines
) )
@@ -810,13 +780,13 @@ struct
String.sub (strHd, String.size strHd - 1) = #"\n" String.sub (strHd, String.size strHd - 1) = #"\n"
then then
(* is in double linebreak *) (* is in double linebreak *)
helpVi0String helpVi0
( String.size strHd - 2, nestStrHd, cursorIdx - 2 ( String.size strHd - 2, nestStrHd, cursorIdx - 2
, leftStrings, leftLines , leftStrings, leftLines
) )
else else
(* is in single linebreak *) (* is in single linebreak *)
helpVi0String helpVi0
( String.size strHd - 1, nestStrHd, cursorIdx - 1 ( String.size strHd - 1, nestStrHd, cursorIdx - 1
, leftStrings, leftLines , leftStrings, leftLines
) )
@@ -825,7 +795,7 @@ struct
let let
val lineColumn = getCursorColumn (lineGap, cursorIdx) val lineColumn = getCursorColumn (lineGap, cursorIdx)
in in
helpViKString helpViK
( strIdx - 1, nestStrHd, cursorIdx - 1 ( strIdx - 1, nestStrHd, cursorIdx - 1
, lineColumn, lineColumn, false , lineColumn, lineColumn, false
, strHd :: leftStrings, nestLnHd, lnHd :: leftLines , strHd :: leftStrings, nestLnHd, lnHd :: leftLines
@@ -971,9 +941,15 @@ struct
end end
| [] => false | [] => false
fun helpNextWordString (strPos, str, absIdx , strTl, lineTl) = fun helpNextWord (strPos, str, absIdx , strTl, lineTl) =
if strPos = String.size str then if strPos = String.size str then
helpNextWordList (strTl, lineTl, absIdx) case (strTl, lineTl) of
(shd :: stl, lhd :: ltl) =>
helpNextWord (0, shd, absIdx, stl, ltl)
| (_, _) =>
(* reached end of lineGap;
* return last valid chr position *)
absIdx - 1
else else
let let
val chr = String.sub (str, strPos) val chr = String.sub (str, strPos)
@@ -982,36 +958,26 @@ struct
if isNextChrNonBlank (strPos, str, strTl) then if isNextChrNonBlank (strPos, str, strTl) then
absIdx + 1 absIdx + 1
else else
helpNextWordString helpNextWord
(strPos + 1, str, absIdx + 1, strTl, lineTl) (strPos + 1, str, absIdx + 1, strTl, lineTl)
else if Char.isSpace chr then else if Char.isSpace chr then
if notIsNextChrSpace (strPos, str, strTl) then if notIsNextChrSpace (strPos, str, strTl) then
absIdx + 1 absIdx + 1
else else
(* nothing to do on space, except keep iterating *) (* nothing to do on space, except keep iterating *)
helpNextWordString helpNextWord
(strPos + 1, str, absIdx + 1, strTl, lineTl) (strPos + 1, str, absIdx + 1, strTl, lineTl)
else else
(* chr is NON_BLANK. *) (* chr is NON_BLANK. *)
if isNextChrAlphaNum (strPos, str, strTl) then if isNextChrAlphaNum (strPos, str, strTl) then
absIdx + 1 absIdx + 1
else else
helpNextWordString helpNextWord
(strPos + 1, str, absIdx + 1, strTl, lineTl) (strPos + 1, str, absIdx + 1, strTl, lineTl)
end end
and helpNextWordList (strings, lines, absIdx) =
case (strings, lines) of
(strHd::strTl, lineHd::lineTl) =>
helpNextWordString
(0, strHd, absIdx, strTl, lineTl)
| (_, _) =>
(* reached end of lineGap;
* return last valid chr position *)
absIdx - 1
fun startNextWord (shd, strIdx, absIdx, stl, ltl) = fun startNextWord (shd, strIdx, absIdx, stl, ltl) =
helpNextWordString helpNextWord
(strIdx, shd, absIdx, stl, ltl) (strIdx, shd, absIdx, stl, ltl)
fun nextWord (lineGap: LineGap.t, cursorIdx) = fun nextWord (lineGap: LineGap.t, cursorIdx) =
@@ -1042,9 +1008,16 @@ struct
| (_, _) => cursorIdx | (_, _) => cursorIdx
end end
fun helpPrevWordString (strPos, str, absIdx, strTl, lineTl) = fun helpPrevWord (strPos, str, absIdx, strTl, lineTl) =
if strPos < 0 then if strPos < 0 then
helpPrevWordList (strTl, lineTl, absIdx) case (strTl, lineTl) of
(shd :: stl, lhd :: ltl) =>
helpPrevWord
(String.size shd - 1, shd, absIdx, stl, ltl)
| (_, _) =>
(* reached start of lineGap;
* return 0 which is start idx *)
0
else else
let let
val chr = String.sub (str, strPos) val chr = String.sub (str, strPos)
@@ -1054,10 +1027,10 @@ struct
orelse isPrevChrNonBlank (strPos, str, strTl) then orelse isPrevChrNonBlank (strPos, str, strTl) then
absIdx absIdx
else else
helpPrevWordString helpPrevWord
(strPos - 1, str, absIdx - 1, strTl, lineTl) (strPos - 1, str, absIdx - 1, strTl, lineTl)
else if Char.isSpace chr then else if Char.isSpace chr then
helpPrevWordString helpPrevWord
(strPos - 1, str, absIdx - 1, strTl, lineTl) (strPos - 1, str, absIdx - 1, strTl, lineTl)
else else
(* is NON_BLANK *) (* is NON_BLANK *)
@@ -1065,26 +1038,16 @@ struct
orelse isPrevChrAlphaNum (strPos, str, strTl) then orelse isPrevChrAlphaNum (strPos, str, strTl) then
absIdx absIdx
else else
helpPrevWordString helpPrevWord
(strPos - 1, str, absIdx - 1, strTl, lineTl) (strPos - 1, str, absIdx - 1, strTl, lineTl)
end end
and helpPrevWordList (strings, lines, absIdx) =
case (strings, lines) of
(strHd::strTl, lineHd::lineTl) =>
helpPrevWordString
(String.size strHd - 1, strHd, absIdx, strTl, lineTl)
| (_, _) =>
(* reached start of lineGap;
* return 0 which is start idx *)
0
fun startPrevWord (shd, strIdx, absIdx, stl, ltl) = fun startPrevWord (shd, strIdx, absIdx, stl, ltl) =
(* we want to start iterating from previous character (* we want to start iterating from previous character
* and ignore the character the cursor is at * and ignore the character the cursor is at
* so check previous character *) * so check previous character *)
if strIdx > 0 then if strIdx > 0 then
helpPrevWordString helpPrevWord
(strIdx - 1, shd, absIdx - 1, stl, ltl) (strIdx - 1, shd, absIdx - 1, stl, ltl)
else else
case (stl, ltl) of case (stl, ltl) of
@@ -1092,7 +1055,7 @@ struct
let let
val prevIdx = String.size stlhd - 1 val prevIdx = String.size stlhd - 1
in in
helpPrevWordString helpPrevWord
(prevIdx, stlhd, absIdx - 1, stltl, ltltl) (prevIdx, stlhd, absIdx - 1, stltl, ltltl)
end end
| (_, _) => | (_, _) =>
@@ -1131,9 +1094,13 @@ struct
| (_, _) => cursorIdx | (_, _) => cursorIdx
end end
fun helpEndOfWordString (strPos, str, absIdx, stl, ltl) = fun helpEndOfWord (strPos, str, absIdx, stl, ltl) =
if strPos = String.size str then if strPos = String.size str then
helpEndOfWordList (stl, ltl, absIdx) case (stl, ltl) of
(shd :: stl, lhd :: ltl) =>
helpEndOfWord (0, shd, absIdx, stl, ltl)
| (_, _) =>
absIdx - 1
else else
let let
val chr = String.sub (str, strPos) val chr = String.sub (str, strPos)
@@ -1143,10 +1110,10 @@ struct
orelse isNextChrNonBlank (strPos, str, stl) then orelse isNextChrNonBlank (strPos, str, stl) then
absIdx absIdx
else else
helpEndOfWordString helpEndOfWord
(strPos + 1, str, absIdx + 1, stl, ltl) (strPos + 1, str, absIdx + 1, stl, ltl)
else if Char.isSpace chr then else if Char.isSpace chr then
helpEndOfWordString helpEndOfWord
(strPos + 1, str, absIdx + 1, stl, ltl) (strPos + 1, str, absIdx + 1, stl, ltl)
else else
(* is NON_BLANK *) (* is NON_BLANK *)
@@ -1154,26 +1121,19 @@ struct
orelse isNextChrAlphaNum (strPos, str, stl) then orelse isNextChrAlphaNum (strPos, str, stl) then
absIdx absIdx
else else
helpEndOfWordString helpEndOfWord
(strPos + 1, str, absIdx + 1, stl, ltl) (strPos + 1, str, absIdx + 1, stl, ltl)
end end
and helpEndOfWordList (strings, lines, absIdx) =
case (strings, lines) of
(shd :: stl, lhd :: ltl) =>
helpEndOfWordString (0, shd, absIdx, stl, ltl)
| (_, _) =>
absIdx - 1
fun startEndOfWord (shd, strIdx, absIdx, stl, ltl) = fun startEndOfWord (shd, strIdx, absIdx, stl, ltl) =
(* we want to start iterating from next char after strIdx *) (* we want to start iterating from next char after strIdx *)
if strIdx - 1 < String.size shd then if strIdx - 1 < String.size shd then
helpEndOfWordString helpEndOfWord
(strIdx + 1, shd, absIdx + 1, stl, ltl) (strIdx + 1, shd, absIdx + 1, stl, ltl)
else else
case (stl, ltl) of case (stl, ltl) of
(stlhd::stltl, ltlhd::ltltl) => (stlhd::stltl, ltlhd::ltltl) =>
helpEndOfWordString helpEndOfWord
(0, stlhd, absIdx + 1, stltl, ltltl) (0, stlhd, absIdx + 1, stltl, ltltl)
| (_, _) => | (_, _) =>
(* tl is empty; just return absIdx *) (* tl is empty; just return absIdx *)

BIN
shf

Binary file not shown.