Add implementations

This commit is contained in:
Florian Schroedl
2022-08-29 12:05:50 +02:00
parent 0ba76a1203
commit 17c8927deb
4 changed files with 221 additions and 0 deletions

View File

@@ -0,0 +1,218 @@
import std/[
collections/sequtils,
strformat,
strutils,
sugar,
]
import fp/[
option,
resultM,
]
import fusion/matching
{.experimental: "caseStmtMacros".}
import ./org_types
import ./org_builder_api
import ../parser/parser
import ../utils/fp
# -- Parsers
let headingStarsParser* = following(@[
ignore(optional(newline)),
manyUntil(ch('*'), ch(' ')),
ignore(space)
])
proc createTodoKeywordParser(xs: seq[string]): parserFnT =
choice(xs.map((x: string) => str(x) + ignore(space)))
let todoKeywords = @["TODO"]
let doneKeywords = @["DONE"]
let parseTodoKeyword = todoKeywords.createTodoKeywordParser()
let parseDoneKeyword = doneKeywords.createTodoKeywordParser()
# let parseContentText = @[
# anyUntil(choice(@[endOfStream, str("\n")])),
# ]
# let parseHeadlineNewline = @[
# choice(@[
# ch(NewLines),
# endOfStream,
# ])
# ]
# let parseHeadingText = @[
# anyUntil(newline),
# ]
# -- Tokenizers
let buildStars = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
org.level = tokens.len
org
# let buildTodo = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
# org.todo = tokens.tokensToString().some()
# org
# let buildHeadlineContent = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
# let headlineString = tokens.tokensToString()
# let tokens = tryBuildInline(headlineString)
# .fold(
# x => newSeq[OrgInlineBuilderT](),
# (x: OrgInlineBuilder) => x.tree,
# )
# org.headlineContent = tokens
# org
# let buildHeadlineChildren = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
# # let headlineString = tokens.tokensToString()
# org
# let buildHeadlineNewline = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.}=
# org
# proc tryBuildHeading(builder: OrgBuilderResult): OrgBuilderResult =
# # echo builder
# builder
# .applyParsersSeqToSingle(
# OrgBlock(kind: orgHeading),
# @[
# (parseHeadingStars, buildStars, false),
# (@[optional(parseTodoKeyword)], buildTodo, true),
# (@[optional(parseDoneKeyword)], buildTodo, true),
# (parseHeadingText, buildHeadlineContent, false),
# # (parseContentText, buildHeadlineChildren, true),
# (parseHeadlineNewline, buildHeadlineNewline, false),
# ]
# )
# let headingParser = choice(@[
# newline + ch('*'),
# endOfStream,
# ])
# let contentEndParser = newline
# let buildNewline = func(tokens: seq[ParserToken], org: OrgBlock): OrgBlock {.closure.} =
# OrgBlock(
# kind: orgNewline
# )
# proc concatOrgBlock(xs: seq[OrgBlock], ys: seq[OrgBlock]): seq[OrgBlock] = xs & ys
# let parseBlockText = @[
# anyUntil(choice(@[endOfStream, str("\n")])),
# ]
# let contentParsersSeq: seq[tuple[
# parsers: seq[Parser -> ParserResult],
# tokenFoldFn: (seq[ParserToken], OrgBlock) -> OrgBlock,
# ignoreEmpty: bool,
# # concatFn: (seq[OrgBlock], seq[OrgBlock]) -> seq[OrgBlock],
# ]] = @[
# (parseBlockText, buildNewline, true),
# (contentEndParser, buildNewline, true),
# ]
# proc parseHeadlineChildren(builder: OrgBuilder): OrgBuilderResult =
# var headingBlock = builder.tree[0]
# # echo "Builder " & $builder
# # var builderAcc: OrgBuilderResult = OrgBuilderResult.ok(builder)
# var builderAcc: OrgBuilderResult = OrgBuilderResult.ok(OrgBuilder(
# (
# parser: builder.parser,
# tree: @[],
# )
# ))
# echo "builderAcc before parse content ", builderAcc
# # echo builderAcc.tryParser(headingParser)
# while builderAcc.isOk() and builderAcc.tryParser(headingParser).isErr():
# builderAcc = builderAcc
# .applyParsersSeqToSeq(
# contentParsersSeq
# )
# echo "builderAcc after parse in while loop ", builderAcc
# # echo builderAcc
# let content = builderAcc.fold(
# (err) => 0, # newSeq[OrgBlock](),
# (builder: OrgBuilder) => len builder.tree,
# )
# # echo "builderAcc" & $builderAcc
# echo "content" & $content
# # headingBlock.content = content
# let res = builderAcc.fold(
# (err) => OrgBuilderResult.err((builder, "Could not parse content")),
# (builder: OrgBuilder) => OrgBuilderResult.ok((
# parser: builder.parser.emptyTokens(),
# tree: @[headingBlock],
# ))
# )
# res
# proc makeOrg*(x: string): OrgBuilderResult =
# var acc = initOrgBuilder(x)
# while acc.isOk() and acc.tryParser(endOfStream).isErr():
# let unsafeAcc = acc.unsafeGet()
# let item = acc
# .tryBuildHeading()
# .flatMap(
# (x: OrgBuilder) => parseHeadlineChildren(x)
# )
# .flatMap(
# (x: OrgBuilder) => OrgBuilderResult.ok(OrgBuilder((
# parser: x.parser,
# tree: unsafeAcc.tree & x.tree,
# )))
# )
# acc = item
# acc
# proc foldOrg*(x: OrgBuilderResult): string =
# x
# .fold(
# (err) => "Error" & $err,
# (builder: OrgBuilder) => $builder.tree,
# )
# # echo acc.unsafeGet().tree[^1]
# when isMainModule:
# let test1 = """* TODO Level 1"""
# let test2 = """* TODO Level 1
# Foo
# ** DONE Level 2
# Some more content
# """
# let test3 = """* TODO Level 1
# Foo
# """
# let acc = makeOrg(test3).foldOrg()
# discard acc

View File

3
src_v2/org/test.nim Normal file
View File

@@ -0,0 +1,3 @@
import experimental/diff
echo diff(@[1,2,3], @[1,2,3])

View File