Create an org heading builder
This commit is contained in:
@@ -7,6 +7,21 @@ 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[
|
||||
|
||||
@@ -3,8 +3,10 @@ import std/strformat
|
||||
import std/collections/sequtils
|
||||
import std/sugar
|
||||
import results
|
||||
import fp/maybe
|
||||
import fusion/matching
|
||||
import ../utils/str
|
||||
import ../utils/fp
|
||||
|
||||
{.experimental: "caseStmtMacros".}
|
||||
|
||||
@@ -46,6 +48,12 @@ type
|
||||
]
|
||||
BuilderResult*[T] = Result[Builder[T], (Builder[T], string)]
|
||||
|
||||
# SingleBuilder*[T] = tuple[
|
||||
# parser: Parser,
|
||||
# tree: T
|
||||
# ]
|
||||
# SingleBuilderResult*[T] = Result[SingleBuilder[T], (SingleBuilder[T], string)]
|
||||
|
||||
# -- Initalizers
|
||||
|
||||
func initParserToken*(x: char): ParserToken = ParserToken(kind: parserTokenChar, charValue: x)
|
||||
@@ -130,6 +138,71 @@ proc mapTree*[T](builder: BuilderResult[T], fn: seq[T] -> seq[T]): BuilderResult
|
||||
tree: fn(b[1]),
|
||||
)))
|
||||
|
||||
proc tryParser*[T](
|
||||
builder: Builder[T],
|
||||
parser: Parser -> ParserResult,
|
||||
): BuilderResult[T] =
|
||||
## Try out a `parser` on a `builder`
|
||||
## When succesful return the original builder, otherwise return an error
|
||||
ParserResult.ok(Parser(
|
||||
state: builder[0].state,
|
||||
tokens: @[]
|
||||
))
|
||||
.flatMap(parser)
|
||||
.foldTokens(
|
||||
(err: ParserError) => BuilderResult[T].err((builder, "Error")),
|
||||
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder),
|
||||
)
|
||||
|
||||
proc tryParser*[T](
|
||||
builder: BuilderResult[T],
|
||||
parser: Parser -> ParserResult,
|
||||
): BuilderResult[T] =
|
||||
## Try out a `parser` on a `builder` result
|
||||
## When succesful return the ok builder, otherwise return an error
|
||||
builder.flatMap((x: Builder[T]) => tryParser(x, parser))
|
||||
|
||||
proc applyParsersToSingle*[T](
|
||||
builder: Builder[T],
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||
initT: T,
|
||||
): BuilderResult[T] =
|
||||
# Apply the current parsing functions and convert to text tokens wrapped in ParserResult
|
||||
let newParser = ParserResult.ok(Parser(
|
||||
state: builder[0].state,
|
||||
tokens: @[]
|
||||
))
|
||||
.parseSeq(parsers)
|
||||
|
||||
newParser
|
||||
.foldTokens(
|
||||
(err: ParserError) => BuilderResult[T].err((builder, "foo")),
|
||||
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(
|
||||
builder.initBuilder(
|
||||
newParser.unsafeGet(),
|
||||
builder.tree
|
||||
.last()
|
||||
.orElse(just(initT))
|
||||
.map((x: T) => @[tokenFoldFn(newTokens, x)])
|
||||
.getOrElse(newSeq[T]())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
proc applyParsersSeqToSingle*[T](
|
||||
builderResult: BuilderResult[T],
|
||||
initT: T,
|
||||
xs: seq[tuple[
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
tokenFoldFn: (seq[ParserToken], T) -> T,
|
||||
]],
|
||||
): BuilderResult[T] =
|
||||
xs.foldl(
|
||||
a.flatMap((builder: Builder[T]) => applyParsersToSingle(builder, b[0], b[1], initT)),
|
||||
builderResult
|
||||
)
|
||||
|
||||
proc applyParsers*[T](
|
||||
builder: Builder[T],
|
||||
parsers: seq[Parser -> ParserResult],
|
||||
|
||||
Reference in New Issue
Block a user