parser.h (2556B)
1 #pragma once 2 3 #include <assert.h> 4 #include <stdbool.h> 5 #include <stddef.h> 6 7 #include "klib/kvec.h" 8 #include "nvim/mbyte_defs.h" 9 #include "nvim/viml/parser/parser_defs.h" // IWYU pragma: keep 10 11 #include "viml/parser/parser.h.generated.h" 12 #include "viml/parser/parser.h.inline.generated.h" 13 14 /// Initialize a new parser state instance 15 /// 16 /// @param[out] ret_pstate Parser state to initialize. 17 /// @param[in] get_line Line getter function. 18 /// @param[in] cookie Argument for the get_line function. 19 /// @param[in] colors Where to save highlighting. May be NULL if it is not 20 /// needed. 21 static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line, 22 void *const cookie, ParserHighlight *const colors) 23 FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1, 2) 24 { 25 *ret_pstate = (ParserState) { 26 .reader = { 27 .get_line = get_line, 28 .cookie = cookie, 29 .conv = MBYTE_NONE_CONV, 30 }, 31 .pos = { 0, 0 }, 32 .colors = colors, 33 .can_continuate = false, 34 }; 35 kvi_init(ret_pstate->reader.lines); 36 kvi_init(ret_pstate->stack); 37 } 38 39 /// Advance position by a given number of bytes 40 /// 41 /// At maximum advances to the next line. 42 /// 43 /// @param pstate Parser state to advance. 44 /// @param[in] len Number of bytes to advance. 45 static inline void viml_parser_advance(ParserState *const pstate, const size_t len) 46 FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL 47 { 48 assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1); 49 const ParserLine pline = kv_last(pstate->reader.lines); 50 if (pstate->pos.col + len >= pline.size) { 51 pstate->pos.line++; 52 pstate->pos.col = 0; 53 } else { 54 pstate->pos.col += len; 55 } 56 } 57 58 /// Record highlighting of some region of text 59 /// 60 /// @param pstate Parser state to work with. 61 /// @param[in] start Start position of the highlight. 62 /// @param[in] len Highlighting chunk length. 63 /// @param[in] group Highlight group. 64 static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start, 65 const size_t len, const char *const group) 66 FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL 67 { 68 if (pstate->colors == NULL || len == 0) { 69 return; 70 } 71 assert(kv_size(*pstate->colors) == 0 72 || kv_Z(*pstate->colors, 0).start.line < start.line 73 || kv_Z(*pstate->colors, 0).end_col <= start.col); 74 kvi_push(*pstate->colors, ((ParserHighlightChunk) { 75 .start = start, 76 .end_col = start.col + len, 77 .group = group, 78 })); 79 }