Started refactor
This commit is contained in:
37
src_v2/utils/fp.nim
Normal file
37
src_v2/utils/fp.nim
Normal file
@@ -0,0 +1,37 @@
|
||||
import std/sugar
|
||||
import fp/maybe
|
||||
import results
|
||||
|
||||
func last*[T](xs: seq[T]): Maybe[T] =
|
||||
if xs.len == 0:
|
||||
nothing(T)
|
||||
else:
|
||||
just(xs[^1])
|
||||
|
||||
template isSome*(self: Result): bool = self.isOk()
|
||||
template isNone*(self: Result): bool = self.isErr()
|
||||
|
||||
proc findMaybe*[T](xs: seq[T], fn: T -> bool): Maybe[T] =
|
||||
for x in xs:
|
||||
if fn(x):
|
||||
return Just(x)
|
||||
return Nothing[T]()
|
||||
|
||||
proc findMaybeFn*[T, B](fns: seq[T {.nimcall.} -> Maybe[B]], val: T): Maybe[B] =
|
||||
for fn in fns:
|
||||
let res = fn(val)
|
||||
if res.isDefined():
|
||||
return res
|
||||
return Nothing[B]()
|
||||
|
||||
proc notNegative*[int](x: Maybe[int]): Maybe[int] =
|
||||
## Maps nil object to nothing
|
||||
x.filter(i => i >= 0)
|
||||
|
||||
when isMainModule:
|
||||
echo @[
|
||||
(x: int) => (if x == 2: Just("foo") else: Nothing[string]()),
|
||||
].findMaybeFn(2)
|
||||
|
||||
assert last(@[1,2,3]) == just(3)
|
||||
assert last[int](@[]) == nothing(int)
|
||||
15
src_v2/utils/parsec_test.nim
Normal file
15
src_v2/utils/parsec_test.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
import sequtils
|
||||
import std/sugar
|
||||
import microparsec
|
||||
import results
|
||||
|
||||
echo toSeq(1..1000000)
|
||||
|
||||
# let headlineParser = manyTill(ch '*', space)
|
||||
# .flatMap((stars: seq[char]) => pure(stars))
|
||||
# # .flatMap((stars) => manyTill(anyChar, endOfLine)
|
||||
# # .flatMap(headline => pure(stars, headline))
|
||||
# # )
|
||||
|
||||
# echo headlineParser.parse("*** Headline")
|
||||
# echo headlineParser.parse("* Headline")
|
||||
28
src_v2/utils/parser.nim
Normal file
28
src_v2/utils/parser.nim
Normal file
@@ -0,0 +1,28 @@
|
||||
import std/parseutils
|
||||
|
||||
proc fastSubstr(s: string; token: var string; start, length: int) =
|
||||
token.setLen length
|
||||
for i in 0 ..< length: token[i] = s[i+start]
|
||||
|
||||
proc parseUntilBackwards*(s: string, token: var string, until: string,
|
||||
start = 0): int {.inline.} =
|
||||
## Parses a token and stores it in ``token``. Returns
|
||||
## the number of the parsed characters or 0 in case of an error. A token
|
||||
## consists of any character that comes before the `until` token.
|
||||
runnableExamples:
|
||||
var myToken: string
|
||||
doAssert parseUntil("Hello World", myToken, "Wor") == 6
|
||||
doAssert myToken == "Hello "
|
||||
doAssert parseUntil("Hello World", myToken, "Wor", 2) == 4
|
||||
doAssert myToken == "llo "
|
||||
var i = s.len
|
||||
while i > 0:
|
||||
if until.len > 0 and s[i] == until[until.len - 1]:
|
||||
var u = 1
|
||||
while i+u < s.len and u < until.len and s[i+u] == until[u]:
|
||||
inc u
|
||||
if u >= until.len: break
|
||||
dec(i)
|
||||
result = i-start
|
||||
fastSubstr(s, token, start, result)
|
||||
#token = substr(s, start, i-1)
|
||||
44
src_v2/utils/printers.nim
Normal file
44
src_v2/utils/printers.nim
Normal file
@@ -0,0 +1,44 @@
|
||||
import std/[
|
||||
options,
|
||||
sequtils,
|
||||
strformat,
|
||||
strutils,
|
||||
sugar,
|
||||
]
|
||||
|
||||
const INDENT_SIZE* = 2;
|
||||
|
||||
func stringifyFields*(
|
||||
xs: seq[tuple[
|
||||
field: string,
|
||||
value: string,
|
||||
print: bool
|
||||
]],
|
||||
indent = 0,
|
||||
): string =
|
||||
xs
|
||||
.filter(x => x.print)
|
||||
.map(x => x.field & ": " & $x.value)
|
||||
.join(",\n")
|
||||
|
||||
func stringifyBlock*(blockName: string, indent = 0, xs: varargs[string]): string =
|
||||
let fieldIndent = indent + INDENT_SIZE
|
||||
|
||||
concat(
|
||||
@[&"{blockName}("],
|
||||
@xs.mapIt(it.indent(fieldIndent)),
|
||||
@[")"],
|
||||
)
|
||||
.join("\n")
|
||||
|
||||
func stringifySeq*[T](xs: seq[T], stringifyFn: (T) -> string, indent = 0): string =
|
||||
let fieldIndent = indent + INDENT_SIZE
|
||||
@[
|
||||
"@[",
|
||||
xs
|
||||
.mapIt(it.stringifyFn())
|
||||
.join(",\n")
|
||||
.indent(fieldIndent),
|
||||
"]",
|
||||
]
|
||||
.join("\n")
|
||||
60
src_v2/utils/str.nim
Normal file
60
src_v2/utils/str.nim
Normal file
@@ -0,0 +1,60 @@
|
||||
import std/[
|
||||
strutils,
|
||||
math,
|
||||
]
|
||||
import fusion/matching
|
||||
|
||||
{.experimental: "caseStmtMacros".}
|
||||
|
||||
func prettyExpectedSet*(x: set[char]): string =
|
||||
## Pretty print value for a set `x` of characters
|
||||
case x:
|
||||
of AllChars:
|
||||
"AllChars {'\x00'..'\xFF'}"
|
||||
of Digits:
|
||||
"Digits {'0'..'9'}"
|
||||
of HexDigits:
|
||||
"HexDigits {'0'..'9', 'A'..'F', 'a'..'f'}"
|
||||
of Letters:
|
||||
"Letters {'A'..'Z', 'a'..'z'}"
|
||||
of Newlines:
|
||||
"Newlines {'\r', '\n'}"
|
||||
of Whitespace:
|
||||
"Whitespace {' ', '\t', '\v', '\r', '\n', '\f'}"
|
||||
else:
|
||||
$x
|
||||
|
||||
func indentAfterNewline*(str: string, count: int): string =
|
||||
## Indent lines following the first line of `str` by `count`.
|
||||
## Useful for indenting nested keys of stringify functions.
|
||||
var strDup = str.indent(count)
|
||||
strDup.delete(0..count - 1)
|
||||
strDup
|
||||
|
||||
proc safeDelete*(str: string, slice: Slice[int]): string =
|
||||
## Deletes the items `str[slice]`, ignoring elements out of range.
|
||||
if slice.a > str.len - 1:
|
||||
str
|
||||
else:
|
||||
let fromIndex = clamp(slice.a, 0..str.len)
|
||||
let toIndex = clamp(slice.b, 0..str.len - 1)
|
||||
|
||||
var strDup = str
|
||||
strDup.delete(fromIndex..toIndex)
|
||||
strDup
|
||||
|
||||
func findAndDelete*(str: string, chars: set[char], start = 0, last = str.len - 1): string =
|
||||
## Find the next instance of `chars` from `start`.
|
||||
## When found delete characters until `last`.
|
||||
# Prevent passing negative numbers (e.g.: initial parser)
|
||||
if start >= 0 and last >= 0:
|
||||
let startChar = str.find(chars, start, last)
|
||||
if startChar == -1:
|
||||
str
|
||||
else:
|
||||
str.safeDelete(startChar..last)
|
||||
else: str
|
||||
|
||||
func deleteAfterNewline*(str: string, start = 0): string =
|
||||
## Delete string after next Newline from `start`.
|
||||
findAndDelete(str, Newlines, start)
|
||||
Reference in New Issue
Block a user