Add 'shf/' from commit 'b6c5a95b664aeb861d7b33ffc9eefe447ba99dd7'
git-subtree-dir: shf git-subtree-mainline:401408448fgit-subtree-split:b6c5a95b66
This commit is contained in:
303
shf/fcore/cursor-dfa/make-dfa-loop.sml
Normal file
303
shf/fcore/cursor-dfa/make-dfa-loop.sml
Normal 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
|
||||
239
shf/fcore/cursor-dfa/vi-caps-word-dfa.sml
Normal file
239
shf/fcore/cursor-dfa/vi-caps-word-dfa.sml
Normal 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
|
||||
64
shf/fcore/cursor-dfa/vi-dlr-dfa.sml
Normal file
64
shf/fcore/cursor-dfa/vi-dlr-dfa.sml
Normal 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
|
||||
76
shf/fcore/cursor-dfa/vi-h-dfa.sml
Normal file
76
shf/fcore/cursor-dfa/vi-h-dfa.sml
Normal 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
|
||||
53
shf/fcore/cursor-dfa/vi-l-dfa.sml
Normal file
53
shf/fcore/cursor-dfa/vi-l-dfa.sml
Normal 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
|
||||
285
shf/fcore/cursor-dfa/vi-word-dfa.sml
Normal file
285
shf/fcore/cursor-dfa/vi-word-dfa.sml
Normal 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
|
||||
Reference in New Issue
Block a user