Use proc, fn and const dont work
This commit is contained in:
2
TODO.org
2
TODO.org
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
** TODO Headline content parser
|
** TODO Headline content parser
|
||||||
:LOGBOOK:
|
:LOGBOOK:
|
||||||
CLOCK: [2022-08-09 Tue 17:51]
|
CLOCK: [2022-08-09 Tue 17:51]--[2022-08-09 Tue 19:51] => 2:00
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
So I've had some heavy misconceptions while working on the content,
|
So I've had some heavy misconceptions while working on the content,
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
import std/sugar
|
|
||||||
import std/collections/sequtils
|
|
||||||
import std/strformat
|
|
||||||
import std/strutils
|
|
||||||
import results
|
|
||||||
import fusion/matching
|
|
||||||
import ./parser_internals
|
|
||||||
import ./parser_types
|
|
||||||
|
|
||||||
# proc tryParseBuildOrg*[T](
|
|
||||||
# builder: Builder[T],
|
|
||||||
# builderFns: seq[
|
|
||||||
# Builder[T] -> BuilderResult[T]
|
|
||||||
# ],
|
|
||||||
# stopAtParserFn = endOfStream
|
|
||||||
# ): BuilderResult[T] =
|
|
||||||
|
|
||||||
# # Mutating accumulators
|
|
||||||
# var builderAcc: BuilderResult[T] = BuilderResult.ok(builder)
|
|
||||||
|
|
||||||
# while builderAcc.isOk() and builderAcc.tryParser(stopAtParserFn).isErr()
|
|
||||||
# for fn in builderFns:
|
|
||||||
# fn
|
|
||||||
|
|
||||||
proc tryParseBuild*[T](
|
|
||||||
builder: Builder[T],
|
|
||||||
builderFns: seq[tuple[
|
|
||||||
parserFn: Parser -> ParserResult,
|
|
||||||
builderFn: seq[ParserToken] -> seq[T],
|
|
||||||
]],
|
|
||||||
defaultBuilderFn: seq[ParserToken] -> seq[T],
|
|
||||||
stopAtParserFn = newline,
|
|
||||||
concatFn = concat[T],
|
|
||||||
): BuilderResult[T] =
|
|
||||||
## Parse text in `builder` by checking the `builderFns` list for a sucessful `parserFn`.
|
|
||||||
## The `ok` `parserFn` result will be merged into the `Builder[T].tree` by using the `concatFn`.
|
|
||||||
## Otherwise continue taking any character until the `stopAtParserFn` condition is found.
|
|
||||||
## Any non-matching tokens will be converted using the `defaultBuilderFn`.
|
|
||||||
let (parser, tree) = builder
|
|
||||||
|
|
||||||
# Mutating accumulators
|
|
||||||
var parserAcc: ParserResult = ParserResult.ok(parser)
|
|
||||||
var builderAcc: Builder[T] = builder
|
|
||||||
|
|
||||||
while parserAcc.isOk() and parserAcc.flatMap(stopAtParserFn).isErr():
|
|
||||||
# Empty the parser tokens as we want to seperate them for the next parser in the sequence
|
|
||||||
let emptyParser = parserAcc.map(emptyTokens)
|
|
||||||
|
|
||||||
# Find the first matching parser and convert its tokens
|
|
||||||
var found = false
|
|
||||||
for fn in builderFns:
|
|
||||||
let (parserFn, builderFn) = fn
|
|
||||||
|
|
||||||
let parseResult = emptyParser.flatMap(parserFn)
|
|
||||||
if parseResult.isOk():
|
|
||||||
let okParser = parseResult.unsafeGet()
|
|
||||||
|
|
||||||
# Convert all previous unmatched tokens via the `defaultBuilderTokens`
|
|
||||||
let defaultBuilderTokens = parserAcc
|
|
||||||
.foldTokens(
|
|
||||||
onError = _ => newSeq[T](),
|
|
||||||
onSuccess = defaultBuilderFn,
|
|
||||||
)
|
|
||||||
|
|
||||||
found = true
|
|
||||||
parserAcc = parseResult.map(emptyTokens)
|
|
||||||
builderAcc = builder.initBuilder(
|
|
||||||
okParser,
|
|
||||||
concatFn(
|
|
||||||
builderAcc.tree,
|
|
||||||
defaultBuilderTokens,
|
|
||||||
builderFn(okParser.tokens),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
if not found:
|
|
||||||
parserAcc = parserAcc.flatMap(anyCh)
|
|
||||||
|
|
||||||
let defaultBuilderTokens = parserAcc
|
|
||||||
.foldTokens(
|
|
||||||
onError = _ => newSeq[T](),
|
|
||||||
onSuccess = defaultBuilderFn,
|
|
||||||
)
|
|
||||||
|
|
||||||
BuilderResult[T].ok(builder.initBuilder(
|
|
||||||
builderAcc.parser,
|
|
||||||
concatFn(
|
|
||||||
builderAcc.tree,
|
|
||||||
defaultBuilderTokens,
|
|
||||||
),
|
|
||||||
))
|
|
||||||
@@ -14,12 +14,12 @@ import ./parser_types
|
|||||||
|
|
||||||
# -- Types
|
# -- Types
|
||||||
|
|
||||||
type parserFnT = proc(t0: Parser): ParserResult {.nosideeffect.}
|
type parserFnT = proc(t0: Parser): ParserResult
|
||||||
|
|
||||||
# -- Utilities
|
# -- Utilities
|
||||||
|
|
||||||
func lookBack*(count: int): (parserFnT) =
|
proc lookBack*(count: int): (parserFnT) =
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
let state = parser.state
|
let state = parser.state
|
||||||
let newIndex = state.position - 1
|
let newIndex = state.position - 1
|
||||||
|
|
||||||
@@ -32,10 +32,10 @@ func lookBack*(count: int): (parserFnT) =
|
|||||||
tokens: parser.tokens,
|
tokens: parser.tokens,
|
||||||
).ok()
|
).ok()
|
||||||
|
|
||||||
# -- Parsing Functions
|
# -- Parsing Proctions
|
||||||
|
|
||||||
func ch*(expectedChars: set[char]): parserFnT {.inline.} =
|
proc ch*(expectedChars: set[char]): parserFnT {.inline.} =
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
let state = parser.state
|
let state = parser.state
|
||||||
let newIndex = state.position + 1
|
let newIndex = state.position + 1
|
||||||
|
|
||||||
@@ -66,8 +66,8 @@ func ch*(expectedChars: set[char]): parserFnT {.inline.} =
|
|||||||
parser: parser,
|
parser: parser,
|
||||||
))
|
))
|
||||||
|
|
||||||
func ch*(expectedChar: char): parserFnT {.inline.} =
|
proc ch*(expectedChar: char): parserFnT {.inline.} =
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
let state = parser.state
|
let state = parser.state
|
||||||
let newIndex = state.position + 1
|
let newIndex = state.position + 1
|
||||||
|
|
||||||
@@ -98,10 +98,10 @@ func ch*(expectedChar: char): parserFnT {.inline.} =
|
|||||||
parser: parser,
|
parser: parser,
|
||||||
))
|
))
|
||||||
|
|
||||||
const anyCh* = ch(AllChars)
|
let anyCh* = ch(AllChars)
|
||||||
|
|
||||||
func str*(s: string): parserFnT {.inline.} =
|
proc str*(s: string): parserFnT {.inline.} =
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
var p = parser.ok()
|
var p = parser.ok()
|
||||||
for c in s.items:
|
for c in s.items:
|
||||||
p = p.flatMap(ch(c))
|
p = p.flatMap(ch(c))
|
||||||
@@ -109,9 +109,9 @@ func str*(s: string): parserFnT {.inline.} =
|
|||||||
|
|
||||||
# -- Parsing API
|
# -- Parsing API
|
||||||
|
|
||||||
func optional*(parserFn: parserFnT): parserFnT {.inline.} =
|
proc optional*(parserFn: parserFnT): parserFnT {.inline.} =
|
||||||
## Parse characters and ignore failure
|
## Parse characters and ignore failure
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
let newParser = parserFn(parser)
|
let newParser = parserFn(parser)
|
||||||
|
|
||||||
if newParser.isOk():
|
if newParser.isOk():
|
||||||
@@ -119,18 +119,18 @@ func optional*(parserFn: parserFnT): parserFnT {.inline.} =
|
|||||||
else:
|
else:
|
||||||
parser.ok()
|
parser.ok()
|
||||||
|
|
||||||
func ignore*(parserFn: parserFnT): parserFnT {.inline.} =
|
proc ignore*(parserFn: parserFnT): parserFnT {.inline.} =
|
||||||
## Parse characters but throw success tokens away
|
## Parse characters but throw success tokens away
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
return parserFn(parser)
|
return parserFn(parser)
|
||||||
.map((x: Parser) => Parser(
|
.map((x: Parser) => Parser(
|
||||||
state: x.state,
|
state: x.state,
|
||||||
tokens: parser.tokens,
|
tokens: parser.tokens,
|
||||||
))
|
))
|
||||||
|
|
||||||
func manyUntilPerformant*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} =
|
proc manyUntilPerformant*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} =
|
||||||
## Parse characters but throw success tokens away
|
## Parse characters but throw success tokens away
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
let startPosition = parser.state.position
|
let startPosition = parser.state.position
|
||||||
var res: ParserResult = parser.ok()
|
var res: ParserResult = parser.ok()
|
||||||
|
|
||||||
@@ -151,22 +151,22 @@ func manyUntilPerformant*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.i
|
|||||||
]
|
]
|
||||||
))
|
))
|
||||||
|
|
||||||
func anyUntilPerformant*(stopFn: parserFnT): parserFnT {.inline.} =
|
proc anyUntilPerformant*(stopFn: parserFnT): parserFnT {.inline.} =
|
||||||
manyUntilPerformant(ch(AllChars), stopFn)
|
manyUntilPerformant(ch(AllChars), stopFn)
|
||||||
|
|
||||||
func manyUntil*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} =
|
proc manyUntil*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} =
|
||||||
## Parse characters but throw success tokens away
|
## Parse characters but throw success tokens away
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
var res: ParserResult = parser.ok()
|
var res: ParserResult = parser.ok()
|
||||||
while res.isOk() and res.flatMap(stopFn).isErr():
|
while res.isOk() and res.flatMap(stopFn).isErr():
|
||||||
res = res.flatMap(acceptFn)
|
res = res.flatMap(acceptFn)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
func anyUntil*(stopFn: parserFnT): parserFnT {.inline.} =
|
proc anyUntil*(stopFn: parserFnT): parserFnT {.inline.} =
|
||||||
manyUntil(anyCh, stopFn)
|
manyUntil(anyCh, stopFn)
|
||||||
|
|
||||||
func choice*(parsers: seq[parserFnT]): parserFnT {.inline} =
|
proc choice*(parsers: seq[parserFnT]): parserFnT {.inline} =
|
||||||
return func(parser: Parser): ParserResult {.closure, nosideeffect.} =
|
return proc(parser: Parser): ParserResult {.closure.} =
|
||||||
var errors: seq[ParserResult] = newSeq[ParserResult]()
|
var errors: seq[ParserResult] = newSeq[ParserResult]()
|
||||||
var found = Nothing[ParserResult]()
|
var found = Nothing[ParserResult]()
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ func choice*(parsers: seq[parserFnT]): parserFnT {.inline} =
|
|||||||
|
|
||||||
return found
|
return found
|
||||||
.fold(
|
.fold(
|
||||||
func(): ParserResult =
|
proc(): ParserResult =
|
||||||
let prettyErrors = errors.map((x: ParserResult) => x.error().expected)
|
let prettyErrors = errors.map((x: ParserResult) => x.error().expected)
|
||||||
err(ParserError(
|
err(ParserError(
|
||||||
kind: choiceMismatchErr,
|
kind: choiceMismatchErr,
|
||||||
@@ -190,21 +190,21 @@ func choice*(parsers: seq[parserFnT]): parserFnT {.inline} =
|
|||||||
unexpected: errors[0].error().unexpected,
|
unexpected: errors[0].error().unexpected,
|
||||||
parser: parser,
|
parser: parser,
|
||||||
)),
|
)),
|
||||||
func(x: ParserResult): ParserResult = x,
|
proc(x: ParserResult): ParserResult = x,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func `+`*(parserFnA: parserFnT, parserFnB: parserFnT): parserFnT {.inline.} =
|
proc `+`*(parserFnA: parserFnT, parserFnB: parserFnT): parserFnT {.inline.} =
|
||||||
## Parse characters and ignore failure
|
## Parse characters and ignore failure
|
||||||
return func(parser: Parser): ParserResult =
|
return proc(parser: Parser): ParserResult =
|
||||||
parserFnA(parser).flatMap(parserFnB)
|
parserFnA(parser).flatMap(parserFnB)
|
||||||
|
|
||||||
func parseSeq*(parser: ParserResult, xs: seq[parserFnT]): ParserResult =
|
proc parseSeq*(parser: ParserResult, xs: seq[parserFnT]): ParserResult {.inline.} =
|
||||||
xs.foldl(a.flatMap(b), parser)
|
xs.foldl(a.flatMap(b), parser)
|
||||||
|
|
||||||
# -- Parsing Aliases
|
# -- Parsing Aliases
|
||||||
|
|
||||||
func endOfStream*(parser: Parser): ParserResult =
|
proc endOfStream*(parser: Parser): ParserResult =
|
||||||
let index = parser.state.position + 1
|
let index = parser.state.position + 1
|
||||||
if index == parser.state.stream.len:
|
if index == parser.state.stream.len:
|
||||||
ok(parser)
|
ok(parser)
|
||||||
@@ -216,27 +216,40 @@ func endOfStream*(parser: Parser): ParserResult =
|
|||||||
parser: parser,
|
parser: parser,
|
||||||
))
|
))
|
||||||
|
|
||||||
const newlineParser = choice(@[
|
let newlineParser = choice(@[
|
||||||
ch(NewLines),
|
ch(NewLines),
|
||||||
endOfStream,
|
endOfStream,
|
||||||
])
|
])
|
||||||
|
|
||||||
func newline*(parser: Parser): ParserResult =
|
proc newline*(parser: Parser): ParserResult =
|
||||||
newlineParser(parser)
|
newlineParser(parser)
|
||||||
.mapErr((x: ParserError) => x.setErrorExpectedField("Newline"))
|
.mapErr((x: ParserError) => x.setErrorExpectedField("Newline"))
|
||||||
|
|
||||||
const whitespaceParser = choice(@[
|
let whitespaceParser = choice(@[
|
||||||
ch(Whitespace),
|
ch(Whitespace),
|
||||||
newlineParser,
|
newlineParser,
|
||||||
])
|
])
|
||||||
func whitespace*(parser: Parser): ParserResult =
|
proc whitespace*(parser: Parser): ParserResult =
|
||||||
whitespaceParser(parser)
|
whitespaceParser(parser)
|
||||||
.mapErr((x: ParserError) => x.setErrorExpectedField("Whitespace"))
|
.mapErr((x: ParserError) => x.setErrorExpectedField("Whitespace"))
|
||||||
|
|
||||||
# -- Parsing Helpers
|
# -- Parsing Helpers
|
||||||
|
|
||||||
const parseBetweenDelimiter* = func(start: parserFnT, stop: parserFnT): parserFnT {.closure.} =
|
let parseBetweenDelimiter* = proc(start: parserFnT, stop: parserFnT): parserFnT {.closure.} =
|
||||||
ignore(start) + anyUntil(stop + whitespace) + ignore(start)
|
ignore(start) + anyUntil(stop + whitespace) + ignore(start)
|
||||||
|
|
||||||
const parseBetweenPair* = func(delimiterParser: parserFnT): parserFnT {.closure.} =
|
let parseBetweenPair* = proc(delimiterParser: parserFnT): parserFnT {.closure.} =
|
||||||
parseBetweenDelimiter(delimiterParser, delimiterParser)
|
parseBetweenDelimiter(delimiterParser, delimiterParser)
|
||||||
|
|
||||||
|
# -- Tests
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
let test1 = initParserResult("123")
|
||||||
|
|
||||||
|
let ch1 = ch('1')
|
||||||
|
let chDigits = @[ch(Digits)]
|
||||||
|
|
||||||
|
# echo type ch1
|
||||||
|
# echo test1.flatMap((x: Parser) => ParserResult.ok(x))
|
||||||
|
echo test1.flatMap(newlineParser)
|
||||||
|
# .flatMap(ch1)
|
||||||
|
|||||||
@@ -70,10 +70,10 @@ func initParser*(str: string): Parser =
|
|||||||
tokens: newSeq[ParserToken](),
|
tokens: newSeq[ParserToken](),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc initParserResult*(str: string): ParserResult =
|
func initParserResult*(str: string): ParserResult =
|
||||||
ParserResult.ok(initParser(str))
|
ParserResult.ok(initParser(str))
|
||||||
|
|
||||||
proc initBuilder*[T](t: Builder[T], parser: Parser, tree: seq[T]): Builder[T] =
|
func initBuilder*[T](t: Builder[T], parser: Parser, tree: seq[T]): Builder[T] =
|
||||||
Builder[T]((
|
Builder[T]((
|
||||||
parser,
|
parser,
|
||||||
tree
|
tree
|
||||||
@@ -113,7 +113,7 @@ func emptyTokens*(parser: Parser): Parser =
|
|||||||
tokens: newSeq[ParserToken](),
|
tokens: newSeq[ParserToken](),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc foldTokens*[T](
|
func foldTokens*[T](
|
||||||
parserResult: ParserResult,
|
parserResult: ParserResult,
|
||||||
onError: ParserError -> T,
|
onError: ParserError -> T,
|
||||||
onSuccess: seq[ParserToken] -> T,
|
onSuccess: seq[ParserToken] -> T,
|
||||||
@@ -133,13 +133,13 @@ func setErrorExpectedField*(err: ParserError, expected: string): ParserError =
|
|||||||
parser: err.parser,
|
parser: err.parser,
|
||||||
)
|
)
|
||||||
|
|
||||||
proc mapTree*[T](builder: BuilderResult[T], fn: seq[T] -> seq[T]): BuilderResult[T] =
|
func mapTree*[T](builder: BuilderResult[T], fn: seq[T] -> seq[T]): BuilderResult[T] =
|
||||||
builder.map(proc(b: Builder[T]): Builder[T] = Builder((
|
builder.map(func(b: Builder[T]): Builder[T] = Builder((
|
||||||
parser: b[0],
|
parser: b[0],
|
||||||
tree: fn(b[1]),
|
tree: fn(b[1]),
|
||||||
)))
|
)))
|
||||||
|
|
||||||
proc tryParser*[T](
|
func tryParser*[T](
|
||||||
builder: Builder[T],
|
builder: Builder[T],
|
||||||
parser: Parser -> ParserResult,
|
parser: Parser -> ParserResult,
|
||||||
): BuilderResult[T] =
|
): BuilderResult[T] =
|
||||||
@@ -155,7 +155,7 @@ proc tryParser*[T](
|
|||||||
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder),
|
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc tryParser*[T](
|
func tryParser*[T](
|
||||||
builder: BuilderResult[T],
|
builder: BuilderResult[T],
|
||||||
parser: Parser -> ParserResult,
|
parser: Parser -> ParserResult,
|
||||||
): BuilderResult[T] =
|
): BuilderResult[T] =
|
||||||
@@ -163,7 +163,7 @@ proc tryParser*[T](
|
|||||||
## When succesful return the ok builder, otherwise return an error
|
## When succesful return the ok builder, otherwise return an error
|
||||||
builder.flatMap((x: Builder[T]) => tryParser(x, parser))
|
builder.flatMap((x: Builder[T]) => tryParser(x, parser))
|
||||||
|
|
||||||
proc applyParsersToSingle*[T](
|
func applyParsersToSingle*[T](
|
||||||
builder: Builder[T],
|
builder: Builder[T],
|
||||||
parsers: seq[Parser -> ParserResult],
|
parsers: seq[Parser -> ParserResult],
|
||||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||||
@@ -200,7 +200,7 @@ proc applyParsersToSingle*[T](
|
|||||||
)
|
)
|
||||||
|
|
||||||
## TODO Implement applyParsersSeqToSingle with this function by forming the concatFn
|
## TODO Implement applyParsersSeqToSingle with this function by forming the concatFn
|
||||||
proc applyParsersToSeq*[T](
|
func applyParsersToSeq*[T](
|
||||||
builder: Builder[T],
|
builder: Builder[T],
|
||||||
parsers: seq[Parser -> ParserResult],
|
parsers: seq[Parser -> ParserResult],
|
||||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||||
@@ -231,7 +231,7 @@ proc applyParsersToSeq*[T](
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
proc applyParsersSeqToSingle*[T](
|
func applyParsersSeqToSingle*[T](
|
||||||
builderResult: BuilderResult[T],
|
builderResult: BuilderResult[T],
|
||||||
initT: T,
|
initT: T,
|
||||||
xs: seq[tuple[
|
xs: seq[tuple[
|
||||||
@@ -252,7 +252,7 @@ proc applyParsersSeqToSingle*[T](
|
|||||||
builderResult
|
builderResult
|
||||||
)
|
)
|
||||||
|
|
||||||
proc applyParsersSeqToSeq*[T](
|
func applyParsersSeqToSeq*[T](
|
||||||
builderResult: BuilderResult[T],
|
builderResult: BuilderResult[T],
|
||||||
xs: seq[tuple[
|
xs: seq[tuple[
|
||||||
parsers: seq[Parser -> ParserResult],
|
parsers: seq[Parser -> ParserResult],
|
||||||
@@ -273,12 +273,12 @@ proc applyParsersSeqToSeq*[T](
|
|||||||
builderResult
|
builderResult
|
||||||
)
|
)
|
||||||
|
|
||||||
proc applyParsers*[T](
|
func applyParsers*[T](
|
||||||
builder: Builder[T],
|
builder: Builder[T],
|
||||||
parsers: seq[Parser -> ParserResult],
|
parsers: seq[Parser -> ParserResult],
|
||||||
tokenFoldFn: (seq[ParserToken], seq[T]) -> seq[T],
|
tokenFoldFn: (seq[ParserToken], seq[T]) -> seq[T],
|
||||||
): BuilderResult[T] =
|
): BuilderResult[T] =
|
||||||
# proc nested(b: Builder[T]): BuilderResult[T] =
|
# func nested(b: Builder[T]): BuilderResult[T] =
|
||||||
let newParser = ParserResult.ok(Parser(
|
let newParser = ParserResult.ok(Parser(
|
||||||
state: builder[0].state,
|
state: builder[0].state,
|
||||||
tokens: @[]
|
tokens: @[]
|
||||||
@@ -293,7 +293,7 @@ proc applyParsers*[T](
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
proc applyParsersSeq*[T](
|
func applyParsersSeq*[T](
|
||||||
builder: BuilderResult[T],
|
builder: BuilderResult[T],
|
||||||
xs: seq[tuple[
|
xs: seq[tuple[
|
||||||
parsers: seq[Parser -> ParserResult],
|
parsers: seq[Parser -> ParserResult],
|
||||||
@@ -302,7 +302,7 @@ proc applyParsersSeq*[T](
|
|||||||
xs.foldl(a.flatMap((x: Builder[T]) => x.applyParsers(b[0], b[1])), builder)
|
xs.foldl(a.flatMap((x: Builder[T]) => x.applyParsers(b[0], b[1])), builder)
|
||||||
|
|
||||||
|
|
||||||
proc foldBuilder*[T, T2](
|
func foldBuilder*[T, T2](
|
||||||
builderResult: BuilderResult[T],
|
builderResult: BuilderResult[T],
|
||||||
onError: string -> T2,
|
onError: string -> T2,
|
||||||
onSuccess: seq[T] -> T2,
|
onSuccess: seq[T] -> T2,
|
||||||
@@ -313,7 +313,7 @@ proc foldBuilder*[T, T2](
|
|||||||
let err = builderResult.error()
|
let err = builderResult.error()
|
||||||
onError(err[1])
|
onError(err[1])
|
||||||
|
|
||||||
# proc parseBuildOr*[T](
|
# func parseBuildOr*[T](
|
||||||
# ## Checks
|
# ## Checks
|
||||||
# builderResult: BuilderResult[T],
|
# builderResult: BuilderResult[T],
|
||||||
# builders: seq[tuple[
|
# builders: seq[tuple[
|
||||||
@@ -415,20 +415,20 @@ func highlightStreamPosition2(stream: string, position: int): string =
|
|||||||
|
|
||||||
stream.dup(insert(&"{beforeNewline}{spaceChars}^{lineChars} Char at \"{escapedChar}\"\n", insertMessageAtIndex))
|
stream.dup(insert(&"{beforeNewline}{spaceChars}^{lineChars} Char at \"{escapedChar}\"\n", insertMessageAtIndex))
|
||||||
|
|
||||||
proc `$`*(x: ParserState): string =
|
func `$`*(x: ParserState): string =
|
||||||
&"""ParserState(
|
&"""ParserState(
|
||||||
stream: "{x.stream.highlightStreamPosition(x.position)}",
|
stream: "{x.stream.highlightStreamPosition(x.position)}",
|
||||||
position: {x.position},
|
position: {x.position},
|
||||||
lastPosition: {x.lastPosition},
|
lastPosition: {x.lastPosition},
|
||||||
)"""
|
)"""
|
||||||
|
|
||||||
proc `$`*(x: Parser): string =
|
func `$`*(x: Parser): string =
|
||||||
&"""Parser(
|
&"""Parser(
|
||||||
state: {indentAfterNewline($x.state, 2)},
|
state: {indentAfterNewline($x.state, 2)},
|
||||||
tokens: {indentAfterNewline($x.tokens, 2)},
|
tokens: {indentAfterNewline($x.tokens, 2)},
|
||||||
)"""
|
)"""
|
||||||
|
|
||||||
proc `$`*(x: ParserError): string =
|
func `$`*(x: ParserError): string =
|
||||||
case x:
|
case x:
|
||||||
of charMismatchErr(expected: @expected, parser: @parser, index: @index, unexpected: @unexpected):
|
of charMismatchErr(expected: @expected, parser: @parser, index: @index, unexpected: @unexpected):
|
||||||
# TODO: Only works for single line right now
|
# TODO: Only works for single line right now
|
||||||
|
|||||||
11
src_v2/parser/test.nim
Normal file
11
src_v2/parser/test.nim
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import sugar
|
||||||
|
import results
|
||||||
|
|
||||||
|
func adder_generator(a: int): (int -> int) =
|
||||||
|
return func(b: int): int =
|
||||||
|
a + b
|
||||||
|
|
||||||
|
|
||||||
|
const add_1 = adder_generator(1)
|
||||||
|
|
||||||
|
echo add_1(1)
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import std/sugar
|
|
||||||
import std/collections/sequtils
|
|
||||||
import results
|
|
||||||
import ./parser_types
|
|
||||||
|
|
||||||
type StringBuilderT* = string
|
|
||||||
type StringBuilder* = Builder[StringBuilderT]
|
|
||||||
type StringBuilderResult* = BuilderResult[StringBuilderT]
|
|
||||||
|
|
||||||
proc stringConcat*(typeInfo: StringBuilderT, seperator = ""):
|
|
||||||
(seq[ParserToken], seq[StringBuilderT]) -> seq[StringBuilderT] =
|
|
||||||
|
|
||||||
return proc(xs: seq[ParserToken], ys: seq[StringBuilderT]): seq[StringBuilderT] =
|
|
||||||
return ys & xs.foldl(a & b.tokenStringValue() & seperator, typeInfo)
|
|
||||||
|
|
||||||
proc initStringBuilder*(str: string): StringBuilderResult =
|
|
||||||
StringBuilderResult
|
|
||||||
.ok(StringBuilder((
|
|
||||||
parser: initParser(str),
|
|
||||||
tree: newSeq[StringBuilderT](),
|
|
||||||
)))
|
|
||||||
|
|
||||||
proc fold*[T, E, T2](
|
|
||||||
self: Result[T, E],
|
|
||||||
onError: E -> T2,
|
|
||||||
onSuccess: T -> T2,
|
|
||||||
): T2 =
|
|
||||||
if self.isOk():
|
|
||||||
onSuccess(self.unsafeGet())
|
|
||||||
else:
|
|
||||||
onError(self.error())
|
|
||||||
Reference in New Issue
Block a user