Basic builder structure
This commit is contained in:
@@ -1,7 +1,11 @@
|
|||||||
|
import std/[
|
||||||
|
sugar,
|
||||||
|
]
|
||||||
import fp/[
|
import fp/[
|
||||||
resultM,
|
resultM,
|
||||||
]
|
]
|
||||||
import ./parser_types
|
import ./parser_types
|
||||||
|
import ./parser_api
|
||||||
|
|
||||||
type
|
type
|
||||||
Builder*[T] = tuple[
|
Builder*[T] = tuple[
|
||||||
@@ -12,5 +16,73 @@ type
|
|||||||
parserError
|
parserError
|
||||||
BuilderError*[T] = ref object
|
BuilderError*[T] = ref object
|
||||||
kind*: builderErrorKind
|
kind*: builderErrorKind
|
||||||
builder*: Builder[T]
|
parser*: ParserError
|
||||||
|
tree*: seq[T]
|
||||||
BuilderResult*[T] = Result[Builder[T], BuilderError[T]]
|
BuilderResult*[T] = Result[Builder[T], BuilderError[T]]
|
||||||
|
|
||||||
|
# -- Initalizers
|
||||||
|
|
||||||
|
proc initBuilder*[T](parser: Parser, tree: seq[T]): Builder[T] =
|
||||||
|
Builder[T]((
|
||||||
|
parser,
|
||||||
|
tree
|
||||||
|
))
|
||||||
|
|
||||||
|
# -- Modifiers
|
||||||
|
|
||||||
|
proc setParser*[T](builder: Builder[T], parser: Parser): Builder[T] =
|
||||||
|
Builder[T]((
|
||||||
|
parser,
|
||||||
|
builder.tree,
|
||||||
|
))
|
||||||
|
|
||||||
|
proc setTree*[T](builder: Builder[T], tree: seq[T]): Builder[T] =
|
||||||
|
Builder[T]((
|
||||||
|
builder.parser,
|
||||||
|
tree,
|
||||||
|
))
|
||||||
|
|
||||||
|
proc tryParser*[T](
|
||||||
|
builder: Builder[T],
|
||||||
|
parserFn: parserFnT,
|
||||||
|
): BuilderResult[T] =
|
||||||
|
## Try out a `parser` on a `builder`
|
||||||
|
## When successful return the original builder, otherwise return an error
|
||||||
|
let parser = ParserResult
|
||||||
|
.ok(Parser(
|
||||||
|
state: builder.parser.state,
|
||||||
|
tokens: @[],
|
||||||
|
))
|
||||||
|
.flatMap(parserFn)
|
||||||
|
|
||||||
|
parser
|
||||||
|
.foldTokens(
|
||||||
|
(err: ParserError) => BuilderResult[T].err(BuilderError[T](
|
||||||
|
kind: parserError,
|
||||||
|
parser: err,
|
||||||
|
tree: builder.tree,
|
||||||
|
)),
|
||||||
|
(newTokens: seq[ParserToken]) => BuilderResult[T].ok(builder),
|
||||||
|
)
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
type TestStringBuilderT* = string
|
||||||
|
type TestStringBuilder* = Builder[TestStringBuilderT]
|
||||||
|
type TestStringBuilderResult* = BuilderResult[TestStringBuilderT]
|
||||||
|
|
||||||
|
let testBuilder123 = initBuilder(
|
||||||
|
initParser("123"),
|
||||||
|
newSeq[TestStringBuilderT]()
|
||||||
|
)
|
||||||
|
|
||||||
|
block testModifiers:
|
||||||
|
# setters
|
||||||
|
assert testBuilder123.setParser(initParser("abc")).parser.state.stream == "abc"
|
||||||
|
assert testBuilder123.setTree(@["abc"]).tree[0] == "abc"
|
||||||
|
|
||||||
|
# tryParser
|
||||||
|
assert testBuilder123.tryParser(ch('1')).isOk() == true
|
||||||
|
assert testBuilder123.tryParser(ch('2')).isErr() == true
|
||||||
|
|
||||||
|
# echo testBuilder123
|
||||||
|
# block testModifiers:
|
||||||
|
|||||||
Reference in New Issue
Block a user