From 0ba76a120350076071a56b183774e6cd4b7a3915 Mon Sep 17 00:00:00 2001 From: Florian Schroedl Date: Sun, 28 Aug 2022 18:19:53 +0200 Subject: [PATCH] Add peek functions --- src_v2/parser/parser_api.nim | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src_v2/parser/parser_api.nim b/src_v2/parser/parser_api.nim index cf9d384..0ff4f19 100644 --- a/src_v2/parser/parser_api.nim +++ b/src_v2/parser/parser_api.nim @@ -185,6 +185,27 @@ proc ignore*(parserFn: parserFnT): parserFnT {.inline.} = tokens: parser.tokens, )) +proc peek*(amount: int, parserFn: parserFnT): parserFnT {.inline.} = + ## Creates parser function with a nested `parserFn`: + ## Parses using the `parserFn` but dont capture the resulting tokens and keep the current position. + return proc(parser: Parser): ParserResult = + let state = parser.state + let newIndex = state.position + amount + + let newParser = initParser( + stream = state.stream, + tokens = parser.tokens, + position = newIndex, + lastPosition = state.position, + ) + + parserFn(newParser) + .map(p => parser) + +proc peek1*(parserFn: parserFnT): parserFnT = peek(1, parserFn) +proc peekCurrent*(parserFn: parserFnT): parserFnT = peek(0, parserFn) +proc peekBack1*(parserFn: parserFnT): parserFnT = peek(-1, parserFn) + proc manyUntil*(acceptFn: parserFnT, stopFn: parserFnT): parserFnT {.inline.} = ## Creates parser function with a nested `acceptFn` parser function until the `stopFn` parserFunction is met: ## Parses until the `stopFn` is reached or on an errror. @@ -330,6 +351,12 @@ when isMainModule: # ignore assert testParser123.flatMap(ignore(ch('1'))).tokensToString() == "" + # peek + assert testParser123.flatMap(ch('1') + peekCurrent(ch('2')) + ch('2')).tokensToString() == "12" + assert testParser123.flatMap(ch('1') + peekCurrent(ch('1'))).isErr() == true + assert testParser123.flatMap(peekCurrent(startOfStream)).isOk() == true + assert testParser123.flatMap(ch('1') + peekBack1(startOfStream)).isOk() == true + # manyUntil assert testAbc1Parser.flatMap(manyUntil(anyCh, digit)).tokensToString() == "abc"