Add 'shf/' from commit 'b6c5a95b664aeb861d7b33ffc9eefe447ba99dd7'

git-subtree-dir: shf
git-subtree-mainline: 401408448f
git-subtree-split: b6c5a95b66
This commit is contained in:
2026-04-24 00:27:49 +01:00
83 changed files with 43952 additions and 0 deletions

View File

@@ -0,0 +1,303 @@
signature MAKE_DFA_LOOP =
sig
val fStart: int * int * string * string list * Word8.word * int -> int
val startState: Word8.word
end
functor MakeNextDfaLoop(M: MAKE_DFA_LOOP) =
struct
fun next (lineGap: LineGap.t, cursorIdx, count) =
let
val {rightStrings, idx = bufferIdx, ...} = lineGap
(* convert absolute cursorIdx to idx relative to hd string *)
val strIdx = cursorIdx - bufferIdx
in
case rightStrings of
shd :: stl =>
if strIdx < String.size shd then
(* strIdx is in this string *)
M.fStart (strIdx, cursorIdx, shd, stl, M.startState, count)
else
(* strIdx is in tl *)
(case stl of
stlhd :: stltl =>
let
val strIdx = strIdx - String.size shd
in
M.fStart
(strIdx, cursorIdx, stlhd, stltl, M.startState, count)
end
| _ => cursorIdx)
| [] => cursorIdx
end
end
functor MakeNextDfaLoopPlus1(M: MAKE_DFA_LOOP) =
struct
fun next (lineGap: LineGap.t, cursorIdx, count) =
let
val {rightStrings, idx = bufferIdx, ...} = lineGap
(* convert absolute cursorIdx to idx relative to hd string *)
val strIdx = cursorIdx - bufferIdx + 1
val absIdx = cursorIdx + 1
in
case rightStrings of
shd :: stl =>
if strIdx < String.size shd then
(* strIdx is in this string *)
M.fStart (strIdx, absIdx, shd, stl, M.startState, count)
else
(* strIdx is in tl *)
(case stl of
stlhd :: stltl =>
let val strIdx = strIdx - String.size shd
in M.fStart (strIdx, absIdx, stlhd, stltl, M.startState, count)
end
| _ => cursorIdx)
| [] => cursorIdx
end
end
functor MakePrevDfaLoop(M: MAKE_DFA_LOOP) =
struct
fun startLeftStrings (leftStrings, absIdx, count) =
case leftStrings of
lhd :: ltl =>
M.fStart (String.size lhd - 1, absIdx, lhd, ltl, M.startState, count)
| [] => 0
fun prev (lineGap: LineGap.t, cursorIdx, count) =
let
val {rightStrings, leftStrings, idx = bufferIdx, ...} = lineGap
(* convert absolute cursorIdx to idx relative to hd string *)
val strIdx = cursorIdx - bufferIdx
in
case rightStrings of
shd :: stl =>
if strIdx < String.size shd then
(* strIdx is in this string *)
M.fStart (strIdx, cursorIdx, shd, leftStrings, M.startState, count)
else
(* strIdx is in tl *)
(case stl of
stlhd :: stltl =>
let
val strIdx = strIdx - String.size shd
val leftStrings = shd :: leftStrings
in
M.fStart
( strIdx
, cursorIdx
, stlhd
, leftStrings
, M.startState
, count
)
end
| [] => startLeftStrings (leftStrings, cursorIdx, count))
| [] => startLeftStrings (leftStrings, cursorIdx, count)
end
end
functor MakePrevDfaLoopMinus1(M: MAKE_DFA_LOOP) =
struct
fun startLeftStrings (leftStrings, absIdx, count) =
case leftStrings of
lhd :: ltl =>
M.fStart (String.size lhd - 1, absIdx, lhd, ltl, M.startState, count)
| [] => 0
fun prev (lineGap: LineGap.t, cursorIdx, count) =
let
val {idx = bufferIdx, leftStrings, ...} = lineGap
val strIdx = cursorIdx - bufferIdx - 1
val absIdx = cursorIdx - 1
in
if strIdx < 0 then
startLeftStrings (leftStrings, absIdx, count)
else
case #rightStrings lineGap of
rhd :: _ =>
M.fStart (strIdx, absIdx, rhd, leftStrings, M.startState, count)
| [] => startLeftStrings (leftStrings, absIdx, count)
end
end
signature MAKE_CHAR_FOLDER =
sig
val startState: Word8.word
val tables: Word8.word vector vector
val isFinal: Word8.word -> bool
val finish: int -> int
end
functor MakeCharFolderNext(Fn: MAKE_CHAR_FOLDER) =
struct
fun nextState (currentState, currentChar) =
let
val currentState = Word8.toInt currentState
val currentTable = Vector.sub (Fn.tables, currentState)
val charIdx = Char.ord currentChar
in
Vector.sub (currentTable, charIdx)
end
fun foldNext (idx, absIdx, str, tl, currentState, counter) =
if idx = String.size str then
case tl of
str :: tl => foldNext (0, absIdx, str, tl, currentState, counter)
| [] => absIdx
else
let
val chr = String.sub (str, idx)
val newState = nextState (currentState, chr)
in
if Fn.isFinal newState then
if counter - 1 = 0 then
Fn.finish absIdx
else
(* new loop, so reset start state and proceed *)
let val newState = nextState (Fn.startState, chr)
in foldNext (idx + 1, absIdx + 1, str, tl, newState, counter - 1)
end
else
foldNext (idx + 1, absIdx + 1, str, tl, newState, counter)
end
end
functor MakeCharFolderPrev(Fn: MAKE_CHAR_FOLDER) =
struct
fun nextState (currentState, currentChar) =
let
val currentState = Word8.toInt currentState
val currentTable = Vector.sub (Fn.tables, currentState)
val charIdx = Char.ord currentChar
in
Vector.sub (currentTable, charIdx)
end
fun foldPrev (idx, absIdx, str, tl, currentState, counter) =
if idx < 0 then
case tl of
str :: tl =>
foldPrev (String.size str - 1, absIdx, str, tl, currentState, counter)
| [] => 0
else
let
val chr = String.sub (str, idx)
val newState = nextState (currentState, chr)
in
if Fn.isFinal newState then
if counter - 1 = 0 then
Fn.finish absIdx
else
let val newState = nextState (Fn.startState, chr)
in foldPrev (idx - 1, absIdx - 1, str, tl, newState, counter - 1)
end
else
foldPrev (idx - 1, absIdx - 1, str, tl, newState, counter)
end
end
signature MAKE_IF_CHAR_FOLDER =
sig
type env
val fStart:
int * string * int vector * int * string list * int vector list * env
-> int
end
functor MakeIfCharFolderPrev(Fn: MAKE_IF_CHAR_FOLDER) =
struct
fun foldPrev (lineGap: LineGap.t, cursorIdx, env: Fn.env) =
let
val
{rightStrings, idx = bufferIdx, rightLines, leftStrings, leftLines, ...} =
lineGap
in
case (rightStrings, rightLines) of
(strHd :: strTl, lnHd :: lnTl) =>
let
(* convert absolute cursorIdx to idx relative to hd string *)
val strIdx = cursorIdx - bufferIdx
in
if strIdx < String.size strHd then
(* strIdx is either in this string or in leftStrings *)
if strIdx < 0 then
case (leftStrings, leftLines) of
(lshd :: lstl, llhd :: lltl) =>
Fn.fStart
( String.size lshd - 1
, lshd
, llhd
, cursorIdx
, lstl
, lltl
, env
)
| (_, _) => 0
else
Fn.fStart
(strIdx, strHd, lnHd, cursorIdx, leftStrings, leftLines, env)
else
(* strIdx must be in the strTl *)
(case (strTl, lnTl) of
(nestStrHd :: _, nestLnHd :: _) =>
let
val strIdx = strIdx - String.size strHd
in
Fn.fStart
( strIdx
, nestStrHd
, nestLnHd
, cursorIdx
, strHd :: leftStrings
, lnHd :: leftLines
, env
)
end
| (_, _) => cursorIdx)
end
| (_, _) => (* nowhere to go, so return cursorIdx *) cursorIdx
end
end
functor MakeIfCharFolderNext(Fn: MAKE_IF_CHAR_FOLDER) =
struct
fun foldNext (lineGap: LineGap.t, cursorIdx, env: Fn.env) =
let
val {rightStrings, idx = bufferIdx, rightLines, ...} = lineGap
in
case (rightStrings, rightLines) of
(strHd :: strTl, lnHd :: lnTl) =>
let
(* convert absolute cursorIdx to idx relative to hd string *)
val strIdx = cursorIdx - bufferIdx
in
if strIdx < String.size strHd then
(* strIdx is in this string *)
Fn.fStart (strIdx, strHd, lnHd, cursorIdx, strTl, lnTl, env)
else
(* strIdx must be in the strTl *)
(case (strTl, lnTl) of
(nestStrHd :: nestStrTl, nestLnHd :: nestLnTl) =>
let
val strIdx = strIdx - String.size strHd
in
Fn.fStart
( strIdx
, nestStrHd
, nestLnHd
, cursorIdx
, nestStrTl
, nestLnTl
, env
)
end
| (_, _) => cursorIdx)
end
| (_, _) => (* nowhere to go, so return cursorIdx *) cursorIdx
end
end

View File

@@ -0,0 +1,239 @@
structure ViCapsWordDfa =
struct
val startState: Word8.word = 0w0
val startNonBlankState: Word8.word = 0w1
val startSpaceState: Word8.word = 0w2
val nonBlankAfterSpaceState: Word8.word = 0w3
val spaceAfterNonBlankState = 0w4
val startNewline: Word8.word = 0w5
val newlineToNewline: Word8.word = 0w6
val chrToNewline: Word8.word = 0w07
fun makeStart i =
let
val chr = Char.chr i
in
if chr = #"\n" then startNewline
else if Char.isSpace chr then startSpaceState
else startNonBlankState
end
fun makeStartNonBlankState i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then spaceAfterNonBlankState
else startNonBlankState
end
fun makeStartSpace i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then startSpaceState
else nonBlankAfterSpaceState
end
fun makeNonBlankAfterSpace i =
let
val chr = Char.chr i
in
if chr = #"\n" then chrToNewline
else if Char.isSpace chr then spaceAfterNonBlankState
else nonBlankAfterSpaceState
end
fun makeStartNewline i =
let
val chr = Char.chr i
in
if chr = #"\n" then newlineToNewline
else if Char.isSpace chr then startSpaceState
else nonBlankAfterSpaceState
end
val startTable = Vector.tabulate (255, makeStart)
val startNonBlankTable = Vector.tabulate (255, makeStartNonBlankState)
val startSpaceTable = Vector.tabulate (255, makeStartSpace)
val nonBlankAfterSpaceTable = Vector.tabulate (255, makeNonBlankAfterSpace)
val spaceAfterNonBlankTable = nonBlankAfterSpaceTable
val newlineTable = Vector.tabulate (255, makeStartNewline)
val tables =
#[ startTable
, startNonBlankTable
, startSpaceTable
, nonBlankAfterSpaceTable
, spaceAfterNonBlankTable
, newlineTable
, newlineTable
, newlineTable
]
structure StartOfNextWORD =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
orelse currentState = newlineToNewline
end)
val fStart = Folder.foldNext
end)
structure StartOfNextWORDForDelete =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
orelse currentState = chrToNewline
end)
val fStart = Folder.foldNext
end)
structure EndOfPrevWORD =
MakePrevDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun finish x = x
fun isFinal currentState =
currentState = nonBlankAfterSpaceState
end)
val fStart = Folder.foldPrev
end)
structure StartOfCurrentWORDFolder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = spaceAfterNonBlankState
orelse currentState = chrToNewline
orelse currentState = newlineToNewline
fun finish idx = idx + 1
end)
structure StartOfCurrentWORD =
MakePrevDfaLoopMinus1
(struct
val startState = startState
val fStart = StartOfCurrentWORDFolder.foldPrev
end)
structure StartOfNextWORDStrict =
MakePrevDfaLoop
(struct
val startState = startState
val fStart = StartOfCurrentWORDFolder.foldPrev
end)
fun endOfCurrentWORDFolderIsFinal currentState =
currentState = spaceAfterNonBlankState orelse currentState = chrToNewline
structure EndOfCurrentWORDFolder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = endOfCurrentWORDFolderIsFinal
fun finish idx =
Int.max (0, idx - 1)
end)
structure EndOfCurrentWORD =
MakeNextDfaLoopPlus1
(struct
val startState = startState
val fStart = EndOfCurrentWORDFolder.foldNext
end)
structure EndOfCurrentWORDForDelete =
MakeNextDfaLoopPlus1
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = endOfCurrentWORDFolderIsFinal
fun finish idx = idx
end)
val fStart = Folder.foldNext
end)
structure EndOfCurrentWORDStrict =
MakeNextDfaLoop
(struct
val startState = startState
val fStart = EndOfCurrentWORDFolder.foldNext
end)
(* W *)
val startOfNextWORD = StartOfNextWORD.next
val startOfNextWORDForDelete = StartOfNextWORDForDelete.next
(* gE *)
val endOfPrevWORD = EndOfPrevWORD.prev
(* B *)
val startOfCurrentWORD = StartOfCurrentWORD.prev
(* E *)
val endOfCurrentWORD = EndOfCurrentWORD.next
val endOfCurrentWORDForDelete = EndOfCurrentWORDForDelete.next
(* functions to strictly get the start and end of the current word.
* Problem: We want to support Vi motions like viW (selects a single word),
* as well as ciW (change one WORD) and diW (delete one WORD).
*
* The 'startOfCurrentWORD' and 'endOfCurrentWORD' functions do this
* (representing the vi 'B' and 'E' commands respectively),
* except that 'B' goes to the previous WORD if the cursor is on the first
* character of the current WORD, and 'E' goes to the next WORD if the cursor
* is on the last character of the current WORD.
*
* What is meant by "strict" is that these below functions always stay
* within the current WORD, not making the two exceptions mentioned above.
*)
val startOfCurrentWORDStrict = StartOfNextWORDStrict.prev
val endOfCurrentWORDStrict = EndOfCurrentWORDStrict.next
end

View File

@@ -0,0 +1,64 @@
structure ViDlrDfa =
struct
val startState: Word8.word = 0w0
val newlineState: Word8.word = 0w1
val notNewlineState = 0w2
fun makeStart i =
if Char.chr i = #"\n" then newlineState else notNewlineState
val startTable = Vector.tabulate (255, makeStart)
val newlineTable = startTable
val notNewlineTable = startTable
val tables = #[startTable, newlineTable, notNewlineTable]
fun isFinal currentState = currentState = newlineState
structure ViDlr =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x - 1
val isFinal = isFinal
end)
fun fStart (idx, absIdx, str, tl, currentState, counter) =
if String.sub (str, idx) = #"\n" then
if counter = 1 then
absIdx
else
Folder.foldNext
(idx + 1, absIdx + 1, str, tl, currentState, counter - 1)
else
Folder.foldNext (idx, absIdx, str, tl, currentState, counter)
end)
structure ViDlrForDelete =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun finish x = x + 1
val isFinal = isFinal
end)
val fStart = Folder.foldNext
end)
val next = ViDlr.next
val nextForDelete = ViDlrForDelete.next
end

View File

@@ -0,0 +1,76 @@
structure ViHDfa =
struct
val startState: Word8.word = 0w0
val oneNewlineState: Word8.word = 0w1
val twoNewlineState: Word8.word = 0w2
val chrState: Word8.word = 0w3
val chrBeforeNewlieState: Word8.word = 0w4
fun makeStart i =
if Char.chr i = #"\n" then oneNewlineState else chrState
fun makeOneNewline i =
if Char.chr i = #"\n" then twoNewlineState else chrBeforeNewlieState
val startTable = Vector.tabulate (255, makeStart)
val oneNewlineTable = Vector.tabulate (255, makeOneNewline)
val twoNewlineTable = oneNewlineTable
val chrTable = startTable
val chrBeforeNewlieTable = startTable
val tables =
#[ startTable
, oneNewlineTable
, twoNewlineTable
, chrTable
, chrBeforeNewlieTable
]
fun next (currentState, chr) =
let val table = Vector.sub (tables, Word8.toInt currentState)
in Vector.sub (table, Char.ord chr)
end
structure ViH =
MakePrevDfaLoop
(struct
val startState = startState
fun loop (idx, absIdx, str, tl, currentState, counter) =
if idx < 0 then
case tl of
str :: tl =>
loop
(String.size str - 1, absIdx, str, tl, currentState, counter)
| [] => 0
else
let
val chr = String.sub (str, idx)
val newState = next (currentState, chr)
in
if newState = chrBeforeNewlieState orelse newState = chrState then
if counter - 1 = ~1 then
absIdx
else
loop (idx - 1, absIdx - 1, str, tl, startState, counter - 1)
else if newState = twoNewlineState then
if counter - 1 = ~1 then
absIdx + 1
else
loop
( idx - 1
, absIdx - 1
, str
, tl
, oneNewlineState
, counter - 1
)
else
loop (idx - 1, absIdx - 1, str, tl, newState, counter)
end
val fStart = loop
end)
val prev = ViH.prev
end

View File

@@ -0,0 +1,53 @@
structure ViLDfa =
struct
val startState: Word8.word = 0w0
val newlineState: Word8.word = 0w1
val chrState: Word8.word = 0w2
val newlineAfterCHrState: Word8.word = 0w3
fun makeStart i =
if Char.chr i = #"\n" then newlineState else chrState
fun makeChr i =
if Char.chr i = #"\n" then newlineAfterCHrState else chrState
val startTable = Vector.tabulate (255, makeStart)
val newlineTable = startTable
val chrTable = Vector.tabulate (255, makeChr)
val newlineAfterCHrTable = startTable
val tables = #[startTable, newlineTable, chrTable, newlineAfterCHrTable]
fun next (currentState, chr) =
let val table = Vector.sub (tables, Word8.toInt currentState)
in Vector.sub (table, Char.ord chr)
end
structure ViL =
MakeNextDfaLoop
(struct
val startState = startState
fun loop (idx, absIdx, str, tl, currentState, counter) =
if idx = String.size str then
case tl of
str :: tl => loop (0, absIdx, str, tl, currentState, counter)
| [] => absIdx
else
let
val chr = String.sub (str, idx)
val newState = next (currentState, chr)
in
if newState = newlineAfterCHrState then
loop (idx + 1, absIdx + 1, str, tl, newState, counter)
else if counter - 1 = ~1 then
absIdx
else
loop (idx + 1, absIdx + 1, str, tl, newState, counter - 1)
end
val fStart = loop
end)
val next = ViL.next
end

View File

@@ -0,0 +1,285 @@
structure ViWordDfa =
struct
val startState: Word8.word = 0w0
val startAlpha: Word8.word = 0w1
val startSpace: Word8.word = 0w2
val startPunct: Word8.word = 0w3
val alphaToSpace: Word8.word = 0w4
val punctToSpace: Word8.word = 0w5
val spaceToAlpha: Word8.word = 0w6
val spaceToPunct: Word8.word = 0w7
val startNewline: Word8.word = 0w8
val newlineToNewline: Word8.word = 0w9
val chrToNewline: Word8.word = 0w10
val newlineToAlpha: Word8.word = 0w11
val newlineToPunct: Word8.word = 0w12
val alphaToPunct: Word8.word = 0w13
val punctToAlpha: Word8.word = 0w14
fun makeStart i =
let
val chr = Char.chr i
in
if Char.isAlphaNum chr orelse chr = #"_" then startAlpha
else if chr = #"\n" then startNewline
else if Char.isSpace chr then startSpace
else startPunct
end
fun makeStartAlpha i =
let
val chr = Char.chr i
in
if Char.isAlphaNum chr orelse chr = #"_" then startAlpha
else if chr = #"\n" then chrToNewline
else if Char.isSpace chr then alphaToSpace
else alphaToPunct
end
fun makeStartSpace i =
let
val chr = Char.chr i
in
if Char.isAlphaNum chr orelse chr = #"_" then spaceToAlpha
else if chr = #"\n" then chrToNewline
else if Char.isSpace chr then startSpace
else spaceToPunct
end
fun makeStartPunct i =
let
val chr = Char.chr i
in
if Char.isAlphaNum chr orelse chr = #"_" then punctToAlpha
else if chr = #"\n" then chrToNewline
else if Char.isSpace chr then punctToSpace
else startPunct
end
fun makeStartNewline i =
let
val chr = Char.chr i
in
if Char.isAlphaNum chr orelse chr = #"_" then newlineToAlpha
else if chr = #"\n" then newlineToNewline
else if Char.isSpace chr then startSpace
else newlineToPunct
end
val startTable = Vector.tabulate (255, makeStart)
val startAlphaTable = Vector.tabulate (255, makeStartAlpha)
val startSpaceTable = Vector.tabulate (255, makeStartSpace)
val startPunctTable = Vector.tabulate (255, makeStartPunct)
val alphaToSpaceTable = startSpaceTable
val punctToSpaceTable = startSpaceTable
val spaceToAlphaTable = startAlphaTable
val spaceToPunctTable = startPunctTable
val newlineTable = Vector.tabulate (255, makeStartNewline)
val tables =
#[ startTable
, startAlphaTable
, startSpaceTable
, startPunctTable
, alphaToSpaceTable
, punctToSpaceTable
, spaceToAlphaTable
, spaceToPunctTable
, newlineTable
, newlineTable
, newlineTable
, startAlphaTable
, startPunctTable
]
structure StartOfNextWord =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = alphaToPunct orelse currentState = punctToAlpha
orelse currentState = spaceToAlpha
orelse currentState = spaceToPunct
orelse currentState = newlineToNewline
orelse currentState = newlineToAlpha
orelse currentState = newlineToPunct
fun finish x = x
end)
val fStart = Folder.foldNext
end)
(* This is the same as StartOfNextWord, except for the `isFinal` function.
* The difference is that the `isFinal` function here considers
* the state where any character goes to a newline,
* to be a final state.
* This is because, in Vim, the 'w' motion will move past a newline
* when that newline is preceded by a non-newline character.
* However, the 'dw' motion deletes until that newline
* (not including the newline itself).
* It is easier, less fragile, and perhaps clearer,
* to implement the difference using a transition table like this
* than convoluted if-statements. *)
structure StartOfNextWordForDelete =
MakeNextDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = alphaToPunct orelse currentState = punctToAlpha
orelse currentState = spaceToAlpha
orelse currentState = spaceToPunct
orelse currentState = chrToNewline
fun finish x = x
end)
val fStart = Folder.foldNext
end)
structure EndOfPrevWord =
MakePrevDfaLoop
(struct
val startState = startState
structure Folder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = alphaToPunct orelse currentState = punctToAlpha
orelse currentState = spaceToAlpha
orelse currentState = spaceToPunct
orelse currentState = newlineToNewline
orelse currentState = newlineToAlpha
orelse currentState = newlineToPunct
fun finish x = x
end)
val fStart = Folder.foldPrev
end)
structure StartOfCurrentWordFolder =
MakeCharFolderPrev
(struct
val startState = startState
val tables = tables
fun isFinal currentState =
currentState = alphaToSpace orelse currentState = punctToSpace
orelse currentState = alphaToPunct orelse currentState = punctToAlpha
orelse currentState = chrToNewline
orelse currentState = newlineToNewline
fun finish idx = idx + 1
end)
structure StartOfCurrentWord =
MakePrevDfaLoopMinus1
(struct
val startState = startState
val fStart = StartOfCurrentWordFolder.foldPrev
end)
structure StartOfCurrentWordStrict =
MakePrevDfaLoop
(struct
val startState = startState
val fStart = StartOfCurrentWordFolder.foldPrev
end)
fun isFinalForEndOfCurrentWord currentState =
currentState = alphaToSpace orelse currentState = punctToSpace
orelse currentState = alphaToPunct orelse currentState = punctToAlpha
orelse currentState = chrToNewline
structure EndOfCurrentWordFolder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = isFinalForEndOfCurrentWord
fun finish x = x - 1
end)
structure EndOfCurrentWord =
MakeNextDfaLoopPlus1
(struct
val startState = startState
val fStart = EndOfCurrentWordFolder.foldNext
end)
structure EndOfCurrentWordStrict =
MakeNextDfaLoop
(struct
val startState = startState
val fStart = EndOfCurrentWordFolder.foldNext
end)
structure EndOfCurrentWordForDelete =
MakeNextDfaLoopPlus1
(struct
val startState = startState
structure Folder =
MakeCharFolderNext
(struct
val startState = startState
val tables = tables
val isFinal = isFinalForEndOfCurrentWord
fun finish x = x
end)
val fStart = Folder.foldNext
end)
(* w *)
val startOfNextWord = StartOfNextWord.next
val startOfNextWordForDelete = StartOfNextWordForDelete.next
(* ge *)
val endOfPrevWord = EndOfPrevWord.prev
(* b *)
val startOfCurrentWord = StartOfCurrentWord.prev
(* e *)
val endOfCurrentWord = EndOfCurrentWord.next
val endOfCurrentWordForDelete = EndOfCurrentWordForDelete.next
(* the meaning of "Strict" and the utility of these two functions
* is described in vi-WORD-dfa.sml *)
val startOfCurrentWordStrict = StartOfCurrentWordStrict.prev
val endOfCurrentWordStrict = EndOfCurrentWordStrict.next
end