From bd5e2db4608d773d085e4880d743357bbb0fd266 Mon Sep 17 00:00:00 2001 From: Larpon Date: Wed, 3 Nov 2021 09:15:40 +0100 Subject: [PATCH] toml: add Parser.peek(n) method (#12369) --- vlib/toml/parser/parser.v | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/vlib/toml/parser/parser.v b/vlib/toml/parser/parser.v index b28b37d625..565da99c03 100644 --- a/vlib/toml/parser/parser.v +++ b/vlib/toml/parser/parser.v @@ -18,6 +18,7 @@ mut: prev_tok token.Token tok token.Token peek_tok token.Token + tokens []token.Token // To be able to peek more than one token ahead. skip_next bool // The root map (map is called table in TOML world) root_map map[string]ast.Value @@ -48,6 +49,7 @@ pub fn new_parser(config Config) Parser { // init initializes the parser. pub fn (mut p Parser) init() ? { p.root_map = map[string]ast.Value{} + p.tokens << p.scanner.scan() ? p.next() ? } @@ -79,10 +81,43 @@ pub fn (mut p Parser) parse() ?&ast.Root { fn (mut p Parser) next() ? { p.prev_tok = p.tok p.tok = p.peek_tok - p.peek_tok = p.scanner.scan() ? + if p.tokens.len > 0 { + p.peek_tok = p.tokens.pop() + p.peek(1) ? + } else { + p.peek(1) ? + p.peek_tok = p.tokens.pop() + } } -// check returns true if the current token's `Kind` is equal that of `expected_token`. +// peek peeks forward `n` tokens. +// peek returns `.unknown` if it can not peek ahead long enough. +fn (mut p Parser) peek(n int) ?token.Token { + if n < 0 { + return error(@MOD + '.' + @STRUCT + '.' + @FN + ' peeking backwards is not supported.') + } + if n == 0 { + return p.peek_tok + } else { + // n >= 1 + if n <= p.tokens.len { + return p.tokens[n - 1] + } else { + mut token := token.Token{} + mut count := n - p.tokens.len + util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'buffering $count tokens...') + for token.kind != .eof && count != 0 { + token = p.scanner.scan() ? + p.tokens << token + count-- + } + return token + } + } +} + +// check forwards the parser to the next token if the current +// token's `Kind` is equal that of `check_token`. fn (mut p Parser) check(check_token token.Kind) ? { if p.tok.kind == check_token { p.next() ?