functorise character folders to reduce repetitive boilerplate code (but have not functorised yet)
This commit is contained in:
@@ -21,8 +21,11 @@ struct
|
|||||||
(* strIdx is in tl *)
|
(* strIdx is in tl *)
|
||||||
(case stl of
|
(case stl of
|
||||||
stlhd :: stltl =>
|
stlhd :: stltl =>
|
||||||
let val strIdx = strIdx - String.size shd
|
let
|
||||||
in M.fStart (strIdx, cursorIdx, stlhd, stltl, M.startState, count)
|
val strIdx = strIdx - String.size shd
|
||||||
|
in
|
||||||
|
M.fStart
|
||||||
|
(strIdx, cursorIdx, stlhd, stltl, M.startState, count)
|
||||||
end
|
end
|
||||||
| _ => cursorIdx)
|
| _ => cursorIdx)
|
||||||
| [] => cursorIdx
|
| [] => cursorIdx
|
||||||
@@ -77,7 +80,13 @@ struct
|
|||||||
val leftStrings = shd :: leftStrings
|
val leftStrings = shd :: leftStrings
|
||||||
in
|
in
|
||||||
M.fStart
|
M.fStart
|
||||||
(strIdx, cursorIdx, stlhd, leftStrings, M.startState, count)
|
( strIdx
|
||||||
|
, cursorIdx
|
||||||
|
, stlhd
|
||||||
|
, leftStrings
|
||||||
|
, M.startState
|
||||||
|
, count
|
||||||
|
)
|
||||||
end
|
end
|
||||||
| [] => cursorIdx)
|
| [] => cursorIdx)
|
||||||
| [] => cursorIdx
|
| [] => cursorIdx
|
||||||
@@ -95,7 +104,8 @@ struct
|
|||||||
if strIdx < 0 then
|
if strIdx < 0 then
|
||||||
case leftStrings of
|
case leftStrings of
|
||||||
lhd :: ltl =>
|
lhd :: ltl =>
|
||||||
M.fStart (String.size lhd - 1, absIdx, lhd, ltl, M.startState, count)
|
M.fStart
|
||||||
|
(String.size lhd - 1, absIdx, lhd, ltl, M.startState, count)
|
||||||
| [] => 0
|
| [] => 0
|
||||||
else
|
else
|
||||||
case #rightStrings lineGap of
|
case #rightStrings lineGap of
|
||||||
@@ -104,3 +114,76 @@ struct
|
|||||||
| [] => Int.max (0, cursorIdx - 2)
|
| [] => Int.max (0, cursorIdx - 2)
|
||||||
end
|
end
|
||||||
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)
|
||||||
|
| [] => Int.max (absIdx - 2, 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
|
||||||
|
(* new loop, so reset to start state and proceed *)
|
||||||
|
foldNext (idx + 1, absIdx + 1, str, tl, Fn.startState, counter - 1)
|
||||||
|
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
|
||||||
|
foldPrev (idx - 1, absIdx - 1, str, tl, Fn.startState, counter - 1)
|
||||||
|
else
|
||||||
|
foldPrev (idx - 1, absIdx - 1, str, tl, newState, counter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user