hs-tree-sitter-capi (empty) → 13.0.14.0
raw patch · 49 files changed
+24489/−0 lines, 49 filesdep +basedep +base-compat-constptrdep +hs-tree-sitter-capi
Dependencies added: base, base-compat-constptr, hs-tree-sitter-capi, tasty, tasty-hunit, tree-sitter-while
Files
- README.md +12/−0
- hs-tree-sitter-capi.cabal +113/−0
- src/TreeSitter/CApi.hsc +4132/−0
- test/Main.hs +11/−0
- test/Test/TreeSitter/CApi.hs +77/−0
- vendor/tree-sitter/lib/include/tree_sitter/api.h +1317/−0
- vendor/tree-sitter/lib/src/alloc.c +48/−0
- vendor/tree-sitter/lib/src/alloc.h +41/−0
- vendor/tree-sitter/lib/src/array.h +290/−0
- vendor/tree-sitter/lib/src/atomic.h +68/−0
- vendor/tree-sitter/lib/src/clock.h +146/−0
- vendor/tree-sitter/lib/src/error_costs.h +11/−0
- vendor/tree-sitter/lib/src/get_changed_ranges.c +501/−0
- vendor/tree-sitter/lib/src/get_changed_ranges.h +36/−0
- vendor/tree-sitter/lib/src/host.h +21/−0
- vendor/tree-sitter/lib/src/language.c +223/−0
- vendor/tree-sitter/lib/src/language.h +297/−0
- vendor/tree-sitter/lib/src/length.h +52/−0
- vendor/tree-sitter/lib/src/lexer.c +432/−0
- vendor/tree-sitter/lib/src/lexer.h +49/−0
- vendor/tree-sitter/lib/src/lib.c +14/−0
- vendor/tree-sitter/lib/src/node.c +920/−0
- vendor/tree-sitter/lib/src/parser.c +2167/−0
- vendor/tree-sitter/lib/src/parser.h +266/−0
- vendor/tree-sitter/lib/src/point.h +62/−0
- vendor/tree-sitter/lib/src/query.c +4187/−0
- vendor/tree-sitter/lib/src/reduce_action.h +34/−0
- vendor/tree-sitter/lib/src/reusable_node.h +95/−0
- vendor/tree-sitter/lib/src/stack.c +899/−0
- vendor/tree-sitter/lib/src/stack.h +130/−0
- vendor/tree-sitter/lib/src/subtree.c +1065/−0
- vendor/tree-sitter/lib/src/subtree.h +382/−0
- vendor/tree-sitter/lib/src/tree.c +172/−0
- vendor/tree-sitter/lib/src/tree.h +31/−0
- vendor/tree-sitter/lib/src/tree_cursor.c +715/−0
- vendor/tree-sitter/lib/src/tree_cursor.h +48/−0
- vendor/tree-sitter/lib/src/ts_assert.h +11/−0
- vendor/tree-sitter/lib/src/unicode.h +50/−0
- vendor/tree-sitter/lib/src/unicode/ptypes.h +1/−0
- vendor/tree-sitter/lib/src/unicode/umachine.h +448/−0
- vendor/tree-sitter/lib/src/unicode/urename.h +1/−0
- vendor/tree-sitter/lib/src/unicode/utf.h +1/−0
- vendor/tree-sitter/lib/src/unicode/utf16.h +733/−0
- vendor/tree-sitter/lib/src/unicode/utf8.h +881/−0
- vendor/tree-sitter/lib/src/wasm/stdlib.c +109/−0
- vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1302/−0
- vendor/tree-sitter/lib/src/wasm_store.c +1847/−0
- vendor/tree-sitter/lib/src/wasm_store.h +31/−0
- vendor/tree-sitter/lib/tree-sitter.pc.in +10/−0
+ README.md view
@@ -0,0 +1,12 @@+# Low-level bindings for tree-sitter++This package implements low-level bindings for [tree-sitter](https://tree-sitter.github.io/tree-sitter/),+a widely-supported parser generator tool and an incremental parsing library.++> ⚠️ WARNING:+> You probably don't want to use this package directly, but instead use the high-level bindings implemented by [hs-tree-sitter](https://hackage.haskell.org/package/hs-tree-sitter).++This package is compiled against [tree-sitter](https://github.com/tree-sitter/tree-sitter) version [0.24.3](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.24.3) (2024-10-09).+It is feature complete for version 14 of the tree-sitter ABI and is backwards compatible down to version 13.++All tree-sitter versions up to version [0.25.8](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.25.8) (2025-07-13) are backwards compatible down to version 13, so this package should work with all grammars generated by any version of tree-sitter after [0.19.0](https://github.com/tree-sitter/tree-sitter/releases/tag/v0.19.0) (2021-03-01), though this is untested.
+ hs-tree-sitter-capi.cabal view
@@ -0,0 +1,113 @@+cabal-version: 3.4+name: hs-tree-sitter-capi+version: 13.0.14.0+license: AGPL-3.0-only+synopsis: Low-level bindings for tree-sitter+description: Low-level bindings for tree-sitter.+author: Wen Kokke+maintainer: wenkokke@users.noreply.github.com+category: Language+build-type: Simple+extra-doc-files: README.md+extra-source-files:+ vendor/tree-sitter/lib/include/tree_sitter/api.h+ vendor/tree-sitter/lib/src/alloc.c+ vendor/tree-sitter/lib/src/alloc.h+ vendor/tree-sitter/lib/src/array.h+ vendor/tree-sitter/lib/src/atomic.h+ vendor/tree-sitter/lib/src/clock.h+ vendor/tree-sitter/lib/src/error_costs.h+ vendor/tree-sitter/lib/src/get_changed_ranges.c+ vendor/tree-sitter/lib/src/get_changed_ranges.h+ vendor/tree-sitter/lib/src/host.h+ vendor/tree-sitter/lib/src/language.c+ vendor/tree-sitter/lib/src/language.h+ vendor/tree-sitter/lib/src/length.h+ vendor/tree-sitter/lib/src/lexer.c+ vendor/tree-sitter/lib/src/lexer.h+ vendor/tree-sitter/lib/src/lib.c+ vendor/tree-sitter/lib/src/node.c+ vendor/tree-sitter/lib/src/parser.c+ vendor/tree-sitter/lib/src/parser.h+ vendor/tree-sitter/lib/src/point.h+ vendor/tree-sitter/lib/src/query.c+ vendor/tree-sitter/lib/src/reduce_action.h+ vendor/tree-sitter/lib/src/reusable_node.h+ vendor/tree-sitter/lib/src/stack.c+ vendor/tree-sitter/lib/src/stack.h+ vendor/tree-sitter/lib/src/subtree.c+ vendor/tree-sitter/lib/src/subtree.h+ vendor/tree-sitter/lib/src/tree.c+ vendor/tree-sitter/lib/src/tree.h+ vendor/tree-sitter/lib/src/tree_cursor.c+ vendor/tree-sitter/lib/src/tree_cursor.h+ vendor/tree-sitter/lib/src/ts_assert.h+ vendor/tree-sitter/lib/src/unicode/ptypes.h+ vendor/tree-sitter/lib/src/unicode/umachine.h+ vendor/tree-sitter/lib/src/unicode/urename.h+ vendor/tree-sitter/lib/src/unicode/utf.h+ vendor/tree-sitter/lib/src/unicode/utf16.h+ vendor/tree-sitter/lib/src/unicode/utf8.h+ vendor/tree-sitter/lib/src/unicode.h+ vendor/tree-sitter/lib/src/wasm/stdlib.c+ vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h+ vendor/tree-sitter/lib/src/wasm_store.c+ vendor/tree-sitter/lib/src/wasm_store.h+ vendor/tree-sitter/lib/tree-sitter.pc.in++tested-with:+ GHC ==8.10.7+ || ==9.0.2+ || ==9.2.8+ || ==9.4.8+ || ==9.6.7+ || ==9.8.4+ || ==9.10.2+ || ==9.12.2++common language+ ghc-options:+ -Wall -Wcompat -Widentities -Wprepositive-qualified-module+ -Wredundant-constraints -Wunticked-promoted-constructors+ -Wunused-packages++ default-language: Haskell2010+ default-extensions: ImportQualifiedPost++ if impl(ghc <9.6.1)+ ghc-options:+ -optc=-Wno-discarded-qualifiers+ -optc=-Wno-incompatible-pointer-types-discards-qualifiers++library+ import: language+ exposed-modules: TreeSitter.CApi+ build-tool-depends: hsc2hs:hsc2hs+ hs-source-dirs: src+ include-dirs:+ vendor/tree-sitter/lib/include vendor/tree-sitter/lib/src++ includes: tree_sitter/api.h+ c-sources: vendor/tree-sitter/lib/src/lib.c+ build-depends:+ , base >=4.13 && <5+ , base-compat-constptr >=0.1 && <0.2++ -- Does not compile on macOS/arm64 with GHC <9.6.5+ -- See: https://gitlab.haskell.org/ghc/ghc/-/issues/23456+ if (impl(ghc <9.6.5) && arch(aarch64))+ build-depends: base >=4.18.2.1++test-suite hs-tree-sitter-capi-test+ import: language+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Main.hs+ other-modules: Test.TreeSitter.CApi+ build-depends:+ , base+ , base-compat-constptr+ , hs-tree-sitter-capi+ , tasty >=1.5 && <1.6+ , tasty-hunit >=0.10 && <0.11+ , tree-sitter-while
+ src/TreeSitter/CApi.hsc view
@@ -0,0 +1,4132 @@+{-# LANGUAGE CApiFFI #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE StandaloneKindSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeApplications #-}++module TreeSitter.CApi+ ( -- * ABI Versioning+ TREE_SITTER_LANGUAGE_VERSION+ , TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION++ -- * Types+ , TSStateId (..)+ , TSSymbol (..)+ , TSFieldId (..)+ , TSLanguage+ , TSParser+ , TSTree+ , TSQuery+ , TSQueryCursor+ , TSLookaheadIterator+ , TSInputEncoding (TSInputEncodingUTF8, TSInputEncodingUTF16, ..)+ , TSSymbolType (TSSymbolTypeRegular, TSSymbolTypeAnonymous, TSSymbolTypeSupertype, TSSymbolTypeAuxiliary, ..)+ , TSPoint (..)+ , TSRange (..)+ , TSInput+ , TSRead+ , TSLogType (TSLogTypeParse, TSLogTypeLex, ..)+ , TSLogger+ , TSLog+ , TSInputEdit (..)+ , TSNode (..)+ , TSNodeContext (..)+ , TSTreeCursor (..)+ , TSTreeCursorContext (..)+ , TSQueryCapture (..)+ , TSQuantifier (TSQuantifierZero, TSQuantifierZeroOrOne, TSQuantifierZeroOrMore, TSQuantifierOne, TSQuantifierOneOrMore, ..)+ , TSQueryMatch (..)+ , TSQueryPredicateStepType (TSQueryPredicateStepTypeDone, TSQueryPredicateStepTypeCapture, TSQueryPredicateStepTypeString, ..)+ , TSQueryPredicateStep (..)+ , TSQueryError (TSQueryErrorNone, TSQueryErrorSyntax, TSQueryErrorNodeType, TSQueryErrorField, TSQueryErrorCapture, TSQueryErrorStructure, TSQueryErrorLanguage, ..)++ -- * Parser+ , ts_parser_new+ , ts_parser_delete+ , p_ts_parser_delete+ , ts_parser_language+ , ts_parser_set_language+ , ts_parser_set_included_ranges+ , ts_parser_included_ranges+ , ts_parser_set_logger+ , ts_parser_logger+ , ts_parser_remove_logger+ , ts_parser_parse+ , ts_parser_parse_string+ , ts_parser_parse_string_encoding+ , ts_parser_reset+ , ts_parser_set_timeout_micros+ , ts_parser_timeout_micros+ , ts_parser_set_cancellation_flag+ , ts_parser_cancellation_flag+ , ts_parser_print_dot_graphs++ -- * Tree+ , ts_tree_copy+ , ts_tree_delete+ , p_ts_tree_delete+ , ts_tree_language+ , ts_tree_included_ranges+ , ts_tree_edit+ , ts_tree_get_changed_ranges+ , ts_tree_print_dot_graph+ , ts_tree_root_node+ , ts_tree_root_node_with_offset++ -- * Node+ , ts_node_type+ , ts_node_symbol+ , ts_node_language+ , ts_node_grammar_type+ , ts_node_grammar_symbol+ , ts_node_start_byte+ , ts_node_start_point+ , ts_node_end_byte+ , ts_node_end_point+ , ts_node_string+ , ts_node_is_null+ , ts_node_is_named+ , ts_node_is_missing+ , ts_node_is_extra+ , ts_node_has_changes+ , ts_node_has_error+ , ts_node_is_error+ , ts_node_parse_state+ , ts_node_next_parse_state+ , ts_node_parent+ , ts_node_child_with_descendant+ , ts_node_child+ , ts_node_field_name_for_child+ , ts_node_field_name_for_named_child+ , ts_node_child_count+ , ts_node_named_child+ , ts_node_named_child_count+ , ts_node_child_by_field_name+ , ts_node_child_by_field_id+ , ts_node_next_sibling+ , ts_node_prev_sibling+ , ts_node_next_named_sibling+ , ts_node_prev_named_sibling+ , ts_node_first_child_for_byte+ , ts_node_first_named_child_for_byte+ , ts_node_descendant_count+ , ts_node_descendant_for_byte_range+ , ts_node_descendant_for_point_range+ , ts_node_named_descendant_for_byte_range+ , ts_node_named_descendant_for_point_range+ , ts_node_edit+ , ts_node_eq++ -- * TreeCursor+ , ts_tree_cursor_new+ , ts_tree_cursor_new_p+ , ts_tree_cursor_delete+ , p_ts_tree_cursor_delete+ , ts_tree_cursor_reset+ , ts_tree_cursor_reset_to+ , ts_tree_cursor_current_node+ , ts_tree_cursor_current_field_name+ , ts_tree_cursor_current_field_id+ , ts_tree_cursor_goto_parent+ , ts_tree_cursor_goto_next_sibling+ , ts_tree_cursor_goto_previous_sibling+ , ts_tree_cursor_goto_first_child+ , ts_tree_cursor_goto_last_child+ , ts_tree_cursor_goto_descendant+ , ts_tree_cursor_current_descendant_index+ , ts_tree_cursor_current_depth+ , ts_tree_cursor_goto_first_child_for_byte+ , ts_tree_cursor_goto_first_child_for_point+ , ts_tree_cursor_copy+ , ts_tree_cursor_copy_p++ -- * Query+ , ts_query_new+ , ts_query_delete+ , p_ts_query_delete+ , ts_query_pattern_count+ , ts_query_capture_count+ , ts_query_string_count+ , ts_query_start_byte_for_pattern+ , ts_query_end_byte_for_pattern+ , ts_query_predicates_for_pattern+ , ts_query_is_pattern_rooted+ , ts_query_is_pattern_non_local+ , ts_query_is_pattern_guaranteed_at_step+ , ts_query_capture_name_for_id+ , ts_query_capture_quantifier_for_id+ , ts_query_string_value_for_id+ , ts_query_disable_capture+ , ts_query_disable_pattern+ , ts_query_cursor_new+ , ts_query_cursor_delete+ , p_ts_query_cursor_delete+ , ts_query_cursor_exec+ , ts_query_cursor_did_exceed_match_limit+ , ts_query_cursor_match_limit+ , ts_query_cursor_set_match_limit+ , ts_query_cursor_set_timeout_micros+ , ts_query_cursor_timeout_micros+ , ts_query_cursor_set_byte_range+ , ts_query_cursor_set_point_range+ , ts_query_cursor_next_match+ , ts_query_cursor_remove_match+ , ts_query_cursor_next_capture+ , ts_query_cursor_set_max_start_depth++ -- * Language+ , ts_language_copy+ , ts_language_delete+ , p_ts_language_delete+ , ts_language_symbol_count+ , ts_language_state_count+ , ts_language_symbol_name+ , ts_language_symbol_for_name+ , ts_language_field_count+ , ts_language_field_name_for_id+ , ts_language_field_id_for_name+ , ts_language_symbol_type+ , ts_language_version+ , ts_language_next_state++ -- * Lookahead Iterator+ , ts_lookahead_iterator_new+ , ts_lookahead_iterator_delete+ , p_ts_lookahead_iterator_delete+ , ts_lookahead_iterator_reset_state+ , ts_lookahead_iterator_reset+ , ts_lookahead_iterator_language+ , ts_lookahead_iterator_next+ , ts_lookahead_iterator_current_symbol+ , ts_lookahead_iterator_current_symbol_name++#ifdef TREE_SITTER_FEATURE_WASM+ -- * WebAssembly Integration+ , TSWasmEngine+ , TSWasmStore+ , TSWasmErrorKind (TSWasmErrorKindNone, TSWasmErrorKindParse, TSWasmErrorKindCompile, TSWasmErrorKindInstantiate, TSWasmErrorKindAllocate)+ , TSWasmError+ , peekTSWasmError+ , withTSWasmError+ , ts_wasm_store_new+ , ts_wasm_store_delete+ , p_ts_wasm_store_delete+ , ts_wasm_store_load_language+ , ts_wasm_store_language_count+ , ts_language_is_wasm+ , ts_parser_set_wasm_store+ , ts_parser_take_wasm_store+#endif++ -- * Global Configuration+ , ts_set_allocator+ ) where++import Control.Exception (bracket, mask_)+#ifdef TREE_SITTER_FEATURE_WASM+import Data.ByteString (ByteString)+import Data.ByteString qualified as BS (packCString, useAsCString)+#endif+import Data.Void (Void)+import Data.Word+import Foreign+import Foreign.C+import Foreign.C.ConstPtr.Compat (ConstPtr(..))+import GHC.TypeLits (Nat)++#include <tree_sitter/api.h>+-- string.h: required for memcpy+#include <string.h>++{----------------------------}+{- Section - ABI Versioning -}+{----------------------------}++{-|+ The latest ABI version that is supported by the current version of the+ library. When Languages are generated by the Tree-sitter CLI, they are+ assigned an ABI version number that corresponds to the current CLI version.+ The Tree-sitter library is generally backwards-compatible with languages+ generated using older CLI versions, but is not forwards-compatible.++ > #define TREE_SITTER_LANGUAGE_VERSION 14+-}+type TREE_SITTER_LANGUAGE_VERSION :: Nat+type TREE_SITTER_LANGUAGE_VERSION = #const TREE_SITTER_LANGUAGE_VERSION++{-|+ The earliest ABI version that is supported by the current version of the+ library.++ > #define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13+-}+type TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION :: Nat+type TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION = #const TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION++{-------------------}+{- Section - Types -}+{-------------------}++{-|+ > typedef uint16_t TSStateId;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSStateId" #-}+ TSStateId = TSStateId #{type TSStateId}+ deriving stock (Show, Read, Eq, Ord)+ deriving newtype (Num, Real, Integral, Enum)++{-|+ > typedef uint16_t TSSymbol;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSSymbol" #-}+ TSSymbol = TSSymbol #{type TSSymbol}+ deriving stock (Show, Read, Eq, Ord)+ deriving newtype (Num, Real, Integral, Enum)++{-|+ > typedef uint16_t TSFieldId;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSFieldId" #-}+ TSFieldId = TSFieldId #{type TSFieldId}+ deriving stock (Show, Read, Eq, Ord)+ deriving newtype (Num, Real, Integral, Enum)++{-|+ > typedef struct TSLanguage TSLanguage;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSLanguage" #-}+ TSLanguage++{-|+ > typedef struct TSParser TSParser;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSParser" #-}+ TSParser++{-|+ > typedef struct TSTree TSTree;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSTree" #-}+ TSTree++{-|+ > typedef struct TSQuery TSQuery;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSQuery" #-}+ TSQuery++{-|+ > typedef struct TSQueryCursor TSQueryCursor;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSQueryCursor" #-}+ TSQueryCursor++{-|+ > typedef struct TSLookaheadIterator TSLookaheadIterator;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSLookaheadIterator" #-}+ TSLookaheadIterator++{-|+ > typedef enum TSInputEncoding {+ > TSInputEncodingUTF8,+ > TSInputEncodingUTF16,+ > } TSInputEncoding;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSInputEncoding" #-}+ TSInputEncoding = TSInputEncoding+ { unTSInputEncoding :: #{type TSInputEncoding}+ }+ deriving (Eq, Show)+ deriving newtype (Storable)++pattern TSInputEncodingUTF8 :: TSInputEncoding+pattern TSInputEncodingUTF8 = TSInputEncoding ( #{const TSInputEncodingUTF8} )++pattern TSInputEncodingUTF16 :: TSInputEncoding+pattern TSInputEncodingUTF16 = TSInputEncoding ( #{const TSInputEncodingUTF16} )++{-# COMPLETE TSInputEncodingUTF8, TSInputEncodingUTF16 #-}++{-|+ > typedef enum TSSymbolType {+ > TSSymbolTypeRegular,+ > TSSymbolTypeAnonymous,+ > TSSymbolTypeSupertype,+ > TSSymbolTypeAuxiliary,+ > } TSSymbolType;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSSymbolType" #-}+ TSSymbolType = TSSymbolType+ { unTSSymbolType :: #{type TSSymbolType}+ }+ deriving (Eq, Show)++pattern TSSymbolTypeRegular :: TSSymbolType+pattern TSSymbolTypeRegular = TSSymbolType ( #{const TSSymbolTypeRegular} )++pattern TSSymbolTypeAnonymous :: TSSymbolType+pattern TSSymbolTypeAnonymous = TSSymbolType ( #{const TSSymbolTypeAnonymous} )++pattern TSSymbolTypeSupertype :: TSSymbolType+pattern TSSymbolTypeSupertype = TSSymbolType ( #{const TSSymbolTypeSupertype} )++pattern TSSymbolTypeAuxiliary :: TSSymbolType+pattern TSSymbolTypeAuxiliary = TSSymbolType ( #{const TSSymbolTypeAuxiliary} )++{-# COMPLETE TSSymbolTypeRegular, TSSymbolTypeAnonymous, TSSymbolTypeSupertype, TSSymbolTypeAuxiliary #-}++{-|+ > typedef struct TSPoint {+ > uint32_t row;+ > uint32_t column;+ > } TSPoint;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSPoint" #-}+ TSPoint = TSPoint+ { row :: {-# UNPACK #-} !( #{type uint32_t} )+ , column :: {-# UNPACK #-} !( #{type uint32_t} )+ }+ deriving (Ord, Eq, Show)++instance Storable TSPoint where+ alignment _ = #{alignment TSPoint}+ sizeOf _ = #{size TSPoint}+ peek ptr = do+ row <- #{peek TSPoint, row} ptr+ column <- #{peek TSPoint, column} ptr+ return TSPoint{..}+ poke ptr TSPoint{..} = do+ #{poke TSPoint, row} ptr row+ #{poke TSPoint, column} ptr column++{-|+ > typedef struct TSRange {+ > TSPoint start_point;+ > TSPoint end_point;+ > uint32_t start_byte;+ > uint32_t end_byte;+ > } TSRange;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSRange" #-}+ TSRange = TSRange+ { start_point :: {-# UNPACK #-} !TSPoint+ , end_point :: {-# UNPACK #-} !TSPoint+ , start_byte :: {-# UNPACK #-} !( #{type uint32_t} )+ , end_byte :: {-# UNPACK #-} !( #{type uint32_t} )+ }+ deriving (Eq, Show)++instance Storable TSRange where+ alignment _ = #{alignment TSRange}+ sizeOf _ = #{size TSRange}+ peek ptr = do+ start_point <- #{peek TSRange, start_point} ptr+ end_point <- #{peek TSRange, end_point} ptr+ start_byte <- #{peek TSRange, start_byte} ptr+ end_byte <- #{peek TSRange, end_byte} ptr+ return TSRange{..}+ poke ptr TSRange{..} = do+ #{poke TSRange, start_point} ptr start_point+ #{poke TSRange, end_point} ptr end_point+ #{poke TSRange, start_byte} ptr start_byte+ #{poke TSRange, end_byte} ptr end_byte++{-|+ > typedef struct TSInput {+ > void *payload;+ > const char *(*read)(+ > void *payload,+ > uint32_t byte_index,+ > TSPoint position,+ > uint32_t *bytes_read+ > );+ > TSInputEncoding encoding;+ > } TSInput;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSInput" #-}+ TSInput++{-| The type of the @`read`@ argument of the @`_wrap_ts_input_new`@ function.++ > typedef const char *(*TSRead)(+ > uint32_t byte_index,+ > TSPoint *position,+ > uint32_t *bytes_read+ > );+ -}+type TSRead =+ ( #{type uint32_t} ) ->+ Ptr TSPoint ->+ Ptr ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)++-- | Convert a Haskell 'TSRead' closure to a C 'TSRead' function pointer.+foreign import ccall "wrapper"+ mkTSReadFunPtr :: TSRead -> IO (FunPtr TSRead)++#{def+ typedef const char *(*TSRead)(+ uint32_t byte_index,+ TSPoint *position,+ uint32_t *bytes_read+ );+}++-- | Create a @`TSInput`@.+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_input_new"+ _wrap_ts_input_new ::+ FunPtr TSRead ->+ TSInputEncoding ->+ IO (Ptr TSInput)++#{def+ const char *_wrap_ts_input_read(+ void *payload,+ uint32_t byte_index,+ TSPoint position,+ uint32_t *bytes_read+ ) {+ TSRead read;+ memcpy(&read, payload, sizeof read);+ TSPoint *position_p = &position;+ return read(byte_index, position_p, bytes_read);+ }+}++#{def+ TSInput *_wrap_ts_input_new(+ TSRead read,+ TSInputEncoding encoding+ ) {+ TSInput *input = malloc(sizeof *input);+ input->payload = malloc(sizeof read);+ memcpy(input->payload, &read, sizeof read);+ input->read = _wrap_ts_input_read;+ input->encoding = encoding;+ return input;+ }+}++-- | Delete a @`TSInput`@.+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_input_delete"+ _wrap_ts_input_delete ::+ Ptr TSInput ->+ IO ()++#{def+ void _wrap_ts_input_delete(+ TSInput *input+ ) {+ free(input->payload);+ free(input);+ }+}++{-|+ > typedef enum TSLogType {+ > TSLogTypeParse,+ > TSLogTypeLex,+ > } TSLogType;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSLogType" #-}+ TSLogType = TSLogType+ { unTSLogType :: #{type TSLogType}+ }+ deriving (Eq, Show)++pattern TSLogTypeParse :: TSLogType+pattern TSLogTypeParse = TSLogType ( #{const TSLogTypeParse} )++pattern TSLogTypeLex :: TSLogType+pattern TSLogTypeLex = TSLogType ( #{const TSLogTypeLex} )++{-# COMPLETE TSLogTypeParse, TSLogTypeLex #-}++{-|+ > typedef struct TSLogger {+ > void *payload;+ > void (*log)(void *payload, TSLogType log_type, const char *buffer);+ > } TSLogger;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSLogger" #-}+ TSLogger++#{def+typedef void (*TSLog)(+ TSLogType log_type,+ const char *buffer+);+}++{-| The type of the @`log`@ argument of the @`_wrap_ts_logger_new`@ function.++ > void (*log)(TSLogType log_type, const char *buffer);+ -}+type TSLog =+ TSLogType ->+ ConstPtr CChar ->+ IO ()++{-|+ > TSLogger *_wrap_ts_logger_new(TSLog log);+ -}+foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_logger_new"+ _wrap_ts_logger_new ::+ FunPtr TSLog ->+ IO (Ptr TSLogger)++#{def+ void _wrap_ts_logger_log(+ void *payload,+ TSLogType log_type,+ const char *buffer+ ) {+ TSLog log;+ memcpy(&log, payload, sizeof log);+ log(log_type, buffer);+ }+}++#{def+ TSLogger *_wrap_ts_logger_new(TSLog log) {+ TSLogger *logger = malloc(sizeof *logger);+ logger->payload = malloc(sizeof log);+ memcpy(logger->payload, &log, sizeof log);+ logger->log = _wrap_ts_logger_log;+ return logger;+ }+}++{-| Allocate a C function pointer for a `TSLog` function.+ -}+foreign import ccall "wrapper"+ mkTSLogFunPtr :: TSLog -> IO (FunPtr TSLog)++{-| Convert a C function pointer for a `TSLog` function+ to the corresponding Haskell function.+ -}+foreign import ccall "dynamic"+ unTSLogFunPtr :: FunPtr TSLog -> TSLog++{-|+ > typedef struct TSInputEdit {+ > uint32_t start_byte;+ > uint32_t old_end_byte;+ > uint32_t new_end_byte;+ > TSPoint start_point;+ > TSPoint old_end_point;+ > TSPoint new_end_point;+ > } TSInputEdit;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSInputEdit" #-}+ TSInputEdit = TSInputEdit+ { start_byte :: {-# UNPACK #-} !( #{type uint32_t} )+ , old_end_byte :: {-# UNPACK #-} !( #{type uint32_t} )+ , new_end_byte :: {-# UNPACK #-} !( #{type uint32_t} )+ , start_point :: {-# UNPACK #-} !TSPoint+ , old_end_point :: {-# UNPACK #-} !TSPoint+ , new_end_point :: {-# UNPACK #-} !TSPoint+ }+ deriving (Eq, Show)++instance Storable TSInputEdit where+ alignment _ = #{alignment TSInputEdit}+ sizeOf _ = #{size TSInputEdit}+ peek ptr = do+ start_byte <- #{peek TSInputEdit, start_byte} ptr+ old_end_byte <- #{peek TSInputEdit, old_end_byte} ptr+ new_end_byte <- #{peek TSInputEdit, new_end_byte} ptr+ start_point <- #{peek TSInputEdit, start_point} ptr+ old_end_point <- #{peek TSInputEdit, old_end_point} ptr+ new_end_point <- #{peek TSInputEdit, new_end_point} ptr+ return TSInputEdit{..}+ poke ptr TSInputEdit{..} = do+ #{poke TSInputEdit, start_byte} ptr start_byte+ #{poke TSInputEdit, old_end_byte} ptr old_end_byte+ #{poke TSInputEdit, new_end_byte} ptr new_end_byte+ #{poke TSInputEdit, start_point} ptr start_point+ #{poke TSInputEdit, old_end_point} ptr old_end_point+ #{poke TSInputEdit, new_end_point} ptr new_end_point++{-|+ > typedef struct TSNode {+ > uint32_t context[4];+ > const void *id;+ > const TSTree *tree;+ > } TSNode;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSNode" #-}+ TSNode = TSNode+ { _context :: {-# UNPACK #-} !TSNodeContext+ , _id :: {-# UNPACK #-} !(ConstPtr Void)+ , _tree :: {-# UNPACK #-} !(ConstPtr TSTree)+ }++instance Storable TSNode where+ alignment _ = #{alignment TSNode}+ sizeOf _ = #{size TSNode}+ peek ptr = do+ _context <- peekTSNodeContext ( #{ptr TSNode, context} ptr )+ _id <- ConstPtr <$> #{peek TSNode, id} ptr+ _tree <- ConstPtr <$> #{peek TSNode, tree} ptr+ return TSNode{..}+ poke ptr TSNode{..} = do+ pokeTSNodeContext ( #{ptr TSNode, context} ptr ) _context+ #{poke TSNode, id} ptr (unConstPtr _id)+ #{poke TSNode, tree} ptr (unConstPtr _tree)++{-| The type of the @`_context`@ field of a @`TSNode`@ struct.++ > uint32_t context[4];+ -}+data+ TSNodeContext = TSNodeContext+ {-# UNPACK #-} !( #{type uint32_t} )+ {-# UNPACK #-} !( #{type uint32_t} )+ {-# UNPACK #-} !( #{type uint32_t} )+ {-# UNPACK #-} !( #{type uint32_t} )++{-| Peek a @`TSNodeContext`@.++ This does the same as `peek` would, except that @`TSNodeContext`@ is not an instance of `Storable`.+ -}+peekTSNodeContext :: Ptr ( #{type uint32_t} ) -> IO TSNodeContext+peekTSNodeContext ptr = do+ [x0, x1, x2, x3] <- peekArray 4 ptr+ return $ TSNodeContext x0 x1 x2 x3++{-| Poke a @`TSNodeContext`@.++ This does the same as `poke` would, except that @`TSNodeContext`@ is not an instance of `Storable`.+ -}+pokeTSNodeContext :: Ptr ( #{type uint32_t} ) -> TSNodeContext -> IO ()+pokeTSNodeContext ptr (TSNodeContext x0 x1 x2 x3) = do+ pokeArray ptr [x0, x1, x2, x3]++{-|+ > typedef struct TSTreeCursor {+ > const void *tree;+ > const void *id;+ > uint32_t context[3];+ > } TSTreeCursor;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSTreeCursor" #-}+ TSTreeCursor = TSTreeCursor+ { _tree :: {-# UNPACK #-} !(ConstPtr Void)+ , _id :: {-# UNPACK #-} !(ConstPtr Void)+ , _context :: {-# UNPACK #-} !TSTreeCursorContext+ }++instance Storable TSTreeCursor where+ alignment _ = #{alignment TSTreeCursor}+ sizeOf _ = #{size TSTreeCursor}+ peek ptr = do+ _tree <- ConstPtr <$> #{peek TSTreeCursor, tree} ptr+ _id <- ConstPtr <$> #{peek TSTreeCursor, id} ptr+ _context <- peekTSTreeCursorContext ( #{ptr TSTreeCursor, context} ptr )+ return TSTreeCursor{..}+ poke ptr TSTreeCursor{..} = do+ #{poke TSTreeCursor, tree} ptr (unConstPtr _tree)+ #{poke TSTreeCursor, id} ptr (unConstPtr _id)+ pokeTSTreeCursorContext ( #{ptr TSTreeCursor, context} ptr ) _context++{-| The type of the @`_context`@ field of a @`TSTreeCursor`@ struct.++ > uint32_t context[3];+ -}+data+ TSTreeCursorContext = TSTreeCursorContext+ {-# UNPACK #-} !( #{type uint32_t} )+ {-# UNPACK #-} !( #{type uint32_t} )+ {-# UNPACK #-} !( #{type uint32_t} )++{-| Peek a @`TSTreeCursorContext`@.++ This does the same as `peek` would, except that @`TSTreeCursorContext`@ is not an instance of `Storable`.+ -}+peekTSTreeCursorContext :: Ptr ( #{type uint32_t} ) -> IO TSTreeCursorContext+peekTSTreeCursorContext ptr = do+ [x0, x1, x2] <- peekArray 3 ptr+ return $ TSTreeCursorContext x0 x1 x2++{-| Poke a @`TSTreeCursorContext`@.++ This does the same as `poke` would, except that @`TSTreeCursorContext`@ is not an instance of `Storable`.+ -}+pokeTSTreeCursorContext :: Ptr ( #{type uint32_t} ) -> TSTreeCursorContext -> IO ()+pokeTSTreeCursorContext ptr (TSTreeCursorContext x0 x1 x2) = do+ pokeArray ptr [x0, x1, x2]++{-|+ > typedef struct TSQueryCapture {+ > TSNode node;+ > uint32_t index;+ > } TSQueryCapture;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSQueryCapture" #-}+ TSQueryCapture = TSQueryCapture+ { _node :: {-# UNPACK #-} !TSNode+ , _index :: {-# UNPACK #-} !( #{type uint32_t} )+ }++instance Storable TSQueryCapture where+ alignment _ = #{alignment TSQueryCapture}+ sizeOf _ = #{size TSQueryCapture}+ peek ptr = do+ _node <- #{peek TSQueryCapture, node} ptr+ _index <- #{peek TSQueryCapture, index} ptr+ return TSQueryCapture{..}+ poke ptr TSQueryCapture{..} = do+ #{poke TSQueryCapture, node} ptr _node+ #{poke TSQueryCapture, index} ptr _index++{-|+ > typedef enum TSQuantifier {+ > TSQuantifierZero = 0, // must match the array initialization value+ > TSQuantifierZeroOrOne,+ > TSQuantifierZeroOrMore,+ > TSQuantifierOne,+ > TSQuantifierOneOrMore,+ > } TSQuantifier;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSQuantifier" #-}+ TSQuantifier = TSQuantifier+ { unTSQuantifier :: #{type TSQuantifier}+ }+ deriving (Eq, Show)+ deriving newtype (Storable)++pattern TSQuantifierZero :: TSQuantifier+pattern TSQuantifierZero = TSQuantifier ( #{const TSQuantifierZero} )++pattern TSQuantifierZeroOrOne :: TSQuantifier+pattern TSQuantifierZeroOrOne = TSQuantifier ( #{const TSQuantifierZeroOrOne} )++pattern TSQuantifierZeroOrMore :: TSQuantifier+pattern TSQuantifierZeroOrMore = TSQuantifier ( #{const TSQuantifierZeroOrMore} )++pattern TSQuantifierOne :: TSQuantifier+pattern TSQuantifierOne = TSQuantifier ( #{const TSQuantifierOne} )++pattern TSQuantifierOneOrMore :: TSQuantifier+pattern TSQuantifierOneOrMore = TSQuantifier ( #{const TSQuantifierOneOrMore} )++{-# COMPLETE TSQuantifierZero, TSQuantifierZeroOrOne, TSQuantifierZeroOrMore, TSQuantifierOne, TSQuantifierOneOrMore #-}++{-|+ > typedef struct TSQueryMatch {+ > uint32_t id;+ > uint16_t pattern_index;+ > uint16_t capture_count;+ > const TSQueryCapture *captures;+ > } TSQueryMatch;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSQueryMatch" #-}+ TSQueryMatch = TSQueryMatch+ { _id :: {-# UNPACK #-} !( #{type uint32_t} )+ , _pattern_index :: {-# UNPACK #-} !( #{type uint16_t} )+ -- , _capture_count :: {-# UNPACK #-} !( #{type uint16_t} )+ -- , _captures :: {-# UNPACK #-} !(Ptr TSQueryCapture)+ , _captures :: ![TSQueryCapture]+ }++instance Storable TSQueryMatch where+ alignment _ = #{alignment TSQueryMatch}+ sizeOf _ = #{size TSQueryMatch}+ peek ptr = do+ _id <- #{peek TSQueryMatch, id} ptr+ _pattern_index <- #{peek TSQueryMatch, pattern_index} ptr+ _capture_count <- #{peek TSQueryMatch, capture_count} ptr+ _captures <- peekTSQueryCapture _capture_count ( #{ptr TSQueryMatch, captures} ptr )+ return TSQueryMatch{..}+ poke ptr TSQueryMatch{..} = do+ #{poke TSQueryMatch, id} ptr _id+ #{poke TSQueryMatch, pattern_index} ptr _pattern_index+ let _capture_count :: ( #{type uint16_t} )+ _capture_count = fromIntegral $ length _captures+ #{poke TSQueryMatch, capture_count} ptr _capture_count+ pokeTSQueryCapture ( #{ptr TSQueryMatch, captures} ptr ) _captures++{-| Peek an array of @`TSQueryCapture`@.++ This does the same as `peekArray`.+ -}+peekTSQueryCapture ::+ ( #{type uint16_t} ) ->+ Ptr TSQueryCapture ->+ IO [TSQueryCapture]+peekTSQueryCapture capture_count ptr =+ peekArray (fromIntegral capture_count) ptr++{-| Poke an array of @`TSQueryCapture`@.++ This does the same as `pokeArray`.+ -}+pokeTSQueryCapture ::+ Ptr TSQueryCapture ->+ [TSQueryCapture] ->+ IO ()+pokeTSQueryCapture ptr captures =+ pokeArray ptr captures++{-|+ > typedef enum TSQueryPredicateStepType {+ > TSQueryPredicateStepTypeDone,+ > TSQueryPredicateStepTypeCapture,+ > TSQueryPredicateStepTypeString,+ > } TSQueryPredicateStepType;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSQueryPredicateStepType" #-}+ TSQueryPredicateStepType = TSQueryPredicateStepType+ { unTSQueryPredicateStepType :: #{type TSQueryPredicateStepType}+ }+ deriving (Eq, Show)+ deriving newtype (Storable)++pattern TSQueryPredicateStepTypeDone :: TSQueryPredicateStepType+pattern TSQueryPredicateStepTypeDone = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeDone} )++pattern TSQueryPredicateStepTypeCapture :: TSQueryPredicateStepType+pattern TSQueryPredicateStepTypeCapture = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeCapture} )++pattern TSQueryPredicateStepTypeString :: TSQueryPredicateStepType+pattern TSQueryPredicateStepTypeString = TSQueryPredicateStepType ( #{const TSQueryPredicateStepTypeString} )++{-# COMPLETE TSQueryPredicateStepTypeDone, TSQueryPredicateStepTypeCapture, TSQueryPredicateStepTypeString #-}++{-|+ > typedef struct TSQueryPredicateStep {+ > TSQueryPredicateStepType type;+ > uint32_t value_id;+ > } TSQueryPredicateStep;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "struct TSQueryPredicateStep" #-}+ TSQueryPredicateStep = TSQueryPredicateStep+ { _type :: {-# UNPACK #-} !TSQueryPredicateStepType+ , _value_id :: {-# UNPACK #-} !( #{type uint32_t} )+ }++instance Storable TSQueryPredicateStep where+ alignment _ = #{alignment TSQueryPredicateStep}+ sizeOf _ = #{size TSQueryPredicateStep}+ peek ptr = do+ _type <- #{peek TSQueryPredicateStep, type} ptr+ _value_id <- #{peek TSQueryPredicateStep, value_id} ptr+ return TSQueryPredicateStep{..}+ poke ptr TSQueryPredicateStep{..} = do+ #{poke TSQueryPredicateStep, type} ptr _type+ #{poke TSQueryPredicateStep, value_id} ptr _value_id++{-|+ > typedef enum TSQueryError {+ > TSQueryErrorNone = 0,+ > TSQueryErrorSyntax,+ > TSQueryErrorNodeType,+ > TSQueryErrorField,+ > TSQueryErrorCapture,+ > TSQueryErrorStructure,+ > TSQueryErrorLanguage,+ > } TSQueryError;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSQueryError" #-}+ TSQueryError = TSQueryError+ { unTSQueryError :: #{type TSQueryError}+ }+ deriving (Eq, Show)+ deriving newtype (Storable)++pattern TSQueryErrorNone :: TSQueryError+pattern TSQueryErrorNone = TSQueryError ( #{const TSQueryErrorNone} )++pattern TSQueryErrorSyntax :: TSQueryError+pattern TSQueryErrorSyntax = TSQueryError ( #{const TSQueryErrorSyntax} )++pattern TSQueryErrorNodeType :: TSQueryError+pattern TSQueryErrorNodeType = TSQueryError ( #{const TSQueryErrorNodeType} )++pattern TSQueryErrorField :: TSQueryError+pattern TSQueryErrorField = TSQueryError ( #{const TSQueryErrorField} )++pattern TSQueryErrorCapture :: TSQueryError+pattern TSQueryErrorCapture = TSQueryError ( #{const TSQueryErrorCapture} )++pattern TSQueryErrorStructure :: TSQueryError+pattern TSQueryErrorStructure = TSQueryError ( #{const TSQueryErrorStructure} )++pattern TSQueryErrorLanguage :: TSQueryError+pattern TSQueryErrorLanguage = TSQueryError ( #{const TSQueryErrorLanguage} )++{-# COMPLETE TSQueryErrorNone, TSQueryErrorSyntax, TSQueryErrorNodeType, TSQueryErrorField, TSQueryErrorCapture, TSQueryErrorStructure, TSQueryErrorLanguage #-}++{--------------------}+{- Section - Parser -}+{--------------------}++{-|+ Create a new parser.++ > TSParser *ts_parser_new(void);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_new"+ ts_parser_new ::+ IO (Ptr TSParser)++{-|+ Delete the parser, freeing all of the memory that it used.++ > void ts_parser_delete(TSParser *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_delete"+ ts_parser_delete ::+ Ptr TSParser ->+ IO ()++{-| C function pointer to @`ts_parser_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_parser_delete"+ p_ts_parser_delete ::+ FunPtr (+ Ptr TSParser ->+ IO ()+ )++{-|+ Get the parser's current language.++ > const TSLanguage *ts_parser_language(const TSParser *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_language"+ ts_parser_language ::+ ConstPtr TSParser ->+ IO (ConstPtr TSLanguage)++{-|+ Set the language that the parser should use for parsing.++ Returns a boolean indicating whether or not the language was successfully+ assigned. True means assignment succeeded. False means there was a version+ mismatch: the language was generated with an incompatible version of the+ Tree-sitter CLI. Check the language's version using @`ts_language_version`@+ and compare it to this library's @`TREE_SITTER_LANGUAGE_VERSION`@ and+ @`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`@ constants.++ > bool ts_parser_set_language(TSParser *self, const TSLanguage *language);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_language"+ ts_parser_set_language ::+ Ptr TSParser ->+ ConstPtr TSLanguage ->+ IO CBool++{-|+ Set the ranges of text that the parser should include when parsing.++ By default, the parser will always include entire documents. This function+ allows you to parse only a *portion* of a document but still return a syntax+ tree whose ranges match up with the document as a whole. You can also pass+ multiple disjoint ranges.++ The second and third parameters specify the location and length of an array+ of ranges. The parser does *not* take ownership of these ranges; it copies+ the data, so it doesn't matter how these ranges are allocated.++ If @count@ is zero, then the entire document will be parsed. Otherwise,+ the given ranges must be ordered from earliest to latest in the document,+ and they must not overlap. That is, the following must hold for all:++ > i < count - 1: ranges[i].end_byte <= ranges[i + 1].start_byte++ If this requirement is not satisfied, the operation will fail, the ranges+ will not be assigned, and this function will return @`False`@. On success,+ this function returns @`True`@.++ > bool ts_parser_set_included_ranges(+ > TSParser *self,+ > const TSRange *ranges,+ > uint32_t count+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_included_ranges"+ ts_parser_set_included_ranges ::+ Ptr TSParser ->+ ConstPtr TSRange ->+ ( #{type uint32_t} ) ->+ IO CBool++{-|+ Get the ranges of text that the parser will include when parsing.++ The returned pointer is owned by the parser. The caller should not free it+ or write to it. The length of the array will be written to the given+ @count@ pointer.++ > const TSRange *ts_parser_included_ranges(+ > const TSParser *self,+ > uint32_t *count+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_included_ranges"+ ts_parser_included_ranges ::+ ConstPtr TSParser ->+ Ptr ( #{type uint32_t} ) ->+ IO (ConstPtr TSRange)++{-|+ Use the parser to parse some source code and create a syntax tree.++ If you are parsing this document for the first time, pass @NULL@ for the+ @old_tree@ parameter. Otherwise, if you have already parsed an earlier+ version of this document and the document has since been edited, pass the+ previous syntax tree so that the unchanged parts of it can be reused.+ This will save time and memory. For this to work correctly, you must have+ already edited the old syntax tree using the @`ts_tree_edit`@ function in a+ way that exactly matches the source code changes.++ The @t`TSInput`@ parameter lets you specify how to read the text. It has the+ following three fields:++ 1. @read@: A function to retrieve a chunk of text at a given byte offset+ and (row, column) position. The function should return a pointer to the+ text and write its length to the @bytes_read@ pointer. The parser does+ not take ownership of this buffer; it just borrows it until it has+ finished reading it. The function should write a zero value to the+ @bytes_read@ pointer to indicate the end of the document.+ 2. @payload@: An arbitrary pointer that will be passed to each invocation+ of the @read@ function.+ 3. @encoding@: An indication of how the text is encoded. Either+ @TSInputEncodingUTF8@ or @TSInputEncodingUTF16@.++ This function returns a syntax tree on success, and @NULL@ on failure. There+ are three possible reasons for failure:++ 1. The parser does not have a language assigned. Check for this using the+ @`ts_parser_language`@ function.+ 2. Parsing was cancelled due to a timeout that was set by an earlier call to+ the @`ts_parser_set_timeout_micros`@ function. You can resume parsing from+ where the parser left out by calling @`ts_parser_parse`@ again with the+ same arguments. Or you can start parsing from scratch by first calling+ @`ts_parser_reset`@.+ 3. Parsing was cancelled using a cancellation flag that was set by an+ earlier call to @`ts_parser_set_cancellation_flag`@. You can resume parsing+ from where the parser left out by calling @`ts_parser_parse`@ again with+ the same arguments.++ > TSTree *ts_parser_parse(+ > TSParser *self,+ > const TSTree *old_tree,+ > TSInput input+ > );+-}+ts_parser_parse ::+ Ptr TSParser ->+ ConstPtr TSTree ->+ TSRead ->+ TSInputEncoding ->+ IO (Ptr TSTree)+ts_parser_parse = \self old_tree readFun encoding ->+ bracket (mkTSReadFunPtr readFun) freeHaskellFunPtr $ \readFun_p ->+ bracket (_wrap_ts_input_new readFun_p encoding) _wrap_ts_input_delete $ \input_p ->+ _wrap_ts_parser_parse self old_tree input_p++foreign import capi safe "TreeSitter/CApi_hsc.h _wrap_ts_parser_parse"+ _wrap_ts_parser_parse ::+ Ptr TSParser ->+ ConstPtr TSTree ->+ Ptr TSInput ->+ IO (Ptr TSTree)++#{def+ TSTree *_wrap_ts_parser_parse(+ TSParser *self,+ const TSTree *old_tree,+ TSInput *input+ )+ {+ return ts_parser_parse(self, old_tree, *input);+ }+}++{-|+ Use the parser to parse some source code stored in one contiguous buffer.+ The first two parameters are the same as in the @`ts_parser_parse`@ function+ above. The second two parameters indicate the location of the buffer and its+ length in bytes.++ > TSTree *ts_parser_parse_string(+ > TSParser *self,+ > const TSTree *old_tree,+ > const char *string,+ > uint32_t length+ > );+-}+foreign import capi safe "tree_sitter/api.h ts_parser_parse_string"+ ts_parser_parse_string ::+ Ptr TSParser ->+ ConstPtr TSTree ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ IO (Ptr TSTree)++{-|+ Use the parser to parse some source code stored in one contiguous buffer with+ a given encoding. The first four parameters work the same as in the+ @`ts_parser_parse_string`@ method above. The final parameter indicates whether+ the text is encoded as UTF8 or UTF16.++ > TSTree *ts_parser_parse_string_encoding(+ > TSParser *self,+ > const TSTree *old_tree,+ > const char *string,+ > uint32_t length,+ > TSInputEncoding encoding+ > );+-}+foreign import capi safe "tree_sitter/api.h ts_parser_parse_string_encoding"+ ts_parser_parse_string_encoding ::+ Ptr TSParser ->+ ConstPtr TSTree ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ TSInputEncoding ->+ IO (Ptr TSTree)++{-|+ Instruct the parser to start the next parse from the beginning.++ If the parser previously failed because of a timeout or a cancellation, then+ by default, it will resume where it left off on the next call to+ @`ts_parser_parse`@ or other parsing functions. If you don't want to resume,+ and instead intend to use this parser to parse some other document, you must+ call @`ts_parser_reset`@ first.++ > void ts_parser_reset(TSParser *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_reset"+ ts_parser_reset ::+ Ptr TSParser ->+ IO ()++{-|+ Set the maximum duration in microseconds that parsing should be allowed to+ take before halting.++ If parsing takes longer than this, it will halt early, returning @NULL@.+ See @`ts_parser_parse`@ for more information.++ > void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_timeout_micros"+ ts_parser_set_timeout_micros ::+ Ptr TSParser ->+ ( #{type uint64_t} ) ->+ IO ()++{-|+ Get the duration in microseconds that parsing is allowed to take.++ > uint64_t ts_parser_timeout_micros(const TSParser *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_timeout_micros"+ ts_parser_timeout_micros ::+ Ptr TSParser ->+ IO ( #{type uint64_t} )++{-|+ Set the parser's current cancellation flag pointer.++ If a non-null pointer is assigned, then the parser will periodically read+ from this pointer during parsing. If it reads a non-zero value, it will+ halt early, returning @NULL@. See @`ts_parser_parse`@ for more information.++ > void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_cancellation_flag"+ ts_parser_set_cancellation_flag ::+ Ptr TSParser ->+ ConstPtr CSize ->+ IO ()++{-|+ Get the parser's current cancellation flag pointer.++ > const size_t *ts_parser_cancellation_flag(const TSParser *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_cancellation_flag"+ ts_parser_cancellation_flag ::+ ConstPtr TSParser ->+ IO (ConstPtr CSize)++{-|+ Set the logger that a parser should use during parsing.++ The parser does not take ownership over the logger payload. If a logger was+ previously assigned, the caller is responsible for releasing any memory+ owned by the previous logger.++ > void ts_parser_set_logger(TSParser *self, TSLogger logger);+-}+ts_parser_set_logger ::+ Ptr TSParser ->+ TSLog ->+ IO ()+ts_parser_set_logger = \self logFun -> mask_ $ do+ logFun_p <- mkTSLogFunPtr logFun+ logger_p <- _wrap_ts_logger_new logFun_p+ _wrap_ts_parser_set_logger self logger_p++#{def+ void _wrap_ts_parser_set_logger(+ TSParser *self,+ TSLogger *logger+ )+ {+ ts_parser_set_logger(self, *logger);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_set_logger"+ _wrap_ts_parser_set_logger ::+ Ptr TSParser ->+ Ptr TSLogger ->+ IO ()++{-|+ Get the parser's current logger.++ > TSLogger ts_parser_logger(const TSParser *self);+-}+ts_parser_logger ::+ ConstPtr TSParser ->+ IO (Maybe TSLog)+ts_parser_logger = \self -> do+ logFun_p <- _wrap_ts_parser_logger self+ pure $+ if logFun_p /= nullFunPtr+ then Just $ unTSLogFunPtr logFun_p+ else Nothing+{-# INLINE ts_parser_logger #-}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_logger"+ _wrap_ts_parser_logger ::+ ConstPtr TSParser ->+ IO (FunPtr TSLog)++#{def+ TSLog _wrap_ts_parser_logger(+ const TSParser *self+ )+ {+ // Get the current logger+ TSLogger logger = ts_parser_logger(self);+ // Copy the payload into the log function+ if(logger.payload) {+ TSLog log;+ memcpy(&log, logger.payload, sizeof log);+ return log;+ }+ return NULL;+ }+}++{-|+ Remove the parser's current logger.+-}+ts_parser_remove_logger ::+ Ptr TSParser ->+ IO (Maybe TSLog)+ts_parser_remove_logger = \self -> mask_ $ do+ logFun_p <- _wrap_ts_parser_remove_logger self+ if logFun_p == nullFunPtr+ then pure Nothing+ else do+ let logFun = unTSLogFunPtr logFun_p+ freeHaskellFunPtr logFun_p+ pure $ Just logFun++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_parser_remove_logger"+ _wrap_ts_parser_remove_logger ::+ Ptr TSParser ->+ IO (FunPtr TSLog)++#{def+ TSLog _wrap_ts_parser_remove_logger(+ TSParser *self+ )+ {+ // Get the current logger+ TSLogger logger = ts_parser_logger(self);+ // Set the parser's logger to NULL+ TSLogger logger_null = {NULL, NULL};+ ts_parser_set_logger(self, logger_null);+ // Copy the payload into the log function+ if (logger.payload) {+ TSLog log;+ memcpy(&log, logger.payload, sizeof log);+ free(logger.payload);+ return log;+ }+ return NULL;+ }+}++{-|+ Set the file descriptor to which the parser should write debugging graphs+ during parsing. The graphs are formatted in the DOT language. You may want+ to pipe these graphs directly to a `dot(1)` process in order to generate+ SVG output. You can turn off this logging by passing a negative number.++ > void ts_parser_print_dot_graphs(TSParser *self, int fd);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_print_dot_graphs"+ ts_parser_print_dot_graphs ::+ Ptr TSParser ->+ ( #{type int} ) ->+ IO ()++{------------------}+{- Section - Tree -}+{------------------}++{-|+ Create a shallow copy of the syntax tree. This is very fast.++ You need to copy a syntax tree in order to use it on more than one thread at+ a time, as syntax trees are not thread safe.++ > TSTree *ts_tree_copy(const TSTree *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_copy"+ ts_tree_copy ::+ Ptr TSTree ->+ IO (Ptr TSTree)++{-|+ Delete the syntax tree, freeing all of the memory that it used.++ > void ts_tree_delete(TSTree *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_delete"+ ts_tree_delete ::+ Ptr TSTree ->+ IO ()++{-| C function pointer to @`ts_tree_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_tree_delete"+ p_ts_tree_delete ::+ FunPtr (+ Ptr TSTree ->+ IO ()+ )++{-|+ Get the root node of the syntax tree.++ > TSNode ts_tree_root_node(const TSTree *self);+-}+ts_tree_root_node ::+ ConstPtr TSTree ->+ IO TSNode+ts_tree_root_node = \self ->+ alloca $ \result_p -> do+ _wrap_ts_tree_root_node self result_p+ peek result_p+{-# INLINE ts_tree_root_node #-}++#{def+ void _wrap_ts_tree_root_node(+ const TSTree *self,+ TSNode *result+ )+ {+ *result = ts_tree_root_node(self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_root_node"+ _wrap_ts_tree_root_node ::+ ConstPtr TSTree ->+ Ptr TSNode ->+ IO ()++{-|+ Get the root node of the syntax tree, but with its position+ shifted forward by the given offset.++ > TSNode ts_tree_root_node_with_offset(+ > const TSTree *self,+ > uint32_t offset_bytes,+ > TSPoint offset_extent+ > );+-}+ts_tree_root_node_with_offset ::+ ConstPtr TSTree ->+ ( #{type uint32_t} ) ->+ TSPoint ->+ IO TSNode+ts_tree_root_node_with_offset = \self offset_bytes offset_extent ->+ alloca $ \result_p -> do+ with offset_extent $ \offset_extent_p ->+ _wrap_ts_tree_root_node_with_offset self offset_bytes offset_extent_p result_p+ peek result_p+{-# INLINE ts_tree_root_node_with_offset #-}++#{def+ void _wrap_ts_tree_root_node_with_offset(+ const TSTree *self,+ uint32_t offset_bytes,+ TSPoint *offset_extent,+ TSNode *result+ )+ {+ *result = ts_tree_root_node_with_offset(self, offset_bytes, *offset_extent);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_root_node_with_offset"+ _wrap_ts_tree_root_node_with_offset ::+ ConstPtr TSTree ->+ ( #{type uint32_t } ) ->+ Ptr TSPoint ->+ Ptr TSNode ->+ IO ()++{-|+ Get the language that was used to parse the syntax tree.++ > const TSLanguage *ts_tree_language(const TSTree *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_language"+ ts_tree_language ::+ Ptr TSTree ->+ IO (ConstPtr TSLanguage)++{-|+ Get the array of included ranges that was used to parse the syntax tree.++ The returned pointer must be freed by the caller.++ > TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_included_ranges"+ ts_tree_included_ranges ::+ Ptr TSTree ->+ Ptr ( #{type uint32_t} ) ->+ IO ( Ptr TSRange )++{-|+ Edit the syntax tree to keep it in sync with source code that has been+ edited.++ You must describe the edit both in terms of byte offsets and in terms of+ (row, column) coordinates.++ > void ts_tree_edit(TSTree *self, const TSInputEdit *edit);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_edit"+ ts_tree_edit ::+ Ptr TSTree ->+ Ptr TSInputEdit ->+ IO ()++{-|+ Compare an old edited syntax tree to a new syntax tree representing the same+ document, returning an array of ranges whose syntactic structure has changed.++ For this to work correctly, the old syntax tree must have been edited such+ that its ranges match up to the new tree. Generally, you'll want to call+ this function right after calling one of the @`ts_parser_parse`@ functions.+ You need to pass the old tree that was passed to parse, as well as the new+ tree that was returned from that function.++ The returned array is allocated using @malloc@ and the caller is responsible+ for freeing it using @free@. The length of the array will be written to the+ given @length@ pointer.++ > TSRange *ts_tree_get_changed_ranges(+ > const TSTree *old_tree,+ > const TSTree *new_tree,+ > uint32_t *length+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_get_changed_ranges"+ ts_tree_get_changed_ranges ::+ Ptr TSTree ->+ Ptr TSTree ->+ Ptr ( #{type uint32_t} ) ->+ IO ( Ptr TSRange )++{-|+ Write a DOT graph describing the syntax tree to the given file.++ > void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_print_dot_graph"+ ts_tree_print_dot_graph ::+ Ptr TSTree ->+ ( #{type int} ) ->+ IO ()++{------------------}+{- Section - Node -}+{------------------}++{-|+ Get the node's type as a null-terminated string.++ > const char *ts_node_type(TSNode self);+-}+ts_node_type ::+ TSNode ->+ IO (ConstPtr CChar)+ts_node_type = \self ->+ with self $ \self_p ->+ _wrap_ts_node_type self_p+{-# INLINE ts_node_type #-}++#{def+ const char *_wrap_ts_node_type(TSNode *self)+ {+ return ts_node_type(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_type"+ _wrap_ts_node_type ::+ Ptr TSNode ->+ IO (ConstPtr CChar)++{-|+ Get the node's type as a numerical id.++ > TSSymbol ts_node_symbol(TSNode self);+-}+ts_node_symbol ::+ TSNode ->+ IO TSSymbol+ts_node_symbol = \self ->+ with self $ \self_p ->+ _wrap_ts_node_symbol self_p+{-# INLINE ts_node_symbol #-}++#{def+ TSSymbol _wrap_ts_node_symbol(TSNode *self)+ {+ return ts_node_symbol(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_symbol"+ _wrap_ts_node_symbol ::+ Ptr TSNode ->+ IO TSSymbol++{-|+ Get the node's language.++ > const TSLanguage *ts_node_language(TSNode self);+-}+ts_node_language ::+ TSNode ->+ IO (ConstPtr TSLanguage)+ts_node_language = \self ->+ with self $ \self_p ->+ _wrap_ts_node_language self_p+{-# INLINE ts_node_language #-}++#{def+ const TSLanguage *_wrap_ts_node_language(TSNode *self)+ {+ return ts_node_language(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_language"+ _wrap_ts_node_language ::+ Ptr TSNode ->+ IO (ConstPtr TSLanguage)++{-|+ Get the node's type as it appears in the grammar ignoring aliases as a+ null-terminated string.++ > const char *ts_node_grammar_type(TSNode self);+-}+ts_node_grammar_type ::+ TSNode ->+ IO (ConstPtr CChar)+ts_node_grammar_type = \self ->+ with self $ \self_p ->+ _wrap_ts_node_grammar_type self_p+{-# INLINE ts_node_grammar_type #-}++#{def+ const char *_wrap_ts_node_grammar_type(TSNode *self)+ {+ return ts_node_grammar_type(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_grammar_type"+ _wrap_ts_node_grammar_type ::+ Ptr TSNode ->+ IO (ConstPtr CChar)++{-|+ Get the node's type as a numerical id as it appears in the grammar ignoring+ aliases. This should be used in @`ts_language_next_state`@ instead of+ @`ts_node_symbol`@.++ > TSSymbol ts_node_grammar_symbol(TSNode self);+-}+ts_node_grammar_symbol ::+ TSNode ->+ IO TSSymbol+ts_node_grammar_symbol = \self ->+ with self $ \self_p ->+ _wrap_ts_node_grammar_symbol self_p+{-# INLINE ts_node_grammar_symbol #-}++#{def+ TSSymbol _wrap_ts_node_grammar_symbol(TSNode *self)+ {+ return ts_node_grammar_symbol(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_grammar_symbol"+ _wrap_ts_node_grammar_symbol ::+ Ptr TSNode ->+ IO TSSymbol++{-|+ Get the node's start byte.++ > uint32_t ts_node_start_byte(TSNode self);+-}+ts_node_start_byte ::+ TSNode ->+ IO ( #{type uint32_t} )+ts_node_start_byte = \self ->+ with self $ \self_p ->+ _wrap_ts_node_start_byte self_p+{-# INLINE ts_node_start_byte #-}++#{def+ uint32_t _wrap_ts_node_start_byte(TSNode *self)+ {+ return ts_node_start_byte(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_start_byte"+ _wrap_ts_node_start_byte ::+ Ptr TSNode ->+ IO ( #{type uint32_t} )++{-|+ Get the node's start position in terms of rows and columns.++ > TSPoint ts_node_start_point(TSNode self);+-}+ts_node_start_point ::+ TSNode ->+ IO TSPoint+ts_node_start_point = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_start_point self_p result_p+ peek result_p+{-# INLINE ts_node_start_point #-}++#{def+ void _wrap_ts_node_start_point(TSNode *self, TSPoint *result)+ {+ *result = ts_node_start_point(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_start_point"+ _wrap_ts_node_start_point ::+ Ptr TSNode ->+ Ptr TSPoint ->+ IO ()++{-|+ Get the node's end byte.++ > uint32_t ts_node_end_byte(TSNode self);+-}+ts_node_end_byte ::+ TSNode ->+ IO ( #{type uint32_t} )+ts_node_end_byte = \self ->+ with self $ \self_p ->+ _wrap_ts_node_end_byte self_p+{-# INLINE ts_node_end_byte #-}++#{def+ uint32_t _wrap_ts_node_end_byte(TSNode *self)+ {+ return ts_node_end_byte(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_end_byte"+ _wrap_ts_node_end_byte ::+ Ptr TSNode ->+ IO ( #{type uint32_t} )++{-|+ Get the node's end position in terms of rows and columns.++ > TSPoint ts_node_end_point(TSNode self);+-}+ts_node_end_point ::+ TSNode ->+ IO TSPoint+ts_node_end_point = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_end_point self_p result_p+ peek result_p+{-# INLINE ts_node_end_point #-}++#{def+ void _wrap_ts_node_end_point(TSNode *self, TSPoint *result)+ {+ *result = ts_node_end_point(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_end_point"+ _wrap_ts_node_end_point ::+ Ptr TSNode ->+ Ptr TSPoint ->+ IO ()++{-|+ Get an S-expression representing the node as a string.++ This string is allocated with @malloc@ and the caller is responsible for+ freeing it using @free@.++ > char *ts_node_string(TSNode self);+-}+ts_node_string ::+ TSNode ->+ IO (Ptr CChar)+ts_node_string = \self ->+ with self $ \self_p ->+ _wrap_ts_node_string self_p+{-# INLINE ts_node_string #-}++#{def+ char *_wrap_ts_node_string(TSNode *self)+ {+ return ts_node_string(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_string"+ _wrap_ts_node_string ::+ Ptr TSNode ->+ IO (Ptr CChar)++{-|+ Check if the node is null. Functions like @`ts_node_child`@ and+ @`ts_node_next_sibling`@ will return a null node to indicate that no such node+ was found.++ > bool ts_node_is_null(TSNode self);+-}+ts_node_is_null ::+ TSNode ->+ IO CBool+ts_node_is_null = \self ->+ with self $ \self_p ->+ _wrap_ts_node_is_null self_p+{-# INLINE ts_node_is_null #-}++#{def+ bool _wrap_ts_node_is_null(TSNode *self)+ {+ return ts_node_is_null(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_null"+ _wrap_ts_node_is_null ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if the node is *named*. Named nodes correspond to named rules in the+ grammar, whereas *anonymous* nodes correspond to string literals in the+ grammar.++ > bool ts_node_is_named(TSNode self);+-}+ts_node_is_named ::+ TSNode ->+ IO CBool+ts_node_is_named = \self ->+ with self $ \self_p ->+ _wrap_ts_node_is_named self_p+{-# INLINE ts_node_is_named #-}++#{def+ bool _wrap_ts_node_is_named(TSNode *self)+ {+ return ts_node_is_named(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_named"+ _wrap_ts_node_is_named ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if the node is *missing*. Missing nodes are inserted by the parser in+ order to recover from certain kinds of syntax errors.++ > bool ts_node_is_missing(TSNode self);+-}+ts_node_is_missing ::+ TSNode ->+ IO CBool+ts_node_is_missing = \self ->+ with self $ \self_p ->+ _wrap_ts_node_is_missing self_p+{-# INLINE ts_node_is_missing #-}++#{def+ bool _wrap_ts_node_is_missing(TSNode *self)+ {+ return ts_node_is_missing(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_missing"+ _wrap_ts_node_is_missing ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if the node is *extra*. Extra nodes represent things like comments,+ which are not required the grammar, but can appear anywhere.++ > bool ts_node_is_extra(TSNode self);+-}+ts_node_is_extra ::+ TSNode ->+ IO CBool+ts_node_is_extra = \self ->+ with self $ \self_p ->+ _wrap_ts_node_is_extra self_p+{-# INLINE ts_node_is_extra #-}++#{def+ bool _wrap_ts_node_is_extra(TSNode *self)+ {+ return ts_node_is_extra(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_extra"+ _wrap_ts_node_is_extra ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if a syntax node has been edited.++ > bool ts_node_has_changes(TSNode self);+-}+ts_node_has_changes ::+ TSNode ->+ IO CBool+ts_node_has_changes = \self ->+ with self $ \self_p ->+ _wrap_ts_node_has_changes self_p+{-# INLINE ts_node_has_changes #-}++#{def+ bool _wrap_ts_node_has_changes(TSNode *self)+ {+ return ts_node_has_changes(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_has_changes"+ _wrap_ts_node_has_changes ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if the node is a syntax error or contains any syntax errors.++ > bool ts_node_has_error(TSNode self);+-}+ts_node_has_error ::+ TSNode ->+ IO CBool+ts_node_has_error = \self ->+ with self $ \self_p ->+ _wrap_ts_node_has_error self_p+{-# INLINE ts_node_has_error #-}++#{def+ bool _wrap_ts_node_has_error(TSNode *self)+ {+ return ts_node_has_error(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_has_error"+ _wrap_ts_node_has_error ::+ Ptr TSNode ->+ IO CBool++{-|+ Check if the node is a syntax error.++ > bool ts_node_is_error (TSNode self)+-}+ts_node_is_error ::+ TSNode ->+ IO CBool+ts_node_is_error = \self ->+ with self $ \self_p ->+ _wrap_ts_node_is_error self_p+{-# INLINE ts_node_is_error #-}++#{def+ bool _wrap_ts_node_is_error(TSNode *self)+ {+ return ts_node_is_error(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_is_error"+ _wrap_ts_node_is_error ::+ Ptr TSNode ->+ IO CBool++{-|+ Get this node's parse state.++ > TSStateId ts_node_parse_state (TSNode self)+-}+ts_node_parse_state ::+ TSNode ->+ IO TSStateId+ts_node_parse_state = \self ->+ with self $ \self_p ->+ _wrap_ts_node_parse_state self_p+{-# INLINE ts_node_parse_state #-}++#{def+ TSStateId _wrap_ts_node_parse_state(TSNode *self)+ {+ return ts_node_parse_state(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_parse_state"+ _wrap_ts_node_parse_state ::+ Ptr TSNode ->+ IO TSStateId++{-|+ Get the parse state after this node.++ > TSStateId ts_node_next_parse_state (TSNode self)+-}+ts_node_next_parse_state ::+ TSNode ->+ IO TSStateId+ts_node_next_parse_state = \self ->+ with self $ \self_p ->+ _wrap_ts_node_next_parse_state self_p+{-# INLINE ts_node_next_parse_state #-}++#{def+ TSStateId _wrap_ts_node_next_parse_state(TSNode *self)+ {+ return ts_node_next_parse_state(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_parse_state"+ _wrap_ts_node_next_parse_state ::+ Ptr TSNode ->+ IO TSStateId++{-|+ Get the node's immediate parent.++ > TSNode ts_node_parent(TSNode self);+-}+ts_node_parent ::+ TSNode ->+ IO TSNode+ts_node_parent = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_parent self_p result_p+ peek result_p+{-# INLINE ts_node_parent #-}++#{def+ void _wrap_ts_node_parent(TSNode *self, TSNode *result)+ {+ *result = ts_node_parent(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_parent"+ _wrap_ts_node_parent ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node that contains @descendant@.++ Note that this can return @descendant@ itself.++ > TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant);+-}+ts_node_child_with_descendant ::+ TSNode ->+ TSNode ->+ IO TSNode+ts_node_child_with_descendant = \self descendant ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ with descendant $ \descendant_p ->+ _wrap_ts_node_child_with_descendant self_p descendant_p result_p+ peek result_p+{-# INLINE ts_node_child_with_descendant #-}++#{def+ void _wrap_ts_node_child_with_descendant(TSNode *self, TSNode *descendant, TSNode *result)+ {+ *result = ts_node_child_with_descendant(*self, *descendant);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_with_descendant"+ _wrap_ts_node_child_with_descendant ::+ Ptr TSNode ->+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's child at the given index, where zero represents the first+ child.++ > TSNode ts_node_child(TSNode self, uint32_t child_index);+-}+ts_node_child ::+ TSNode ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_child = \self child_index ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_child self_p child_index result_p+ peek result_p+{-# INLINE ts_node_child #-}++#{def+ void _wrap_ts_node_child(TSNode *self, uint32_t child_index, TSNode *result)+ {+ *result = ts_node_child(*self, child_index);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child"+ _wrap_ts_node_child ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the field name for node's child at the given index, where zero represents+ the first child. Returns @NULL@ if no field is found.++ > const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index);+-}+ts_node_field_name_for_child ::+ TSNode ->+ ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)+ts_node_field_name_for_child = \self child_index ->+ with self $ \self_p ->+ _wrap_ts_node_field_name_for_child self_p child_index+{-# INLINE ts_node_field_name_for_child #-}++#{def+ const char *_wrap_ts_node_field_name_for_child(TSNode *self, uint32_t child_index)+ {+ return ts_node_field_name_for_child(*self, child_index);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_field_name_for_child"+ _wrap_ts_node_field_name_for_child ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)++{-|+ Get the field name for node's named child at the given index, where zero+ represents the first named child. Returns @NULL@, if no field is found.++ > const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index);+-}+ts_node_field_name_for_named_child ::+ TSNode ->+ ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)+ts_node_field_name_for_named_child = \self child_index ->+ with self $ \self_p ->+ _wrap_ts_node_field_name_for_named_child self_p child_index+{-# INLINE ts_node_field_name_for_named_child #-}++#{def+ const char *_wrap_ts_node_field_name_for_named_child(TSNode *self, uint32_t child_index)+ {+ return ts_node_field_name_for_named_child(*self, child_index);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_field_name_for_named_child"+ _wrap_ts_node_field_name_for_named_child ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)++{-|+ Get the node's number of children.++ > uint32_t ts_node_child_count(TSNode self);+-}+ts_node_child_count ::+ TSNode ->+ IO ( #{type uint32_t} )+ts_node_child_count = \self ->+ with self $ \self_p ->+ _wrap_ts_node_child_count self_p+{-# INLINE ts_node_child_count #-}++#{def+ uint32_t _wrap_ts_node_child_count(TSNode *self)+ {+ return ts_node_child_count(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_count"+ _wrap_ts_node_child_count ::+ Ptr TSNode ->+ IO ( #{type uint32_t} )++{-|+ Get the node's *named* child at the given index.++ See also @`ts_node_is_named`@.++ > TSNode ts_node_named_child(TSNode self, uint32_t child_index);+-}+ts_node_named_child ::+ TSNode ->+ #{type uint32_t} ->+ IO TSNode+ts_node_named_child = \self child_index ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_named_child self_p child_index result_p+ peek result_p+{-# INLINE ts_node_named_child #-}++#{def+ void _wrap_ts_node_named_child(TSNode *self, uint32_t child_index, TSNode *result)+ {+ *result = ts_node_named_child(*self, child_index);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_child"+ _wrap_ts_node_named_child ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's number of *named* children.++ See also @`ts_node_is_named`@.++ > uint32_t ts_node_named_child_count(TSNode self);+-}+ts_node_named_child_count ::+ TSNode ->+ IO ( #{type uint32_t} )+ts_node_named_child_count = \self ->+ with self $ \self_p ->+ _wrap_ts_node_named_child_count self_p+{-# INLINE ts_node_named_child_count #-}++#{def+ uint32_t _wrap_ts_node_named_child_count(TSNode *self)+ {+ return ts_node_named_child_count(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_child_count"+ _wrap_ts_node_named_child_count ::+ Ptr TSNode ->+ IO ( #{type uint32_t} )++{-|+ Get the node's child with the given field name.++ > TSNode ts_node_child_by_field_name(+ > TSNode self,+ > const char *name,+ > uint32_t name_length+ > );+-}+ts_node_child_by_field_name ::+ TSNode ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_child_by_field_name = \self name name_length ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_child_by_field_name self_p name name_length result_p+ peek result_p+{-# INLINE ts_node_child_by_field_name #-}++#{def+ void _wrap_ts_node_child_by_field_name(+ TSNode *self,+ const char *name,+ uint32_t name_length,+ TSNode *result+ )+ {+ *result = ts_node_child_by_field_name(*self, name, name_length);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_by_field_name"+ _wrap_ts_node_child_by_field_name ::+ Ptr TSNode ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's child with the given numerical field id.++ You can convert a field name to an id using the+ @`ts_language_field_id_for_name`@ function.++ > TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id);+-}+ts_node_child_by_field_id ::+ TSNode ->+ TSFieldId ->+ IO TSNode+ts_node_child_by_field_id = \self field_id ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_child_by_field_id self_p field_id result_p+ peek result_p+{-# INLINE ts_node_child_by_field_id #-}++#{def+ void _wrap_ts_node_child_by_field_id(+ TSNode *self,+ TSFieldId field_id,+ TSNode *result+ )+ {+ *result = ts_node_child_by_field_id(*self, field_id);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_child_by_field_id"+ _wrap_ts_node_child_by_field_id ::+ Ptr TSNode ->+ TSFieldId ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's next sibling.++ > TSNode ts_node_next_sibling(TSNode self);+-}+ts_node_next_sibling ::+ TSNode ->+ IO TSNode+ts_node_next_sibling = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_next_sibling self_p result_p+ peek result_p+{-# INLINE ts_node_next_sibling #-}++#{def+ void _wrap_ts_node_next_sibling(TSNode *self, TSNode *result)+ {+ *result = ts_node_next_sibling(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_sibling"+ _wrap_ts_node_next_sibling ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's previous sibling.++ > TSNode ts_node_prev_sibling(TSNode self);+-}+ts_node_prev_sibling ::+ TSNode ->+ IO TSNode+ts_node_prev_sibling = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_prev_sibling self_p result_p+ peek result_p+{-# INLINE ts_node_prev_sibling #-}++#{def+ void _wrap_ts_node_prev_sibling(TSNode *self, TSNode *result)+ {+ *result = ts_node_prev_sibling(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_prev_sibling"+ _wrap_ts_node_prev_sibling ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's next *named* sibling.++ > TSNode ts_node_next_named_sibling(TSNode self);+-}+ts_node_next_named_sibling ::+ TSNode ->+ IO TSNode+ts_node_next_named_sibling = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_next_named_sibling self_p result_p+ peek result_p+{-# INLINE ts_node_next_named_sibling #-}++#{def+ void _wrap_ts_node_next_named_sibling(TSNode *self, TSNode *result)+ {+ *result = ts_node_next_named_sibling(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_next_named_sibling"+ _wrap_ts_node_next_named_sibling ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's previous *named* sibling.++ > TSNode ts_node_prev_named_sibling(TSNode self);+-}+ts_node_prev_named_sibling ::+ TSNode ->+ IO TSNode+ts_node_prev_named_sibling = \self ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_prev_named_sibling self_p result_p+ peek result_p+{-# INLINE ts_node_prev_named_sibling #-}++#{def+ void _wrap_ts_node_prev_named_sibling(TSNode *self, TSNode *result)+ {+ *result = ts_node_prev_named_sibling(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_prev_named_sibling"+ _wrap_ts_node_prev_named_sibling ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's first child that extends beyond the given byte offset.++ > TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte);+-}+ts_node_first_child_for_byte ::+ TSNode ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_first_child_for_byte = \self byte ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_first_child_for_byte self_p byte result_p+ peek result_p+{-# INLINE ts_node_first_child_for_byte #-}++#{def+ void _wrap_ts_node_first_child_for_byte(TSNode *self, uint32_t byte, TSNode *result)+ {+ *result = ts_node_first_child_for_byte(*self, byte);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_first_child_for_byte"+ _wrap_ts_node_first_child_for_byte ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's first named child that extends beyond the given byte offset.++ > TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte);+-}+ts_node_first_named_child_for_byte ::+ TSNode ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_first_named_child_for_byte = \self byte ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_first_named_child_for_byte self_p byte result_p+ peek result_p+{-# INLINE ts_node_first_named_child_for_byte #-}++#{def+ void _wrap_ts_node_first_named_child_for_byte(TSNode *self, uint32_t byte, TSNode *result)+ {+ *result = ts_node_first_named_child_for_byte(*self, byte);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_first_named_child_for_byte"+ _wrap_ts_node_first_named_child_for_byte ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the node's number of descendants, including one for the node itself.++ > uint32_t ts_node_descendant_count(TSNode self);+-}+ts_node_descendant_count ::+ TSNode ->+ IO ( #{type uint32_t} )+ts_node_descendant_count = \self ->+ with self $ \self_p ->+ _wrap_ts_node_descendant_count self_p+{-# INLINE ts_node_descendant_count #-}++#{def+ uint32_t _wrap_ts_node_descendant_count(TSNode *self)+ {+ return ts_node_descendant_count(*self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_count"+ _wrap_ts_node_descendant_count ::+ Ptr TSNode ->+ IO ( #{type uint32_t} )++{-|+ Get the smallest node within this node that spans the given range of bytes.++ > TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);+-}+ts_node_descendant_for_byte_range ::+ TSNode ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_descendant_for_byte_range = \self start end ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_descendant_for_byte_range self_p start end result_p+ peek result_p+{-# INLINE ts_node_descendant_for_byte_range #-}++#{def+ void _wrap_ts_node_descendant_for_byte_range(TSNode *self, uint32_t start, uint32_t end, TSNode *result)+ {+ *result = ts_node_descendant_for_byte_range(*self, start, end);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_for_byte_range"+ _wrap_ts_node_descendant_for_byte_range ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the smallest node within this node that spans the given range of positions.++ > TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);+-}+ts_node_descendant_for_point_range ::+ TSNode ->+ TSPoint ->+ TSPoint ->+ IO TSNode+ts_node_descendant_for_point_range = \self start end ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ with start $ \start_p ->+ with end $ \end_p ->+ _wrap_ts_node_descendant_for_point_range self_p start_p end_p result_p+ peek result_p+{-# INLINE ts_node_descendant_for_point_range #-}++#{def+ void _wrap_ts_node_descendant_for_point_range(TSNode *self, TSPoint *start, TSPoint *end, TSNode *result)+ {+ *result = ts_node_descendant_for_point_range(*self, *start, *end);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_descendant_for_point_range"+ _wrap_ts_node_descendant_for_point_range ::+ Ptr TSNode ->+ Ptr TSPoint ->+ Ptr TSPoint ->+ Ptr TSNode ->+ IO ()++{-|+ Get the smallest named node within this node that spans the given range of+ bytes.++ > TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);+-}+ts_node_named_descendant_for_byte_range ::+ TSNode ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ IO TSNode+ts_node_named_descendant_for_byte_range = \self start end ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ _wrap_ts_node_named_descendant_for_byte_range self_p start end result_p+ peek result_p+{-# INLINE ts_node_named_descendant_for_byte_range #-}++#{def+ void _wrap_ts_node_named_descendant_for_byte_range(TSNode *self, uint32_t start, uint32_t end, TSNode *result)+ {+ *result = ts_node_named_descendant_for_byte_range(*self, start, end);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_descendant_for_byte_range"+ _wrap_ts_node_named_descendant_for_byte_range ::+ Ptr TSNode ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ Ptr TSNode ->+ IO ()++{-|+ Get the smallest named node within this node that spans the given range of positions.++ > TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);+-}+ts_node_named_descendant_for_point_range ::+ TSNode ->+ TSPoint ->+ TSPoint ->+ IO TSNode+ts_node_named_descendant_for_point_range = \self start end ->+ alloca $ \result_p -> do+ with self $ \self_p ->+ with start $ \start_p ->+ with end $ \end_p ->+ _wrap_ts_node_named_descendant_for_point_range self_p start_p end_p result_p+ peek result_p+{-# INLINE ts_node_named_descendant_for_point_range #-}++#{def+ void _wrap_ts_node_named_descendant_for_point_range(TSNode *self, TSPoint *start, TSPoint *end, TSNode *result)+ {+ *result = ts_node_named_descendant_for_point_range(*self, *start, *end);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_named_descendant_for_point_range"+ _wrap_ts_node_named_descendant_for_point_range ::+ Ptr TSNode ->+ Ptr TSPoint ->+ Ptr TSPoint ->+ Ptr TSNode ->+ IO ()++{-|+ Edit the node to keep it in-sync with source code that has been edited.++ This function is only rarely needed. When you edit a syntax tree with the+ @`ts_tree_edit`@ function, all of the nodes that you retrieve from the tree+ afterward will already reflect the edit. You only need to use @`ts_node_edit`@+ when you have a @t`TSNode`@ instance that you want to keep and continue to use+ after an edit.++ > void ts_node_edit(TSNode *self, const TSInputEdit *edit);+-}+foreign import capi unsafe "TreeSitter/CApi_hsc.h ts_node_edit"+ ts_node_edit ::+ Ptr TSNode ->+ ConstPtr TSInputEdit ->+ IO ()++{-|+ Check if two nodes are identical.++ > bool ts_node_eq(TSNode self, TSNode other);+-}+ts_node_eq ::+ TSNode ->+ TSNode ->+ IO CBool+ts_node_eq = \self other ->+ with self $ \self_p ->+ with other $ \other_p ->+ _wrap_ts_node_eq self_p other_p+{-# INLINE ts_node_eq #-}++#{def+ bool _wrap_ts_node_eq(TSNode *self, TSNode *other)+ {+ return ts_node_eq(*self, *other);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_node_eq"+ _wrap_ts_node_eq ::+ Ptr TSNode ->+ Ptr TSNode ->+ IO CBool++{- Section - TreeCursor -}++{-|+ Create a new tree cursor starting from the given node.++ A tree cursor allows you to walk a syntax tree more efficiently than is+ possible using the @t`TSNode`@ functions. It is a mutable object that is always+ on a certain syntax node, and can be moved imperatively to different nodes.++ > TSTreeCursor ts_tree_cursor_new(TSNode node);+-}+ts_tree_cursor_new ::+ TSNode ->+ IO TSTreeCursor+ts_tree_cursor_new = \node ->+ alloca $ \result_p -> do+ ts_tree_cursor_new_p node result_p+ peek result_p+{-# INLINE ts_tree_cursor_new #-}++-- | Create a new tree cursor starting from the given node.+--+-- Variant of 'ts_tree_cursor_new' that writes the tree cursor to the provided pointer.+ts_tree_cursor_new_p ::+ TSNode ->+ Ptr TSTreeCursor -> -- ^ Output pointer for the new tree cursor.+ IO ()+ts_tree_cursor_new_p = \node result_p ->+ with node $ \node_p ->+ _wrap_ts_tree_cursor_new node_p result_p+{-# INLINE ts_tree_cursor_new_p #-}++#{def+ void _wrap_ts_tree_cursor_new(TSNode *node, TSTreeCursor *result)+ {+ *result = ts_tree_cursor_new(*node);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_new"+ _wrap_ts_tree_cursor_new ::+ Ptr TSNode ->+ Ptr TSTreeCursor ->+ IO ()++{-|+ Delete a tree cursor, freeing all of the memory that it used.++ > void ts_tree_cursor_delete(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_delete"+ ts_tree_cursor_delete ::+ Ptr TSTreeCursor ->+ IO ()++{-| C function pointer to @`ts_tree_cursor_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_tree_cursor_delete"+ p_ts_tree_cursor_delete ::+ FunPtr (+ Ptr TSTreeCursor ->+ IO ()+ )++{-|+ Re-initialize a tree cursor to start at the original node that the cursor was+ constructed with.++ > void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node);+-}+ts_tree_cursor_reset ::+ Ptr TSTreeCursor ->+ TSNode ->+ IO ()+ts_tree_cursor_reset = \self node ->+ with node $ \node_p ->+ _wrap_ts_tree_cursor_reset self node_p+{-# INLINE ts_tree_cursor_reset #-}++#{def+ void _wrap_ts_tree_cursor_reset(TSTreeCursor *self, TSNode *node)+ {+ ts_tree_cursor_reset(self, *node);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_reset"+ _wrap_ts_tree_cursor_reset ::+ Ptr TSTreeCursor ->+ Ptr TSNode ->+ IO ()++{-|+ Re-initialize a tree cursor to the same position as another cursor.++ Unlike @`ts_tree_cursor_reset`@, this will not lose parent information and+ allows reusing already created cursors.++ > void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_reset_to"+ ts_tree_cursor_reset_to ::+ Ptr TSTreeCursor ->+ ConstPtr TSTreeCursor ->+ IO ()++{-|+ Get the tree cursor's current node.++ > TSNode ts_tree_cursor_current_node(const TSTreeCursor *self);+-}+ts_tree_cursor_current_node ::+ ConstPtr TSTreeCursor ->+ IO TSNode+ts_tree_cursor_current_node = \self ->+ alloca $ \result_p -> do+ _wrap_ts_tree_cursor_current_node self result_p+ peek result_p+{-# INLINE ts_tree_cursor_current_node #-}++#{def+ void _wrap_ts_tree_cursor_current_node(const TSTreeCursor *self, TSNode *result)+ {+ *result = ts_tree_cursor_current_node(self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_current_node"+ _wrap_ts_tree_cursor_current_node ::+ ConstPtr TSTreeCursor ->+ Ptr TSNode ->+ IO ()++{-|+ Get the field name of the tree cursor's current node.++ This returns @NULL@ if the current node doesn't have a field.+ See also @`ts_node_child_by_field_name`@.++ > const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_field_name"+ ts_tree_cursor_current_field_name ::+ ConstPtr TSTreeCursor ->+ IO (ConstPtr CChar)++{-|+ Get the field id of the tree cursor's current node.++ This returns zero if the current node doesn't have a field.+ See also @`ts_node_child_by_field_id`@, @`ts_language_field_id_for_name`@.++ > TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_field_id"+ ts_tree_cursor_current_field_id ::+ ConstPtr TSTreeCursor ->+ IO TSFieldId++{-|+ Move the cursor to the parent of its current node.++ This returns @true@ if the cursor successfully moved, and returns @false@+ if there was no parent node (the cursor was already on the root node).++ > bool ts_tree_cursor_goto_parent(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_parent"+ ts_tree_cursor_goto_parent ::+ Ptr TSTreeCursor ->+ IO CBool++{-|+ Move the cursor to the next sibling of its current node.++ This returns @true@ if the cursor successfully moved, and returns @false@+ if there was no next sibling node.++ > bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_next_sibling"+ ts_tree_cursor_goto_next_sibling ::+ Ptr TSTreeCursor ->+ IO CBool++{-|+ Move the cursor to the previous sibling of its current node.++ This returns @true@ if the cursor successfully moved, and returns @false@ if+ there was no previous sibling node.++ Note, that this function may be slower than+ @`ts_tree_cursor_goto_next_sibling`@ due to how node positions are stored. In+ the worst case, this will need to iterate through all the children upto the+ previous sibling node to recalculate its position.++ > bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_previous_sibling"+ ts_tree_cursor_goto_previous_sibling ::+ Ptr TSTreeCursor ->+ IO CBool++{-|+ Move the cursor to the first child of its current node.++ This returns @true@ if the cursor successfully moved, and returns @false@+ if there were no children.++ > bool ts_tree_cursor_goto_first_child(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_first_child"+ ts_tree_cursor_goto_first_child ::+ Ptr TSTreeCursor ->+ IO CBool++{-|+ Move the cursor to the last child of its current node.++ This returns @true@ if the cursor successfully moved, and returns @false@ if+ there were no children.++ Note that this function may be slower than @`ts_tree_cursor_goto_first_child`@+ because it needs to iterate through all the children to compute the child's+ position.++ > bool ts_tree_cursor_goto_last_child(TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_last_child"+ ts_tree_cursor_goto_last_child ::+ Ptr TSTreeCursor ->+ IO CBool++{-|+ Move the cursor to the node that is the nth descendant of+ the original node that the cursor was constructed with, where+ zero represents the original node itself.++ > void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_descendant"+ ts_tree_cursor_goto_descendant ::+ Ptr TSTreeCursor ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Get the index of the cursor's current node out of all of the+ descendants of the original node that the cursor was constructed with.++ > uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_descendant_index"+ ts_tree_cursor_current_descendant_index ::+ ConstPtr TSTreeCursor ->+ IO ( #{type uint32_t} )++{-|+ Get the depth of the cursor's current node relative to the original+ node that the cursor was constructed with.++ > uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_current_depth"+ ts_tree_cursor_current_depth ::+ ConstPtr TSTreeCursor ->+ IO ( #{type uint32_t} )++{-|+ Move the cursor to the first child of its current node that extends beyond+ the given byte offset.++ This returns the index of the child node if one was found, and returns -1+ if no such child was found.++ > int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte);+-}+foreign import capi unsafe "tree_sitter/api.h ts_tree_cursor_goto_first_child_for_byte"+ ts_tree_cursor_goto_first_child_for_byte ::+ Ptr TSTreeCursor ->+ ( #{type uint32_t} ) ->+ IO ( #{type int64_t} )++{-|+ Move the cursor to the first child of its current node that extends beyond+ the given byte point.++ This returns the index of the child node if one was found, and returns -1+ if no such child was found.++ > int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point);+-}+ts_tree_cursor_goto_first_child_for_point ::+ Ptr TSTreeCursor ->+ TSPoint ->+ IO ( #{type int64_t} )+ts_tree_cursor_goto_first_child_for_point = \self goal_point ->+ with goal_point $ \goal_point_p ->+ _wrap_ts_tree_cursor_goto_first_child_for_point self goal_point_p+{-# INLINE ts_tree_cursor_goto_first_child_for_point #-}++#{def+ int64_t _wrap_ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint *goal_point)+ {+ return ts_tree_cursor_goto_first_child_for_point(self, *goal_point);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_goto_first_child_for_point"+ _wrap_ts_tree_cursor_goto_first_child_for_point ::+ Ptr TSTreeCursor ->+ Ptr TSPoint ->+ IO ( #{type int64_t} )++{-|+ > TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor);+ -}+ts_tree_cursor_copy ::+ Ptr TSTreeCursor ->+ IO TSTreeCursor+ts_tree_cursor_copy = \self ->+ alloca $ \result_p -> do+ _wrap_ts_tree_cursor_copy self result_p+ peek result_p+{-# INLINE ts_tree_cursor_copy #-}++-- | Copy a tree cursor.+--+-- Variant of 'ts_tree_cursor_copy' that writes the tree cursor to the provided pointer.+ts_tree_cursor_copy_p ::+ Ptr TSTreeCursor ->+ Ptr TSTreeCursor -> -- ^ Output pointer for the new tree cursor.+ IO ()+ts_tree_cursor_copy_p = _wrap_ts_tree_cursor_copy+{-# INLINE ts_tree_cursor_copy_p #-}+++#{def+ void _wrap_ts_tree_cursor_copy(TSTreeCursor *self, TSTreeCursor *result)+ {+ *result = ts_tree_cursor_copy(self);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_tree_cursor_copy"+ _wrap_ts_tree_cursor_copy ::+ Ptr TSTreeCursor ->+ Ptr TSTreeCursor ->+ IO ()++{- Section - Query -}++{-|+ Create a new query from a string containing one or more S-expression+ patterns. The query is associated with a particular language, and can+ only be run on syntax nodes parsed with that language.++ If all of the given patterns are valid, this returns a @t`TSQuery`@.+ If a pattern is invalid, this returns @NULL@, and provides two pieces+ of information about the problem:+ 1. The byte offset of the error is written to the @error_offset@ parameter.+ 2. The type of error is written to the @error_type@ parameter.++ > TSQuery *ts_query_new(+ > const TSLanguage *language,+ > const char *source,+ > uint32_t source_len,+ > uint32_t *error_offset,+ > TSQueryError *error_type+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_new"+ ts_query_new ::+ ConstPtr TSLanguage ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ Ptr ( #{type uint32_t} ) ->+ Ptr TSQueryError ->+ IO (Ptr TSQuery)++{-|+ Delete a query, freeing all of the memory that it used.++ > void ts_query_delete(TSQuery *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_delete"+ ts_query_delete ::+ Ptr TSQuery ->+ IO ()++{-| C function pointer to @`ts_query_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_query_delete"+ p_ts_query_delete ::+ FunPtr (+ Ptr TSQuery ->+ IO ()+ )++{-|+ Get the number of patterns in the query.++ > uint32_t ts_query_pattern_count(const TSQuery *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_pattern_count"+ ts_query_pattern_count ::+ ConstPtr TSQuery ->+ IO ( #{type uint32_t} )++{-|+ Get the number of captures in the query.++ > uint32_t ts_query_capture_count(const TSQuery *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_count"+ ts_query_capture_count ::+ ConstPtr TSQuery ->+ IO ( #{type uint32_t} )++{-|+ Get the number of string literals in the query.++ > uint32_t ts_query_string_count(const TSQuery *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_string_count"+ ts_query_string_count ::+ ConstPtr TSQuery ->+ IO ( #{type uint32_t} )++{-|+ Get the byte offset where the given pattern starts in the query's source.++ This can be useful when combining queries by concatenating their source+ code strings.++ > uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_start_byte_for_pattern"+ ts_query_start_byte_for_pattern ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ IO ( #{type uint32_t} )++{-|+ Get the byte offset where the given pattern ends in the query's source.++ This can be useful when combining queries by concatenating their source+ code strings.++ > uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_end_byte_for_pattern"+ ts_query_end_byte_for_pattern ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ IO ( #{type uint32_t} )++{-|+ Get all of the predicates for the given pattern in the query.++ The predicates are represented as a single array of steps. There are three+ types of steps in this array, which correspond to the three legal values for+ the `type` field:+ - @`TSQueryPredicateStepTypeCapture`@ - Steps with this type represent names+ of captures. Their @value_id@ can be used with the+ @`ts_query_capture_name_for_id`@ function to obtain the name of the capture.+ - @`TSQueryPredicateStepTypeString`@ - Steps with this type represent literal+ strings. Their @value_id@ can be used with the+ @`ts_query_string_value_for_id`@ function to obtain their string value.+ - @`TSQueryPredicateStepTypeDone`@ - Steps with this type are *sentinels*+ that represent the end of an individual predicate. If a pattern has two+ predicates, then there will be two steps with this `type` in the array.++ > const TSQueryPredicateStep *ts_query_predicates_for_pattern(+ > const TSQuery *self,+ > uint32_t pattern_index,+ > uint32_t *step_count+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_predicates_for_pattern"+ ts_query_predicates_for_pattern ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ Ptr ( #{type uint32_t} ) ->+ IO (ConstPtr TSQueryPredicateStep)++{-|+ Check if the given pattern in the query has a single root node.++ > bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_rooted"+ ts_query_is_pattern_rooted ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ IO CBool++{-|+ Check if the given pattern in the query is non-local.++ A non-local pattern has multiple root nodes and can match within a+ repeating sequence of nodes, as specified by the grammar. Non-local+ patterns disable certain optimizations that would otherwise be possible+ when executing a query on a specific range of a syntax tree.++ > bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_non_local"+ ts_query_is_pattern_non_local ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ IO CBool++{-|+ Check if a given pattern is guaranteed to match once a given step is reached.+ The step is specified by its byte offset in the query's source code.++ > bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_is_pattern_guaranteed_at_step"+ ts_query_is_pattern_guaranteed_at_step ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ IO CBool++{-|+ Get the name and length of one of the query's captures, or one of the+ query's string literals. Each capture and string is associated with a+ numeric id based on the order that it appeared in the query's source.++ > const char *ts_query_capture_name_for_id(+ > const TSQuery *self,+ > uint32_t index,+ > uint32_t *length+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_name_for_id"+ ts_query_capture_name_for_id ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ Ptr ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)++{-|+ Get the quantifier of the query's captures. Each capture is * associated+ with a numeric id based on the order that it appeared in the query's source.++ > TSQuantifier ts_query_capture_quantifier_for_id(+ > const TSQuery *self,+ > uint32_t pattern_index,+ > uint32_t capture_index+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_capture_quantifier_for_id"+ ts_query_capture_quantifier_for_id ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ IO TSQuantifier++{-|+ > const char *ts_query_string_value_for_id(+ > const TSQuery *self,+ > uint32_t index,+ > uint32_t *length+ > );+ -}+foreign import capi unsafe "tree_sitter/api.h ts_query_string_value_for_id"+ ts_query_string_value_for_id ::+ ConstPtr TSQuery ->+ ( #{type uint32_t} ) ->+ Ptr ( #{type uint32_t} ) ->+ IO (ConstPtr CChar)++{-|+ Disable a certain capture within a query.++ This prevents the capture from being returned in matches, and also avoids+ any resource usage associated with recording the capture. Currently, there+ is no way to undo this.++ > void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_disable_capture"+ ts_query_disable_capture ::+ Ptr TSQuery ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Disable a certain pattern within a query.++ This prevents the pattern from matching and removes most of the overhead+ associated with the pattern. Currently, there is no way to undo this.++ > void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_disable_pattern"+ ts_query_disable_pattern ::+ Ptr TSQuery ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Create a new cursor for executing a given query.++ The cursor stores the state that is needed to iteratively search+ for matches. To use the query cursor, first call @`ts_query_cursor_exec`@+ to start running a given query on a given syntax node. Then, there are+ two options for consuming the results of the query:+ 1. Repeatedly call @`ts_query_cursor_next_match`@ to iterate over all of the+ *matches* in the order that they were found. Each match contains the+ index of the pattern that matched, and an array of captures. Because+ multiple patterns can match the same set of nodes, one match may contain+ captures that appear *before* some of the captures from a previous match.+ 2. Repeatedly call @`ts_query_cursor_next_capture`@ to iterate over all of the+ individual *captures* in the order that they appear. This is useful if+ don't care about which pattern matched, and just want a single ordered+ sequence of captures.++ If you don't care about consuming all of the results, you can stop calling+ @`ts_query_cursor_next_match`@ or @`ts_query_cursor_next_capture`@ at any point.+ You can then start executing another query on another node by calling+ @`ts_query_cursor_exec`@ again.++ > TSQueryCursor *ts_query_cursor_new(void);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_new"+ ts_query_cursor_new ::+ IO (Ptr TSQueryCursor)++{-|+ Delete a query cursor, freeing all of the memory that it used.++ > void ts_query_cursor_delete(TSQueryCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_delete"+ ts_query_cursor_delete ::+ Ptr TSQueryCursor ->+ IO ()++{-| C function pointer to @`ts_query_cursor_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_query_cursor_delete"+ p_ts_query_cursor_delete ::+ FunPtr (+ Ptr TSQueryCursor ->+ IO ()+ )++{-|+ Start running a given query on a given node.++ > void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node);+-}+ts_query_cursor_exec ::+ Ptr TSQueryCursor ->+ ConstPtr TSQuery ->+ TSNode ->+ IO ()+ts_query_cursor_exec = \self query node ->+ with node $ \node_p ->+ _wrap_ts_query_cursor_exec self query node_p+{-# INLINE ts_query_cursor_exec #-}++#{def+ void _wrap_ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode *node)+ {+ return ts_query_cursor_exec(self, query, *node);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_query_cursor_exec"+ _wrap_ts_query_cursor_exec ::+ Ptr TSQueryCursor ->+ ConstPtr TSQuery ->+ Ptr TSNode ->+ IO ()++{-|+ Check whether the maximum number of in-progress matches allowed by this query cursor was exceeded.++ Query cursors have an optional maximum capacity for storing lists of+ in-progress captures. If this capacity is exceeded, then the+ earliest-starting match will silently be dropped to make room for further+ matches. This maximum capacity is optional — by default, query cursors allow+ any number of pending matches, dynamically allocating new space for them as+ needed as the query is executed.++ > bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_did_exceed_match_limit"+ ts_query_cursor_did_exceed_match_limit ::+ ConstPtr TSQueryCursor ->+ IO CBool++{-|+ Get the maximum number of in-progress matches allowed by this query cursor.++ > uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_match_limit"+ ts_query_cursor_match_limit ::+ ConstPtr TSQueryCursor ->+ IO ( #{type uint32_t} )++{-|+ Set the maximum number of in-progress matches allowed by this query cursor.++ > void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_match_limit"+ ts_query_cursor_set_match_limit ::+ Ptr TSQueryCursor ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Set the maximum duration in microseconds that query execution should be allowed to+ take before halting.++ If query execution takes longer than this, it will halt early, returning @NULL@.+ See @`ts_query_cursor_next_match`@ or @`ts_query_cursor_next_capture`@ for more information.++ > void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_timeout_micros"+ ts_query_cursor_set_timeout_micros ::+ Ptr TSQueryCursor ->+ ( #{type uint64_t} ) ->+ IO ()++{-|+ Get the duration in microseconds that query execution is allowed to take.++ This is set via @`ts_query_cursor_set_timeout_micros`@.++ > uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_timeout_micros"+ ts_query_cursor_timeout_micros ::+ ConstPtr TSQueryCursor ->+ IO ( #{type uint64_t} )++{-|+ Set the range of bytes in which the query will be executed.++ > void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_byte_range"+ ts_query_cursor_set_byte_range ::+ Ptr TSQueryCursor ->+ ( #{type uint32_t} ) ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Set the range of positions in which the query will be executed.++ > void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point);+-}+ts_query_cursor_set_point_range ::+ Ptr TSQueryCursor ->+ TSPoint ->+ TSPoint ->+ IO ()+ts_query_cursor_set_point_range = \self start_point end_point ->+ with start_point $ \start_point_p ->+ with end_point $ \end_point_p ->+ _wrap_ts_query_cursor_set_point_range self start_point_p end_point_p+{-# INLINE ts_query_cursor_set_point_range #-}++#{def+ void _wrap_ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint *start_point, TSPoint *end_point)+ {+ ts_query_cursor_set_point_range(self, *start_point, *end_point);+ }+}++foreign import capi unsafe "TreeSitter/CApi_hsc.h _wrap_ts_query_cursor_set_point_range"+ _wrap_ts_query_cursor_set_point_range ::+ Ptr TSQueryCursor ->+ Ptr TSPoint ->+ Ptr TSPoint ->+ IO ()++{-|+ Advance to the next match of the currently running query.++ If there is a match, write it to `*match` and return @true@.+ Otherwise, return @false@.++ > bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_next_match"+ ts_query_cursor_next_match ::+ Ptr TSQueryCursor ->+ Ptr TSQueryMatch ->+ IO CBool++{-|+ Remove a match of the currently running query.++ > void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_remove_match"+ ts_query_cursor_remove_match ::+ Ptr TSQueryCursor ->+ ( #{type uint32_t} ) ->+ IO ()++{-|+ Advance to the next capture of the currently running query.++ If there is a capture, write its match to `*match` and its index within+ the matche's capture list to `*capture_index`. Otherwise, return @false@.++ > bool ts_query_cursor_next_capture(+ > TSQueryCursor *self,+ > TSQueryMatch *match,+ > uint32_t *capture_index+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_next_capture"+ ts_query_cursor_next_capture ::+ Ptr TSQueryCursor ->+ Ptr TSQueryMatch ->+ Ptr ( #{type uint32_t} ) ->+ IO CBool++{-|+ Set the maximum start depth for a query cursor.++ This prevents cursors from exploring children nodes at a certain depth.+ Note if a pattern includes many children, then they will still be checked.++ The zero max start depth value can be used as a special behavior and+ it helps to destructure a subtree by staying on a node and using captures+ for interested parts. Note that the zero max start depth only limit a search+ depth for a pattern's root node but other nodes that are parts of the pattern+ may be searched at any depth what defined by the pattern structure.++ Set to @UINT32_MAX@ to remove the maximum start depth.++ > void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth);+-}+foreign import capi unsafe "tree_sitter/api.h ts_query_cursor_set_max_start_depth"+ ts_query_cursor_set_max_start_depth ::+ Ptr TSQueryCursor ->+ ( #{type uint32_t} ) ->+ IO ()++{- Section - Language -}++{-|+ Get another reference to the given language.++ > const TSLanguage *ts_language_copy(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_copy"+ ts_language_copy ::+ ConstPtr TSLanguage ->+ IO (ConstPtr TSLanguage)++{-|+ Free any dynamically-allocated resources for this language, if+ this is the last reference.++ > void ts_language_delete(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_delete"+ ts_language_delete ::+ ConstPtr TSLanguage ->+ IO ()++{-| C function pointer to @`ts_language_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_language_delete"+ p_ts_language_delete ::+ FunPtr (+ ConstPtr TSLanguage ->+ IO ()+ )++{-|+ Get the number of distinct node types in the language.++ > uint32_t ts_language_symbol_count(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_count"+ ts_language_symbol_count ::+ ConstPtr TSLanguage ->+ IO ( #{type uint32_t} )++{-|+ Get the number of valid states in this language.++ > uint32_t ts_language_state_count(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_state_count"+ ts_language_state_count ::+ ConstPtr TSLanguage ->+ IO ( #{type uint32_t} )++{-|+ Get a node type string for the given numerical id.++ > const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_name"+ ts_language_symbol_name ::+ ConstPtr TSLanguage ->+ TSSymbol ->+ IO (ConstPtr CChar)++{-|+ Get the numerical id for the given node type string.++ > TSSymbol ts_language_symbol_for_name(+ > const TSLanguage *self,+ > const char *string,+ > uint32_t length,+ > bool is_named+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_for_name"+ ts_language_symbol_for_name ::+ ConstPtr TSLanguage ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ CBool ->+ IO TSSymbol++{-|+ Get the number of distinct field names in the language.++ > uint32_t ts_language_field_count(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_field_count"+ ts_language_field_count ::+ ConstPtr TSLanguage ->+ IO ( #{type uint32_t} )++{-|+ Get the field name string for the given numerical id.++ > const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_field_name_for_id"+ ts_language_field_name_for_id ::+ ConstPtr TSLanguage ->+ TSFieldId ->+ IO (ConstPtr CChar)++{-|+ Get the numerical id for the given field name string.++ > TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_field_id_for_name"+ ts_language_field_id_for_name ::+ ConstPtr TSLanguage ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ IO TSFieldId++{-|+ Check whether the given node type id belongs to named nodes, anonymous nodes,+ or a hidden nodes.++ See also @`ts_node_is_named`@. Hidden nodes are never returned from the API.++ > TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_symbol_type"+ ts_language_symbol_type ::+ ConstPtr TSLanguage ->+ TSSymbol ->+ IO TSSymbolType++{-|+ Get the ABI version number for this language. This version number is used+ to ensure that languages were generated by a compatible version of+ Tree-sitter.++ See also @`ts_parser_set_language`@.++ > uint32_t ts_language_version(const TSLanguage *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_version"+ ts_language_version ::+ ConstPtr TSLanguage ->+ IO ( #{type uint32_t} )++{-|+ Get the next parse state. Combine this with lookahead iterators to generate+ completion suggestions or valid symbols in error nodes. Use+ @`ts_node_grammar_symbol`@ for valid symbols.++ > TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_next_state"+ ts_language_next_state ::+ ConstPtr TSLanguage ->+ TSStateId ->+ TSSymbol ->+ IO TSStateId++{--------------------------------}+{- Section - Lookahead Iterator -}+{--------------------------------}++{-|+ Create a new lookahead iterator for the given language and parse state.++ This returns @NULL@ if state is invalid for the language.++ Repeatedly using @`ts_lookahead_iterator_next`@ and+ @`ts_lookahead_iterator_current_symbol`@ will generate valid symbols in the+ given parse state. Newly created lookahead iterators will contain the @ERROR@+ symbol.++ Lookahead iterators can be useful to generate suggestions and improve syntax+ error diagnostics. To get symbols valid in an ERROR node, use the lookahead+ iterator on its first leaf node state. For @MISSING@ nodes, a lookahead+ iterator created on the previous non-extra leaf node may be appropriate.++ > TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_new"+ ts_lookahead_iterator_new ::+ ConstPtr TSLanguage ->+ TSStateId ->+ IO (Ptr TSLookaheadIterator)++{-|+ Delete a lookahead iterator freeing all the memory used.++ > void ts_lookahead_iterator_delete(TSLookaheadIterator *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_delete"+ ts_lookahead_iterator_delete ::+ Ptr TSLookaheadIterator ->+ IO ()++{-| C function pointer to @`ts_lookahead_iterator_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_lookahead_iterator_delete"+ p_ts_lookahead_iterator_delete ::+ FunPtr (+ Ptr TSLookaheadIterator ->+ IO ()+ )++{-|+ Reset the lookahead iterator to another state.++ This returns @true@ if the iterator was reset to the given state and @false@+ otherwise.++ > bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_reset_state"+ ts_lookahead_iterator_reset_state ::+ Ptr TSLookaheadIterator ->+ TSStateId ->+ IO CBool++{-|+ Reset the lookahead iterator.++ This returns @true@ if the language was set successfully and @false@+ otherwise.++ > bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_reset"+ ts_lookahead_iterator_reset ::+ Ptr TSLookaheadIterator ->+ ConstPtr TSLanguage ->+ TSStateId ->+ IO CBool++{-|+ Get the current language of the lookahead iterator.++ > const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_language"+ ts_lookahead_iterator_language ::+ Ptr TSLookaheadIterator ->+ IO (ConstPtr TSLanguage)++{-|+ Advance the lookahead iterator to the next symbol.++ This returns @true@ if there is a new symbol and @false@ otherwise.++ > bool ts_lookahead_iterator_next(TSLookaheadIterator *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_next"+ ts_lookahead_iterator_next ::+ Ptr TSLookaheadIterator ->+ IO CBool++{-|+ Get the current symbol of the lookahead iterator;++ > TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_current_symbol"+ ts_lookahead_iterator_current_symbol ::+ ConstPtr TSLookaheadIterator ->+ IO TSSymbol++{-|+ Get the current symbol type of the lookahead iterator as a null terminated+ string.++ > const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self);+-}+foreign import capi unsafe "tree_sitter/api.h ts_lookahead_iterator_current_symbol_name"+ ts_lookahead_iterator_current_symbol_name ::+ ConstPtr TSLookaheadIterator ->+ IO (ConstPtr CChar)++{-------------------------------------}+{- Section - WebAssembly Integration -}+{-------------------------------------}++-- def TREE_SITTER_FEATURE_WASM+#ifdef TREE_SITTER_FEATURE_WASM++{-|+ > typedef struct wasm_engine_t TSWasmEngine;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSWasmEngine" #-}+ TSWasmEngine++{-|+ > typedef struct TSWasmStore TSWasmStore;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSWasmStore" #-}+ TSWasmStore++{-|+ > typedef enum {+ > TSWasmErrorKindNone = 0,+ > TSWasmErrorKindParse,+ > TSWasmErrorKindCompile,+ > TSWasmErrorKindInstantiate,+ > TSWasmErrorKindAllocate,+ > } TSWasmErrorKind;+ -}+newtype+ {-# CTYPE "tree_sitter/api.h" "TSWasmErrorKind" #-}+ TSWasmErrorKind = TSWasmErrorKind+ { unTSWasmErrorKind :: #{type TSWasmErrorKind}+ }+ deriving (Eq, Show)+ deriving newtype (Storable)++pattern TSWasmErrorKindNone :: TSWasmErrorKind+pattern TSWasmErrorKindNone = TSWasmErrorKind ( #{const TSWasmErrorKindNone} )++pattern TSWasmErrorKindParse :: TSWasmErrorKind+pattern TSWasmErrorKindParse = TSWasmErrorKind ( #{const TSWasmErrorKindParse} )++pattern TSWasmErrorKindCompile :: TSWasmErrorKind+pattern TSWasmErrorKindCompile = TSWasmErrorKind ( #{const TSWasmErrorKindCompile} )++pattern TSWasmErrorKindInstantiate :: TSWasmErrorKind+pattern TSWasmErrorKindInstantiate = TSWasmErrorKind ( #{const TSWasmErrorKindInstantiate} )++pattern TSWasmErrorKindAllocate :: TSWasmErrorKind+pattern TSWasmErrorKindAllocate = TSWasmErrorKind ( #{const TSWasmErrorKindAllocate} )++{-# COMPLETE TSWasmErrorKindNone, TSWasmErrorKindParse, TSWasmErrorKindCompile, TSWasmErrorKindInstantiate, TSWasmErrorKindAllocate #-}++{-|+ > typedef struct {+ > TSWasmErrorKind kind;+ > char *message;+ > } TSWasmError;+ -}+data+ {-# CTYPE "tree_sitter/api.h" "TSWasmError" #-}+ TSWasmError = TSWasmError+ { _kind :: {-# UNPACK #-} !TSWasmErrorKind+ , _message :: {-# UNPACK #-} !ByteString+ }++peekTSWasmError :: Ptr TSWasmError -> IO TSWasmError+peekTSWasmError ptr = do+ _kind <- #{peek TSWasmError, kind} ptr+ _message <- BS.packCString ( #{ptr TSWasmError, message} ptr )+ return TSWasmError{..}++withTSWasmError :: TSWasmError -> (Ptr TSWasmError -> IO a) -> IO a+withTSWasmError TSWasmError{..} action = do+ allocaBytesAligned @TSWasmError ( #{size TSWasmError} ) ( #{alignment TSWasmError} ) $ \ptr -> do+ #{poke TSWasmError, kind} ptr _kind+ BS.useAsCString _message $ \_message_p -> do+ #{poke TSWasmError, message} ptr _message_p+ action ptr++{-|+ Create a Wasm store.++ > TSWasmStore *ts_wasm_store_new(+ > TSWasmEngine *engine,+ > TSWasmError *error+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_new"+ ts_wasm_store_new ::+ Ptr TSWasmEngine ->+ Ptr TSWasmError ->+ IO (Ptr TSWasmStore)++{-|+ Free the memory associated with the given Wasm store.++ > void ts_wasm_store_delete(TSWasmStore *);+-}+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_delete"+ ts_wasm_store_delete ::+ Ptr TSWasmStore ->+ IO ()++{-| C function pointer to @`ts_wasm_store_delete`@.+ -}+foreign import capi unsafe "tree_sitter/api.h &ts_wasm_store_delete"+ p_ts_wasm_store_delete ::+ FunPtr (+ Ptr TSWasmStore ->+ IO ()+ )++{-|+ Create a language from a buffer of Wasm. The resulting language behaves+ like any other Tree-sitter language, except that in order to use it with+ a parser, that parser must have a Wasm store. Note that the language+ can be used with any Wasm store, it doesn't need to be the same store that+ was used to originally load it.++ > const TSLanguage *ts_wasm_store_load_language(+ > TSWasmStore *,+ > const char *name,+ > const char *wasm,+ > uint32_t wasm_len,+ > TSWasmError *error+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_load_language"+ ts_wasm_store_load_language ::+ Ptr TSWasmStore ->+ ConstPtr CChar ->+ ConstPtr CChar ->+ ( #{type uint32_t} ) ->+ Ptr TSWasmError ->+ IO (ConstPtr TSLanguage)++{-|+ Get the number of languages instantiated in the given wasm store.++ > size_t ts_wasm_store_language_count(const TSWasmStore *);+-}+foreign import capi unsafe "tree_sitter/api.h ts_wasm_store_language_count"+ ts_wasm_store_language_count ::+ ConstPtr TSWasmStore ->+ IO CSize++{-|+ Check if the language came from a Wasm module. If so, then in order to use+ this language with a Parser, that parser must have a Wasm store assigned.++ > bool ts_language_is_wasm(const TSLanguage *);+-}+foreign import capi unsafe "tree_sitter/api.h ts_language_is_wasm"+ ts_language_is_wasm ::+ ConstPtr TSLanguage ->+ IO CBool++{-|+ Assign the given Wasm store to the parser. A parser must have a Wasm store+ in order to use Wasm languages.++ > void ts_parser_set_wasm_store(TSParser *, TSWasmStore *);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_set_wasm_store"+ ts_parser_set_wasm_store ::+ Ptr TSParser ->+ Ptr TSWasmStore ->+ IO ()++{-|+ Remove the parser's current Wasm store and return it. This returns @NULL@ if+ the parser doesn't have a Wasm store.++ > TSWasmStore *ts_parser_take_wasm_store(TSParser *);+-}+foreign import capi unsafe "tree_sitter/api.h ts_parser_take_wasm_store"+ ts_parser_take_wasm_store ::+ Ptr TSParser ->+ IO (Ptr TSWasmStore)++-- end TREE_SITTER_FEATURE_WASM+#endif++{----------------------------------}+{- Section - Global Configuration -}+{----------------------------------}++{-|+ Set the allocation functions used by the library.++ By default, Tree-sitter uses the standard libc allocation functions,+ but aborts the process when an allocation fails. This function lets+ you supply alternative allocation functions at runtime.++ If you pass @NULL@ for any parameter, Tree-sitter will switch back to+ its default implementation of that function.++ If you call this function after the library has already been used, then+ you must ensure that either:++ 1. All the existing objects have been freed.+ 2. The new allocator shares its state with the old one, so it is capable of freeing memory that was allocated by the old allocator.++ > void ts_set_allocator(+ > void *(*new_malloc)(size_t),+ > void *(*new_calloc)(size_t, size_t),+ > void *(*new_realloc)(void *, size_t),+ > void (*new_free)(void *)+ > );+-}+foreign import capi unsafe "tree_sitter/api.h ts_set_allocator"+ ts_set_allocator ::+ FunPtr (CSize -> IO ()) ->+ FunPtr (CSize -> CSize -> IO ()) ->+ FunPtr (Ptr a -> CSize -> IO ()) ->+ FunPtr (Ptr a -> IO ()) ->+ IO ()
+ test/Main.hs view
@@ -0,0 +1,11 @@+-- | Test suite for @tree-sitter-capi@.+module Main where++import Test.Tasty (defaultMain, testGroup)+import Test.TreeSitter.CApi qualified as CApi++-- | All tests for @tree-sitter-capi@.+main :: IO ()+main = do+ defaultMain $+ testGroup "TreeSitter" [CApi.tests]
+ test/Test/TreeSitter/CApi.hs view
@@ -0,0 +1,77 @@+{-|+Tests for `TreeSitter.CApi`.+-}+module Test.TreeSitter.CApi where++import Control.Exception (bracket)+import Control.Monad (when)+import Data.Foldable (for_)+import Foreign (castPtr, nullPtr)+import Foreign.C (withCStringLen)+import Foreign.C.ConstPtr.Compat (ConstPtr (..))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.HUnit (testCase, (@=?))+import TreeSitter.CApi (+ TSStateId (..),+ ts_language_delete,+ ts_language_state_count,+ ts_lookahead_iterator_current_symbol,+ ts_lookahead_iterator_delete,+ ts_lookahead_iterator_new,+ ts_lookahead_iterator_next,+ ts_parser_delete,+ ts_parser_new,+ ts_parser_parse_string,+ )+import TreeSitter.While (tree_sitter_while)++-- | All tests for `TreeSitter.CApi`.+tests :: TestTree+tests =+ testGroup+ "CApi"+ [ test_ts_lookaheaditerator+ , test_ts_language_delete+ , test_ts_parser_parse_fails_without_language+ ]++-- | Does the lookahead iterator work?+test_ts_lookaheaditerator :: TestTree+test_ts_lookaheaditerator =+ testCase "test_ts_lookaheaditerator" $ do+ language <- castConstPtr <$> tree_sitter_while+ stateCount <- ts_language_state_count language+ for_ [0 .. stateCount - 1] $ \stateId -> do+ lookaheadIterator <- ts_lookahead_iterator_new language (TSStateId . fromIntegral $ stateId)+ let loop = do+ _currentSymbol <- ts_lookahead_iterator_current_symbol (ConstPtr lookaheadIterator)+ success <- ts_lookahead_iterator_next lookaheadIterator+ when (success >= 1) loop+ loop+ ts_lookahead_iterator_delete lookaheadIterator++-- | Is deleting a @`TreeSitter.CApi.TSLanguage`@ multiple times safe?+test_ts_language_delete :: TestTree+test_ts_language_delete =+ testCase "ts_language_delete" $ do+ language <- castConstPtr <$> tree_sitter_while+ ts_language_delete language+ ts_language_delete language++-- | Does @`ts_parser_parse_string`@ return @NULL@ when the parser does not have a language assigned.+test_ts_parser_parse_fails_without_language :: TestTree+test_ts_parser_parse_fails_without_language =+ testCase "test_ts_parser_parse fails without language" $ do+ bracket ts_parser_new ts_parser_delete $ \ts_parser ->+ withCStringLen "" $ \(string, string_length) -> do+ tree_p <-+ ts_parser_parse_string+ ts_parser+ (ConstPtr nullPtr)+ (ConstPtr string)+ (fromIntegral string_length)+ nullPtr @=? tree_p++-- | Internal helper: Cast a t`ConstPtr` using `castPtr`.+castConstPtr :: ConstPtr a -> ConstPtr b+castConstPtr = ConstPtr . castPtr . unConstPtr
+ vendor/tree-sitter/lib/include/tree_sitter/api.h view
@@ -0,0 +1,1317 @@+#ifndef TREE_SITTER_API_H_+#define TREE_SITTER_API_H_++#ifndef TREE_SITTER_HIDE_SYMBOLS+#if defined(__GNUC__) || defined(__clang__)+#pragma GCC visibility push(default)+#endif+#endif++#include <stdlib.h>+#include <stdint.h>+#include <stdbool.h>++#ifdef __cplusplus+extern "C" {+#endif++/****************************/+/* Section - ABI Versioning */+/****************************/++/**+ * The latest ABI version that is supported by the current version of the+ * library. When Languages are generated by the Tree-sitter CLI, they are+ * assigned an ABI version number that corresponds to the current CLI version.+ * The Tree-sitter library is generally backwards-compatible with languages+ * generated using older CLI versions, but is not forwards-compatible.+ */+#define TREE_SITTER_LANGUAGE_VERSION 14++/**+ * The earliest ABI version that is supported by the current version of the+ * library.+ */+#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13++/*******************/+/* Section - Types */+/*******************/++typedef uint16_t TSStateId;+typedef uint16_t TSSymbol;+typedef uint16_t TSFieldId;+typedef struct TSLanguage TSLanguage;+typedef struct TSParser TSParser;+typedef struct TSTree TSTree;+typedef struct TSQuery TSQuery;+typedef struct TSQueryCursor TSQueryCursor;+typedef struct TSLookaheadIterator TSLookaheadIterator;++typedef enum TSInputEncoding {+ TSInputEncodingUTF8,+ TSInputEncodingUTF16,+} TSInputEncoding;++typedef enum TSSymbolType {+ TSSymbolTypeRegular,+ TSSymbolTypeAnonymous,+ TSSymbolTypeSupertype,+ TSSymbolTypeAuxiliary,+} TSSymbolType;++typedef struct TSPoint {+ uint32_t row;+ uint32_t column;+} TSPoint;++typedef struct TSRange {+ TSPoint start_point;+ TSPoint end_point;+ uint32_t start_byte;+ uint32_t end_byte;+} TSRange;++typedef struct TSInput {+ void *payload;+ const char *(*read)(void *payload, uint32_t byte_index, TSPoint position, uint32_t *bytes_read);+ TSInputEncoding encoding;+} TSInput;++typedef enum TSLogType {+ TSLogTypeParse,+ TSLogTypeLex,+} TSLogType;++typedef struct TSLogger {+ void *payload;+ void (*log)(void *payload, TSLogType log_type, const char *buffer);+} TSLogger;++typedef struct TSInputEdit {+ uint32_t start_byte;+ uint32_t old_end_byte;+ uint32_t new_end_byte;+ TSPoint start_point;+ TSPoint old_end_point;+ TSPoint new_end_point;+} TSInputEdit;++typedef struct TSNode {+ uint32_t context[4];+ const void *id;+ const TSTree *tree;+} TSNode;++typedef struct TSTreeCursor {+ const void *tree;+ const void *id;+ uint32_t context[3];+} TSTreeCursor;++typedef struct TSQueryCapture {+ TSNode node;+ uint32_t index;+} TSQueryCapture;++typedef enum TSQuantifier {+ TSQuantifierZero = 0, // must match the array initialization value+ TSQuantifierZeroOrOne,+ TSQuantifierZeroOrMore,+ TSQuantifierOne,+ TSQuantifierOneOrMore,+} TSQuantifier;++typedef struct TSQueryMatch {+ uint32_t id;+ uint16_t pattern_index;+ uint16_t capture_count;+ const TSQueryCapture *captures;+} TSQueryMatch;++typedef enum TSQueryPredicateStepType {+ TSQueryPredicateStepTypeDone,+ TSQueryPredicateStepTypeCapture,+ TSQueryPredicateStepTypeString,+} TSQueryPredicateStepType;++typedef struct TSQueryPredicateStep {+ TSQueryPredicateStepType type;+ uint32_t value_id;+} TSQueryPredicateStep;++typedef enum TSQueryError {+ TSQueryErrorNone = 0,+ TSQueryErrorSyntax,+ TSQueryErrorNodeType,+ TSQueryErrorField,+ TSQueryErrorCapture,+ TSQueryErrorStructure,+ TSQueryErrorLanguage,+} TSQueryError;++/********************/+/* Section - Parser */+/********************/++/**+ * Create a new parser.+ */+TSParser *ts_parser_new(void);++/**+ * Delete the parser, freeing all of the memory that it used.+ */+void ts_parser_delete(TSParser *self);++/**+ * Get the parser's current language.+ */+const TSLanguage *ts_parser_language(const TSParser *self);++/**+ * Set the language that the parser should use for parsing.+ *+ * Returns a boolean indicating whether or not the language was successfully+ * assigned. True means assignment succeeded. False means there was a version+ * mismatch: the language was generated with an incompatible version of the+ * Tree-sitter CLI. Check the language's version using [`ts_language_version`]+ * and compare it to this library's [`TREE_SITTER_LANGUAGE_VERSION`] and+ * [`TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION`] constants.+ */+bool ts_parser_set_language(TSParser *self, const TSLanguage *language);++/**+ * Set the ranges of text that the parser should include when parsing.+ *+ * By default, the parser will always include entire documents. This function+ * allows you to parse only a *portion* of a document but still return a syntax+ * tree whose ranges match up with the document as a whole. You can also pass+ * multiple disjoint ranges.+ *+ * The second and third parameters specify the location and length of an array+ * of ranges. The parser does *not* take ownership of these ranges; it copies+ * the data, so it doesn't matter how these ranges are allocated.+ *+ * If `count` is zero, then the entire document will be parsed. Otherwise,+ * the given ranges must be ordered from earliest to latest in the document,+ * and they must not overlap. That is, the following must hold for all:+ *+ * `i < count - 1`: `ranges[i].end_byte <= ranges[i + 1].start_byte`+ *+ * If this requirement is not satisfied, the operation will fail, the ranges+ * will not be assigned, and this function will return `false`. On success,+ * this function returns `true`+ */+bool ts_parser_set_included_ranges(+ TSParser *self,+ const TSRange *ranges,+ uint32_t count+);++/**+ * Get the ranges of text that the parser will include when parsing.+ *+ * The returned pointer is owned by the parser. The caller should not free it+ * or write to it. The length of the array will be written to the given+ * `count` pointer.+ */+const TSRange *ts_parser_included_ranges(+ const TSParser *self,+ uint32_t *count+);++/**+ * Use the parser to parse some source code and create a syntax tree.+ *+ * If you are parsing this document for the first time, pass `NULL` for the+ * `old_tree` parameter. Otherwise, if you have already parsed an earlier+ * version of this document and the document has since been edited, pass the+ * previous syntax tree so that the unchanged parts of it can be reused.+ * This will save time and memory. For this to work correctly, you must have+ * already edited the old syntax tree using the [`ts_tree_edit`] function in a+ * way that exactly matches the source code changes.+ *+ * The [`TSInput`] parameter lets you specify how to read the text. It has the+ * following three fields:+ * 1. [`read`]: A function to retrieve a chunk of text at a given byte offset+ * and (row, column) position. The function should return a pointer to the+ * text and write its length to the [`bytes_read`] pointer. The parser does+ * not take ownership of this buffer; it just borrows it until it has+ * finished reading it. The function should write a zero value to the+ * [`bytes_read`] pointer to indicate the end of the document.+ * 2. [`payload`]: An arbitrary pointer that will be passed to each invocation+ * of the [`read`] function.+ * 3. [`encoding`]: An indication of how the text is encoded. Either+ * `TSInputEncodingUTF8` or `TSInputEncodingUTF16`.+ *+ * This function returns a syntax tree on success, and `NULL` on failure. There+ * are three possible reasons for failure:+ * 1. The parser does not have a language assigned. Check for this using the+ [`ts_parser_language`] function.+ * 2. Parsing was cancelled due to a timeout that was set by an earlier call to+ * the [`ts_parser_set_timeout_micros`] function. You can resume parsing from+ * where the parser left out by calling [`ts_parser_parse`] again with the+ * same arguments. Or you can start parsing from scratch by first calling+ * [`ts_parser_reset`].+ * 3. Parsing was cancelled using a cancellation flag that was set by an+ * earlier call to [`ts_parser_set_cancellation_flag`]. You can resume parsing+ * from where the parser left out by calling [`ts_parser_parse`] again with+ * the same arguments.+ *+ * [`read`]: TSInput::read+ * [`payload`]: TSInput::payload+ * [`encoding`]: TSInput::encoding+ * [`bytes_read`]: TSInput::read+ */+TSTree *ts_parser_parse(+ TSParser *self,+ const TSTree *old_tree,+ TSInput input+);++/**+ * Use the parser to parse some source code stored in one contiguous buffer.+ * The first two parameters are the same as in the [`ts_parser_parse`] function+ * above. The second two parameters indicate the location of the buffer and its+ * length in bytes.+ */+TSTree *ts_parser_parse_string(+ TSParser *self,+ const TSTree *old_tree,+ const char *string,+ uint32_t length+);++/**+ * Use the parser to parse some source code stored in one contiguous buffer with+ * a given encoding. The first four parameters work the same as in the+ * [`ts_parser_parse_string`] method above. The final parameter indicates whether+ * the text is encoded as UTF8 or UTF16.+ */+TSTree *ts_parser_parse_string_encoding(+ TSParser *self,+ const TSTree *old_tree,+ const char *string,+ uint32_t length,+ TSInputEncoding encoding+);++/**+ * Instruct the parser to start the next parse from the beginning.+ *+ * If the parser previously failed because of a timeout or a cancellation, then+ * by default, it will resume where it left off on the next call to+ * [`ts_parser_parse`] or other parsing functions. If you don't want to resume,+ * and instead intend to use this parser to parse some other document, you must+ * call [`ts_parser_reset`] first.+ */+void ts_parser_reset(TSParser *self);++/**+ * Set the maximum duration in microseconds that parsing should be allowed to+ * take before halting.+ *+ * If parsing takes longer than this, it will halt early, returning NULL.+ * See [`ts_parser_parse`] for more information.+ */+void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros);++/**+ * Get the duration in microseconds that parsing is allowed to take.+ */+uint64_t ts_parser_timeout_micros(const TSParser *self);++/**+ * Set the parser's current cancellation flag pointer.+ *+ * If a non-null pointer is assigned, then the parser will periodically read+ * from this pointer during parsing. If it reads a non-zero value, it will+ * halt early, returning NULL. See [`ts_parser_parse`] for more information.+ */+void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag);++/**+ * Get the parser's current cancellation flag pointer.+ */+const size_t *ts_parser_cancellation_flag(const TSParser *self);++/**+ * Set the logger that a parser should use during parsing.+ *+ * The parser does not take ownership over the logger payload. If a logger was+ * previously assigned, the caller is responsible for releasing any memory+ * owned by the previous logger.+ */+void ts_parser_set_logger(TSParser *self, TSLogger logger);++/**+ * Get the parser's current logger.+ */+TSLogger ts_parser_logger(const TSParser *self);++/**+ * Set the file descriptor to which the parser should write debugging graphs+ * during parsing. The graphs are formatted in the DOT language. You may want+ * to pipe these graphs directly to a `dot(1)` process in order to generate+ * SVG output. You can turn off this logging by passing a negative number.+ */+void ts_parser_print_dot_graphs(TSParser *self, int fd);++/******************/+/* Section - Tree */+/******************/++/**+ * Create a shallow copy of the syntax tree. This is very fast.+ *+ * You need to copy a syntax tree in order to use it on more than one thread at+ * a time, as syntax trees are not thread safe.+ */+TSTree *ts_tree_copy(const TSTree *self);++/**+ * Delete the syntax tree, freeing all of the memory that it used.+ */+void ts_tree_delete(TSTree *self);++/**+ * Get the root node of the syntax tree.+ */+TSNode ts_tree_root_node(const TSTree *self);++/**+ * Get the root node of the syntax tree, but with its position+ * shifted forward by the given offset.+ */+TSNode ts_tree_root_node_with_offset(+ const TSTree *self,+ uint32_t offset_bytes,+ TSPoint offset_extent+);++/**+ * Get the language that was used to parse the syntax tree.+ */+const TSLanguage *ts_tree_language(const TSTree *self);++/**+ * Get the array of included ranges that was used to parse the syntax tree.+ *+ * The returned pointer must be freed by the caller.+ */+TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length);++/**+ * Edit the syntax tree to keep it in sync with source code that has been+ * edited.+ *+ * You must describe the edit both in terms of byte offsets and in terms of+ * (row, column) coordinates.+ */+void ts_tree_edit(TSTree *self, const TSInputEdit *edit);++/**+ * Compare an old edited syntax tree to a new syntax tree representing the same+ * document, returning an array of ranges whose syntactic structure has changed.+ *+ * For this to work correctly, the old syntax tree must have been edited such+ * that its ranges match up to the new tree. Generally, you'll want to call+ * this function right after calling one of the [`ts_parser_parse`] functions.+ * You need to pass the old tree that was passed to parse, as well as the new+ * tree that was returned from that function.+ *+ * The returned array is allocated using `malloc` and the caller is responsible+ * for freeing it using `free`. The length of the array will be written to the+ * given `length` pointer.+ */+TSRange *ts_tree_get_changed_ranges(+ const TSTree *old_tree,+ const TSTree *new_tree,+ uint32_t *length+);++/**+ * Write a DOT graph describing the syntax tree to the given file.+ */+void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor);++/******************/+/* Section - Node */+/******************/++/**+ * Get the node's type as a null-terminated string.+ */+const char *ts_node_type(TSNode self);++/**+ * Get the node's type as a numerical id.+ */+TSSymbol ts_node_symbol(TSNode self);++/**+ * Get the node's language.+ */+const TSLanguage *ts_node_language(TSNode self);++/**+ * Get the node's type as it appears in the grammar ignoring aliases as a+ * null-terminated string.+ */+const char *ts_node_grammar_type(TSNode self);++/**+ * Get the node's type as a numerical id as it appears in the grammar ignoring+ * aliases. This should be used in [`ts_language_next_state`] instead of+ * [`ts_node_symbol`].+ */+TSSymbol ts_node_grammar_symbol(TSNode self);++/**+ * Get the node's start byte.+ */+uint32_t ts_node_start_byte(TSNode self);++/**+ * Get the node's start position in terms of rows and columns.+ */+TSPoint ts_node_start_point(TSNode self);++/**+ * Get the node's end byte.+ */+uint32_t ts_node_end_byte(TSNode self);++/**+ * Get the node's end position in terms of rows and columns.+ */+TSPoint ts_node_end_point(TSNode self);++/**+ * Get an S-expression representing the node as a string.+ *+ * This string is allocated with `malloc` and the caller is responsible for+ * freeing it using `free`.+ */+char *ts_node_string(TSNode self);++/**+ * Check if the node is null. Functions like [`ts_node_child`] and+ * [`ts_node_next_sibling`] will return a null node to indicate that no such node+ * was found.+ */+bool ts_node_is_null(TSNode self);++/**+ * Check if the node is *named*. Named nodes correspond to named rules in the+ * grammar, whereas *anonymous* nodes correspond to string literals in the+ * grammar.+ */+bool ts_node_is_named(TSNode self);++/**+ * Check if the node is *missing*. Missing nodes are inserted by the parser in+ * order to recover from certain kinds of syntax errors.+ */+bool ts_node_is_missing(TSNode self);++/**+ * Check if the node is *extra*. Extra nodes represent things like comments,+ * which are not required the grammar, but can appear anywhere.+ */+bool ts_node_is_extra(TSNode self);++/**+ * Check if a syntax node has been edited.+ */+bool ts_node_has_changes(TSNode self);++/**+ * Check if the node is a syntax error or contains any syntax errors.+ */+bool ts_node_has_error(TSNode self);++/**+ * Check if the node is a syntax error.+*/+bool ts_node_is_error(TSNode self);++/**+ * Get this node's parse state.+*/+TSStateId ts_node_parse_state(TSNode self);++/**+ * Get the parse state after this node.+*/+TSStateId ts_node_next_parse_state(TSNode self);++/**+ * Get the node's immediate parent.+ * Prefer [`ts_node_child_containing_descendant`] for+ * iterating over the node's ancestors.+ */+TSNode ts_node_parent(TSNode self);++/**+ * @deprecated use [`ts_node_contains_descendant`] instead, this will be removed in 0.25+ *+ * Get the node's child containing `descendant`. This will not return+ * the descendant if it is a direct child of `self`, for that use+ * `ts_node_contains_descendant`.+ */+TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant);++/**+ * Get the node that contains `descendant`.+ *+ * Note that this can return `descendant` itself, unlike the deprecated function+ * [`ts_node_child_containing_descendant`].+ */+TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant);++/**+ * Get the node's child at the given index, where zero represents the first+ * child.+ */+TSNode ts_node_child(TSNode self, uint32_t child_index);++/**+ * Get the field name for node's child at the given index, where zero represents+ * the first child. Returns NULL, if no field is found.+ */+const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index);++/**+ * Get the field name for node's named child at the given index, where zero+ * represents the first named child. Returns NULL, if no field is found.+ */+const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index);++/**+ * Get the node's number of children.+ */+uint32_t ts_node_child_count(TSNode self);++/**+ * Get the node's *named* child at the given index.+ *+ * See also [`ts_node_is_named`].+ */+TSNode ts_node_named_child(TSNode self, uint32_t child_index);++/**+ * Get the node's number of *named* children.+ *+ * See also [`ts_node_is_named`].+ */+uint32_t ts_node_named_child_count(TSNode self);++/**+ * Get the node's child with the given field name.+ */+TSNode ts_node_child_by_field_name(+ TSNode self,+ const char *name,+ uint32_t name_length+);++/**+ * Get the node's child with the given numerical field id.+ *+ * You can convert a field name to an id using the+ * [`ts_language_field_id_for_name`] function.+ */+TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id);++/**+ * Get the node's next / previous sibling.+ */+TSNode ts_node_next_sibling(TSNode self);+TSNode ts_node_prev_sibling(TSNode self);++/**+ * Get the node's next / previous *named* sibling.+ */+TSNode ts_node_next_named_sibling(TSNode self);+TSNode ts_node_prev_named_sibling(TSNode self);++/**+ * Get the node's first child that extends beyond the given byte offset.+ */+TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte);++/**+ * Get the node's first named child that extends beyond the given byte offset.+ */+TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte);++/**+ * Get the node's number of descendants, including one for the node itself.+ */+uint32_t ts_node_descendant_count(TSNode self);++/**+ * Get the smallest node within this node that spans the given range of bytes+ * or (row, column) positions.+ */+TSNode ts_node_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);+TSNode ts_node_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);++/**+ * Get the smallest named node within this node that spans the given range of+ * bytes or (row, column) positions.+ */+TSNode ts_node_named_descendant_for_byte_range(TSNode self, uint32_t start, uint32_t end);+TSNode ts_node_named_descendant_for_point_range(TSNode self, TSPoint start, TSPoint end);++/**+ * Edit the node to keep it in-sync with source code that has been edited.+ *+ * This function is only rarely needed. When you edit a syntax tree with the+ * [`ts_tree_edit`] function, all of the nodes that you retrieve from the tree+ * afterward will already reflect the edit. You only need to use [`ts_node_edit`]+ * when you have a [`TSNode`] instance that you want to keep and continue to use+ * after an edit.+ */+void ts_node_edit(TSNode *self, const TSInputEdit *edit);++/**+ * Check if two nodes are identical.+ */+bool ts_node_eq(TSNode self, TSNode other);++/************************/+/* Section - TreeCursor */+/************************/++/**+ * Create a new tree cursor starting from the given node.+ *+ * A tree cursor allows you to walk a syntax tree more efficiently than is+ * possible using the [`TSNode`] functions. It is a mutable object that is always+ * on a certain syntax node, and can be moved imperatively to different nodes.+ */+TSTreeCursor ts_tree_cursor_new(TSNode node);++/**+ * Delete a tree cursor, freeing all of the memory that it used.+ */+void ts_tree_cursor_delete(TSTreeCursor *self);++/**+ * Re-initialize a tree cursor to start at the original node that the cursor was+ * constructed with.+ */+void ts_tree_cursor_reset(TSTreeCursor *self, TSNode node);++/**+ * Re-initialize a tree cursor to the same position as another cursor.+ *+ * Unlike [`ts_tree_cursor_reset`], this will not lose parent information and+ * allows reusing already created cursors.+*/+void ts_tree_cursor_reset_to(TSTreeCursor *dst, const TSTreeCursor *src);++/**+ * Get the tree cursor's current node.+ */+TSNode ts_tree_cursor_current_node(const TSTreeCursor *self);++/**+ * Get the field name of the tree cursor's current node.+ *+ * This returns `NULL` if the current node doesn't have a field.+ * See also [`ts_node_child_by_field_name`].+ */+const char *ts_tree_cursor_current_field_name(const TSTreeCursor *self);++/**+ * Get the field id of the tree cursor's current node.+ *+ * This returns zero if the current node doesn't have a field.+ * See also [`ts_node_child_by_field_id`], [`ts_language_field_id_for_name`].+ */+TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *self);++/**+ * Move the cursor to the parent of its current node.+ *+ * This returns `true` if the cursor successfully moved, and returns `false`+ * if there was no parent node (the cursor was already on the root node).+ */+bool ts_tree_cursor_goto_parent(TSTreeCursor *self);++/**+ * Move the cursor to the next sibling of its current node.+ *+ * This returns `true` if the cursor successfully moved, and returns `false`+ * if there was no next sibling node.+ */+bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self);++/**+ * Move the cursor to the previous sibling of its current node.+ *+ * This returns `true` if the cursor successfully moved, and returns `false` if+ * there was no previous sibling node.+ *+ * Note, that this function may be slower than+ * [`ts_tree_cursor_goto_next_sibling`] due to how node positions are stored. In+ * the worst case, this will need to iterate through all the children upto the+ * previous sibling node to recalculate its position.+ */+bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self);++/**+ * Move the cursor to the first child of its current node.+ *+ * This returns `true` if the cursor successfully moved, and returns `false`+ * if there were no children.+ */+bool ts_tree_cursor_goto_first_child(TSTreeCursor *self);++/**+ * Move the cursor to the last child of its current node.+ *+ * This returns `true` if the cursor successfully moved, and returns `false` if+ * there were no children.+ *+ * Note that this function may be slower than [`ts_tree_cursor_goto_first_child`]+ * because it needs to iterate through all the children to compute the child's+ * position.+ */+bool ts_tree_cursor_goto_last_child(TSTreeCursor *self);++/**+ * Move the cursor to the node that is the nth descendant of+ * the original node that the cursor was constructed with, where+ * zero represents the original node itself.+ */+void ts_tree_cursor_goto_descendant(TSTreeCursor *self, uint32_t goal_descendant_index);++/**+ * Get the index of the cursor's current node out of all of the+ * descendants of the original node that the cursor was constructed with.+ */+uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *self);++/**+ * Get the depth of the cursor's current node relative to the original+ * node that the cursor was constructed with.+ */+uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *self);++/**+ * Move the cursor to the first child of its current node that extends beyond+ * the given byte offset or point.+ *+ * This returns the index of the child node if one was found, and returns -1+ * if no such child was found.+ */+int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte);+int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point);++TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *cursor);++/*******************/+/* Section - Query */+/*******************/++/**+ * Create a new query from a string containing one or more S-expression+ * patterns. The query is associated with a particular language, and can+ * only be run on syntax nodes parsed with that language.+ *+ * If all of the given patterns are valid, this returns a [`TSQuery`].+ * If a pattern is invalid, this returns `NULL`, and provides two pieces+ * of information about the problem:+ * 1. The byte offset of the error is written to the `error_offset` parameter.+ * 2. The type of error is written to the `error_type` parameter.+ */+TSQuery *ts_query_new(+ const TSLanguage *language,+ const char *source,+ uint32_t source_len,+ uint32_t *error_offset,+ TSQueryError *error_type+);++/**+ * Delete a query, freeing all of the memory that it used.+ */+void ts_query_delete(TSQuery *self);++/**+ * Get the number of patterns, captures, or string literals in the query.+ */+uint32_t ts_query_pattern_count(const TSQuery *self);+uint32_t ts_query_capture_count(const TSQuery *self);+uint32_t ts_query_string_count(const TSQuery *self);++/**+ * Get the byte offset where the given pattern starts in the query's source.+ *+ * This can be useful when combining queries by concatenating their source+ * code strings.+ */+uint32_t ts_query_start_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);++/**+ * Get the byte offset where the given pattern ends in the query's source.+ *+ * This can be useful when combining queries by concatenating their source+ * code strings.+ */+uint32_t ts_query_end_byte_for_pattern(const TSQuery *self, uint32_t pattern_index);++/**+ * Get all of the predicates for the given pattern in the query.+ *+ * The predicates are represented as a single array of steps. There are three+ * types of steps in this array, which correspond to the three legal values for+ * the `type` field:+ * - `TSQueryPredicateStepTypeCapture` - Steps with this type represent names+ * of captures. Their `value_id` can be used with the+ * [`ts_query_capture_name_for_id`] function to obtain the name of the capture.+ * - `TSQueryPredicateStepTypeString` - Steps with this type represent literal+ * strings. Their `value_id` can be used with the+ * [`ts_query_string_value_for_id`] function to obtain their string value.+ * - `TSQueryPredicateStepTypeDone` - Steps with this type are *sentinels*+ * that represent the end of an individual predicate. If a pattern has two+ * predicates, then there will be two steps with this `type` in the array.+ */+const TSQueryPredicateStep *ts_query_predicates_for_pattern(+ const TSQuery *self,+ uint32_t pattern_index,+ uint32_t *step_count+);++/*+ * Check if the given pattern in the query has a single root node.+ */+bool ts_query_is_pattern_rooted(const TSQuery *self, uint32_t pattern_index);++/*+ * Check if the given pattern in the query is 'non local'.+ *+ * A non-local pattern has multiple root nodes and can match within a+ * repeating sequence of nodes, as specified by the grammar. Non-local+ * patterns disable certain optimizations that would otherwise be possible+ * when executing a query on a specific range of a syntax tree.+ */+bool ts_query_is_pattern_non_local(const TSQuery *self, uint32_t pattern_index);++/*+ * Check if a given pattern is guaranteed to match once a given step is reached.+ * The step is specified by its byte offset in the query's source code.+ */+bool ts_query_is_pattern_guaranteed_at_step(const TSQuery *self, uint32_t byte_offset);++/**+ * Get the name and length of one of the query's captures, or one of the+ * query's string literals. Each capture and string is associated with a+ * numeric id based on the order that it appeared in the query's source.+ */+const char *ts_query_capture_name_for_id(+ const TSQuery *self,+ uint32_t index,+ uint32_t *length+);++/**+ * Get the quantifier of the query's captures. Each capture is * associated+ * with a numeric id based on the order that it appeared in the query's source.+ */+TSQuantifier ts_query_capture_quantifier_for_id(+ const TSQuery *self,+ uint32_t pattern_index,+ uint32_t capture_index+);++const char *ts_query_string_value_for_id(+ const TSQuery *self,+ uint32_t index,+ uint32_t *length+);++/**+ * Disable a certain capture within a query.+ *+ * This prevents the capture from being returned in matches, and also avoids+ * any resource usage associated with recording the capture. Currently, there+ * is no way to undo this.+ */+void ts_query_disable_capture(TSQuery *self, const char *name, uint32_t length);++/**+ * Disable a certain pattern within a query.+ *+ * This prevents the pattern from matching and removes most of the overhead+ * associated with the pattern. Currently, there is no way to undo this.+ */+void ts_query_disable_pattern(TSQuery *self, uint32_t pattern_index);++/**+ * Create a new cursor for executing a given query.+ *+ * The cursor stores the state that is needed to iteratively search+ * for matches. To use the query cursor, first call [`ts_query_cursor_exec`]+ * to start running a given query on a given syntax node. Then, there are+ * two options for consuming the results of the query:+ * 1. Repeatedly call [`ts_query_cursor_next_match`] to iterate over all of the+ * *matches* in the order that they were found. Each match contains the+ * index of the pattern that matched, and an array of captures. Because+ * multiple patterns can match the same set of nodes, one match may contain+ * captures that appear *before* some of the captures from a previous match.+ * 2. Repeatedly call [`ts_query_cursor_next_capture`] to iterate over all of the+ * individual *captures* in the order that they appear. This is useful if+ * don't care about which pattern matched, and just want a single ordered+ * sequence of captures.+ *+ * If you don't care about consuming all of the results, you can stop calling+ * [`ts_query_cursor_next_match`] or [`ts_query_cursor_next_capture`] at any point.+ * You can then start executing another query on another node by calling+ * [`ts_query_cursor_exec`] again.+ */+TSQueryCursor *ts_query_cursor_new(void);++/**+ * Delete a query cursor, freeing all of the memory that it used.+ */+void ts_query_cursor_delete(TSQueryCursor *self);++/**+ * Start running a given query on a given node.+ */+void ts_query_cursor_exec(TSQueryCursor *self, const TSQuery *query, TSNode node);++/**+ * Manage the maximum number of in-progress matches allowed by this query+ * cursor.+ *+ * Query cursors have an optional maximum capacity for storing lists of+ * in-progress captures. If this capacity is exceeded, then the+ * earliest-starting match will silently be dropped to make room for further+ * matches. This maximum capacity is optional — by default, query cursors allow+ * any number of pending matches, dynamically allocating new space for them as+ * needed as the query is executed.+ */+bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self);+uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self);+void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit);++/**+ * Set the maximum duration in microseconds that query execution should be allowed to+ * take before halting.+ *+ * If query execution takes longer than this, it will halt early, returning NULL.+ * See [`ts_query_cursor_next_match`] or [`ts_query_cursor_next_capture`] for more information.+ */+void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros);++/**+ * Get the duration in microseconds that query execution is allowed to take.+ *+ * This is set via [`ts_query_cursor_set_timeout_micros`].+ */+uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self);++/**+ * Set the range of bytes or (row, column) positions in which the query+ * will be executed.+ */+void ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte);+void ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point);++/**+ * Advance to the next match of the currently running query.+ *+ * If there is a match, write it to `*match` and return `true`.+ * Otherwise, return `false`.+ */+bool ts_query_cursor_next_match(TSQueryCursor *self, TSQueryMatch *match);+void ts_query_cursor_remove_match(TSQueryCursor *self, uint32_t match_id);++/**+ * Advance to the next capture of the currently running query.+ *+ * If there is a capture, write its match to `*match` and its index within+ * the matche's capture list to `*capture_index`. Otherwise, return `false`.+ */+bool ts_query_cursor_next_capture(+ TSQueryCursor *self,+ TSQueryMatch *match,+ uint32_t *capture_index+);++/**+ * Set the maximum start depth for a query cursor.+ *+ * This prevents cursors from exploring children nodes at a certain depth.+ * Note if a pattern includes many children, then they will still be checked.+ *+ * The zero max start depth value can be used as a special behavior and+ * it helps to destructure a subtree by staying on a node and using captures+ * for interested parts. Note that the zero max start depth only limit a search+ * depth for a pattern's root node but other nodes that are parts of the pattern+ * may be searched at any depth what defined by the pattern structure.+ *+ * Set to `UINT32_MAX` to remove the maximum start depth.+ */+void ts_query_cursor_set_max_start_depth(TSQueryCursor *self, uint32_t max_start_depth);++/**********************/+/* Section - Language */+/**********************/++/**+ * Get another reference to the given language.+ */+const TSLanguage *ts_language_copy(const TSLanguage *self);++/**+ * Free any dynamically-allocated resources for this language, if+ * this is the last reference.+ */+void ts_language_delete(const TSLanguage *self);++/**+ * Get the number of distinct node types in the language.+ */+uint32_t ts_language_symbol_count(const TSLanguage *self);++/**+ * Get the number of valid states in this language.+*/+uint32_t ts_language_state_count(const TSLanguage *self);++/**+ * Get a node type string for the given numerical id.+ */+const char *ts_language_symbol_name(const TSLanguage *self, TSSymbol symbol);++/**+ * Get the numerical id for the given node type string.+ */+TSSymbol ts_language_symbol_for_name(+ const TSLanguage *self,+ const char *string,+ uint32_t length,+ bool is_named+);++/**+ * Get the number of distinct field names in the language.+ */+uint32_t ts_language_field_count(const TSLanguage *self);++/**+ * Get the field name string for the given numerical id.+ */+const char *ts_language_field_name_for_id(const TSLanguage *self, TSFieldId id);++/**+ * Get the numerical id for the given field name string.+ */+TSFieldId ts_language_field_id_for_name(const TSLanguage *self, const char *name, uint32_t name_length);++/**+ * Check whether the given node type id belongs to named nodes, anonymous nodes,+ * or a hidden nodes.+ *+ * See also [`ts_node_is_named`]. Hidden nodes are never returned from the API.+ */+TSSymbolType ts_language_symbol_type(const TSLanguage *self, TSSymbol symbol);++/**+ * Get the ABI version number for this language. This version number is used+ * to ensure that languages were generated by a compatible version of+ * Tree-sitter.+ *+ * See also [`ts_parser_set_language`].+ */+uint32_t ts_language_version(const TSLanguage *self);++/**+ * Get the next parse state. Combine this with lookahead iterators to generate+ * completion suggestions or valid symbols in error nodes. Use+ * [`ts_node_grammar_symbol`] for valid symbols.+*/+TSStateId ts_language_next_state(const TSLanguage *self, TSStateId state, TSSymbol symbol);++/********************************/+/* Section - Lookahead Iterator */+/********************************/++/**+ * Create a new lookahead iterator for the given language and parse state.+ *+ * This returns `NULL` if state is invalid for the language.+ *+ * Repeatedly using [`ts_lookahead_iterator_next`] and+ * [`ts_lookahead_iterator_current_symbol`] will generate valid symbols in the+ * given parse state. Newly created lookahead iterators will contain the `ERROR`+ * symbol.+ *+ * Lookahead iterators can be useful to generate suggestions and improve syntax+ * error diagnostics. To get symbols valid in an ERROR node, use the lookahead+ * iterator on its first leaf node state. For `MISSING` nodes, a lookahead+ * iterator created on the previous non-extra leaf node may be appropriate.+*/+TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state);++/**+ * Delete a lookahead iterator freeing all the memory used.+*/+void ts_lookahead_iterator_delete(TSLookaheadIterator *self);++/**+ * Reset the lookahead iterator to another state.+ *+ * This returns `true` if the iterator was reset to the given state and `false`+ * otherwise.+*/+bool ts_lookahead_iterator_reset_state(TSLookaheadIterator *self, TSStateId state);++/**+ * Reset the lookahead iterator.+ *+ * This returns `true` if the language was set successfully and `false`+ * otherwise.+*/+bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state);++/**+ * Get the current language of the lookahead iterator.+*/+const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self);++/**+ * Advance the lookahead iterator to the next symbol.+ *+ * This returns `true` if there is a new symbol and `false` otherwise.+*/+bool ts_lookahead_iterator_next(TSLookaheadIterator *self);++/**+ * Get the current symbol of the lookahead iterator;+*/+TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self);++/**+ * Get the current symbol type of the lookahead iterator as a null terminated+ * string.+*/+const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self);++/*************************************/+/* Section - WebAssembly Integration */+/************************************/++typedef struct wasm_engine_t TSWasmEngine;+typedef struct TSWasmStore TSWasmStore;++typedef enum {+ TSWasmErrorKindNone = 0,+ TSWasmErrorKindParse,+ TSWasmErrorKindCompile,+ TSWasmErrorKindInstantiate,+ TSWasmErrorKindAllocate,+} TSWasmErrorKind;++typedef struct {+ TSWasmErrorKind kind;+ char *message;+} TSWasmError;++/**+ * Create a Wasm store.+ */+TSWasmStore *ts_wasm_store_new(+ TSWasmEngine *engine,+ TSWasmError *error+);++/**+ * Free the memory associated with the given Wasm store.+ */+void ts_wasm_store_delete(TSWasmStore *);++/**+ * Create a language from a buffer of Wasm. The resulting language behaves+ * like any other Tree-sitter language, except that in order to use it with+ * a parser, that parser must have a Wasm store. Note that the language+ * can be used with any Wasm store, it doesn't need to be the same store that+ * was used to originally load it.+ */+const TSLanguage *ts_wasm_store_load_language(+ TSWasmStore *,+ const char *name,+ const char *wasm,+ uint32_t wasm_len,+ TSWasmError *error+);++/**+ * Get the number of languages instantiated in the given wasm store.+ */+size_t ts_wasm_store_language_count(const TSWasmStore *);++/**+ * Check if the language came from a Wasm module. If so, then in order to use+ * this language with a Parser, that parser must have a Wasm store assigned.+ */+bool ts_language_is_wasm(const TSLanguage *);++/**+ * Assign the given Wasm store to the parser. A parser must have a Wasm store+ * in order to use Wasm languages.+ */+void ts_parser_set_wasm_store(TSParser *, TSWasmStore *);++/**+ * Remove the parser's current Wasm store and return it. This returns NULL if+ * the parser doesn't have a Wasm store.+ */+TSWasmStore *ts_parser_take_wasm_store(TSParser *);++/**********************************/+/* Section - Global Configuration */+/**********************************/++/**+ * Set the allocation functions used by the library.+ *+ * By default, Tree-sitter uses the standard libc allocation functions,+ * but aborts the process when an allocation fails. This function lets+ * you supply alternative allocation functions at runtime.+ *+ * If you pass `NULL` for any parameter, Tree-sitter will switch back to+ * its default implementation of that function.+ *+ * If you call this function after the library has already been used, then+ * you must ensure that either:+ * 1. All the existing objects have been freed.+ * 2. The new allocator shares its state with the old one, so it is capable+ * of freeing memory that was allocated by the old allocator.+ */+void ts_set_allocator(+ void *(*new_malloc)(size_t),+ void *(*new_calloc)(size_t, size_t),+ void *(*new_realloc)(void *, size_t),+ void (*new_free)(void *)+);++#ifdef __cplusplus+}+#endif++#ifndef TREE_SITTER_HIDE_SYMBOLS+#if defined(__GNUC__) || defined(__clang__)+#pragma GCC visibility pop+#endif+#endif++#endif // TREE_SITTER_API_H_
+ vendor/tree-sitter/lib/src/alloc.c view
@@ -0,0 +1,48 @@+#include "alloc.h"+#include "tree_sitter/api.h"+#include <stdlib.h>++static void *ts_malloc_default(size_t size) {+ void *result = malloc(size);+ if (size > 0 && !result) {+ fprintf(stderr, "tree-sitter failed to allocate %zu bytes", size);+ abort();+ }+ return result;+}++static void *ts_calloc_default(size_t count, size_t size) {+ void *result = calloc(count, size);+ if (count > 0 && !result) {+ fprintf(stderr, "tree-sitter failed to allocate %zu bytes", count * size);+ abort();+ }+ return result;+}++static void *ts_realloc_default(void *buffer, size_t size) {+ void *result = realloc(buffer, size);+ if (size > 0 && !result) {+ fprintf(stderr, "tree-sitter failed to reallocate %zu bytes", size);+ abort();+ }+ return result;+}++// Allow clients to override allocation functions dynamically+TS_PUBLIC void *(*ts_current_malloc)(size_t) = ts_malloc_default;+TS_PUBLIC void *(*ts_current_calloc)(size_t, size_t) = ts_calloc_default;+TS_PUBLIC void *(*ts_current_realloc)(void *, size_t) = ts_realloc_default;+TS_PUBLIC void (*ts_current_free)(void *) = free;++void ts_set_allocator(+ void *(*new_malloc)(size_t size),+ void *(*new_calloc)(size_t count, size_t size),+ void *(*new_realloc)(void *ptr, size_t size),+ void (*new_free)(void *ptr)+) {+ ts_current_malloc = new_malloc ? new_malloc : ts_malloc_default;+ ts_current_calloc = new_calloc ? new_calloc : ts_calloc_default;+ ts_current_realloc = new_realloc ? new_realloc : ts_realloc_default;+ ts_current_free = new_free ? new_free : free;+}
+ vendor/tree-sitter/lib/src/alloc.h view
@@ -0,0 +1,41 @@+#ifndef TREE_SITTER_ALLOC_H_+#define TREE_SITTER_ALLOC_H_++#ifdef __cplusplus+extern "C" {+#endif++#include <stdbool.h>+#include <stdio.h>+#include <stdlib.h>++#if defined(TREE_SITTER_HIDDEN_SYMBOLS) || defined(_WIN32)+#define TS_PUBLIC+#else+#define TS_PUBLIC __attribute__((visibility("default")))+#endif++TS_PUBLIC extern void *(*ts_current_malloc)(size_t size);+TS_PUBLIC extern void *(*ts_current_calloc)(size_t count, size_t size);+TS_PUBLIC extern void *(*ts_current_realloc)(void *ptr, size_t size);+TS_PUBLIC extern void (*ts_current_free)(void *ptr);++// Allow clients to override allocation functions+#ifndef ts_malloc+#define ts_malloc ts_current_malloc+#endif+#ifndef ts_calloc+#define ts_calloc ts_current_calloc+#endif+#ifndef ts_realloc+#define ts_realloc ts_current_realloc+#endif+#ifndef ts_free+#define ts_free ts_current_free+#endif++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_ALLOC_H_
+ vendor/tree-sitter/lib/src/array.h view
@@ -0,0 +1,290 @@+#ifndef TREE_SITTER_ARRAY_H_+#define TREE_SITTER_ARRAY_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./alloc.h"+#include "./ts_assert.h"++#include <stdbool.h>+#include <stdint.h>+#include <stdlib.h>+#include <string.h>++#ifdef _MSC_VER+#pragma warning(disable : 4101)+#elif defined(__GNUC__) || defined(__clang__)+#pragma GCC diagnostic push+#pragma GCC diagnostic ignored "-Wunused-variable"+#endif++#define Array(T) \+ struct { \+ T *contents; \+ uint32_t size; \+ uint32_t capacity; \+ }++/// Initialize an array.+#define array_init(self) \+ ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)++/// Create an empty array.+#define array_new() \+ { NULL, 0, 0 }++/// Get a pointer to the element at a given `index` in the array.+#define array_get(self, _index) \+ (ts_assert((uint32_t)(_index) < (self)->size), &(self)->contents[_index])++/// Get a pointer to the first element in the array.+#define array_front(self) array_get(self, 0)++/// Get a pointer to the last element in the array.+#define array_back(self) array_get(self, (self)->size - 1)++/// Clear the array, setting its size to zero. Note that this does not free any+/// memory allocated for the array's contents.+#define array_clear(self) ((self)->size = 0)++/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is+/// less than the array's current capacity, this function has no effect.+#define array_reserve(self, new_capacity) \+ _array__reserve((Array *)(self), array_elem_size(self), new_capacity)++/// Free any memory allocated for this array. Note that this does not free any+/// memory allocated for the array's contents.+#define array_delete(self) _array__delete((Array *)(self))++/// Push a new `element` onto the end of the array.+#define array_push(self, element) \+ (_array__grow((Array *)(self), 1, array_elem_size(self)), \+ (self)->contents[(self)->size++] = (element))++/// Increase the array's size by `count` elements.+/// New elements are zero-initialized.+#define array_grow_by(self, count) \+ do { \+ if ((count) == 0) break; \+ _array__grow((Array *)(self), count, array_elem_size(self)); \+ memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \+ (self)->size += (count); \+ } while (0)++/// Append all elements from one array to the end of another.+#define array_push_all(self, other) \+ array_extend((self), (other)->size, (other)->contents)++/// Append `count` elements to the end of the array, reading their values from the+/// `contents` pointer.+#define array_extend(self, count, contents) \+ _array__splice( \+ (Array *)(self), array_elem_size(self), (self)->size, \+ 0, count, contents \+ )++/// Remove `old_count` elements from the array starting at the given `index`. At+/// the same index, insert `new_count` new elements, reading their values from the+/// `new_contents` pointer.+#define array_splice(self, _index, old_count, new_count, new_contents) \+ _array__splice( \+ (Array *)(self), array_elem_size(self), _index, \+ old_count, new_count, new_contents \+ )++/// Insert one `element` into the array at the given `index`.+#define array_insert(self, _index, element) \+ _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element))++/// Remove one element from the array at the given `index`.+#define array_erase(self, _index) \+ _array__erase((Array *)(self), array_elem_size(self), _index)++/// Pop the last element off the array, returning the element by value.+#define array_pop(self) ((self)->contents[--(self)->size])++/// Assign the contents of one array to another, reallocating if necessary.+#define array_assign(self, other) \+ _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self))++/// Swap one array with another+#define array_swap(self, other) \+ _array__swap((Array *)(self), (Array *)(other))++/// Get the size of the array contents+#define array_elem_size(self) (sizeof *(self)->contents)++/// Search a sorted array for a given `needle` value, using the given `compare`+/// callback to determine the order.+///+/// If an existing element is found to be equal to `needle`, then the `index`+/// out-parameter is set to the existing value's index, and the `exists`+/// out-parameter is set to true. Otherwise, `index` is set to an index where+/// `needle` should be inserted in order to preserve the sorting, and `exists`+/// is set to false.+#define array_search_sorted_with(self, compare, needle, _index, _exists) \+ _array__search_sorted(self, 0, compare, , needle, _index, _exists)++/// Search a sorted array for a given `needle` value, using integer comparisons+/// of a given struct field (specified with a leading dot) to determine the order.+///+/// See also `array_search_sorted_with`.+#define array_search_sorted_by(self, field, needle, _index, _exists) \+ _array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)++/// Insert a given `value` into a sorted array, using the given `compare`+/// callback to determine the order.+#define array_insert_sorted_with(self, compare, value) \+ do { \+ unsigned _index, _exists; \+ array_search_sorted_with(self, compare, &(value), &_index, &_exists); \+ if (!_exists) array_insert(self, _index, value); \+ } while (0)++/// Insert a given `value` into a sorted array, using integer comparisons of+/// a given struct field (specified with a leading dot) to determine the order.+///+/// See also `array_search_sorted_by`.+#define array_insert_sorted_by(self, field, value) \+ do { \+ unsigned _index, _exists; \+ array_search_sorted_by(self, field, (value) field, &_index, &_exists); \+ if (!_exists) array_insert(self, _index, value); \+ } while (0)++// Private++typedef Array(void) Array;++/// This is not what you're looking for, see `array_delete`.+static inline void _array__delete(Array *self) {+ if (self->contents) {+ ts_free(self->contents);+ self->contents = NULL;+ self->size = 0;+ self->capacity = 0;+ }+}++/// This is not what you're looking for, see `array_erase`.+static inline void _array__erase(Array *self, size_t element_size,+ uint32_t index) {+ ts_assert(index < self->size);+ char *contents = (char *)self->contents;+ memmove(contents + index * element_size, contents + (index + 1) * element_size,+ (self->size - index - 1) * element_size);+ self->size--;+}++/// This is not what you're looking for, see `array_reserve`.+static inline void _array__reserve(Array *self, size_t element_size, uint32_t new_capacity) {+ if (new_capacity > self->capacity) {+ if (self->contents) {+ self->contents = ts_realloc(self->contents, new_capacity * element_size);+ } else {+ self->contents = ts_malloc(new_capacity * element_size);+ }+ self->capacity = new_capacity;+ }+}++/// This is not what you're looking for, see `array_assign`.+static inline void _array__assign(Array *self, const Array *other, size_t element_size) {+ _array__reserve(self, element_size, other->size);+ self->size = other->size;+ memcpy(self->contents, other->contents, self->size * element_size);+}++/// This is not what you're looking for, see `array_swap`.+static inline void _array__swap(Array *self, Array *other) {+ Array swap = *other;+ *other = *self;+ *self = swap;+}++/// This is not what you're looking for, see `array_push` or `array_grow_by`.+static inline void _array__grow(Array *self, uint32_t count, size_t element_size) {+ uint32_t new_size = self->size + count;+ if (new_size > self->capacity) {+ uint32_t new_capacity = self->capacity * 2;+ if (new_capacity < 8) new_capacity = 8;+ if (new_capacity < new_size) new_capacity = new_size;+ _array__reserve(self, element_size, new_capacity);+ }+}++/// This is not what you're looking for, see `array_splice`.+static inline void _array__splice(Array *self, size_t element_size,+ uint32_t index, uint32_t old_count,+ uint32_t new_count, const void *elements) {+ uint32_t new_size = self->size + new_count - old_count;+ uint32_t old_end = index + old_count;+ uint32_t new_end = index + new_count;+ ts_assert(old_end <= self->size);++ _array__reserve(self, element_size, new_size);++ char *contents = (char *)self->contents;+ if (self->size > old_end) {+ memmove(+ contents + new_end * element_size,+ contents + old_end * element_size,+ (self->size - old_end) * element_size+ );+ }+ if (new_count > 0) {+ if (elements) {+ memcpy(+ (contents + index * element_size),+ elements,+ new_count * element_size+ );+ } else {+ memset(+ (contents + index * element_size),+ 0,+ new_count * element_size+ );+ }+ }+ self->size += new_count - old_count;+}++/// A binary search routine, based on Rust's `std::slice::binary_search_by`.+/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.+#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \+ do { \+ *(_index) = start; \+ *(_exists) = false; \+ uint32_t size = (self)->size - *(_index); \+ if (size == 0) break; \+ int comparison; \+ while (size > 1) { \+ uint32_t half_size = size / 2; \+ uint32_t mid_index = *(_index) + half_size; \+ comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \+ if (comparison <= 0) *(_index) = mid_index; \+ size -= half_size; \+ } \+ comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \+ if (comparison == 0) *(_exists) = true; \+ else if (comparison < 0) *(_index) += 1; \+ } while (0)++/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)+/// parameter by reference in order to work with the generic sorting function above.+#define _compare_int(a, b) ((int)*(a) - (int)(b))++#ifdef _MSC_VER+#pragma warning(default : 4101)+#elif defined(__GNUC__) || defined(__clang__)+#pragma GCC diagnostic pop+#endif++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_ARRAY_H_
+ vendor/tree-sitter/lib/src/atomic.h view
@@ -0,0 +1,68 @@+#ifndef TREE_SITTER_ATOMIC_H_+#define TREE_SITTER_ATOMIC_H_++#include <stddef.h>+#include <stdint.h>+#include <stdlib.h>++#ifdef __TINYC__++static inline size_t atomic_load(const volatile size_t *p) {+ return *p;+}++static inline uint32_t atomic_inc(volatile uint32_t *p) {+ *p += 1;+ return *p;+}++static inline uint32_t atomic_dec(volatile uint32_t *p) {+ *p-= 1;+ return *p;+}++#elif defined(_WIN32)++#include <windows.h>++static inline size_t atomic_load(const volatile size_t *p) {+ return *p;+}++static inline uint32_t atomic_inc(volatile uint32_t *p) {+ return InterlockedIncrement((long volatile *)p);+}++static inline uint32_t atomic_dec(volatile uint32_t *p) {+ return InterlockedDecrement((long volatile *)p);+}++#else++static inline size_t atomic_load(const volatile size_t *p) {+#ifdef __ATOMIC_RELAXED+ return __atomic_load_n(p, __ATOMIC_RELAXED);+#else+ return __sync_fetch_and_add((volatile size_t *)p, 0);+#endif+}++static inline uint32_t atomic_inc(volatile uint32_t *p) {+ #ifdef __ATOMIC_RELAXED+ return __atomic_add_fetch(p, 1U, __ATOMIC_SEQ_CST);+ #else+ return __sync_add_and_fetch(p, 1U);+ #endif+}++static inline uint32_t atomic_dec(volatile uint32_t *p) {+ #ifdef __ATOMIC_RELAXED+ return __atomic_sub_fetch(p, 1U, __ATOMIC_SEQ_CST);+ #else+ return __sync_sub_and_fetch(p, 1U);+ #endif+}++#endif++#endif // TREE_SITTER_ATOMIC_H_
+ vendor/tree-sitter/lib/src/clock.h view
@@ -0,0 +1,146 @@+#ifndef TREE_SITTER_CLOCK_H_+#define TREE_SITTER_CLOCK_H_++#include <stdbool.h>+#include <stdint.h>++typedef uint64_t TSDuration;++#ifdef _WIN32++// Windows:+// * Represent a time as a performance counter value.+// * Represent a duration as a number of performance counter ticks.++#include <windows.h>+typedef uint64_t TSClock;++static inline TSDuration duration_from_micros(uint64_t micros) {+ LARGE_INTEGER frequency;+ QueryPerformanceFrequency(&frequency);+ return micros * (uint64_t)frequency.QuadPart / 1000000;+}++static inline uint64_t duration_to_micros(TSDuration self) {+ LARGE_INTEGER frequency;+ QueryPerformanceFrequency(&frequency);+ return self * 1000000 / (uint64_t)frequency.QuadPart;+}++static inline TSClock clock_null(void) {+ return 0;+}++static inline TSClock clock_now(void) {+ LARGE_INTEGER result;+ QueryPerformanceCounter(&result);+ return (uint64_t)result.QuadPart;+}++static inline TSClock clock_after(TSClock base, TSDuration duration) {+ return base + duration;+}++static inline bool clock_is_null(TSClock self) {+ return !self;+}++static inline bool clock_is_gt(TSClock self, TSClock other) {+ return self > other;+}++#elif defined(CLOCK_MONOTONIC) && !defined(__APPLE__)++// POSIX with monotonic clock support (Linux)+// * Represent a time as a monotonic (seconds, nanoseconds) pair.+// * Represent a duration as a number of microseconds.+//+// On these platforms, parse timeouts will correspond accurately to+// real time, regardless of what other processes are running.++#include <time.h>+typedef struct timespec TSClock;++static inline TSDuration duration_from_micros(uint64_t micros) {+ return micros;+}++static inline uint64_t duration_to_micros(TSDuration self) {+ return self;+}++static inline TSClock clock_now(void) {+ TSClock result;+ clock_gettime(CLOCK_MONOTONIC, &result);+ return result;+}++static inline TSClock clock_null(void) {+ return (TSClock) {0, 0};+}++static inline TSClock clock_after(TSClock base, TSDuration duration) {+ TSClock result = base;+ result.tv_sec += duration / 1000000;+ result.tv_nsec += (duration % 1000000) * 1000;+ if (result.tv_nsec >= 1000000000) {+ result.tv_nsec -= 1000000000;+ ++(result.tv_sec);+ }+ return result;+}++static inline bool clock_is_null(TSClock self) {+ return !self.tv_sec && !self.tv_nsec;+}++static inline bool clock_is_gt(TSClock self, TSClock other) {+ if (self.tv_sec > other.tv_sec) return true;+ if (self.tv_sec < other.tv_sec) return false;+ return self.tv_nsec > other.tv_nsec;+}++#else++// macOS or POSIX without monotonic clock support+// * Represent a time as a process clock value.+// * Represent a duration as a number of process clock ticks.+//+// On these platforms, parse timeouts may be affected by other processes,+// which is not ideal, but is better than using a non-monotonic time API+// like `gettimeofday`.++#include <time.h>+typedef uint64_t TSClock;++static inline TSDuration duration_from_micros(uint64_t micros) {+ return micros * (uint64_t)CLOCKS_PER_SEC / 1000000;+}++static inline uint64_t duration_to_micros(TSDuration self) {+ return self * 1000000 / (uint64_t)CLOCKS_PER_SEC;+}++static inline TSClock clock_null(void) {+ return 0;+}++static inline TSClock clock_now(void) {+ return (uint64_t)clock();+}++static inline TSClock clock_after(TSClock base, TSDuration duration) {+ return base + duration;+}++static inline bool clock_is_null(TSClock self) {+ return !self;+}++static inline bool clock_is_gt(TSClock self, TSClock other) {+ return self > other;+}++#endif++#endif // TREE_SITTER_CLOCK_H_
+ vendor/tree-sitter/lib/src/error_costs.h view
@@ -0,0 +1,11 @@+#ifndef TREE_SITTER_ERROR_COSTS_H_+#define TREE_SITTER_ERROR_COSTS_H_++#define ERROR_STATE 0+#define ERROR_COST_PER_RECOVERY 500+#define ERROR_COST_PER_MISSING_TREE 110+#define ERROR_COST_PER_SKIPPED_TREE 100+#define ERROR_COST_PER_SKIPPED_LINE 30+#define ERROR_COST_PER_SKIPPED_CHAR 1++#endif
+ vendor/tree-sitter/lib/src/get_changed_ranges.c view
@@ -0,0 +1,501 @@+#include "./get_changed_ranges.h"+#include "./subtree.h"+#include "./language.h"+#include "./error_costs.h"+#include "./tree_cursor.h"+#include "./ts_assert.h"++// #define DEBUG_GET_CHANGED_RANGES++static void ts_range_array_add(+ TSRangeArray *self,+ Length start,+ Length end+) {+ if (self->size > 0) {+ TSRange *last_range = array_back(self);+ if (start.bytes <= last_range->end_byte) {+ last_range->end_byte = end.bytes;+ last_range->end_point = end.extent;+ return;+ }+ }++ if (start.bytes < end.bytes) {+ TSRange range = { start.extent, end.extent, start.bytes, end.bytes };+ array_push(self, range);+ }+}++bool ts_range_array_intersects(+ const TSRangeArray *self,+ unsigned start_index,+ uint32_t start_byte,+ uint32_t end_byte+) {+ for (unsigned i = start_index; i < self->size; i++) {+ TSRange *range = &self->contents[i];+ if (range->end_byte > start_byte) {+ if (range->start_byte >= end_byte) break;+ return true;+ }+ }+ return false;+}++void ts_range_array_get_changed_ranges(+ const TSRange *old_ranges, unsigned old_range_count,+ const TSRange *new_ranges, unsigned new_range_count,+ TSRangeArray *differences+) {+ unsigned new_index = 0;+ unsigned old_index = 0;+ Length current_position = length_zero();+ bool in_old_range = false;+ bool in_new_range = false;++ while (old_index < old_range_count || new_index < new_range_count) {+ const TSRange *old_range = &old_ranges[old_index];+ const TSRange *new_range = &new_ranges[new_index];++ Length next_old_position;+ if (in_old_range) {+ next_old_position = (Length) {old_range->end_byte, old_range->end_point};+ } else if (old_index < old_range_count) {+ next_old_position = (Length) {old_range->start_byte, old_range->start_point};+ } else {+ next_old_position = LENGTH_MAX;+ }++ Length next_new_position;+ if (in_new_range) {+ next_new_position = (Length) {new_range->end_byte, new_range->end_point};+ } else if (new_index < new_range_count) {+ next_new_position = (Length) {new_range->start_byte, new_range->start_point};+ } else {+ next_new_position = LENGTH_MAX;+ }++ if (next_old_position.bytes < next_new_position.bytes) {+ if (in_old_range != in_new_range) {+ ts_range_array_add(differences, current_position, next_old_position);+ }+ if (in_old_range) old_index++;+ current_position = next_old_position;+ in_old_range = !in_old_range;+ } else if (next_new_position.bytes < next_old_position.bytes) {+ if (in_old_range != in_new_range) {+ ts_range_array_add(differences, current_position, next_new_position);+ }+ if (in_new_range) new_index++;+ current_position = next_new_position;+ in_new_range = !in_new_range;+ } else {+ if (in_old_range != in_new_range) {+ ts_range_array_add(differences, current_position, next_new_position);+ }+ if (in_old_range) old_index++;+ if (in_new_range) new_index++;+ in_old_range = !in_old_range;+ in_new_range = !in_new_range;+ current_position = next_new_position;+ }+ }+}++typedef struct {+ TreeCursor cursor;+ const TSLanguage *language;+ unsigned visible_depth;+ bool in_padding;+} Iterator;++static Iterator iterator_new(+ TreeCursor *cursor,+ const Subtree *tree,+ const TSLanguage *language+) {+ array_clear(&cursor->stack);+ array_push(&cursor->stack, ((TreeCursorEntry) {+ .subtree = tree,+ .position = length_zero(),+ .child_index = 0,+ .structural_child_index = 0,+ }));+ return (Iterator) {+ .cursor = *cursor,+ .language = language,+ .visible_depth = 1,+ .in_padding = false,+ };+}++static bool iterator_done(Iterator *self) {+ return self->cursor.stack.size == 0;+}++static Length iterator_start_position(Iterator *self) {+ TreeCursorEntry entry = *array_back(&self->cursor.stack);+ if (self->in_padding) {+ return entry.position;+ } else {+ return length_add(entry.position, ts_subtree_padding(*entry.subtree));+ }+}++static Length iterator_end_position(Iterator *self) {+ TreeCursorEntry entry = *array_back(&self->cursor.stack);+ Length result = length_add(entry.position, ts_subtree_padding(*entry.subtree));+ if (self->in_padding) {+ return result;+ } else {+ return length_add(result, ts_subtree_size(*entry.subtree));+ }+}++static bool iterator_tree_is_visible(const Iterator *self) {+ TreeCursorEntry entry = *array_back(&self->cursor.stack);+ if (ts_subtree_visible(*entry.subtree)) return true;+ if (self->cursor.stack.size > 1) {+ Subtree parent = *self->cursor.stack.contents[self->cursor.stack.size - 2].subtree;+ return ts_language_alias_at(+ self->language,+ parent.ptr->production_id,+ entry.structural_child_index+ ) != 0;+ }+ return false;+}++static void iterator_get_visible_state(+ const Iterator *self,+ Subtree *tree,+ TSSymbol *alias_symbol,+ uint32_t *start_byte+) {+ uint32_t i = self->cursor.stack.size - 1;++ if (self->in_padding) {+ if (i == 0) return;+ i--;+ }++ for (; i + 1 > 0; i--) {+ TreeCursorEntry entry = self->cursor.stack.contents[i];++ if (i > 0) {+ const Subtree *parent = self->cursor.stack.contents[i - 1].subtree;+ *alias_symbol = ts_language_alias_at(+ self->language,+ parent->ptr->production_id,+ entry.structural_child_index+ );+ }++ if (ts_subtree_visible(*entry.subtree) || *alias_symbol) {+ *tree = *entry.subtree;+ *start_byte = entry.position.bytes;+ break;+ }+ }+}++static void iterator_ascend(Iterator *self) {+ if (iterator_done(self)) return;+ if (iterator_tree_is_visible(self) && !self->in_padding) self->visible_depth--;+ if (array_back(&self->cursor.stack)->child_index > 0) self->in_padding = false;+ self->cursor.stack.size--;+}++static bool iterator_descend(Iterator *self, uint32_t goal_position) {+ if (self->in_padding) return false;++ bool did_descend = false;+ do {+ did_descend = false;+ TreeCursorEntry entry = *array_back(&self->cursor.stack);+ Length position = entry.position;+ uint32_t structural_child_index = 0;+ for (uint32_t i = 0, n = ts_subtree_child_count(*entry.subtree); i < n; i++) {+ const Subtree *child = &ts_subtree_children(*entry.subtree)[i];+ Length child_left = length_add(position, ts_subtree_padding(*child));+ Length child_right = length_add(child_left, ts_subtree_size(*child));++ if (child_right.bytes > goal_position) {+ array_push(&self->cursor.stack, ((TreeCursorEntry) {+ .subtree = child,+ .position = position,+ .child_index = i,+ .structural_child_index = structural_child_index,+ }));++ if (iterator_tree_is_visible(self)) {+ if (child_left.bytes > goal_position) {+ self->in_padding = true;+ } else {+ self->visible_depth++;+ }+ return true;+ }++ did_descend = true;+ break;+ }++ position = child_right;+ if (!ts_subtree_extra(*child)) structural_child_index++;+ }+ } while (did_descend);++ return false;+}++static void iterator_advance(Iterator *self) {+ if (self->in_padding) {+ self->in_padding = false;+ if (iterator_tree_is_visible(self)) {+ self->visible_depth++;+ } else {+ iterator_descend(self, 0);+ }+ return;+ }++ for (;;) {+ if (iterator_tree_is_visible(self)) self->visible_depth--;+ TreeCursorEntry entry = array_pop(&self->cursor.stack);+ if (iterator_done(self)) return;++ const Subtree *parent = array_back(&self->cursor.stack)->subtree;+ uint32_t child_index = entry.child_index + 1;+ if (ts_subtree_child_count(*parent) > child_index) {+ Length position = length_add(entry.position, ts_subtree_total_size(*entry.subtree));+ uint32_t structural_child_index = entry.structural_child_index;+ if (!ts_subtree_extra(*entry.subtree)) structural_child_index++;+ const Subtree *next_child = &ts_subtree_children(*parent)[child_index];++ array_push(&self->cursor.stack, ((TreeCursorEntry) {+ .subtree = next_child,+ .position = position,+ .child_index = child_index,+ .structural_child_index = structural_child_index,+ }));++ if (iterator_tree_is_visible(self)) {+ if (ts_subtree_padding(*next_child).bytes > 0) {+ self->in_padding = true;+ } else {+ self->visible_depth++;+ }+ } else {+ iterator_descend(self, 0);+ }+ break;+ }+ }+}++typedef enum {+ IteratorDiffers,+ IteratorMayDiffer,+ IteratorMatches,+} IteratorComparison;++static IteratorComparison iterator_compare(+ const Iterator *old_iter,+ const Iterator *new_iter+) {+ Subtree old_tree = NULL_SUBTREE;+ Subtree new_tree = NULL_SUBTREE;+ uint32_t old_start = 0;+ uint32_t new_start = 0;+ TSSymbol old_alias_symbol = 0;+ TSSymbol new_alias_symbol = 0;+ iterator_get_visible_state(old_iter, &old_tree, &old_alias_symbol, &old_start);+ iterator_get_visible_state(new_iter, &new_tree, &new_alias_symbol, &new_start);++ if (!old_tree.ptr && !new_tree.ptr) return IteratorMatches;+ if (!old_tree.ptr || !new_tree.ptr) return IteratorDiffers;++ if (+ old_alias_symbol == new_alias_symbol &&+ ts_subtree_symbol(old_tree) == ts_subtree_symbol(new_tree)+ ) {+ if (old_start == new_start &&+ !ts_subtree_has_changes(old_tree) &&+ ts_subtree_symbol(old_tree) != ts_builtin_sym_error &&+ ts_subtree_size(old_tree).bytes == ts_subtree_size(new_tree).bytes &&+ ts_subtree_parse_state(old_tree) != TS_TREE_STATE_NONE &&+ ts_subtree_parse_state(new_tree) != TS_TREE_STATE_NONE &&+ (ts_subtree_parse_state(old_tree) == ERROR_STATE) ==+ (ts_subtree_parse_state(new_tree) == ERROR_STATE)) {+ return IteratorMatches;+ } else {+ return IteratorMayDiffer;+ }+ }++ return IteratorDiffers;+}++#ifdef DEBUG_GET_CHANGED_RANGES+static inline void iterator_print_state(Iterator *self) {+ TreeCursorEntry entry = *array_back(&self->cursor.stack);+ TSPoint start = iterator_start_position(self).extent;+ TSPoint end = iterator_end_position(self).extent;+ const char *name = ts_language_symbol_name(self->language, ts_subtree_symbol(*entry.subtree));+ printf(+ "(%-25s %s\t depth:%u [%u, %u] - [%u, %u])",+ name, self->in_padding ? "(p)" : " ",+ self->visible_depth,+ start.row + 1, start.column,+ end.row + 1, end.column+ );+}+#endif++unsigned ts_subtree_get_changed_ranges(+ const Subtree *old_tree, const Subtree *new_tree,+ TreeCursor *cursor1, TreeCursor *cursor2,+ const TSLanguage *language,+ const TSRangeArray *included_range_differences,+ TSRange **ranges+) {+ TSRangeArray results = array_new();++ Iterator old_iter = iterator_new(cursor1, old_tree, language);+ Iterator new_iter = iterator_new(cursor2, new_tree, language);++ unsigned included_range_difference_index = 0;++ Length position = iterator_start_position(&old_iter);+ Length next_position = iterator_start_position(&new_iter);+ if (position.bytes < next_position.bytes) {+ ts_range_array_add(&results, position, next_position);+ position = next_position;+ } else if (position.bytes > next_position.bytes) {+ ts_range_array_add(&results, next_position, position);+ next_position = position;+ }++ do {+ #ifdef DEBUG_GET_CHANGED_RANGES+ printf("At [%-2u, %-2u] Compare ", position.extent.row + 1, position.extent.column);+ iterator_print_state(&old_iter);+ printf("\tvs\t");+ iterator_print_state(&new_iter);+ puts("");+ #endif++ // Compare the old and new subtrees.+ IteratorComparison comparison = iterator_compare(&old_iter, &new_iter);++ // Even if the two subtrees appear to be identical, they could differ+ // internally if they contain a range of text that was previously+ // excluded from the parse, and is now included, or vice-versa.+ if (comparison == IteratorMatches && ts_range_array_intersects(+ included_range_differences,+ included_range_difference_index,+ position.bytes,+ iterator_end_position(&old_iter).bytes+ )) {+ comparison = IteratorMayDiffer;+ }++ bool is_changed = false;+ switch (comparison) {+ // If the subtrees are definitely identical, move to the end+ // of both subtrees.+ case IteratorMatches:+ next_position = iterator_end_position(&old_iter);+ break;++ // If the subtrees might differ internally, descend into both+ // subtrees, finding the first child that spans the current position.+ case IteratorMayDiffer:+ if (iterator_descend(&old_iter, position.bytes)) {+ if (!iterator_descend(&new_iter, position.bytes)) {+ is_changed = true;+ next_position = iterator_end_position(&old_iter);+ }+ } else if (iterator_descend(&new_iter, position.bytes)) {+ is_changed = true;+ next_position = iterator_end_position(&new_iter);+ } else {+ next_position = length_min(+ iterator_end_position(&old_iter),+ iterator_end_position(&new_iter)+ );+ }+ break;++ // If the subtrees are different, record a change and then move+ // to the end of both subtrees.+ case IteratorDiffers:+ is_changed = true;+ next_position = length_min(+ iterator_end_position(&old_iter),+ iterator_end_position(&new_iter)+ );+ break;+ }++ // Ensure that both iterators are caught up to the current position.+ while (+ !iterator_done(&old_iter) &&+ iterator_end_position(&old_iter).bytes <= next_position.bytes+ ) iterator_advance(&old_iter);+ while (+ !iterator_done(&new_iter) &&+ iterator_end_position(&new_iter).bytes <= next_position.bytes+ ) iterator_advance(&new_iter);++ // Ensure that both iterators are at the same depth in the tree.+ while (old_iter.visible_depth > new_iter.visible_depth) {+ iterator_ascend(&old_iter);+ }+ while (new_iter.visible_depth > old_iter.visible_depth) {+ iterator_ascend(&new_iter);+ }++ if (is_changed) {+ #ifdef DEBUG_GET_CHANGED_RANGES+ printf(+ " change: [[%u, %u] - [%u, %u]]\n",+ position.extent.row + 1, position.extent.column,+ next_position.extent.row + 1, next_position.extent.column+ );+ #endif++ ts_range_array_add(&results, position, next_position);+ }++ position = next_position;++ // Keep track of the current position in the included range differences+ // array in order to avoid scanning the entire array on each iteration.+ while (included_range_difference_index < included_range_differences->size) {+ const TSRange *range = &included_range_differences->contents[+ included_range_difference_index+ ];+ if (range->end_byte <= position.bytes) {+ included_range_difference_index++;+ } else {+ break;+ }+ }+ } while (!iterator_done(&old_iter) && !iterator_done(&new_iter));++ Length old_size = ts_subtree_total_size(*old_tree);+ Length new_size = ts_subtree_total_size(*new_tree);+ if (old_size.bytes < new_size.bytes) {+ ts_range_array_add(&results, old_size, new_size);+ } else if (new_size.bytes < old_size.bytes) {+ ts_range_array_add(&results, new_size, old_size);+ }++ *cursor1 = old_iter.cursor;+ *cursor2 = new_iter.cursor;+ *ranges = results.contents;+ return results.size;+}
+ vendor/tree-sitter/lib/src/get_changed_ranges.h view
@@ -0,0 +1,36 @@+#ifndef TREE_SITTER_GET_CHANGED_RANGES_H_+#define TREE_SITTER_GET_CHANGED_RANGES_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./tree_cursor.h"+#include "./subtree.h"++typedef Array(TSRange) TSRangeArray;++void ts_range_array_get_changed_ranges(+ const TSRange *old_ranges, unsigned old_range_count,+ const TSRange *new_ranges, unsigned new_range_count,+ TSRangeArray *differences+);++bool ts_range_array_intersects(+ const TSRangeArray *self, unsigned start_index,+ uint32_t start_byte, uint32_t end_byte+);++unsigned ts_subtree_get_changed_ranges(+ const Subtree *old_tree, const Subtree *new_tree,+ TreeCursor *cursor1, TreeCursor *cursor2,+ const TSLanguage *language,+ const TSRangeArray *included_range_differences,+ TSRange **ranges+);++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_GET_CHANGED_RANGES_H_
+ vendor/tree-sitter/lib/src/host.h view
@@ -0,0 +1,21 @@++// Determine endian and pointer size based on known defines.+// TS_BIG_ENDIAN and TS_PTR_SIZE can be set as -D compiler arguments+// to override this.++#if !defined(TS_BIG_ENDIAN)+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \+ || (defined( __APPLE_CC__) && (defined(__ppc__) || defined(__ppc64__)))+#define TS_BIG_ENDIAN 1+#else+#define TS_BIG_ENDIAN 0+#endif+#endif++#if !defined(TS_PTR_SIZE)+#if UINTPTR_MAX == 0xFFFFFFFF+#define TS_PTR_SIZE 32+#else+#define TS_PTR_SIZE 64+#endif+#endif
+ vendor/tree-sitter/lib/src/language.c view
@@ -0,0 +1,223 @@+#include "./language.h"+#include "./wasm_store.h"+#include "tree_sitter/api.h"+#include <string.h>++const TSLanguage *ts_language_copy(const TSLanguage *self) {+ if (self && ts_language_is_wasm(self)) {+ ts_wasm_language_retain(self);+ }+ return self;+}++void ts_language_delete(const TSLanguage *self) {+ if (self && ts_language_is_wasm(self)) {+ ts_wasm_language_release(self);+ }+}++uint32_t ts_language_symbol_count(const TSLanguage *self) {+ return self->symbol_count + self->alias_count;+}++uint32_t ts_language_state_count(const TSLanguage *self) {+ return self->state_count;+}++uint32_t ts_language_version(const TSLanguage *self) {+ return self->version;+}++uint32_t ts_language_field_count(const TSLanguage *self) {+ return self->field_count;+}++void ts_language_table_entry(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol,+ TableEntry *result+) {+ if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {+ result->action_count = 0;+ result->is_reusable = false;+ result->actions = NULL;+ } else {+ ts_assert(symbol < self->token_count);+ uint32_t action_index = ts_language_lookup(self, state, symbol);+ const TSParseActionEntry *entry = &self->parse_actions[action_index];+ result->action_count = entry->entry.count;+ result->is_reusable = entry->entry.reusable;+ result->actions = (const TSParseAction *)(entry + 1);+ }+}++TSSymbolMetadata ts_language_symbol_metadata(+ const TSLanguage *self,+ TSSymbol symbol+) {+ if (symbol == ts_builtin_sym_error) {+ return (TSSymbolMetadata) {.visible = true, .named = true};+ } else if (symbol == ts_builtin_sym_error_repeat) {+ return (TSSymbolMetadata) {.visible = false, .named = false};+ } else {+ return self->symbol_metadata[symbol];+ }+}++TSSymbol ts_language_public_symbol(+ const TSLanguage *self,+ TSSymbol symbol+) {+ if (symbol == ts_builtin_sym_error) return symbol;+ return self->public_symbol_map[symbol];+}++TSStateId ts_language_next_state(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol+) {+ if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat) {+ return 0;+ } else if (symbol < self->token_count) {+ uint32_t count;+ const TSParseAction *actions = ts_language_actions(self, state, symbol, &count);+ if (count > 0) {+ TSParseAction action = actions[count - 1];+ if (action.type == TSParseActionTypeShift) {+ return action.shift.extra ? state : action.shift.state;+ }+ }+ return 0;+ } else {+ return ts_language_lookup(self, state, symbol);+ }+}++const char *ts_language_symbol_name(+ const TSLanguage *self,+ TSSymbol symbol+) {+ if (symbol == ts_builtin_sym_error) {+ return "ERROR";+ } else if (symbol == ts_builtin_sym_error_repeat) {+ return "_ERROR";+ } else if (symbol < ts_language_symbol_count(self)) {+ return self->symbol_names[symbol];+ } else {+ return NULL;+ }+}++TSSymbol ts_language_symbol_for_name(+ const TSLanguage *self,+ const char *string,+ uint32_t length,+ bool is_named+) {+ if (!strncmp(string, "ERROR", length)) return ts_builtin_sym_error;+ uint16_t count = (uint16_t)ts_language_symbol_count(self);+ for (TSSymbol i = 0; i < count; i++) {+ TSSymbolMetadata metadata = ts_language_symbol_metadata(self, i);+ if ((!metadata.visible && !metadata.supertype) || metadata.named != is_named) continue;+ const char *symbol_name = self->symbol_names[i];+ if (!strncmp(symbol_name, string, length) && !symbol_name[length]) {+ return self->public_symbol_map[i];+ }+ }+ return 0;+}++TSSymbolType ts_language_symbol_type(+ const TSLanguage *self,+ TSSymbol symbol+) {+ TSSymbolMetadata metadata = ts_language_symbol_metadata(self, symbol);+ if (metadata.named && metadata.visible) {+ return TSSymbolTypeRegular;+ } else if (metadata.visible) {+ return TSSymbolTypeAnonymous;+ } else if (metadata.supertype) {+ return TSSymbolTypeSupertype;+ } else {+ return TSSymbolTypeAuxiliary;+ }+}++const char *ts_language_field_name_for_id(+ const TSLanguage *self,+ TSFieldId id+) {+ uint32_t count = ts_language_field_count(self);+ if (count && id <= count) {+ return self->field_names[id];+ } else {+ return NULL;+ }+}++TSFieldId ts_language_field_id_for_name(+ const TSLanguage *self,+ const char *name,+ uint32_t name_length+) {+ uint16_t count = (uint16_t)ts_language_field_count(self);+ for (TSSymbol i = 1; i < count + 1; i++) {+ switch (strncmp(name, self->field_names[i], name_length)) {+ case 0:+ if (self->field_names[i][name_length] == 0) return i;+ break;+ case -1:+ return 0;+ default:+ break;+ }+ }+ return 0;+}++TSLookaheadIterator *ts_lookahead_iterator_new(const TSLanguage *self, TSStateId state) {+ if (state >= self->state_count) return NULL;+ LookaheadIterator *iterator = ts_malloc(sizeof(LookaheadIterator));+ *iterator = ts_language_lookaheads(self, state);+ return (TSLookaheadIterator *)iterator;+}++void ts_lookahead_iterator_delete(TSLookaheadIterator *self) {+ ts_free(self);+}++bool ts_lookahead_iterator_reset_state(TSLookaheadIterator * self, TSStateId state) {+ LookaheadIterator *iterator = (LookaheadIterator *)self;+ if (state >= iterator->language->state_count) return false;+ *iterator = ts_language_lookaheads(iterator->language, state);+ return true;+}++const TSLanguage *ts_lookahead_iterator_language(const TSLookaheadIterator *self) {+ const LookaheadIterator *iterator = (const LookaheadIterator *)self;+ return iterator->language;+}++bool ts_lookahead_iterator_reset(TSLookaheadIterator *self, const TSLanguage *language, TSStateId state) {+ if (state >= language->state_count) return false;+ LookaheadIterator *iterator = (LookaheadIterator *)self;+ *iterator = ts_language_lookaheads(language, state);+ return true;+}++bool ts_lookahead_iterator_next(TSLookaheadIterator *self) {+ LookaheadIterator *iterator = (LookaheadIterator *)self;+ return ts_lookahead_iterator__next(iterator);+}++TSSymbol ts_lookahead_iterator_current_symbol(const TSLookaheadIterator *self) {+ const LookaheadIterator *iterator = (const LookaheadIterator *)self;+ return iterator->symbol;+}++const char *ts_lookahead_iterator_current_symbol_name(const TSLookaheadIterator *self) {+ const LookaheadIterator *iterator = (const LookaheadIterator *)self;+ return ts_language_symbol_name(iterator->language, iterator->symbol);+}
+ vendor/tree-sitter/lib/src/language.h view
@@ -0,0 +1,297 @@+#ifndef TREE_SITTER_LANGUAGE_H_+#define TREE_SITTER_LANGUAGE_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./subtree.h"+#include "./parser.h"++#define ts_builtin_sym_error_repeat (ts_builtin_sym_error - 1)++#define LANGUAGE_VERSION_WITH_PRIMARY_STATES 14+#define LANGUAGE_VERSION_USABLE_VIA_WASM 13++typedef struct {+ const TSParseAction *actions;+ uint32_t action_count;+ bool is_reusable;+} TableEntry;++typedef struct {+ const TSLanguage *language;+ const uint16_t *data;+ const uint16_t *group_end;+ TSStateId state;+ uint16_t table_value;+ uint16_t section_index;+ uint16_t group_count;+ bool is_small_state;++ const TSParseAction *actions;+ TSSymbol symbol;+ TSStateId next_state;+ uint16_t action_count;+} LookaheadIterator;++void ts_language_table_entry(const TSLanguage *self, TSStateId state, TSSymbol symbol, TableEntry *result);++TSSymbolMetadata ts_language_symbol_metadata(const TSLanguage *self, TSSymbol symbol);++TSSymbol ts_language_public_symbol(const TSLanguage *self, TSSymbol symbol);++static inline bool ts_language_is_symbol_external(const TSLanguage *self, TSSymbol symbol) {+ return 0 < symbol && symbol < self->external_token_count + 1;+}++static inline const TSParseAction *ts_language_actions(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol,+ uint32_t *count+) {+ TableEntry entry;+ ts_language_table_entry(self, state, symbol, &entry);+ *count = entry.action_count;+ return entry.actions;+}++static inline bool ts_language_has_reduce_action(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol+) {+ TableEntry entry;+ ts_language_table_entry(self, state, symbol, &entry);+ return entry.action_count > 0 && entry.actions[0].type == TSParseActionTypeReduce;+}++// Lookup the table value for a given symbol and state.+//+// For non-terminal symbols, the table value represents a successor state.+// For terminal symbols, it represents an index in the actions table.+// For 'large' parse states, this is a direct lookup. For 'small' parse+// states, this requires searching through the symbol groups to find+// the given symbol.+static inline uint16_t ts_language_lookup(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol+) {+ if (state >= self->large_state_count) {+ uint32_t index = self->small_parse_table_map[state - self->large_state_count];+ const uint16_t *data = &self->small_parse_table[index];+ uint16_t group_count = *(data++);+ for (unsigned i = 0; i < group_count; i++) {+ uint16_t section_value = *(data++);+ uint16_t symbol_count = *(data++);+ for (unsigned j = 0; j < symbol_count; j++) {+ if (*(data++) == symbol) return section_value;+ }+ }+ return 0;+ } else {+ return self->parse_table[state * self->symbol_count + symbol];+ }+}++static inline bool ts_language_has_actions(+ const TSLanguage *self,+ TSStateId state,+ TSSymbol symbol+) {+ return ts_language_lookup(self, state, symbol) != 0;+}++// Iterate over all of the symbols that are valid in the given state.+//+// For 'large' parse states, this just requires iterating through+// all possible symbols and checking the parse table for each one.+// For 'small' parse states, this exploits the structure of the+// table to only visit the valid symbols.+static inline LookaheadIterator ts_language_lookaheads(+ const TSLanguage *self,+ TSStateId state+) {+ bool is_small_state = state >= self->large_state_count;+ const uint16_t *data;+ const uint16_t *group_end = NULL;+ uint16_t group_count = 0;+ if (is_small_state) {+ uint32_t index = self->small_parse_table_map[state - self->large_state_count];+ data = &self->small_parse_table[index];+ group_end = data + 1;+ group_count = *data;+ } else {+ data = &self->parse_table[state * self->symbol_count] - 1;+ }+ return (LookaheadIterator) {+ .language = self,+ .data = data,+ .group_end = group_end,+ .group_count = group_count,+ .is_small_state = is_small_state,+ .symbol = UINT16_MAX,+ .next_state = 0,+ };+}++static inline bool ts_lookahead_iterator__next(LookaheadIterator *self) {+ // For small parse states, valid symbols are listed explicitly,+ // grouped by their value. There's no need to look up the actions+ // again until moving to the next group.+ if (self->is_small_state) {+ self->data++;+ if (self->data == self->group_end) {+ if (self->group_count == 0) return false;+ self->group_count--;+ self->table_value = *(self->data++);+ unsigned symbol_count = *(self->data++);+ self->group_end = self->data + symbol_count;+ self->symbol = *self->data;+ } else {+ self->symbol = *self->data;+ return true;+ }+ }++ // For large parse states, iterate through every symbol until one+ // is found that has valid actions.+ else {+ do {+ self->data++;+ self->symbol++;+ if (self->symbol >= self->language->symbol_count) return false;+ self->table_value = *self->data;+ } while (!self->table_value);+ }++ // Depending on if the symbols is terminal or non-terminal, the table value either+ // represents a list of actions or a successor state.+ if (self->symbol < self->language->token_count) {+ const TSParseActionEntry *entry = &self->language->parse_actions[self->table_value];+ self->action_count = entry->entry.count;+ self->actions = (const TSParseAction *)(entry + 1);+ self->next_state = 0;+ } else {+ self->action_count = 0;+ self->next_state = self->table_value;+ }+ return true;+}++// Whether the state is a "primary state". If this returns false, it indicates that there exists+// another state that behaves identically to this one with respect to query analysis.+static inline bool ts_language_state_is_primary(+ const TSLanguage *self,+ TSStateId state+) {+ if (self->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) {+ return state == self->primary_state_ids[state];+ } else {+ return true;+ }+}++static inline const bool *ts_language_enabled_external_tokens(+ const TSLanguage *self,+ unsigned external_scanner_state+) {+ if (external_scanner_state == 0) {+ return NULL;+ } else {+ return self->external_scanner.states + self->external_token_count * external_scanner_state;+ }+}++static inline const TSSymbol *ts_language_alias_sequence(+ const TSLanguage *self,+ uint32_t production_id+) {+ return production_id ?+ &self->alias_sequences[production_id * self->max_alias_sequence_length] :+ NULL;+}++static inline TSSymbol ts_language_alias_at(+ const TSLanguage *self,+ uint32_t production_id,+ uint32_t child_index+) {+ return production_id ?+ self->alias_sequences[production_id * self->max_alias_sequence_length + child_index] :+ 0;+}++static inline void ts_language_field_map(+ const TSLanguage *self,+ uint32_t production_id,+ const TSFieldMapEntry **start,+ const TSFieldMapEntry **end+) {+ if (self->field_count == 0) {+ *start = NULL;+ *end = NULL;+ return;+ }++ TSFieldMapSlice slice = self->field_map_slices[production_id];+ *start = &self->field_map_entries[slice.index];+ *end = &self->field_map_entries[slice.index] + slice.length;+}++static inline void ts_language_aliases_for_symbol(+ const TSLanguage *self,+ TSSymbol original_symbol,+ const TSSymbol **start,+ const TSSymbol **end+) {+ *start = &self->public_symbol_map[original_symbol];+ *end = *start + 1;++ unsigned idx = 0;+ for (;;) {+ TSSymbol symbol = self->alias_map[idx++];+ if (symbol == 0 || symbol > original_symbol) break;+ uint16_t count = self->alias_map[idx++];+ if (symbol == original_symbol) {+ *start = &self->alias_map[idx];+ *end = &self->alias_map[idx + count];+ break;+ }+ idx += count;+ }+}++static inline void ts_language_write_symbol_as_dot_string(+ const TSLanguage *self,+ FILE *f,+ TSSymbol symbol+) {+ const char *name = ts_language_symbol_name(self, symbol);+ for (const char *chr = name; *chr; chr++) {+ switch (*chr) {+ case '"':+ case '\\':+ fputc('\\', f);+ fputc(*chr, f);+ break;+ case '\n':+ fputs("\\n", f);+ break;+ case '\t':+ fputs("\\t", f);+ break;+ default:+ fputc(*chr, f);+ break;+ }+ }+}++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_LANGUAGE_H_
+ vendor/tree-sitter/lib/src/length.h view
@@ -0,0 +1,52 @@+#ifndef TREE_SITTER_LENGTH_H_+#define TREE_SITTER_LENGTH_H_++#include <stdlib.h>+#include <stdbool.h>+#include "./point.h"+#include "tree_sitter/api.h"++typedef struct {+ uint32_t bytes;+ TSPoint extent;+} Length;++static const Length LENGTH_UNDEFINED = {0, {0, 1}};+static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};++static inline bool length_is_undefined(Length length) {+ return length.bytes == 0 && length.extent.column != 0;+}++static inline Length length_min(Length len1, Length len2) {+ return (len1.bytes < len2.bytes) ? len1 : len2;+}++static inline Length length_add(Length len1, Length len2) {+ Length result;+ result.bytes = len1.bytes + len2.bytes;+ result.extent = point_add(len1.extent, len2.extent);+ return result;+}++static inline Length length_sub(Length len1, Length len2) {+ Length result;+ result.bytes = len1.bytes - len2.bytes;+ result.extent = point_sub(len1.extent, len2.extent);+ return result;+}++static inline Length length_zero(void) {+ Length result = {0, {0, 0}};+ return result;+}++static inline Length length_saturating_sub(Length len1, Length len2) {+ if (len1.bytes > len2.bytes) {+ return length_sub(len1, len2);+ } else {+ return length_zero();+ }+}++#endif
+ vendor/tree-sitter/lib/src/lexer.c view
@@ -0,0 +1,432 @@+#include <stdio.h>+#include "./lexer.h"+#include "./subtree.h"+#include "./length.h"+#include "./unicode.h"+#include <stdarg.h>++#define LOG(message, character) \+ if (self->logger.log) { \+ snprintf( \+ self->debug_buffer, \+ TREE_SITTER_SERIALIZATION_BUFFER_SIZE, \+ 32 <= character && character < 127 ? \+ message " character:'%c'" : \+ message " character:%d", \+ character \+ ); \+ self->logger.log( \+ self->logger.payload, \+ TSLogTypeLex, \+ self->debug_buffer \+ ); \+ }++static const int32_t BYTE_ORDER_MARK = 0xFEFF;++static const TSRange DEFAULT_RANGE = {+ .start_point = {+ .row = 0,+ .column = 0,+ },+ .end_point = {+ .row = UINT32_MAX,+ .column = UINT32_MAX,+ },+ .start_byte = 0,+ .end_byte = UINT32_MAX+};++// Check if the lexer has reached EOF. This state is stored+// by setting the lexer's `current_included_range_index` such that+// it has consumed all of its available ranges.+static bool ts_lexer__eof(const TSLexer *_self) {+ Lexer *self = (Lexer *)_self;+ return self->current_included_range_index == self->included_range_count;+}++// Clear the currently stored chunk of source code, because the lexer's+// position has changed.+static void ts_lexer__clear_chunk(Lexer *self) {+ self->chunk = NULL;+ self->chunk_size = 0;+ self->chunk_start = 0;+}++// Call the lexer's input callback to obtain a new chunk of source code+// for the current position.+static void ts_lexer__get_chunk(Lexer *self) {+ self->chunk_start = self->current_position.bytes;+ self->chunk = self->input.read(+ self->input.payload,+ self->current_position.bytes,+ self->current_position.extent,+ &self->chunk_size+ );+ if (!self->chunk_size) {+ self->current_included_range_index = self->included_range_count;+ self->chunk = NULL;+ }+}++// Decode the next unicode character in the current chunk of source code.+// This assumes that the lexer has already retrieved a chunk of source+// code that spans the current position.+static void ts_lexer__get_lookahead(Lexer *self) {+ uint32_t position_in_chunk = self->current_position.bytes - self->chunk_start;+ uint32_t size = self->chunk_size - position_in_chunk;++ if (size == 0) {+ self->lookahead_size = 1;+ self->data.lookahead = '\0';+ return;+ }++ const uint8_t *chunk = (const uint8_t *)self->chunk + position_in_chunk;+ UnicodeDecodeFunction decode = self->input.encoding == TSInputEncodingUTF8+ ? ts_decode_utf8+ : ts_decode_utf16;++ self->lookahead_size = decode(chunk, size, &self->data.lookahead);++ // If this chunk ended in the middle of a multi-byte character,+ // try again with a fresh chunk.+ if (self->data.lookahead == TS_DECODE_ERROR && size < 4) {+ ts_lexer__get_chunk(self);+ chunk = (const uint8_t *)self->chunk;+ size = self->chunk_size;+ self->lookahead_size = decode(chunk, size, &self->data.lookahead);+ }++ if (self->data.lookahead == TS_DECODE_ERROR) {+ self->lookahead_size = 1;+ }+}++static void ts_lexer_goto(Lexer *self, Length position) {+ self->current_position = position;++ // Move to the first valid position at or after the given position.+ bool found_included_range = false;+ for (unsigned i = 0; i < self->included_range_count; i++) {+ TSRange *included_range = &self->included_ranges[i];+ if (+ included_range->end_byte > self->current_position.bytes &&+ included_range->end_byte > included_range->start_byte+ ) {+ if (included_range->start_byte >= self->current_position.bytes) {+ self->current_position = (Length) {+ .bytes = included_range->start_byte,+ .extent = included_range->start_point,+ };+ }++ self->current_included_range_index = i;+ found_included_range = true;+ break;+ }+ }++ if (found_included_range) {+ // If the current position is outside of the current chunk of text,+ // then clear out the current chunk of text.+ if (self->chunk && (+ self->current_position.bytes < self->chunk_start ||+ self->current_position.bytes >= self->chunk_start + self->chunk_size+ )) {+ ts_lexer__clear_chunk(self);+ }++ self->lookahead_size = 0;+ self->data.lookahead = '\0';+ }++ // If the given position is beyond any of included ranges, move to the EOF+ // state - past the end of the included ranges.+ else {+ self->current_included_range_index = self->included_range_count;+ TSRange *last_included_range = &self->included_ranges[self->included_range_count - 1];+ self->current_position = (Length) {+ .bytes = last_included_range->end_byte,+ .extent = last_included_range->end_point,+ };+ ts_lexer__clear_chunk(self);+ self->lookahead_size = 1;+ self->data.lookahead = '\0';+ }+}++// Intended to be called only from functions that control logging.+static void ts_lexer__do_advance(Lexer *self, bool skip) {+ if (self->lookahead_size) {+ self->current_position.bytes += self->lookahead_size;+ if (self->data.lookahead == '\n') {+ self->current_position.extent.row++;+ self->current_position.extent.column = 0;+ } else {+ self->current_position.extent.column += self->lookahead_size;+ }+ }++ const TSRange *current_range = &self->included_ranges[self->current_included_range_index];+ while (+ self->current_position.bytes >= current_range->end_byte ||+ current_range->end_byte == current_range->start_byte+ ) {+ if (self->current_included_range_index < self->included_range_count) {+ self->current_included_range_index++;+ }+ if (self->current_included_range_index < self->included_range_count) {+ current_range++;+ self->current_position = (Length) {+ current_range->start_byte,+ current_range->start_point,+ };+ } else {+ current_range = NULL;+ break;+ }+ }++ if (skip) self->token_start_position = self->current_position;++ if (current_range) {+ if (+ self->current_position.bytes < self->chunk_start ||+ self->current_position.bytes >= self->chunk_start + self->chunk_size+ ) {+ ts_lexer__get_chunk(self);+ }+ ts_lexer__get_lookahead(self);+ } else {+ ts_lexer__clear_chunk(self);+ self->data.lookahead = '\0';+ self->lookahead_size = 1;+ }+}++// Advance to the next character in the source code, retrieving a new+// chunk of source code if needed.+static void ts_lexer__advance(TSLexer *_self, bool skip) {+ Lexer *self = (Lexer *)_self;+ if (!self->chunk) return;++ if (skip) {+ LOG("skip", self->data.lookahead)+ } else {+ LOG("consume", self->data.lookahead)+ }++ ts_lexer__do_advance(self, skip);+}++// Mark that a token match has completed. This can be called multiple+// times if a longer match is found later.+static void ts_lexer__mark_end(TSLexer *_self) {+ Lexer *self = (Lexer *)_self;+ if (!ts_lexer__eof(&self->data)) {+ // If the lexer is right at the beginning of included range,+ // then the token should be considered to end at the *end* of the+ // previous included range, rather than here.+ TSRange *current_included_range = &self->included_ranges[+ self->current_included_range_index+ ];+ if (+ self->current_included_range_index > 0 &&+ self->current_position.bytes == current_included_range->start_byte+ ) {+ TSRange *previous_included_range = current_included_range - 1;+ self->token_end_position = (Length) {+ previous_included_range->end_byte,+ previous_included_range->end_point,+ };+ return;+ }+ }+ self->token_end_position = self->current_position;+}++static uint32_t ts_lexer__get_column(TSLexer *_self) {+ Lexer *self = (Lexer *)_self;++ uint32_t goal_byte = self->current_position.bytes;++ self->did_get_column = true;+ Length start_of_col = {+ self->current_position.bytes - self->current_position.extent.column,+ {self->current_position.extent.row, 0},+ };+ ts_lexer_goto(self, start_of_col);+ ts_lexer__get_chunk(self);++ uint32_t result = 0;+ if (!ts_lexer__eof(_self)) {+ ts_lexer__get_lookahead(self);+ while (self->current_position.bytes < goal_byte && self->chunk) {+ result++;+ ts_lexer__do_advance(self, false);+ if (ts_lexer__eof(_self)) break;+ }+ }++ return result;+}++// Is the lexer at a boundary between two disjoint included ranges of+// source code? This is exposed as an API because some languages' external+// scanners need to perform custom actions at these boundaries.+static bool ts_lexer__is_at_included_range_start(const TSLexer *_self) {+ const Lexer *self = (const Lexer *)_self;+ if (self->current_included_range_index < self->included_range_count) {+ TSRange *current_range = &self->included_ranges[self->current_included_range_index];+ return self->current_position.bytes == current_range->start_byte;+ } else {+ return false;+ }+}++static void ts_lexer__log(const TSLexer *_self, const char *fmt, ...) {+ Lexer *self = (Lexer *)_self;+ va_list args;+ va_start(args, fmt);+ if (self->logger.log) {+ vsnprintf(self->debug_buffer, TREE_SITTER_SERIALIZATION_BUFFER_SIZE, fmt, args);+ self->logger.log(self->logger.payload, TSLogTypeLex, self->debug_buffer);+ }+ va_end(args);+}++void ts_lexer_init(Lexer *self) {+ *self = (Lexer) {+ .data = {+ // The lexer's methods are stored as struct fields so that generated+ // parsers can call them without needing to be linked against this+ // library.+ .advance = ts_lexer__advance,+ .mark_end = ts_lexer__mark_end,+ .get_column = ts_lexer__get_column,+ .is_at_included_range_start = ts_lexer__is_at_included_range_start,+ .eof = ts_lexer__eof,+ .log = ts_lexer__log,+ .lookahead = 0,+ .result_symbol = 0,+ },+ .chunk = NULL,+ .chunk_size = 0,+ .chunk_start = 0,+ .current_position = {0, {0, 0}},+ .logger = {+ .payload = NULL,+ .log = NULL+ },+ .included_ranges = NULL,+ .included_range_count = 0,+ .current_included_range_index = 0,+ };+ ts_lexer_set_included_ranges(self, NULL, 0);+}++void ts_lexer_delete(Lexer *self) {+ ts_free(self->included_ranges);+}++void ts_lexer_set_input(Lexer *self, TSInput input) {+ self->input = input;+ ts_lexer__clear_chunk(self);+ ts_lexer_goto(self, self->current_position);+}++// Move the lexer to the given position. This doesn't do any work+// if the parser is already at the given position.+void ts_lexer_reset(Lexer *self, Length position) {+ if (position.bytes != self->current_position.bytes) {+ ts_lexer_goto(self, position);+ }+}++void ts_lexer_start(Lexer *self) {+ self->token_start_position = self->current_position;+ self->token_end_position = LENGTH_UNDEFINED;+ self->data.result_symbol = 0;+ self->did_get_column = false;+ if (!ts_lexer__eof(&self->data)) {+ if (!self->chunk_size) ts_lexer__get_chunk(self);+ if (!self->lookahead_size) ts_lexer__get_lookahead(self);+ if (+ self->current_position.bytes == 0 &&+ self->data.lookahead == BYTE_ORDER_MARK+ ) ts_lexer__advance(&self->data, true);+ }+}++void ts_lexer_finish(Lexer *self, uint32_t *lookahead_end_byte) {+ if (length_is_undefined(self->token_end_position)) {+ ts_lexer__mark_end(&self->data);+ }++ // If the token ended at an included range boundary, then its end position+ // will have been reset to the end of the preceding range. Reset the start+ // position to match.+ if (self->token_end_position.bytes < self->token_start_position.bytes) {+ self->token_start_position = self->token_end_position;+ }++ uint32_t current_lookahead_end_byte = self->current_position.bytes + 1;++ // In order to determine that a byte sequence is invalid UTF8 or UTF16,+ // the character decoding algorithm may have looked at the following byte.+ // Therefore, the next byte *after* the current (invalid) character+ // affects the interpretation of the current character.+ if (self->data.lookahead == TS_DECODE_ERROR) {+ current_lookahead_end_byte += 4; // the maximum number of bytes read to identify an invalid code point+ }++ if (current_lookahead_end_byte > *lookahead_end_byte) {+ *lookahead_end_byte = current_lookahead_end_byte;+ }+}++void ts_lexer_advance_to_end(Lexer *self) {+ while (self->chunk) {+ ts_lexer__advance(&self->data, false);+ }+}++void ts_lexer_mark_end(Lexer *self) {+ ts_lexer__mark_end(&self->data);+}++bool ts_lexer_set_included_ranges(+ Lexer *self,+ const TSRange *ranges,+ uint32_t count+) {+ if (count == 0 || !ranges) {+ ranges = &DEFAULT_RANGE;+ count = 1;+ } else {+ uint32_t previous_byte = 0;+ for (unsigned i = 0; i < count; i++) {+ const TSRange *range = &ranges[i];+ if (+ range->start_byte < previous_byte ||+ range->end_byte < range->start_byte+ ) return false;+ previous_byte = range->end_byte;+ }+ }++ size_t size = count * sizeof(TSRange);+ self->included_ranges = ts_realloc(self->included_ranges, size);+ memcpy(self->included_ranges, ranges, size);+ self->included_range_count = count;+ ts_lexer_goto(self, self->current_position);+ return true;+}++TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count) {+ *count = self->included_range_count;+ return self->included_ranges;+}++#undef LOG
+ vendor/tree-sitter/lib/src/lexer.h view
@@ -0,0 +1,49 @@+#ifndef TREE_SITTER_LEXER_H_+#define TREE_SITTER_LEXER_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./length.h"+#include "./subtree.h"+#include "tree_sitter/api.h"+#include "./parser.h"++typedef struct {+ TSLexer data;+ Length current_position;+ Length token_start_position;+ Length token_end_position;++ TSRange *included_ranges;+ const char *chunk;+ TSInput input;+ TSLogger logger;++ uint32_t included_range_count;+ uint32_t current_included_range_index;+ uint32_t chunk_start;+ uint32_t chunk_size;+ uint32_t lookahead_size;+ bool did_get_column;++ char debug_buffer[TREE_SITTER_SERIALIZATION_BUFFER_SIZE];+} Lexer;++void ts_lexer_init(Lexer *self);+void ts_lexer_delete(Lexer *self);+void ts_lexer_set_input(Lexer *self, TSInput input);+void ts_lexer_reset(Lexer *self, Length position);+void ts_lexer_start(Lexer *self);+void ts_lexer_finish(Lexer *self, uint32_t *lookahead_end_byte);+void ts_lexer_advance_to_end(Lexer *self);+void ts_lexer_mark_end(Lexer *self);+bool ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, uint32_t count);+TSRange *ts_lexer_included_ranges(const Lexer *self, uint32_t *count);++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_LEXER_H_
+ vendor/tree-sitter/lib/src/lib.c view
@@ -0,0 +1,14 @@+#define _POSIX_C_SOURCE 200112L++#include "./alloc.c"+#include "./get_changed_ranges.c"+#include "./language.c"+#include "./lexer.c"+#include "./node.c"+#include "./parser.c"+#include "./query.c"+#include "./stack.c"+#include "./subtree.c"+#include "./tree_cursor.c"+#include "./tree.c"+#include "./wasm_store.c"
+ vendor/tree-sitter/lib/src/node.c view
@@ -0,0 +1,920 @@+#include <stdbool.h>+#include "./subtree.h"+#include "./tree.h"+#include "./language.h"++typedef struct {+ Subtree parent;+ const TSTree *tree;+ Length position;+ uint32_t child_index;+ uint32_t structural_child_index;+ const TSSymbol *alias_sequence;+} NodeChildIterator;++static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous);++// TSNode - constructors++TSNode ts_node_new(+ const TSTree *tree,+ const Subtree *subtree,+ Length position,+ TSSymbol alias+) {+ return (TSNode) {+ {position.bytes, position.extent.row, position.extent.column, alias},+ subtree,+ tree,+ };+}++static inline TSNode ts_node__null(void) {+ return ts_node_new(NULL, NULL, length_zero(), 0);+}++// TSNode - accessors++uint32_t ts_node_start_byte(TSNode self) {+ return self.context[0];+}++TSPoint ts_node_start_point(TSNode self) {+ return (TSPoint) {self.context[1], self.context[2]};+}++static inline uint32_t ts_node__alias(const TSNode *self) {+ return self->context[3];+}++static inline Subtree ts_node__subtree(TSNode self) {+ return *(const Subtree *)self.id;+}++// NodeChildIterator++static inline NodeChildIterator ts_node_iterate_children(const TSNode *node) {+ Subtree subtree = ts_node__subtree(*node);+ if (ts_subtree_child_count(subtree) == 0) {+ return (NodeChildIterator) {NULL_SUBTREE, node->tree, length_zero(), 0, 0, NULL};+ }+ const TSSymbol *alias_sequence = ts_language_alias_sequence(+ node->tree->language,+ subtree.ptr->production_id+ );+ return (NodeChildIterator) {+ .tree = node->tree,+ .parent = subtree,+ .position = {ts_node_start_byte(*node), ts_node_start_point(*node)},+ .child_index = 0,+ .structural_child_index = 0,+ .alias_sequence = alias_sequence,+ };+}++static inline bool ts_node_child_iterator_done(NodeChildIterator *self) {+ return self->child_index == self->parent.ptr->child_count;+}++static inline bool ts_node_child_iterator_next(+ NodeChildIterator *self,+ TSNode *result+) {+ if (!self->parent.ptr || ts_node_child_iterator_done(self)) return false;+ const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];+ TSSymbol alias_symbol = 0;+ if (!ts_subtree_extra(*child)) {+ if (self->alias_sequence) {+ alias_symbol = self->alias_sequence[self->structural_child_index];+ }+ self->structural_child_index++;+ }+ if (self->child_index > 0) {+ self->position = length_add(self->position, ts_subtree_padding(*child));+ }+ *result = ts_node_new(+ self->tree,+ child,+ self->position,+ alias_symbol+ );+ self->position = length_add(self->position, ts_subtree_size(*child));+ self->child_index++;+ return true;+}++// This will return true if the next sibling is a zero-width token that is adjacent to the current node and is relevant+static inline bool ts_node_child_iterator_next_sibling_is_empty_adjacent(NodeChildIterator *self, TSNode previous) {+ if (!self->parent.ptr || ts_node_child_iterator_done(self)) return false;+ if (self->child_index == 0) return false;+ const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];+ TSSymbol alias = 0;+ if (!ts_subtree_extra(*child)) {+ if (self->alias_sequence) {+ alias = self->alias_sequence[self->structural_child_index];+ }+ }+ TSNode next = ts_node_new(self->tree, child, self->position, alias);+ return ts_node_end_byte(previous) == ts_node_end_byte(next) && ts_node__is_relevant(next, true);+}++// TSNode - private++static inline bool ts_node__is_relevant(TSNode self, bool include_anonymous) {+ Subtree tree = ts_node__subtree(self);+ if (include_anonymous) {+ return ts_subtree_visible(tree) || ts_node__alias(&self);+ } else {+ TSSymbol alias = ts_node__alias(&self);+ if (alias) {+ return ts_language_symbol_metadata(self.tree->language, alias).named;+ } else {+ return ts_subtree_visible(tree) && ts_subtree_named(tree);+ }+ }+}++static inline uint32_t ts_node__relevant_child_count(+ TSNode self,+ bool include_anonymous+) {+ Subtree tree = ts_node__subtree(self);+ if (ts_subtree_child_count(tree) > 0) {+ if (include_anonymous) {+ return tree.ptr->visible_child_count;+ } else {+ return tree.ptr->named_child_count;+ }+ } else {+ return 0;+ }+}++static inline TSNode ts_node__child(+ TSNode self,+ uint32_t child_index,+ bool include_anonymous+) {+ TSNode result = self;+ bool did_descend = true;++ while (did_descend) {+ did_descend = false;++ TSNode child;+ uint32_t index = 0;+ NodeChildIterator iterator = ts_node_iterate_children(&result);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (ts_node__is_relevant(child, include_anonymous)) {+ if (index == child_index) {+ return child;+ }+ index++;+ } else {+ uint32_t grandchild_index = child_index - index;+ uint32_t grandchild_count = ts_node__relevant_child_count(child, include_anonymous);+ if (grandchild_index < grandchild_count) {+ did_descend = true;+ result = child;+ child_index = grandchild_index;+ break;+ }+ index += grandchild_count;+ }+ }+ }++ return ts_node__null();+}++static bool ts_subtree_has_trailing_empty_descendant(+ Subtree self,+ Subtree other+) {+ for (unsigned i = ts_subtree_child_count(self) - 1; i + 1 > 0; i--) {+ Subtree child = ts_subtree_children(self)[i];+ if (ts_subtree_total_bytes(child) > 0) break;+ if (child.ptr == other.ptr || ts_subtree_has_trailing_empty_descendant(child, other)) {+ return true;+ }+ }+ return false;+}++static inline TSNode ts_node__prev_sibling(TSNode self, bool include_anonymous) {+ Subtree self_subtree = ts_node__subtree(self);+ bool self_is_empty = ts_subtree_total_bytes(self_subtree) == 0;+ uint32_t target_end_byte = ts_node_end_byte(self);++ TSNode node = ts_node_parent(self);+ TSNode earlier_node = ts_node__null();+ bool earlier_node_is_relevant = false;++ while (!ts_node_is_null(node)) {+ TSNode earlier_child = ts_node__null();+ bool earlier_child_is_relevant = false;+ bool found_child_containing_target = false;++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&node);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (child.id == self.id) break;+ if (iterator.position.bytes > target_end_byte) {+ found_child_containing_target = true;+ break;+ }++ if (iterator.position.bytes == target_end_byte &&+ (!self_is_empty ||+ ts_subtree_has_trailing_empty_descendant(ts_node__subtree(child), self_subtree))) {+ found_child_containing_target = true;+ break;+ }++ if (ts_node__is_relevant(child, include_anonymous)) {+ earlier_child = child;+ earlier_child_is_relevant = true;+ } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {+ earlier_child = child;+ earlier_child_is_relevant = false;+ }+ }++ if (found_child_containing_target) {+ if (!ts_node_is_null(earlier_child)) {+ earlier_node = earlier_child;+ earlier_node_is_relevant = earlier_child_is_relevant;+ }+ node = child;+ } else if (earlier_child_is_relevant) {+ return earlier_child;+ } else if (!ts_node_is_null(earlier_child)) {+ node = earlier_child;+ } else if (earlier_node_is_relevant) {+ return earlier_node;+ } else {+ node = earlier_node;+ earlier_node = ts_node__null();+ earlier_node_is_relevant = false;+ }+ }++ return ts_node__null();+}++static inline TSNode ts_node__next_sibling(TSNode self, bool include_anonymous) {+ uint32_t target_end_byte = ts_node_end_byte(self);++ TSNode node = ts_node_parent(self);+ TSNode later_node = ts_node__null();+ bool later_node_is_relevant = false;++ while (!ts_node_is_null(node)) {+ TSNode later_child = ts_node__null();+ bool later_child_is_relevant = false;+ TSNode child_containing_target = ts_node__null();++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&node);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (iterator.position.bytes < target_end_byte) continue;+ if (ts_node_start_byte(child) <= ts_node_start_byte(self)) {+ if (ts_node__subtree(child).ptr != ts_node__subtree(self).ptr) {+ child_containing_target = child;+ }+ } else if (ts_node__is_relevant(child, include_anonymous)) {+ later_child = child;+ later_child_is_relevant = true;+ break;+ } else if (ts_node__relevant_child_count(child, include_anonymous) > 0) {+ later_child = child;+ later_child_is_relevant = false;+ break;+ }+ }++ if (!ts_node_is_null(child_containing_target)) {+ if (!ts_node_is_null(later_child)) {+ later_node = later_child;+ later_node_is_relevant = later_child_is_relevant;+ }+ node = child_containing_target;+ } else if (later_child_is_relevant) {+ return later_child;+ } else if (!ts_node_is_null(later_child)) {+ node = later_child;+ } else if (later_node_is_relevant) {+ return later_node;+ } else {+ node = later_node;+ }+ }++ return ts_node__null();+}++static inline TSNode ts_node__first_child_for_byte(+ TSNode self,+ uint32_t goal,+ bool include_anonymous+) {+ TSNode node = self;+ bool did_descend = true;++ NodeChildIterator last_iterator;+ bool has_last_iterator = false;++ while (did_descend) {+ did_descend = false;++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&node);+ loop:+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (ts_node_end_byte(child) > goal) {+ if (ts_node__is_relevant(child, include_anonymous)) {+ return child;+ } else if (ts_node_child_count(child) > 0) {+ if (iterator.child_index < ts_subtree_child_count(ts_node__subtree(child))) {+ last_iterator = iterator;+ has_last_iterator = true;+ }+ did_descend = true;+ node = child;+ break;+ }+ }+ }++ if (!did_descend && has_last_iterator) {+ iterator = last_iterator;+ has_last_iterator = false;+ goto loop;+ }+ }++ return ts_node__null();+}++static inline TSNode ts_node__descendant_for_byte_range(+ TSNode self,+ uint32_t range_start,+ uint32_t range_end,+ bool include_anonymous+) {+ TSNode node = self;+ TSNode last_visible_node = self;++ bool did_descend = true;+ while (did_descend) {+ did_descend = false;++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&node);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ uint32_t node_end = iterator.position.bytes;++ // The end of this node must extend far enough forward to touch+ // the end of the range+ if (node_end < range_end) continue;++ // ...and exceed the start of the range, unless the node itself is+ // empty, in which case it must at least be equal to the start of the range.+ bool is_empty = ts_node_start_byte(child) == node_end;+ if (is_empty ? node_end < range_start : node_end <= range_start) continue;++ // The start of this node must extend far enough backward to+ // touch the start of the range.+ if (range_start < ts_node_start_byte(child)) break;++ node = child;+ if (ts_node__is_relevant(node, include_anonymous)) {+ last_visible_node = node;+ }+ did_descend = true;+ break;+ }+ }++ return last_visible_node;+}++static inline TSNode ts_node__descendant_for_point_range(+ TSNode self,+ TSPoint range_start,+ TSPoint range_end,+ bool include_anonymous+) {+ TSNode node = self;+ TSNode last_visible_node = self;++ bool did_descend = true;+ while (did_descend) {+ did_descend = false;++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&node);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ TSPoint node_end = iterator.position.extent;++ // The end of this node must extend far enough forward to touch+ // the end of the range+ if (point_lt(node_end, range_end)) continue;++ // ...and exceed the start of the range, unless the node itself is+ // empty, in which case it must at least be equal to the start of the range.+ bool is_empty = point_eq(ts_node_start_point(child), node_end);+ if (is_empty ? point_lt(node_end, range_start) : point_lte(node_end, range_start)) {+ continue;+ }++ // The start of this node must extend far enough backward to+ // touch the start of the range.+ if (point_lt(range_start, ts_node_start_point(child))) break;++ node = child;+ if (ts_node__is_relevant(node, include_anonymous)) {+ last_visible_node = node;+ }+ did_descend = true;+ break;+ }+ }++ return last_visible_node;+}++// TSNode - public++uint32_t ts_node_end_byte(TSNode self) {+ return ts_node_start_byte(self) + ts_subtree_size(ts_node__subtree(self)).bytes;+}++TSPoint ts_node_end_point(TSNode self) {+ return point_add(ts_node_start_point(self), ts_subtree_size(ts_node__subtree(self)).extent);+}++TSSymbol ts_node_symbol(TSNode self) {+ TSSymbol symbol = ts_node__alias(&self);+ if (!symbol) symbol = ts_subtree_symbol(ts_node__subtree(self));+ return ts_language_public_symbol(self.tree->language, symbol);+}++const char *ts_node_type(TSNode self) {+ TSSymbol symbol = ts_node__alias(&self);+ if (!symbol) symbol = ts_subtree_symbol(ts_node__subtree(self));+ return ts_language_symbol_name(self.tree->language, symbol);+}++const TSLanguage *ts_node_language(TSNode self) {+ return self.tree->language;+}++TSSymbol ts_node_grammar_symbol(TSNode self) {+ return ts_subtree_symbol(ts_node__subtree(self));+}++const char *ts_node_grammar_type(TSNode self) {+ TSSymbol symbol = ts_subtree_symbol(ts_node__subtree(self));+ return ts_language_symbol_name(self.tree->language, symbol);+}++char *ts_node_string(TSNode self) {+ TSSymbol alias_symbol = ts_node__alias(&self);+ return ts_subtree_string(+ ts_node__subtree(self),+ alias_symbol,+ ts_language_symbol_metadata(self.tree->language, alias_symbol).visible,+ self.tree->language,+ false+ );+}++bool ts_node_eq(TSNode self, TSNode other) {+ return self.tree == other.tree && self.id == other.id;+}++bool ts_node_is_null(TSNode self) {+ return self.id == 0;+}++bool ts_node_is_extra(TSNode self) {+ return ts_subtree_extra(ts_node__subtree(self));+}++bool ts_node_is_named(TSNode self) {+ TSSymbol alias = ts_node__alias(&self);+ return alias+ ? ts_language_symbol_metadata(self.tree->language, alias).named+ : ts_subtree_named(ts_node__subtree(self));+}++bool ts_node_is_missing(TSNode self) {+ return ts_subtree_missing(ts_node__subtree(self));+}++bool ts_node_has_changes(TSNode self) {+ return ts_subtree_has_changes(ts_node__subtree(self));+}++bool ts_node_has_error(TSNode self) {+ return ts_subtree_error_cost(ts_node__subtree(self)) > 0;+}++bool ts_node_is_error(TSNode self) {+ TSSymbol symbol = ts_node_symbol(self);+ return symbol == ts_builtin_sym_error;+}++uint32_t ts_node_descendant_count(TSNode self) {+ return ts_subtree_visible_descendant_count(ts_node__subtree(self)) + 1;+}++TSStateId ts_node_parse_state(TSNode self) {+ return ts_subtree_parse_state(ts_node__subtree(self));+}++TSStateId ts_node_next_parse_state(TSNode self) {+ const TSLanguage *language = self.tree->language;+ uint16_t state = ts_node_parse_state(self);+ if (state == TS_TREE_STATE_NONE) {+ return TS_TREE_STATE_NONE;+ }+ uint16_t symbol = ts_node_grammar_symbol(self);+ return ts_language_next_state(language, state, symbol);+}++TSNode ts_node_parent(TSNode self) {+ TSNode node = ts_tree_root_node(self.tree);+ if (node.id == self.id) return ts_node__null();++ while (true) {+ TSNode next_node = ts_node_child_containing_descendant(node, self);+ if (ts_node_is_null(next_node)) break;+ node = next_node;+ }++ return node;+}++TSNode ts_node_child_containing_descendant(TSNode self, TSNode descendant) {+ uint32_t start_byte = ts_node_start_byte(descendant);+ uint32_t end_byte = ts_node_end_byte(descendant);++ do {+ NodeChildIterator iter = ts_node_iterate_children(&self);+ do {+ if (+ !ts_node_child_iterator_next(&iter, &self)+ || ts_node_start_byte(self) > start_byte+ || self.id == descendant.id+ ) {+ return ts_node__null();+ }++ // Here we check the current self node and *all* of its zero-width token siblings that follow.+ // If any of these nodes contain the target subnode, we return that node. Otherwise, we restore the node we started at+ // for the loop condition, and that will continue with the next *non-zero-width* sibling.+ TSNode old = self;+ // While the next sibling is a zero-width token+ while (ts_node_child_iterator_next_sibling_is_empty_adjacent(&iter, self)) {+ TSNode current_node = ts_node_child_containing_descendant(self, descendant);+ // If the target child is in self, return it+ if (!ts_node_is_null(current_node)) {+ return current_node;+ }+ ts_node_child_iterator_next(&iter, &self);+ if (self.id == descendant.id) {+ return ts_node__null();+ }+ }+ self = old;+ } while (iter.position.bytes < end_byte || ts_node_child_count(self) == 0);+ } while (!ts_node__is_relevant(self, true));++ return self;+}++TSNode ts_node_child_with_descendant(TSNode self, TSNode descendant) {+ uint32_t start_byte = ts_node_start_byte(descendant);+ uint32_t end_byte = ts_node_end_byte(descendant);++ do {+ NodeChildIterator iter = ts_node_iterate_children(&self);+ do {+ if (+ !ts_node_child_iterator_next(&iter, &self)+ || ts_node_start_byte(self) > start_byte+ ) {+ return ts_node__null();+ }+ if (self.id == descendant.id) {+ return self;+ }++ // Here we check the current self node and *all* of its zero-width token siblings that follow.+ // If any of these nodes contain the target subnode, we return that node. Otherwise, we restore the node we started at+ // for the loop condition, and that will continue with the next *non-zero-width* sibling.+ TSNode old = self;+ // While the next sibling is a zero-width token+ while (ts_node_child_iterator_next_sibling_is_empty_adjacent(&iter, self)) {+ TSNode current_node = ts_node_child_with_descendant(self, descendant);+ // If the target child is in self, return it+ if (!ts_node_is_null(current_node)) {+ return current_node;+ }+ ts_node_child_iterator_next(&iter, &self);+ if (self.id == descendant.id) {+ return self;+ }+ }+ self = old;+ } while (iter.position.bytes < end_byte || ts_node_child_count(self) == 0);+ } while (!ts_node__is_relevant(self, true));++ return self;+}++TSNode ts_node_child(TSNode self, uint32_t child_index) {+ return ts_node__child(self, child_index, true);+}++TSNode ts_node_named_child(TSNode self, uint32_t child_index) {+ return ts_node__child(self, child_index, false);+}++TSNode ts_node_child_by_field_id(TSNode self, TSFieldId field_id) {+recur:+ if (!field_id || ts_node_child_count(self) == 0) return ts_node__null();++ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(+ self.tree->language,+ ts_node__subtree(self).ptr->production_id,+ &field_map,+ &field_map_end+ );+ if (field_map == field_map_end) return ts_node__null();++ // The field mappings are sorted by their field id. Scan all+ // the mappings to find the ones for the given field id.+ while (field_map->field_id < field_id) {+ field_map++;+ if (field_map == field_map_end) return ts_node__null();+ }+ while (field_map_end[-1].field_id > field_id) {+ field_map_end--;+ if (field_map == field_map_end) return ts_node__null();+ }++ TSNode child;+ NodeChildIterator iterator = ts_node_iterate_children(&self);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (!ts_subtree_extra(ts_node__subtree(child))) {+ uint32_t index = iterator.structural_child_index - 1;+ if (index < field_map->child_index) continue;++ // Hidden nodes' fields are "inherited" by their visible parent.+ if (field_map->inherited) {++ // If this is the *last* possible child node for this field,+ // then perform a tail call to avoid recursion.+ if (field_map + 1 == field_map_end) {+ self = child;+ goto recur;+ }++ // Otherwise, descend into this child, but if it doesn't contain+ // the field, continue searching subsequent children.+ else {+ TSNode result = ts_node_child_by_field_id(child, field_id);+ if (result.id) return result;+ field_map++;+ if (field_map == field_map_end) return ts_node__null();+ }+ }++ else if (ts_node__is_relevant(child, true)) {+ return child;+ }++ // If the field refers to a hidden node with visible children,+ // return the first visible child.+ else if (ts_node_child_count(child) > 0 ) {+ return ts_node_child(child, 0);+ }++ // Otherwise, continue searching subsequent children.+ else {+ field_map++;+ if (field_map == field_map_end) return ts_node__null();+ }+ }+ }++ return ts_node__null();+}++static inline const char *ts_node__field_name_from_language(TSNode self, uint32_t structural_child_index) {+ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(+ self.tree->language,+ ts_node__subtree(self).ptr->production_id,+ &field_map,+ &field_map_end+ );+ for (; field_map != field_map_end; field_map++) {+ if (!field_map->inherited && field_map->child_index == structural_child_index) {+ return self.tree->language->field_names[field_map->field_id];+ }+ }+ return NULL;+}++const char *ts_node_field_name_for_child(TSNode self, uint32_t child_index) {+ TSNode result = self;+ bool did_descend = true;+ const char *inherited_field_name = NULL;++ while (did_descend) {+ did_descend = false;++ TSNode child;+ uint32_t index = 0;+ NodeChildIterator iterator = ts_node_iterate_children(&result);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (ts_node__is_relevant(child, true)) {+ if (index == child_index) {+ if (ts_node_is_extra(child)) {+ return NULL;+ }+ const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);+ if (field_name) return field_name;+ return inherited_field_name;+ }+ index++;+ } else {+ uint32_t grandchild_index = child_index - index;+ uint32_t grandchild_count = ts_node__relevant_child_count(child, true);+ if (grandchild_index < grandchild_count) {+ const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);+ if (field_name) inherited_field_name = field_name;++ did_descend = true;+ result = child;+ child_index = grandchild_index;+ break;+ }+ index += grandchild_count;+ }+ }+ }++ return NULL;+}++const char *ts_node_field_name_for_named_child(TSNode self, uint32_t named_child_index) {+ TSNode result = self;+ bool did_descend = true;+ const char *inherited_field_name = NULL;++ while (did_descend) {+ did_descend = false;++ TSNode child;+ uint32_t index = 0;+ NodeChildIterator iterator = ts_node_iterate_children(&result);+ while (ts_node_child_iterator_next(&iterator, &child)) {+ if (ts_node__is_relevant(child, false)) {+ if (index == named_child_index) {+ if (ts_node_is_extra(child)) {+ return NULL;+ }+ const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);+ if (field_name) return field_name;+ return inherited_field_name;+ }+ index++;+ } else {+ uint32_t named_grandchild_index = named_child_index - index;+ uint32_t grandchild_count = ts_node__relevant_child_count(child, false);+ if (named_grandchild_index < grandchild_count) {+ const char *field_name = ts_node__field_name_from_language(result, iterator.structural_child_index - 1);+ if (field_name) inherited_field_name = field_name;++ did_descend = true;+ result = child;+ named_child_index = named_grandchild_index;+ break;+ }+ index += grandchild_count;+ }+ }+ }++ return NULL;+}++TSNode ts_node_child_by_field_name(+ TSNode self,+ const char *name,+ uint32_t name_length+) {+ TSFieldId field_id = ts_language_field_id_for_name(+ self.tree->language,+ name,+ name_length+ );+ return ts_node_child_by_field_id(self, field_id);+}++uint32_t ts_node_child_count(TSNode self) {+ Subtree tree = ts_node__subtree(self);+ if (ts_subtree_child_count(tree) > 0) {+ return tree.ptr->visible_child_count;+ } else {+ return 0;+ }+}++uint32_t ts_node_named_child_count(TSNode self) {+ Subtree tree = ts_node__subtree(self);+ if (ts_subtree_child_count(tree) > 0) {+ return tree.ptr->named_child_count;+ } else {+ return 0;+ }+}++TSNode ts_node_next_sibling(TSNode self) {+ return ts_node__next_sibling(self, true);+}++TSNode ts_node_next_named_sibling(TSNode self) {+ return ts_node__next_sibling(self, false);+}++TSNode ts_node_prev_sibling(TSNode self) {+ return ts_node__prev_sibling(self, true);+}++TSNode ts_node_prev_named_sibling(TSNode self) {+ return ts_node__prev_sibling(self, false);+}++TSNode ts_node_first_child_for_byte(TSNode self, uint32_t byte) {+ return ts_node__first_child_for_byte(self, byte, true);+}++TSNode ts_node_first_named_child_for_byte(TSNode self, uint32_t byte) {+ return ts_node__first_child_for_byte(self, byte, false);+}++TSNode ts_node_descendant_for_byte_range(+ TSNode self,+ uint32_t start,+ uint32_t end+) {+ return ts_node__descendant_for_byte_range(self, start, end, true);+}++TSNode ts_node_named_descendant_for_byte_range(+ TSNode self,+ uint32_t start,+ uint32_t end+) {+ return ts_node__descendant_for_byte_range(self, start, end, false);+}++TSNode ts_node_descendant_for_point_range(+ TSNode self,+ TSPoint start,+ TSPoint end+) {+ return ts_node__descendant_for_point_range(self, start, end, true);+}++TSNode ts_node_named_descendant_for_point_range(+ TSNode self,+ TSPoint start,+ TSPoint end+) {+ return ts_node__descendant_for_point_range(self, start, end, false);+}++void ts_node_edit(TSNode *self, const TSInputEdit *edit) {+ uint32_t start_byte = ts_node_start_byte(*self);+ TSPoint start_point = ts_node_start_point(*self);++ if (start_byte >= edit->old_end_byte) {+ start_byte = edit->new_end_byte + (start_byte - edit->old_end_byte);+ start_point = point_add(edit->new_end_point, point_sub(start_point, edit->old_end_point));+ } else if (start_byte > edit->start_byte) {+ start_byte = edit->new_end_byte;+ start_point = edit->new_end_point;+ }++ self->context[0] = start_byte;+ self->context[1] = start_point.row;+ self->context[2] = start_point.column;+}
+ vendor/tree-sitter/lib/src/parser.c view
@@ -0,0 +1,2167 @@+#define _POSIX_C_SOURCE 200112L++#include <time.h>+#include <stdio.h>+#include <limits.h>+#include <stdbool.h>+#include <inttypes.h>+#include "tree_sitter/api.h"+#include "./alloc.h"+#include "./array.h"+#include "./atomic.h"+#include "./clock.h"+#include "./error_costs.h"+#include "./get_changed_ranges.h"+#include "./language.h"+#include "./length.h"+#include "./lexer.h"+#include "./reduce_action.h"+#include "./reusable_node.h"+#include "./stack.h"+#include "./subtree.h"+#include "./tree.h"+#include "./ts_assert.h"+#include "./wasm_store.h"++#define LOG(...) \+ if (self->lexer.logger.log || self->dot_graph_file) { \+ snprintf(self->lexer.debug_buffer, TREE_SITTER_SERIALIZATION_BUFFER_SIZE, __VA_ARGS__); \+ ts_parser__log(self); \+ }++#define LOG_LOOKAHEAD(symbol_name, size) \+ if (self->lexer.logger.log || self->dot_graph_file) { \+ char *buf = self->lexer.debug_buffer; \+ const char *symbol = symbol_name; \+ int off = snprintf( \+ buf, \+ TREE_SITTER_SERIALIZATION_BUFFER_SIZE, \+ "lexed_lookahead sym:" \+ ); \+ for ( \+ int i = 0; \+ symbol[i] != '\0' \+ && off < TREE_SITTER_SERIALIZATION_BUFFER_SIZE; \+ i++ \+ ) { \+ switch (symbol[i]) { \+ case '\t': buf[off++] = '\\'; buf[off++] = 't'; break; \+ case '\n': buf[off++] = '\\'; buf[off++] = 'n'; break; \+ case '\v': buf[off++] = '\\'; buf[off++] = 'v'; break; \+ case '\f': buf[off++] = '\\'; buf[off++] = 'f'; break; \+ case '\r': buf[off++] = '\\'; buf[off++] = 'r'; break; \+ case '\\': buf[off++] = '\\'; buf[off++] = '\\'; break; \+ default: buf[off++] = symbol[i]; break; \+ } \+ } \+ snprintf( \+ buf + off, \+ TREE_SITTER_SERIALIZATION_BUFFER_SIZE - off, \+ ", size:%u", \+ size \+ ); \+ ts_parser__log(self); \+ }++#define LOG_STACK() \+ if (self->dot_graph_file) { \+ ts_stack_print_dot_graph(self->stack, self->language, self->dot_graph_file); \+ fputs("\n\n", self->dot_graph_file); \+ }++#define LOG_TREE(tree) \+ if (self->dot_graph_file) { \+ ts_subtree_print_dot_graph(tree, self->language, self->dot_graph_file); \+ fputs("\n", self->dot_graph_file); \+ }++#define SYM_NAME(symbol) ts_language_symbol_name(self->language, symbol)++#define TREE_NAME(tree) SYM_NAME(ts_subtree_symbol(tree))++static const unsigned MAX_VERSION_COUNT = 6;+static const unsigned MAX_VERSION_COUNT_OVERFLOW = 4;+static const unsigned MAX_SUMMARY_DEPTH = 16;+static const unsigned MAX_COST_DIFFERENCE = 16 * ERROR_COST_PER_SKIPPED_TREE;+static const unsigned OP_COUNT_PER_PARSER_TIMEOUT_CHECK = 100;++typedef struct {+ Subtree token;+ Subtree last_external_token;+ uint32_t byte_index;+} TokenCache;++struct TSParser {+ Lexer lexer;+ Stack *stack;+ SubtreePool tree_pool;+ const TSLanguage *language;+ TSWasmStore *wasm_store;+ ReduceActionSet reduce_actions;+ Subtree finished_tree;+ SubtreeArray trailing_extras;+ SubtreeArray trailing_extras2;+ SubtreeArray scratch_trees;+ TokenCache token_cache;+ ReusableNode reusable_node;+ void *external_scanner_payload;+ FILE *dot_graph_file;+ TSClock end_clock;+ TSDuration timeout_duration;+ unsigned accept_count;+ unsigned operation_count;+ const volatile size_t *cancellation_flag;+ Subtree old_tree;+ TSRangeArray included_range_differences;+ unsigned included_range_difference_index;+ bool has_scanner_error;+};++typedef struct {+ unsigned cost;+ unsigned node_count;+ int dynamic_precedence;+ bool is_in_error;+} ErrorStatus;++typedef enum {+ ErrorComparisonTakeLeft,+ ErrorComparisonPreferLeft,+ ErrorComparisonNone,+ ErrorComparisonPreferRight,+ ErrorComparisonTakeRight,+} ErrorComparison;++typedef struct {+ const char *string;+ uint32_t length;+} TSStringInput;++// StringInput++static const char *ts_string_input_read(+ void *_self,+ uint32_t byte,+ TSPoint point,+ uint32_t *length+) {+ (void)point;+ TSStringInput *self = (TSStringInput *)_self;+ if (byte >= self->length) {+ *length = 0;+ return "";+ } else {+ *length = self->length - byte;+ return self->string + byte;+ }+}++// Parser - Private++static void ts_parser__log(TSParser *self) {+ if (self->lexer.logger.log) {+ self->lexer.logger.log(+ self->lexer.logger.payload,+ TSLogTypeParse,+ self->lexer.debug_buffer+ );+ }++ if (self->dot_graph_file) {+ fprintf(self->dot_graph_file, "graph {\nlabel=\"");+ for (char *chr = &self->lexer.debug_buffer[0]; *chr != 0; chr++) {+ if (*chr == '"' || *chr == '\\') fputc('\\', self->dot_graph_file);+ fputc(*chr, self->dot_graph_file);+ }+ fprintf(self->dot_graph_file, "\"\n}\n\n");+ }+}++static bool ts_parser__breakdown_top_of_stack(+ TSParser *self,+ StackVersion version+) {+ bool did_break_down = false;+ bool pending = false;++ do {+ StackSliceArray pop = ts_stack_pop_pending(self->stack, version);+ if (!pop.size) break;++ did_break_down = true;+ pending = false;+ for (uint32_t i = 0; i < pop.size; i++) {+ StackSlice slice = pop.contents[i];+ TSStateId state = ts_stack_state(self->stack, slice.version);+ Subtree parent = *array_front(&slice.subtrees);++ for (uint32_t j = 0, n = ts_subtree_child_count(parent); j < n; j++) {+ Subtree child = ts_subtree_children(parent)[j];+ pending = ts_subtree_child_count(child) > 0;++ if (ts_subtree_is_error(child)) {+ state = ERROR_STATE;+ } else if (!ts_subtree_extra(child)) {+ state = ts_language_next_state(self->language, state, ts_subtree_symbol(child));+ }++ ts_subtree_retain(child);+ ts_stack_push(self->stack, slice.version, child, pending, state);+ }++ for (uint32_t j = 1; j < slice.subtrees.size; j++) {+ Subtree tree = slice.subtrees.contents[j];+ ts_stack_push(self->stack, slice.version, tree, false, state);+ }++ ts_subtree_release(&self->tree_pool, parent);+ array_delete(&slice.subtrees);++ LOG("breakdown_top_of_stack tree:%s", TREE_NAME(parent));+ LOG_STACK();+ }+ } while (pending);++ return did_break_down;+}++static void ts_parser__breakdown_lookahead(+ TSParser *self,+ Subtree *lookahead,+ TSStateId state,+ ReusableNode *reusable_node+) {+ bool did_descend = false;+ Subtree tree = reusable_node_tree(reusable_node);+ while (ts_subtree_child_count(tree) > 0 && ts_subtree_parse_state(tree) != state) {+ LOG("state_mismatch sym:%s", TREE_NAME(tree));+ reusable_node_descend(reusable_node);+ tree = reusable_node_tree(reusable_node);+ did_descend = true;+ }++ if (did_descend) {+ ts_subtree_release(&self->tree_pool, *lookahead);+ *lookahead = tree;+ ts_subtree_retain(*lookahead);+ }+}++static ErrorComparison ts_parser__compare_versions(+ TSParser *self,+ ErrorStatus a,+ ErrorStatus b+) {+ (void)self;+ if (!a.is_in_error && b.is_in_error) {+ if (a.cost < b.cost) {+ return ErrorComparisonTakeLeft;+ } else {+ return ErrorComparisonPreferLeft;+ }+ }++ if (a.is_in_error && !b.is_in_error) {+ if (b.cost < a.cost) {+ return ErrorComparisonTakeRight;+ } else {+ return ErrorComparisonPreferRight;+ }+ }++ if (a.cost < b.cost) {+ if ((b.cost - a.cost) * (1 + a.node_count) > MAX_COST_DIFFERENCE) {+ return ErrorComparisonTakeLeft;+ } else {+ return ErrorComparisonPreferLeft;+ }+ }++ if (b.cost < a.cost) {+ if ((a.cost - b.cost) * (1 + b.node_count) > MAX_COST_DIFFERENCE) {+ return ErrorComparisonTakeRight;+ } else {+ return ErrorComparisonPreferRight;+ }+ }++ if (a.dynamic_precedence > b.dynamic_precedence) return ErrorComparisonPreferLeft;+ if (b.dynamic_precedence > a.dynamic_precedence) return ErrorComparisonPreferRight;+ return ErrorComparisonNone;+}++static ErrorStatus ts_parser__version_status(+ TSParser *self,+ StackVersion version+) {+ unsigned cost = ts_stack_error_cost(self->stack, version);+ bool is_paused = ts_stack_is_paused(self->stack, version);+ if (is_paused) cost += ERROR_COST_PER_SKIPPED_TREE;+ return (ErrorStatus) {+ .cost = cost,+ .node_count = ts_stack_node_count_since_error(self->stack, version),+ .dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),+ .is_in_error = is_paused || ts_stack_state(self->stack, version) == ERROR_STATE+ };+}++static bool ts_parser__better_version_exists(+ TSParser *self,+ StackVersion version,+ bool is_in_error,+ unsigned cost+) {+ if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) <= cost) {+ return true;+ }++ Length position = ts_stack_position(self->stack, version);+ ErrorStatus status = {+ .cost = cost,+ .is_in_error = is_in_error,+ .dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),+ .node_count = ts_stack_node_count_since_error(self->stack, version),+ };++ for (StackVersion i = 0, n = ts_stack_version_count(self->stack); i < n; i++) {+ if (i == version ||+ !ts_stack_is_active(self->stack, i) ||+ ts_stack_position(self->stack, i).bytes < position.bytes) continue;+ ErrorStatus status_i = ts_parser__version_status(self, i);+ switch (ts_parser__compare_versions(self, status, status_i)) {+ case ErrorComparisonTakeRight:+ return true;+ case ErrorComparisonPreferRight:+ if (ts_stack_can_merge(self->stack, i, version)) return true;+ break;+ default:+ break;+ }+ }++ return false;+}++static bool ts_parser__call_main_lex_fn(TSParser *self, TSLexMode lex_mode) {+ if (ts_language_is_wasm(self->language)) {+ return ts_wasm_store_call_lex_main(self->wasm_store, lex_mode.lex_state);+ } else {+ return self->language->lex_fn(&self->lexer.data, lex_mode.lex_state);+ }+}++static bool ts_parser__call_keyword_lex_fn(TSParser *self, TSLexMode lex_mode) {+ if (ts_language_is_wasm(self->language)) {+ return ts_wasm_store_call_lex_keyword(self->wasm_store, 0);+ } else {+ return self->language->keyword_lex_fn(&self->lexer.data, 0);+ }+}++static void ts_parser__external_scanner_create(+ TSParser *self+) {+ if (self->language && self->language->external_scanner.states) {+ if (ts_language_is_wasm(self->language)) {+ self->external_scanner_payload = (void *)(uintptr_t)ts_wasm_store_call_scanner_create(+ self->wasm_store+ );+ if (ts_wasm_store_has_error(self->wasm_store)) {+ self->has_scanner_error = true;+ }+ } else if (self->language->external_scanner.create) {+ self->external_scanner_payload = self->language->external_scanner.create();+ }+ }+}++static void ts_parser__external_scanner_destroy(+ TSParser *self+) {+ if (+ self->language &&+ self->external_scanner_payload &&+ self->language->external_scanner.destroy &&+ !ts_language_is_wasm(self->language)+ ) {+ self->language->external_scanner.destroy(+ self->external_scanner_payload+ );+ }+ self->external_scanner_payload = NULL;+}++static unsigned ts_parser__external_scanner_serialize(+ TSParser *self+) {+ if (ts_language_is_wasm(self->language)) {+ return ts_wasm_store_call_scanner_serialize(+ self->wasm_store,+ (uintptr_t)self->external_scanner_payload,+ self->lexer.debug_buffer+ );+ } else {+ uint32_t length = self->language->external_scanner.serialize(+ self->external_scanner_payload,+ self->lexer.debug_buffer+ );+ ts_assert(length <= TREE_SITTER_SERIALIZATION_BUFFER_SIZE);+ return length;+ }+}++static void ts_parser__external_scanner_deserialize(+ TSParser *self,+ Subtree external_token+) {+ const char *data = NULL;+ uint32_t length = 0;+ if (external_token.ptr) {+ data = ts_external_scanner_state_data(&external_token.ptr->external_scanner_state);+ length = external_token.ptr->external_scanner_state.length;+ }++ if (ts_language_is_wasm(self->language)) {+ ts_wasm_store_call_scanner_deserialize(+ self->wasm_store,+ (uintptr_t)self->external_scanner_payload,+ data,+ length+ );+ if (ts_wasm_store_has_error(self->wasm_store)) {+ self->has_scanner_error = true;+ }+ } else {+ self->language->external_scanner.deserialize(+ self->external_scanner_payload,+ data,+ length+ );+ }+}++static bool ts_parser__external_scanner_scan(+ TSParser *self,+ TSStateId external_lex_state+) {+ if (ts_language_is_wasm(self->language)) {+ bool result = ts_wasm_store_call_scanner_scan(+ self->wasm_store,+ (uintptr_t)self->external_scanner_payload,+ external_lex_state * self->language->external_token_count+ );+ if (ts_wasm_store_has_error(self->wasm_store)) {+ self->has_scanner_error = true;+ }+ return result;+ } else {+ const bool *valid_external_tokens = ts_language_enabled_external_tokens(+ self->language,+ external_lex_state+ );+ return self->language->external_scanner.scan(+ self->external_scanner_payload,+ &self->lexer.data,+ valid_external_tokens+ );+ }+}++static bool ts_parser__can_reuse_first_leaf(+ TSParser *self,+ TSStateId state,+ Subtree tree,+ TableEntry *table_entry+) {+ TSLexMode current_lex_mode = self->language->lex_modes[state];+ TSSymbol leaf_symbol = ts_subtree_leaf_symbol(tree);+ TSStateId leaf_state = ts_subtree_leaf_parse_state(tree);+ TSLexMode leaf_lex_mode = self->language->lex_modes[leaf_state];++ // At the end of a non-terminal extra node, the lexer normally returns+ // NULL, which indicates that the parser should look for a reduce action+ // at symbol `0`. Avoid reusing tokens in this situation to ensure that+ // the same thing happens when incrementally reparsing.+ if (current_lex_mode.lex_state == (uint16_t)(-1)) return false;++ // If the token was created in a state with the same set of lookaheads, it is reusable.+ if (+ table_entry->action_count > 0 &&+ memcmp(&leaf_lex_mode, ¤t_lex_mode, sizeof(TSLexMode)) == 0 &&+ (+ leaf_symbol != self->language->keyword_capture_token ||+ (!ts_subtree_is_keyword(tree) && ts_subtree_parse_state(tree) == state)+ )+ ) return true;++ // Empty tokens are not reusable in states with different lookaheads.+ if (ts_subtree_size(tree).bytes == 0 && leaf_symbol != ts_builtin_sym_end) return false;++ // If the current state allows external tokens or other tokens that conflict with this+ // token, this token is not reusable.+ return current_lex_mode.external_lex_state == 0 && table_entry->is_reusable;+}++static Subtree ts_parser__lex(+ TSParser *self,+ StackVersion version,+ TSStateId parse_state+) {+ TSLexMode lex_mode = self->language->lex_modes[parse_state];+ if (lex_mode.lex_state == (uint16_t)-1) {+ LOG("no_lookahead_after_non_terminal_extra");+ return NULL_SUBTREE;+ }++ const Length start_position = ts_stack_position(self->stack, version);+ const Subtree external_token = ts_stack_last_external_token(self->stack, version);++ bool found_external_token = false;+ bool error_mode = parse_state == ERROR_STATE;+ bool skipped_error = false;+ bool called_get_column = false;+ int32_t first_error_character = 0;+ Length error_start_position = length_zero();+ Length error_end_position = length_zero();+ uint32_t lookahead_end_byte = 0;+ uint32_t external_scanner_state_len = 0;+ bool external_scanner_state_changed = false;+ ts_lexer_reset(&self->lexer, start_position);++ for (;;) {+ bool found_token = false;+ Length current_position = self->lexer.current_position;++ if (lex_mode.external_lex_state != 0) {+ LOG(+ "lex_external state:%d, row:%u, column:%u",+ lex_mode.external_lex_state,+ current_position.extent.row,+ current_position.extent.column+ );+ ts_lexer_start(&self->lexer);+ ts_parser__external_scanner_deserialize(self, external_token);+ found_token = ts_parser__external_scanner_scan(self, lex_mode.external_lex_state);+ if (self->has_scanner_error) return NULL_SUBTREE;+ ts_lexer_finish(&self->lexer, &lookahead_end_byte);++ if (found_token) {+ external_scanner_state_len = ts_parser__external_scanner_serialize(self);+ external_scanner_state_changed = !ts_external_scanner_state_eq(+ ts_subtree_external_scanner_state(external_token),+ self->lexer.debug_buffer,+ external_scanner_state_len+ );++ // When recovering from an error, ignore any zero-length external tokens+ // unless they have changed the external scanner's state. This helps to+ // avoid infinite loops which could otherwise occur, because the lexer is+ // looking for any possible token, instead of looking for the specific set of+ // tokens that are valid in some parse state.+ //+ // Note that it's possible that the token end position may be *before* the+ // original position of the lexer because of the way that tokens are positioned+ // at included range boundaries: when a token is terminated at the start of+ // an included range, it is marked as ending at the *end* of the preceding+ // included range.+ if (+ self->lexer.token_end_position.bytes <= current_position.bytes &&+ (error_mode || !ts_stack_has_advanced_since_error(self->stack, version)) &&+ !external_scanner_state_changed+ ) {+ LOG(+ "ignore_empty_external_token symbol:%s",+ SYM_NAME(self->language->external_scanner.symbol_map[self->lexer.data.result_symbol])+ )+ found_token = false;+ }+ }++ if (found_token) {+ found_external_token = true;+ called_get_column = self->lexer.did_get_column;+ break;+ }++ ts_lexer_reset(&self->lexer, current_position);+ }++ LOG(+ "lex_internal state:%d, row:%u, column:%u",+ lex_mode.lex_state,+ current_position.extent.row,+ current_position.extent.column+ );+ ts_lexer_start(&self->lexer);+ found_token = ts_parser__call_main_lex_fn(self, lex_mode);+ ts_lexer_finish(&self->lexer, &lookahead_end_byte);+ if (found_token) break;++ if (!error_mode) {+ error_mode = true;+ lex_mode = self->language->lex_modes[ERROR_STATE];+ ts_lexer_reset(&self->lexer, start_position);+ continue;+ }++ if (!skipped_error) {+ LOG("skip_unrecognized_character");+ skipped_error = true;+ error_start_position = self->lexer.token_start_position;+ error_end_position = self->lexer.token_start_position;+ first_error_character = self->lexer.data.lookahead;+ }++ if (self->lexer.current_position.bytes == error_end_position.bytes) {+ if (self->lexer.data.eof(&self->lexer.data)) {+ self->lexer.data.result_symbol = ts_builtin_sym_error;+ break;+ }+ self->lexer.data.advance(&self->lexer.data, false);+ }++ error_end_position = self->lexer.current_position;+ }++ Subtree result;+ if (skipped_error) {+ Length padding = length_sub(error_start_position, start_position);+ Length size = length_sub(error_end_position, error_start_position);+ uint32_t lookahead_bytes = lookahead_end_byte - error_end_position.bytes;+ result = ts_subtree_new_error(+ &self->tree_pool,+ first_error_character,+ padding,+ size,+ lookahead_bytes,+ parse_state,+ self->language+ );+ } else {+ bool is_keyword = false;+ TSSymbol symbol = self->lexer.data.result_symbol;+ Length padding = length_sub(self->lexer.token_start_position, start_position);+ Length size = length_sub(self->lexer.token_end_position, self->lexer.token_start_position);+ uint32_t lookahead_bytes = lookahead_end_byte - self->lexer.token_end_position.bytes;++ if (found_external_token) {+ symbol = self->language->external_scanner.symbol_map[symbol];+ } else if (symbol == self->language->keyword_capture_token && symbol != 0) {+ uint32_t end_byte = self->lexer.token_end_position.bytes;+ ts_lexer_reset(&self->lexer, self->lexer.token_start_position);+ ts_lexer_start(&self->lexer);++ is_keyword = ts_parser__call_keyword_lex_fn(self, lex_mode);++ if (+ is_keyword &&+ self->lexer.token_end_position.bytes == end_byte &&+ ts_language_has_actions(self->language, parse_state, self->lexer.data.result_symbol)+ ) {+ symbol = self->lexer.data.result_symbol;+ }+ }++ result = ts_subtree_new_leaf(+ &self->tree_pool,+ symbol,+ padding,+ size,+ lookahead_bytes,+ parse_state,+ found_external_token,+ called_get_column,+ is_keyword,+ self->language+ );++ if (found_external_token) {+ MutableSubtree mut_result = ts_subtree_to_mut_unsafe(result);+ ts_external_scanner_state_init(+ &mut_result.ptr->external_scanner_state,+ self->lexer.debug_buffer,+ external_scanner_state_len+ );+ mut_result.ptr->has_external_scanner_state_change = external_scanner_state_changed;+ }+ }++ LOG_LOOKAHEAD(+ SYM_NAME(ts_subtree_symbol(result)),+ ts_subtree_total_size(result).bytes+ );+ return result;+}++static Subtree ts_parser__get_cached_token(+ TSParser *self,+ TSStateId state,+ size_t position,+ Subtree last_external_token,+ TableEntry *table_entry+) {+ TokenCache *cache = &self->token_cache;+ if (+ cache->token.ptr && cache->byte_index == position &&+ ts_subtree_external_scanner_state_eq(cache->last_external_token, last_external_token)+ ) {+ ts_language_table_entry(self->language, state, ts_subtree_symbol(cache->token), table_entry);+ if (ts_parser__can_reuse_first_leaf(self, state, cache->token, table_entry)) {+ ts_subtree_retain(cache->token);+ return cache->token;+ }+ }+ return NULL_SUBTREE;+}++static void ts_parser__set_cached_token(+ TSParser *self,+ uint32_t byte_index,+ Subtree last_external_token,+ Subtree token+) {+ TokenCache *cache = &self->token_cache;+ if (token.ptr) ts_subtree_retain(token);+ if (last_external_token.ptr) ts_subtree_retain(last_external_token);+ if (cache->token.ptr) ts_subtree_release(&self->tree_pool, cache->token);+ if (cache->last_external_token.ptr) ts_subtree_release(&self->tree_pool, cache->last_external_token);+ cache->token = token;+ cache->byte_index = byte_index;+ cache->last_external_token = last_external_token;+}++static bool ts_parser__has_included_range_difference(+ const TSParser *self,+ uint32_t start_position,+ uint32_t end_position+) {+ return ts_range_array_intersects(+ &self->included_range_differences,+ self->included_range_difference_index,+ start_position,+ end_position+ );+}++static Subtree ts_parser__reuse_node(+ TSParser *self,+ StackVersion version,+ TSStateId *state,+ uint32_t position,+ Subtree last_external_token,+ TableEntry *table_entry+) {+ Subtree result;+ while ((result = reusable_node_tree(&self->reusable_node)).ptr) {+ uint32_t byte_offset = reusable_node_byte_offset(&self->reusable_node);+ uint32_t end_byte_offset = byte_offset + ts_subtree_total_bytes(result);++ // Do not reuse an EOF node if the included ranges array has changes+ // later on in the file.+ if (ts_subtree_is_eof(result)) end_byte_offset = UINT32_MAX;++ if (byte_offset > position) {+ LOG("before_reusable_node symbol:%s", TREE_NAME(result));+ break;+ }++ if (byte_offset < position) {+ LOG("past_reusable_node symbol:%s", TREE_NAME(result));+ if (end_byte_offset <= position || !reusable_node_descend(&self->reusable_node)) {+ reusable_node_advance(&self->reusable_node);+ }+ continue;+ }++ if (!ts_subtree_external_scanner_state_eq(self->reusable_node.last_external_token, last_external_token)) {+ LOG("reusable_node_has_different_external_scanner_state symbol:%s", TREE_NAME(result));+ reusable_node_advance(&self->reusable_node);+ continue;+ }++ const char *reason = NULL;+ if (ts_subtree_has_changes(result)) {+ reason = "has_changes";+ } else if (ts_subtree_is_error(result)) {+ reason = "is_error";+ } else if (ts_subtree_missing(result)) {+ reason = "is_missing";+ } else if (ts_subtree_is_fragile(result)) {+ reason = "is_fragile";+ } else if (ts_parser__has_included_range_difference(self, byte_offset, end_byte_offset)) {+ reason = "contains_different_included_range";+ }++ if (reason) {+ LOG("cant_reuse_node_%s tree:%s", reason, TREE_NAME(result));+ if (!reusable_node_descend(&self->reusable_node)) {+ reusable_node_advance(&self->reusable_node);+ ts_parser__breakdown_top_of_stack(self, version);+ *state = ts_stack_state(self->stack, version);+ }+ continue;+ }++ TSSymbol leaf_symbol = ts_subtree_leaf_symbol(result);+ ts_language_table_entry(self->language, *state, leaf_symbol, table_entry);+ if (!ts_parser__can_reuse_first_leaf(self, *state, result, table_entry)) {+ LOG(+ "cant_reuse_node symbol:%s, first_leaf_symbol:%s",+ TREE_NAME(result),+ SYM_NAME(leaf_symbol)+ );+ reusable_node_advance_past_leaf(&self->reusable_node);+ break;+ }++ LOG("reuse_node symbol:%s", TREE_NAME(result));+ ts_subtree_retain(result);+ return result;+ }++ return NULL_SUBTREE;+}++// Determine if a given tree should be replaced by an alternative tree.+//+// The decision is based on the trees' error costs (if any), their dynamic precedence,+// and finally, as a default, by a recursive comparison of the trees' symbols.+static bool ts_parser__select_tree(TSParser *self, Subtree left, Subtree right) {+ if (!left.ptr) return true;+ if (!right.ptr) return false;++ if (ts_subtree_error_cost(right) < ts_subtree_error_cost(left)) {+ LOG("select_smaller_error symbol:%s, over_symbol:%s", TREE_NAME(right), TREE_NAME(left));+ return true;+ }++ if (ts_subtree_error_cost(left) < ts_subtree_error_cost(right)) {+ LOG("select_smaller_error symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));+ return false;+ }++ if (ts_subtree_dynamic_precedence(right) > ts_subtree_dynamic_precedence(left)) {+ LOG("select_higher_precedence symbol:%s, prec:%" PRId32 ", over_symbol:%s, other_prec:%" PRId32,+ TREE_NAME(right), ts_subtree_dynamic_precedence(right), TREE_NAME(left),+ ts_subtree_dynamic_precedence(left));+ return true;+ }++ if (ts_subtree_dynamic_precedence(left) > ts_subtree_dynamic_precedence(right)) {+ LOG("select_higher_precedence symbol:%s, prec:%" PRId32 ", over_symbol:%s, other_prec:%" PRId32,+ TREE_NAME(left), ts_subtree_dynamic_precedence(left), TREE_NAME(right),+ ts_subtree_dynamic_precedence(right));+ return false;+ }++ if (ts_subtree_error_cost(left) > 0) return true;++ int comparison = ts_subtree_compare(left, right, &self->tree_pool);+ switch (comparison) {+ case -1:+ LOG("select_earlier symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));+ return false;+ break;+ case 1:+ LOG("select_earlier symbol:%s, over_symbol:%s", TREE_NAME(right), TREE_NAME(left));+ return true;+ default:+ LOG("select_existing symbol:%s, over_symbol:%s", TREE_NAME(left), TREE_NAME(right));+ return false;+ }+}++// Determine if a given tree's children should be replaced by an alternative+// array of children.+static bool ts_parser__select_children(+ TSParser *self,+ Subtree left,+ const SubtreeArray *children+) {+ array_assign(&self->scratch_trees, children);++ // Create a temporary subtree using the scratch trees array. This node does+ // not perform any allocation except for possibly growing the array to make+ // room for its own heap data. The scratch tree is never explicitly released,+ // so the same 'scratch trees' array can be reused again later.+ MutableSubtree scratch_tree = ts_subtree_new_node(+ ts_subtree_symbol(left),+ &self->scratch_trees,+ 0,+ self->language+ );++ return ts_parser__select_tree(+ self,+ left,+ ts_subtree_from_mut(scratch_tree)+ );+}++static void ts_parser__shift(+ TSParser *self,+ StackVersion version,+ TSStateId state,+ Subtree lookahead,+ bool extra+) {+ bool is_leaf = ts_subtree_child_count(lookahead) == 0;+ Subtree subtree_to_push = lookahead;+ if (extra != ts_subtree_extra(lookahead) && is_leaf) {+ MutableSubtree result = ts_subtree_make_mut(&self->tree_pool, lookahead);+ ts_subtree_set_extra(&result, extra);+ subtree_to_push = ts_subtree_from_mut(result);+ }++ ts_stack_push(self->stack, version, subtree_to_push, !is_leaf, state);+ if (ts_subtree_has_external_tokens(subtree_to_push)) {+ ts_stack_set_last_external_token(+ self->stack, version, ts_subtree_last_external_token(subtree_to_push)+ );+ }+}++static StackVersion ts_parser__reduce(+ TSParser *self,+ StackVersion version,+ TSSymbol symbol,+ uint32_t count,+ int dynamic_precedence,+ uint16_t production_id,+ bool is_fragile,+ bool end_of_non_terminal_extra+) {+ uint32_t initial_version_count = ts_stack_version_count(self->stack);++ // Pop the given number of nodes from the given version of the parse stack.+ // If stack versions have previously merged, then there may be more than one+ // path back through the stack. For each path, create a new parent node to+ // contain the popped children, and push it onto the stack in place of the+ // children.+ StackSliceArray pop = ts_stack_pop_count(self->stack, version, count);+ uint32_t removed_version_count = 0;+ for (uint32_t i = 0; i < pop.size; i++) {+ StackSlice slice = pop.contents[i];+ StackVersion slice_version = slice.version - removed_version_count;++ // This is where new versions are added to the parse stack. The versions+ // will all be sorted and truncated at the end of the outer parsing loop.+ // Allow the maximum version count to be temporarily exceeded, but only+ // by a limited threshold.+ if (slice_version > MAX_VERSION_COUNT + MAX_VERSION_COUNT_OVERFLOW) {+ ts_stack_remove_version(self->stack, slice_version);+ ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);+ removed_version_count++;+ while (i + 1 < pop.size) {+ StackSlice next_slice = pop.contents[i + 1];+ if (next_slice.version != slice.version) break;+ ts_subtree_array_delete(&self->tree_pool, &next_slice.subtrees);+ i++;+ }+ continue;+ }++ // Extra tokens on top of the stack should not be included in this new parent+ // node. They will be re-pushed onto the stack after the parent node is+ // created and pushed.+ SubtreeArray children = slice.subtrees;+ ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);++ MutableSubtree parent = ts_subtree_new_node(+ symbol, &children, production_id, self->language+ );++ // This pop operation may have caused multiple stack versions to collapse+ // into one, because they all diverged from a common state. In that case,+ // choose one of the arrays of trees to be the parent node's children, and+ // delete the rest of the tree arrays.+ while (i + 1 < pop.size) {+ StackSlice next_slice = pop.contents[i + 1];+ if (next_slice.version != slice.version) break;+ i++;++ SubtreeArray next_slice_children = next_slice.subtrees;+ ts_subtree_array_remove_trailing_extras(&next_slice_children, &self->trailing_extras2);++ if (ts_parser__select_children(+ self,+ ts_subtree_from_mut(parent),+ &next_slice_children+ )) {+ ts_subtree_array_clear(&self->tree_pool, &self->trailing_extras);+ ts_subtree_release(&self->tree_pool, ts_subtree_from_mut(parent));+ array_swap(&self->trailing_extras, &self->trailing_extras2);+ parent = ts_subtree_new_node(+ symbol, &next_slice_children, production_id, self->language+ );+ } else {+ array_clear(&self->trailing_extras2);+ ts_subtree_array_delete(&self->tree_pool, &next_slice.subtrees);+ }+ }++ TSStateId state = ts_stack_state(self->stack, slice_version);+ TSStateId next_state = ts_language_next_state(self->language, state, symbol);+ if (end_of_non_terminal_extra && next_state == state) {+ parent.ptr->extra = true;+ }+ if (is_fragile || pop.size > 1 || initial_version_count > 1) {+ parent.ptr->fragile_left = true;+ parent.ptr->fragile_right = true;+ parent.ptr->parse_state = TS_TREE_STATE_NONE;+ } else {+ parent.ptr->parse_state = state;+ }+ parent.ptr->dynamic_precedence += dynamic_precedence;++ // Push the parent node onto the stack, along with any extra tokens that+ // were previously on top of the stack.+ ts_stack_push(self->stack, slice_version, ts_subtree_from_mut(parent), false, next_state);+ for (uint32_t j = 0; j < self->trailing_extras.size; j++) {+ ts_stack_push(self->stack, slice_version, self->trailing_extras.contents[j], false, next_state);+ }++ for (StackVersion j = 0; j < slice_version; j++) {+ if (j == version) continue;+ if (ts_stack_merge(self->stack, j, slice_version)) {+ removed_version_count++;+ break;+ }+ }+ }++ // Return the first new stack version that was created.+ return ts_stack_version_count(self->stack) > initial_version_count+ ? initial_version_count+ : STACK_VERSION_NONE;+}++static void ts_parser__accept(+ TSParser *self,+ StackVersion version,+ Subtree lookahead+) {+ ts_assert(ts_subtree_is_eof(lookahead));+ ts_stack_push(self->stack, version, lookahead, false, 1);++ StackSliceArray pop = ts_stack_pop_all(self->stack, version);+ for (uint32_t i = 0; i < pop.size; i++) {+ SubtreeArray trees = pop.contents[i].subtrees;++ Subtree root = NULL_SUBTREE;+ for (uint32_t j = trees.size - 1; j + 1 > 0; j--) {+ Subtree tree = trees.contents[j];+ if (!ts_subtree_extra(tree)) {+ ts_assert(!tree.data.is_inline);+ uint32_t child_count = ts_subtree_child_count(tree);+ const Subtree *children = ts_subtree_children(tree);+ for (uint32_t k = 0; k < child_count; k++) {+ ts_subtree_retain(children[k]);+ }+ array_splice(&trees, j, 1, child_count, children);+ root = ts_subtree_from_mut(ts_subtree_new_node(+ ts_subtree_symbol(tree),+ &trees,+ tree.ptr->production_id,+ self->language+ ));+ ts_subtree_release(&self->tree_pool, tree);+ break;+ }+ }++ ts_assert(root.ptr);+ self->accept_count++;++ if (self->finished_tree.ptr) {+ if (ts_parser__select_tree(self, self->finished_tree, root)) {+ ts_subtree_release(&self->tree_pool, self->finished_tree);+ self->finished_tree = root;+ } else {+ ts_subtree_release(&self->tree_pool, root);+ }+ } else {+ self->finished_tree = root;+ }+ }++ ts_stack_remove_version(self->stack, pop.contents[0].version);+ ts_stack_halt(self->stack, version);+}++static bool ts_parser__do_all_potential_reductions(+ TSParser *self,+ StackVersion starting_version,+ TSSymbol lookahead_symbol+) {+ uint32_t initial_version_count = ts_stack_version_count(self->stack);++ bool can_shift_lookahead_symbol = false;+ StackVersion version = starting_version;+ for (unsigned i = 0; true; i++) {+ uint32_t version_count = ts_stack_version_count(self->stack);+ if (version >= version_count) break;++ bool merged = false;+ for (StackVersion j = initial_version_count; j < version; j++) {+ if (ts_stack_merge(self->stack, j, version)) {+ merged = true;+ break;+ }+ }+ if (merged) continue;++ TSStateId state = ts_stack_state(self->stack, version);+ bool has_shift_action = false;+ array_clear(&self->reduce_actions);++ TSSymbol first_symbol, end_symbol;+ if (lookahead_symbol != 0) {+ first_symbol = lookahead_symbol;+ end_symbol = lookahead_symbol + 1;+ } else {+ first_symbol = 1;+ end_symbol = self->language->token_count;+ }++ for (TSSymbol symbol = first_symbol; symbol < end_symbol; symbol++) {+ TableEntry entry;+ ts_language_table_entry(self->language, state, symbol, &entry);+ for (uint32_t j = 0; j < entry.action_count; j++) {+ TSParseAction action = entry.actions[j];+ switch (action.type) {+ case TSParseActionTypeShift:+ case TSParseActionTypeRecover:+ if (!action.shift.extra && !action.shift.repetition) has_shift_action = true;+ break;+ case TSParseActionTypeReduce:+ if (action.reduce.child_count > 0)+ ts_reduce_action_set_add(&self->reduce_actions, (ReduceAction) {+ .symbol = action.reduce.symbol,+ .count = action.reduce.child_count,+ .dynamic_precedence = action.reduce.dynamic_precedence,+ .production_id = action.reduce.production_id,+ });+ break;+ default:+ break;+ }+ }+ }++ StackVersion reduction_version = STACK_VERSION_NONE;+ for (uint32_t j = 0; j < self->reduce_actions.size; j++) {+ ReduceAction action = self->reduce_actions.contents[j];++ reduction_version = ts_parser__reduce(+ self, version, action.symbol, action.count,+ action.dynamic_precedence, action.production_id,+ true, false+ );+ }++ if (has_shift_action) {+ can_shift_lookahead_symbol = true;+ } else if (reduction_version != STACK_VERSION_NONE && i < MAX_VERSION_COUNT) {+ ts_stack_renumber_version(self->stack, reduction_version, version);+ continue;+ } else if (lookahead_symbol != 0) {+ ts_stack_remove_version(self->stack, version);+ }++ if (version == starting_version) {+ version = version_count;+ } else {+ version++;+ }+ }++ return can_shift_lookahead_symbol;+}++static bool ts_parser__recover_to_state(+ TSParser *self,+ StackVersion version,+ unsigned depth,+ TSStateId goal_state+) {+ StackSliceArray pop = ts_stack_pop_count(self->stack, version, depth);+ StackVersion previous_version = STACK_VERSION_NONE;++ for (unsigned i = 0; i < pop.size; i++) {+ StackSlice slice = pop.contents[i];++ if (slice.version == previous_version) {+ ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);+ array_erase(&pop, i--);+ continue;+ }++ if (ts_stack_state(self->stack, slice.version) != goal_state) {+ ts_stack_halt(self->stack, slice.version);+ ts_subtree_array_delete(&self->tree_pool, &slice.subtrees);+ array_erase(&pop, i--);+ continue;+ }++ SubtreeArray error_trees = ts_stack_pop_error(self->stack, slice.version);+ if (error_trees.size > 0) {+ ts_assert(error_trees.size == 1);+ Subtree error_tree = error_trees.contents[0];+ uint32_t error_child_count = ts_subtree_child_count(error_tree);+ if (error_child_count > 0) {+ array_splice(&slice.subtrees, 0, 0, error_child_count, ts_subtree_children(error_tree));+ for (unsigned j = 0; j < error_child_count; j++) {+ ts_subtree_retain(slice.subtrees.contents[j]);+ }+ }+ ts_subtree_array_delete(&self->tree_pool, &error_trees);+ }++ ts_subtree_array_remove_trailing_extras(&slice.subtrees, &self->trailing_extras);++ if (slice.subtrees.size > 0) {+ Subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);+ ts_stack_push(self->stack, slice.version, error, false, goal_state);+ } else {+ array_delete(&slice.subtrees);+ }++ for (unsigned j = 0; j < self->trailing_extras.size; j++) {+ Subtree tree = self->trailing_extras.contents[j];+ ts_stack_push(self->stack, slice.version, tree, false, goal_state);+ }++ previous_version = slice.version;+ }++ return previous_version != STACK_VERSION_NONE;+}++static void ts_parser__recover(+ TSParser *self,+ StackVersion version,+ Subtree lookahead+) {+ bool did_recover = false;+ unsigned previous_version_count = ts_stack_version_count(self->stack);+ Length position = ts_stack_position(self->stack, version);+ StackSummary *summary = ts_stack_get_summary(self->stack, version);+ unsigned node_count_since_error = ts_stack_node_count_since_error(self->stack, version);+ unsigned current_error_cost = ts_stack_error_cost(self->stack, version);++ // When the parser is in the error state, there are two strategies for recovering with a+ // given lookahead token:+ // 1. Find a previous state on the stack in which that lookahead token would be valid. Then,+ // create a new stack version that is in that state again. This entails popping all of the+ // subtrees that have been pushed onto the stack since that previous state, and wrapping+ // them in an ERROR node.+ // 2. Wrap the lookahead token in an ERROR node, push that ERROR node onto the stack, and+ // move on to the next lookahead token, remaining in the error state.+ //+ // First, try the strategy 1. Upon entering the error state, the parser recorded a summary+ // of the previous parse states and their depths. Look at each state in the summary, to see+ // if the current lookahead token would be valid in that state.+ if (summary && !ts_subtree_is_error(lookahead)) {+ for (unsigned i = 0; i < summary->size; i++) {+ StackSummaryEntry entry = summary->contents[i];++ if (entry.state == ERROR_STATE) continue;+ if (entry.position.bytes == position.bytes) continue;+ unsigned depth = entry.depth;+ if (node_count_since_error > 0) depth++;++ // Do not recover in ways that create redundant stack versions.+ bool would_merge = false;+ for (unsigned j = 0; j < previous_version_count; j++) {+ if (+ ts_stack_state(self->stack, j) == entry.state &&+ ts_stack_position(self->stack, j).bytes == position.bytes+ ) {+ would_merge = true;+ break;+ }+ }+ if (would_merge) continue;++ // Do not recover if the result would clearly be worse than some existing stack version.+ unsigned new_cost =+ current_error_cost ++ entry.depth * ERROR_COST_PER_SKIPPED_TREE ++ (position.bytes - entry.position.bytes) * ERROR_COST_PER_SKIPPED_CHAR ++ (position.extent.row - entry.position.extent.row) * ERROR_COST_PER_SKIPPED_LINE;+ if (ts_parser__better_version_exists(self, version, false, new_cost)) break;++ // If the current lookahead token is valid in some previous state, recover to that state.+ // Then stop looking for further recoveries.+ if (ts_language_has_actions(self->language, entry.state, ts_subtree_symbol(lookahead))) {+ if (ts_parser__recover_to_state(self, version, depth, entry.state)) {+ did_recover = true;+ LOG("recover_to_previous state:%u, depth:%u", entry.state, depth);+ LOG_STACK();+ break;+ }+ }+ }+ }++ // In the process of attempting to recover, some stack versions may have been created+ // and subsequently halted. Remove those versions.+ for (unsigned i = previous_version_count; i < ts_stack_version_count(self->stack); i++) {+ if (!ts_stack_is_active(self->stack, i)) {+ ts_stack_remove_version(self->stack, i--);+ }+ }++ // If strategy 1 succeeded, a new stack version will have been created which is able to handle+ // the current lookahead token. Now, in addition, try strategy 2 described above: skip the+ // current lookahead token by wrapping it in an ERROR node.++ // Don't pursue this additional strategy if there are already too many stack versions.+ if (did_recover && ts_stack_version_count(self->stack) > MAX_VERSION_COUNT) {+ ts_stack_halt(self->stack, version);+ ts_subtree_release(&self->tree_pool, lookahead);+ return;+ }++ if (+ did_recover &&+ ts_subtree_has_external_scanner_state_change(lookahead)+ ) {+ ts_stack_halt(self->stack, version);+ ts_subtree_release(&self->tree_pool, lookahead);+ return;+ }++ // If the parser is still in the error state at the end of the file, just wrap everything+ // in an ERROR node and terminate.+ if (ts_subtree_is_eof(lookahead)) {+ LOG("recover_eof");+ SubtreeArray children = array_new();+ Subtree parent = ts_subtree_new_error_node(&children, false, self->language);+ ts_stack_push(self->stack, version, parent, false, 1);+ ts_parser__accept(self, version, lookahead);+ return;+ }++ // Do not recover if the result would clearly be worse than some existing stack version.+ unsigned new_cost =+ current_error_cost + ERROR_COST_PER_SKIPPED_TREE ++ ts_subtree_total_bytes(lookahead) * ERROR_COST_PER_SKIPPED_CHAR ++ ts_subtree_total_size(lookahead).extent.row * ERROR_COST_PER_SKIPPED_LINE;+ if (ts_parser__better_version_exists(self, version, false, new_cost)) {+ ts_stack_halt(self->stack, version);+ ts_subtree_release(&self->tree_pool, lookahead);+ return;+ }++ // If the current lookahead token is an extra token, mark it as extra. This means it won't+ // be counted in error cost calculations.+ unsigned n;+ const TSParseAction *actions = ts_language_actions(self->language, 1, ts_subtree_symbol(lookahead), &n);+ if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra) {+ MutableSubtree mutable_lookahead = ts_subtree_make_mut(&self->tree_pool, lookahead);+ ts_subtree_set_extra(&mutable_lookahead, true);+ lookahead = ts_subtree_from_mut(mutable_lookahead);+ }++ // Wrap the lookahead token in an ERROR.+ LOG("skip_token symbol:%s", TREE_NAME(lookahead));+ SubtreeArray children = array_new();+ array_reserve(&children, 1);+ array_push(&children, lookahead);+ MutableSubtree error_repeat = ts_subtree_new_node(+ ts_builtin_sym_error_repeat,+ &children,+ 0,+ self->language+ );++ // If other tokens have already been skipped, so there is already an ERROR at the top of the+ // stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger+ // ERROR.+ if (node_count_since_error > 0) {+ StackSliceArray pop = ts_stack_pop_count(self->stack, version, 1);++ // TODO: Figure out how to make this condition occur.+ // See https://github.com/atom/atom/issues/18450#issuecomment-439579778+ // If multiple stack versions have merged at this point, just pick one of the errors+ // arbitrarily and discard the rest.+ if (pop.size > 1) {+ for (unsigned i = 1; i < pop.size; i++) {+ ts_subtree_array_delete(&self->tree_pool, &pop.contents[i].subtrees);+ }+ while (ts_stack_version_count(self->stack) > pop.contents[0].version + 1) {+ ts_stack_remove_version(self->stack, pop.contents[0].version + 1);+ }+ }++ ts_stack_renumber_version(self->stack, pop.contents[0].version, version);+ array_push(&pop.contents[0].subtrees, ts_subtree_from_mut(error_repeat));+ error_repeat = ts_subtree_new_node(+ ts_builtin_sym_error_repeat,+ &pop.contents[0].subtrees,+ 0,+ self->language+ );+ }++ // Push the new ERROR onto the stack.+ ts_stack_push(self->stack, version, ts_subtree_from_mut(error_repeat), false, ERROR_STATE);+ if (ts_subtree_has_external_tokens(lookahead)) {+ ts_stack_set_last_external_token(+ self->stack, version, ts_subtree_last_external_token(lookahead)+ );+ }+}++static void ts_parser__handle_error(+ TSParser *self,+ StackVersion version,+ Subtree lookahead+) {+ uint32_t previous_version_count = ts_stack_version_count(self->stack);++ // Perform any reductions that can happen in this state, regardless of the lookahead. After+ // skipping one or more invalid tokens, the parser might find a token that would have allowed+ // a reduction to take place.+ ts_parser__do_all_potential_reductions(self, version, 0);+ uint32_t version_count = ts_stack_version_count(self->stack);+ Length position = ts_stack_position(self->stack, version);++ // Push a discontinuity onto the stack. Merge all of the stack versions that+ // were created in the previous step.+ bool did_insert_missing_token = false;+ for (StackVersion v = version; v < version_count;) {+ if (!did_insert_missing_token) {+ TSStateId state = ts_stack_state(self->stack, v);+ for (+ TSSymbol missing_symbol = 1;+ missing_symbol < (uint16_t)self->language->token_count;+ missing_symbol+++ ) {+ TSStateId state_after_missing_symbol = ts_language_next_state(+ self->language, state, missing_symbol+ );+ if (state_after_missing_symbol == 0 || state_after_missing_symbol == state) {+ continue;+ }++ if (ts_language_has_reduce_action(+ self->language,+ state_after_missing_symbol,+ ts_subtree_leaf_symbol(lookahead)+ )) {+ // In case the parser is currently outside of any included range, the lexer will+ // snap to the beginning of the next included range. The missing token's padding+ // must be assigned to position it within the next included range.+ ts_lexer_reset(&self->lexer, position);+ ts_lexer_mark_end(&self->lexer);+ Length padding = length_sub(self->lexer.token_end_position, position);+ uint32_t lookahead_bytes = ts_subtree_total_bytes(lookahead) + ts_subtree_lookahead_bytes(lookahead);++ StackVersion version_with_missing_tree = ts_stack_copy_version(self->stack, v);+ Subtree missing_tree = ts_subtree_new_missing_leaf(+ &self->tree_pool, missing_symbol,+ padding, lookahead_bytes,+ self->language+ );+ ts_stack_push(+ self->stack, version_with_missing_tree,+ missing_tree, false,+ state_after_missing_symbol+ );++ if (ts_parser__do_all_potential_reductions(+ self, version_with_missing_tree,+ ts_subtree_leaf_symbol(lookahead)+ )) {+ LOG(+ "recover_with_missing symbol:%s, state:%u",+ SYM_NAME(missing_symbol),+ ts_stack_state(self->stack, version_with_missing_tree)+ );+ did_insert_missing_token = true;+ break;+ }+ }+ }+ }++ ts_stack_push(self->stack, v, NULL_SUBTREE, false, ERROR_STATE);+ v = (v == version) ? previous_version_count : v + 1;+ }++ for (unsigned i = previous_version_count; i < version_count; i++) {+ bool did_merge = ts_stack_merge(self->stack, version, previous_version_count);+ ts_assert(did_merge);+ }++ ts_stack_record_summary(self->stack, version, MAX_SUMMARY_DEPTH);++ // Begin recovery with the current lookahead node, rather than waiting for the+ // next turn of the parse loop. This ensures that the tree accounts for the+ // current lookahead token's "lookahead bytes" value, which describes how far+ // the lexer needed to look ahead beyond the content of the token in order to+ // recognize it.+ if (ts_subtree_child_count(lookahead) > 0) {+ ts_parser__breakdown_lookahead(self, &lookahead, ERROR_STATE, &self->reusable_node);+ }+ ts_parser__recover(self, version, lookahead);++ LOG_STACK();+}++static bool ts_parser__advance(+ TSParser *self,+ StackVersion version,+ bool allow_node_reuse+) {+ TSStateId state = ts_stack_state(self->stack, version);+ uint32_t position = ts_stack_position(self->stack, version).bytes;+ Subtree last_external_token = ts_stack_last_external_token(self->stack, version);++ bool did_reuse = true;+ Subtree lookahead = NULL_SUBTREE;+ TableEntry table_entry = {.action_count = 0};++ // If possible, reuse a node from the previous syntax tree.+ if (allow_node_reuse) {+ lookahead = ts_parser__reuse_node(+ self, version, &state, position, last_external_token, &table_entry+ );+ }++ // If no node from the previous syntax tree could be reused, then try to+ // reuse the token previously returned by the lexer.+ if (!lookahead.ptr) {+ did_reuse = false;+ lookahead = ts_parser__get_cached_token(+ self, state, position, last_external_token, &table_entry+ );+ }++ bool needs_lex = !lookahead.ptr;+ for (;;) {+ // Otherwise, re-run the lexer.+ if (needs_lex) {+ needs_lex = false;+ lookahead = ts_parser__lex(self, version, state);+ if (self->has_scanner_error) return false;++ if (lookahead.ptr) {+ ts_parser__set_cached_token(self, position, last_external_token, lookahead);+ ts_language_table_entry(self->language, state, ts_subtree_symbol(lookahead), &table_entry);+ }++ // When parsing a non-terminal extra, a null lookahead indicates the+ // end of the rule. The reduction is stored in the EOF table entry.+ // After the reduction, the lexer needs to be run again.+ else {+ ts_language_table_entry(self->language, state, ts_builtin_sym_end, &table_entry);+ }+ }++ // If a cancellation flag or a timeout was provided, then check every+ // time a fixed number of parse actions has been processed.+ if (++self->operation_count == OP_COUNT_PER_PARSER_TIMEOUT_CHECK) {+ self->operation_count = 0;+ }+ if (+ self->operation_count == 0 &&+ ((self->cancellation_flag && atomic_load(self->cancellation_flag)) ||+ (!clock_is_null(self->end_clock) && clock_is_gt(clock_now(), self->end_clock)))+ ) {+ if (lookahead.ptr) {+ ts_subtree_release(&self->tree_pool, lookahead);+ }+ return false;+ }++ // Process each parse action for the current lookahead token in+ // the current state. If there are multiple actions, then this is+ // an ambiguous state. REDUCE actions always create a new stack+ // version, whereas SHIFT actions update the existing stack version+ // and terminate this loop.+ StackVersion last_reduction_version = STACK_VERSION_NONE;+ for (uint32_t i = 0; i < table_entry.action_count; i++) {+ TSParseAction action = table_entry.actions[i];++ switch (action.type) {+ case TSParseActionTypeShift: {+ if (action.shift.repetition) break;+ TSStateId next_state;+ if (action.shift.extra) {+ next_state = state;+ LOG("shift_extra");+ } else {+ next_state = action.shift.state;+ LOG("shift state:%u", next_state);+ }++ if (ts_subtree_child_count(lookahead) > 0) {+ ts_parser__breakdown_lookahead(self, &lookahead, state, &self->reusable_node);+ next_state = ts_language_next_state(self->language, state, ts_subtree_symbol(lookahead));+ }++ ts_parser__shift(self, version, next_state, lookahead, action.shift.extra);+ if (did_reuse) reusable_node_advance(&self->reusable_node);+ return true;+ }++ case TSParseActionTypeReduce: {+ bool is_fragile = table_entry.action_count > 1;+ bool end_of_non_terminal_extra = lookahead.ptr == NULL;+ LOG("reduce sym:%s, child_count:%u", SYM_NAME(action.reduce.symbol), action.reduce.child_count);+ StackVersion reduction_version = ts_parser__reduce(+ self, version, action.reduce.symbol, action.reduce.child_count,+ action.reduce.dynamic_precedence, action.reduce.production_id,+ is_fragile, end_of_non_terminal_extra+ );+ if (reduction_version != STACK_VERSION_NONE) {+ last_reduction_version = reduction_version;+ }+ break;+ }++ case TSParseActionTypeAccept: {+ LOG("accept");+ ts_parser__accept(self, version, lookahead);+ return true;+ }++ case TSParseActionTypeRecover: {+ if (ts_subtree_child_count(lookahead) > 0) {+ ts_parser__breakdown_lookahead(self, &lookahead, ERROR_STATE, &self->reusable_node);+ }++ ts_parser__recover(self, version, lookahead);+ if (did_reuse) reusable_node_advance(&self->reusable_node);+ return true;+ }+ }+ }++ // If a reduction was performed, then replace the current stack version+ // with one of the stack versions created by a reduction, and continue+ // processing this version of the stack with the same lookahead symbol.+ if (last_reduction_version != STACK_VERSION_NONE) {+ ts_stack_renumber_version(self->stack, last_reduction_version, version);+ LOG_STACK();+ state = ts_stack_state(self->stack, version);++ // At the end of a non-terminal extra rule, the lexer will return a+ // null subtree, because the parser needs to perform a fixed reduction+ // regardless of the lookahead node. After performing that reduction,+ // (and completing the non-terminal extra rule) run the lexer again based+ // on the current parse state.+ if (!lookahead.ptr) {+ needs_lex = true;+ } else {+ ts_language_table_entry(+ self->language,+ state,+ ts_subtree_leaf_symbol(lookahead),+ &table_entry+ );+ }++ continue;+ }++ // A non-terminal extra rule was reduced and merged into an existing+ // stack version. This version can be discarded.+ if (!lookahead.ptr) {+ ts_stack_halt(self->stack, version);+ return true;+ }++ // If there were no parse actions for the current lookahead token, then+ // it is not valid in this state. If the current lookahead token is a+ // keyword, then switch to treating it as the normal word token if that+ // token is valid in this state.+ if (+ ts_subtree_is_keyword(lookahead) &&+ ts_subtree_symbol(lookahead) != self->language->keyword_capture_token+ ) {+ ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);+ if (table_entry.action_count > 0) {+ LOG(+ "switch from_keyword:%s, to_word_token:%s",+ TREE_NAME(lookahead),+ SYM_NAME(self->language->keyword_capture_token)+ );++ MutableSubtree mutable_lookahead = ts_subtree_make_mut(&self->tree_pool, lookahead);+ ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);+ lookahead = ts_subtree_from_mut(mutable_lookahead);+ continue;+ }+ }++ // If the current lookahead token is not valid and the parser is+ // already in the error state, restart the error recovery process.+ // TODO - can this be unified with the other `RECOVER` case above?+ if (state == ERROR_STATE) {+ ts_parser__recover(self, version, lookahead);+ return true;+ }++ // If the current lookahead token is not valid and the previous+ // subtree on the stack was reused from an old tree, it isn't actually+ // valid to reuse it. Remove it from the stack, and in its place,+ // push each of its children. Then try again to process the current+ // lookahead.+ if (ts_parser__breakdown_top_of_stack(self, version)) {+ state = ts_stack_state(self->stack, version);+ ts_subtree_release(&self->tree_pool, lookahead);+ needs_lex = true;+ continue;+ }++ // At this point, the current lookahead token is definitely not valid+ // for this parse stack version. Mark this version as paused and continue+ // processing any other stack versions that might exist. If some other+ // version advances successfully, then this version can simply be removed.+ // But if all versions end up paused, then error recovery is needed.+ LOG("detect_error");+ ts_stack_pause(self->stack, version, lookahead);+ return true;+ }+}++static unsigned ts_parser__condense_stack(TSParser *self) {+ bool made_changes = false;+ unsigned min_error_cost = UINT_MAX;+ for (StackVersion i = 0; i < ts_stack_version_count(self->stack); i++) {+ // Prune any versions that have been marked for removal.+ if (ts_stack_is_halted(self->stack, i)) {+ ts_stack_remove_version(self->stack, i);+ i--;+ continue;+ }++ // Keep track of the minimum error cost of any stack version so+ // that it can be returned.+ ErrorStatus status_i = ts_parser__version_status(self, i);+ if (!status_i.is_in_error && status_i.cost < min_error_cost) {+ min_error_cost = status_i.cost;+ }++ // Examine each pair of stack versions, removing any versions that+ // are clearly worse than another version. Ensure that the versions+ // are ordered from most promising to least promising.+ for (StackVersion j = 0; j < i; j++) {+ ErrorStatus status_j = ts_parser__version_status(self, j);++ switch (ts_parser__compare_versions(self, status_j, status_i)) {+ case ErrorComparisonTakeLeft:+ made_changes = true;+ ts_stack_remove_version(self->stack, i);+ i--;+ j = i;+ break;++ case ErrorComparisonPreferLeft:+ case ErrorComparisonNone:+ if (ts_stack_merge(self->stack, j, i)) {+ made_changes = true;+ i--;+ j = i;+ }+ break;++ case ErrorComparisonPreferRight:+ made_changes = true;+ if (ts_stack_merge(self->stack, j, i)) {+ i--;+ j = i;+ } else {+ ts_stack_swap_versions(self->stack, i, j);+ }+ break;++ case ErrorComparisonTakeRight:+ made_changes = true;+ ts_stack_remove_version(self->stack, j);+ i--;+ j--;+ break;+ }+ }+ }++ // Enforce a hard upper bound on the number of stack versions by+ // discarding the least promising versions.+ while (ts_stack_version_count(self->stack) > MAX_VERSION_COUNT) {+ ts_stack_remove_version(self->stack, MAX_VERSION_COUNT);+ made_changes = true;+ }++ // If the best-performing stack version is currently paused, or all+ // versions are paused, then resume the best paused version and begin+ // the error recovery process. Otherwise, remove the paused versions.+ if (ts_stack_version_count(self->stack) > 0) {+ bool has_unpaused_version = false;+ for (StackVersion i = 0, n = ts_stack_version_count(self->stack); i < n; i++) {+ if (ts_stack_is_paused(self->stack, i)) {+ if (!has_unpaused_version && self->accept_count < MAX_VERSION_COUNT) {+ LOG("resume version:%u", i);+ min_error_cost = ts_stack_error_cost(self->stack, i);+ Subtree lookahead = ts_stack_resume(self->stack, i);+ ts_parser__handle_error(self, i, lookahead);+ has_unpaused_version = true;+ } else {+ ts_stack_remove_version(self->stack, i);+ i--;+ n--;+ }+ } else {+ has_unpaused_version = true;+ }+ }+ }++ if (made_changes) {+ LOG("condense");+ LOG_STACK();+ }++ return min_error_cost;+}++static bool ts_parser_has_outstanding_parse(TSParser *self) {+ return (+ self->external_scanner_payload ||+ ts_stack_state(self->stack, 0) != 1 ||+ ts_stack_node_count_since_error(self->stack, 0) != 0+ );+}++// Parser - Public++TSParser *ts_parser_new(void) {+ TSParser *self = ts_calloc(1, sizeof(TSParser));+ ts_lexer_init(&self->lexer);+ array_init(&self->reduce_actions);+ array_reserve(&self->reduce_actions, 4);+ self->tree_pool = ts_subtree_pool_new(32);+ self->stack = ts_stack_new(&self->tree_pool);+ self->finished_tree = NULL_SUBTREE;+ self->reusable_node = reusable_node_new();+ self->dot_graph_file = NULL;+ self->cancellation_flag = NULL;+ self->timeout_duration = 0;+ self->language = NULL;+ self->has_scanner_error = false;+ self->external_scanner_payload = NULL;+ self->end_clock = clock_null();+ self->operation_count = 0;+ self->old_tree = NULL_SUBTREE;+ self->included_range_differences = (TSRangeArray) array_new();+ self->included_range_difference_index = 0;+ ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);+ return self;+}++void ts_parser_delete(TSParser *self) {+ if (!self) return;++ ts_parser_set_language(self, NULL);+ ts_stack_delete(self->stack);+ if (self->reduce_actions.contents) {+ array_delete(&self->reduce_actions);+ }+ if (self->included_range_differences.contents) {+ array_delete(&self->included_range_differences);+ }+ if (self->old_tree.ptr) {+ ts_subtree_release(&self->tree_pool, self->old_tree);+ self->old_tree = NULL_SUBTREE;+ }+ ts_wasm_store_delete(self->wasm_store);+ ts_lexer_delete(&self->lexer);+ ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);+ ts_subtree_pool_delete(&self->tree_pool);+ reusable_node_delete(&self->reusable_node);+ array_delete(&self->trailing_extras);+ array_delete(&self->trailing_extras2);+ array_delete(&self->scratch_trees);+ ts_free(self);+}++const TSLanguage *ts_parser_language(const TSParser *self) {+ return self->language;+}++bool ts_parser_set_language(TSParser *self, const TSLanguage *language) {+ ts_parser_reset(self);+ ts_language_delete(self->language);+ self->language = NULL;++ if (language) {+ if (+ language->version > TREE_SITTER_LANGUAGE_VERSION ||+ language->version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION+ ) return false;++ if (ts_language_is_wasm(language)) {+ if (+ !self->wasm_store ||+ !ts_wasm_store_start(self->wasm_store, &self->lexer.data, language)+ ) return false;+ }+ }++ self->language = ts_language_copy(language);+ return true;+}++TSLogger ts_parser_logger(const TSParser *self) {+ return self->lexer.logger;+}++void ts_parser_set_logger(TSParser *self, TSLogger logger) {+ self->lexer.logger = logger;+}++void ts_parser_print_dot_graphs(TSParser *self, int fd) {+ if (self->dot_graph_file) {+ fclose(self->dot_graph_file);+ }++ if (fd >= 0) {+ #ifdef _WIN32+ self->dot_graph_file = _fdopen(fd, "a");+ #else+ self->dot_graph_file = fdopen(fd, "a");+ #endif+ } else {+ self->dot_graph_file = NULL;+ }+}++const size_t *ts_parser_cancellation_flag(const TSParser *self) {+ return (const size_t *)self->cancellation_flag;+}++void ts_parser_set_cancellation_flag(TSParser *self, const size_t *flag) {+ self->cancellation_flag = (const volatile size_t *)flag;+}++uint64_t ts_parser_timeout_micros(const TSParser *self) {+ return duration_to_micros(self->timeout_duration);+}++void ts_parser_set_timeout_micros(TSParser *self, uint64_t timeout_micros) {+ self->timeout_duration = duration_from_micros(timeout_micros);+}++bool ts_parser_set_included_ranges(+ TSParser *self,+ const TSRange *ranges,+ uint32_t count+) {+ return ts_lexer_set_included_ranges(&self->lexer, ranges, count);+}++const TSRange *ts_parser_included_ranges(const TSParser *self, uint32_t *count) {+ return ts_lexer_included_ranges(&self->lexer, count);+}++void ts_parser_reset(TSParser *self) {+ ts_parser__external_scanner_destroy(self);+ if (self->wasm_store) {+ ts_wasm_store_reset(self->wasm_store);+ }++ if (self->old_tree.ptr) {+ ts_subtree_release(&self->tree_pool, self->old_tree);+ self->old_tree = NULL_SUBTREE;+ }++ reusable_node_clear(&self->reusable_node);+ ts_lexer_reset(&self->lexer, length_zero());+ ts_stack_clear(self->stack);+ ts_parser__set_cached_token(self, 0, NULL_SUBTREE, NULL_SUBTREE);+ if (self->finished_tree.ptr) {+ ts_subtree_release(&self->tree_pool, self->finished_tree);+ self->finished_tree = NULL_SUBTREE;+ }+ self->accept_count = 0;+ self->has_scanner_error = false;+}++TSTree *ts_parser_parse(+ TSParser *self,+ const TSTree *old_tree,+ TSInput input+) {+ TSTree *result = NULL;+ if (!self->language || !input.read) return NULL;++ if (ts_language_is_wasm(self->language)) {+ if (!self->wasm_store) return NULL;+ ts_wasm_store_start(self->wasm_store, &self->lexer.data, self->language);+ }++ ts_lexer_set_input(&self->lexer, input);+ array_clear(&self->included_range_differences);+ self->included_range_difference_index = 0;++ if (ts_parser_has_outstanding_parse(self)) {+ LOG("resume_parsing");+ } else {+ ts_parser__external_scanner_create(self);+ if (self->has_scanner_error) goto exit;++ if (old_tree) {+ ts_subtree_retain(old_tree->root);+ self->old_tree = old_tree->root;+ ts_range_array_get_changed_ranges(+ old_tree->included_ranges, old_tree->included_range_count,+ self->lexer.included_ranges, self->lexer.included_range_count,+ &self->included_range_differences+ );+ reusable_node_reset(&self->reusable_node, old_tree->root);+ LOG("parse_after_edit");+ LOG_TREE(self->old_tree);+ for (unsigned i = 0; i < self->included_range_differences.size; i++) {+ TSRange *range = &self->included_range_differences.contents[i];+ LOG("different_included_range %u - %u", range->start_byte, range->end_byte);+ }+ } else {+ reusable_node_clear(&self->reusable_node);+ LOG("new_parse");+ }+ }++ self->operation_count = 0;+ if (self->timeout_duration) {+ self->end_clock = clock_after(clock_now(), self->timeout_duration);+ } else {+ self->end_clock = clock_null();+ }++ uint32_t position = 0, last_position = 0, version_count = 0;+ do {+ for (+ StackVersion version = 0;+ version_count = ts_stack_version_count(self->stack),+ version < version_count;+ version+++ ) {+ bool allow_node_reuse = version_count == 1;+ while (ts_stack_is_active(self->stack, version)) {+ LOG(+ "process version:%u, version_count:%u, state:%d, row:%u, col:%u",+ version,+ ts_stack_version_count(self->stack),+ ts_stack_state(self->stack, version),+ ts_stack_position(self->stack, version).extent.row,+ ts_stack_position(self->stack, version).extent.column+ );++ if (!ts_parser__advance(self, version, allow_node_reuse)) {+ if (self->has_scanner_error) goto exit;+ return NULL;+ }++ LOG_STACK();++ position = ts_stack_position(self->stack, version).bytes;+ if (position > last_position || (version > 0 && position == last_position)) {+ last_position = position;+ break;+ }+ }+ }++ // After advancing each version of the stack, re-sort the versions by their cost,+ // removing any versions that are no longer worth pursuing.+ unsigned min_error_cost = ts_parser__condense_stack(self);++ // If there's already a finished parse tree that's better than any in-progress version,+ // then terminate parsing. Clear the parse stack to remove any extra references to subtrees+ // within the finished tree, ensuring that these subtrees can be safely mutated in-place+ // for rebalancing.+ if (self->finished_tree.ptr && ts_subtree_error_cost(self->finished_tree) < min_error_cost) {+ ts_stack_clear(self->stack);+ break;+ }++ while (self->included_range_difference_index < self->included_range_differences.size) {+ TSRange *range = &self->included_range_differences.contents[self->included_range_difference_index];+ if (range->end_byte <= position) {+ self->included_range_difference_index++;+ } else {+ break;+ }+ }+ } while (version_count != 0);++ ts_assert(self->finished_tree.ptr);+ ts_subtree_balance(self->finished_tree, &self->tree_pool, self->language);+ LOG("done");+ LOG_TREE(self->finished_tree);++ result = ts_tree_new(+ self->finished_tree,+ self->language,+ self->lexer.included_ranges,+ self->lexer.included_range_count+ );+ self->finished_tree = NULL_SUBTREE;++exit:+ ts_parser_reset(self);+ return result;+}++TSTree *ts_parser_parse_string(+ TSParser *self,+ const TSTree *old_tree,+ const char *string,+ uint32_t length+) {+ return ts_parser_parse_string_encoding(self, old_tree, string, length, TSInputEncodingUTF8);+}++TSTree *ts_parser_parse_string_encoding(+ TSParser *self,+ const TSTree *old_tree,+ const char *string,+ uint32_t length,+ TSInputEncoding encoding+) {+ TSStringInput input = {string, length};+ return ts_parser_parse(self, old_tree, (TSInput) {+ &input,+ ts_string_input_read,+ encoding,+ });+}++void ts_parser_set_wasm_store(TSParser *self, TSWasmStore *store) {+ if (self->language && ts_language_is_wasm(self->language)) {+ // Copy the assigned language into the new store.+ const TSLanguage *copy = ts_language_copy(self->language);+ ts_parser_set_language(self, copy);+ ts_language_delete(copy);+ }++ ts_wasm_store_delete(self->wasm_store);+ self->wasm_store = store;+}++TSWasmStore *ts_parser_take_wasm_store(TSParser *self) {+ if (self->language && ts_language_is_wasm(self->language)) {+ ts_parser_set_language(self, NULL);+ }++ TSWasmStore *result = self->wasm_store;+ self->wasm_store = NULL;+ return result;+}++#undef LOG
+ vendor/tree-sitter/lib/src/parser.h view
@@ -0,0 +1,266 @@+#ifndef TREE_SITTER_PARSER_H_+#define TREE_SITTER_PARSER_H_++#ifdef __cplusplus+extern "C" {+#endif++#include <stdbool.h>+#include <stdint.h>+#include <stdlib.h>++#define ts_builtin_sym_error ((TSSymbol)-1)+#define ts_builtin_sym_end 0+#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024++#ifndef TREE_SITTER_API_H_+typedef uint16_t TSStateId;+typedef uint16_t TSSymbol;+typedef uint16_t TSFieldId;+typedef struct TSLanguage TSLanguage;+#endif++typedef struct {+ TSFieldId field_id;+ uint8_t child_index;+ bool inherited;+} TSFieldMapEntry;++typedef struct {+ uint16_t index;+ uint16_t length;+} TSFieldMapSlice;++typedef struct {+ bool visible;+ bool named;+ bool supertype;+} TSSymbolMetadata;++typedef struct TSLexer TSLexer;++struct TSLexer {+ int32_t lookahead;+ TSSymbol result_symbol;+ void (*advance)(TSLexer *, bool);+ void (*mark_end)(TSLexer *);+ uint32_t (*get_column)(TSLexer *);+ bool (*is_at_included_range_start)(const TSLexer *);+ bool (*eof)(const TSLexer *);+ void (*log)(const TSLexer *, const char *, ...);+};++typedef enum {+ TSParseActionTypeShift,+ TSParseActionTypeReduce,+ TSParseActionTypeAccept,+ TSParseActionTypeRecover,+} TSParseActionType;++typedef union {+ struct {+ uint8_t type;+ TSStateId state;+ bool extra;+ bool repetition;+ } shift;+ struct {+ uint8_t type;+ uint8_t child_count;+ TSSymbol symbol;+ int16_t dynamic_precedence;+ uint16_t production_id;+ } reduce;+ uint8_t type;+} TSParseAction;++typedef struct {+ uint16_t lex_state;+ uint16_t external_lex_state;+} TSLexMode;++typedef union {+ TSParseAction action;+ struct {+ uint8_t count;+ bool reusable;+ } entry;+} TSParseActionEntry;++typedef struct {+ int32_t start;+ int32_t end;+} TSCharacterRange;++struct TSLanguage {+ uint32_t version;+ uint32_t symbol_count;+ uint32_t alias_count;+ uint32_t token_count;+ uint32_t external_token_count;+ uint32_t state_count;+ uint32_t large_state_count;+ uint32_t production_id_count;+ uint32_t field_count;+ uint16_t max_alias_sequence_length;+ const uint16_t *parse_table;+ const uint16_t *small_parse_table;+ const uint32_t *small_parse_table_map;+ const TSParseActionEntry *parse_actions;+ const char * const *symbol_names;+ const char * const *field_names;+ const TSFieldMapSlice *field_map_slices;+ const TSFieldMapEntry *field_map_entries;+ const TSSymbolMetadata *symbol_metadata;+ const TSSymbol *public_symbol_map;+ const uint16_t *alias_map;+ const TSSymbol *alias_sequences;+ const TSLexMode *lex_modes;+ bool (*lex_fn)(TSLexer *, TSStateId);+ bool (*keyword_lex_fn)(TSLexer *, TSStateId);+ TSSymbol keyword_capture_token;+ struct {+ const bool *states;+ const TSSymbol *symbol_map;+ void *(*create)(void);+ void (*destroy)(void *);+ bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);+ unsigned (*serialize)(void *, char *);+ void (*deserialize)(void *, const char *, unsigned);+ } external_scanner;+ const TSStateId *primary_state_ids;+};++static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) {+ uint32_t index = 0;+ uint32_t size = len - index;+ while (size > 1) {+ uint32_t half_size = size / 2;+ uint32_t mid_index = index + half_size;+ TSCharacterRange *range = &ranges[mid_index];+ if (lookahead >= range->start && lookahead <= range->end) {+ return true;+ } else if (lookahead > range->end) {+ index = mid_index;+ }+ size -= half_size;+ }+ TSCharacterRange *range = &ranges[index];+ return (lookahead >= range->start && lookahead <= range->end);+}++/*+ * Lexer Macros+ */++#ifdef _MSC_VER+#define UNUSED __pragma(warning(suppress : 4101))+#else+#define UNUSED __attribute__((unused))+#endif++#define START_LEXER() \+ bool result = false; \+ bool skip = false; \+ UNUSED \+ bool eof = false; \+ int32_t lookahead; \+ goto start; \+ next_state: \+ lexer->advance(lexer, skip); \+ start: \+ skip = false; \+ lookahead = lexer->lookahead;++#define ADVANCE(state_value) \+ { \+ state = state_value; \+ goto next_state; \+ }++#define ADVANCE_MAP(...) \+ { \+ static const uint16_t map[] = { __VA_ARGS__ }; \+ for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) { \+ if (map[i] == lookahead) { \+ state = map[i + 1]; \+ goto next_state; \+ } \+ } \+ }++#define SKIP(state_value) \+ { \+ skip = true; \+ state = state_value; \+ goto next_state; \+ }++#define ACCEPT_TOKEN(symbol_value) \+ result = true; \+ lexer->result_symbol = symbol_value; \+ lexer->mark_end(lexer);++#define END_STATE() return result;++/*+ * Parse Table Macros+ */++#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)++#define STATE(id) id++#define ACTIONS(id) id++#define SHIFT(state_value) \+ {{ \+ .shift = { \+ .type = TSParseActionTypeShift, \+ .state = (state_value) \+ } \+ }}++#define SHIFT_REPEAT(state_value) \+ {{ \+ .shift = { \+ .type = TSParseActionTypeShift, \+ .state = (state_value), \+ .repetition = true \+ } \+ }}++#define SHIFT_EXTRA() \+ {{ \+ .shift = { \+ .type = TSParseActionTypeShift, \+ .extra = true \+ } \+ }}++#define REDUCE(symbol_name, children, precedence, prod_id) \+ {{ \+ .reduce = { \+ .type = TSParseActionTypeReduce, \+ .symbol = symbol_name, \+ .child_count = children, \+ .dynamic_precedence = precedence, \+ .production_id = prod_id \+ }, \+ }}++#define RECOVER() \+ {{ \+ .type = TSParseActionTypeRecover \+ }}++#define ACCEPT_INPUT() \+ {{ \+ .type = TSParseActionTypeAccept \+ }}++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_PARSER_H_
+ vendor/tree-sitter/lib/src/point.h view
@@ -0,0 +1,62 @@+#ifndef TREE_SITTER_POINT_H_+#define TREE_SITTER_POINT_H_++#include "tree_sitter/api.h"++#define POINT_ZERO ((TSPoint) {0, 0})+#define POINT_MAX ((TSPoint) {UINT32_MAX, UINT32_MAX})++static inline TSPoint point__new(unsigned row, unsigned column) {+ TSPoint result = {row, column};+ return result;+}++static inline TSPoint point_add(TSPoint a, TSPoint b) {+ if (b.row > 0)+ return point__new(a.row + b.row, b.column);+ else+ return point__new(a.row, a.column + b.column);+}++static inline TSPoint point_sub(TSPoint a, TSPoint b) {+ if (a.row > b.row)+ return point__new(a.row - b.row, a.column);+ else+ return point__new(0, a.column - b.column);+}++static inline bool point_lte(TSPoint a, TSPoint b) {+ return (a.row < b.row) || (a.row == b.row && a.column <= b.column);+}++static inline bool point_lt(TSPoint a, TSPoint b) {+ return (a.row < b.row) || (a.row == b.row && a.column < b.column);+}++static inline bool point_gt(TSPoint a, TSPoint b) {+ return (a.row > b.row) || (a.row == b.row && a.column > b.column);+}++static inline bool point_gte(TSPoint a, TSPoint b) {+ return (a.row > b.row) || (a.row == b.row && a.column >= b.column);+}++static inline bool point_eq(TSPoint a, TSPoint b) {+ return a.row == b.row && a.column == b.column;+}++static inline TSPoint point_min(TSPoint a, TSPoint b) {+ if (a.row < b.row || (a.row == b.row && a.column < b.column))+ return a;+ else+ return b;+}++static inline TSPoint point_max(TSPoint a, TSPoint b) {+ if (a.row > b.row || (a.row == b.row && a.column > b.column))+ return a;+ else+ return b;+}++#endif
+ vendor/tree-sitter/lib/src/query.c view
@@ -0,0 +1,4187 @@+#include "tree_sitter/api.h"+#include "./alloc.h"+#include "./array.h"+#include "./clock.h"+#include "./language.h"+#include "./point.h"+#include "./tree_cursor.h"+#include "./unicode.h"+#include <wctype.h>++// #define DEBUG_ANALYZE_QUERY+// #define DEBUG_EXECUTE_QUERY++#define MAX_STEP_CAPTURE_COUNT 3+#define MAX_NEGATED_FIELD_COUNT 8+#define MAX_STATE_PREDECESSOR_COUNT 256+#define MAX_ANALYSIS_STATE_DEPTH 8+#define MAX_ANALYSIS_ITERATION_COUNT 256++/*+ * Stream - A sequence of unicode characters derived from a UTF8 string.+ * This struct is used in parsing queries from S-expressions.+ */+typedef struct {+ const char *input;+ const char *start;+ const char *end;+ int32_t next;+ uint8_t next_size;+} Stream;++/*+ * QueryStep - A step in the process of matching a query. Each node within+ * a query S-expression corresponds to one of these steps. An entire pattern+ * is represented as a sequence of these steps. The basic properties of a+ * node are represented by these fields:+ * - `symbol` - The grammar symbol to match. A zero value represents the+ * wildcard symbol, '_'.+ * - `field` - The field name to match. A zero value means that a field name+ * was not specified.+ * - `capture_ids` - An array of integers representing the names of captures+ * associated with this node in the pattern, terminated by a `NONE` value.+ * - `depth` - The depth where this node occurs in the pattern. The root node+ * of the pattern has depth zero.+ * - `negated_field_list_id` - An id representing a set of fields that must+ * not be present on a node matching this step.+ *+ * Steps have some additional fields in order to handle the `.` (or "anchor") operator,+ * which forbids additional child nodes:+ * - `is_immediate` - Indicates that the node matching this step cannot be preceded+ * by other sibling nodes that weren't specified in the pattern.+ * - `is_last_child` - Indicates that the node matching this step cannot have any+ * subsequent named siblings.+ *+ * For simple patterns, steps are matched in sequential order. But in order to+ * handle alternative/repeated/optional sub-patterns, query steps are not always+ * structured as a linear sequence; they sometimes need to split and merge. This+ * is done using the following fields:+ * - `alternative_index` - The index of a different query step that serves as+ * an alternative to this step. A `NONE` value represents no alternative.+ * When a query state reaches a step with an alternative index, the state+ * is duplicated, with one copy remaining at the original step, and one copy+ * moving to the alternative step. The alternative may have its own alternative+ * step, so this splitting is an iterative process.+ * - `is_dead_end` - Indicates that this state cannot be passed directly, and+ * exists only in order to redirect to an alternative index, with no splitting.+ * - `is_pass_through` - Indicates that state has no matching logic of its own,+ * and exists only to split a state. One copy of the state advances immediately+ * to the next step, and one moves to the alternative step.+ * - `alternative_is_immediate` - Indicates that this step's alternative step+ * should be treated as if `is_immediate` is true.+ *+ * Steps also store some derived state that summarizes how they relate to other+ * steps within the same pattern. This is used to optimize the matching process:+ * - `contains_captures` - Indicates that this step or one of its child steps+ * has a non-empty `capture_ids` list.+ * - `parent_pattern_guaranteed` - Indicates that if this step is reached, then+ * it and all of its subsequent sibling steps within the same parent pattern+ * are guaranteed to match.+ * - `root_pattern_guaranteed` - Similar to `parent_pattern_guaranteed`, but+ * for the entire top-level pattern. When iterating through a query's+ * captures using `ts_query_cursor_next_capture`, this field is used to+ * detect that a capture can safely be returned from a match that has not+ * even completed yet.+ */+typedef struct {+ TSSymbol symbol;+ TSSymbol supertype_symbol;+ TSFieldId field;+ uint16_t capture_ids[MAX_STEP_CAPTURE_COUNT];+ uint16_t depth;+ uint16_t alternative_index;+ uint16_t negated_field_list_id;+ bool is_named: 1;+ bool is_immediate: 1;+ bool is_last_child: 1;+ bool is_pass_through: 1;+ bool is_dead_end: 1;+ bool alternative_is_immediate: 1;+ bool contains_captures: 1;+ bool root_pattern_guaranteed: 1;+ bool parent_pattern_guaranteed: 1;+} QueryStep;++/*+ * Slice - A slice of an external array. Within a query, capture names,+ * literal string values, and predicate step information are stored in three+ * contiguous arrays. Individual captures, string values, and predicates are+ * represented as slices of these three arrays.+ */+typedef struct {+ uint32_t offset;+ uint32_t length;+} Slice;++/*+ * SymbolTable - a two-way mapping of strings to ids.+ */+typedef struct {+ Array(char) characters;+ Array(Slice) slices;+} SymbolTable;++/**+ * CaptureQuantififers - a data structure holding the quantifiers of pattern captures.+ */+typedef Array(uint8_t) CaptureQuantifiers;++/*+ * PatternEntry - Information about the starting point for matching a particular+ * pattern. These entries are stored in a 'pattern map' - a sorted array that+ * makes it possible to efficiently lookup patterns based on the symbol for their+ * first step. The entry consists of the following fields:+ * - `pattern_index` - the index of the pattern within the query+ * - `step_index` - the index of the pattern's first step in the shared `steps` array+ * - `is_rooted` - whether or not the pattern has a single root node. This property+ * affects decisions about whether or not to start the pattern for nodes outside+ * of a QueryCursor's range restriction.+ */+typedef struct {+ uint16_t step_index;+ uint16_t pattern_index;+ bool is_rooted;+} PatternEntry;++typedef struct {+ Slice steps;+ Slice predicate_steps;+ uint32_t start_byte;+ uint32_t end_byte;+ bool is_non_local;+} QueryPattern;++typedef struct {+ uint32_t byte_offset;+ uint16_t step_index;+} StepOffset;++/*+ * QueryState - The state of an in-progress match of a particular pattern+ * in a query. While executing, a `TSQueryCursor` must keep track of a number+ * of possible in-progress matches. Each of those possible matches is+ * represented as one of these states. Fields:+ * - `id` - A numeric id that is exposed to the public API. This allows the+ * caller to remove a given match, preventing any more of its captures+ * from being returned.+ * - `start_depth` - The depth in the tree where the first step of the state's+ * pattern was matched.+ * - `pattern_index` - The pattern that the state is matching.+ * - `consumed_capture_count` - The number of captures from this match that+ * have already been returned.+ * - `capture_list_id` - A numeric id that can be used to retrieve the state's+ * list of captures from the `CaptureListPool`.+ * - `seeking_immediate_match` - A flag that indicates that the state's next+ * step must be matched by the very next sibling. This is used when+ * processing repetitions.+ * - `has_in_progress_alternatives` - A flag that indicates that there is are+ * other states that have the same captures as this state, but are at+ * different steps in their pattern. This means that in order to obey the+ * 'longest-match' rule, this state should not be returned as a match until+ * it is clear that there can be no other alternative match with more captures.+ */+typedef struct {+ uint32_t id;+ uint32_t capture_list_id;+ uint16_t start_depth;+ uint16_t step_index;+ uint16_t pattern_index;+ uint16_t consumed_capture_count: 12;+ bool seeking_immediate_match: 1;+ bool has_in_progress_alternatives: 1;+ bool dead: 1;+ bool needs_parent: 1;+} QueryState;++typedef Array(TSQueryCapture) CaptureList;++/*+ * CaptureListPool - A collection of *lists* of captures. Each query state needs+ * to maintain its own list of captures. To avoid repeated allocations, this struct+ * maintains a fixed set of capture lists, and keeps track of which ones are+ * currently in use by a query state.+ */+typedef struct {+ Array(CaptureList) list;+ CaptureList empty_list;+ // The maximum number of capture lists that we are allowed to allocate. We+ // never allow `list` to allocate more entries than this, dropping pending+ // matches if needed to stay under the limit.+ uint32_t max_capture_list_count;+ // The number of capture lists allocated in `list` that are not currently in+ // use. We reuse those existing-but-unused capture lists before trying to+ // allocate any new ones. We use an invalid value (UINT32_MAX) for a capture+ // list's length to indicate that it's not in use.+ uint32_t free_capture_list_count;+} CaptureListPool;++/*+ * AnalysisState - The state needed for walking the parse table when analyzing+ * a query pattern, to determine at which steps the pattern might fail to match.+ */+typedef struct {+ TSStateId parse_state;+ TSSymbol parent_symbol;+ uint16_t child_index;+ TSFieldId field_id: 15;+ bool done: 1;+} AnalysisStateEntry;++typedef struct {+ AnalysisStateEntry stack[MAX_ANALYSIS_STATE_DEPTH];+ uint16_t depth;+ uint16_t step_index;+ TSSymbol root_symbol;+} AnalysisState;++typedef Array(AnalysisState *) AnalysisStateSet;++typedef struct {+ AnalysisStateSet states;+ AnalysisStateSet next_states;+ AnalysisStateSet deeper_states;+ AnalysisStateSet state_pool;+ Array(uint16_t) final_step_indices;+ Array(TSSymbol) finished_parent_symbols;+ bool did_abort;+} QueryAnalysis;++/*+ * AnalysisSubgraph - A subset of the states in the parse table that are used+ * in constructing nodes with a certain symbol. Each state is accompanied by+ * some information about the possible node that could be produced in+ * downstream states.+ */+typedef struct {+ TSStateId state;+ uint16_t production_id;+ uint8_t child_index: 7;+ bool done: 1;+} AnalysisSubgraphNode;++typedef struct {+ TSSymbol symbol;+ Array(TSStateId) start_states;+ Array(AnalysisSubgraphNode) nodes;+} AnalysisSubgraph;++typedef Array(AnalysisSubgraph) AnalysisSubgraphArray;++/*+ * StatePredecessorMap - A map that stores the predecessors of each parse state.+ * This is used during query analysis to determine which parse states can lead+ * to which reduce actions.+ */+typedef struct {+ TSStateId *contents;+} StatePredecessorMap;++/*+ * TSQuery - A tree query, compiled from a string of S-expressions. The query+ * itself is immutable. The mutable state used in the process of executing the+ * query is stored in a `TSQueryCursor`.+ */+struct TSQuery {+ SymbolTable captures;+ SymbolTable predicate_values;+ Array(CaptureQuantifiers) capture_quantifiers;+ Array(QueryStep) steps;+ Array(PatternEntry) pattern_map;+ Array(TSQueryPredicateStep) predicate_steps;+ Array(QueryPattern) patterns;+ Array(StepOffset) step_offsets;+ Array(TSFieldId) negated_fields;+ Array(char) string_buffer;+ Array(TSSymbol) repeat_symbols_with_rootless_patterns;+ const TSLanguage *language;+ uint16_t wildcard_root_pattern_count;+};++/*+ * TSQueryCursor - A stateful struct used to execute a query on a tree.+ */+struct TSQueryCursor {+ const TSQuery *query;+ TSTreeCursor cursor;+ Array(QueryState) states;+ Array(QueryState) finished_states;+ CaptureListPool capture_list_pool;+ uint32_t depth;+ uint32_t max_start_depth;+ uint32_t start_byte;+ uint32_t end_byte;+ TSPoint start_point;+ TSPoint end_point;+ uint32_t next_state_id;+ TSClock end_clock;+ TSDuration timeout_duration;+ unsigned operation_count;+ bool on_visible_node;+ bool ascending;+ bool halted;+ bool did_exceed_match_limit;+};++static const TSQueryError PARENT_DONE = -1;+static const uint16_t PATTERN_DONE_MARKER = UINT16_MAX;+static const uint16_t NONE = UINT16_MAX;+static const TSSymbol WILDCARD_SYMBOL = 0;+static const unsigned OP_COUNT_PER_QUERY_TIMEOUT_CHECK = 100;++/**********+ * Stream+ **********/++// Advance to the next unicode code point in the stream.+static bool stream_advance(Stream *self) {+ self->input += self->next_size;+ if (self->input < self->end) {+ uint32_t size = ts_decode_utf8(+ (const uint8_t *)self->input,+ (uint32_t)(self->end - self->input),+ &self->next+ );+ if (size > 0) {+ self->next_size = size;+ return true;+ }+ } else {+ self->next_size = 0;+ self->next = '\0';+ }+ return false;+}++// Reset the stream to the given input position, represented as a pointer+// into the input string.+static void stream_reset(Stream *self, const char *input) {+ self->input = input;+ self->next_size = 0;+ stream_advance(self);+}++static Stream stream_new(const char *string, uint32_t length) {+ Stream self = {+ .next = 0,+ .input = string,+ .start = string,+ .end = string + length,+ };+ stream_advance(&self);+ return self;+}++static void stream_skip_whitespace(Stream *self) {+ for (;;) {+ if (iswspace(self->next)) {+ stream_advance(self);+ } else if (self->next == ';') {+ // skip over comments+ stream_advance(self);+ while (self->next && self->next != '\n') {+ if (!stream_advance(self)) break;+ }+ } else {+ break;+ }+ }+}++static bool stream_is_ident_start(Stream *self) {+ return iswalnum(self->next) || self->next == '_' || self->next == '-';+}++static void stream_scan_identifier(Stream *stream) {+ do {+ stream_advance(stream);+ } while (+ iswalnum(stream->next) ||+ stream->next == '_' ||+ stream->next == '-' ||+ stream->next == '.' ||+ stream->next == '?' ||+ stream->next == '!'+ );+}++static uint32_t stream_offset(Stream *self) {+ return (uint32_t)(self->input - self->start);+}++/******************+ * CaptureListPool+ ******************/++static CaptureListPool capture_list_pool_new(void) {+ return (CaptureListPool) {+ .list = array_new(),+ .empty_list = array_new(),+ .max_capture_list_count = UINT32_MAX,+ .free_capture_list_count = 0,+ };+}++static void capture_list_pool_reset(CaptureListPool *self) {+ for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {+ // This invalid size means that the list is not in use.+ self->list.contents[i].size = UINT32_MAX;+ }+ self->free_capture_list_count = self->list.size;+}++static void capture_list_pool_delete(CaptureListPool *self) {+ for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {+ array_delete(&self->list.contents[i]);+ }+ array_delete(&self->list);+}++static const CaptureList *capture_list_pool_get(const CaptureListPool *self, uint16_t id) {+ if (id >= self->list.size) return &self->empty_list;+ return &self->list.contents[id];+}++static CaptureList *capture_list_pool_get_mut(CaptureListPool *self, uint16_t id) {+ ts_assert(id < self->list.size);+ return &self->list.contents[id];+}++static bool capture_list_pool_is_empty(const CaptureListPool *self) {+ // The capture list pool is empty if all allocated lists are in use, and we+ // have reached the maximum allowed number of allocated lists.+ return self->free_capture_list_count == 0 && self->list.size >= self->max_capture_list_count;+}++static uint16_t capture_list_pool_acquire(CaptureListPool *self) {+ // First see if any already allocated capture list is currently unused.+ if (self->free_capture_list_count > 0) {+ for (uint16_t i = 0; i < (uint16_t)self->list.size; i++) {+ if (self->list.contents[i].size == UINT32_MAX) {+ array_clear(&self->list.contents[i]);+ self->free_capture_list_count--;+ return i;+ }+ }+ }++ // Otherwise allocate and initialize a new capture list, as long as that+ // doesn't put us over the requested maximum.+ uint32_t i = self->list.size;+ if (i >= self->max_capture_list_count) {+ return NONE;+ }+ CaptureList list;+ array_init(&list);+ array_push(&self->list, list);+ return i;+}++static void capture_list_pool_release(CaptureListPool *self, uint16_t id) {+ if (id >= self->list.size) return;+ self->list.contents[id].size = UINT32_MAX;+ self->free_capture_list_count++;+}++/**************+ * Quantifiers+ **************/++static TSQuantifier quantifier_mul(+ TSQuantifier left,+ TSQuantifier right+) {+ switch (left)+ {+ case TSQuantifierZero:+ return TSQuantifierZero;+ case TSQuantifierZeroOrOne:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZero;+ case TSQuantifierZeroOrOne:+ case TSQuantifierOne:+ return TSQuantifierZeroOrOne;+ case TSQuantifierZeroOrMore:+ case TSQuantifierOneOrMore:+ return TSQuantifierZeroOrMore;+ };+ break;+ case TSQuantifierZeroOrMore:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZero;+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierZeroOrMore;+ };+ break;+ case TSQuantifierOne:+ return right;+ case TSQuantifierOneOrMore:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZero;+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ }+ return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!+}++static TSQuantifier quantifier_join(+ TSQuantifier left,+ TSQuantifier right+) {+ switch (left)+ {+ case TSQuantifierZero:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZero;+ case TSQuantifierZeroOrOne:+ case TSQuantifierOne:+ return TSQuantifierZeroOrOne;+ case TSQuantifierZeroOrMore:+ case TSQuantifierOneOrMore:+ return TSQuantifierZeroOrMore;+ };+ break;+ case TSQuantifierZeroOrOne:+ switch (right) {+ case TSQuantifierZero:+ case TSQuantifierZeroOrOne:+ case TSQuantifierOne:+ return TSQuantifierZeroOrOne;+ break;+ case TSQuantifierZeroOrMore:+ case TSQuantifierOneOrMore:+ return TSQuantifierZeroOrMore;+ break;+ };+ break;+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ switch (right) {+ case TSQuantifierZero:+ case TSQuantifierZeroOrOne:+ return TSQuantifierZeroOrOne;+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ return TSQuantifierOne;+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ case TSQuantifierOneOrMore:+ switch (right) {+ case TSQuantifierZero:+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ }+ return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!+}++static TSQuantifier quantifier_add(+ TSQuantifier left,+ TSQuantifier right+) {+ switch (left)+ {+ case TSQuantifierZero:+ return right;+ case TSQuantifierZeroOrOne:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZeroOrOne;+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ case TSQuantifierZeroOrMore:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierZeroOrMore;+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ return TSQuantifierZeroOrMore;+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ case TSQuantifierOne:+ switch (right) {+ case TSQuantifierZero:+ return TSQuantifierOne;+ case TSQuantifierZeroOrOne:+ case TSQuantifierZeroOrMore:+ case TSQuantifierOne:+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ };+ break;+ case TSQuantifierOneOrMore:+ return TSQuantifierOneOrMore;+ }+ return TSQuantifierZero; // to make compiler happy, but all cases should be covered above!+}++// Create new capture quantifiers structure+static CaptureQuantifiers capture_quantifiers_new(void) {+ return (CaptureQuantifiers) array_new();+}++// Delete capture quantifiers structure+static void capture_quantifiers_delete(+ CaptureQuantifiers *self+) {+ array_delete(self);+}++// Clear capture quantifiers structure+static void capture_quantifiers_clear(+ CaptureQuantifiers *self+) {+ array_clear(self);+}++// Replace capture quantifiers with the given quantifiers+static void capture_quantifiers_replace(+ CaptureQuantifiers *self,+ CaptureQuantifiers *quantifiers+) {+ array_clear(self);+ array_push_all(self, quantifiers);+}++// Return capture quantifier for the given capture id+static TSQuantifier capture_quantifier_for_id(+ const CaptureQuantifiers *self,+ uint16_t id+) {+ return (self->size <= id) ? TSQuantifierZero : (TSQuantifier) *array_get(self, id);+}++// Add the given quantifier to the current value for id+static void capture_quantifiers_add_for_id(+ CaptureQuantifiers *self,+ uint16_t id,+ TSQuantifier quantifier+) {+ if (self->size <= id) {+ array_grow_by(self, id + 1 - self->size);+ }+ uint8_t *own_quantifier = array_get(self, id);+ *own_quantifier = (uint8_t) quantifier_add((TSQuantifier) *own_quantifier, quantifier);+}++// Point-wise add the given quantifiers to the current values+static void capture_quantifiers_add_all(+ CaptureQuantifiers *self,+ CaptureQuantifiers *quantifiers+) {+ if (self->size < quantifiers->size) {+ array_grow_by(self, quantifiers->size - self->size);+ }+ for (uint16_t id = 0; id < (uint16_t)quantifiers->size; id++) {+ uint8_t *quantifier = array_get(quantifiers, id);+ uint8_t *own_quantifier = array_get(self, id);+ *own_quantifier = (uint8_t) quantifier_add((TSQuantifier) *own_quantifier, (TSQuantifier) *quantifier);+ }+}++// Join the given quantifier with the current values+static void capture_quantifiers_mul(+ CaptureQuantifiers *self,+ TSQuantifier quantifier+) {+ for (uint16_t id = 0; id < (uint16_t)self->size; id++) {+ uint8_t *own_quantifier = array_get(self, id);+ *own_quantifier = (uint8_t) quantifier_mul((TSQuantifier) *own_quantifier, quantifier);+ }+}++// Point-wise join the quantifiers from a list of alternatives with the current values+static void capture_quantifiers_join_all(+ CaptureQuantifiers *self,+ CaptureQuantifiers *quantifiers+) {+ if (self->size < quantifiers->size) {+ array_grow_by(self, quantifiers->size - self->size);+ }+ for (uint32_t id = 0; id < quantifiers->size; id++) {+ uint8_t *quantifier = array_get(quantifiers, id);+ uint8_t *own_quantifier = array_get(self, id);+ *own_quantifier = (uint8_t) quantifier_join((TSQuantifier) *own_quantifier, (TSQuantifier) *quantifier);+ }+ for (uint32_t id = quantifiers->size; id < self->size; id++) {+ uint8_t *own_quantifier = array_get(self, id);+ *own_quantifier = (uint8_t) quantifier_join((TSQuantifier) *own_quantifier, TSQuantifierZero);+ }+}++/**************+ * SymbolTable+ **************/++static SymbolTable symbol_table_new(void) {+ return (SymbolTable) {+ .characters = array_new(),+ .slices = array_new(),+ };+}++static void symbol_table_delete(SymbolTable *self) {+ array_delete(&self->characters);+ array_delete(&self->slices);+}++static int symbol_table_id_for_name(+ const SymbolTable *self,+ const char *name,+ uint32_t length+) {+ for (unsigned i = 0; i < self->slices.size; i++) {+ Slice slice = self->slices.contents[i];+ if (+ slice.length == length &&+ !strncmp(&self->characters.contents[slice.offset], name, length)+ ) return i;+ }+ return -1;+}++static const char *symbol_table_name_for_id(+ const SymbolTable *self,+ uint16_t id,+ uint32_t *length+) {+ Slice slice = self->slices.contents[id];+ *length = slice.length;+ return &self->characters.contents[slice.offset];+}++static uint16_t symbol_table_insert_name(+ SymbolTable *self,+ const char *name,+ uint32_t length+) {+ int id = symbol_table_id_for_name(self, name, length);+ if (id >= 0) return (uint16_t)id;+ Slice slice = {+ .offset = self->characters.size,+ .length = length,+ };+ array_grow_by(&self->characters, length + 1);+ memcpy(&self->characters.contents[slice.offset], name, length);+ self->characters.contents[self->characters.size - 1] = 0;+ array_push(&self->slices, slice);+ return self->slices.size - 1;+}++/************+ * QueryStep+ ************/++static QueryStep query_step__new(+ TSSymbol symbol,+ uint16_t depth,+ bool is_immediate+) {+ QueryStep step = {+ .symbol = symbol,+ .depth = depth,+ .field = 0,+ .alternative_index = NONE,+ .negated_field_list_id = 0,+ .contains_captures = false,+ .is_last_child = false,+ .is_named = false,+ .is_pass_through = false,+ .is_dead_end = false,+ .root_pattern_guaranteed = false,+ .is_immediate = is_immediate,+ .alternative_is_immediate = false,+ };+ for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {+ step.capture_ids[i] = NONE;+ }+ return step;+}++static void query_step__add_capture(QueryStep *self, uint16_t capture_id) {+ for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {+ if (self->capture_ids[i] == NONE) {+ self->capture_ids[i] = capture_id;+ break;+ }+ }+}++static void query_step__remove_capture(QueryStep *self, uint16_t capture_id) {+ for (unsigned i = 0; i < MAX_STEP_CAPTURE_COUNT; i++) {+ if (self->capture_ids[i] == capture_id) {+ self->capture_ids[i] = NONE;+ while (i + 1 < MAX_STEP_CAPTURE_COUNT) {+ if (self->capture_ids[i + 1] == NONE) break;+ self->capture_ids[i] = self->capture_ids[i + 1];+ self->capture_ids[i + 1] = NONE;+ i++;+ }+ break;+ }+ }+}++/**********************+ * StatePredecessorMap+ **********************/++static inline StatePredecessorMap state_predecessor_map_new(+ const TSLanguage *language+) {+ return (StatePredecessorMap) {+ .contents = ts_calloc(+ (size_t)language->state_count * (MAX_STATE_PREDECESSOR_COUNT + 1),+ sizeof(TSStateId)+ ),+ };+}++static inline void state_predecessor_map_delete(StatePredecessorMap *self) {+ ts_free(self->contents);+}++static inline void state_predecessor_map_add(+ StatePredecessorMap *self,+ TSStateId state,+ TSStateId predecessor+) {+ size_t index = (size_t)state * (MAX_STATE_PREDECESSOR_COUNT + 1);+ TSStateId *count = &self->contents[index];+ if (+ *count == 0 ||+ (*count < MAX_STATE_PREDECESSOR_COUNT && self->contents[index + *count] != predecessor)+ ) {+ (*count)++;+ self->contents[index + *count] = predecessor;+ }+}++static inline const TSStateId *state_predecessor_map_get(+ const StatePredecessorMap *self,+ TSStateId state,+ unsigned *count+) {+ size_t index = (size_t)state * (MAX_STATE_PREDECESSOR_COUNT + 1);+ *count = self->contents[index];+ return &self->contents[index + 1];+}++/****************+ * AnalysisState+ ****************/++static unsigned analysis_state__recursion_depth(const AnalysisState *self) {+ unsigned result = 0;+ for (unsigned i = 0; i < self->depth; i++) {+ TSSymbol symbol = self->stack[i].parent_symbol;+ for (unsigned j = 0; j < i; j++) {+ if (self->stack[j].parent_symbol == symbol) {+ result++;+ break;+ }+ }+ }+ return result;+}++static inline int analysis_state__compare_position(+ AnalysisState *const *self,+ AnalysisState *const *other+) {+ for (unsigned i = 0; i < (*self)->depth; i++) {+ if (i >= (*other)->depth) return -1;+ if ((*self)->stack[i].child_index < (*other)->stack[i].child_index) return -1;+ if ((*self)->stack[i].child_index > (*other)->stack[i].child_index) return 1;+ }+ if ((*self)->depth < (*other)->depth) return 1;+ if ((*self)->step_index < (*other)->step_index) return -1;+ if ((*self)->step_index > (*other)->step_index) return 1;+ return 0;+}++static inline int analysis_state__compare(+ AnalysisState *const *self,+ AnalysisState *const *other+) {+ int result = analysis_state__compare_position(self, other);+ if (result != 0) return result;+ for (unsigned i = 0; i < (*self)->depth; i++) {+ if ((*self)->stack[i].parent_symbol < (*other)->stack[i].parent_symbol) return -1;+ if ((*self)->stack[i].parent_symbol > (*other)->stack[i].parent_symbol) return 1;+ if ((*self)->stack[i].parse_state < (*other)->stack[i].parse_state) return -1;+ if ((*self)->stack[i].parse_state > (*other)->stack[i].parse_state) return 1;+ if ((*self)->stack[i].field_id < (*other)->stack[i].field_id) return -1;+ if ((*self)->stack[i].field_id > (*other)->stack[i].field_id) return 1;+ }+ return 0;+}++static inline AnalysisStateEntry *analysis_state__top(AnalysisState *self) {+ if (self->depth == 0) {+ return &self->stack[0];+ }+ return &self->stack[self->depth - 1];+}++static inline bool analysis_state__has_supertype(AnalysisState *self, TSSymbol symbol) {+ for (unsigned i = 0; i < self->depth; i++) {+ if (self->stack[i].parent_symbol == symbol) return true;+ }+ return false;+}++/******************+ * AnalysisStateSet+ ******************/++// Obtains an `AnalysisState` instance, either by consuming one from this set's object pool, or by+// cloning one from scratch.+static inline AnalysisState *analysis_state_pool__clone_or_reuse(+ AnalysisStateSet *self,+ AnalysisState *borrowed_item+) {+ AnalysisState *new_item;+ if (self->size) {+ new_item = array_pop(self);+ } else {+ new_item = ts_malloc(sizeof(AnalysisState));+ }+ *new_item = *borrowed_item;+ return new_item;+}++// Inserts a clone of the passed-in item at the appropriate position to maintain ordering in this+// set. The set does not contain duplicates, so if the item is already present, it will not be+// inserted, and no clone will be made.+//+// The caller retains ownership of the passed-in memory. However, the clone that is created by this+// function will be managed by the state set.+static inline void analysis_state_set__insert_sorted(+ AnalysisStateSet *self,+ AnalysisStateSet *pool,+ AnalysisState *borrowed_item+) {+ unsigned index, exists;+ array_search_sorted_with(self, analysis_state__compare, &borrowed_item, &index, &exists);+ if (!exists) {+ AnalysisState *new_item = analysis_state_pool__clone_or_reuse(pool, borrowed_item);+ array_insert(self, index, new_item);+ }+}++// Inserts a clone of the passed-in item at the end position of this list.+//+// IMPORTANT: The caller MUST ENSURE that this item is larger (by the comparison function+// `analysis_state__compare`) than largest item already in this set. If items are inserted in the+// wrong order, the set will not function properly for future use.+//+// The caller retains ownership of the passed-in memory. However, the clone that is created by this+// function will be managed by the state set.+static inline void analysis_state_set__push(+ AnalysisStateSet *self,+ AnalysisStateSet *pool,+ AnalysisState *borrowed_item+) {+ AnalysisState *new_item = analysis_state_pool__clone_or_reuse(pool, borrowed_item);+ array_push(self, new_item);+}++// Removes all items from this set, returning it to an empty state.+static inline void analysis_state_set__clear(AnalysisStateSet *self, AnalysisStateSet *pool) {+ array_push_all(pool, self);+ array_clear(self);+}++// Releases all memory that is managed with this state set, including any items currently present.+// After calling this function, the set is no longer suitable for use.+static inline void analysis_state_set__delete(AnalysisStateSet *self) {+ for (unsigned i = 0; i < self->size; i++) {+ ts_free(self->contents[i]);+ }+ array_delete(self);+}++/****************+ * QueryAnalyzer+ ****************/++static inline QueryAnalysis query_analysis__new(void) {+ return (QueryAnalysis) {+ .states = array_new(),+ .next_states = array_new(),+ .deeper_states = array_new(),+ .state_pool = array_new(),+ .final_step_indices = array_new(),+ .finished_parent_symbols = array_new(),+ .did_abort = false,+ };+}++static inline void query_analysis__delete(QueryAnalysis *self) {+ analysis_state_set__delete(&self->states);+ analysis_state_set__delete(&self->next_states);+ analysis_state_set__delete(&self->deeper_states);+ analysis_state_set__delete(&self->state_pool);+ array_delete(&self->final_step_indices);+ array_delete(&self->finished_parent_symbols);+}++/***********************+ * AnalysisSubgraphNode+ ***********************/++static inline int analysis_subgraph_node__compare(const AnalysisSubgraphNode *self, const AnalysisSubgraphNode *other) {+ if (self->state < other->state) return -1;+ if (self->state > other->state) return 1;+ if (self->child_index < other->child_index) return -1;+ if (self->child_index > other->child_index) return 1;+ if (self->done < other->done) return -1;+ if (self->done > other->done) return 1;+ if (self->production_id < other->production_id) return -1;+ if (self->production_id > other->production_id) return 1;+ return 0;+}++/*********+ * Query+ *********/++// The `pattern_map` contains a mapping from TSSymbol values to indices in the+// `steps` array. For a given syntax node, the `pattern_map` makes it possible+// to quickly find the starting steps of all of the patterns whose root matches+// that node. Each entry has two fields: a `pattern_index`, which identifies one+// of the patterns in the query, and a `step_index`, which indicates the start+// offset of that pattern's steps within the `steps` array.+//+// The entries are sorted by the patterns' root symbols, and lookups use a+// binary search. This ensures that the cost of this initial lookup step+// scales logarithmically with the number of patterns in the query.+//+// This returns `true` if the symbol is present and `false` otherwise.+// If the symbol is not present `*result` is set to the index where the+// symbol should be inserted.+static inline bool ts_query__pattern_map_search(+ const TSQuery *self,+ TSSymbol needle,+ uint32_t *result+) {+ uint32_t base_index = self->wildcard_root_pattern_count;+ uint32_t size = self->pattern_map.size - base_index;+ if (size == 0) {+ *result = base_index;+ return false;+ }+ while (size > 1) {+ uint32_t half_size = size / 2;+ uint32_t mid_index = base_index + half_size;+ TSSymbol mid_symbol = self->steps.contents[+ self->pattern_map.contents[mid_index].step_index+ ].symbol;+ if (needle > mid_symbol) base_index = mid_index;+ size -= half_size;+ }++ TSSymbol symbol = self->steps.contents[+ self->pattern_map.contents[base_index].step_index+ ].symbol;++ if (needle > symbol) {+ base_index++;+ if (base_index < self->pattern_map.size) {+ symbol = self->steps.contents[+ self->pattern_map.contents[base_index].step_index+ ].symbol;+ }+ }++ *result = base_index;+ return needle == symbol;+}++// Insert a new pattern's start index into the pattern map, maintaining+// the pattern map's ordering invariant.+static inline void ts_query__pattern_map_insert(+ TSQuery *self,+ TSSymbol symbol,+ PatternEntry new_entry+) {+ uint32_t index;+ ts_query__pattern_map_search(self, symbol, &index);++ // Ensure that the entries are sorted not only by symbol, but also+ // by pattern_index. This way, states for earlier patterns will be+ // initiated first, which allows the ordering of the states array+ // to be maintained more efficiently.+ while (index < self->pattern_map.size) {+ PatternEntry *entry = &self->pattern_map.contents[index];+ if (+ self->steps.contents[entry->step_index].symbol == symbol &&+ entry->pattern_index < new_entry.pattern_index+ ) {+ index++;+ } else {+ break;+ }+ }++ array_insert(&self->pattern_map, index, new_entry);+}++// Walk the subgraph for this non-terminal, tracking all of the possible+// sequences of progress within the pattern.+static void ts_query__perform_analysis(+ TSQuery *self,+ const AnalysisSubgraphArray *subgraphs,+ QueryAnalysis *analysis+) {+ unsigned recursion_depth_limit = 0;+ unsigned prev_final_step_count = 0;+ array_clear(&analysis->final_step_indices);+ array_clear(&analysis->finished_parent_symbols);++ for (unsigned iteration = 0;; iteration++) {+ if (iteration == MAX_ANALYSIS_ITERATION_COUNT) {+ analysis->did_abort = true;+ break;+ }++ #ifdef DEBUG_ANALYZE_QUERY+ printf("Iteration: %u. Final step indices:", iteration);+ for (unsigned j = 0; j < analysis->final_step_indices.size; j++) {+ printf(" %4u", analysis->final_step_indices.contents[j]);+ }+ printf("\n");+ for (unsigned j = 0; j < analysis->states.size; j++) {+ AnalysisState *state = analysis->states.contents[j];+ printf(" %3u: step: %u, stack: [", j, state->step_index);+ for (unsigned k = 0; k < state->depth; k++) {+ printf(+ " {%s, child: %u, state: %4u",+ self->language->symbol_names[state->stack[k].parent_symbol],+ state->stack[k].child_index,+ state->stack[k].parse_state+ );+ if (state->stack[k].field_id) printf(", field: %s", self->language->field_names[state->stack[k].field_id]);+ if (state->stack[k].done) printf(", DONE");+ printf("}");+ }+ printf(" ]\n");+ }+ #endif++ // If no further progress can be made within the current recursion depth limit, then+ // bump the depth limit by one, and continue to process the states the exceeded the+ // limit. But only allow this if progress has been made since the last time the depth+ // limit was increased.+ if (analysis->states.size == 0) {+ if (+ analysis->deeper_states.size > 0 &&+ analysis->final_step_indices.size > prev_final_step_count+ ) {+ #ifdef DEBUG_ANALYZE_QUERY+ printf("Increase recursion depth limit to %u\n", recursion_depth_limit + 1);+ #endif++ prev_final_step_count = analysis->final_step_indices.size;+ recursion_depth_limit++;+ AnalysisStateSet _states = analysis->states;+ analysis->states = analysis->deeper_states;+ analysis->deeper_states = _states;+ continue;+ }++ break;+ }++ analysis_state_set__clear(&analysis->next_states, &analysis->state_pool);+ for (unsigned j = 0; j < analysis->states.size; j++) {+ AnalysisState * const state = analysis->states.contents[j];++ // For efficiency, it's important to avoid processing the same analysis state more+ // than once. To achieve this, keep the states in order of ascending position within+ // their hypothetical syntax trees. In each iteration of this loop, start by advancing+ // the states that have made the least progress. Avoid advancing states that have already+ // made more progress.+ if (analysis->next_states.size > 0) {+ int comparison = analysis_state__compare_position(+ &state,+ array_back(&analysis->next_states)+ );+ if (comparison == 0) {+ analysis_state_set__insert_sorted(&analysis->next_states, &analysis->state_pool, state);+ continue;+ } else if (comparison > 0) {+ #ifdef DEBUG_ANALYZE_QUERY+ printf("Terminate iteration at state %u\n", j);+ #endif+ while (j < analysis->states.size) {+ analysis_state_set__push(+ &analysis->next_states,+ &analysis->state_pool,+ analysis->states.contents[j]+ );+ j++;+ }+ break;+ }+ }++ const TSStateId parse_state = analysis_state__top(state)->parse_state;+ const TSSymbol parent_symbol = analysis_state__top(state)->parent_symbol;+ const TSFieldId parent_field_id = analysis_state__top(state)->field_id;+ const unsigned child_index = analysis_state__top(state)->child_index;+ const QueryStep * const step = &self->steps.contents[state->step_index];++ unsigned subgraph_index, exists;+ array_search_sorted_by(subgraphs, .symbol, parent_symbol, &subgraph_index, &exists);+ if (!exists) continue;+ const AnalysisSubgraph *subgraph = &subgraphs->contents[subgraph_index];++ // Follow every possible path in the parse table, but only visit states that+ // are part of the subgraph for the current symbol.+ LookaheadIterator lookahead_iterator = ts_language_lookaheads(self->language, parse_state);+ while (ts_lookahead_iterator__next(&lookahead_iterator)) {+ TSSymbol sym = lookahead_iterator.symbol;++ AnalysisSubgraphNode successor = {+ .state = parse_state,+ .child_index = child_index,+ };+ if (lookahead_iterator.action_count) {+ const TSParseAction *action = &lookahead_iterator.actions[lookahead_iterator.action_count - 1];+ if (action->type == TSParseActionTypeShift) {+ if (!action->shift.extra) {+ successor.state = action->shift.state;+ successor.child_index++;+ }+ } else {+ continue;+ }+ } else if (lookahead_iterator.next_state != 0) {+ successor.state = lookahead_iterator.next_state;+ successor.child_index++;+ } else {+ continue;+ }++ unsigned node_index;+ array_search_sorted_with(+ &subgraph->nodes,+ analysis_subgraph_node__compare, &successor,+ &node_index, &exists+ );+ while (node_index < subgraph->nodes.size) {+ AnalysisSubgraphNode *node = &subgraph->nodes.contents[node_index++];+ if (node->state != successor.state || node->child_index != successor.child_index) break;++ // Use the subgraph to determine what alias and field will eventually be applied+ // to this child node.+ TSSymbol alias = ts_language_alias_at(self->language, node->production_id, child_index);+ TSSymbol visible_symbol = alias+ ? alias+ : self->language->symbol_metadata[sym].visible+ ? self->language->public_symbol_map[sym]+ : 0;+ TSFieldId field_id = parent_field_id;+ if (!field_id) {+ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(self->language, node->production_id, &field_map, &field_map_end);+ for (; field_map != field_map_end; field_map++) {+ if (!field_map->inherited && field_map->child_index == child_index) {+ field_id = field_map->field_id;+ break;+ }+ }+ }++ // Create a new state that has advanced past this hypothetical subtree.+ AnalysisState next_state = *state;+ AnalysisStateEntry *next_state_top = analysis_state__top(&next_state);+ next_state_top->child_index = successor.child_index;+ next_state_top->parse_state = successor.state;+ if (node->done) next_state_top->done = true;++ // Determine if this hypothetical child node would match the current step+ // of the query pattern.+ bool does_match = false;+ if (visible_symbol) {+ does_match = true;+ if (step->symbol == WILDCARD_SYMBOL) {+ if (+ step->is_named &&+ !self->language->symbol_metadata[visible_symbol].named+ ) does_match = false;+ } else if (step->symbol != visible_symbol) {+ does_match = false;+ }+ if (step->field && step->field != field_id) {+ does_match = false;+ }+ if (+ step->supertype_symbol &&+ !analysis_state__has_supertype(state, step->supertype_symbol)+ ) does_match = false;+ }++ // If this child is hidden, then descend into it and walk through its children.+ // If the top entry of the stack is at the end of its rule, then that entry can+ // be replaced. Otherwise, push a new entry onto the stack.+ else if (sym >= self->language->token_count) {+ if (!next_state_top->done) {+ if (next_state.depth + 1 >= MAX_ANALYSIS_STATE_DEPTH) {+ #ifdef DEBUG_ANALYZE_QUERY+ printf("Exceeded depth limit for state %u\n", j);+ #endif++ analysis->did_abort = true;+ continue;+ }++ next_state.depth++;+ next_state_top = analysis_state__top(&next_state);+ }++ *next_state_top = (AnalysisStateEntry) {+ .parse_state = parse_state,+ .parent_symbol = sym,+ .child_index = 0,+ .field_id = field_id,+ .done = false,+ };++ if (analysis_state__recursion_depth(&next_state) > recursion_depth_limit) {+ analysis_state_set__insert_sorted(+ &analysis->deeper_states,+ &analysis->state_pool,+ &next_state+ );+ continue;+ }+ }++ // Pop from the stack when this state reached the end of its current syntax node.+ while (next_state.depth > 0 && next_state_top->done) {+ next_state.depth--;+ next_state_top = analysis_state__top(&next_state);+ }++ // If this hypothetical child did match the current step of the query pattern,+ // then advance to the next step at the current depth. This involves skipping+ // over any descendant steps of the current child.+ const QueryStep *next_step = step;+ if (does_match) {+ for (;;) {+ next_state.step_index++;+ next_step = &self->steps.contents[next_state.step_index];+ if (+ next_step->depth == PATTERN_DONE_MARKER ||+ next_step->depth <= step->depth+ ) break;+ }+ } else if (successor.state == parse_state) {+ continue;+ }++ for (;;) {+ // Skip pass-through states. Although these states have alternatives, they are only+ // used to implement repetitions, and query analysis does not need to process+ // repetitions in order to determine whether steps are possible and definite.+ if (next_step->is_pass_through) {+ next_state.step_index++;+ next_step++;+ continue;+ }++ // If the pattern is finished or hypothetical parent node is complete, then+ // record that matching can terminate at this step of the pattern. Otherwise,+ // add this state to the list of states to process on the next iteration.+ if (!next_step->is_dead_end) {+ bool did_finish_pattern = self->steps.contents[next_state.step_index].depth != step->depth;+ if (did_finish_pattern) {+ array_insert_sorted_by(&analysis->finished_parent_symbols, , state->root_symbol);+ } else if (next_state.depth == 0) {+ array_insert_sorted_by(&analysis->final_step_indices, , next_state.step_index);+ } else {+ analysis_state_set__insert_sorted(&analysis->next_states, &analysis->state_pool, &next_state);+ }+ }++ // If the state has advanced to a step with an alternative step, then add another state+ // at that alternative step. This process is simpler than the process of actually matching a+ // pattern during query execution, because for the purposes of query analysis, there is no+ // need to process repetitions.+ if (+ does_match &&+ next_step->alternative_index != NONE &&+ next_step->alternative_index > next_state.step_index+ ) {+ next_state.step_index = next_step->alternative_index;+ next_step = &self->steps.contents[next_state.step_index];+ } else {+ break;+ }+ }+ }+ }+ }++ AnalysisStateSet _states = analysis->states;+ analysis->states = analysis->next_states;+ analysis->next_states = _states;+ }+}++static bool ts_query__analyze_patterns(TSQuery *self, unsigned *error_offset) {+ Array(uint16_t) non_rooted_pattern_start_steps = array_new();+ for (unsigned i = 0; i < self->pattern_map.size; i++) {+ PatternEntry *pattern = &self->pattern_map.contents[i];+ if (!pattern->is_rooted) {+ QueryStep *step = &self->steps.contents[pattern->step_index];+ if (step->symbol != WILDCARD_SYMBOL) {+ array_push(&non_rooted_pattern_start_steps, i);+ }+ }+ }++ // Walk forward through all of the steps in the query, computing some+ // basic information about each step. Mark all of the steps that contain+ // captures, and record the indices of all of the steps that have child steps.+ Array(uint32_t) parent_step_indices = array_new();+ for (unsigned i = 0; i < self->steps.size; i++) {+ QueryStep *step = &self->steps.contents[i];+ if (step->depth == PATTERN_DONE_MARKER) {+ step->parent_pattern_guaranteed = true;+ step->root_pattern_guaranteed = true;+ continue;+ }++ bool has_children = false;+ bool is_wildcard = step->symbol == WILDCARD_SYMBOL;+ step->contains_captures = step->capture_ids[0] != NONE;+ for (unsigned j = i + 1; j < self->steps.size; j++) {+ QueryStep *next_step = &self->steps.contents[j];+ if (+ next_step->depth == PATTERN_DONE_MARKER ||+ next_step->depth <= step->depth+ ) break;+ if (next_step->capture_ids[0] != NONE) {+ step->contains_captures = true;+ }+ if (!is_wildcard) {+ next_step->root_pattern_guaranteed = true;+ next_step->parent_pattern_guaranteed = true;+ }+ has_children = true;+ }++ if (has_children && !is_wildcard) {+ array_push(&parent_step_indices, i);+ }+ }++ // For every parent symbol in the query, initialize an 'analysis subgraph'.+ // This subgraph lists all of the states in the parse table that are directly+ // involved in building subtrees for this symbol.+ //+ // In addition to the parent symbols in the query, construct subgraphs for all+ // of the hidden symbols in the grammar, because these might occur within+ // one of the parent nodes, such that their children appear to belong to the+ // parent.+ AnalysisSubgraphArray subgraphs = array_new();+ for (unsigned i = 0; i < parent_step_indices.size; i++) {+ uint32_t parent_step_index = parent_step_indices.contents[i];+ TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;+ AnalysisSubgraph subgraph = { .symbol = parent_symbol };+ array_insert_sorted_by(&subgraphs, .symbol, subgraph);+ }+ for (TSSymbol sym = (uint16_t)self->language->token_count; sym < (uint16_t)self->language->symbol_count; sym++) {+ if (!ts_language_symbol_metadata(self->language, sym).visible) {+ AnalysisSubgraph subgraph = { .symbol = sym };+ array_insert_sorted_by(&subgraphs, .symbol, subgraph);+ }+ }++ // Scan the parse table to find the data needed to populate these subgraphs.+ // Collect three things during this scan:+ // 1) All of the parse states where one of these symbols can start.+ // 2) All of the parse states where one of these symbols can end, along+ // with information about the node that would be created.+ // 3) A list of predecessor states for each state.+ StatePredecessorMap predecessor_map = state_predecessor_map_new(self->language);+ for (TSStateId state = 1; state < (uint16_t)self->language->state_count; state++) {+ unsigned subgraph_index, exists;+ LookaheadIterator lookahead_iterator = ts_language_lookaheads(self->language, state);+ while (ts_lookahead_iterator__next(&lookahead_iterator)) {+ if (lookahead_iterator.action_count) {+ for (unsigned i = 0; i < lookahead_iterator.action_count; i++) {+ const TSParseAction *action = &lookahead_iterator.actions[i];+ if (action->type == TSParseActionTypeReduce) {+ const TSSymbol *aliases, *aliases_end;+ ts_language_aliases_for_symbol(+ self->language,+ action->reduce.symbol,+ &aliases,+ &aliases_end+ );+ for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {+ array_search_sorted_by(+ &subgraphs,+ .symbol,+ *symbol,+ &subgraph_index,+ &exists+ );+ if (exists) {+ AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];+ if (subgraph->nodes.size == 0 || array_back(&subgraph->nodes)->state != state) {+ array_push(&subgraph->nodes, ((AnalysisSubgraphNode) {+ .state = state,+ .production_id = action->reduce.production_id,+ .child_index = action->reduce.child_count,+ .done = true,+ }));+ }+ }+ }+ } else if (action->type == TSParseActionTypeShift && !action->shift.extra) {+ TSStateId next_state = action->shift.state;+ state_predecessor_map_add(&predecessor_map, next_state, state);+ }+ }+ } else if (lookahead_iterator.next_state != 0) {+ if (lookahead_iterator.next_state != state) {+ state_predecessor_map_add(&predecessor_map, lookahead_iterator.next_state, state);+ }+ if (ts_language_state_is_primary(self->language, state)) {+ const TSSymbol *aliases, *aliases_end;+ ts_language_aliases_for_symbol(+ self->language,+ lookahead_iterator.symbol,+ &aliases,+ &aliases_end+ );+ for (const TSSymbol *symbol = aliases; symbol < aliases_end; symbol++) {+ array_search_sorted_by(+ &subgraphs,+ .symbol,+ *symbol,+ &subgraph_index,+ &exists+ );+ if (exists) {+ AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];+ if (+ subgraph->start_states.size == 0 ||+ *array_back(&subgraph->start_states) != state+ )+ array_push(&subgraph->start_states, state);+ }+ }+ }+ }+ }+ }++ // For each subgraph, compute the preceding states by walking backward+ // from the end states using the predecessor map.+ Array(AnalysisSubgraphNode) next_nodes = array_new();+ for (unsigned i = 0; i < subgraphs.size; i++) {+ AnalysisSubgraph *subgraph = &subgraphs.contents[i];+ if (subgraph->nodes.size == 0) {+ array_delete(&subgraph->start_states);+ array_erase(&subgraphs, i);+ i--;+ continue;+ }+ array_assign(&next_nodes, &subgraph->nodes);+ while (next_nodes.size > 0) {+ AnalysisSubgraphNode node = array_pop(&next_nodes);+ if (node.child_index > 1) {+ unsigned predecessor_count;+ const TSStateId *predecessors = state_predecessor_map_get(+ &predecessor_map,+ node.state,+ &predecessor_count+ );+ for (unsigned j = 0; j < predecessor_count; j++) {+ AnalysisSubgraphNode predecessor_node = {+ .state = predecessors[j],+ .child_index = node.child_index - 1,+ .production_id = node.production_id,+ .done = false,+ };+ unsigned index, exists;+ array_search_sorted_with(+ &subgraph->nodes, analysis_subgraph_node__compare, &predecessor_node,+ &index, &exists+ );+ if (!exists) {+ array_insert(&subgraph->nodes, index, predecessor_node);+ array_push(&next_nodes, predecessor_node);+ }+ }+ }+ }+ }++ #ifdef DEBUG_ANALYZE_QUERY+ printf("\nSubgraphs:\n");+ for (unsigned i = 0; i < subgraphs.size; i++) {+ AnalysisSubgraph *subgraph = &subgraphs.contents[i];+ printf(" %u, %s:\n", subgraph->symbol, ts_language_symbol_name(self->language, subgraph->symbol));+ for (unsigned j = 0; j < subgraph->start_states.size; j++) {+ printf(+ " {state: %u}\n",+ subgraph->start_states.contents[j]+ );+ }+ for (unsigned j = 0; j < subgraph->nodes.size; j++) {+ AnalysisSubgraphNode *node = &subgraph->nodes.contents[j];+ printf(+ " {state: %u, child_index: %u, production_id: %u, done: %d}\n",+ node->state, node->child_index, node->production_id, node->done+ );+ }+ printf("\n");+ }+ #endif++ // For each non-terminal pattern, determine if the pattern can successfully match,+ // and identify all of the possible children within the pattern where matching could fail.+ bool all_patterns_are_valid = true;+ QueryAnalysis analysis = query_analysis__new();+ for (unsigned i = 0; i < parent_step_indices.size; i++) {+ uint16_t parent_step_index = parent_step_indices.contents[i];+ uint16_t parent_depth = self->steps.contents[parent_step_index].depth;+ TSSymbol parent_symbol = self->steps.contents[parent_step_index].symbol;+ if (parent_symbol == ts_builtin_sym_error) continue;++ // Find the subgraph that corresponds to this pattern's root symbol. If the pattern's+ // root symbol is a terminal, then return an error.+ unsigned subgraph_index, exists;+ array_search_sorted_by(&subgraphs, .symbol, parent_symbol, &subgraph_index, &exists);+ if (!exists) {+ unsigned first_child_step_index = parent_step_index + 1;+ uint32_t j, child_exists;+ array_search_sorted_by(&self->step_offsets, .step_index, first_child_step_index, &j, &child_exists);+ ts_assert(child_exists);+ *error_offset = self->step_offsets.contents[j].byte_offset;+ all_patterns_are_valid = false;+ break;+ }++ // Initialize an analysis state at every parse state in the table where+ // this parent symbol can occur.+ AnalysisSubgraph *subgraph = &subgraphs.contents[subgraph_index];+ analysis_state_set__clear(&analysis.states, &analysis.state_pool);+ analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);+ for (unsigned j = 0; j < subgraph->start_states.size; j++) {+ TSStateId parse_state = subgraph->start_states.contents[j];+ analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {+ .step_index = parent_step_index + 1,+ .stack = {+ [0] = {+ .parse_state = parse_state,+ .parent_symbol = parent_symbol,+ .child_index = 0,+ .field_id = 0,+ .done = false,+ },+ },+ .depth = 1,+ .root_symbol = parent_symbol,+ }));+ }++ #ifdef DEBUG_ANALYZE_QUERY+ printf(+ "\nWalk states for %s:\n",+ ts_language_symbol_name(self->language, analysis.states.contents[0]->stack[0].parent_symbol)+ );+ #endif++ analysis.did_abort = false;+ ts_query__perform_analysis(self, &subgraphs, &analysis);++ // If this pattern could not be fully analyzed, then every step should+ // be considered fallible.+ if (analysis.did_abort) {+ for (unsigned j = parent_step_index + 1; j < self->steps.size; j++) {+ QueryStep *step = &self->steps.contents[j];+ if (+ step->depth <= parent_depth ||+ step->depth == PATTERN_DONE_MARKER+ ) break;+ if (!step->is_dead_end) {+ step->parent_pattern_guaranteed = false;+ step->root_pattern_guaranteed = false;+ }+ }+ continue;+ }++ // If this pattern cannot match, store the pattern index so that it can be+ // returned to the caller.+ if (analysis.finished_parent_symbols.size == 0) {+ ts_assert(analysis.final_step_indices.size > 0);+ uint16_t impossible_step_index = *array_back(&analysis.final_step_indices);+ uint32_t j, impossible_exists;+ array_search_sorted_by(&self->step_offsets, .step_index, impossible_step_index, &j, &impossible_exists);+ if (j >= self->step_offsets.size) j = self->step_offsets.size - 1;+ *error_offset = self->step_offsets.contents[j].byte_offset;+ all_patterns_are_valid = false;+ break;+ }++ // Mark as fallible any step where a match terminated.+ // Later, this property will be propagated to all of the step's predecessors.+ for (unsigned j = 0; j < analysis.final_step_indices.size; j++) {+ uint32_t final_step_index = analysis.final_step_indices.contents[j];+ QueryStep *step = &self->steps.contents[final_step_index];+ if (+ step->depth != PATTERN_DONE_MARKER &&+ step->depth > parent_depth &&+ !step->is_dead_end+ ) {+ step->parent_pattern_guaranteed = false;+ step->root_pattern_guaranteed = false;+ }+ }+ }++ // Mark as indefinite any step with captures that are used in predicates.+ Array(uint16_t) predicate_capture_ids = array_new();+ for (unsigned i = 0; i < self->patterns.size; i++) {+ QueryPattern *pattern = &self->patterns.contents[i];++ // Gather all of the captures that are used in predicates for this pattern.+ array_clear(&predicate_capture_ids);+ for (+ unsigned start = pattern->predicate_steps.offset,+ end = start + pattern->predicate_steps.length,+ j = start; j < end; j+++ ) {+ TSQueryPredicateStep *step = &self->predicate_steps.contents[j];+ if (step->type == TSQueryPredicateStepTypeCapture) {+ uint16_t value_id = step->value_id;+ array_insert_sorted_by(&predicate_capture_ids, , value_id);+ }+ }++ // Find all of the steps that have these captures.+ for (+ unsigned start = pattern->steps.offset,+ end = start + pattern->steps.length,+ j = start; j < end; j+++ ) {+ QueryStep *step = &self->steps.contents[j];+ for (unsigned k = 0; k < MAX_STEP_CAPTURE_COUNT; k++) {+ uint16_t capture_id = step->capture_ids[k];+ if (capture_id == NONE) break;+ unsigned index, exists;+ array_search_sorted_by(&predicate_capture_ids, , capture_id, &index, &exists);+ if (exists) {+ step->root_pattern_guaranteed = false;+ break;+ }+ }+ }+ }++ // Propagate fallibility. If a pattern is fallible at a given step, then it is+ // fallible at all of its preceding steps.+ bool done = self->steps.size == 0;+ while (!done) {+ done = true;+ for (unsigned i = self->steps.size - 1; i > 0; i--) {+ QueryStep *step = &self->steps.contents[i];+ if (step->depth == PATTERN_DONE_MARKER) continue;++ // Determine if this step is definite or has definite alternatives.+ bool parent_pattern_guaranteed = false;+ for (;;) {+ if (step->root_pattern_guaranteed) {+ parent_pattern_guaranteed = true;+ break;+ }+ if (step->alternative_index == NONE || step->alternative_index < i) {+ break;+ }+ step = &self->steps.contents[step->alternative_index];+ }++ // If not, mark its predecessor as indefinite.+ if (!parent_pattern_guaranteed) {+ QueryStep *prev_step = &self->steps.contents[i - 1];+ if (+ !prev_step->is_dead_end &&+ prev_step->depth != PATTERN_DONE_MARKER &&+ prev_step->root_pattern_guaranteed+ ) {+ prev_step->root_pattern_guaranteed = false;+ done = false;+ }+ }+ }+ }++ #ifdef DEBUG_ANALYZE_QUERY+ printf("Steps:\n");+ for (unsigned i = 0; i < self->steps.size; i++) {+ QueryStep *step = &self->steps.contents[i];+ if (step->depth == PATTERN_DONE_MARKER) {+ printf(" %u: DONE\n", i);+ } else {+ printf(+ " %u: {symbol: %s, field: %s, depth: %u, parent_pattern_guaranteed: %d, root_pattern_guaranteed: %d}\n",+ i,+ (step->symbol == WILDCARD_SYMBOL)+ ? "ANY"+ : ts_language_symbol_name(self->language, step->symbol),+ (step->field ? ts_language_field_name_for_id(self->language, step->field) : "-"),+ step->depth,+ step->parent_pattern_guaranteed,+ step->root_pattern_guaranteed+ );+ }+ }+ #endif++ // Determine which repetition symbols in this language have the possibility+ // of matching non-rooted patterns in this query. These repetition symbols+ // prevent certain optimizations with range restrictions.+ analysis.did_abort = false;+ for (uint32_t i = 0; i < non_rooted_pattern_start_steps.size; i++) {+ uint16_t pattern_entry_index = non_rooted_pattern_start_steps.contents[i];+ PatternEntry *pattern_entry = &self->pattern_map.contents[pattern_entry_index];++ analysis_state_set__clear(&analysis.states, &analysis.state_pool);+ analysis_state_set__clear(&analysis.deeper_states, &analysis.state_pool);+ for (unsigned j = 0; j < subgraphs.size; j++) {+ AnalysisSubgraph *subgraph = &subgraphs.contents[j];+ TSSymbolMetadata metadata = ts_language_symbol_metadata(self->language, subgraph->symbol);+ if (metadata.visible || metadata.named) continue;++ for (uint32_t k = 0; k < subgraph->start_states.size; k++) {+ TSStateId parse_state = subgraph->start_states.contents[k];+ analysis_state_set__push(&analysis.states, &analysis.state_pool, &((AnalysisState) {+ .step_index = pattern_entry->step_index,+ .stack = {+ [0] = {+ .parse_state = parse_state,+ .parent_symbol = subgraph->symbol,+ .child_index = 0,+ .field_id = 0,+ .done = false,+ },+ },+ .root_symbol = subgraph->symbol,+ .depth = 1,+ }));+ }+ }++ #ifdef DEBUG_ANALYZE_QUERY+ printf("\nWalk states for rootless pattern step %u:\n", pattern_entry->step_index);+ #endif++ ts_query__perform_analysis(+ self,+ &subgraphs,+ &analysis+ );++ if (analysis.finished_parent_symbols.size > 0) {+ self->patterns.contents[pattern_entry->pattern_index].is_non_local = true;+ }++ for (unsigned k = 0; k < analysis.finished_parent_symbols.size; k++) {+ TSSymbol symbol = analysis.finished_parent_symbols.contents[k];+ array_insert_sorted_by(&self->repeat_symbols_with_rootless_patterns, , symbol);+ }+ }++ #ifdef DEBUG_ANALYZE_QUERY+ if (self->repeat_symbols_with_rootless_patterns.size > 0) {+ printf("\nRepetition symbols with rootless patterns:\n");+ printf("aborted analysis: %d\n", analysis.did_abort);+ for (unsigned i = 0; i < self->repeat_symbols_with_rootless_patterns.size; i++) {+ TSSymbol symbol = self->repeat_symbols_with_rootless_patterns.contents[i];+ printf(" %u, %s\n", symbol, ts_language_symbol_name(self->language, symbol));+ }+ printf("\n");+ }+ #endif++ // Cleanup+ for (unsigned i = 0; i < subgraphs.size; i++) {+ array_delete(&subgraphs.contents[i].start_states);+ array_delete(&subgraphs.contents[i].nodes);+ }+ array_delete(&subgraphs);+ query_analysis__delete(&analysis);+ array_delete(&next_nodes);+ array_delete(&non_rooted_pattern_start_steps);+ array_delete(&parent_step_indices);+ array_delete(&predicate_capture_ids);+ state_predecessor_map_delete(&predecessor_map);++ return all_patterns_are_valid;+}++static void ts_query__add_negated_fields(+ TSQuery *self,+ uint16_t step_index,+ TSFieldId *field_ids,+ uint16_t field_count+) {+ QueryStep *step = &self->steps.contents[step_index];++ // The negated field array stores a list of field lists, separated by zeros.+ // Try to find the start index of an existing list that matches this new list.+ bool failed_match = false;+ unsigned match_count = 0;+ unsigned start_i = 0;+ for (unsigned i = 0; i < self->negated_fields.size; i++) {+ TSFieldId existing_field_id = self->negated_fields.contents[i];++ // At each zero value, terminate the match attempt. If we've exactly+ // matched the new field list, then reuse this index. Otherwise,+ // start over the matching process.+ if (existing_field_id == 0) {+ if (match_count == field_count) {+ step->negated_field_list_id = start_i;+ return;+ } else {+ start_i = i + 1;+ match_count = 0;+ failed_match = false;+ }+ }++ // If the existing list matches our new list so far, then advance+ // to the next element of the new list.+ else if (+ match_count < field_count &&+ existing_field_id == field_ids[match_count] &&+ !failed_match+ ) {+ match_count++;+ }++ // Otherwise, this existing list has failed to match.+ else {+ match_count = 0;+ failed_match = true;+ }+ }++ step->negated_field_list_id = self->negated_fields.size;+ array_extend(&self->negated_fields, field_count, field_ids);+ array_push(&self->negated_fields, 0);+}++static TSQueryError ts_query__parse_string_literal(+ TSQuery *self,+ Stream *stream+) {+ const char *string_start = stream->input;+ if (stream->next != '"') return TSQueryErrorSyntax;+ stream_advance(stream);+ const char *prev_position = stream->input;++ bool is_escaped = false;+ array_clear(&self->string_buffer);+ for (;;) {+ if (is_escaped) {+ is_escaped = false;+ switch (stream->next) {+ case 'n':+ array_push(&self->string_buffer, '\n');+ break;+ case 'r':+ array_push(&self->string_buffer, '\r');+ break;+ case 't':+ array_push(&self->string_buffer, '\t');+ break;+ case '0':+ array_push(&self->string_buffer, '\0');+ break;+ default:+ array_extend(&self->string_buffer, stream->next_size, stream->input);+ break;+ }+ prev_position = stream->input + stream->next_size;+ } else {+ if (stream->next == '\\') {+ array_extend(&self->string_buffer, (uint32_t)(stream->input - prev_position), prev_position);+ prev_position = stream->input + 1;+ is_escaped = true;+ } else if (stream->next == '"') {+ array_extend(&self->string_buffer, (uint32_t)(stream->input - prev_position), prev_position);+ stream_advance(stream);+ return TSQueryErrorNone;+ } else if (stream->next == '\n') {+ stream_reset(stream, string_start);+ return TSQueryErrorSyntax;+ }+ }+ if (!stream_advance(stream)) {+ stream_reset(stream, string_start);+ return TSQueryErrorSyntax;+ }+ }+}++// Parse a single predicate associated with a pattern, adding it to the+// query's internal `predicate_steps` array. Predicates are arbitrary+// S-expressions associated with a pattern which are meant to be handled at+// a higher level of abstraction, such as the Rust/JavaScript bindings. They+// can contain '@'-prefixed capture names, double-quoted strings, and bare+// symbols, which also represent strings.+static TSQueryError ts_query__parse_predicate(+ TSQuery *self,+ Stream *stream+) {+ if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;+ const char *predicate_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - predicate_name);+ uint16_t id = symbol_table_insert_name(+ &self->predicate_values,+ predicate_name,+ length+ );+ array_push(&self->predicate_steps, ((TSQueryPredicateStep) {+ .type = TSQueryPredicateStepTypeString,+ .value_id = id,+ }));+ stream_skip_whitespace(stream);++ for (;;) {+ if (stream->next == ')') {+ stream_advance(stream);+ stream_skip_whitespace(stream);+ array_push(&self->predicate_steps, ((TSQueryPredicateStep) {+ .type = TSQueryPredicateStepTypeDone,+ .value_id = 0,+ }));+ break;+ }++ // Parse an '@'-prefixed capture name+ else if (stream->next == '@') {+ stream_advance(stream);++ // Parse the capture name+ if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;+ const char *capture_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t capture_length = (uint32_t)(stream->input - capture_name);++ // Add the capture id to the first step of the pattern+ int capture_id = symbol_table_id_for_name(+ &self->captures,+ capture_name,+ capture_length+ );+ if (capture_id == -1) {+ stream_reset(stream, capture_name);+ return TSQueryErrorCapture;+ }++ array_push(&self->predicate_steps, ((TSQueryPredicateStep) {+ .type = TSQueryPredicateStepTypeCapture,+ .value_id = capture_id,+ }));+ }++ // Parse a string literal+ else if (stream->next == '"') {+ TSQueryError e = ts_query__parse_string_literal(self, stream);+ if (e) return e;+ uint16_t query_id = symbol_table_insert_name(+ &self->predicate_values,+ self->string_buffer.contents,+ self->string_buffer.size+ );+ array_push(&self->predicate_steps, ((TSQueryPredicateStep) {+ .type = TSQueryPredicateStepTypeString,+ .value_id = query_id,+ }));+ }++ // Parse a bare symbol+ else if (stream_is_ident_start(stream)) {+ const char *symbol_start = stream->input;+ stream_scan_identifier(stream);+ uint32_t symbol_length = (uint32_t)(stream->input - symbol_start);+ uint16_t query_id = symbol_table_insert_name(+ &self->predicate_values,+ symbol_start,+ symbol_length+ );+ array_push(&self->predicate_steps, ((TSQueryPredicateStep) {+ .type = TSQueryPredicateStepTypeString,+ .value_id = query_id,+ }));+ }++ else {+ return TSQueryErrorSyntax;+ }++ stream_skip_whitespace(stream);+ }++ return 0;+}++// Read one S-expression pattern from the stream, and incorporate it into+// the query's internal state machine representation. For nested patterns,+// this function calls itself recursively.+//+// The caller is responsible for passing in a dedicated CaptureQuantifiers.+// These should not be shared between different calls to ts_query__parse_pattern!+static TSQueryError ts_query__parse_pattern(+ TSQuery *self,+ Stream *stream,+ uint32_t depth,+ bool is_immediate,+ CaptureQuantifiers *capture_quantifiers+) {+ if (stream->next == 0) return TSQueryErrorSyntax;+ if (stream->next == ')' || stream->next == ']') return PARENT_DONE;++ const uint32_t starting_step_index = self->steps.size;++ // Store the byte offset of each step in the query.+ if (+ self->step_offsets.size == 0 ||+ array_back(&self->step_offsets)->step_index != starting_step_index+ ) {+ array_push(&self->step_offsets, ((StepOffset) {+ .step_index = starting_step_index,+ .byte_offset = stream_offset(stream),+ }));+ }++ // An open bracket is the start of an alternation.+ if (stream->next == '[') {+ stream_advance(stream);+ stream_skip_whitespace(stream);++ // Parse each branch, and add a placeholder step in between the branches.+ Array(uint32_t) branch_step_indices = array_new();+ CaptureQuantifiers branch_capture_quantifiers = capture_quantifiers_new();+ for (;;) {+ uint32_t start_index = self->steps.size;+ TSQueryError e = ts_query__parse_pattern(+ self,+ stream,+ depth,+ is_immediate,+ &branch_capture_quantifiers+ );++ if (e == PARENT_DONE) {+ if (stream->next == ']' && branch_step_indices.size > 0) {+ stream_advance(stream);+ break;+ }+ e = TSQueryErrorSyntax;+ }+ if (e) {+ capture_quantifiers_delete(&branch_capture_quantifiers);+ array_delete(&branch_step_indices);+ return e;+ }++ if (start_index == starting_step_index) {+ capture_quantifiers_replace(capture_quantifiers, &branch_capture_quantifiers);+ } else {+ capture_quantifiers_join_all(capture_quantifiers, &branch_capture_quantifiers);+ }++ array_push(&branch_step_indices, start_index);+ array_push(&self->steps, query_step__new(0, depth, false));+ capture_quantifiers_clear(&branch_capture_quantifiers);+ }+ (void)array_pop(&self->steps);++ // For all of the branches except for the last one, add the subsequent branch as an+ // alternative, and link the end of the branch to the current end of the steps.+ for (unsigned i = 0; i < branch_step_indices.size - 1; i++) {+ uint32_t step_index = branch_step_indices.contents[i];+ uint32_t next_step_index = branch_step_indices.contents[i + 1];+ QueryStep *start_step = &self->steps.contents[step_index];+ QueryStep *end_step = &self->steps.contents[next_step_index - 1];+ start_step->alternative_index = next_step_index;+ end_step->alternative_index = self->steps.size;+ end_step->is_dead_end = true;+ }++ capture_quantifiers_delete(&branch_capture_quantifiers);+ array_delete(&branch_step_indices);+ }++ // An open parenthesis can be the start of three possible constructs:+ // * A grouped sequence+ // * A predicate+ // * A named node+ else if (stream->next == '(') {+ stream_advance(stream);+ stream_skip_whitespace(stream);++ // If this parenthesis is followed by a node, then it represents a grouped sequence.+ if (stream->next == '(' || stream->next == '"' || stream->next == '[') {+ bool child_is_immediate = is_immediate;+ CaptureQuantifiers child_capture_quantifiers = capture_quantifiers_new();+ for (;;) {+ if (stream->next == '.') {+ child_is_immediate = true;+ stream_advance(stream);+ stream_skip_whitespace(stream);+ }+ TSQueryError e = ts_query__parse_pattern(+ self,+ stream,+ depth,+ child_is_immediate,+ &child_capture_quantifiers+ );+ if (e == PARENT_DONE) {+ if (stream->next == ')') {+ stream_advance(stream);+ break;+ }+ e = TSQueryErrorSyntax;+ }+ if (e) {+ capture_quantifiers_delete(&child_capture_quantifiers);+ return e;+ }++ capture_quantifiers_add_all(capture_quantifiers, &child_capture_quantifiers);+ capture_quantifiers_clear(&child_capture_quantifiers);+ child_is_immediate = false;+ }++ capture_quantifiers_delete(&child_capture_quantifiers);+ }++ // A dot/pound character indicates the start of a predicate.+ else if (stream->next == '.' || stream->next == '#') {+ stream_advance(stream);+ return ts_query__parse_predicate(self, stream);+ }++ // Otherwise, this parenthesis is the start of a named node.+ else {+ TSSymbol symbol;++ // Parse a normal node name+ if (stream_is_ident_start(stream)) {+ const char *node_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - node_name);++ // Parse the wildcard symbol+ if (length == 1 && node_name[0] == '_') {+ symbol = WILDCARD_SYMBOL;+ }++ else {+ symbol = ts_language_symbol_for_name(+ self->language,+ node_name,+ length,+ true+ );+ if (!symbol) {+ stream_reset(stream, node_name);+ return TSQueryErrorNodeType;+ }+ }+ } else {+ return TSQueryErrorSyntax;+ }++ // Add a step for the node.+ array_push(&self->steps, query_step__new(symbol, depth, is_immediate));+ QueryStep *step = array_back(&self->steps);+ if (ts_language_symbol_metadata(self->language, symbol).supertype) {+ step->supertype_symbol = step->symbol;+ step->symbol = WILDCARD_SYMBOL;+ }+ if (symbol == WILDCARD_SYMBOL) {+ step->is_named = true;+ }++ stream_skip_whitespace(stream);++ if (stream->next == '/') {+ stream_advance(stream);+ if (!stream_is_ident_start(stream)) {+ return TSQueryErrorSyntax;+ }++ const char *node_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - node_name);++ step->symbol = ts_language_symbol_for_name(+ self->language,+ node_name,+ length,+ true+ );+ if (!step->symbol) {+ stream_reset(stream, node_name);+ return TSQueryErrorNodeType;+ }++ stream_skip_whitespace(stream);+ }++ // Parse the child patterns+ bool child_is_immediate = false;+ uint16_t last_child_step_index = 0;+ uint16_t negated_field_count = 0;+ TSFieldId negated_field_ids[MAX_NEGATED_FIELD_COUNT];+ CaptureQuantifiers child_capture_quantifiers = capture_quantifiers_new();+ for (;;) {+ // Parse a negated field assertion+ if (stream->next == '!') {+ stream_advance(stream);+ stream_skip_whitespace(stream);+ if (!stream_is_ident_start(stream)) {+ capture_quantifiers_delete(&child_capture_quantifiers);+ return TSQueryErrorSyntax;+ }+ const char *field_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - field_name);+ stream_skip_whitespace(stream);++ TSFieldId field_id = ts_language_field_id_for_name(+ self->language,+ field_name,+ length+ );+ if (!field_id) {+ stream->input = field_name;+ capture_quantifiers_delete(&child_capture_quantifiers);+ return TSQueryErrorField;+ }++ // Keep the field ids sorted.+ if (negated_field_count < MAX_NEGATED_FIELD_COUNT) {+ negated_field_ids[negated_field_count] = field_id;+ negated_field_count++;+ }++ continue;+ }++ // Parse a sibling anchor+ if (stream->next == '.') {+ child_is_immediate = true;+ stream_advance(stream);+ stream_skip_whitespace(stream);+ }++ uint16_t step_index = self->steps.size;+ TSQueryError e = ts_query__parse_pattern(+ self,+ stream,+ depth + 1,+ child_is_immediate,+ &child_capture_quantifiers+ );+ if (e == PARENT_DONE) {+ if (stream->next == ')') {+ if (child_is_immediate) {+ if (last_child_step_index == 0) {+ capture_quantifiers_delete(&child_capture_quantifiers);+ return TSQueryErrorSyntax;+ }+ self->steps.contents[last_child_step_index].is_last_child = true;+ }++ if (negated_field_count) {+ ts_query__add_negated_fields(+ self,+ starting_step_index,+ negated_field_ids,+ negated_field_count+ );+ }++ stream_advance(stream);+ break;+ }+ e = TSQueryErrorSyntax;+ }+ if (e) {+ capture_quantifiers_delete(&child_capture_quantifiers);+ return e;+ }++ capture_quantifiers_add_all(capture_quantifiers, &child_capture_quantifiers);++ last_child_step_index = step_index;+ child_is_immediate = false;+ capture_quantifiers_clear(&child_capture_quantifiers);+ }+ capture_quantifiers_delete(&child_capture_quantifiers);+ }+ }++ // Parse a wildcard pattern+ else if (stream->next == '_') {+ stream_advance(stream);+ stream_skip_whitespace(stream);++ // Add a step that matches any kind of node+ array_push(&self->steps, query_step__new(WILDCARD_SYMBOL, depth, is_immediate));+ }++ // Parse a double-quoted anonymous leaf node expression+ else if (stream->next == '"') {+ const char *string_start = stream->input;+ TSQueryError e = ts_query__parse_string_literal(self, stream);+ if (e) return e;++ // Add a step for the node+ TSSymbol symbol = ts_language_symbol_for_name(+ self->language,+ self->string_buffer.contents,+ self->string_buffer.size,+ false+ );+ if (!symbol) {+ stream_reset(stream, string_start + 1);+ return TSQueryErrorNodeType;+ }+ array_push(&self->steps, query_step__new(symbol, depth, is_immediate));+ }++ // Parse a field-prefixed pattern+ else if (stream_is_ident_start(stream)) {+ // Parse the field name+ const char *field_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - field_name);+ stream_skip_whitespace(stream);++ if (stream->next != ':') {+ stream_reset(stream, field_name);+ return TSQueryErrorSyntax;+ }+ stream_advance(stream);+ stream_skip_whitespace(stream);++ // Parse the pattern+ CaptureQuantifiers field_capture_quantifiers = capture_quantifiers_new();+ TSQueryError e = ts_query__parse_pattern(+ self,+ stream,+ depth,+ is_immediate,+ &field_capture_quantifiers+ );+ if (e) {+ capture_quantifiers_delete(&field_capture_quantifiers);+ if (e == PARENT_DONE) e = TSQueryErrorSyntax;+ return e;+ }++ // Add the field name to the first step of the pattern+ TSFieldId field_id = ts_language_field_id_for_name(+ self->language,+ field_name,+ length+ );+ if (!field_id) {+ stream->input = field_name;+ return TSQueryErrorField;+ }++ uint32_t step_index = starting_step_index;+ QueryStep *step = &self->steps.contents[step_index];+ for (;;) {+ step->field = field_id;+ if (+ step->alternative_index != NONE &&+ step->alternative_index > step_index &&+ step->alternative_index < self->steps.size+ ) {+ step_index = step->alternative_index;+ step = &self->steps.contents[step_index];+ } else {+ break;+ }+ }++ capture_quantifiers_add_all(capture_quantifiers, &field_capture_quantifiers);+ capture_quantifiers_delete(&field_capture_quantifiers);+ }++ else {+ return TSQueryErrorSyntax;+ }++ stream_skip_whitespace(stream);++ // Parse suffixes modifiers for this pattern+ TSQuantifier quantifier = TSQuantifierOne;+ for (;;) {+ // Parse the one-or-more operator.+ if (stream->next == '+') {+ quantifier = quantifier_join(TSQuantifierOneOrMore, quantifier);++ stream_advance(stream);+ stream_skip_whitespace(stream);++ QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false);+ repeat_step.alternative_index = starting_step_index;+ repeat_step.is_pass_through = true;+ repeat_step.alternative_is_immediate = true;+ array_push(&self->steps, repeat_step);+ }++ // Parse the zero-or-more repetition operator.+ else if (stream->next == '*') {+ quantifier = quantifier_join(TSQuantifierZeroOrMore, quantifier);++ stream_advance(stream);+ stream_skip_whitespace(stream);++ QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false);+ repeat_step.alternative_index = starting_step_index;+ repeat_step.is_pass_through = true;+ repeat_step.alternative_is_immediate = true;+ array_push(&self->steps, repeat_step);++ // Stop when `step->alternative_index` is `NONE` or it points to+ // `repeat_step` or beyond. Note that having just been pushed,+ // `repeat_step` occupies slot `self->steps.size - 1`.+ QueryStep *step = &self->steps.contents[starting_step_index];+ while (step->alternative_index != NONE && step->alternative_index < self->steps.size - 1) {+ step = &self->steps.contents[step->alternative_index];+ }+ step->alternative_index = self->steps.size;+ }++ // Parse the optional operator.+ else if (stream->next == '?') {+ quantifier = quantifier_join(TSQuantifierZeroOrOne, quantifier);++ stream_advance(stream);+ stream_skip_whitespace(stream);++ QueryStep *step = &self->steps.contents[starting_step_index];+ while (step->alternative_index != NONE && step->alternative_index < self->steps.size) {+ step = &self->steps.contents[step->alternative_index];+ }+ step->alternative_index = self->steps.size;+ }++ // Parse an '@'-prefixed capture pattern+ else if (stream->next == '@') {+ stream_advance(stream);+ if (!stream_is_ident_start(stream)) return TSQueryErrorSyntax;+ const char *capture_name = stream->input;+ stream_scan_identifier(stream);+ uint32_t length = (uint32_t)(stream->input - capture_name);+ stream_skip_whitespace(stream);++ // Add the capture id to the first step of the pattern+ uint16_t capture_id = symbol_table_insert_name(+ &self->captures,+ capture_name,+ length+ );++ // Add the capture quantifier+ capture_quantifiers_add_for_id(capture_quantifiers, capture_id, TSQuantifierOne);++ uint32_t step_index = starting_step_index;+ for (;;) {+ QueryStep *step = &self->steps.contents[step_index];+ query_step__add_capture(step, capture_id);+ if (+ step->alternative_index != NONE &&+ step->alternative_index > step_index &&+ step->alternative_index < self->steps.size+ ) {+ step_index = step->alternative_index;+ } else {+ break;+ }+ }+ }++ // No more suffix modifiers+ else {+ break;+ }+ }++ capture_quantifiers_mul(capture_quantifiers, quantifier);++ return 0;+}++TSQuery *ts_query_new(+ const TSLanguage *language,+ const char *source,+ uint32_t source_len,+ uint32_t *error_offset,+ TSQueryError *error_type+) {+ if (+ !language ||+ language->version > TREE_SITTER_LANGUAGE_VERSION ||+ language->version < TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION+ ) {+ *error_type = TSQueryErrorLanguage;+ return NULL;+ }++ TSQuery *self = ts_malloc(sizeof(TSQuery));+ *self = (TSQuery) {+ .steps = array_new(),+ .pattern_map = array_new(),+ .captures = symbol_table_new(),+ .capture_quantifiers = array_new(),+ .predicate_values = symbol_table_new(),+ .predicate_steps = array_new(),+ .patterns = array_new(),+ .step_offsets = array_new(),+ .string_buffer = array_new(),+ .negated_fields = array_new(),+ .repeat_symbols_with_rootless_patterns = array_new(),+ .wildcard_root_pattern_count = 0,+ .language = ts_language_copy(language),+ };++ array_push(&self->negated_fields, 0);++ // Parse all of the S-expressions in the given string.+ Stream stream = stream_new(source, source_len);+ stream_skip_whitespace(&stream);+ while (stream.input < stream.end) {+ uint32_t pattern_index = self->patterns.size;+ uint32_t start_step_index = self->steps.size;+ uint32_t start_predicate_step_index = self->predicate_steps.size;+ array_push(&self->patterns, ((QueryPattern) {+ .steps = (Slice) {.offset = start_step_index},+ .predicate_steps = (Slice) {.offset = start_predicate_step_index},+ .start_byte = stream_offset(&stream),+ .is_non_local = false,+ }));+ CaptureQuantifiers capture_quantifiers = capture_quantifiers_new();+ *error_type = ts_query__parse_pattern(self, &stream, 0, false, &capture_quantifiers);+ array_push(&self->steps, query_step__new(0, PATTERN_DONE_MARKER, false));++ QueryPattern *pattern = array_back(&self->patterns);+ pattern->steps.length = self->steps.size - start_step_index;+ pattern->predicate_steps.length = self->predicate_steps.size - start_predicate_step_index;+ pattern->end_byte = stream_offset(&stream);++ // If any pattern could not be parsed, then report the error information+ // and terminate.+ if (*error_type) {+ if (*error_type == PARENT_DONE) *error_type = TSQueryErrorSyntax;+ *error_offset = stream_offset(&stream);+ capture_quantifiers_delete(&capture_quantifiers);+ ts_query_delete(self);+ return NULL;+ }++ // Maintain a list of capture quantifiers for each pattern+ array_push(&self->capture_quantifiers, capture_quantifiers);++ // Maintain a map that can look up patterns for a given root symbol.+ uint16_t wildcard_root_alternative_index = NONE;+ for (;;) {+ QueryStep *step = &self->steps.contents[start_step_index];++ // If a pattern has a wildcard at its root, but it has a non-wildcard child,+ // then optimize the matching process by skipping matching the wildcard.+ // Later, during the matching process, the query cursor will check that+ // there is a parent node, and capture it if necessary.+ if (step->symbol == WILDCARD_SYMBOL && step->depth == 0 && !step->field) {+ QueryStep *second_step = &self->steps.contents[start_step_index + 1];+ if (second_step->symbol != WILDCARD_SYMBOL && second_step->depth == 1 && !second_step->is_immediate) {+ wildcard_root_alternative_index = step->alternative_index;+ start_step_index += 1;+ step = second_step;+ }+ }++ // Determine whether the pattern has a single root node. This affects+ // decisions about whether or not to start matching the pattern when+ // a query cursor has a range restriction or when immediately within an+ // error node.+ uint32_t start_depth = step->depth;+ bool is_rooted = start_depth == 0;+ for (uint32_t step_index = start_step_index + 1; step_index < self->steps.size; step_index++) {+ QueryStep *child_step = &self->steps.contents[step_index];+ if (child_step->is_dead_end) break;+ if (child_step->depth == start_depth) {+ is_rooted = false;+ break;+ }+ }++ ts_query__pattern_map_insert(self, step->symbol, (PatternEntry) {+ .step_index = start_step_index,+ .pattern_index = pattern_index,+ .is_rooted = is_rooted+ });+ if (step->symbol == WILDCARD_SYMBOL) {+ self->wildcard_root_pattern_count++;+ }++ // If there are alternatives or options at the root of the pattern,+ // then add multiple entries to the pattern map.+ if (step->alternative_index != NONE) {+ start_step_index = step->alternative_index;+ } else if (wildcard_root_alternative_index != NONE) {+ start_step_index = wildcard_root_alternative_index;+ wildcard_root_alternative_index = NONE;+ } else {+ break;+ }+ }+ }++ if (!ts_query__analyze_patterns(self, error_offset)) {+ *error_type = TSQueryErrorStructure;+ ts_query_delete(self);+ return NULL;+ }++ array_delete(&self->string_buffer);+ return self;+}++void ts_query_delete(TSQuery *self) {+ if (self) {+ array_delete(&self->steps);+ array_delete(&self->pattern_map);+ array_delete(&self->predicate_steps);+ array_delete(&self->patterns);+ array_delete(&self->step_offsets);+ array_delete(&self->string_buffer);+ array_delete(&self->negated_fields);+ array_delete(&self->repeat_symbols_with_rootless_patterns);+ ts_language_delete(self->language);+ symbol_table_delete(&self->captures);+ symbol_table_delete(&self->predicate_values);+ for (uint32_t index = 0; index < self->capture_quantifiers.size; index++) {+ CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, index);+ capture_quantifiers_delete(capture_quantifiers);+ }+ array_delete(&self->capture_quantifiers);+ ts_free(self);+ }+}++uint32_t ts_query_pattern_count(const TSQuery *self) {+ return self->patterns.size;+}++uint32_t ts_query_capture_count(const TSQuery *self) {+ return self->captures.slices.size;+}++uint32_t ts_query_string_count(const TSQuery *self) {+ return self->predicate_values.slices.size;+}++const char *ts_query_capture_name_for_id(+ const TSQuery *self,+ uint32_t index,+ uint32_t *length+) {+ return symbol_table_name_for_id(&self->captures, index, length);+}++TSQuantifier ts_query_capture_quantifier_for_id(+ const TSQuery *self,+ uint32_t pattern_index,+ uint32_t capture_index+) {+ CaptureQuantifiers *capture_quantifiers = array_get(&self->capture_quantifiers, pattern_index);+ return capture_quantifier_for_id(capture_quantifiers, capture_index);+}++const char *ts_query_string_value_for_id(+ const TSQuery *self,+ uint32_t index,+ uint32_t *length+) {+ return symbol_table_name_for_id(&self->predicate_values, index, length);+}++const TSQueryPredicateStep *ts_query_predicates_for_pattern(+ const TSQuery *self,+ uint32_t pattern_index,+ uint32_t *step_count+) {+ Slice slice = self->patterns.contents[pattern_index].predicate_steps;+ *step_count = slice.length;+ if (self->predicate_steps.contents == NULL) {+ return NULL;+ }+ return &self->predicate_steps.contents[slice.offset];+}++uint32_t ts_query_start_byte_for_pattern(+ const TSQuery *self,+ uint32_t pattern_index+) {+ return self->patterns.contents[pattern_index].start_byte;+}++uint32_t ts_query_end_byte_for_pattern(+ const TSQuery *self,+ uint32_t pattern_index+) {+ return self->patterns.contents[pattern_index].end_byte;+}++bool ts_query_is_pattern_rooted(+ const TSQuery *self,+ uint32_t pattern_index+) {+ for (unsigned i = 0; i < self->pattern_map.size; i++) {+ PatternEntry *entry = &self->pattern_map.contents[i];+ if (entry->pattern_index == pattern_index) {+ if (!entry->is_rooted) return false;+ }+ }+ return true;+}++bool ts_query_is_pattern_non_local(+ const TSQuery *self,+ uint32_t pattern_index+) {+ if (pattern_index < self->patterns.size) {+ return self->patterns.contents[pattern_index].is_non_local;+ } else {+ return false;+ }+}++bool ts_query_is_pattern_guaranteed_at_step(+ const TSQuery *self,+ uint32_t byte_offset+) {+ uint32_t step_index = UINT32_MAX;+ for (unsigned i = 0; i < self->step_offsets.size; i++) {+ StepOffset *step_offset = &self->step_offsets.contents[i];+ if (step_offset->byte_offset > byte_offset) break;+ step_index = step_offset->step_index;+ }+ if (step_index < self->steps.size) {+ return self->steps.contents[step_index].root_pattern_guaranteed;+ } else {+ return false;+ }+}++bool ts_query__step_is_fallible(+ const TSQuery *self,+ uint16_t step_index+) {+ ts_assert((uint32_t)step_index + 1 < self->steps.size);+ QueryStep *step = &self->steps.contents[step_index];+ QueryStep *next_step = &self->steps.contents[step_index + 1];+ return (+ next_step->depth != PATTERN_DONE_MARKER &&+ next_step->depth > step->depth &&+ !next_step->parent_pattern_guaranteed+ );+}++void ts_query_disable_capture(+ TSQuery *self,+ const char *name,+ uint32_t length+) {+ // Remove capture information for any pattern step that previously+ // captured with the given name.+ int id = symbol_table_id_for_name(&self->captures, name, length);+ if (id != -1) {+ for (unsigned i = 0; i < self->steps.size; i++) {+ QueryStep *step = &self->steps.contents[i];+ query_step__remove_capture(step, id);+ }+ }+}++void ts_query_disable_pattern(+ TSQuery *self,+ uint32_t pattern_index+) {+ // Remove the given pattern from the pattern map. Its steps will still+ // be in the `steps` array, but they will never be read.+ for (unsigned i = 0; i < self->pattern_map.size; i++) {+ PatternEntry *pattern = &self->pattern_map.contents[i];+ if (pattern->pattern_index == pattern_index) {+ array_erase(&self->pattern_map, i);+ i--;+ }+ }+}++/***************+ * QueryCursor+ ***************/++TSQueryCursor *ts_query_cursor_new(void) {+ TSQueryCursor *self = ts_malloc(sizeof(TSQueryCursor));+ *self = (TSQueryCursor) {+ .did_exceed_match_limit = false,+ .ascending = false,+ .halted = false,+ .states = array_new(),+ .finished_states = array_new(),+ .capture_list_pool = capture_list_pool_new(),+ .start_byte = 0,+ .end_byte = UINT32_MAX,+ .start_point = {0, 0},+ .end_point = POINT_MAX,+ .max_start_depth = UINT32_MAX,+ .timeout_duration = 0,+ .end_clock = clock_null(),+ .operation_count = 0,+ };+ array_reserve(&self->states, 8);+ array_reserve(&self->finished_states, 8);+ return self;+}++void ts_query_cursor_delete(TSQueryCursor *self) {+ array_delete(&self->states);+ array_delete(&self->finished_states);+ ts_tree_cursor_delete(&self->cursor);+ capture_list_pool_delete(&self->capture_list_pool);+ ts_free(self);+}++bool ts_query_cursor_did_exceed_match_limit(const TSQueryCursor *self) {+ return self->did_exceed_match_limit;+}++uint32_t ts_query_cursor_match_limit(const TSQueryCursor *self) {+ return self->capture_list_pool.max_capture_list_count;+}++void ts_query_cursor_set_match_limit(TSQueryCursor *self, uint32_t limit) {+ self->capture_list_pool.max_capture_list_count = limit;+}++uint64_t ts_query_cursor_timeout_micros(const TSQueryCursor *self) {+ return duration_to_micros(self->timeout_duration);+}++void ts_query_cursor_set_timeout_micros(TSQueryCursor *self, uint64_t timeout_micros) {+ self->timeout_duration = duration_from_micros(timeout_micros);+}++#ifdef DEBUG_EXECUTE_QUERY+#define LOG(...) fprintf(stderr, __VA_ARGS__)+#else+#define LOG(...)+#endif++void ts_query_cursor_exec(+ TSQueryCursor *self,+ const TSQuery *query,+ TSNode node+) {+ if (query) {+ LOG("query steps:\n");+ for (unsigned i = 0; i < query->steps.size; i++) {+ QueryStep *step = &query->steps.contents[i];+ LOG(" %u: {", i);+ if (step->depth == PATTERN_DONE_MARKER) {+ LOG("DONE");+ } else if (step->is_dead_end) {+ LOG("dead_end");+ } else if (step->is_pass_through) {+ LOG("pass_through");+ } else if (step->symbol != WILDCARD_SYMBOL) {+ LOG("symbol: %s", query->language->symbol_names[step->symbol]);+ } else {+ LOG("symbol: *");+ }+ if (step->field) {+ LOG(", field: %s", query->language->field_names[step->field]);+ }+ if (step->alternative_index != NONE) {+ LOG(", alternative: %u", step->alternative_index);+ }+ LOG("},\n");+ }+ }++ array_clear(&self->states);+ array_clear(&self->finished_states);+ ts_tree_cursor_reset(&self->cursor, node);+ capture_list_pool_reset(&self->capture_list_pool);+ self->on_visible_node = true;+ self->next_state_id = 0;+ self->depth = 0;+ self->ascending = false;+ self->halted = false;+ self->query = query;+ self->did_exceed_match_limit = false;+ self->operation_count = 0;+ if (self->timeout_duration) {+ self->end_clock = clock_after(clock_now(), self->timeout_duration);+ } else {+ self->end_clock = clock_null();+ }+}++void ts_query_cursor_set_byte_range(+ TSQueryCursor *self,+ uint32_t start_byte,+ uint32_t end_byte+) {+ if (end_byte == 0) {+ end_byte = UINT32_MAX;+ }+ self->start_byte = start_byte;+ self->end_byte = end_byte;+}++void ts_query_cursor_set_point_range(+ TSQueryCursor *self,+ TSPoint start_point,+ TSPoint end_point+) {+ if (end_point.row == 0 && end_point.column == 0) {+ end_point = POINT_MAX;+ }+ self->start_point = start_point;+ self->end_point = end_point;+}++// Search through all of the in-progress states, and find the captured+// node that occurs earliest in the document.+static bool ts_query_cursor__first_in_progress_capture(+ TSQueryCursor *self,+ uint32_t *state_index,+ uint32_t *byte_offset,+ uint32_t *pattern_index,+ bool *root_pattern_guaranteed+) {+ bool result = false;+ *state_index = UINT32_MAX;+ *byte_offset = UINT32_MAX;+ *pattern_index = UINT32_MAX;+ for (unsigned i = 0; i < self->states.size; i++) {+ QueryState *state = &self->states.contents[i];+ if (state->dead) continue;++ const CaptureList *captures = capture_list_pool_get(+ &self->capture_list_pool,+ state->capture_list_id+ );+ if (state->consumed_capture_count >= captures->size) {+ continue;+ }++ TSNode node = captures->contents[state->consumed_capture_count].node;+ if (+ ts_node_end_byte(node) <= self->start_byte ||+ point_lte(ts_node_end_point(node), self->start_point)+ ) {+ state->consumed_capture_count++;+ i--;+ continue;+ }++ uint32_t node_start_byte = ts_node_start_byte(node);+ if (+ !result ||+ node_start_byte < *byte_offset ||+ (node_start_byte == *byte_offset && state->pattern_index < *pattern_index)+ ) {+ QueryStep *step = &self->query->steps.contents[state->step_index];+ if (root_pattern_guaranteed) {+ *root_pattern_guaranteed = step->root_pattern_guaranteed;+ } else if (step->root_pattern_guaranteed) {+ continue;+ }++ result = true;+ *state_index = i;+ *byte_offset = node_start_byte;+ *pattern_index = state->pattern_index;+ }+ }+ return result;+}++// Determine which node is first in a depth-first traversal+int ts_query_cursor__compare_nodes(TSNode left, TSNode right) {+ if (left.id != right.id) {+ uint32_t left_start = ts_node_start_byte(left);+ uint32_t right_start = ts_node_start_byte(right);+ if (left_start < right_start) return -1;+ if (left_start > right_start) return 1;+ uint32_t left_node_count = ts_node_end_byte(left);+ uint32_t right_node_count = ts_node_end_byte(right);+ if (left_node_count > right_node_count) return -1;+ if (left_node_count < right_node_count) return 1;+ }+ return 0;+}++// Determine if either state contains a superset of the other state's captures.+void ts_query_cursor__compare_captures(+ TSQueryCursor *self,+ QueryState *left_state,+ QueryState *right_state,+ bool *left_contains_right,+ bool *right_contains_left+) {+ const CaptureList *left_captures = capture_list_pool_get(+ &self->capture_list_pool,+ left_state->capture_list_id+ );+ const CaptureList *right_captures = capture_list_pool_get(+ &self->capture_list_pool,+ right_state->capture_list_id+ );+ *left_contains_right = true;+ *right_contains_left = true;+ unsigned i = 0, j = 0;+ for (;;) {+ if (i < left_captures->size) {+ if (j < right_captures->size) {+ TSQueryCapture *left = &left_captures->contents[i];+ TSQueryCapture *right = &right_captures->contents[j];+ if (left->node.id == right->node.id && left->index == right->index) {+ i++;+ j++;+ } else {+ switch (ts_query_cursor__compare_nodes(left->node, right->node)) {+ case -1:+ *right_contains_left = false;+ i++;+ break;+ case 1:+ *left_contains_right = false;+ j++;+ break;+ default:+ *right_contains_left = false;+ *left_contains_right = false;+ i++;+ j++;+ break;+ }+ }+ } else {+ *right_contains_left = false;+ break;+ }+ } else {+ if (j < right_captures->size) {+ *left_contains_right = false;+ }+ break;+ }+ }+}++static void ts_query_cursor__add_state(+ TSQueryCursor *self,+ const PatternEntry *pattern+) {+ QueryStep *step = &self->query->steps.contents[pattern->step_index];+ uint32_t start_depth = self->depth - step->depth;++ // Keep the states array in ascending order of start_depth and pattern_index,+ // so that it can be processed more efficiently elsewhere. Usually, there is+ // no work to do here because of two facts:+ // * States with lower start_depth are naturally added first due to the+ // order in which nodes are visited.+ // * Earlier patterns are naturally added first because of the ordering of the+ // pattern_map data structure that's used to initiate matches.+ //+ // This loop is only needed in cases where two conditions hold:+ // * A pattern consists of more than one sibling node, so that its states+ // remain in progress after exiting the node that started the match.+ // * The first node in the pattern matches against multiple nodes at the+ // same depth.+ //+ // An example of this is the pattern '((comment)* (function))'. If multiple+ // `comment` nodes appear in a row, then we may initiate a new state for this+ // pattern while another state for the same pattern is already in progress.+ // If there are multiple patterns like this in a query, then this loop will+ // need to execute in order to keep the states ordered by pattern_index.+ uint32_t index = self->states.size;+ while (index > 0) {+ QueryState *prev_state = &self->states.contents[index - 1];+ if (prev_state->start_depth < start_depth) break;+ if (prev_state->start_depth == start_depth) {+ // Avoid inserting an unnecessary duplicate state, which would be+ // immediately pruned by the longest-match criteria.+ if (+ prev_state->pattern_index == pattern->pattern_index &&+ prev_state->step_index == pattern->step_index+ ) return;+ if (prev_state->pattern_index <= pattern->pattern_index) break;+ }+ index--;+ }++ LOG(+ " start state. pattern:%u, step:%u\n",+ pattern->pattern_index,+ pattern->step_index+ );+ array_insert(&self->states, index, ((QueryState) {+ .id = UINT32_MAX,+ .capture_list_id = NONE,+ .step_index = pattern->step_index,+ .pattern_index = pattern->pattern_index,+ .start_depth = start_depth,+ .consumed_capture_count = 0,+ .seeking_immediate_match = true,+ .has_in_progress_alternatives = false,+ .needs_parent = step->depth == 1,+ .dead = false,+ }));+}++// Acquire a capture list for this state. If there are no capture lists left in the+// pool, this will steal the capture list from another existing state, and mark that+// other state as 'dead'.+static CaptureList *ts_query_cursor__prepare_to_capture(+ TSQueryCursor *self,+ QueryState *state,+ unsigned state_index_to_preserve+) {+ if (state->capture_list_id == NONE) {+ state->capture_list_id = capture_list_pool_acquire(&self->capture_list_pool);++ // If there are no capture lists left in the pool, then terminate whichever+ // state has captured the earliest node in the document, and steal its+ // capture list.+ if (state->capture_list_id == NONE) {+ self->did_exceed_match_limit = true;+ uint32_t state_index, byte_offset, pattern_index;+ if (+ ts_query_cursor__first_in_progress_capture(+ self,+ &state_index,+ &byte_offset,+ &pattern_index,+ NULL+ ) &&+ state_index != state_index_to_preserve+ ) {+ LOG(+ " abandon state. index:%u, pattern:%u, offset:%u.\n",+ state_index, pattern_index, byte_offset+ );+ QueryState *other_state = &self->states.contents[state_index];+ state->capture_list_id = other_state->capture_list_id;+ other_state->capture_list_id = NONE;+ other_state->dead = true;+ CaptureList *list = capture_list_pool_get_mut(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_clear(list);+ return list;+ } else {+ LOG(" ran out of capture lists");+ return NULL;+ }+ }+ }+ return capture_list_pool_get_mut(&self->capture_list_pool, state->capture_list_id);+}++static void ts_query_cursor__capture(+ TSQueryCursor *self,+ QueryState *state,+ QueryStep *step,+ TSNode node+) {+ if (state->dead) return;+ CaptureList *capture_list = ts_query_cursor__prepare_to_capture(self, state, UINT32_MAX);+ if (!capture_list) {+ state->dead = true;+ return;+ }++ for (unsigned j = 0; j < MAX_STEP_CAPTURE_COUNT; j++) {+ uint16_t capture_id = step->capture_ids[j];+ if (step->capture_ids[j] == NONE) break;+ array_push(capture_list, ((TSQueryCapture) { node, capture_id }));+ LOG(+ " capture node. type:%s, pattern:%u, capture_id:%u, capture_count:%u\n",+ ts_node_type(node),+ state->pattern_index,+ capture_id,+ capture_list->size+ );+ }+}++// Duplicate the given state and insert the newly-created state immediately after+// the given state in the `states` array. Ensures that the given state reference is+// still valid, even if the states array is reallocated.+static QueryState *ts_query_cursor__copy_state(+ TSQueryCursor *self,+ QueryState **state_ref+) {+ const QueryState *state = *state_ref;+ uint32_t state_index = (uint32_t)(state - self->states.contents);+ QueryState copy = *state;+ copy.capture_list_id = NONE;++ // If the state has captures, copy its capture list.+ if (state->capture_list_id != NONE) {+ CaptureList *new_captures = ts_query_cursor__prepare_to_capture(self, ©, state_index);+ if (!new_captures) return NULL;+ const CaptureList *old_captures = capture_list_pool_get(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_push_all(new_captures, old_captures);+ }++ array_insert(&self->states, state_index + 1, copy);+ *state_ref = &self->states.contents[state_index];+ return &self->states.contents[state_index + 1];+}++static inline bool ts_query_cursor__should_descend(+ TSQueryCursor *self,+ bool node_intersects_range+) {++ if (node_intersects_range && self->depth < self->max_start_depth) {+ return true;+ }++ // If there are in-progress matches whose remaining steps occur+ // deeper in the tree, then descend.+ for (unsigned i = 0; i < self->states.size; i++) {+ QueryState *state = &self->states.contents[i];;+ QueryStep *next_step = &self->query->steps.contents[state->step_index];+ if (+ next_step->depth != PATTERN_DONE_MARKER &&+ state->start_depth + next_step->depth > self->depth+ ) {+ return true;+ }+ }++ if (self->depth >= self->max_start_depth) {+ return false;+ }++ // If the current node is hidden, then a non-rooted pattern might match+ // one if its roots inside of this node, and match another of its roots+ // as part of a sibling node, so we may need to descend.+ if (!self->on_visible_node) {+ // Descending into a repetition node outside of the range can be+ // expensive, because these nodes can have many visible children.+ // Avoid descending into repetition nodes unless we have already+ // determined that this query can match rootless patterns inside+ // of this type of repetition node.+ Subtree subtree = ts_tree_cursor_current_subtree(&self->cursor);+ if (ts_subtree_is_repetition(subtree)) {+ bool exists;+ uint32_t index;+ array_search_sorted_by(+ &self->query->repeat_symbols_with_rootless_patterns,,+ ts_subtree_symbol(subtree),+ &index,+ &exists+ );+ return exists;+ }++ return true;+ }++ return false;+}++// Walk the tree, processing patterns until at least one pattern finishes,+// If one or more patterns finish, return `true` and store their states in the+// `finished_states` array. Multiple patterns can finish on the same node. If+// there are no more matches, return `false`.+static inline bool ts_query_cursor__advance(+ TSQueryCursor *self,+ bool stop_on_definite_step+) {+ bool did_match = false;+ for (;;) {+ if (self->halted) {+ while (self->states.size > 0) {+ QueryState state = array_pop(&self->states);+ capture_list_pool_release(+ &self->capture_list_pool,+ state.capture_list_id+ );+ }+ }++ if (++self->operation_count == OP_COUNT_PER_QUERY_TIMEOUT_CHECK) {+ self->operation_count = 0;+ }+ if (+ did_match ||+ self->halted ||+ (+ self->operation_count == 0 &&+ !clock_is_null(self->end_clock) && clock_is_gt(clock_now(), self->end_clock)+ )+ ) {+ return did_match;+ }++ // Exit the current node.+ if (self->ascending) {+ if (self->on_visible_node) {+ LOG(+ "leave node. depth:%u, type:%s\n",+ self->depth,+ ts_node_type(ts_tree_cursor_current_node(&self->cursor))+ );++ // After leaving a node, remove any states that cannot make further progress.+ uint32_t deleted_count = 0;+ for (unsigned i = 0, n = self->states.size; i < n; i++) {+ QueryState *state = &self->states.contents[i];+ QueryStep *step = &self->query->steps.contents[state->step_index];++ // If a state completed its pattern inside of this node, but was deferred from finishing+ // in order to search for longer matches, mark it as finished.+ if (+ step->depth == PATTERN_DONE_MARKER &&+ (state->start_depth > self->depth || self->depth == 0)+ ) {+ LOG(" finish pattern %u\n", state->pattern_index);+ array_push(&self->finished_states, *state);+ did_match = true;+ deleted_count++;+ }++ // If a state needed to match something within this node, then remove that state+ // as it has failed to match.+ else if (+ step->depth != PATTERN_DONE_MARKER &&+ (uint32_t)state->start_depth + (uint32_t)step->depth > self->depth+ ) {+ LOG(+ " failed to match. pattern:%u, step:%u\n",+ state->pattern_index,+ state->step_index+ );+ capture_list_pool_release(+ &self->capture_list_pool,+ state->capture_list_id+ );+ deleted_count++;+ }++ else if (deleted_count > 0) {+ self->states.contents[i - deleted_count] = *state;+ }+ }+ self->states.size -= deleted_count;+ }++ // Leave this node by stepping to its next sibling or to its parent.+ switch (ts_tree_cursor_goto_next_sibling_internal(&self->cursor)) {+ case TreeCursorStepVisible:+ if (!self->on_visible_node) {+ self->depth++;+ self->on_visible_node = true;+ }+ self->ascending = false;+ break;+ case TreeCursorStepHidden:+ if (self->on_visible_node) {+ self->depth--;+ self->on_visible_node = false;+ }+ self->ascending = false;+ break;+ default:+ if (ts_tree_cursor_goto_parent(&self->cursor)) {+ self->depth--;+ } else {+ LOG("halt at root\n");+ self->halted = true;+ }+ }+ }++ // Enter a new node.+ else {+ // Get the properties of the current node.+ TSNode node = ts_tree_cursor_current_node(&self->cursor);+ TSNode parent_node = ts_tree_cursor_parent_node(&self->cursor);++ uint32_t start_byte = ts_node_start_byte(node);+ uint32_t end_byte = ts_node_end_byte(node);+ TSPoint start_point = ts_node_start_point(node);+ TSPoint end_point = ts_node_end_point(node);+ bool is_empty = start_byte == end_byte;++ bool parent_precedes_range = !ts_node_is_null(parent_node) && (+ ts_node_end_byte(parent_node) <= self->start_byte ||+ point_lte(ts_node_end_point(parent_node), self->start_point)+ );+ bool parent_follows_range = !ts_node_is_null(parent_node) && (+ ts_node_start_byte(parent_node) >= self->end_byte ||+ point_gte(ts_node_start_point(parent_node), self->end_point)+ );+ bool node_precedes_range =+ parent_precedes_range ||+ end_byte < self->start_byte ||+ point_lt(end_point, self->start_point) ||+ (!is_empty && end_byte == self->start_byte) ||+ (!is_empty && point_eq(end_point, self->start_point));++ bool node_follows_range = parent_follows_range || (+ start_byte >= self->end_byte ||+ point_gte(start_point, self->end_point)+ );+ bool parent_intersects_range = !parent_precedes_range && !parent_follows_range;+ bool node_intersects_range = !node_precedes_range && !node_follows_range;++ if (self->on_visible_node) {+ TSSymbol symbol = ts_node_symbol(node);+ bool is_named = ts_node_is_named(node);+ bool has_later_siblings;+ bool has_later_named_siblings;+ bool can_have_later_siblings_with_this_field;+ TSFieldId field_id = 0;+ TSSymbol supertypes[8] = {0};+ unsigned supertype_count = 8;+ ts_tree_cursor_current_status(+ &self->cursor,+ &field_id,+ &has_later_siblings,+ &has_later_named_siblings,+ &can_have_later_siblings_with_this_field,+ supertypes,+ &supertype_count+ );+ LOG(+ "enter node. depth:%u, type:%s, field:%s, row:%u state_count:%u, finished_state_count:%u\n",+ self->depth,+ ts_node_type(node),+ ts_language_field_name_for_id(self->query->language, field_id),+ ts_node_start_point(node).row,+ self->states.size,+ self->finished_states.size+ );++ bool node_is_error = symbol == ts_builtin_sym_error;+ bool parent_is_error =+ !ts_node_is_null(parent_node) &&+ ts_node_symbol(parent_node) == ts_builtin_sym_error;++ // Add new states for any patterns whose root node is a wildcard.+ if (!node_is_error) {+ for (unsigned i = 0; i < self->query->wildcard_root_pattern_count; i++) {+ PatternEntry *pattern = &self->query->pattern_map.contents[i];++ // If this node matches the first step of the pattern, then add a new+ // state at the start of this pattern.+ QueryStep *step = &self->query->steps.contents[pattern->step_index];+ uint32_t start_depth = self->depth - step->depth;+ if (+ (pattern->is_rooted ?+ node_intersects_range :+ (parent_intersects_range && !parent_is_error)) &&+ (!step->field || field_id == step->field) &&+ (!step->supertype_symbol || supertype_count > 0) &&+ (start_depth <= self->max_start_depth)+ ) {+ ts_query_cursor__add_state(self, pattern);+ }+ }+ }++ // Add new states for any patterns whose root node matches this node.+ unsigned i;+ if (ts_query__pattern_map_search(self->query, symbol, &i)) {+ PatternEntry *pattern = &self->query->pattern_map.contents[i];++ QueryStep *step = &self->query->steps.contents[pattern->step_index];+ uint32_t start_depth = self->depth - step->depth;+ do {+ // If this node matches the first step of the pattern, then add a new+ // state at the start of this pattern.+ if (+ (pattern->is_rooted ?+ node_intersects_range :+ (parent_intersects_range && !parent_is_error)) &&+ (!step->field || field_id == step->field) &&+ (start_depth <= self->max_start_depth)+ ) {+ ts_query_cursor__add_state(self, pattern);+ }++ // Advance to the next pattern whose root node matches this node.+ i++;+ if (i == self->query->pattern_map.size) break;+ pattern = &self->query->pattern_map.contents[i];+ step = &self->query->steps.contents[pattern->step_index];+ } while (step->symbol == symbol);+ }++ // Update all of the in-progress states with current node.+ for (unsigned j = 0, copy_count = 0; j < self->states.size; j += 1 + copy_count) {+ QueryState *state = &self->states.contents[j];+ QueryStep *step = &self->query->steps.contents[state->step_index];+ state->has_in_progress_alternatives = false;+ copy_count = 0;++ // Check that the node matches all of the criteria for the next+ // step of the pattern.+ if ((uint32_t)state->start_depth + (uint32_t)step->depth != self->depth) continue;++ // Determine if this node matches this step of the pattern, and also+ // if this node can have later siblings that match this step of the+ // pattern.+ bool node_does_match = false;+ if (step->symbol == WILDCARD_SYMBOL) {+ node_does_match = !node_is_error && (is_named || !step->is_named);+ } else {+ node_does_match = symbol == step->symbol;+ }+ bool later_sibling_can_match = has_later_siblings;+ if ((step->is_immediate && is_named) || state->seeking_immediate_match) {+ later_sibling_can_match = false;+ }+ if (step->is_last_child && has_later_named_siblings) {+ node_does_match = false;+ }+ if (step->supertype_symbol) {+ bool has_supertype = false;+ for (unsigned k = 0; k < supertype_count; k++) {+ if (supertypes[k] == step->supertype_symbol) {+ has_supertype = true;+ break;+ }+ }+ if (!has_supertype) node_does_match = false;+ }+ if (step->field) {+ if (step->field == field_id) {+ if (!can_have_later_siblings_with_this_field) {+ later_sibling_can_match = false;+ }+ } else {+ node_does_match = false;+ }+ }++ if (step->negated_field_list_id) {+ TSFieldId *negated_field_ids = &self->query->negated_fields.contents[step->negated_field_list_id];+ for (;;) {+ TSFieldId negated_field_id = *negated_field_ids;+ if (negated_field_id) {+ negated_field_ids++;+ if (ts_node_child_by_field_id(node, negated_field_id).id) {+ node_does_match = false;+ break;+ }+ } else {+ break;+ }+ }+ }++ // Remove states immediately if it is ever clear that they cannot match.+ if (!node_does_match) {+ if (!later_sibling_can_match) {+ LOG(+ " discard state. pattern:%u, step:%u\n",+ state->pattern_index,+ state->step_index+ );+ capture_list_pool_release(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_erase(&self->states, j);+ j--;+ }+ continue;+ }++ // Some patterns can match their root node in multiple ways, capturing different+ // children. If this pattern step could match later children within the same+ // parent, then this query state cannot simply be updated in place. It must be+ // split into two states: one that matches this node, and one which skips over+ // this node, to preserve the possibility of matching later siblings.+ if (later_sibling_can_match && (+ step->contains_captures ||+ ts_query__step_is_fallible(self->query, state->step_index)+ )) {+ if (ts_query_cursor__copy_state(self, &state)) {+ LOG(+ " split state for capture. pattern:%u, step:%u\n",+ state->pattern_index,+ state->step_index+ );+ copy_count++;+ }+ }++ // If this pattern started with a wildcard, such that the pattern map+ // actually points to the *second* step of the pattern, then check+ // that the node has a parent, and capture the parent node if necessary.+ if (state->needs_parent) {+ TSNode parent = ts_tree_cursor_parent_node(&self->cursor);+ if (ts_node_is_null(parent)) {+ LOG(" missing parent node\n");+ state->dead = true;+ } else {+ state->needs_parent = false;+ QueryStep *skipped_wildcard_step = step;+ do {+ skipped_wildcard_step--;+ } while (+ skipped_wildcard_step->is_dead_end ||+ skipped_wildcard_step->is_pass_through ||+ skipped_wildcard_step->depth > 0+ );+ if (skipped_wildcard_step->capture_ids[0] != NONE) {+ LOG(" capture wildcard parent\n");+ ts_query_cursor__capture(+ self,+ state,+ skipped_wildcard_step,+ parent+ );+ }+ }+ }++ // If the current node is captured in this pattern, add it to the capture list.+ if (step->capture_ids[0] != NONE) {+ ts_query_cursor__capture(self, state, step, node);+ }++ if (state->dead) {+ array_erase(&self->states, j);+ j--;+ continue;+ }++ // Advance this state to the next step of its pattern.+ state->step_index++;+ state->seeking_immediate_match = false;+ LOG(+ " advance state. pattern:%u, step:%u\n",+ state->pattern_index,+ state->step_index+ );++ QueryStep *next_step = &self->query->steps.contents[state->step_index];+ if (stop_on_definite_step && next_step->root_pattern_guaranteed) did_match = true;++ // If this state's next step has an alternative step, then copy the state in order+ // to pursue both alternatives. The alternative step itself may have an alternative,+ // so this is an interactive process.+ unsigned end_index = j + 1;+ for (unsigned k = j; k < end_index; k++) {+ QueryState *child_state = &self->states.contents[k];+ QueryStep *child_step = &self->query->steps.contents[child_state->step_index];+ if (child_step->alternative_index != NONE) {+ // A "dead-end" step exists only to add a non-sequential jump into the step sequence,+ // via its alternative index. When a state reaches a dead-end step, it jumps straight+ // to the step's alternative.+ if (child_step->is_dead_end) {+ child_state->step_index = child_step->alternative_index;+ k--;+ continue;+ }++ // A "pass-through" step exists only to add a branch into the step sequence,+ // via its alternative_index. When a state reaches a pass-through step, it splits+ // in order to process the alternative step, and then it advances to the next step.+ if (child_step->is_pass_through) {+ child_state->step_index++;+ k--;+ }++ QueryState *copy = ts_query_cursor__copy_state(self, &child_state);+ if (copy) {+ LOG(+ " split state for branch. pattern:%u, from_step:%u, to_step:%u, immediate:%d, capture_count: %u\n",+ copy->pattern_index,+ copy->step_index,+ next_step->alternative_index,+ next_step->alternative_is_immediate,+ capture_list_pool_get(&self->capture_list_pool, copy->capture_list_id)->size+ );+ end_index++;+ copy_count++;+ copy->step_index = child_step->alternative_index;+ if (child_step->alternative_is_immediate) {+ copy->seeking_immediate_match = true;+ }+ }+ }+ }+ }++ for (unsigned j = 0; j < self->states.size; j++) {+ QueryState *state = &self->states.contents[j];+ if (state->dead) {+ array_erase(&self->states, j);+ j--;+ continue;+ }++ // Enforce the longest-match criteria. When a query pattern contains optional or+ // repeated nodes, this is necessary to avoid multiple redundant states, where+ // one state has a strict subset of another state's captures.+ bool did_remove = false;+ for (unsigned k = j + 1; k < self->states.size; k++) {+ QueryState *other_state = &self->states.contents[k];++ // Query states are kept in ascending order of start_depth and pattern_index.+ // Since the longest-match criteria is only used for deduping matches of the same+ // pattern and root node, we only need to perform pairwise comparisons within a+ // small slice of the states array.+ if (+ other_state->start_depth != state->start_depth ||+ other_state->pattern_index != state->pattern_index+ ) break;++ bool left_contains_right, right_contains_left;+ ts_query_cursor__compare_captures(+ self,+ state,+ other_state,+ &left_contains_right,+ &right_contains_left+ );+ if (left_contains_right) {+ if (state->step_index == other_state->step_index) {+ LOG(+ " drop shorter state. pattern: %u, step_index: %u\n",+ state->pattern_index,+ state->step_index+ );+ capture_list_pool_release(&self->capture_list_pool, other_state->capture_list_id);+ array_erase(&self->states, k);+ k--;+ continue;+ }+ other_state->has_in_progress_alternatives = true;+ }+ if (right_contains_left) {+ if (state->step_index == other_state->step_index) {+ LOG(+ " drop shorter state. pattern: %u, step_index: %u\n",+ state->pattern_index,+ state->step_index+ );+ capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);+ array_erase(&self->states, j);+ j--;+ did_remove = true;+ break;+ }+ state->has_in_progress_alternatives = true;+ }+ }++ // If the state is at the end of its pattern, remove it from the list+ // of in-progress states and add it to the list of finished states.+ if (!did_remove) {+ LOG(+ " keep state. pattern: %u, start_depth: %u, step_index: %u, capture_count: %u\n",+ state->pattern_index,+ state->start_depth,+ state->step_index,+ capture_list_pool_get(&self->capture_list_pool, state->capture_list_id)->size+ );+ QueryStep *next_step = &self->query->steps.contents[state->step_index];+ if (next_step->depth == PATTERN_DONE_MARKER) {+ if (state->has_in_progress_alternatives) {+ LOG(" defer finishing pattern %u\n", state->pattern_index);+ } else {+ LOG(" finish pattern %u\n", state->pattern_index);+ array_push(&self->finished_states, *state);+ array_erase(&self->states, (uint32_t)(state - self->states.contents));+ did_match = true;+ j--;+ }+ }+ }+ }+ }++ if (ts_query_cursor__should_descend(self, node_intersects_range)) {+ switch (ts_tree_cursor_goto_first_child_internal(&self->cursor)) {+ case TreeCursorStepVisible:+ self->depth++;+ self->on_visible_node = true;+ continue;+ case TreeCursorStepHidden:+ self->on_visible_node = false;+ continue;+ default:+ break;+ }+ }++ self->ascending = true;+ }+ }+}++bool ts_query_cursor_next_match(+ TSQueryCursor *self,+ TSQueryMatch *match+) {+ if (self->finished_states.size == 0) {+ if (!ts_query_cursor__advance(self, false)) {+ return false;+ }+ }++ QueryState *state = &self->finished_states.contents[0];+ if (state->id == UINT32_MAX) state->id = self->next_state_id++;+ match->id = state->id;+ match->pattern_index = state->pattern_index;+ const CaptureList *captures = capture_list_pool_get(+ &self->capture_list_pool,+ state->capture_list_id+ );+ match->captures = captures->contents;+ match->capture_count = captures->size;+ capture_list_pool_release(&self->capture_list_pool, state->capture_list_id);+ array_erase(&self->finished_states, 0);+ return true;+}++void ts_query_cursor_remove_match(+ TSQueryCursor *self,+ uint32_t match_id+) {+ for (unsigned i = 0; i < self->finished_states.size; i++) {+ const QueryState *state = &self->finished_states.contents[i];+ if (state->id == match_id) {+ capture_list_pool_release(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_erase(&self->finished_states, i);+ return;+ }+ }++ // Remove unfinished query states as well to prevent future+ // captures for a match being removed.+ for (unsigned i = 0; i < self->states.size; i++) {+ const QueryState *state = &self->states.contents[i];+ if (state->id == match_id) {+ capture_list_pool_release(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_erase(&self->states, i);+ return;+ }+ }+}++bool ts_query_cursor_next_capture(+ TSQueryCursor *self,+ TSQueryMatch *match,+ uint32_t *capture_index+) {+ // The goal here is to return captures in order, even though they may not+ // be discovered in order, because patterns can overlap. Search for matches+ // until there is a finished capture that is before any unfinished capture.+ for (;;) {+ // First, find the earliest capture in an unfinished match.+ uint32_t first_unfinished_capture_byte;+ uint32_t first_unfinished_pattern_index;+ uint32_t first_unfinished_state_index;+ bool first_unfinished_state_is_definite = false;+ bool found_unfinished_state = ts_query_cursor__first_in_progress_capture(+ self,+ &first_unfinished_state_index,+ &first_unfinished_capture_byte,+ &first_unfinished_pattern_index,+ &first_unfinished_state_is_definite+ );++ // Then find the earliest capture in a finished match. It must occur+ // before the first capture in an *unfinished* match.+ QueryState *first_finished_state = NULL;+ uint32_t first_finished_capture_byte = first_unfinished_capture_byte;+ uint32_t first_finished_pattern_index = first_unfinished_pattern_index;+ for (unsigned i = 0; i < self->finished_states.size;) {+ QueryState *state = &self->finished_states.contents[i];+ const CaptureList *captures = capture_list_pool_get(+ &self->capture_list_pool,+ state->capture_list_id+ );++ // Remove states whose captures are all consumed.+ if (state->consumed_capture_count >= captures->size) {+ capture_list_pool_release(+ &self->capture_list_pool,+ state->capture_list_id+ );+ array_erase(&self->finished_states, i);+ continue;+ }++ TSNode node = captures->contents[state->consumed_capture_count].node;++ bool node_precedes_range = (+ ts_node_end_byte(node) <= self->start_byte ||+ point_lte(ts_node_end_point(node), self->start_point)+ );+ bool node_follows_range = (+ ts_node_start_byte(node) >= self->end_byte ||+ point_gte(ts_node_start_point(node), self->end_point)+ );+ bool node_outside_of_range = node_precedes_range || node_follows_range;++ // Skip captures that are outside of the cursor's range.+ if (node_outside_of_range) {+ state->consumed_capture_count++;+ continue;+ }++ uint32_t node_start_byte = ts_node_start_byte(node);+ if (+ node_start_byte < first_finished_capture_byte ||+ (+ node_start_byte == first_finished_capture_byte &&+ state->pattern_index < first_finished_pattern_index+ )+ ) {+ first_finished_state = state;+ first_finished_capture_byte = node_start_byte;+ first_finished_pattern_index = state->pattern_index;+ }+ i++;+ }++ // If there is finished capture that is clearly before any unfinished+ // capture, then return its match, and its capture index. Internally+ // record the fact that the capture has been 'consumed'.+ QueryState *state;+ if (first_finished_state) {+ state = first_finished_state;+ } else if (first_unfinished_state_is_definite) {+ state = &self->states.contents[first_unfinished_state_index];+ } else {+ state = NULL;+ }++ if (state) {+ if (state->id == UINT32_MAX) state->id = self->next_state_id++;+ match->id = state->id;+ match->pattern_index = state->pattern_index;+ const CaptureList *captures = capture_list_pool_get(+ &self->capture_list_pool,+ state->capture_list_id+ );+ match->captures = captures->contents;+ match->capture_count = captures->size;+ *capture_index = state->consumed_capture_count;+ state->consumed_capture_count++;+ return true;+ }++ if (capture_list_pool_is_empty(&self->capture_list_pool) && found_unfinished_state) {+ LOG(+ " abandon state. index:%u, pattern:%u, offset:%u.\n",+ first_unfinished_state_index,+ first_unfinished_pattern_index,+ first_unfinished_capture_byte+ );+ capture_list_pool_release(+ &self->capture_list_pool,+ self->states.contents[first_unfinished_state_index].capture_list_id+ );+ array_erase(&self->states, first_unfinished_state_index);+ }++ // If there are no finished matches that are ready to be returned, then+ // continue finding more matches.+ if (+ !ts_query_cursor__advance(self, true) &&+ self->finished_states.size == 0+ ) return false;+ }+}++void ts_query_cursor_set_max_start_depth(+ TSQueryCursor *self,+ uint32_t max_start_depth+) {+ self->max_start_depth = max_start_depth;+}++#undef LOG
+ vendor/tree-sitter/lib/src/reduce_action.h view
@@ -0,0 +1,34 @@+#ifndef TREE_SITTER_REDUCE_ACTION_H_+#define TREE_SITTER_REDUCE_ACTION_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./array.h"+#include "tree_sitter/api.h"++typedef struct {+ uint32_t count;+ TSSymbol symbol;+ int dynamic_precedence;+ unsigned short production_id;+} ReduceAction;++typedef Array(ReduceAction) ReduceActionSet;++static inline void ts_reduce_action_set_add(ReduceActionSet *self,+ ReduceAction new_action) {+ for (uint32_t i = 0; i < self->size; i++) {+ ReduceAction action = self->contents[i];+ if (action.symbol == new_action.symbol && action.count == new_action.count)+ return;+ }+ array_push(self, new_action);+}++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_REDUCE_ACTION_H_
+ vendor/tree-sitter/lib/src/reusable_node.h view
@@ -0,0 +1,95 @@+#include "./subtree.h"++typedef struct {+ Subtree tree;+ uint32_t child_index;+ uint32_t byte_offset;+} StackEntry;++typedef struct {+ Array(StackEntry) stack;+ Subtree last_external_token;+} ReusableNode;++static inline ReusableNode reusable_node_new(void) {+ return (ReusableNode) {array_new(), NULL_SUBTREE};+}++static inline void reusable_node_clear(ReusableNode *self) {+ array_clear(&self->stack);+ self->last_external_token = NULL_SUBTREE;+}++static inline Subtree reusable_node_tree(ReusableNode *self) {+ return self->stack.size > 0+ ? self->stack.contents[self->stack.size - 1].tree+ : NULL_SUBTREE;+}++static inline uint32_t reusable_node_byte_offset(ReusableNode *self) {+ return self->stack.size > 0+ ? self->stack.contents[self->stack.size - 1].byte_offset+ : UINT32_MAX;+}++static inline void reusable_node_delete(ReusableNode *self) {+ array_delete(&self->stack);+}++static inline void reusable_node_advance(ReusableNode *self) {+ StackEntry last_entry = *array_back(&self->stack);+ uint32_t byte_offset = last_entry.byte_offset + ts_subtree_total_bytes(last_entry.tree);+ if (ts_subtree_has_external_tokens(last_entry.tree)) {+ self->last_external_token = ts_subtree_last_external_token(last_entry.tree);+ }++ Subtree tree;+ uint32_t next_index;+ do {+ StackEntry popped_entry = array_pop(&self->stack);+ next_index = popped_entry.child_index + 1;+ if (self->stack.size == 0) return;+ tree = array_back(&self->stack)->tree;+ } while (ts_subtree_child_count(tree) <= next_index);++ array_push(&self->stack, ((StackEntry) {+ .tree = ts_subtree_children(tree)[next_index],+ .child_index = next_index,+ .byte_offset = byte_offset,+ }));+}++static inline bool reusable_node_descend(ReusableNode *self) {+ StackEntry last_entry = *array_back(&self->stack);+ if (ts_subtree_child_count(last_entry.tree) > 0) {+ array_push(&self->stack, ((StackEntry) {+ .tree = ts_subtree_children(last_entry.tree)[0],+ .child_index = 0,+ .byte_offset = last_entry.byte_offset,+ }));+ return true;+ } else {+ return false;+ }+}++static inline void reusable_node_advance_past_leaf(ReusableNode *self) {+ while (reusable_node_descend(self)) {}+ reusable_node_advance(self);+}++static inline void reusable_node_reset(ReusableNode *self, Subtree tree) {+ reusable_node_clear(self);+ array_push(&self->stack, ((StackEntry) {+ .tree = tree,+ .child_index = 0,+ .byte_offset = 0,+ }));++ // Never reuse the root node, because it has a non-standard internal structure+ // due to transformations that are applied when it is accepted: adding the EOF+ // child and any extra children.+ if (!reusable_node_descend(self)) {+ reusable_node_clear(self);+ }+}
+ vendor/tree-sitter/lib/src/stack.c view
@@ -0,0 +1,899 @@+#include "./alloc.h"+#include "./language.h"+#include "./subtree.h"+#include "./array.h"+#include "./stack.h"+#include "./length.h"+#include <assert.h>+#include <inttypes.h>+#include <stdio.h>++#define MAX_LINK_COUNT 8+#define MAX_NODE_POOL_SIZE 50+#define MAX_ITERATOR_COUNT 64++#if defined _WIN32 && !defined __GNUC__+#define forceinline __forceinline+#else+#define forceinline static inline __attribute__((always_inline))+#endif++typedef struct StackNode StackNode;++typedef struct {+ StackNode *node;+ Subtree subtree;+ bool is_pending;+} StackLink;++struct StackNode {+ TSStateId state;+ Length position;+ StackLink links[MAX_LINK_COUNT];+ short unsigned int link_count;+ uint32_t ref_count;+ unsigned error_cost;+ unsigned node_count;+ int dynamic_precedence;+};++typedef struct {+ StackNode *node;+ SubtreeArray subtrees;+ uint32_t subtree_count;+ bool is_pending;+} StackIterator;++typedef Array(StackNode *) StackNodeArray;++typedef enum {+ StackStatusActive,+ StackStatusPaused,+ StackStatusHalted,+} StackStatus;++typedef struct {+ StackNode *node;+ StackSummary *summary;+ unsigned node_count_at_last_error;+ Subtree last_external_token;+ Subtree lookahead_when_paused;+ StackStatus status;+} StackHead;++struct Stack {+ Array(StackHead) heads;+ StackSliceArray slices;+ Array(StackIterator) iterators;+ StackNodeArray node_pool;+ StackNode *base_node;+ SubtreePool *subtree_pool;+};++typedef unsigned StackAction;+enum {+ StackActionNone,+ StackActionStop = 1,+ StackActionPop = 2,+};++typedef StackAction (*StackCallback)(void *, const StackIterator *);++static void stack_node_retain(StackNode *self) {+ if (!self)+ return;+ ts_assert(self->ref_count > 0);+ self->ref_count++;+ ts_assert(self->ref_count != 0);+}++static void stack_node_release(+ StackNode *self,+ StackNodeArray *pool,+ SubtreePool *subtree_pool+) {+recur:+ ts_assert(self->ref_count != 0);+ self->ref_count--;+ if (self->ref_count > 0) return;++ StackNode *first_predecessor = NULL;+ if (self->link_count > 0) {+ for (unsigned i = self->link_count - 1; i > 0; i--) {+ StackLink link = self->links[i];+ if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);+ stack_node_release(link.node, pool, subtree_pool);+ }+ StackLink link = self->links[0];+ if (link.subtree.ptr) ts_subtree_release(subtree_pool, link.subtree);+ first_predecessor = self->links[0].node;+ }++ if (pool->size < MAX_NODE_POOL_SIZE) {+ array_push(pool, self);+ } else {+ ts_free(self);+ }++ if (first_predecessor) {+ self = first_predecessor;+ goto recur;+ }+}++/// Get the number of nodes in the subtree, for the purpose of measuring+/// how much progress has been made by a given version of the stack.+static uint32_t stack__subtree_node_count(Subtree subtree) {+ uint32_t count = ts_subtree_visible_descendant_count(subtree);+ if (ts_subtree_visible(subtree)) count++;++ // Count intermediate error nodes even though they are not visible,+ // because a stack version's node count is used to check whether it+ // has made any progress since the last time it encountered an error.+ if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat) count++;++ return count;+}++static StackNode *stack_node_new(+ StackNode *previous_node,+ Subtree subtree,+ bool is_pending,+ TSStateId state,+ StackNodeArray *pool+) {+ StackNode *node = pool->size > 0+ ? array_pop(pool)+ : ts_malloc(sizeof(StackNode));+ *node = (StackNode) {+ .ref_count = 1,+ .link_count = 0,+ .state = state+ };++ if (previous_node) {+ node->link_count = 1;+ node->links[0] = (StackLink) {+ .node = previous_node,+ .subtree = subtree,+ .is_pending = is_pending,+ };++ node->position = previous_node->position;+ node->error_cost = previous_node->error_cost;+ node->dynamic_precedence = previous_node->dynamic_precedence;+ node->node_count = previous_node->node_count;++ if (subtree.ptr) {+ node->error_cost += ts_subtree_error_cost(subtree);+ node->position = length_add(node->position, ts_subtree_total_size(subtree));+ node->node_count += stack__subtree_node_count(subtree);+ node->dynamic_precedence += ts_subtree_dynamic_precedence(subtree);+ }+ } else {+ node->position = length_zero();+ node->error_cost = 0;+ }++ return node;+}++static bool stack__subtree_is_equivalent(Subtree left, Subtree right) {+ if (left.ptr == right.ptr) return true;+ if (!left.ptr || !right.ptr) return false;++ // Symbols must match+ if (ts_subtree_symbol(left) != ts_subtree_symbol(right)) return false;++ // If both have errors, don't bother keeping both.+ if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0) return true;++ return (+ ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes &&+ ts_subtree_size(left).bytes == ts_subtree_size(right).bytes &&+ ts_subtree_child_count(left) == ts_subtree_child_count(right) &&+ ts_subtree_extra(left) == ts_subtree_extra(right) &&+ ts_subtree_external_scanner_state_eq(left, right)+ );+}++static void stack_node_add_link(+ StackNode *self,+ StackLink link,+ SubtreePool *subtree_pool+) {+ if (link.node == self) return;++ for (int i = 0; i < self->link_count; i++) {+ StackLink *existing_link = &self->links[i];+ if (stack__subtree_is_equivalent(existing_link->subtree, link.subtree)) {+ // In general, we preserve ambiguities until they are removed from the stack+ // during a pop operation where multiple paths lead to the same node. But in+ // the special case where two links directly connect the same pair of nodes,+ // we can safely remove the ambiguity ahead of time without changing behavior.+ if (existing_link->node == link.node) {+ if (+ ts_subtree_dynamic_precedence(link.subtree) >+ ts_subtree_dynamic_precedence(existing_link->subtree)+ ) {+ ts_subtree_retain(link.subtree);+ ts_subtree_release(subtree_pool, existing_link->subtree);+ existing_link->subtree = link.subtree;+ self->dynamic_precedence =+ link.node->dynamic_precedence + ts_subtree_dynamic_precedence(link.subtree);+ }+ return;+ }++ // If the previous nodes are mergeable, merge them recursively.+ if (+ existing_link->node->state == link.node->state &&+ existing_link->node->position.bytes == link.node->position.bytes &&+ existing_link->node->error_cost == link.node->error_cost+ ) {+ for (int j = 0; j < link.node->link_count; j++) {+ stack_node_add_link(existing_link->node, link.node->links[j], subtree_pool);+ }+ int32_t dynamic_precedence = link.node->dynamic_precedence;+ if (link.subtree.ptr) {+ dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);+ }+ if (dynamic_precedence > self->dynamic_precedence) {+ self->dynamic_precedence = dynamic_precedence;+ }+ return;+ }+ }+ }++ if (self->link_count == MAX_LINK_COUNT) return;++ stack_node_retain(link.node);+ unsigned node_count = link.node->node_count;+ int dynamic_precedence = link.node->dynamic_precedence;+ self->links[self->link_count++] = link;++ if (link.subtree.ptr) {+ ts_subtree_retain(link.subtree);+ node_count += stack__subtree_node_count(link.subtree);+ dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);+ }++ if (node_count > self->node_count) self->node_count = node_count;+ if (dynamic_precedence > self->dynamic_precedence) self->dynamic_precedence = dynamic_precedence;+}++static void stack_head_delete(+ StackHead *self,+ StackNodeArray *pool,+ SubtreePool *subtree_pool+) {+ if (self->node) {+ if (self->last_external_token.ptr) {+ ts_subtree_release(subtree_pool, self->last_external_token);+ }+ if (self->lookahead_when_paused.ptr) {+ ts_subtree_release(subtree_pool, self->lookahead_when_paused);+ }+ if (self->summary) {+ array_delete(self->summary);+ ts_free(self->summary);+ }+ stack_node_release(self->node, pool, subtree_pool);+ }+}++static StackVersion ts_stack__add_version(+ Stack *self,+ StackVersion original_version,+ StackNode *node+) {+ StackHead head = {+ .node = node,+ .node_count_at_last_error = self->heads.contents[original_version].node_count_at_last_error,+ .last_external_token = self->heads.contents[original_version].last_external_token,+ .status = StackStatusActive,+ .lookahead_when_paused = NULL_SUBTREE,+ };+ array_push(&self->heads, head);+ stack_node_retain(node);+ if (head.last_external_token.ptr) ts_subtree_retain(head.last_external_token);+ return (StackVersion)(self->heads.size - 1);+}++static void ts_stack__add_slice(+ Stack *self,+ StackVersion original_version,+ StackNode *node,+ SubtreeArray *subtrees+) {+ for (uint32_t i = self->slices.size - 1; i + 1 > 0; i--) {+ StackVersion version = self->slices.contents[i].version;+ if (self->heads.contents[version].node == node) {+ StackSlice slice = {*subtrees, version};+ array_insert(&self->slices, i + 1, slice);+ return;+ }+ }++ StackVersion version = ts_stack__add_version(self, original_version, node);+ StackSlice slice = { *subtrees, version };+ array_push(&self->slices, slice);+}++static StackSliceArray stack__iter(+ Stack *self,+ StackVersion version,+ StackCallback callback,+ void *payload,+ int goal_subtree_count+) {+ array_clear(&self->slices);+ array_clear(&self->iterators);++ StackHead *head = array_get(&self->heads, version);+ StackIterator new_iterator = {+ .node = head->node,+ .subtrees = array_new(),+ .subtree_count = 0,+ .is_pending = true,+ };++ bool include_subtrees = false;+ if (goal_subtree_count >= 0) {+ include_subtrees = true;+ array_reserve(&new_iterator.subtrees, (uint32_t)ts_subtree_alloc_size(goal_subtree_count) / sizeof(Subtree));+ }++ array_push(&self->iterators, new_iterator);++ while (self->iterators.size > 0) {+ for (uint32_t i = 0, size = self->iterators.size; i < size; i++) {+ StackIterator *iterator = &self->iterators.contents[i];+ StackNode *node = iterator->node;++ StackAction action = callback(payload, iterator);+ bool should_pop = action & StackActionPop;+ bool should_stop = action & StackActionStop || node->link_count == 0;++ if (should_pop) {+ SubtreeArray subtrees = iterator->subtrees;+ if (!should_stop) {+ ts_subtree_array_copy(subtrees, &subtrees);+ }+ ts_subtree_array_reverse(&subtrees);+ ts_stack__add_slice(+ self,+ version,+ node,+ &subtrees+ );+ }++ if (should_stop) {+ if (!should_pop) {+ ts_subtree_array_delete(self->subtree_pool, &iterator->subtrees);+ }+ array_erase(&self->iterators, i);+ i--, size--;+ continue;+ }++ for (uint32_t j = 1; j <= node->link_count; j++) {+ StackIterator *next_iterator;+ StackLink link;+ if (j == node->link_count) {+ link = node->links[0];+ next_iterator = &self->iterators.contents[i];+ } else {+ if (self->iterators.size >= MAX_ITERATOR_COUNT) continue;+ link = node->links[j];+ StackIterator current_iterator = self->iterators.contents[i];+ array_push(&self->iterators, current_iterator);+ next_iterator = array_back(&self->iterators);+ ts_subtree_array_copy(next_iterator->subtrees, &next_iterator->subtrees);+ }++ next_iterator->node = link.node;+ if (link.subtree.ptr) {+ if (include_subtrees) {+ array_push(&next_iterator->subtrees, link.subtree);+ ts_subtree_retain(link.subtree);+ }++ if (!ts_subtree_extra(link.subtree)) {+ next_iterator->subtree_count++;+ if (!link.is_pending) {+ next_iterator->is_pending = false;+ }+ }+ } else {+ next_iterator->subtree_count++;+ next_iterator->is_pending = false;+ }+ }+ }+ }++ return self->slices;+}++Stack *ts_stack_new(SubtreePool *subtree_pool) {+ Stack *self = ts_calloc(1, sizeof(Stack));++ array_init(&self->heads);+ array_init(&self->slices);+ array_init(&self->iterators);+ array_init(&self->node_pool);+ array_reserve(&self->heads, 4);+ array_reserve(&self->slices, 4);+ array_reserve(&self->iterators, 4);+ array_reserve(&self->node_pool, MAX_NODE_POOL_SIZE);++ self->subtree_pool = subtree_pool;+ self->base_node = stack_node_new(NULL, NULL_SUBTREE, false, 1, &self->node_pool);+ ts_stack_clear(self);++ return self;+}++void ts_stack_delete(Stack *self) {+ if (self->slices.contents)+ array_delete(&self->slices);+ if (self->iterators.contents)+ array_delete(&self->iterators);+ stack_node_release(self->base_node, &self->node_pool, self->subtree_pool);+ for (uint32_t i = 0; i < self->heads.size; i++) {+ stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);+ }+ array_clear(&self->heads);+ if (self->node_pool.contents) {+ for (uint32_t i = 0; i < self->node_pool.size; i++)+ ts_free(self->node_pool.contents[i]);+ array_delete(&self->node_pool);+ }+ array_delete(&self->heads);+ ts_free(self);+}++uint32_t ts_stack_version_count(const Stack *self) {+ return self->heads.size;+}++TSStateId ts_stack_state(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->node->state;+}++Length ts_stack_position(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->node->position;+}++Subtree ts_stack_last_external_token(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->last_external_token;+}++void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token) {+ StackHead *head = array_get(&self->heads, version);+ if (token.ptr) ts_subtree_retain(token);+ if (head->last_external_token.ptr) ts_subtree_release(self->subtree_pool, head->last_external_token);+ head->last_external_token = token;+}++unsigned ts_stack_error_cost(const Stack *self, StackVersion version) {+ StackHead *head = array_get(&self->heads, version);+ unsigned result = head->node->error_cost;+ if (+ head->status == StackStatusPaused ||+ (head->node->state == ERROR_STATE && !head->node->links[0].subtree.ptr)) {+ result += ERROR_COST_PER_RECOVERY;+ }+ return result;+}++unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version) {+ StackHead *head = array_get(&self->heads, version);+ if (head->node->node_count < head->node_count_at_last_error) {+ head->node_count_at_last_error = head->node->node_count;+ }+ return head->node->node_count - head->node_count_at_last_error;+}++void ts_stack_push(+ Stack *self,+ StackVersion version,+ Subtree subtree,+ bool pending,+ TSStateId state+) {+ StackHead *head = array_get(&self->heads, version);+ StackNode *new_node = stack_node_new(head->node, subtree, pending, state, &self->node_pool);+ if (!subtree.ptr) head->node_count_at_last_error = new_node->node_count;+ head->node = new_node;+}++forceinline StackAction pop_count_callback(void *payload, const StackIterator *iterator) {+ unsigned *goal_subtree_count = payload;+ if (iterator->subtree_count == *goal_subtree_count) {+ return StackActionPop | StackActionStop;+ } else {+ return StackActionNone;+ }+}++StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count) {+ return stack__iter(self, version, pop_count_callback, &count, (int)count);+}++forceinline StackAction pop_pending_callback(void *payload, const StackIterator *iterator) {+ (void)payload;+ if (iterator->subtree_count >= 1) {+ if (iterator->is_pending) {+ return StackActionPop | StackActionStop;+ } else {+ return StackActionStop;+ }+ } else {+ return StackActionNone;+ }+}++StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version) {+ StackSliceArray pop = stack__iter(self, version, pop_pending_callback, NULL, 0);+ if (pop.size > 0) {+ ts_stack_renumber_version(self, pop.contents[0].version, version);+ pop.contents[0].version = version;+ }+ return pop;+}++forceinline StackAction pop_error_callback(void *payload, const StackIterator *iterator) {+ if (iterator->subtrees.size > 0) {+ bool *found_error = payload;+ if (!*found_error && ts_subtree_is_error(iterator->subtrees.contents[0])) {+ *found_error = true;+ return StackActionPop | StackActionStop;+ } else {+ return StackActionStop;+ }+ } else {+ return StackActionNone;+ }+}++SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version) {+ StackNode *node = array_get(&self->heads, version)->node;+ for (unsigned i = 0; i < node->link_count; i++) {+ if (node->links[i].subtree.ptr && ts_subtree_is_error(node->links[i].subtree)) {+ bool found_error = false;+ StackSliceArray pop = stack__iter(self, version, pop_error_callback, &found_error, 1);+ if (pop.size > 0) {+ ts_assert(pop.size == 1);+ ts_stack_renumber_version(self, pop.contents[0].version, version);+ return pop.contents[0].subtrees;+ }+ break;+ }+ }+ return (SubtreeArray) {.size = 0};+}++forceinline StackAction pop_all_callback(void *payload, const StackIterator *iterator) {+ (void)payload;+ return iterator->node->link_count == 0 ? StackActionPop : StackActionNone;+}++StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version) {+ return stack__iter(self, version, pop_all_callback, NULL, 0);+}++typedef struct {+ StackSummary *summary;+ unsigned max_depth;+} SummarizeStackSession;++forceinline StackAction summarize_stack_callback(void *payload, const StackIterator *iterator) {+ SummarizeStackSession *session = payload;+ TSStateId state = iterator->node->state;+ unsigned depth = iterator->subtree_count;+ if (depth > session->max_depth) return StackActionStop;+ for (unsigned i = session->summary->size - 1; i + 1 > 0; i--) {+ StackSummaryEntry entry = session->summary->contents[i];+ if (entry.depth < depth) break;+ if (entry.depth == depth && entry.state == state) return StackActionNone;+ }+ array_push(session->summary, ((StackSummaryEntry) {+ .position = iterator->node->position,+ .depth = depth,+ .state = state,+ }));+ return StackActionNone;+}++void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth) {+ SummarizeStackSession session = {+ .summary = ts_malloc(sizeof(StackSummary)),+ .max_depth = max_depth+ };+ array_init(session.summary);+ stack__iter(self, version, summarize_stack_callback, &session, -1);+ StackHead *head = &self->heads.contents[version];+ if (head->summary) {+ array_delete(head->summary);+ ts_free(head->summary);+ }+ head->summary = session.summary;+}++StackSummary *ts_stack_get_summary(Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->summary;+}++int ts_stack_dynamic_precedence(Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->node->dynamic_precedence;+}++bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version) {+ const StackHead *head = array_get(&self->heads, version);+ const StackNode *node = head->node;+ if (node->error_cost == 0) return true;+ while (node) {+ if (node->link_count > 0) {+ Subtree subtree = node->links[0].subtree;+ if (subtree.ptr) {+ if (ts_subtree_total_bytes(subtree) > 0) {+ return true;+ } else if (+ node->node_count > head->node_count_at_last_error &&+ ts_subtree_error_cost(subtree) == 0+ ) {+ node = node->links[0].node;+ continue;+ }+ }+ }+ break;+ }+ return false;+}++void ts_stack_remove_version(Stack *self, StackVersion version) {+ stack_head_delete(array_get(&self->heads, version), &self->node_pool, self->subtree_pool);+ array_erase(&self->heads, version);+}++void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2) {+ if (v1 == v2) return;+ ts_assert(v2 < v1);+ ts_assert((uint32_t)v1 < self->heads.size);+ StackHead *source_head = &self->heads.contents[v1];+ StackHead *target_head = &self->heads.contents[v2];+ if (target_head->summary && !source_head->summary) {+ source_head->summary = target_head->summary;+ target_head->summary = NULL;+ }+ stack_head_delete(target_head, &self->node_pool, self->subtree_pool);+ *target_head = *source_head;+ array_erase(&self->heads, v1);+}++void ts_stack_swap_versions(Stack *self, StackVersion v1, StackVersion v2) {+ StackHead temporary_head = self->heads.contents[v1];+ self->heads.contents[v1] = self->heads.contents[v2];+ self->heads.contents[v2] = temporary_head;+}++StackVersion ts_stack_copy_version(Stack *self, StackVersion version) {+ ts_assert(version < self->heads.size);+ array_push(&self->heads, self->heads.contents[version]);+ StackHead *head = array_back(&self->heads);+ stack_node_retain(head->node);+ if (head->last_external_token.ptr) ts_subtree_retain(head->last_external_token);+ head->summary = NULL;+ return self->heads.size - 1;+}++bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2) {+ if (!ts_stack_can_merge(self, version1, version2)) return false;+ StackHead *head1 = &self->heads.contents[version1];+ StackHead *head2 = &self->heads.contents[version2];+ for (uint32_t i = 0; i < head2->node->link_count; i++) {+ stack_node_add_link(head1->node, head2->node->links[i], self->subtree_pool);+ }+ if (head1->node->state == ERROR_STATE) {+ head1->node_count_at_last_error = head1->node->node_count;+ }+ ts_stack_remove_version(self, version2);+ return true;+}++bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2) {+ StackHead *head1 = &self->heads.contents[version1];+ StackHead *head2 = &self->heads.contents[version2];+ return+ head1->status == StackStatusActive &&+ head2->status == StackStatusActive &&+ head1->node->state == head2->node->state &&+ head1->node->position.bytes == head2->node->position.bytes &&+ head1->node->error_cost == head2->node->error_cost &&+ ts_subtree_external_scanner_state_eq(head1->last_external_token, head2->last_external_token);+}++void ts_stack_halt(Stack *self, StackVersion version) {+ array_get(&self->heads, version)->status = StackStatusHalted;+}++void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead) {+ StackHead *head = array_get(&self->heads, version);+ head->status = StackStatusPaused;+ head->lookahead_when_paused = lookahead;+ head->node_count_at_last_error = head->node->node_count;+}++bool ts_stack_is_active(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->status == StackStatusActive;+}++bool ts_stack_is_halted(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->status == StackStatusHalted;+}++bool ts_stack_is_paused(const Stack *self, StackVersion version) {+ return array_get(&self->heads, version)->status == StackStatusPaused;+}++Subtree ts_stack_resume(Stack *self, StackVersion version) {+ StackHead *head = array_get(&self->heads, version);+ ts_assert(head->status == StackStatusPaused);+ Subtree result = head->lookahead_when_paused;+ head->status = StackStatusActive;+ head->lookahead_when_paused = NULL_SUBTREE;+ return result;+}++void ts_stack_clear(Stack *self) {+ stack_node_retain(self->base_node);+ for (uint32_t i = 0; i < self->heads.size; i++) {+ stack_head_delete(&self->heads.contents[i], &self->node_pool, self->subtree_pool);+ }+ array_clear(&self->heads);+ array_push(&self->heads, ((StackHead) {+ .node = self->base_node,+ .status = StackStatusActive,+ .last_external_token = NULL_SUBTREE,+ .lookahead_when_paused = NULL_SUBTREE,+ }));+}++bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f) {+ array_reserve(&self->iterators, 32);+ if (!f) f = stderr;++ fprintf(f, "digraph stack {\n");+ fprintf(f, "rankdir=\"RL\";\n");+ fprintf(f, "edge [arrowhead=none]\n");++ Array(StackNode *) visited_nodes = array_new();++ array_clear(&self->iterators);+ for (uint32_t i = 0; i < self->heads.size; i++) {+ StackHead *head = &self->heads.contents[i];+ if (head->status == StackStatusHalted) continue;++ fprintf(f, "node_head_%u [shape=none, label=\"\"]\n", i);+ fprintf(f, "node_head_%u -> node_%p [", i, (void *)head->node);++ if (head->status == StackStatusPaused) {+ fprintf(f, "color=red ");+ }+ fprintf(f,+ "label=%u, fontcolor=blue, weight=10000, labeltooltip=\"node_count: %u\nerror_cost: %u",+ i,+ ts_stack_node_count_since_error(self, i),+ ts_stack_error_cost(self, i)+ );++ if (head->summary) {+ fprintf(f, "\nsummary:");+ for (uint32_t j = 0; j < head->summary->size; j++) fprintf(f, " %u", head->summary->contents[j].state);+ }++ if (head->last_external_token.ptr) {+ const ExternalScannerState *state = &head->last_external_token.ptr->external_scanner_state;+ const char *data = ts_external_scanner_state_data(state);+ fprintf(f, "\nexternal_scanner_state:");+ for (uint32_t j = 0; j < state->length; j++) fprintf(f, " %2X", data[j]);+ }++ fprintf(f, "\"]\n");+ array_push(&self->iterators, ((StackIterator) {+ .node = head->node+ }));+ }++ bool all_iterators_done = false;+ while (!all_iterators_done) {+ all_iterators_done = true;++ for (uint32_t i = 0; i < self->iterators.size; i++) {+ StackIterator iterator = self->iterators.contents[i];+ StackNode *node = iterator.node;++ for (uint32_t j = 0; j < visited_nodes.size; j++) {+ if (visited_nodes.contents[j] == node) {+ node = NULL;+ break;+ }+ }++ if (!node) continue;+ all_iterators_done = false;++ fprintf(f, "node_%p [", (void *)node);+ if (node->state == ERROR_STATE) {+ fprintf(f, "label=\"?\"");+ } else if (+ node->link_count == 1 &&+ node->links[0].subtree.ptr &&+ ts_subtree_extra(node->links[0].subtree)+ ) {+ fprintf(f, "shape=point margin=0 label=\"\"");+ } else {+ fprintf(f, "label=\"%d\"", node->state);+ }++ fprintf(+ f,+ " tooltip=\"position: %u,%u\nnode_count:%u\nerror_cost: %u\ndynamic_precedence: %d\"];\n",+ node->position.extent.row + 1,+ node->position.extent.column,+ node->node_count,+ node->error_cost,+ node->dynamic_precedence+ );++ for (int j = 0; j < node->link_count; j++) {+ StackLink link = node->links[j];+ fprintf(f, "node_%p -> node_%p [", (void *)node, (void *)link.node);+ if (link.is_pending) fprintf(f, "style=dashed ");+ if (link.subtree.ptr && ts_subtree_extra(link.subtree)) fprintf(f, "fontcolor=gray ");++ if (!link.subtree.ptr) {+ fprintf(f, "color=red");+ } else {+ fprintf(f, "label=\"");+ bool quoted = ts_subtree_visible(link.subtree) && !ts_subtree_named(link.subtree);+ if (quoted) fprintf(f, "'");+ ts_language_write_symbol_as_dot_string(language, f, ts_subtree_symbol(link.subtree));+ if (quoted) fprintf(f, "'");+ fprintf(f, "\"");+ fprintf(+ f,+ "labeltooltip=\"error_cost: %u\ndynamic_precedence: %" PRId32 "\"",+ ts_subtree_error_cost(link.subtree),+ ts_subtree_dynamic_precedence(link.subtree)+ );+ }++ fprintf(f, "];\n");++ StackIterator *next_iterator;+ if (j == 0) {+ next_iterator = &self->iterators.contents[i];+ } else {+ array_push(&self->iterators, iterator);+ next_iterator = array_back(&self->iterators);+ }+ next_iterator->node = link.node;+ }++ array_push(&visited_nodes, node);+ }+ }++ fprintf(f, "}\n");++ array_delete(&visited_nodes);+ return true;+}++#undef forceinline
+ vendor/tree-sitter/lib/src/stack.h view
@@ -0,0 +1,130 @@+#ifndef TREE_SITTER_PARSE_STACK_H_+#define TREE_SITTER_PARSE_STACK_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "./array.h"+#include "./subtree.h"+#include <stdio.h>++typedef struct Stack Stack;++typedef unsigned StackVersion;+#define STACK_VERSION_NONE ((StackVersion)-1)++typedef struct {+ SubtreeArray subtrees;+ StackVersion version;+} StackSlice;+typedef Array(StackSlice) StackSliceArray;++typedef struct {+ Length position;+ unsigned depth;+ TSStateId state;+} StackSummaryEntry;+typedef Array(StackSummaryEntry) StackSummary;++// Create a stack.+Stack *ts_stack_new(SubtreePool *subtree_pool);++// Release the memory reserved for a given stack.+void ts_stack_delete(Stack *self);++// Get the stack's current number of versions.+uint32_t ts_stack_version_count(const Stack *self);++// Get the state at the top of the given version of the stack. If the stack is+// empty, this returns the initial state, 0.+TSStateId ts_stack_state(const Stack *self, StackVersion version);++// Get the last external token associated with a given version of the stack.+Subtree ts_stack_last_external_token(const Stack *self, StackVersion version);++// Set the last external token associated with a given version of the stack.+void ts_stack_set_last_external_token(Stack *self, StackVersion version, Subtree token);++// Get the position of the given version of the stack within the document.+Length ts_stack_position(const Stack *, StackVersion);++// Push a tree and state onto the given version of the stack.+//+// This transfers ownership of the tree to the Stack. Callers that+// need to retain ownership of the tree for their own purposes should+// first retain the tree.+void ts_stack_push(Stack *self, StackVersion version, Subtree subtree, bool pending, TSStateId state);++// Pop the given number of entries from the given version of the stack. This+// operation can increase the number of stack versions by revealing multiple+// versions which had previously been merged. It returns an array that+// specifies the index of each revealed version and the trees that were+// removed from that version.+StackSliceArray ts_stack_pop_count(Stack *self, StackVersion version, uint32_t count);++// Remove an error at the top of the given version of the stack.+SubtreeArray ts_stack_pop_error(Stack *self, StackVersion version);++// Remove any pending trees from the top of the given version of the stack.+StackSliceArray ts_stack_pop_pending(Stack *self, StackVersion version);++// Remove all trees from the given version of the stack.+StackSliceArray ts_stack_pop_all(Stack *self, StackVersion version);++// Get the maximum number of tree nodes reachable from this version of the stack+// since the last error was detected.+unsigned ts_stack_node_count_since_error(const Stack *self, StackVersion version);++int ts_stack_dynamic_precedence(Stack *self, StackVersion version);++bool ts_stack_has_advanced_since_error(const Stack *self, StackVersion version);++// Compute a summary of all the parse states near the top of the given+// version of the stack and store the summary for later retrieval.+void ts_stack_record_summary(Stack *self, StackVersion version, unsigned max_depth);++// Retrieve a summary of all the parse states near the top of the+// given version of the stack.+StackSummary *ts_stack_get_summary(Stack *self, StackVersion version);++// Get the total cost of all errors on the given version of the stack.+unsigned ts_stack_error_cost(const Stack *self, StackVersion version);++// Merge the given two stack versions if possible, returning true+// if they were successfully merged and false otherwise.+bool ts_stack_merge(Stack *self, StackVersion version1, StackVersion version2);++// Determine whether the given two stack versions can be merged.+bool ts_stack_can_merge(Stack *self, StackVersion version1, StackVersion version2);++Subtree ts_stack_resume(Stack *self, StackVersion version);++void ts_stack_pause(Stack *self, StackVersion version, Subtree lookahead);++void ts_stack_halt(Stack *self, StackVersion version);++bool ts_stack_is_active(const Stack *self, StackVersion version);++bool ts_stack_is_paused(const Stack *self, StackVersion version);++bool ts_stack_is_halted(const Stack *self, StackVersion version);++void ts_stack_renumber_version(Stack *self, StackVersion v1, StackVersion v2);++void ts_stack_swap_versions(Stack *, StackVersion v1, StackVersion v2);++StackVersion ts_stack_copy_version(Stack *self, StackVersion version);++// Remove the given version from the stack.+void ts_stack_remove_version(Stack *self, StackVersion version);++void ts_stack_clear(Stack *self);++bool ts_stack_print_dot_graph(Stack *self, const TSLanguage *language, FILE *f);++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_PARSE_STACK_H_
+ vendor/tree-sitter/lib/src/subtree.c view
@@ -0,0 +1,1065 @@+#include <ctype.h>+#include <stdint.h>+#include <stdbool.h>+#include <string.h>+#include <stdio.h>+#include "./alloc.h"+#include "./array.h"+#include "./atomic.h"+#include "./subtree.h"+#include "./length.h"+#include "./language.h"+#include "./error_costs.h"+#include "./ts_assert.h"+#include <stddef.h>++typedef struct {+ Length start;+ Length old_end;+ Length new_end;+} Edit;++#define TS_MAX_INLINE_TREE_LENGTH UINT8_MAX+#define TS_MAX_TREE_POOL_SIZE 32++// ExternalScannerState++void ts_external_scanner_state_init(ExternalScannerState *self, const char *data, unsigned length) {+ self->length = length;+ if (length > sizeof(self->short_data)) {+ self->long_data = ts_malloc(length);+ memcpy(self->long_data, data, length);+ } else {+ memcpy(self->short_data, data, length);+ }+}++ExternalScannerState ts_external_scanner_state_copy(const ExternalScannerState *self) {+ ExternalScannerState result = *self;+ if (self->length > sizeof(self->short_data)) {+ result.long_data = ts_malloc(self->length);+ memcpy(result.long_data, self->long_data, self->length);+ }+ return result;+}++void ts_external_scanner_state_delete(ExternalScannerState *self) {+ if (self->length > sizeof(self->short_data)) {+ ts_free(self->long_data);+ }+}++const char *ts_external_scanner_state_data(const ExternalScannerState *self) {+ if (self->length > sizeof(self->short_data)) {+ return self->long_data;+ } else {+ return self->short_data;+ }+}++bool ts_external_scanner_state_eq(const ExternalScannerState *self, const char *buffer, unsigned length) {+ return+ self->length == length &&+ memcmp(ts_external_scanner_state_data(self), buffer, length) == 0;+}++// SubtreeArray++void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest) {+ dest->size = self.size;+ dest->capacity = self.capacity;+ dest->contents = self.contents;+ if (self.capacity > 0) {+ dest->contents = ts_calloc(self.capacity, sizeof(Subtree));+ memcpy(dest->contents, self.contents, self.size * sizeof(Subtree));+ for (uint32_t i = 0; i < self.size; i++) {+ ts_subtree_retain(dest->contents[i]);+ }+ }+}++void ts_subtree_array_clear(SubtreePool *pool, SubtreeArray *self) {+ for (uint32_t i = 0; i < self->size; i++) {+ ts_subtree_release(pool, self->contents[i]);+ }+ array_clear(self);+}++void ts_subtree_array_delete(SubtreePool *pool, SubtreeArray *self) {+ ts_subtree_array_clear(pool, self);+ array_delete(self);+}++void ts_subtree_array_remove_trailing_extras(+ SubtreeArray *self,+ SubtreeArray *destination+) {+ array_clear(destination);+ while (self->size > 0) {+ Subtree last = self->contents[self->size - 1];+ if (ts_subtree_extra(last)) {+ self->size--;+ array_push(destination, last);+ } else {+ break;+ }+ }+ ts_subtree_array_reverse(destination);+}++void ts_subtree_array_reverse(SubtreeArray *self) {+ for (uint32_t i = 0, limit = self->size / 2; i < limit; i++) {+ size_t reverse_index = self->size - 1 - i;+ Subtree swap = self->contents[i];+ self->contents[i] = self->contents[reverse_index];+ self->contents[reverse_index] = swap;+ }+}++// SubtreePool++SubtreePool ts_subtree_pool_new(uint32_t capacity) {+ SubtreePool self = {array_new(), array_new()};+ array_reserve(&self.free_trees, capacity);+ return self;+}++void ts_subtree_pool_delete(SubtreePool *self) {+ if (self->free_trees.contents) {+ for (unsigned i = 0; i < self->free_trees.size; i++) {+ ts_free(self->free_trees.contents[i].ptr);+ }+ array_delete(&self->free_trees);+ }+ if (self->tree_stack.contents) array_delete(&self->tree_stack);+}++static SubtreeHeapData *ts_subtree_pool_allocate(SubtreePool *self) {+ if (self->free_trees.size > 0) {+ return array_pop(&self->free_trees).ptr;+ } else {+ return ts_malloc(sizeof(SubtreeHeapData));+ }+}++static void ts_subtree_pool_free(SubtreePool *self, SubtreeHeapData *tree) {+ if (self->free_trees.capacity > 0 && self->free_trees.size + 1 <= TS_MAX_TREE_POOL_SIZE) {+ array_push(&self->free_trees, (MutableSubtree) {.ptr = tree});+ } else {+ ts_free(tree);+ }+}++// Subtree++static inline bool ts_subtree_can_inline(Length padding, Length size, uint32_t lookahead_bytes) {+ return+ padding.bytes < TS_MAX_INLINE_TREE_LENGTH &&+ padding.extent.row < 16 &&+ padding.extent.column < TS_MAX_INLINE_TREE_LENGTH &&+ size.extent.row == 0 &&+ size.extent.column < TS_MAX_INLINE_TREE_LENGTH &&+ lookahead_bytes < 16;+}++Subtree ts_subtree_new_leaf(+ SubtreePool *pool, TSSymbol symbol, Length padding, Length size,+ uint32_t lookahead_bytes, TSStateId parse_state,+ bool has_external_tokens, bool depends_on_column,+ bool is_keyword, const TSLanguage *language+) {+ TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);+ bool extra = symbol == ts_builtin_sym_end;++ bool is_inline = (+ symbol <= UINT8_MAX &&+ !has_external_tokens &&+ ts_subtree_can_inline(padding, size, lookahead_bytes)+ );++ if (is_inline) {+ return (Subtree) {{+ .parse_state = parse_state,+ .symbol = symbol,+ .padding_bytes = padding.bytes,+ .padding_rows = padding.extent.row,+ .padding_columns = padding.extent.column,+ .size_bytes = size.bytes,+ .lookahead_bytes = lookahead_bytes,+ .visible = metadata.visible,+ .named = metadata.named,+ .extra = extra,+ .has_changes = false,+ .is_missing = false,+ .is_keyword = is_keyword,+ .is_inline = true,+ }};+ } else {+ SubtreeHeapData *data = ts_subtree_pool_allocate(pool);+ *data = (SubtreeHeapData) {+ .ref_count = 1,+ .padding = padding,+ .size = size,+ .lookahead_bytes = lookahead_bytes,+ .error_cost = 0,+ .child_count = 0,+ .symbol = symbol,+ .parse_state = parse_state,+ .visible = metadata.visible,+ .named = metadata.named,+ .extra = extra,+ .fragile_left = false,+ .fragile_right = false,+ .has_changes = false,+ .has_external_tokens = has_external_tokens,+ .has_external_scanner_state_change = false,+ .depends_on_column = depends_on_column,+ .is_missing = false,+ .is_keyword = is_keyword,+ {{.first_leaf = {.symbol = 0, .parse_state = 0}}}+ };+ return (Subtree) {.ptr = data};+ }+}++void ts_subtree_set_symbol(+ MutableSubtree *self,+ TSSymbol symbol,+ const TSLanguage *language+) {+ TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);+ if (self->data.is_inline) {+ ts_assert(symbol < UINT8_MAX);+ self->data.symbol = symbol;+ self->data.named = metadata.named;+ self->data.visible = metadata.visible;+ } else {+ self->ptr->symbol = symbol;+ self->ptr->named = metadata.named;+ self->ptr->visible = metadata.visible;+ }+}++Subtree ts_subtree_new_error(+ SubtreePool *pool, int32_t lookahead_char, Length padding, Length size,+ uint32_t bytes_scanned, TSStateId parse_state, const TSLanguage *language+) {+ Subtree result = ts_subtree_new_leaf(+ pool, ts_builtin_sym_error, padding, size, bytes_scanned,+ parse_state, false, false, false, language+ );+ SubtreeHeapData *data = (SubtreeHeapData *)result.ptr;+ data->fragile_left = true;+ data->fragile_right = true;+ data->lookahead_char = lookahead_char;+ return result;+}++// Clone a subtree.+MutableSubtree ts_subtree_clone(Subtree self) {+ size_t alloc_size = ts_subtree_alloc_size(self.ptr->child_count);+ Subtree *new_children = ts_malloc(alloc_size);+ Subtree *old_children = ts_subtree_children(self);+ memcpy(new_children, old_children, alloc_size);+ SubtreeHeapData *result = (SubtreeHeapData *)&new_children[self.ptr->child_count];+ if (self.ptr->child_count > 0) {+ for (uint32_t i = 0; i < self.ptr->child_count; i++) {+ ts_subtree_retain(new_children[i]);+ }+ } else if (self.ptr->has_external_tokens) {+ result->external_scanner_state = ts_external_scanner_state_copy(+ &self.ptr->external_scanner_state+ );+ }+ result->ref_count = 1;+ return (MutableSubtree) {.ptr = result};+}++// Get mutable version of a subtree.+//+// This takes ownership of the subtree. If the subtree has only one owner,+// this will directly convert it into a mutable version. Otherwise, it will+// perform a copy.+MutableSubtree ts_subtree_make_mut(SubtreePool *pool, Subtree self) {+ if (self.data.is_inline) return (MutableSubtree) {self.data};+ if (self.ptr->ref_count == 1) return ts_subtree_to_mut_unsafe(self);+ MutableSubtree result = ts_subtree_clone(self);+ ts_subtree_release(pool, self);+ return result;+}++static void ts_subtree__compress(+ MutableSubtree self,+ unsigned count,+ const TSLanguage *language,+ MutableSubtreeArray *stack+) {+ unsigned initial_stack_size = stack->size;++ MutableSubtree tree = self;+ TSSymbol symbol = tree.ptr->symbol;+ for (unsigned i = 0; i < count; i++) {+ if (tree.ptr->ref_count > 1 || tree.ptr->child_count < 2) break;++ MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);+ if (+ child.data.is_inline ||+ child.ptr->child_count < 2 ||+ child.ptr->ref_count > 1 ||+ child.ptr->symbol != symbol+ ) break;++ MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[0]);+ if (+ grandchild.data.is_inline ||+ grandchild.ptr->child_count < 2 ||+ grandchild.ptr->ref_count > 1 ||+ grandchild.ptr->symbol != symbol+ ) break;++ ts_subtree_children(tree)[0] = ts_subtree_from_mut(grandchild);+ ts_subtree_children(child)[0] = ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1];+ ts_subtree_children(grandchild)[grandchild.ptr->child_count - 1] = ts_subtree_from_mut(child);+ array_push(stack, tree);+ tree = grandchild;+ }++ while (stack->size > initial_stack_size) {+ tree = array_pop(stack);+ MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);+ MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[child.ptr->child_count - 1]);+ ts_subtree_summarize_children(grandchild, language);+ ts_subtree_summarize_children(child, language);+ ts_subtree_summarize_children(tree, language);+ }+}++void ts_subtree_balance(Subtree self, SubtreePool *pool, const TSLanguage *language) {+ array_clear(&pool->tree_stack);++ if (ts_subtree_child_count(self) > 0 && self.ptr->ref_count == 1) {+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(self));+ }++ while (pool->tree_stack.size > 0) {+ MutableSubtree tree = array_pop(&pool->tree_stack);++ if (tree.ptr->repeat_depth > 0) {+ Subtree child1 = ts_subtree_children(tree)[0];+ Subtree child2 = ts_subtree_children(tree)[tree.ptr->child_count - 1];+ long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);+ if (repeat_delta > 0) {+ unsigned n = (unsigned)repeat_delta;+ for (unsigned i = n / 2; i > 0; i /= 2) {+ ts_subtree__compress(tree, i, language, &pool->tree_stack);+ n -= i;+ }+ }+ }++ for (uint32_t i = 0; i < tree.ptr->child_count; i++) {+ Subtree child = ts_subtree_children(tree)[i];+ if (ts_subtree_child_count(child) > 0 && child.ptr->ref_count == 1) {+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(child));+ }+ }+ }+}++// Assign all of the node's properties that depend on its children.+void ts_subtree_summarize_children(+ MutableSubtree self,+ const TSLanguage *language+) {+ ts_assert(!self.data.is_inline);++ self.ptr->named_child_count = 0;+ self.ptr->visible_child_count = 0;+ self.ptr->error_cost = 0;+ self.ptr->repeat_depth = 0;+ self.ptr->visible_descendant_count = 0;+ self.ptr->has_external_tokens = false;+ self.ptr->depends_on_column = false;+ self.ptr->has_external_scanner_state_change = false;+ self.ptr->dynamic_precedence = 0;++ uint32_t structural_index = 0;+ const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);+ uint32_t lookahead_end_byte = 0;++ const Subtree *children = ts_subtree_children(self);+ for (uint32_t i = 0; i < self.ptr->child_count; i++) {+ Subtree child = children[i];++ if (+ self.ptr->size.extent.row == 0 &&+ ts_subtree_depends_on_column(child)+ ) {+ self.ptr->depends_on_column = true;+ }++ if (ts_subtree_has_external_scanner_state_change(child)) {+ self.ptr->has_external_scanner_state_change = true;+ }++ if (i == 0) {+ self.ptr->padding = ts_subtree_padding(child);+ self.ptr->size = ts_subtree_size(child);+ } else {+ self.ptr->size = length_add(self.ptr->size, ts_subtree_total_size(child));+ }++ uint32_t child_lookahead_end_byte =+ self.ptr->padding.bytes ++ self.ptr->size.bytes ++ ts_subtree_lookahead_bytes(child);+ if (child_lookahead_end_byte > lookahead_end_byte) {+ lookahead_end_byte = child_lookahead_end_byte;+ }++ if (ts_subtree_symbol(child) != ts_builtin_sym_error_repeat) {+ self.ptr->error_cost += ts_subtree_error_cost(child);+ }++ uint32_t grandchild_count = ts_subtree_child_count(child);+ if (+ self.ptr->symbol == ts_builtin_sym_error ||+ self.ptr->symbol == ts_builtin_sym_error_repeat+ ) {+ if (!ts_subtree_extra(child) && !(ts_subtree_is_error(child) && grandchild_count == 0)) {+ if (ts_subtree_visible(child)) {+ self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE;+ } else if (grandchild_count > 0) {+ self.ptr->error_cost += ERROR_COST_PER_SKIPPED_TREE * child.ptr->visible_child_count;+ }+ }+ }++ self.ptr->dynamic_precedence += ts_subtree_dynamic_precedence(child);+ self.ptr->visible_descendant_count += ts_subtree_visible_descendant_count(child);++ if (alias_sequence && alias_sequence[structural_index] != 0 && !ts_subtree_extra(child)) {+ self.ptr->visible_descendant_count++;+ self.ptr->visible_child_count++;+ if (ts_language_symbol_metadata(language, alias_sequence[structural_index]).named) {+ self.ptr->named_child_count++;+ }+ } else if (ts_subtree_visible(child)) {+ self.ptr->visible_descendant_count++;+ self.ptr->visible_child_count++;+ if (ts_subtree_named(child)) self.ptr->named_child_count++;+ } else if (grandchild_count > 0) {+ self.ptr->visible_child_count += child.ptr->visible_child_count;+ self.ptr->named_child_count += child.ptr->named_child_count;+ }++ if (ts_subtree_has_external_tokens(child)) self.ptr->has_external_tokens = true;++ if (ts_subtree_is_error(child)) {+ self.ptr->fragile_left = self.ptr->fragile_right = true;+ self.ptr->parse_state = TS_TREE_STATE_NONE;+ }++ if (!ts_subtree_extra(child)) structural_index++;+ }++ self.ptr->lookahead_bytes = lookahead_end_byte - self.ptr->size.bytes - self.ptr->padding.bytes;++ if (+ self.ptr->symbol == ts_builtin_sym_error ||+ self.ptr->symbol == ts_builtin_sym_error_repeat+ ) {+ self.ptr->error_cost +=+ ERROR_COST_PER_RECOVERY ++ ERROR_COST_PER_SKIPPED_CHAR * self.ptr->size.bytes ++ ERROR_COST_PER_SKIPPED_LINE * self.ptr->size.extent.row;+ }++ if (self.ptr->child_count > 0) {+ Subtree first_child = children[0];+ Subtree last_child = children[self.ptr->child_count - 1];++ self.ptr->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);+ self.ptr->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);++ if (ts_subtree_fragile_left(first_child)) self.ptr->fragile_left = true;+ if (ts_subtree_fragile_right(last_child)) self.ptr->fragile_right = true;++ if (+ self.ptr->child_count >= 2 &&+ !self.ptr->visible &&+ !self.ptr->named &&+ ts_subtree_symbol(first_child) == self.ptr->symbol+ ) {+ if (ts_subtree_repeat_depth(first_child) > ts_subtree_repeat_depth(last_child)) {+ self.ptr->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;+ } else {+ self.ptr->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;+ }+ }+ }+}++// Create a new parent node with the given children.+//+// This takes ownership of the children array.+MutableSubtree ts_subtree_new_node(+ TSSymbol symbol,+ SubtreeArray *children,+ unsigned production_id,+ const TSLanguage *language+) {+ TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);+ bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;++ // Allocate the node's data at the end of the array of children.+ size_t new_byte_size = ts_subtree_alloc_size(children->size);+ if (children->capacity * sizeof(Subtree) < new_byte_size) {+ children->contents = ts_realloc(children->contents, new_byte_size);+ children->capacity = (uint32_t)(new_byte_size / sizeof(Subtree));+ }+ SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];++ *data = (SubtreeHeapData) {+ .ref_count = 1,+ .symbol = symbol,+ .child_count = children->size,+ .visible = metadata.visible,+ .named = metadata.named,+ .has_changes = false,+ .has_external_scanner_state_change = false,+ .fragile_left = fragile,+ .fragile_right = fragile,+ .is_keyword = false,+ {{+ .visible_descendant_count = 0,+ .production_id = production_id,+ .first_leaf = {.symbol = 0, .parse_state = 0},+ }}+ };+ MutableSubtree result = {.ptr = data};+ ts_subtree_summarize_children(result, language);+ return result;+}++// Create a new error node containing the given children.+//+// This node is treated as 'extra'. Its children are prevented from having+// having any effect on the parse state.+Subtree ts_subtree_new_error_node(+ SubtreeArray *children,+ bool extra,+ const TSLanguage *language+) {+ MutableSubtree result = ts_subtree_new_node(+ ts_builtin_sym_error, children, 0, language+ );+ result.ptr->extra = extra;+ return ts_subtree_from_mut(result);+}++// Create a new 'missing leaf' node.+//+// This node is treated as 'extra'. Its children are prevented from having+// having any effect on the parse state.+Subtree ts_subtree_new_missing_leaf(+ SubtreePool *pool,+ TSSymbol symbol,+ Length padding,+ uint32_t lookahead_bytes,+ const TSLanguage *language+) {+ Subtree result = ts_subtree_new_leaf(+ pool, symbol, padding, length_zero(), lookahead_bytes,+ 0, false, false, false, language+ );+ if (result.data.is_inline) {+ result.data.is_missing = true;+ } else {+ ((SubtreeHeapData *)result.ptr)->is_missing = true;+ }+ return result;+}++void ts_subtree_retain(Subtree self) {+ if (self.data.is_inline) return;+ ts_assert(self.ptr->ref_count > 0);+ atomic_inc((volatile uint32_t *)&self.ptr->ref_count);+ ts_assert(self.ptr->ref_count != 0);+}++void ts_subtree_release(SubtreePool *pool, Subtree self) {+ if (self.data.is_inline) return;+ array_clear(&pool->tree_stack);++ ts_assert(self.ptr->ref_count > 0);+ if (atomic_dec((volatile uint32_t *)&self.ptr->ref_count) == 0) {+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(self));+ }++ while (pool->tree_stack.size > 0) {+ MutableSubtree tree = array_pop(&pool->tree_stack);+ if (tree.ptr->child_count > 0) {+ Subtree *children = ts_subtree_children(tree);+ for (uint32_t i = 0; i < tree.ptr->child_count; i++) {+ Subtree child = children[i];+ if (child.data.is_inline) continue;+ ts_assert(child.ptr->ref_count > 0);+ if (atomic_dec((volatile uint32_t *)&child.ptr->ref_count) == 0) {+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(child));+ }+ }+ ts_free(children);+ } else {+ if (tree.ptr->has_external_tokens) {+ ts_external_scanner_state_delete(&tree.ptr->external_scanner_state);+ }+ ts_subtree_pool_free(pool, tree.ptr);+ }+ }+}++int ts_subtree_compare(Subtree left, Subtree right, SubtreePool *pool) {+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(left));+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(right));++ while (pool->tree_stack.size > 0) {+ right = ts_subtree_from_mut(array_pop(&pool->tree_stack));+ left = ts_subtree_from_mut(array_pop(&pool->tree_stack));++ int result = 0;+ if (ts_subtree_symbol(left) < ts_subtree_symbol(right)) result = -1;+ else if (ts_subtree_symbol(right) < ts_subtree_symbol(left)) result = 1;+ else if (ts_subtree_child_count(left) < ts_subtree_child_count(right)) result = -1;+ else if (ts_subtree_child_count(right) < ts_subtree_child_count(left)) result = 1;+ if (result != 0) {+ array_clear(&pool->tree_stack);+ return result;+ }++ for (uint32_t i = ts_subtree_child_count(left); i > 0; i--) {+ Subtree left_child = ts_subtree_children(left)[i - 1];+ Subtree right_child = ts_subtree_children(right)[i - 1];+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(left_child));+ array_push(&pool->tree_stack, ts_subtree_to_mut_unsafe(right_child));+ }+ }++ return 0;+}++static inline void ts_subtree_set_has_changes(MutableSubtree *self) {+ if (self->data.is_inline) {+ self->data.has_changes = true;+ } else {+ self->ptr->has_changes = true;+ }+}++Subtree ts_subtree_edit(Subtree self, const TSInputEdit *input_edit, SubtreePool *pool) {+ typedef struct {+ Subtree *tree;+ Edit edit;+ } EditEntry;++ Array(EditEntry) stack = array_new();+ array_push(&stack, ((EditEntry) {+ .tree = &self,+ .edit = (Edit) {+ .start = {input_edit->start_byte, input_edit->start_point},+ .old_end = {input_edit->old_end_byte, input_edit->old_end_point},+ .new_end = {input_edit->new_end_byte, input_edit->new_end_point},+ },+ }));++ while (stack.size) {+ EditEntry entry = array_pop(&stack);+ Edit edit = entry.edit;+ bool is_noop = edit.old_end.bytes == edit.start.bytes && edit.new_end.bytes == edit.start.bytes;+ bool is_pure_insertion = edit.old_end.bytes == edit.start.bytes;+ bool parent_depends_on_column = ts_subtree_depends_on_column(*entry.tree);+ bool column_shifted = edit.new_end.extent.column != edit.old_end.extent.column;++ Length size = ts_subtree_size(*entry.tree);+ Length padding = ts_subtree_padding(*entry.tree);+ Length total_size = length_add(padding, size);+ uint32_t lookahead_bytes = ts_subtree_lookahead_bytes(*entry.tree);+ uint32_t end_byte = total_size.bytes + lookahead_bytes;+ if (edit.start.bytes > end_byte || (is_noop && edit.start.bytes == end_byte)) continue;++ // If the edit is entirely within the space before this subtree, then shift this+ // subtree over according to the edit without changing its size.+ if (edit.old_end.bytes <= padding.bytes) {+ padding = length_add(edit.new_end, length_sub(padding, edit.old_end));+ }++ // If the edit starts in the space before this subtree and extends into this subtree,+ // shrink the subtree's content to compensate for the change in the space before it.+ else if (edit.start.bytes < padding.bytes) {+ size = length_saturating_sub(size, length_sub(edit.old_end, padding));+ padding = edit.new_end;+ }++ // If the edit is a pure insertion right at the start of the subtree,+ // shift the subtree over according to the insertion.+ else if (edit.start.bytes == padding.bytes && is_pure_insertion) {+ padding = edit.new_end;+ }++ // If the edit is within this subtree, resize the subtree to reflect the edit.+ else if (+ edit.start.bytes < total_size.bytes ||+ (edit.start.bytes == total_size.bytes && is_pure_insertion)+ ) {+ size = length_add(+ length_sub(edit.new_end, padding),+ length_saturating_sub(total_size, edit.old_end)+ );+ }++ MutableSubtree result = ts_subtree_make_mut(pool, *entry.tree);++ if (result.data.is_inline) {+ if (ts_subtree_can_inline(padding, size, lookahead_bytes)) {+ result.data.padding_bytes = padding.bytes;+ result.data.padding_rows = padding.extent.row;+ result.data.padding_columns = padding.extent.column;+ result.data.size_bytes = size.bytes;+ } else {+ SubtreeHeapData *data = ts_subtree_pool_allocate(pool);+ data->ref_count = 1;+ data->padding = padding;+ data->size = size;+ data->lookahead_bytes = lookahead_bytes;+ data->error_cost = 0;+ data->child_count = 0;+ data->symbol = result.data.symbol;+ data->parse_state = result.data.parse_state;+ data->visible = result.data.visible;+ data->named = result.data.named;+ data->extra = result.data.extra;+ data->fragile_left = false;+ data->fragile_right = false;+ data->has_changes = false;+ data->has_external_tokens = false;+ data->depends_on_column = false;+ data->is_missing = result.data.is_missing;+ data->is_keyword = result.data.is_keyword;+ result.ptr = data;+ }+ } else {+ result.ptr->padding = padding;+ result.ptr->size = size;+ }++ ts_subtree_set_has_changes(&result);+ *entry.tree = ts_subtree_from_mut(result);++ Length child_left, child_right = length_zero();+ for (uint32_t i = 0, n = ts_subtree_child_count(*entry.tree); i < n; i++) {+ Subtree *child = &ts_subtree_children(*entry.tree)[i];+ Length child_size = ts_subtree_total_size(*child);+ child_left = child_right;+ child_right = length_add(child_left, child_size);++ // If this child ends before the edit, it is not affected.+ if (child_right.bytes + ts_subtree_lookahead_bytes(*child) < edit.start.bytes) continue;++ // Keep editing child nodes until a node is reached that starts after the edit.+ // Also, if this node's validity depends on its column position, then continue+ // invaliditing child nodes until reaching a line break.+ if ((+ (child_left.bytes > edit.old_end.bytes) ||+ (child_left.bytes == edit.old_end.bytes && child_size.bytes > 0 && i > 0)+ ) && (+ !parent_depends_on_column ||+ child_left.extent.row > padding.extent.row+ ) && (+ !ts_subtree_depends_on_column(*child) ||+ !column_shifted ||+ child_left.extent.row > edit.old_end.extent.row+ )) {+ break;+ }++ // Transform edit into the child's coordinate space.+ Edit child_edit = {+ .start = length_saturating_sub(edit.start, child_left),+ .old_end = length_saturating_sub(edit.old_end, child_left),+ .new_end = length_saturating_sub(edit.new_end, child_left),+ };++ // Interpret all inserted text as applying to the *first* child that touches the edit.+ // Subsequent children are only never have any text inserted into them; they are only+ // shrunk to compensate for the edit.+ if (+ child_right.bytes > edit.start.bytes ||+ (child_right.bytes == edit.start.bytes && is_pure_insertion)+ ) {+ edit.new_end = edit.start;+ }++ // Children that occur before the edit are not reshaped by the edit.+ else {+ child_edit.old_end = child_edit.start;+ child_edit.new_end = child_edit.start;+ }++ // Queue processing of this child's subtree.+ array_push(&stack, ((EditEntry) {+ .tree = child,+ .edit = child_edit,+ }));+ }+ }++ array_delete(&stack);+ return self;+}++Subtree ts_subtree_last_external_token(Subtree tree) {+ if (!ts_subtree_has_external_tokens(tree)) return NULL_SUBTREE;+ while (tree.ptr->child_count > 0) {+ for (uint32_t i = tree.ptr->child_count - 1; i + 1 > 0; i--) {+ Subtree child = ts_subtree_children(tree)[i];+ if (ts_subtree_has_external_tokens(child)) {+ tree = child;+ break;+ }+ }+ }+ return tree;+}++static size_t ts_subtree__write_char_to_string(char *str, size_t n, int32_t chr) {+ if (chr == -1)+ return snprintf(str, n, "INVALID");+ else if (chr == '\0')+ return snprintf(str, n, "'\\0'");+ else if (chr == '\n')+ return snprintf(str, n, "'\\n'");+ else if (chr == '\t')+ return snprintf(str, n, "'\\t'");+ else if (chr == '\r')+ return snprintf(str, n, "'\\r'");+ else if (0 < chr && chr < 128 && isprint(chr))+ return snprintf(str, n, "'%c'", chr);+ else+ return snprintf(str, n, "%d", chr);+}++static const char *const ROOT_FIELD = "__ROOT__";++static size_t ts_subtree__write_to_string(+ Subtree self, char *string, size_t limit,+ const TSLanguage *language, bool include_all,+ TSSymbol alias_symbol, bool alias_is_named, const char *field_name+) {+ if (!self.ptr) return snprintf(string, limit, "(NULL)");++ char *cursor = string;+ char **writer = (limit > 1) ? &cursor : &string;+ bool is_root = field_name == ROOT_FIELD;+ bool is_visible =+ include_all ||+ ts_subtree_missing(self) ||+ (+ alias_symbol+ ? alias_is_named+ : ts_subtree_visible(self) && ts_subtree_named(self)+ );++ if (is_visible) {+ if (!is_root) {+ cursor += snprintf(*writer, limit, " ");+ if (field_name) {+ cursor += snprintf(*writer, limit, "%s: ", field_name);+ }+ }++ if (ts_subtree_is_error(self) && ts_subtree_child_count(self) == 0 && self.ptr->size.bytes > 0) {+ cursor += snprintf(*writer, limit, "(UNEXPECTED ");+ cursor += ts_subtree__write_char_to_string(*writer, limit, self.ptr->lookahead_char);+ } else {+ TSSymbol symbol = alias_symbol ? alias_symbol : ts_subtree_symbol(self);+ const char *symbol_name = ts_language_symbol_name(language, symbol);+ if (ts_subtree_missing(self)) {+ cursor += snprintf(*writer, limit, "(MISSING ");+ if (alias_is_named || ts_subtree_named(self)) {+ cursor += snprintf(*writer, limit, "%s", symbol_name);+ } else {+ cursor += snprintf(*writer, limit, "\"%s\"", symbol_name);+ }+ } else {+ cursor += snprintf(*writer, limit, "(%s", symbol_name);+ }+ }+ } else if (is_root) {+ TSSymbol symbol = alias_symbol ? alias_symbol : ts_subtree_symbol(self);+ const char *symbol_name = ts_language_symbol_name(language, symbol);+ if (ts_subtree_child_count(self) > 0) {+ cursor += snprintf(*writer, limit, "(%s", symbol_name);+ } else if (ts_subtree_named(self)) {+ cursor += snprintf(*writer, limit, "(%s)", symbol_name);+ } else {+ cursor += snprintf(*writer, limit, "(\"%s\")", symbol_name);+ }+ }++ if (ts_subtree_child_count(self)) {+ const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self.ptr->production_id);+ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(+ language,+ self.ptr->production_id,+ &field_map,+ &field_map_end+ );++ uint32_t structural_child_index = 0;+ for (uint32_t i = 0; i < self.ptr->child_count; i++) {+ Subtree child = ts_subtree_children(self)[i];+ if (ts_subtree_extra(child)) {+ cursor += ts_subtree__write_to_string(+ child, *writer, limit,+ language, include_all,+ 0, false, NULL+ );+ } else {+ TSSymbol subtree_alias_symbol = alias_sequence+ ? alias_sequence[structural_child_index]+ : 0;+ bool subtree_alias_is_named = subtree_alias_symbol+ ? ts_language_symbol_metadata(language, subtree_alias_symbol).named+ : false;++ const char *child_field_name = is_visible ? NULL : field_name;+ for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {+ if (!map->inherited && map->child_index == structural_child_index) {+ child_field_name = language->field_names[map->field_id];+ break;+ }+ }++ cursor += ts_subtree__write_to_string(+ child, *writer, limit,+ language, include_all,+ subtree_alias_symbol, subtree_alias_is_named, child_field_name+ );+ structural_child_index++;+ }+ }+ }++ if (is_visible) cursor += snprintf(*writer, limit, ")");++ return cursor - string;+}++char *ts_subtree_string(+ Subtree self,+ TSSymbol alias_symbol,+ bool alias_is_named,+ const TSLanguage *language,+ bool include_all+) {+ char scratch_string[1];+ size_t size = ts_subtree__write_to_string(+ self, scratch_string, 1,+ language, include_all,+ alias_symbol, alias_is_named, ROOT_FIELD+ ) + 1;+ char *result = ts_malloc(size * sizeof(char));+ ts_subtree__write_to_string(+ self, result, size,+ language, include_all,+ alias_symbol, alias_is_named, ROOT_FIELD+ );+ return result;+}++void ts_subtree__print_dot_graph(const Subtree *self, uint32_t start_offset,+ const TSLanguage *language, TSSymbol alias_symbol,+ FILE *f) {+ TSSymbol subtree_symbol = ts_subtree_symbol(*self);+ TSSymbol symbol = alias_symbol ? alias_symbol : subtree_symbol;+ uint32_t end_offset = start_offset + ts_subtree_total_bytes(*self);+ fprintf(f, "tree_%p [label=\"", (void *)self);+ ts_language_write_symbol_as_dot_string(language, f, symbol);+ fprintf(f, "\"");++ if (ts_subtree_child_count(*self) == 0) fprintf(f, ", shape=plaintext");+ if (ts_subtree_extra(*self)) fprintf(f, ", fontcolor=gray");++ fprintf(f, ", tooltip=\""+ "range: %u - %u\n"+ "state: %d\n"+ "error-cost: %u\n"+ "has-changes: %u\n"+ "depends-on-column: %u\n"+ "descendant-count: %u\n"+ "repeat-depth: %u\n"+ "lookahead-bytes: %u",+ start_offset, end_offset,+ ts_subtree_parse_state(*self),+ ts_subtree_error_cost(*self),+ ts_subtree_has_changes(*self),+ ts_subtree_depends_on_column(*self),+ ts_subtree_visible_descendant_count(*self),+ ts_subtree_repeat_depth(*self),+ ts_subtree_lookahead_bytes(*self)+ );++ if (ts_subtree_is_error(*self) && ts_subtree_child_count(*self) == 0 && self->ptr->lookahead_char != 0) {+ fprintf(f, "\ncharacter: '%c'", self->ptr->lookahead_char);+ }++ fprintf(f, "\"]\n");++ uint32_t child_start_offset = start_offset;+ uint32_t child_info_offset =+ language->max_alias_sequence_length *+ ts_subtree_production_id(*self);+ for (uint32_t i = 0, n = ts_subtree_child_count(*self); i < n; i++) {+ const Subtree *child = &ts_subtree_children(*self)[i];+ TSSymbol subtree_alias_symbol = 0;+ if (!ts_subtree_extra(*child) && child_info_offset) {+ subtree_alias_symbol = language->alias_sequences[child_info_offset];+ child_info_offset++;+ }+ ts_subtree__print_dot_graph(child, child_start_offset, language, subtree_alias_symbol, f);+ fprintf(f, "tree_%p -> tree_%p [tooltip=%u]\n", (void *)self, (void *)child, i);+ child_start_offset += ts_subtree_total_bytes(*child);+ }+}++void ts_subtree_print_dot_graph(Subtree self, const TSLanguage *language, FILE *f) {+ fprintf(f, "digraph tree {\n");+ fprintf(f, "edge [arrowhead=none]\n");+ ts_subtree__print_dot_graph(&self, 0, language, 0, f);+ fprintf(f, "}\n");+}++const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self) {+ static const ExternalScannerState empty_state = {{.short_data = {0}}, .length = 0};+ if (+ self.ptr &&+ !self.data.is_inline &&+ self.ptr->has_external_tokens &&+ self.ptr->child_count == 0+ ) {+ return &self.ptr->external_scanner_state;+ } else {+ return &empty_state;+ }+}++bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other) {+ const ExternalScannerState *state_self = ts_subtree_external_scanner_state(self);+ const ExternalScannerState *state_other = ts_subtree_external_scanner_state(other);+ return ts_external_scanner_state_eq(+ state_self,+ ts_external_scanner_state_data(state_other),+ state_other->length+ );+}
+ vendor/tree-sitter/lib/src/subtree.h view
@@ -0,0 +1,382 @@+#ifndef TREE_SITTER_SUBTREE_H_+#define TREE_SITTER_SUBTREE_H_++#ifdef __cplusplus+extern "C" {+#endif++#include <limits.h>+#include <stdbool.h>+#include <stdio.h>+#include "./length.h"+#include "./array.h"+#include "./error_costs.h"+#include "./host.h"+#include "tree_sitter/api.h"+#include "./parser.h"++#define TS_TREE_STATE_NONE USHRT_MAX+#define NULL_SUBTREE ((Subtree) {.ptr = NULL})++// The serialized state of an external scanner.+//+// Every time an external token subtree is created after a call to an+// external scanner, the scanner's `serialize` function is called to+// retrieve a serialized copy of its state. The bytes are then copied+// onto the subtree itself so that the scanner's state can later be+// restored using its `deserialize` function.+//+// Small byte arrays are stored inline, and long ones are allocated+// separately on the heap.+typedef struct {+ union {+ char *long_data;+ char short_data[24];+ };+ uint32_t length;+} ExternalScannerState;++// A compact representation of a subtree.+//+// This representation is used for small leaf nodes that are not+// errors, and were not created by an external scanner.+//+// The idea behind the layout of this struct is that the `is_inline`+// bit will fall exactly into the same location as the least significant+// bit of the pointer in `Subtree` or `MutableSubtree`, respectively.+// Because of alignment, for any valid pointer this will be 0, giving+// us the opportunity to make use of this bit to signify whether to use+// the pointer or the inline struct.+typedef struct SubtreeInlineData SubtreeInlineData;++#define SUBTREE_BITS \+ bool visible : 1; \+ bool named : 1; \+ bool extra : 1; \+ bool has_changes : 1; \+ bool is_missing : 1; \+ bool is_keyword : 1;++#define SUBTREE_SIZE \+ uint8_t padding_columns; \+ uint8_t padding_rows : 4; \+ uint8_t lookahead_bytes : 4; \+ uint8_t padding_bytes; \+ uint8_t size_bytes;++#if TS_BIG_ENDIAN+#if TS_PTR_SIZE == 32++struct SubtreeInlineData {+ uint16_t parse_state;+ uint8_t symbol;+ SUBTREE_BITS+ bool unused : 1;+ bool is_inline : 1;+ SUBTREE_SIZE+};++#else++struct SubtreeInlineData {+ SUBTREE_SIZE+ uint16_t parse_state;+ uint8_t symbol;+ SUBTREE_BITS+ bool unused : 1;+ bool is_inline : 1;+};++#endif+#else++struct SubtreeInlineData {+ bool is_inline : 1;+ SUBTREE_BITS+ uint8_t symbol;+ uint16_t parse_state;+ SUBTREE_SIZE+};++#endif++#undef SUBTREE_BITS+#undef SUBTREE_SIZE++// A heap-allocated representation of a subtree.+//+// This representation is used for parent nodes, external tokens,+// errors, and other leaf nodes whose data is too large to fit into+// the inline representation.+typedef struct {+ volatile uint32_t ref_count;+ Length padding;+ Length size;+ uint32_t lookahead_bytes;+ uint32_t error_cost;+ uint32_t child_count;+ TSSymbol symbol;+ TSStateId parse_state;++ bool visible : 1;+ bool named : 1;+ bool extra : 1;+ bool fragile_left : 1;+ bool fragile_right : 1;+ bool has_changes : 1;+ bool has_external_tokens : 1;+ bool has_external_scanner_state_change : 1;+ bool depends_on_column: 1;+ bool is_missing : 1;+ bool is_keyword : 1;++ union {+ // Non-terminal subtrees (`child_count > 0`)+ struct {+ uint32_t visible_child_count;+ uint32_t named_child_count;+ uint32_t visible_descendant_count;+ int32_t dynamic_precedence;+ uint16_t repeat_depth;+ uint16_t production_id;+ struct {+ TSSymbol symbol;+ TSStateId parse_state;+ } first_leaf;+ };++ // External terminal subtrees (`child_count == 0 && has_external_tokens`)+ ExternalScannerState external_scanner_state;++ // Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)+ int32_t lookahead_char;+ };+} SubtreeHeapData;++// The fundamental building block of a syntax tree.+typedef union {+ SubtreeInlineData data;+ const SubtreeHeapData *ptr;+} Subtree;++// Like Subtree, but mutable.+typedef union {+ SubtreeInlineData data;+ SubtreeHeapData *ptr;+} MutableSubtree;++typedef Array(Subtree) SubtreeArray;+typedef Array(MutableSubtree) MutableSubtreeArray;++typedef struct {+ MutableSubtreeArray free_trees;+ MutableSubtreeArray tree_stack;+} SubtreePool;++void ts_external_scanner_state_init(ExternalScannerState *, const char *, unsigned);+const char *ts_external_scanner_state_data(const ExternalScannerState *);+bool ts_external_scanner_state_eq(const ExternalScannerState *self, const char *, unsigned);+void ts_external_scanner_state_delete(ExternalScannerState *self);++void ts_subtree_array_copy(SubtreeArray, SubtreeArray *);+void ts_subtree_array_clear(SubtreePool *, SubtreeArray *);+void ts_subtree_array_delete(SubtreePool *, SubtreeArray *);+void ts_subtree_array_remove_trailing_extras(SubtreeArray *, SubtreeArray *);+void ts_subtree_array_reverse(SubtreeArray *);++SubtreePool ts_subtree_pool_new(uint32_t capacity);+void ts_subtree_pool_delete(SubtreePool *);++Subtree ts_subtree_new_leaf(+ SubtreePool *, TSSymbol, Length, Length, uint32_t,+ TSStateId, bool, bool, bool, const TSLanguage *+);+Subtree ts_subtree_new_error(+ SubtreePool *, int32_t, Length, Length, uint32_t, TSStateId, const TSLanguage *+);+MutableSubtree ts_subtree_new_node(TSSymbol, SubtreeArray *, unsigned, const TSLanguage *);+Subtree ts_subtree_new_error_node(SubtreeArray *, bool, const TSLanguage *);+Subtree ts_subtree_new_missing_leaf(SubtreePool *, TSSymbol, Length, uint32_t, const TSLanguage *);+MutableSubtree ts_subtree_make_mut(SubtreePool *, Subtree);+void ts_subtree_retain(Subtree);+void ts_subtree_release(SubtreePool *, Subtree);+int ts_subtree_compare(Subtree, Subtree, SubtreePool *);+void ts_subtree_set_symbol(MutableSubtree *, TSSymbol, const TSLanguage *);+void ts_subtree_summarize(MutableSubtree, const Subtree *, uint32_t, const TSLanguage *);+void ts_subtree_summarize_children(MutableSubtree, const TSLanguage *);+void ts_subtree_balance(Subtree, SubtreePool *, const TSLanguage *);+Subtree ts_subtree_edit(Subtree, const TSInputEdit *edit, SubtreePool *);+char *ts_subtree_string(Subtree, TSSymbol, bool, const TSLanguage *, bool include_all);+void ts_subtree_print_dot_graph(Subtree, const TSLanguage *, FILE *);+Subtree ts_subtree_last_external_token(Subtree);+const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self);+bool ts_subtree_external_scanner_state_eq(Subtree, Subtree);++#define SUBTREE_GET(self, name) ((self).data.is_inline ? (self).data.name : (self).ptr->name)++static inline TSSymbol ts_subtree_symbol(Subtree self) { return SUBTREE_GET(self, symbol); }+static inline bool ts_subtree_visible(Subtree self) { return SUBTREE_GET(self, visible); }+static inline bool ts_subtree_named(Subtree self) { return SUBTREE_GET(self, named); }+static inline bool ts_subtree_extra(Subtree self) { return SUBTREE_GET(self, extra); }+static inline bool ts_subtree_has_changes(Subtree self) { return SUBTREE_GET(self, has_changes); }+static inline bool ts_subtree_missing(Subtree self) { return SUBTREE_GET(self, is_missing); }+static inline bool ts_subtree_is_keyword(Subtree self) { return SUBTREE_GET(self, is_keyword); }+static inline TSStateId ts_subtree_parse_state(Subtree self) { return SUBTREE_GET(self, parse_state); }+static inline uint32_t ts_subtree_lookahead_bytes(Subtree self) { return SUBTREE_GET(self, lookahead_bytes); }++#undef SUBTREE_GET++// Get the size needed to store a heap-allocated subtree with the given+// number of children.+static inline size_t ts_subtree_alloc_size(uint32_t child_count) {+ return child_count * sizeof(Subtree) + sizeof(SubtreeHeapData);+}++// Get a subtree's children, which are allocated immediately before the+// tree's own heap data.+#define ts_subtree_children(self) \+ ((self).data.is_inline ? NULL : (Subtree *)((self).ptr) - (self).ptr->child_count)++static inline void ts_subtree_set_extra(MutableSubtree *self, bool is_extra) {+ if (self->data.is_inline) {+ self->data.extra = is_extra;+ } else {+ self->ptr->extra = is_extra;+ }+}++static inline TSSymbol ts_subtree_leaf_symbol(Subtree self) {+ if (self.data.is_inline) return self.data.symbol;+ if (self.ptr->child_count == 0) return self.ptr->symbol;+ return self.ptr->first_leaf.symbol;+}++static inline TSStateId ts_subtree_leaf_parse_state(Subtree self) {+ if (self.data.is_inline) return self.data.parse_state;+ if (self.ptr->child_count == 0) return self.ptr->parse_state;+ return self.ptr->first_leaf.parse_state;+}++static inline Length ts_subtree_padding(Subtree self) {+ if (self.data.is_inline) {+ Length result = {self.data.padding_bytes, {self.data.padding_rows, self.data.padding_columns}};+ return result;+ } else {+ return self.ptr->padding;+ }+}++static inline Length ts_subtree_size(Subtree self) {+ if (self.data.is_inline) {+ Length result = {self.data.size_bytes, {0, self.data.size_bytes}};+ return result;+ } else {+ return self.ptr->size;+ }+}++static inline Length ts_subtree_total_size(Subtree self) {+ return length_add(ts_subtree_padding(self), ts_subtree_size(self));+}++static inline uint32_t ts_subtree_total_bytes(Subtree self) {+ return ts_subtree_total_size(self).bytes;+}++static inline uint32_t ts_subtree_child_count(Subtree self) {+ return self.data.is_inline ? 0 : self.ptr->child_count;+}++static inline uint32_t ts_subtree_repeat_depth(Subtree self) {+ return self.data.is_inline ? 0 : self.ptr->repeat_depth;+}++static inline uint32_t ts_subtree_is_repetition(Subtree self) {+ return self.data.is_inline+ ? 0+ : !self.ptr->named && !self.ptr->visible && self.ptr->child_count != 0;+}++static inline uint32_t ts_subtree_visible_descendant_count(Subtree self) {+ return (self.data.is_inline || self.ptr->child_count == 0)+ ? 0+ : self.ptr->visible_descendant_count;+}++static inline uint32_t ts_subtree_visible_child_count(Subtree self) {+ if (ts_subtree_child_count(self) > 0) {+ return self.ptr->visible_child_count;+ } else {+ return 0;+ }+}++static inline uint32_t ts_subtree_error_cost(Subtree self) {+ if (ts_subtree_missing(self)) {+ return ERROR_COST_PER_MISSING_TREE + ERROR_COST_PER_RECOVERY;+ } else {+ return self.data.is_inline ? 0 : self.ptr->error_cost;+ }+}++static inline int32_t ts_subtree_dynamic_precedence(Subtree self) {+ return (self.data.is_inline || self.ptr->child_count == 0) ? 0 : self.ptr->dynamic_precedence;+}++static inline uint16_t ts_subtree_production_id(Subtree self) {+ if (ts_subtree_child_count(self) > 0) {+ return self.ptr->production_id;+ } else {+ return 0;+ }+}++static inline bool ts_subtree_fragile_left(Subtree self) {+ return self.data.is_inline ? false : self.ptr->fragile_left;+}++static inline bool ts_subtree_fragile_right(Subtree self) {+ return self.data.is_inline ? false : self.ptr->fragile_right;+}++static inline bool ts_subtree_has_external_tokens(Subtree self) {+ return self.data.is_inline ? false : self.ptr->has_external_tokens;+}++static inline bool ts_subtree_has_external_scanner_state_change(Subtree self) {+ return self.data.is_inline ? false : self.ptr->has_external_scanner_state_change;+}++static inline bool ts_subtree_depends_on_column(Subtree self) {+ return self.data.is_inline ? false : self.ptr->depends_on_column;+}++static inline bool ts_subtree_is_fragile(Subtree self) {+ return self.data.is_inline ? false : (self.ptr->fragile_left || self.ptr->fragile_right);+}++static inline bool ts_subtree_is_error(Subtree self) {+ return ts_subtree_symbol(self) == ts_builtin_sym_error;+}++static inline bool ts_subtree_is_eof(Subtree self) {+ return ts_subtree_symbol(self) == ts_builtin_sym_end;+}++static inline Subtree ts_subtree_from_mut(MutableSubtree self) {+ Subtree result;+ result.data = self.data;+ return result;+}++static inline MutableSubtree ts_subtree_to_mut_unsafe(Subtree self) {+ MutableSubtree result;+ result.data = self.data;+ return result;+}++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_SUBTREE_H_
+ vendor/tree-sitter/lib/src/tree.c view
@@ -0,0 +1,172 @@+#define _POSIX_C_SOURCE 200112L++#include "tree_sitter/api.h"+#include "./array.h"+#include "./get_changed_ranges.h"+#include "./length.h"+#include "./subtree.h"+#include "./tree_cursor.h"+#include "./tree.h"++TSTree *ts_tree_new(+ Subtree root, const TSLanguage *language,+ const TSRange *included_ranges, unsigned included_range_count+) {+ TSTree *result = ts_malloc(sizeof(TSTree));+ result->root = root;+ result->language = ts_language_copy(language);+ result->included_ranges = ts_calloc(included_range_count, sizeof(TSRange));+ memcpy(result->included_ranges, included_ranges, included_range_count * sizeof(TSRange));+ result->included_range_count = included_range_count;+ return result;+}++TSTree *ts_tree_copy(const TSTree *self) {+ ts_subtree_retain(self->root);+ return ts_tree_new(self->root, self->language, self->included_ranges, self->included_range_count);+}++void ts_tree_delete(TSTree *self) {+ if (!self) return;++ SubtreePool pool = ts_subtree_pool_new(0);+ ts_subtree_release(&pool, self->root);+ ts_subtree_pool_delete(&pool);+ ts_language_delete(self->language);+ ts_free(self->included_ranges);+ ts_free(self);+}++TSNode ts_tree_root_node(const TSTree *self) {+ return ts_node_new(self, &self->root, ts_subtree_padding(self->root), 0);+}++TSNode ts_tree_root_node_with_offset(+ const TSTree *self,+ uint32_t offset_bytes,+ TSPoint offset_extent+) {+ Length offset = {offset_bytes, offset_extent};+ return ts_node_new(self, &self->root, length_add(offset, ts_subtree_padding(self->root)), 0);+}++const TSLanguage *ts_tree_language(const TSTree *self) {+ return self->language;+}++void ts_tree_edit(TSTree *self, const TSInputEdit *edit) {+ for (unsigned i = 0; i < self->included_range_count; i++) {+ TSRange *range = &self->included_ranges[i];+ if (range->end_byte >= edit->old_end_byte) {+ if (range->end_byte != UINT32_MAX) {+ range->end_byte = edit->new_end_byte + (range->end_byte - edit->old_end_byte);+ range->end_point = point_add(+ edit->new_end_point,+ point_sub(range->end_point, edit->old_end_point)+ );+ if (range->end_byte < edit->new_end_byte) {+ range->end_byte = UINT32_MAX;+ range->end_point = POINT_MAX;+ }+ }+ } else if (range->end_byte > edit->start_byte) {+ range->end_byte = edit->start_byte;+ range->end_point = edit->start_point;+ }+ if (range->start_byte >= edit->old_end_byte) {+ range->start_byte = edit->new_end_byte + (range->start_byte - edit->old_end_byte);+ range->start_point = point_add(+ edit->new_end_point,+ point_sub(range->start_point, edit->old_end_point)+ );+ if (range->start_byte < edit->new_end_byte) {+ range->start_byte = UINT32_MAX;+ range->start_point = POINT_MAX;+ }+ } else if (range->start_byte > edit->start_byte) {+ range->start_byte = edit->start_byte;+ range->start_point = edit->start_point;+ }+ }++ SubtreePool pool = ts_subtree_pool_new(0);+ self->root = ts_subtree_edit(self->root, edit, &pool);+ ts_subtree_pool_delete(&pool);+}++TSRange *ts_tree_included_ranges(const TSTree *self, uint32_t *length) {+ *length = self->included_range_count;+ TSRange *ranges = ts_calloc(self->included_range_count, sizeof(TSRange));+ memcpy(ranges, self->included_ranges, self->included_range_count * sizeof(TSRange));+ return ranges;+}++TSRange *ts_tree_get_changed_ranges(const TSTree *old_tree, const TSTree *new_tree, uint32_t *length) {+ TreeCursor cursor1 = {NULL, array_new(), 0};+ TreeCursor cursor2 = {NULL, array_new(), 0};+ ts_tree_cursor_init(&cursor1, ts_tree_root_node(old_tree));+ ts_tree_cursor_init(&cursor2, ts_tree_root_node(new_tree));++ TSRangeArray included_range_differences = array_new();+ ts_range_array_get_changed_ranges(+ old_tree->included_ranges, old_tree->included_range_count,+ new_tree->included_ranges, new_tree->included_range_count,+ &included_range_differences+ );++ TSRange *result;+ *length = ts_subtree_get_changed_ranges(+ &old_tree->root, &new_tree->root, &cursor1, &cursor2,+ old_tree->language, &included_range_differences, &result+ );++ array_delete(&included_range_differences);+ array_delete(&cursor1.stack);+ array_delete(&cursor2.stack);+ return result;+}++#ifdef _WIN32++#include <io.h>+#include <windows.h>++int _ts_dup(HANDLE handle) {+ HANDLE dup_handle;+ if (!DuplicateHandle(+ GetCurrentProcess(), handle,+ GetCurrentProcess(), &dup_handle,+ 0, FALSE, DUPLICATE_SAME_ACCESS+ )) return -1;++ return _open_osfhandle((intptr_t)dup_handle, 0);+}++void ts_tree_print_dot_graph(const TSTree *self, int fd) {+ FILE *file = _fdopen(_ts_dup((HANDLE)_get_osfhandle(fd)), "a");+ ts_subtree_print_dot_graph(self->root, self->language, file);+ fclose(file);+}++#elif !defined(__wasi__) // WASI doesn't support dup++#include <unistd.h>++int _ts_dup(int file_descriptor) {+ return dup(file_descriptor);+}++void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) {+ FILE *file = fdopen(_ts_dup(file_descriptor), "a");+ ts_subtree_print_dot_graph(self->root, self->language, file);+ fclose(file);+}++#else++void ts_tree_print_dot_graph(const TSTree *self, int file_descriptor) {+ (void)self;+ (void)file_descriptor;+}++#endif
+ vendor/tree-sitter/lib/src/tree.h view
@@ -0,0 +1,31 @@+#ifndef TREE_SITTER_TREE_H_+#define TREE_SITTER_TREE_H_++#include "./subtree.h"++#ifdef __cplusplus+extern "C" {+#endif++typedef struct {+ const Subtree *child;+ const Subtree *parent;+ Length position;+ TSSymbol alias_symbol;+} ParentCacheEntry;++struct TSTree {+ Subtree root;+ const TSLanguage *language;+ TSRange *included_ranges;+ unsigned included_range_count;+};++TSTree *ts_tree_new(Subtree root, const TSLanguage *language, const TSRange *included_ranges, unsigned included_range_count);+TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias);++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_TREE_H_
+ vendor/tree-sitter/lib/src/tree_cursor.c view
@@ -0,0 +1,715 @@+#include "tree_sitter/api.h"+#include "./alloc.h"+#include "./tree_cursor.h"+#include "./language.h"+#include "./tree.h"++typedef struct {+ Subtree parent;+ const TSTree *tree;+ Length position;+ uint32_t child_index;+ uint32_t structural_child_index;+ uint32_t descendant_index;+ const TSSymbol *alias_sequence;+} CursorChildIterator;++// CursorChildIterator++static inline bool ts_tree_cursor_is_entry_visible(const TreeCursor *self, uint32_t index) {+ TreeCursorEntry *entry = &self->stack.contents[index];+ if (index == 0 || ts_subtree_visible(*entry->subtree)) {+ return true;+ } else if (!ts_subtree_extra(*entry->subtree)) {+ TreeCursorEntry *parent_entry = &self->stack.contents[index - 1];+ return ts_language_alias_at(+ self->tree->language,+ parent_entry->subtree->ptr->production_id,+ entry->structural_child_index+ );+ } else {+ return false;+ }+}++static inline CursorChildIterator ts_tree_cursor_iterate_children(const TreeCursor *self) {+ TreeCursorEntry *last_entry = array_back(&self->stack);+ if (ts_subtree_child_count(*last_entry->subtree) == 0) {+ return (CursorChildIterator) {NULL_SUBTREE, self->tree, length_zero(), 0, 0, 0, NULL};+ }+ const TSSymbol *alias_sequence = ts_language_alias_sequence(+ self->tree->language,+ last_entry->subtree->ptr->production_id+ );++ uint32_t descendant_index = last_entry->descendant_index;+ if (ts_tree_cursor_is_entry_visible(self, self->stack.size - 1)) {+ descendant_index += 1;+ }++ return (CursorChildIterator) {+ .tree = self->tree,+ .parent = *last_entry->subtree,+ .position = last_entry->position,+ .child_index = 0,+ .structural_child_index = 0,+ .descendant_index = descendant_index,+ .alias_sequence = alias_sequence,+ };+}++static inline bool ts_tree_cursor_child_iterator_next(+ CursorChildIterator *self,+ TreeCursorEntry *result,+ bool *visible+) {+ if (!self->parent.ptr || self->child_index == self->parent.ptr->child_count) return false;+ const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];+ *result = (TreeCursorEntry) {+ .subtree = child,+ .position = self->position,+ .child_index = self->child_index,+ .structural_child_index = self->structural_child_index,+ .descendant_index = self->descendant_index,+ };+ *visible = ts_subtree_visible(*child);+ bool extra = ts_subtree_extra(*child);+ if (!extra) {+ if (self->alias_sequence) {+ *visible |= self->alias_sequence[self->structural_child_index];+ }+ self->structural_child_index++;+ }++ self->descendant_index += ts_subtree_visible_descendant_count(*child);+ if (*visible) {+ self->descendant_index += 1;+ }++ self->position = length_add(self->position, ts_subtree_size(*child));+ self->child_index++;++ if (self->child_index < self->parent.ptr->child_count) {+ Subtree next_child = ts_subtree_children(self->parent)[self->child_index];+ self->position = length_add(self->position, ts_subtree_padding(next_child));+ }++ return true;+}++// Return a position that, when `b` is added to it, yields `a`. This+// can only be computed if `b` has zero rows. Otherwise, this function+// returns `LENGTH_UNDEFINED`, and the caller needs to recompute+// the position some other way.+static inline Length length_backtrack(Length a, Length b) {+ if (length_is_undefined(a) || b.extent.row != 0) {+ return LENGTH_UNDEFINED;+ }++ Length result;+ result.bytes = a.bytes - b.bytes;+ result.extent.row = a.extent.row;+ result.extent.column = a.extent.column - b.extent.column;+ return result;+}++static inline bool ts_tree_cursor_child_iterator_previous(+ CursorChildIterator *self,+ TreeCursorEntry *result,+ bool *visible+) {+ // this is mostly a reverse `ts_tree_cursor_child_iterator_next` taking into+ // account unsigned underflow+ if (!self->parent.ptr || (int8_t)self->child_index == -1) return false;+ const Subtree *child = &ts_subtree_children(self->parent)[self->child_index];+ *result = (TreeCursorEntry) {+ .subtree = child,+ .position = self->position,+ .child_index = self->child_index,+ .structural_child_index = self->structural_child_index,+ };+ *visible = ts_subtree_visible(*child);+ bool extra = ts_subtree_extra(*child);+ if (!extra && self->alias_sequence) {+ *visible |= self->alias_sequence[self->structural_child_index];+ self->structural_child_index--;+ }++ self->position = length_backtrack(self->position, ts_subtree_padding(*child));+ self->child_index--;++ // unsigned can underflow so compare it to child_count+ if (self->child_index < self->parent.ptr->child_count) {+ Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];+ Length size = ts_subtree_size(previous_child);+ self->position = length_backtrack(self->position, size);+ }++ return true;+}++// TSTreeCursor - lifecycle++TSTreeCursor ts_tree_cursor_new(TSNode node) {+ TSTreeCursor self = {NULL, NULL, {0, 0, 0}};+ ts_tree_cursor_init((TreeCursor *)&self, node);+ return self;+}++void ts_tree_cursor_reset(TSTreeCursor *_self, TSNode node) {+ ts_tree_cursor_init((TreeCursor *)_self, node);+}++void ts_tree_cursor_init(TreeCursor *self, TSNode node) {+ self->tree = node.tree;+ self->root_alias_symbol = node.context[3];+ array_clear(&self->stack);+ array_push(&self->stack, ((TreeCursorEntry) {+ .subtree = (const Subtree *)node.id,+ .position = {+ ts_node_start_byte(node),+ ts_node_start_point(node)+ },+ .child_index = 0,+ .structural_child_index = 0,+ .descendant_index = 0,+ }));+}++void ts_tree_cursor_delete(TSTreeCursor *_self) {+ TreeCursor *self = (TreeCursor *)_self;+ array_delete(&self->stack);+}++// TSTreeCursor - walking the tree++TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self) {+ TreeCursor *self = (TreeCursor *)_self;+ bool visible;+ TreeCursorEntry entry;+ CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);+ while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {+ if (visible) {+ array_push(&self->stack, entry);+ return TreeCursorStepVisible;+ }+ if (ts_subtree_visible_child_count(*entry.subtree) > 0) {+ array_push(&self->stack, entry);+ return TreeCursorStepHidden;+ }+ }+ return TreeCursorStepNone;+}++bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) {+ for (;;) {+ switch (ts_tree_cursor_goto_first_child_internal(self)) {+ case TreeCursorStepHidden:+ continue;+ case TreeCursorStepVisible:+ return true;+ default:+ return false;+ }+ }+ return false;+}++TreeCursorStep ts_tree_cursor_goto_last_child_internal(TSTreeCursor *_self) {+ TreeCursor *self = (TreeCursor *)_self;+ bool visible;+ TreeCursorEntry entry;+ CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);+ if (!iterator.parent.ptr || iterator.parent.ptr->child_count == 0) return TreeCursorStepNone;++ TreeCursorEntry last_entry = {0};+ TreeCursorStep last_step = TreeCursorStepNone;+ while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {+ if (visible) {+ last_entry = entry;+ last_step = TreeCursorStepVisible;+ }+ else if (ts_subtree_visible_child_count(*entry.subtree) > 0) {+ last_entry = entry;+ last_step = TreeCursorStepHidden;+ }+ }+ if (last_entry.subtree) {+ array_push(&self->stack, last_entry);+ return last_step;+ }++ return TreeCursorStepNone;+}++bool ts_tree_cursor_goto_last_child(TSTreeCursor *self) {+ for (;;) {+ switch (ts_tree_cursor_goto_last_child_internal(self)) {+ case TreeCursorStepHidden:+ continue;+ case TreeCursorStepVisible:+ return true;+ default:+ return false;+ }+ }+ return false;+}++static inline int64_t ts_tree_cursor_goto_first_child_for_byte_and_point(+ TSTreeCursor *_self,+ uint32_t goal_byte,+ TSPoint goal_point+) {+ TreeCursor *self = (TreeCursor *)_self;+ uint32_t initial_size = self->stack.size;+ uint32_t visible_child_index = 0;++ bool did_descend;+ do {+ did_descend = false;++ bool visible;+ TreeCursorEntry entry;+ CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);+ while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {+ Length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));+ bool at_goal = entry_end.bytes > goal_byte && point_gt(entry_end.extent, goal_point);+ uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);+ if (at_goal) {+ if (visible) {+ array_push(&self->stack, entry);+ return visible_child_index;+ }+ if (visible_child_count > 0) {+ array_push(&self->stack, entry);+ did_descend = true;+ break;+ }+ } else if (visible) {+ visible_child_index++;+ } else {+ visible_child_index += visible_child_count;+ }+ }+ } while (did_descend);++ self->stack.size = initial_size;+ return -1;+}++int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) {+ return ts_tree_cursor_goto_first_child_for_byte_and_point(self, goal_byte, POINT_ZERO);+}++int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) {+ return ts_tree_cursor_goto_first_child_for_byte_and_point(self, 0, goal_point);+}++TreeCursorStep ts_tree_cursor_goto_sibling_internal(+ TSTreeCursor *_self,+ bool (*advance)(CursorChildIterator *, TreeCursorEntry *, bool *)) {+ TreeCursor *self = (TreeCursor *)_self;+ uint32_t initial_size = self->stack.size;++ while (self->stack.size > 1) {+ TreeCursorEntry entry = array_pop(&self->stack);+ CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);+ iterator.child_index = entry.child_index;+ iterator.structural_child_index = entry.structural_child_index;+ iterator.position = entry.position;+ iterator.descendant_index = entry.descendant_index;++ bool visible = false;+ advance(&iterator, &entry, &visible);+ if (visible && self->stack.size + 1 < initial_size) break;++ while (advance(&iterator, &entry, &visible)) {+ if (visible) {+ array_push(&self->stack, entry);+ return TreeCursorStepVisible;+ }++ if (ts_subtree_visible_child_count(*entry.subtree)) {+ array_push(&self->stack, entry);+ return TreeCursorStepHidden;+ }+ }+ }++ self->stack.size = initial_size;+ return TreeCursorStepNone;+}++TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self) {+ return ts_tree_cursor_goto_sibling_internal(_self, ts_tree_cursor_child_iterator_next);+}++bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {+ switch (ts_tree_cursor_goto_next_sibling_internal(self)) {+ case TreeCursorStepHidden:+ ts_tree_cursor_goto_first_child(self);+ return true;+ case TreeCursorStepVisible:+ return true;+ default:+ return false;+ }+}++TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(TSTreeCursor *_self) {+ // since subtracting across row loses column information, we may have to+ // restore it+ TreeCursor *self = (TreeCursor *)_self;++ // for that, save current position before traversing+ TreeCursorStep step = ts_tree_cursor_goto_sibling_internal(+ _self, ts_tree_cursor_child_iterator_previous);+ if (step == TreeCursorStepNone)+ return step;++ // if length is already valid, there's no need to recompute it+ if (!length_is_undefined(array_back(&self->stack)->position))+ return step;++ // restore position from the parent node+ const TreeCursorEntry *parent = &self->stack.contents[self->stack.size - 2];+ Length position = parent->position;+ uint32_t child_index = array_back(&self->stack)->child_index;+ const Subtree *children = ts_subtree_children((*(parent->subtree)));++ if (child_index > 0) {+ // skip first child padding since its position should match the position of the parent+ position = length_add(position, ts_subtree_size(children[0]));+ for (uint32_t i = 1; i < child_index; ++i) {+ position = length_add(position, ts_subtree_total_size(children[i]));+ }+ position = length_add(position, ts_subtree_padding(children[child_index]));+ }++ array_back(&self->stack)->position = position;++ return step;+}++bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *self) {+ switch (ts_tree_cursor_goto_previous_sibling_internal(self)) {+ case TreeCursorStepHidden:+ ts_tree_cursor_goto_last_child(self);+ return true;+ case TreeCursorStepVisible:+ return true;+ default:+ return false;+ }+}++bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {+ TreeCursor *self = (TreeCursor *)_self;+ for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) {+ if (ts_tree_cursor_is_entry_visible(self, i)) {+ self->stack.size = i + 1;+ return true;+ }+ }+ return false;+}++void ts_tree_cursor_goto_descendant(+ TSTreeCursor *_self,+ uint32_t goal_descendant_index+) {+ TreeCursor *self = (TreeCursor *)_self;++ // Ascend to the lowest ancestor that contains the goal node.+ for (;;) {+ uint32_t i = self->stack.size - 1;+ TreeCursorEntry *entry = &self->stack.contents[i];+ uint32_t next_descendant_index =+ entry->descendant_index ++ (ts_tree_cursor_is_entry_visible(self, i) ? 1 : 0) ++ ts_subtree_visible_descendant_count(*entry->subtree);+ if (+ (entry->descendant_index <= goal_descendant_index) &&+ (next_descendant_index > goal_descendant_index)+ ) {+ break;+ } else if (self->stack.size <= 1) {+ return;+ } else {+ self->stack.size--;+ }+ }++ // Descend to the goal node.+ bool did_descend = true;+ do {+ did_descend = false;+ bool visible;+ TreeCursorEntry entry;+ CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);+ if (iterator.descendant_index > goal_descendant_index) {+ return;+ }++ while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {+ if (iterator.descendant_index > goal_descendant_index) {+ array_push(&self->stack, entry);+ if (visible && entry.descendant_index == goal_descendant_index) {+ return;+ } else {+ did_descend = true;+ break;+ }+ }+ }+ } while (did_descend);+}++uint32_t ts_tree_cursor_current_descendant_index(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;+ TreeCursorEntry *last_entry = array_back(&self->stack);+ return last_entry->descendant_index;+}++TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;+ TreeCursorEntry *last_entry = array_back(&self->stack);+ bool is_extra = ts_subtree_extra(*last_entry->subtree);+ TSSymbol alias_symbol = is_extra ? 0 : self->root_alias_symbol;+ if (self->stack.size > 1 && !is_extra) {+ TreeCursorEntry *parent_entry = &self->stack.contents[self->stack.size - 2];+ alias_symbol = ts_language_alias_at(+ self->tree->language,+ parent_entry->subtree->ptr->production_id,+ last_entry->structural_child_index+ );+ }+ return ts_node_new(+ self->tree,+ last_entry->subtree,+ last_entry->position,+ alias_symbol+ );+}++// Private - Get various facts about the current node that are needed+// when executing tree queries.+void ts_tree_cursor_current_status(+ const TSTreeCursor *_self,+ TSFieldId *field_id,+ bool *has_later_siblings,+ bool *has_later_named_siblings,+ bool *can_have_later_siblings_with_this_field,+ TSSymbol *supertypes,+ unsigned *supertype_count+) {+ const TreeCursor *self = (const TreeCursor *)_self;+ unsigned max_supertypes = *supertype_count;+ *field_id = 0;+ *supertype_count = 0;+ *has_later_siblings = false;+ *has_later_named_siblings = false;+ *can_have_later_siblings_with_this_field = false;++ // Walk up the tree, visiting the current node and its invisible ancestors,+ // because fields can refer to nodes through invisible *wrapper* nodes,+ for (unsigned i = self->stack.size - 1; i > 0; i--) {+ TreeCursorEntry *entry = &self->stack.contents[i];+ TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];++ const TSSymbol *alias_sequence = ts_language_alias_sequence(+ self->tree->language,+ parent_entry->subtree->ptr->production_id+ );++ #define subtree_symbol(subtree, structural_child_index) \+ (( \+ !ts_subtree_extra(subtree) && \+ alias_sequence && \+ alias_sequence[structural_child_index] \+ ) ? \+ alias_sequence[structural_child_index] : \+ ts_subtree_symbol(subtree))++ // Stop walking up when a visible ancestor is found.+ TSSymbol entry_symbol = subtree_symbol(+ *entry->subtree,+ entry->structural_child_index+ );+ TSSymbolMetadata entry_metadata = ts_language_symbol_metadata(+ self->tree->language,+ entry_symbol+ );+ if (i != self->stack.size - 1 && entry_metadata.visible) break;++ // Record any supertypes+ if (entry_metadata.supertype && *supertype_count < max_supertypes) {+ supertypes[*supertype_count] = entry_symbol;+ (*supertype_count)++;+ }++ // Determine if the current node has later siblings.+ if (!*has_later_siblings) {+ unsigned sibling_count = parent_entry->subtree->ptr->child_count;+ unsigned structural_child_index = entry->structural_child_index;+ if (!ts_subtree_extra(*entry->subtree)) structural_child_index++;+ for (unsigned j = entry->child_index + 1; j < sibling_count; j++) {+ Subtree sibling = ts_subtree_children(*parent_entry->subtree)[j];+ TSSymbolMetadata sibling_metadata = ts_language_symbol_metadata(+ self->tree->language,+ subtree_symbol(sibling, structural_child_index)+ );+ if (sibling_metadata.visible) {+ *has_later_siblings = true;+ if (*has_later_named_siblings) break;+ if (sibling_metadata.named) {+ *has_later_named_siblings = true;+ break;+ }+ } else if (ts_subtree_visible_child_count(sibling) > 0) {+ *has_later_siblings = true;+ if (*has_later_named_siblings) break;+ if (sibling.ptr->named_child_count > 0) {+ *has_later_named_siblings = true;+ break;+ }+ }+ if (!ts_subtree_extra(sibling)) structural_child_index++;+ }+ }++ #undef subtree_symbol++ if (!ts_subtree_extra(*entry->subtree)) {+ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(+ self->tree->language,+ parent_entry->subtree->ptr->production_id,+ &field_map, &field_map_end+ );++ // Look for a field name associated with the current node.+ if (!*field_id) {+ for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {+ if (!map->inherited && map->child_index == entry->structural_child_index) {+ *field_id = map->field_id;+ break;+ }+ }+ }++ // Determine if the current node can have later siblings with the same field name.+ if (*field_id) {+ for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {+ if (+ map->field_id == *field_id &&+ map->child_index > entry->structural_child_index+ ) {+ *can_have_later_siblings_with_this_field = true;+ break;+ }+ }+ }+ }+ }+}++uint32_t ts_tree_cursor_current_depth(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;+ uint32_t depth = 0;+ for (unsigned i = 1; i < self->stack.size; i++) {+ if (ts_tree_cursor_is_entry_visible(self, i)) {+ depth++;+ }+ }+ return depth;+}++TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;+ for (int i = (int)self->stack.size - 2; i >= 0; i--) {+ TreeCursorEntry *entry = &self->stack.contents[i];+ bool is_visible = true;+ TSSymbol alias_symbol = 0;+ if (i > 0) {+ TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];+ alias_symbol = ts_language_alias_at(+ self->tree->language,+ parent_entry->subtree->ptr->production_id,+ entry->structural_child_index+ );+ is_visible = (alias_symbol != 0) || ts_subtree_visible(*entry->subtree);+ }+ if (is_visible) {+ return ts_node_new(+ self->tree,+ entry->subtree,+ entry->position,+ alias_symbol+ );+ }+ }+ return ts_node_new(NULL, NULL, length_zero(), 0);+}++TSFieldId ts_tree_cursor_current_field_id(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;++ // Walk up the tree, visiting the current node and its invisible ancestors.+ for (unsigned i = self->stack.size - 1; i > 0; i--) {+ TreeCursorEntry *entry = &self->stack.contents[i];+ TreeCursorEntry *parent_entry = &self->stack.contents[i - 1];++ // Stop walking up when another visible node is found.+ if (+ i != self->stack.size - 1 &&+ ts_tree_cursor_is_entry_visible(self, i)+ ) break;++ if (ts_subtree_extra(*entry->subtree)) break;++ const TSFieldMapEntry *field_map, *field_map_end;+ ts_language_field_map(+ self->tree->language,+ parent_entry->subtree->ptr->production_id,+ &field_map, &field_map_end+ );+ for (const TSFieldMapEntry *map = field_map; map < field_map_end; map++) {+ if (!map->inherited && map->child_index == entry->structural_child_index) {+ return map->field_id;+ }+ }+ }+ return 0;+}++const char *ts_tree_cursor_current_field_name(const TSTreeCursor *_self) {+ TSFieldId id = ts_tree_cursor_current_field_id(_self);+ if (id) {+ const TreeCursor *self = (const TreeCursor *)_self;+ return self->tree->language->field_names[id];+ } else {+ return NULL;+ }+}++TSTreeCursor ts_tree_cursor_copy(const TSTreeCursor *_cursor) {+ const TreeCursor *cursor = (const TreeCursor *)_cursor;+ TSTreeCursor res = {NULL, NULL, {0, 0}};+ TreeCursor *copy = (TreeCursor *)&res;+ copy->tree = cursor->tree;+ copy->root_alias_symbol = cursor->root_alias_symbol;+ array_init(©->stack);+ array_push_all(©->stack, &cursor->stack);+ return res;+}++void ts_tree_cursor_reset_to(TSTreeCursor *_dst, const TSTreeCursor *_src) {+ const TreeCursor *cursor = (const TreeCursor *)_src;+ TreeCursor *copy = (TreeCursor *)_dst;+ copy->tree = cursor->tree;+ copy->root_alias_symbol = cursor->root_alias_symbol;+ array_clear(©->stack);+ array_push_all(©->stack, &cursor->stack);+}
+ vendor/tree-sitter/lib/src/tree_cursor.h view
@@ -0,0 +1,48 @@+#ifndef TREE_SITTER_TREE_CURSOR_H_+#define TREE_SITTER_TREE_CURSOR_H_++#include "./subtree.h"++typedef struct {+ const Subtree *subtree;+ Length position;+ uint32_t child_index;+ uint32_t structural_child_index;+ uint32_t descendant_index;+} TreeCursorEntry;++typedef struct {+ const TSTree *tree;+ Array(TreeCursorEntry) stack;+ TSSymbol root_alias_symbol;+} TreeCursor;++typedef enum {+ TreeCursorStepNone,+ TreeCursorStepHidden,+ TreeCursorStepVisible,+} TreeCursorStep;++void ts_tree_cursor_init(TreeCursor *self, TSNode node);+void ts_tree_cursor_current_status(+ const TSTreeCursor *_self,+ TSFieldId *field_id,+ bool *has_later_siblings,+ bool *has_later_named_siblings,+ bool *can_have_later_siblings_with_this_field,+ TSSymbol *supertypes,+ unsigned *supertype_count+);++TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self);+TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self);++static inline Subtree ts_tree_cursor_current_subtree(const TSTreeCursor *_self) {+ const TreeCursor *self = (const TreeCursor *)_self;+ TreeCursorEntry *last_entry = array_back(&self->stack);+ return *last_entry->subtree;+}++TSNode ts_tree_cursor_parent_node(const TSTreeCursor *_self);++#endif // TREE_SITTER_TREE_CURSOR_H_
+ vendor/tree-sitter/lib/src/ts_assert.h view
@@ -0,0 +1,11 @@+#ifndef TREE_SITTER_ASSERT_H_+#define TREE_SITTER_ASSERT_H_++#ifdef NDEBUG+#define ts_assert(e) ((void)(e))+#else+#include <assert.h>+#define ts_assert(e) assert(e)+#endif++#endif // TREE_SITTER_ASSERT_H_
+ vendor/tree-sitter/lib/src/unicode.h view
@@ -0,0 +1,50 @@+#ifndef TREE_SITTER_UNICODE_H_+#define TREE_SITTER_UNICODE_H_++#ifdef __cplusplus+extern "C" {+#endif++#include <limits.h>+#include <stdint.h>++#define U_EXPORT+#define U_EXPORT2+#include "unicode/utf8.h"+#include "unicode/utf16.h"++static const int32_t TS_DECODE_ERROR = U_SENTINEL;++// These functions read one unicode code point from the given string,+// returning the number of bytes consumed.+typedef uint32_t (*UnicodeDecodeFunction)(+ const uint8_t *string,+ uint32_t length,+ int32_t *code_point+);++static inline uint32_t ts_decode_utf8(+ const uint8_t *string,+ uint32_t length,+ int32_t *code_point+) {+ uint32_t i = 0;+ U8_NEXT(string, i, length, *code_point);+ return i;+}++static inline uint32_t ts_decode_utf16(+ const uint8_t *string,+ uint32_t length,+ int32_t *code_point+) {+ uint32_t i = 0;+ U16_NEXT(((uint16_t *)string), i, length, *code_point);+ return i * 2;+}++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_UNICODE_H_
+ vendor/tree-sitter/lib/src/unicode/ptypes.h view
@@ -0,0 +1,1 @@+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
+ vendor/tree-sitter/lib/src/unicode/umachine.h view
@@ -0,0 +1,448 @@+// © 2016 and later: Unicode, Inc. and others.+// License & terms of use: http://www.unicode.org/copyright.html+/*+******************************************************************************+*+* Copyright (C) 1999-2015, International Business Machines+* Corporation and others. All Rights Reserved.+*+******************************************************************************+* file name: umachine.h+* encoding: UTF-8+* tab size: 8 (not used)+* indentation:4+*+* created on: 1999sep13+* created by: Markus W. Scherer+*+* This file defines basic types and constants for ICU to be+* platform-independent. umachine.h and utf.h are included into+* utypes.h to provide all the general definitions for ICU.+* All of these definitions used to be in utypes.h before+* the UTF-handling macros made this unmaintainable.+*/++#ifndef __UMACHINE_H__+#define __UMACHINE_H__+++/**+ * \file+ * \brief Basic types and constants for UTF+ *+ * <h2> Basic types and constants for UTF </h2>+ * This file defines basic types and constants for utf.h to be+ * platform-independent. umachine.h and utf.h are included into+ * utypes.h to provide all the general definitions for ICU.+ * All of these definitions used to be in utypes.h before+ * the UTF-handling macros made this unmaintainable.+ *+ */+/*==========================================================================*/+/* Include platform-dependent definitions */+/* which are contained in the platform-specific file platform.h */+/*==========================================================================*/++#include "unicode/ptypes.h" /* platform.h is included in ptypes.h */++/*+ * ANSI C headers:+ * stddef.h defines wchar_t+ */+#include <stddef.h>++/*==========================================================================*/+/* For C wrappers, we use the symbol U_STABLE. */+/* This works properly if the includer is C or C++. */+/* Functions are declared U_STABLE return-type U_EXPORT2 function-name()... */+/*==========================================================================*/++/**+ * \def U_CFUNC+ * This is used in a declaration of a library private ICU C function.+ * @stable ICU 2.4+ */++/**+ * \def U_CDECL_BEGIN+ * This is used to begin a declaration of a library private ICU C API.+ * @stable ICU 2.4+ */++/**+ * \def U_CDECL_END+ * This is used to end a declaration of a library private ICU C API+ * @stable ICU 2.4+ */++#ifdef __cplusplus+# define U_CFUNC extern "C"+# define U_CDECL_BEGIN extern "C" {+# define U_CDECL_END }+#else+# define U_CFUNC extern+# define U_CDECL_BEGIN+# define U_CDECL_END+#endif++#ifndef U_ATTRIBUTE_DEPRECATED+/**+ * \def U_ATTRIBUTE_DEPRECATED+ * This is used for GCC specific attributes+ * @internal+ */+#if U_GCC_MAJOR_MINOR >= 302+# define U_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated))+/**+ * \def U_ATTRIBUTE_DEPRECATED+ * This is used for Visual C++ specific attributes+ * @internal+ */+#elif defined(_MSC_VER) && (_MSC_VER >= 1400)+# define U_ATTRIBUTE_DEPRECATED __declspec(deprecated)+#else+# define U_ATTRIBUTE_DEPRECATED+#endif+#endif++/** This is used to declare a function as a public ICU C API @stable ICU 2.0*/+#define U_CAPI U_CFUNC U_EXPORT+/** This is used to declare a function as a stable public ICU C API*/+#define U_STABLE U_CAPI+/** This is used to declare a function as a draft public ICU C API */+#define U_DRAFT U_CAPI+/** This is used to declare a function as a deprecated public ICU C API */+#define U_DEPRECATED U_CAPI U_ATTRIBUTE_DEPRECATED+/** This is used to declare a function as an obsolete public ICU C API */+#define U_OBSOLETE U_CAPI+/** This is used to declare a function as an internal ICU C API */+#define U_INTERNAL U_CAPI++/**+ * \def U_OVERRIDE+ * Defined to the C++11 "override" keyword if available.+ * Denotes a class or member which is an override of the base class.+ * May result in an error if it applied to something not an override.+ * @internal+ */+#ifndef U_OVERRIDE+#define U_OVERRIDE override+#endif++/**+ * \def U_FINAL+ * Defined to the C++11 "final" keyword if available.+ * Denotes a class or member which may not be overridden in subclasses.+ * May result in an error if subclasses attempt to override.+ * @internal+ */+#if !defined(U_FINAL) || defined(U_IN_DOXYGEN)+#define U_FINAL final+#endif++// Before ICU 65, function-like, multi-statement ICU macros were just defined as+// series of statements wrapped in { } blocks and the caller could choose to+// either treat them as if they were actual functions and end the invocation+// with a trailing ; creating an empty statement after the block or else omit+// this trailing ; using the knowledge that the macro would expand to { }.+//+// But doing so doesn't work well with macros that look like functions and+// compiler warnings about empty statements (ICU-20601) and ICU 65 therefore+// switches to the standard solution of wrapping such macros in do { } while.+//+// This will however break existing code that depends on being able to invoke+// these macros without a trailing ; so to be able to remain compatible with+// such code the wrapper is itself defined as macros so that it's possible to+// build ICU 65 and later with the old macro behaviour, like this:+//+// CPPFLAGS='-DUPRV_BLOCK_MACRO_BEGIN="" -DUPRV_BLOCK_MACRO_END=""'+// runConfigureICU ...++/**+ * \def UPRV_BLOCK_MACRO_BEGIN+ * Defined as the "do" keyword by default.+ * @internal+ */+#ifndef UPRV_BLOCK_MACRO_BEGIN+#define UPRV_BLOCK_MACRO_BEGIN do+#endif++/**+ * \def UPRV_BLOCK_MACRO_END+ * Defined as "while (FALSE)" by default.+ * @internal+ */+#ifndef UPRV_BLOCK_MACRO_END+#define UPRV_BLOCK_MACRO_END while (FALSE)+#endif++/*==========================================================================*/+/* limits for int32_t etc., like in POSIX inttypes.h */+/*==========================================================================*/++#ifndef INT8_MIN+/** The smallest value an 8 bit signed integer can hold @stable ICU 2.0 */+# define INT8_MIN ((int8_t)(-128))+#endif+#ifndef INT16_MIN+/** The smallest value a 16 bit signed integer can hold @stable ICU 2.0 */+# define INT16_MIN ((int16_t)(-32767-1))+#endif+#ifndef INT32_MIN+/** The smallest value a 32 bit signed integer can hold @stable ICU 2.0 */+# define INT32_MIN ((int32_t)(-2147483647-1))+#endif++#ifndef INT8_MAX+/** The largest value an 8 bit signed integer can hold @stable ICU 2.0 */+# define INT8_MAX ((int8_t)(127))+#endif+#ifndef INT16_MAX+/** The largest value a 16 bit signed integer can hold @stable ICU 2.0 */+# define INT16_MAX ((int16_t)(32767))+#endif+#ifndef INT32_MAX+/** The largest value a 32 bit signed integer can hold @stable ICU 2.0 */+# define INT32_MAX ((int32_t)(2147483647))+#endif++#ifndef UINT8_MAX+/** The largest value an 8 bit unsigned integer can hold @stable ICU 2.0 */+# define UINT8_MAX ((uint8_t)(255U))+#endif+#ifndef UINT16_MAX+/** The largest value a 16 bit unsigned integer can hold @stable ICU 2.0 */+# define UINT16_MAX ((uint16_t)(65535U))+#endif+#ifndef UINT32_MAX+/** The largest value a 32 bit unsigned integer can hold @stable ICU 2.0 */+# define UINT32_MAX ((uint32_t)(4294967295U))+#endif++#if defined(U_INT64_T_UNAVAILABLE)+# error int64_t is required for decimal format and rule-based number format.+#else+# ifndef INT64_C+/**+ * Provides a platform independent way to specify a signed 64-bit integer constant.+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides INT64_C+ * @stable ICU 2.8+ */+# define INT64_C(c) c ## LL+# endif+# ifndef UINT64_C+/**+ * Provides a platform independent way to specify an unsigned 64-bit integer constant.+ * note: may be wrong for some 64 bit platforms - ensure your compiler provides UINT64_C+ * @stable ICU 2.8+ */+# define UINT64_C(c) c ## ULL+# endif+# ifndef U_INT64_MIN+/** The smallest value a 64 bit signed integer can hold @stable ICU 2.8 */+# define U_INT64_MIN ((int64_t)(INT64_C(-9223372036854775807)-1))+# endif+# ifndef U_INT64_MAX+/** The largest value a 64 bit signed integer can hold @stable ICU 2.8 */+# define U_INT64_MAX ((int64_t)(INT64_C(9223372036854775807)))+# endif+# ifndef U_UINT64_MAX+/** The largest value a 64 bit unsigned integer can hold @stable ICU 2.8 */+# define U_UINT64_MAX ((uint64_t)(UINT64_C(18446744073709551615)))+# endif+#endif++/*==========================================================================*/+/* Boolean data type */+/*==========================================================================*/++/** The ICU boolean type @stable ICU 2.0 */+typedef int8_t UBool;++#ifndef TRUE+/** The TRUE value of a UBool @stable ICU 2.0 */+# define TRUE 1+#endif+#ifndef FALSE+/** The FALSE value of a UBool @stable ICU 2.0 */+# define FALSE 0+#endif+++/*==========================================================================*/+/* Unicode data types */+/*==========================================================================*/++/* wchar_t-related definitions -------------------------------------------- */++/*+ * \def U_WCHAR_IS_UTF16+ * Defined if wchar_t uses UTF-16.+ *+ * @stable ICU 2.0+ */+/*+ * \def U_WCHAR_IS_UTF32+ * Defined if wchar_t uses UTF-32.+ *+ * @stable ICU 2.0+ */+#if !defined(U_WCHAR_IS_UTF16) && !defined(U_WCHAR_IS_UTF32)+# ifdef __STDC_ISO_10646__+# if (U_SIZEOF_WCHAR_T==2)+# define U_WCHAR_IS_UTF16+# elif (U_SIZEOF_WCHAR_T==4)+# define U_WCHAR_IS_UTF32+# endif+# elif defined __UCS2__+# if (U_PF_OS390 <= U_PLATFORM && U_PLATFORM <= U_PF_OS400) && (U_SIZEOF_WCHAR_T==2)+# define U_WCHAR_IS_UTF16+# endif+# elif defined(__UCS4__) || (U_PLATFORM == U_PF_OS400 && defined(__UTF32__))+# if (U_SIZEOF_WCHAR_T==4)+# define U_WCHAR_IS_UTF32+# endif+# elif U_PLATFORM_IS_DARWIN_BASED || (U_SIZEOF_WCHAR_T==4 && U_PLATFORM_IS_LINUX_BASED)+# define U_WCHAR_IS_UTF32+# elif U_PLATFORM_HAS_WIN32_API+# define U_WCHAR_IS_UTF16+# endif+#endif++/* UChar and UChar32 definitions -------------------------------------------- */++/** Number of bytes in a UChar. @stable ICU 2.0 */+#define U_SIZEOF_UCHAR 2++/**+ * \def U_CHAR16_IS_TYPEDEF+ * If 1, then char16_t is a typedef and not a real type (yet)+ * @internal+ */+#if (U_PLATFORM == U_PF_AIX) && defined(__cplusplus) &&(U_CPLUSPLUS_VERSION < 11)+// for AIX, uchar.h needs to be included+# include <uchar.h>+# define U_CHAR16_IS_TYPEDEF 1+#elif defined(_MSC_VER) && (_MSC_VER < 1900)+// Versions of Visual Studio/MSVC below 2015 do not support char16_t as a real type,+// and instead use a typedef. https://msdn.microsoft.com/library/bb531344.aspx+# define U_CHAR16_IS_TYPEDEF 1+#else+# define U_CHAR16_IS_TYPEDEF 0+#endif+++/**+ * \var UChar+ *+ * The base type for UTF-16 code units and pointers.+ * Unsigned 16-bit integer.+ * Starting with ICU 59, C++ API uses char16_t directly, while C API continues to use UChar.+ *+ * UChar is configurable by defining the macro UCHAR_TYPE+ * on the preprocessor or compiler command line:+ * -DUCHAR_TYPE=uint16_t or -DUCHAR_TYPE=wchar_t (if U_SIZEOF_WCHAR_T==2) etc.+ * (The UCHAR_TYPE can also be \#defined earlier in this file, for outside the ICU library code.)+ * This is for transitional use from application code that uses uint16_t or wchar_t for UTF-16.+ *+ * The default is UChar=char16_t.+ *+ * C++11 defines char16_t as bit-compatible with uint16_t, but as a distinct type.+ *+ * In C, char16_t is a simple typedef of uint_least16_t.+ * ICU requires uint_least16_t=uint16_t for data memory mapping.+ * On macOS, char16_t is not available because the uchar.h standard header is missing.+ *+ * @stable ICU 4.4+ */++#if 1+ // #if 1 is normal. UChar defaults to char16_t in C++.+ // For configuration testing of UChar=uint16_t temporarily change this to #if 0.+ // The intltest Makefile #defines UCHAR_TYPE=char16_t,+ // so we only #define it to uint16_t if it is undefined so far.+#elif !defined(UCHAR_TYPE)+# define UCHAR_TYPE uint16_t+#endif++#if defined(U_COMBINED_IMPLEMENTATION) || defined(U_COMMON_IMPLEMENTATION) || \+ defined(U_I18N_IMPLEMENTATION) || defined(U_IO_IMPLEMENTATION)+ // Inside the ICU library code, never configurable.+ typedef char16_t UChar;+#elif defined(UCHAR_TYPE)+ typedef UCHAR_TYPE UChar;+#elif defined(__cplusplus)+ typedef char16_t UChar;+#else+ typedef uint16_t UChar;+#endif++/**+ * \var OldUChar+ * Default ICU 58 definition of UChar.+ * A base type for UTF-16 code units and pointers.+ * Unsigned 16-bit integer.+ *+ * Define OldUChar to be wchar_t if that is 16 bits wide.+ * If wchar_t is not 16 bits wide, then define UChar to be uint16_t.+ *+ * This makes the definition of OldUChar platform-dependent+ * but allows direct string type compatibility with platforms with+ * 16-bit wchar_t types.+ *+ * This is how UChar was defined in ICU 58, for transition convenience.+ * Exception: ICU 58 UChar was defined to UCHAR_TYPE if that macro was defined.+ * The current UChar responds to UCHAR_TYPE but OldUChar does not.+ *+ * @stable ICU 59+ */+#if U_SIZEOF_WCHAR_T==2+ typedef wchar_t OldUChar;+#elif defined(__CHAR16_TYPE__)+ typedef __CHAR16_TYPE__ OldUChar;+#else+ typedef uint16_t OldUChar;+#endif++/**+ * Define UChar32 as a type for single Unicode code points.+ * UChar32 is a signed 32-bit integer (same as int32_t).+ *+ * The Unicode code point range is 0..0x10ffff.+ * All other values (negative or >=0x110000) are illegal as Unicode code points.+ * They may be used as sentinel values to indicate "done", "error"+ * or similar non-code point conditions.+ *+ * Before ICU 2.4 (Jitterbug 2146), UChar32 was defined+ * to be wchar_t if that is 32 bits wide (wchar_t may be signed or unsigned)+ * or else to be uint32_t.+ * That is, the definition of UChar32 was platform-dependent.+ *+ * @see U_SENTINEL+ * @stable ICU 2.4+ */+typedef int32_t UChar32;++/**+ * This value is intended for sentinel values for APIs that+ * (take or) return single code points (UChar32).+ * It is outside of the Unicode code point range 0..0x10ffff.+ *+ * For example, a "done" or "error" value in a new API+ * could be indicated with U_SENTINEL.+ *+ * ICU APIs designed before ICU 2.4 usually define service-specific "done"+ * values, mostly 0xffff.+ * Those may need to be distinguished from+ * actual U+ffff text contents by calling functions like+ * CharacterIterator::hasNext() or UnicodeString::length().+ *+ * @return -1+ * @see UChar32+ * @stable ICU 2.4+ */+#define U_SENTINEL (-1)++#include "unicode/urename.h"++#endif
+ vendor/tree-sitter/lib/src/unicode/urename.h view
@@ -0,0 +1,1 @@+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
+ vendor/tree-sitter/lib/src/unicode/utf.h view
@@ -0,0 +1,1 @@+// This file must exist in order for `utf8.h` and `utf16.h` to be used.
+ vendor/tree-sitter/lib/src/unicode/utf16.h view
@@ -0,0 +1,733 @@+// © 2016 and later: Unicode, Inc. and others.+// License & terms of use: http://www.unicode.org/copyright.html+/*+*******************************************************************************+*+* Copyright (C) 1999-2012, International Business Machines+* Corporation and others. All Rights Reserved.+*+*******************************************************************************+* file name: utf16.h+* encoding: UTF-8+* tab size: 8 (not used)+* indentation:4+*+* created on: 1999sep09+* created by: Markus W. Scherer+*/++/**+ * \file+ * \brief C API: 16-bit Unicode handling macros+ * + * This file defines macros to deal with 16-bit Unicode (UTF-16) code units and strings.+ *+ * For more information see utf.h and the ICU User Guide Strings chapter+ * (http://userguide.icu-project.org/strings).+ *+ * <em>Usage:</em>+ * ICU coding guidelines for if() statements should be followed when using these macros.+ * Compound statements (curly braces {}) must be used for if-else-while... + * bodies and all macro statements should be terminated with semicolon.+ */++#ifndef __UTF16_H__+#define __UTF16_H__++#include "unicode/umachine.h"+#ifndef __UTF_H__+# include "unicode/utf.h"+#endif++/* single-code point definitions -------------------------------------------- */++/**+ * Does this code unit alone encode a code point (BMP, not a surrogate)?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)++/**+ * Is this code unit a lead surrogate (U+d800..U+dbff)?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)++/**+ * Is this code unit a trail surrogate (U+dc00..U+dfff)?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)++/**+ * Is this code unit a surrogate (U+d800..U+dfff)?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)++/**+ * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),+ * is it a lead surrogate?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)++/**+ * Assuming c is a surrogate code point (U16_IS_SURROGATE(c)),+ * is it a trail surrogate?+ * @param c 16-bit code unit+ * @return TRUE or FALSE+ * @stable ICU 4.2+ */+#define U16_IS_SURROGATE_TRAIL(c) (((c)&0x400)!=0)++/**+ * Helper constant for U16_GET_SUPPLEMENTARY.+ * @internal+ */+#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)++/**+ * Get a supplementary code point value (U+10000..U+10ffff)+ * from its lead and trail surrogates.+ * The result is undefined if the input values are not+ * lead and trail surrogates.+ *+ * @param lead lead surrogate (U+d800..U+dbff)+ * @param trail trail surrogate (U+dc00..U+dfff)+ * @return supplementary code point (U+10000..U+10ffff)+ * @stable ICU 2.4+ */+#define U16_GET_SUPPLEMENTARY(lead, trail) \+ (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)+++/**+ * Get the lead surrogate (0xd800..0xdbff) for a+ * supplementary code point (0x10000..0x10ffff).+ * @param supplementary 32-bit code point (U+10000..U+10ffff)+ * @return lead surrogate (U+d800..U+dbff) for supplementary+ * @stable ICU 2.4+ */+#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)++/**+ * Get the trail surrogate (0xdc00..0xdfff) for a+ * supplementary code point (0x10000..0x10ffff).+ * @param supplementary 32-bit code point (U+10000..U+10ffff)+ * @return trail surrogate (U+dc00..U+dfff) for supplementary+ * @stable ICU 2.4+ */+#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)++/**+ * How many 16-bit code units are used to encode this Unicode code point? (1 or 2)+ * The result is not defined if c is not a Unicode code point (U+0000..U+10ffff).+ * @param c 32-bit code point+ * @return 1 or 2+ * @stable ICU 2.4+ */+#define U16_LENGTH(c) ((uint32_t)(c)<=0xffff ? 1 : 2)++/**+ * The maximum number of 16-bit code units per Unicode code point (U+0000..U+10ffff).+ * @return 2+ * @stable ICU 2.4+ */+#define U16_MAX_LENGTH 2++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * The offset may point to either the lead or trail surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the adjacent matching surrogate as well.+ * The result is undefined if the offset points to a single, unpaired surrogate.+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT.+ *+ * @param s const UChar * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U16_GET+ * @stable ICU 2.4+ */+#define U16_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[i]; \+ if(U16_IS_SURROGATE(c)) { \+ if(U16_IS_SURROGATE_LEAD(c)) { \+ (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)+1]); \+ } else { \+ (c)=U16_GET_SUPPLEMENTARY((s)[(i)-1], (c)); \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The offset may point to either the lead or trail surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the adjacent matching surrogate as well.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * If the offset points to a single, unpaired surrogate, then+ * c is set to that unpaired surrogate.+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<=i<length+ * @param length string length+ * @param c output UChar32 variable+ * @see U16_GET_UNSAFE+ * @stable ICU 2.4+ */+#define U16_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[i]; \+ if(U16_IS_SURROGATE(c)) { \+ uint16_t __c2; \+ if(U16_IS_SURROGATE_LEAD(c)) { \+ if((i)+1!=(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \+ (c)=U16_GET_SUPPLEMENTARY((c), __c2); \+ } \+ } else { \+ if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \+ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \+ } \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The offset may point to either the lead or trail surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the adjacent matching surrogate as well.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * If the offset points to a single, unpaired surrogate, then+ * c is set to U+FFFD.+ * Iteration through a string is more efficient with U16_NEXT_UNSAFE or U16_NEXT_OR_FFFD.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<=i<length+ * @param length string length+ * @param c output UChar32 variable+ * @see U16_GET_UNSAFE+ * @stable ICU 60+ */+#define U16_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[i]; \+ if(U16_IS_SURROGATE(c)) { \+ uint16_t __c2; \+ if(U16_IS_SURROGATE_LEAD(c)) { \+ if((i)+1!=(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \+ (c)=U16_GET_SUPPLEMENTARY((c), __c2); \+ } else { \+ (c)=0xfffd; \+ } \+ } else { \+ if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \+ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \+ } else { \+ (c)=0xfffd; \+ } \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/* definitions with forward iteration --------------------------------------- */++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * The offset may point to the lead surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the following trail surrogate as well.+ * If the offset points to a trail surrogate, then that itself+ * will be returned as the code point.+ * The result is undefined if the offset points to a single, unpaired lead surrogate.+ *+ * @param s const UChar * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U16_NEXT+ * @stable ICU 2.4+ */+#define U16_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[(i)++]; \+ if(U16_IS_LEAD(c)) { \+ (c)=U16_GET_SUPPLEMENTARY((c), (s)[(i)++]); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * The offset may point to the lead surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the following trail surrogate as well.+ * If the offset points to a trail surrogate or+ * to a single, unpaired lead surrogate, then c is set to that unpaired surrogate.+ *+ * @param s const UChar * string+ * @param i string offset, must be i<length+ * @param length string length+ * @param c output UChar32 variable+ * @see U16_NEXT_UNSAFE+ * @stable ICU 2.4+ */+#define U16_NEXT(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[(i)++]; \+ if(U16_IS_LEAD(c)) { \+ uint16_t __c2; \+ if((i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \+ ++(i); \+ (c)=U16_GET_SUPPLEMENTARY((c), __c2); \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * The offset may point to the lead surrogate unit+ * for a supplementary code point, in which case the macro will read+ * the following trail surrogate as well.+ * If the offset points to a trail surrogate or+ * to a single, unpaired lead surrogate, then c is set to U+FFFD.+ *+ * @param s const UChar * string+ * @param i string offset, must be i<length+ * @param length string length+ * @param c output UChar32 variable+ * @see U16_NEXT_UNSAFE+ * @stable ICU 60+ */+#define U16_NEXT_OR_FFFD(s, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[(i)++]; \+ if(U16_IS_SURROGATE(c)) { \+ uint16_t __c2; \+ if(U16_IS_SURROGATE_LEAD(c) && (i)!=(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \+ ++(i); \+ (c)=U16_GET_SUPPLEMENTARY((c), __c2); \+ } else { \+ (c)=0xfffd; \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Append a code point to a string, overwriting 1 or 2 code units.+ * The offset points to the current end of the string contents+ * and is advanced (post-increment).+ * "Unsafe" macro, assumes a valid code point and sufficient space in the string.+ * Otherwise, the result is undefined.+ *+ * @param s const UChar * string buffer+ * @param i string offset+ * @param c code point to append+ * @see U16_APPEND+ * @stable ICU 2.4+ */+#define U16_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ if((uint32_t)(c)<=0xffff) { \+ (s)[(i)++]=(uint16_t)(c); \+ } else { \+ (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \+ (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Append a code point to a string, overwriting 1 or 2 code units.+ * The offset points to the current end of the string contents+ * and is advanced (post-increment).+ * "Safe" macro, checks for a valid code point.+ * If a surrogate pair is written, checks for sufficient space in the string.+ * If the code point is not valid or a trail surrogate does not fit,+ * then isError is set to TRUE.+ *+ * @param s const UChar * string buffer+ * @param i string offset, must be i<capacity+ * @param capacity size of the string buffer+ * @param c code point to append+ * @param isError output UBool set to TRUE if an error occurs, otherwise not modified+ * @see U16_APPEND_UNSAFE+ * @stable ICU 2.4+ */+#define U16_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \+ if((uint32_t)(c)<=0xffff) { \+ (s)[(i)++]=(uint16_t)(c); \+ } else if((uint32_t)(c)<=0x10ffff && (i)+1<(capacity)) { \+ (s)[(i)++]=(uint16_t)(((c)>>10)+0xd7c0); \+ (s)[(i)++]=(uint16_t)(((c)&0x3ff)|0xdc00); \+ } else /* c>0x10ffff or not enough space */ { \+ (isError)=TRUE; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the next.+ * (Post-incrementing iteration.)+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @see U16_FWD_1+ * @stable ICU 2.4+ */+#define U16_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_LEAD((s)[(i)++])) { \+ ++(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the next.+ * (Post-incrementing iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const UChar * string+ * @param i string offset, must be i<length+ * @param length string length+ * @see U16_FWD_1_UNSAFE+ * @stable ICU 2.4+ */+#define U16_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_LEAD((s)[(i)++]) && (i)!=(length) && U16_IS_TRAIL((s)[i])) { \+ ++(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the n-th next one,+ * i.e., move forward by n code points.+ * (Post-incrementing iteration.)+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @param n number of code points to skip+ * @see U16_FWD_N+ * @stable ICU 2.4+ */+#define U16_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0) { \+ U16_FWD_1_UNSAFE(s, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the n-th next one,+ * i.e., move forward by n code points.+ * (Post-incrementing iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const UChar * string+ * @param i int32_t string offset, must be i<length+ * @param length int32_t string length+ * @param n number of code points to skip+ * @see U16_FWD_N_UNSAFE+ * @stable ICU 2.4+ */+#define U16_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \+ U16_FWD_1(s, i, length); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary+ * at the start of a code point.+ * If the offset points to the trail surrogate of a surrogate pair,+ * then the offset is decremented.+ * Otherwise, it is not modified.+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @see U16_SET_CP_START+ * @stable ICU 2.4+ */+#define U16_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_TRAIL((s)[i])) { \+ --(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary+ * at the start of a code point.+ * If the offset points to the trail surrogate of a surrogate pair,+ * then the offset is decremented.+ * Otherwise, it is not modified.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<=i+ * @see U16_SET_CP_START_UNSAFE+ * @stable ICU 2.4+ */+#define U16_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_TRAIL((s)[i]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \+ --(i); \+ } \+} UPRV_BLOCK_MACRO_END++/* definitions with backward iteration -------------------------------------- */++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a trail surrogate unit+ * for a supplementary code point, then the macro will read+ * the preceding lead surrogate as well.+ * If the offset is behind a lead surrogate, then that itself+ * will be returned as the code point.+ * The result is undefined if the offset is behind a single, unpaired trail surrogate.+ *+ * @param s const UChar * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U16_PREV+ * @stable ICU 2.4+ */+#define U16_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[--(i)]; \+ if(U16_IS_TRAIL(c)) { \+ (c)=U16_GET_SUPPLEMENTARY((s)[--(i)], (c)); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a trail surrogate unit+ * for a supplementary code point, then the macro will read+ * the preceding lead surrogate as well.+ * If the offset is behind a lead surrogate or behind a single, unpaired+ * trail surrogate, then c is set to that unpaired surrogate.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<i+ * @param c output UChar32 variable+ * @see U16_PREV_UNSAFE+ * @stable ICU 2.4+ */+#define U16_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[--(i)]; \+ if(U16_IS_TRAIL(c)) { \+ uint16_t __c2; \+ if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \+ --(i); \+ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a trail surrogate unit+ * for a supplementary code point, then the macro will read+ * the preceding lead surrogate as well.+ * If the offset is behind a lead surrogate or behind a single, unpaired+ * trail surrogate, then c is set to U+FFFD.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<i+ * @param c output UChar32 variable+ * @see U16_PREV_UNSAFE+ * @stable ICU 60+ */+#define U16_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(s)[--(i)]; \+ if(U16_IS_SURROGATE(c)) { \+ uint16_t __c2; \+ if(U16_IS_SURROGATE_TRAIL(c) && (i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \+ --(i); \+ (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \+ } else { \+ (c)=0xfffd; \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @see U16_BACK_1+ * @stable ICU 2.4+ */+#define U16_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_TRAIL((s)[--(i)])) { \+ --(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * @param s const UChar * string+ * @param start starting string offset (usually 0)+ * @param i string offset, must be start<i+ * @see U16_BACK_1_UNSAFE+ * @stable ICU 2.4+ */+#define U16_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \+ --(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the n-th one before it,+ * i.e., move backward by n code points.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @param n number of code points to skip+ * @see U16_BACK_N+ * @stable ICU 2.4+ */+#define U16_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0) { \+ U16_BACK_1_UNSAFE(s, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the n-th one before it,+ * i.e., move backward by n code points.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * @param s const UChar * string+ * @param start start of string+ * @param i string offset, must be start<i+ * @param n number of code points to skip+ * @see U16_BACK_N_UNSAFE+ * @stable ICU 2.4+ */+#define U16_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0 && (i)>(start)) { \+ U16_BACK_1(s, start, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary after a code point.+ * If the offset is behind the lead surrogate of a surrogate pair,+ * then the offset is incremented.+ * Otherwise, it is not modified.+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-16.+ *+ * @param s const UChar * string+ * @param i string offset+ * @see U16_SET_CP_LIMIT+ * @stable ICU 2.4+ */+#define U16_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U16_IS_LEAD((s)[(i)-1])) { \+ ++(i); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary after a code point.+ * If the offset is behind the lead surrogate of a surrogate pair,+ * then the offset is incremented.+ * Otherwise, it is not modified.+ * The input offset may be the same as the string length.+ * "Safe" macro, handles unpaired surrogates and checks for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const UChar * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, start<=i<=length+ * @param length int32_t string length+ * @see U16_SET_CP_LIMIT_UNSAFE+ * @stable ICU 2.4+ */+#define U16_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \+ if((start)<(i) && ((i)<(length) || (length)<0) && U16_IS_LEAD((s)[(i)-1]) && U16_IS_TRAIL((s)[i])) { \+ ++(i); \+ } \+} UPRV_BLOCK_MACRO_END++#endif
+ vendor/tree-sitter/lib/src/unicode/utf8.h view
@@ -0,0 +1,881 @@+// © 2016 and later: Unicode, Inc. and others.+// License & terms of use: http://www.unicode.org/copyright.html+/*+*******************************************************************************+*+* Copyright (C) 1999-2015, International Business Machines+* Corporation and others. All Rights Reserved.+*+*******************************************************************************+* file name: utf8.h+* encoding: UTF-8+* tab size: 8 (not used)+* indentation:4+*+* created on: 1999sep13+* created by: Markus W. Scherer+*/++/**+ * \file+ * \brief C API: 8-bit Unicode handling macros+ *+ * This file defines macros to deal with 8-bit Unicode (UTF-8) code units (bytes) and strings.+ *+ * For more information see utf.h and the ICU User Guide Strings chapter+ * (http://userguide.icu-project.org/strings).+ *+ * <em>Usage:</em>+ * ICU coding guidelines for if() statements should be followed when using these macros.+ * Compound statements (curly braces {}) must be used for if-else-while...+ * bodies and all macro statements should be terminated with semicolon.+ */++#ifndef __UTF8_H__+#define __UTF8_H__++#include "unicode/umachine.h"+#ifndef __UTF_H__+# include "unicode/utf.h"+#endif++/* internal definitions ----------------------------------------------------- */++/**+ * Counts the trail bytes for a UTF-8 lead byte.+ * Returns 0 for 0..0xc1 as well as for 0xf5..0xff.+ * leadByte might be evaluated multiple times.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is called by public macros in this file and thus must remain stable.+ *+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.+ * @internal+ */+#define U8_COUNT_TRAIL_BYTES(leadByte) \+ (U8_IS_LEAD(leadByte) ? \+ ((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0)+1 : 0)++/**+ * Counts the trail bytes for a UTF-8 lead byte of a valid UTF-8 sequence.+ * Returns 0 for 0..0xc1. Undefined for 0xf5..0xff.+ * leadByte might be evaluated multiple times.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is called by public macros in this file and thus must remain stable.+ *+ * @param leadByte The first byte of a UTF-8 sequence. Must be 0..0xff.+ * @internal+ */+#define U8_COUNT_TRAIL_BYTES_UNSAFE(leadByte) \+ (((uint8_t)(leadByte)>=0xc2)+((uint8_t)(leadByte)>=0xe0)+((uint8_t)(leadByte)>=0xf0))++/**+ * Mask a UTF-8 lead byte, leave only the lower bits that form part of the code point value.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is called by public macros in this file and thus must remain stable.+ * @internal+ */+#define U8_MASK_LEAD_BYTE(leadByte, countTrailBytes) ((leadByte)&=(1<<(6-(countTrailBytes)))-1)++/**+ * Internal bit vector for 3-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD3_AND_T1.+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.+ * Lead byte E0..EF bits 3..0 are used as byte index,+ * first trail byte bits 7..5 are used as bit index into that byte.+ * @see U8_IS_VALID_LEAD3_AND_T1+ * @internal+ */+#define U8_LEAD3_T1_BITS "\x20\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x30\x10\x30\x30"++/**+ * Internal 3-byte UTF-8 validity check.+ * Non-zero if lead byte E0..EF and first trail byte 00..FF start a valid sequence.+ * @internal+ */+#define U8_IS_VALID_LEAD3_AND_T1(lead, t1) (U8_LEAD3_T1_BITS[(lead)&0xf]&(1<<((uint8_t)(t1)>>5)))++/**+ * Internal bit vector for 4-byte UTF-8 validity check, for use in U8_IS_VALID_LEAD4_AND_T1.+ * Each bit indicates whether one lead byte + first trail byte pair starts a valid sequence.+ * First trail byte bits 7..4 are used as byte index,+ * lead byte F0..F4 bits 2..0 are used as bit index into that byte.+ * @see U8_IS_VALID_LEAD4_AND_T1+ * @internal+ */+#define U8_LEAD4_T1_BITS "\x00\x00\x00\x00\x00\x00\x00\x00\x1E\x0F\x0F\x0F\x00\x00\x00\x00"++/**+ * Internal 4-byte UTF-8 validity check.+ * Non-zero if lead byte F0..F4 and first trail byte 00..FF start a valid sequence.+ * @internal+ */+#define U8_IS_VALID_LEAD4_AND_T1(lead, t1) (U8_LEAD4_T1_BITS[(uint8_t)(t1)>>4]&(1<<((lead)&7)))++/**+ * Function for handling "next code point" with error-checking.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this+ * file and thus must remain stable, and should not be hidden when other internal+ * functions are hidden (otherwise public macros would fail to compile).+ * @internal+ */+U_STABLE UChar32 U_EXPORT2+utf8_nextCharSafeBody(const uint8_t *s, int32_t *pi, int32_t length, UChar32 c, UBool strict);++/**+ * Function for handling "append code point" with error-checking.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this+ * file and thus must remain stable, and should not be hidden when other internal+ * functions are hidden (otherwise public macros would fail to compile).+ * @internal+ */+U_STABLE int32_t U_EXPORT2+utf8_appendCharSafeBody(uint8_t *s, int32_t i, int32_t length, UChar32 c, UBool *pIsError);++/**+ * Function for handling "previous code point" with error-checking.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this+ * file and thus must remain stable, and should not be hidden when other internal+ * functions are hidden (otherwise public macros would fail to compile).+ * @internal+ */+U_STABLE UChar32 U_EXPORT2+utf8_prevCharSafeBody(const uint8_t *s, int32_t start, int32_t *pi, UChar32 c, UBool strict);++/**+ * Function for handling "skip backward one code point" with error-checking.+ *+ * This is internal since it is not meant to be called directly by external clients;+ * however it is U_STABLE (not U_INTERNAL) since it is called by public macros in this+ * file and thus must remain stable, and should not be hidden when other internal+ * functions are hidden (otherwise public macros would fail to compile).+ * @internal+ */+U_STABLE int32_t U_EXPORT2+utf8_back1SafeBody(const uint8_t *s, int32_t start, int32_t i);++/* single-code point definitions -------------------------------------------- */++/**+ * Does this code unit (byte) encode a code point by itself (US-ASCII 0..0x7f)?+ * @param c 8-bit code unit (byte)+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U8_IS_SINGLE(c) (((c)&0x80)==0)++/**+ * Is this code unit (byte) a UTF-8 lead byte? (0xC2..0xF4)+ * @param c 8-bit code unit (byte)+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U8_IS_LEAD(c) ((uint8_t)((c)-0xc2)<=0x32)+// 0x32=0xf4-0xc2++/**+ * Is this code unit (byte) a UTF-8 trail byte? (0x80..0xBF)+ * @param c 8-bit code unit (byte)+ * @return TRUE or FALSE+ * @stable ICU 2.4+ */+#define U8_IS_TRAIL(c) ((int8_t)(c)<-0x40)++/**+ * How many code units (bytes) are used for the UTF-8 encoding+ * of this Unicode code point?+ * @param c 32-bit code point+ * @return 1..4, or 0 if c is a surrogate or not a Unicode code point+ * @stable ICU 2.4+ */+#define U8_LENGTH(c) \+ ((uint32_t)(c)<=0x7f ? 1 : \+ ((uint32_t)(c)<=0x7ff ? 2 : \+ ((uint32_t)(c)<=0xd7ff ? 3 : \+ ((uint32_t)(c)<=0xdfff || (uint32_t)(c)>0x10ffff ? 0 : \+ ((uint32_t)(c)<=0xffff ? 3 : 4)\+ ) \+ ) \+ ) \+ )++/**+ * The maximum number of UTF-8 code units (bytes) per Unicode code point (U+0000..U+10ffff).+ * @return 4+ * @stable ICU 2.4+ */+#define U8_MAX_LENGTH 4++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * The offset may point to either the lead byte or one of the trail bytes+ * for a code point, in which case the macro will read all of the bytes+ * for the code point.+ * The result is undefined if the offset points to an illegal UTF-8+ * byte sequence.+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U8_GET+ * @stable ICU 2.4+ */+#define U8_GET_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t _u8_get_unsafe_index=(int32_t)(i); \+ U8_SET_CP_START_UNSAFE(s, _u8_get_unsafe_index); \+ U8_NEXT_UNSAFE(s, _u8_get_unsafe_index, c); \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * The offset may point to either the lead byte or one of the trail bytes+ * for a code point, in which case the macro will read all of the bytes+ * for the code point.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * If the offset points to an illegal UTF-8 byte sequence, then+ * c is set to a negative value.+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset+ * @param i int32_t string offset, must be start<=i<length+ * @param length int32_t string length+ * @param c output UChar32 variable, set to <0 in case of an error+ * @see U8_GET_UNSAFE+ * @stable ICU 2.4+ */+#define U8_GET(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t _u8_get_index=(i); \+ U8_SET_CP_START(s, start, _u8_get_index); \+ U8_NEXT(s, _u8_get_index, length, c); \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a random-access offset,+ * without changing the offset.+ * The offset may point to either the lead byte or one of the trail bytes+ * for a code point, in which case the macro will read all of the bytes+ * for the code point.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * If the offset points to an illegal UTF-8 byte sequence, then+ * c is set to U+FFFD.+ * Iteration through a string is more efficient with U8_NEXT_UNSAFE or U8_NEXT_OR_FFFD.+ *+ * This macro does not distinguish between a real U+FFFD in the text+ * and U+FFFD returned for an ill-formed sequence.+ * Use U8_GET() if that distinction is important.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset+ * @param i int32_t string offset, must be start<=i<length+ * @param length int32_t string length+ * @param c output UChar32 variable, set to U+FFFD in case of an error+ * @see U8_GET+ * @stable ICU 51+ */+#define U8_GET_OR_FFFD(s, start, i, length, c) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t _u8_get_index=(i); \+ U8_SET_CP_START(s, start, _u8_get_index); \+ U8_NEXT_OR_FFFD(s, _u8_get_index, length, c); \+} UPRV_BLOCK_MACRO_END++/* definitions with forward iteration --------------------------------------- */++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * The offset may point to the lead byte of a multi-byte sequence,+ * in which case the macro will read the whole sequence.+ * The result is undefined if the offset points to a trail byte+ * or an illegal UTF-8 sequence.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U8_NEXT+ * @stable ICU 2.4+ */+#define U8_NEXT_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(uint8_t)(s)[(i)++]; \+ if(!U8_IS_SINGLE(c)) { \+ if((c)<0xe0) { \+ (c)=(((c)&0x1f)<<6)|((s)[(i)++]&0x3f); \+ } else if((c)<0xf0) { \+ /* no need for (c&0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */ \+ (c)=(UChar)(((c)<<12)|(((s)[i]&0x3f)<<6)|((s)[(i)+1]&0x3f)); \+ (i)+=2; \+ } else { \+ (c)=(((c)&7)<<18)|(((s)[i]&0x3f)<<12)|(((s)[(i)+1]&0x3f)<<6)|((s)[(i)+2]&0x3f); \+ (i)+=3; \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * The offset may point to the lead byte of a multi-byte sequence,+ * in which case the macro will read the whole sequence.+ * If the offset points to a trail byte or an illegal UTF-8 sequence, then+ * c is set to a negative value.+ *+ * @param s const uint8_t * string+ * @param i int32_t string offset, must be i<length+ * @param length int32_t string length+ * @param c output UChar32 variable, set to <0 in case of an error+ * @see U8_NEXT_UNSAFE+ * @stable ICU 2.4+ */+#define U8_NEXT(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, U_SENTINEL)++/**+ * Get a code point from a string at a code point boundary offset,+ * and advance the offset to the next code point boundary.+ * (Post-incrementing forward iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * The offset may point to the lead byte of a multi-byte sequence,+ * in which case the macro will read the whole sequence.+ * If the offset points to a trail byte or an illegal UTF-8 sequence, then+ * c is set to U+FFFD.+ *+ * This macro does not distinguish between a real U+FFFD in the text+ * and U+FFFD returned for an ill-formed sequence.+ * Use U8_NEXT() if that distinction is important.+ *+ * @param s const uint8_t * string+ * @param i int32_t string offset, must be i<length+ * @param length int32_t string length+ * @param c output UChar32 variable, set to U+FFFD in case of an error+ * @see U8_NEXT+ * @stable ICU 51+ */+#define U8_NEXT_OR_FFFD(s, i, length, c) U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, 0xfffd)++/** @internal */+#define U8_INTERNAL_NEXT_OR_SUB(s, i, length, c, sub) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(uint8_t)(s)[(i)++]; \+ if(!U8_IS_SINGLE(c)) { \+ uint8_t __t = 0; \+ if((i)!=(length) && \+ /* fetch/validate/assemble all but last trail byte */ \+ ((c)>=0xe0 ? \+ ((c)<0xf0 ? /* U+0800..U+FFFF except surrogates */ \+ U8_LEAD3_T1_BITS[(c)&=0xf]&(1<<((__t=(s)[i])>>5)) && \+ (__t&=0x3f, 1) \+ : /* U+10000..U+10FFFF */ \+ ((c)-=0xf0)<=4 && \+ U8_LEAD4_T1_BITS[(__t=(s)[i])>>4]&(1<<(c)) && \+ ((c)=((c)<<6)|(__t&0x3f), ++(i)!=(length)) && \+ (__t=(s)[i]-0x80)<=0x3f) && \+ /* valid second-to-last trail byte */ \+ ((c)=((c)<<6)|__t, ++(i)!=(length)) \+ : /* U+0080..U+07FF */ \+ (c)>=0xc2 && ((c)&=0x1f, 1)) && \+ /* last trail byte */ \+ (__t=(s)[i]-0x80)<=0x3f && \+ ((c)=((c)<<6)|__t, ++(i), 1)) { \+ } else { \+ (c)=(sub); /* ill-formed*/ \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Append a code point to a string, overwriting 1 to 4 bytes.+ * The offset points to the current end of the string contents+ * and is advanced (post-increment).+ * "Unsafe" macro, assumes a valid code point and sufficient space in the string.+ * Otherwise, the result is undefined.+ *+ * @param s const uint8_t * string buffer+ * @param i string offset+ * @param c code point to append+ * @see U8_APPEND+ * @stable ICU 2.4+ */+#define U8_APPEND_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ uint32_t __uc=(c); \+ if(__uc<=0x7f) { \+ (s)[(i)++]=(uint8_t)__uc; \+ } else { \+ if(__uc<=0x7ff) { \+ (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \+ } else { \+ if(__uc<=0xffff) { \+ (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \+ } else { \+ (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \+ (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \+ } \+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \+ } \+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Append a code point to a string, overwriting 1 to 4 bytes.+ * The offset points to the current end of the string contents+ * and is advanced (post-increment).+ * "Safe" macro, checks for a valid code point.+ * If a non-ASCII code point is written, checks for sufficient space in the string.+ * If the code point is not valid or trail bytes do not fit,+ * then isError is set to TRUE.+ *+ * @param s const uint8_t * string buffer+ * @param i int32_t string offset, must be i<capacity+ * @param capacity int32_t size of the string buffer+ * @param c UChar32 code point to append+ * @param isError output UBool set to TRUE if an error occurs, otherwise not modified+ * @see U8_APPEND_UNSAFE+ * @stable ICU 2.4+ */+#define U8_APPEND(s, i, capacity, c, isError) UPRV_BLOCK_MACRO_BEGIN { \+ uint32_t __uc=(c); \+ if(__uc<=0x7f) { \+ (s)[(i)++]=(uint8_t)__uc; \+ } else if(__uc<=0x7ff && (i)+1<(capacity)) { \+ (s)[(i)++]=(uint8_t)((__uc>>6)|0xc0); \+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \+ } else if((__uc<=0xd7ff || (0xe000<=__uc && __uc<=0xffff)) && (i)+2<(capacity)) { \+ (s)[(i)++]=(uint8_t)((__uc>>12)|0xe0); \+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \+ } else if(0xffff<__uc && __uc<=0x10ffff && (i)+3<(capacity)) { \+ (s)[(i)++]=(uint8_t)((__uc>>18)|0xf0); \+ (s)[(i)++]=(uint8_t)(((__uc>>12)&0x3f)|0x80); \+ (s)[(i)++]=(uint8_t)(((__uc>>6)&0x3f)|0x80); \+ (s)[(i)++]=(uint8_t)((__uc&0x3f)|0x80); \+ } else { \+ (isError)=TRUE; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the next.+ * (Post-incrementing iteration.)+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @see U8_FWD_1+ * @stable ICU 2.4+ */+#define U8_FWD_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ (i)+=1+U8_COUNT_TRAIL_BYTES_UNSAFE((s)[i]); \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the next.+ * (Post-incrementing iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const uint8_t * string+ * @param i int32_t string offset, must be i<length+ * @param length int32_t string length+ * @see U8_FWD_1_UNSAFE+ * @stable ICU 2.4+ */+#define U8_FWD_1(s, i, length) UPRV_BLOCK_MACRO_BEGIN { \+ uint8_t __b=(s)[(i)++]; \+ if(U8_IS_LEAD(__b) && (i)!=(length)) { \+ uint8_t __t1=(s)[i]; \+ if((0xe0<=__b && __b<0xf0)) { \+ if(U8_IS_VALID_LEAD3_AND_T1(__b, __t1) && \+ ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \+ ++(i); \+ } \+ } else if(__b<0xe0) { \+ if(U8_IS_TRAIL(__t1)) { \+ ++(i); \+ } \+ } else /* c>=0xf0 */ { \+ if(U8_IS_VALID_LEAD4_AND_T1(__b, __t1) && \+ ++(i)!=(length) && U8_IS_TRAIL((s)[i]) && \+ ++(i)!=(length) && U8_IS_TRAIL((s)[i])) { \+ ++(i); \+ } \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the n-th next one,+ * i.e., move forward by n code points.+ * (Post-incrementing iteration.)+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @param n number of code points to skip+ * @see U8_FWD_N+ * @stable ICU 2.4+ */+#define U8_FWD_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0) { \+ U8_FWD_1_UNSAFE(s, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Advance the string offset from one code point boundary to the n-th next one,+ * i.e., move forward by n code points.+ * (Post-incrementing iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const uint8_t * string+ * @param i int32_t string offset, must be i<length+ * @param length int32_t string length+ * @param n number of code points to skip+ * @see U8_FWD_N_UNSAFE+ * @stable ICU 2.4+ */+#define U8_FWD_N(s, i, length, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0 && ((i)<(length) || ((length)<0 && (s)[i]!=0))) { \+ U8_FWD_1(s, i, length); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary+ * at the start of a code point.+ * If the offset points to a UTF-8 trail byte,+ * then the offset is moved backward to the corresponding lead byte.+ * Otherwise, it is not modified.+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @see U8_SET_CP_START+ * @stable ICU 2.4+ */+#define U8_SET_CP_START_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ while(U8_IS_TRAIL((s)[i])) { --(i); } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary+ * at the start of a code point.+ * If the offset points to a UTF-8 trail byte,+ * then the offset is moved backward to the corresponding lead byte.+ * Otherwise, it is not modified.+ *+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ * Unlike U8_TRUNCATE_IF_INCOMPLETE(), this macro always reads s[i].+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, must be start<=i+ * @see U8_SET_CP_START_UNSAFE+ * @see U8_TRUNCATE_IF_INCOMPLETE+ * @stable ICU 2.4+ */+#define U8_SET_CP_START(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U8_IS_TRAIL((s)[(i)])) { \+ (i)=utf8_back1SafeBody(s, start, (i)); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * If the string ends with a UTF-8 byte sequence that is valid so far+ * but incomplete, then reduce the length of the string to end before+ * the lead byte of that incomplete sequence.+ * For example, if the string ends with E1 80, the length is reduced by 2.+ *+ * In all other cases (the string ends with a complete sequence, or it is not+ * possible for any further trail byte to extend the trailing sequence)+ * the length remains unchanged.+ *+ * Useful for processing text split across multiple buffers+ * (save the incomplete sequence for later)+ * and for optimizing iteration+ * (check for string length only once per character).+ *+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ * Unlike U8_SET_CP_START(), this macro never reads s[length].+ *+ * (In UTF-16, simply check for U16_IS_LEAD(last code unit).)+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param length int32_t string length (usually start<=length)+ * @see U8_SET_CP_START+ * @stable ICU 61+ */+#define U8_TRUNCATE_IF_INCOMPLETE(s, start, length) UPRV_BLOCK_MACRO_BEGIN { \+ if((length)>(start)) { \+ uint8_t __b1=s[(length)-1]; \+ if(U8_IS_SINGLE(__b1)) { \+ /* common ASCII character */ \+ } else if(U8_IS_LEAD(__b1)) { \+ --(length); \+ } else if(U8_IS_TRAIL(__b1) && ((length)-2)>=(start)) { \+ uint8_t __b2=s[(length)-2]; \+ if(0xe0<=__b2 && __b2<=0xf4) { \+ if(__b2<0xf0 ? U8_IS_VALID_LEAD3_AND_T1(__b2, __b1) : \+ U8_IS_VALID_LEAD4_AND_T1(__b2, __b1)) { \+ (length)-=2; \+ } \+ } else if(U8_IS_TRAIL(__b2) && ((length)-3)>=(start)) { \+ uint8_t __b3=s[(length)-3]; \+ if(0xf0<=__b3 && __b3<=0xf4 && U8_IS_VALID_LEAD4_AND_T1(__b3, __b2)) { \+ (length)-=3; \+ } \+ } \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/* definitions with backward iteration -------------------------------------- */++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a multi-byte sequence, then the macro will read+ * the whole sequence.+ * If the offset is behind a lead byte, then that itself+ * will be returned as the code point.+ * The result is undefined if the offset is behind an illegal UTF-8 sequence.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @param c output UChar32 variable+ * @see U8_PREV+ * @stable ICU 2.4+ */+#define U8_PREV_UNSAFE(s, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(uint8_t)(s)[--(i)]; \+ if(U8_IS_TRAIL(c)) { \+ uint8_t __b, __count=1, __shift=6; \+\+ /* c is a trail byte */ \+ (c)&=0x3f; \+ for(;;) { \+ __b=(s)[--(i)]; \+ if(__b>=0xc0) { \+ U8_MASK_LEAD_BYTE(__b, __count); \+ (c)|=(UChar32)__b<<__shift; \+ break; \+ } else { \+ (c)|=(UChar32)(__b&0x3f)<<__shift; \+ ++__count; \+ __shift+=6; \+ } \+ } \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a multi-byte sequence, then the macro will read+ * the whole sequence.+ * If the offset is behind a lead byte, then that itself+ * will be returned as the code point.+ * If the offset is behind an illegal UTF-8 sequence, then c is set to a negative value.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, must be start<i+ * @param c output UChar32 variable, set to <0 in case of an error+ * @see U8_PREV_UNSAFE+ * @stable ICU 2.4+ */+#define U8_PREV(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(uint8_t)(s)[--(i)]; \+ if(!U8_IS_SINGLE(c)) { \+ (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -1); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one+ * and get the code point between them.+ * (Pre-decrementing backward iteration.)+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The input offset may be the same as the string length.+ * If the offset is behind a multi-byte sequence, then the macro will read+ * the whole sequence.+ * If the offset is behind a lead byte, then that itself+ * will be returned as the code point.+ * If the offset is behind an illegal UTF-8 sequence, then c is set to U+FFFD.+ *+ * This macro does not distinguish between a real U+FFFD in the text+ * and U+FFFD returned for an ill-formed sequence.+ * Use U8_PREV() if that distinction is important.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, must be start<i+ * @param c output UChar32 variable, set to U+FFFD in case of an error+ * @see U8_PREV+ * @stable ICU 51+ */+#define U8_PREV_OR_FFFD(s, start, i, c) UPRV_BLOCK_MACRO_BEGIN { \+ (c)=(uint8_t)(s)[--(i)]; \+ if(!U8_IS_SINGLE(c)) { \+ (c)=utf8_prevCharSafeBody((const uint8_t *)s, start, &(i), c, -3); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @see U8_BACK_1+ * @stable ICU 2.4+ */+#define U8_BACK_1_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ while(U8_IS_TRAIL((s)[--(i)])) {} \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the previous one.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, must be start<i+ * @see U8_BACK_1_UNSAFE+ * @stable ICU 2.4+ */+#define U8_BACK_1(s, start, i) UPRV_BLOCK_MACRO_BEGIN { \+ if(U8_IS_TRAIL((s)[--(i)])) { \+ (i)=utf8_back1SafeBody(s, start, (i)); \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the n-th one before it,+ * i.e., move backward by n code points.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @param n number of code points to skip+ * @see U8_BACK_N+ * @stable ICU 2.4+ */+#define U8_BACK_N_UNSAFE(s, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0) { \+ U8_BACK_1_UNSAFE(s, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Move the string offset from one code point boundary to the n-th one before it,+ * i.e., move backward by n code points.+ * (Pre-decrementing backward iteration.)+ * The input offset may be the same as the string length.+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * @param s const uint8_t * string+ * @param start int32_t index of the start of the string+ * @param i int32_t string offset, must be start<i+ * @param n number of code points to skip+ * @see U8_BACK_N_UNSAFE+ * @stable ICU 2.4+ */+#define U8_BACK_N(s, start, i, n) UPRV_BLOCK_MACRO_BEGIN { \+ int32_t __N=(n); \+ while(__N>0 && (i)>(start)) { \+ U8_BACK_1(s, start, i); \+ --__N; \+ } \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary after a code point.+ * If the offset is behind a partial multi-byte sequence,+ * then the offset is incremented to behind the whole sequence.+ * Otherwise, it is not modified.+ * The input offset may be the same as the string length.+ * "Unsafe" macro, assumes well-formed UTF-8.+ *+ * @param s const uint8_t * string+ * @param i string offset+ * @see U8_SET_CP_LIMIT+ * @stable ICU 2.4+ */+#define U8_SET_CP_LIMIT_UNSAFE(s, i) UPRV_BLOCK_MACRO_BEGIN { \+ U8_BACK_1_UNSAFE(s, i); \+ U8_FWD_1_UNSAFE(s, i); \+} UPRV_BLOCK_MACRO_END++/**+ * Adjust a random-access offset to a code point boundary after a code point.+ * If the offset is behind a partial multi-byte sequence,+ * then the offset is incremented to behind the whole sequence.+ * Otherwise, it is not modified.+ * The input offset may be the same as the string length.+ * "Safe" macro, checks for illegal sequences and for string boundaries.+ *+ * The length can be negative for a NUL-terminated string.+ *+ * @param s const uint8_t * string+ * @param start int32_t starting string offset (usually 0)+ * @param i int32_t string offset, must be start<=i<=length+ * @param length int32_t string length+ * @see U8_SET_CP_LIMIT_UNSAFE+ * @stable ICU 2.4+ */+#define U8_SET_CP_LIMIT(s, start, i, length) UPRV_BLOCK_MACRO_BEGIN { \+ if((start)<(i) && ((i)<(length) || (length)<0)) { \+ U8_BACK_1(s, start, i); \+ U8_FWD_1(s, i, length); \+ } \+} UPRV_BLOCK_MACRO_END++#endif
+ vendor/tree-sitter/lib/src/wasm/stdlib.c view
@@ -0,0 +1,109 @@+// This file implements a very simple allocator for external scanners running+// in WASM. Allocation is just bumping a static pointer and growing the heap+// as needed, and freeing is mostly a noop. But in the special case of freeing+// the last-allocated pointer, we'll reuse that pointer again.++#include <stdio.h>+#include <unistd.h>+#include <stdlib.h>+#include <string.h>++extern void tree_sitter_debug_message(const char *, size_t);++#define PAGESIZE 0x10000+#define MAX_HEAP_SIZE (4 * 1024 * 1024)++typedef struct {+ size_t size;+ char data[0];+} Region;++static Region *heap_end = NULL;+static Region *heap_start = NULL;+static Region *next = NULL;++// Get the region metadata for the given heap pointer.+static inline Region *region_for_ptr(void *ptr) {+ return ((Region *)ptr) - 1;+}++// Get the location of the next region after the given region,+// if the given region had the given size.+static inline Region *region_after(Region *self, size_t len) {+ char *address = self->data + len;+ char *aligned = (char *)((uintptr_t)(address + 3) & ~0x3);+ return (Region *)aligned;+}++static void *get_heap_end() {+ return (void *)(__builtin_wasm_memory_size(0) * PAGESIZE);+}++static int grow_heap(size_t size) {+ size_t new_page_count = ((size - 1) / PAGESIZE) + 1;+ return __builtin_wasm_memory_grow(0, new_page_count) != SIZE_MAX;+}++// Clear out the heap, and move it to the given address.+void reset_heap(void *new_heap_start) {+ heap_start = new_heap_start;+ next = new_heap_start;+ heap_end = get_heap_end();+}++void *malloc(size_t size) {+ Region *region_end = region_after(next, size);++ if (region_end > heap_end) {+ if ((char *)region_end - (char *)heap_start > MAX_HEAP_SIZE) {+ return NULL;+ }+ if (!grow_heap(size)) return NULL;+ heap_end = get_heap_end();+ }++ void *result = &next->data;+ next->size = size;+ next = region_end;++ return result;+}++void free(void *ptr) {+ if (ptr == NULL) return;++ Region *region = region_for_ptr(ptr);+ Region *region_end = region_after(region, region->size);++ // When freeing the last allocated pointer, re-use that+ // pointer for the next allocation.+ if (region_end == next) {+ next = region;+ }+}++void *calloc(size_t count, size_t size) {+ void *result = malloc(count * size);+ memset(result, 0, count * size);+ return result;+}++void *realloc(void *ptr, size_t new_size) {+ if (ptr == NULL) {+ return malloc(new_size);+ }++ Region *region = region_for_ptr(ptr);+ Region *region_end = region_after(region, region->size);++ // When reallocating the last allocated region, return+ // the same pointer, and skip copying the data.+ if (region_end == next) {+ next = region;+ return malloc(new_size);+ }++ void *result = malloc(new_size);+ memcpy(result, ®ion->data, region->size);+ return result;+}
+ vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h view
@@ -0,0 +1,1302 @@+unsigned char STDLIB_WASM[] = {+ 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x06, 0x60,+ 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00,+ 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7f, 0x60, 0x03, 0x7f,+ 0x7f, 0x7f, 0x01, 0x7f, 0x02, 0x9e, 0x01, 0x05, 0x03, 0x65, 0x6e, 0x76,+ 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x65,+ 0x6e, 0x76, 0x19, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63,+ 0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74,+ 0x61, 0x62, 0x6c, 0x65, 0x01, 0x70, 0x00, 0x01, 0x16, 0x77, 0x61, 0x73,+ 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70,+ 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73,+ 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f,+ 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65,+ 0x76, 0x69, 0x65, 0x77, 0x31, 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73,+ 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77,+ 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74,+ 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72,+ 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x00, 0x01, 0x03, 0x2a, 0x29,+ 0x02, 0x00, 0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00,+ 0x00, 0x01, 0x02, 0x02, 0x05, 0x05, 0x03, 0x03, 0x05, 0x05, 0x00, 0x03,+ 0x00, 0x03, 0x05, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x05,+ 0x03, 0x03, 0x00, 0x03, 0x03, 0x06, 0x0d, 0x02, 0x7f, 0x01, 0x41, 0x80,+ 0x80, 0x04, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0xad, 0x02, 0x1c,+ 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c,+ 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x03, 0x0f, 0x5f, 0x5f, 0x73,+ 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72,+ 0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x06, 0x0a,+ 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x00, 0x07,+ 0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x08, 0x04, 0x66, 0x72,+ 0x65, 0x65, 0x00, 0x09, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00,+ 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, 0x74, 0x00, 0x14, 0x07, 0x72,+ 0x65, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x0b, 0x06, 0x6d, 0x65, 0x6d,+ 0x63, 0x70, 0x79, 0x00, 0x13, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e,+ 0x00, 0x15, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x6e, 0x75, 0x6d, 0x00,+ 0x2b, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x16,+ 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x00, 0x22, 0x08,+ 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x23, 0x08, 0x69,+ 0x73, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, 0x20, 0x08, 0x69, 0x73,+ 0x77, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x2a, 0x08, 0x69, 0x73, 0x77,+ 0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x1e, 0x09, 0x69, 0x73, 0x77, 0x78,+ 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x27, 0x08, 0x74, 0x6f, 0x77, 0x6c,+ 0x6f, 0x77, 0x65, 0x72, 0x00, 0x1a, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70,+ 0x70, 0x65, 0x72, 0x00, 0x1c, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72,+ 0x00, 0x18, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x6d, 0x70, 0x00, 0x17, 0x07,+ 0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x00, 0x1f, 0x06, 0x73, 0x74,+ 0x72, 0x63, 0x6d, 0x70, 0x00, 0x19, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63,+ 0x61, 0x74, 0x00, 0x24, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70,+ 0x00, 0x1d, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x70, 0x79, 0x00, 0x26,+ 0x08, 0x01, 0x05, 0x0a, 0xe8, 0x2b, 0x29, 0x02, 0x00, 0x0b, 0x03, 0x00,+ 0x00, 0x0b, 0x0d, 0x00, 0x41, 0xe8, 0xc2, 0x04, 0x41, 0x00, 0x41, 0x10,+ 0xfc, 0x0b, 0x00, 0x0b, 0x52, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x02, 0x40,+ 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xe8, 0xc2, 0x84, 0x80, 0x00,+ 0x6a, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00,+ 0x41, 0xe8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x41, 0x01, 0x36, 0x02, 0x00,+ 0x10, 0x83, 0x80, 0x80, 0x80, 0x00, 0x10, 0x8d, 0x80, 0x80, 0x80, 0x00,+ 0x21, 0x00, 0x10, 0x92, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x0d, 0x01,+ 0x0f, 0x0b, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, 0x80,+ 0x00, 0x00, 0x0b, 0x37, 0x01, 0x01, 0x7f, 0x23, 0x81, 0x80, 0x80, 0x80,+ 0x00, 0x22, 0x01, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00,+ 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00, 0x6a,+ 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xf4, 0xc2, 0x84, 0x80,+ 0x00, 0x6a, 0x3f, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, 0xb4,+ 0x01, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80,+ 0x80, 0x00, 0x22, 0x01, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28,+ 0x02, 0x00, 0x20, 0x01, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28,+ 0x02, 0x00, 0x22, 0x01, 0x20, 0x00, 0x6a, 0x41, 0x07, 0x6a, 0x41, 0x7c,+ 0x71, 0x22, 0x02, 0x4f, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x01, 0x20, 0x02,+ 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00,+ 0x6a, 0x28, 0x02, 0x00, 0x6b, 0x41, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x0d,+ 0x01, 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x01, 0x6a,+ 0x40, 0x00, 0x41, 0x7f, 0x46, 0x0d, 0x01, 0x3f, 0x00, 0x21, 0x01, 0x23,+ 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x03, 0x41, 0xf4, 0xc2, 0x84, 0x80,+ 0x00, 0x6a, 0x20, 0x01, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x20, 0x03,+ 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x21, 0x01,+ 0x0b, 0x20, 0x01, 0x20, 0x00, 0x36, 0x02, 0x00, 0x23, 0x81, 0x80, 0x80,+ 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36,+ 0x02, 0x00, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x01,+ 0x0b, 0x48, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00,+ 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x22, 0x01, 0x28, 0x02, 0x00, 0x21, 0x02,+ 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00,+ 0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x41, 0x03, 0x6a,+ 0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00,+ 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x01, 0x36, 0x02, 0x00,+ 0x0b, 0x0b, 0x19, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6c, 0x22, 0x00, 0x10,+ 0x88, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, 0x20, 0x00, 0x10, 0x94, 0x80,+ 0x80, 0x80, 0x00, 0x0b, 0x6b, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00,+ 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x28, 0x02,+ 0x00, 0x21, 0x03, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41,+ 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20,+ 0x03, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23,+ 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a,+ 0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x88,+ 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x20, 0x02, 0x28, 0x02, 0x00, 0x10,+ 0x93, 0x80, 0x80, 0x80, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80,+ 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80,+ 0x80, 0x00, 0x00, 0x0b, 0xd5, 0x01, 0x01, 0x03, 0x7f, 0x23, 0x80, 0x80,+ 0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x80, 0x80, 0x80,+ 0x80, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,+ 0x20, 0x00, 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, 0x8f,+ 0x80, 0x80, 0x80, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x08, 0x41,+ 0x01, 0x6a, 0x22, 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x28, 0x02, 0x0c,+ 0x10, 0x88, 0x80, 0x80, 0x80, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20,+ 0x01, 0x41, 0x04, 0x10, 0x8a, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x45,+ 0x0d, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x8e, 0x80, 0x80, 0x80, 0x00,+ 0x0d, 0x04, 0x20, 0x00, 0x28, 0x02, 0x08, 0x20, 0x01, 0x10, 0x84, 0x80,+ 0x80, 0x80, 0x00, 0x21, 0x01, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x24, 0x80,+ 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x0f, 0x0b, 0x41, 0xc7, 0x00, 0x10,+ 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c,+ 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80,+ 0x80, 0x80, 0x00, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80,+ 0x00, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b,+ 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x10, 0x89,+ 0x80, 0x80, 0x80, 0x00, 0x41, 0xc7, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80,+ 0x00, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x80, 0x80,+ 0x80, 0x80, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0b, 0x11, 0x00, 0x20,+ 0x00, 0x20, 0x01, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xff, 0xff,+ 0x03, 0x71, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x82, 0x80, 0x80, 0x80,+ 0x00, 0x00, 0x0b, 0x02, 0x00, 0x0b, 0x0e, 0x00, 0x10, 0x91, 0x80, 0x80,+ 0x80, 0x00, 0x10, 0x91, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xe6, 0x07, 0x01,+ 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x20,+ 0x4b, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20,+ 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a,+ 0x00, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41,+ 0x01, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x05, 0x41,+ 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00,+ 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x7e,+ 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x01,+ 0x41, 0x02, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20,+ 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a,+ 0x00, 0x02, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41,+ 0x03, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x05, 0x41,+ 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00,+ 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x7c,+ 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x01,+ 0x41, 0x04, 0x6a, 0x21, 0x05, 0x0c, 0x02, 0x0b, 0x20, 0x00, 0x20, 0x01,+ 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x02,+ 0x21, 0x03, 0x20, 0x00, 0x21, 0x04, 0x20, 0x01, 0x21, 0x05, 0x0b, 0x02,+ 0x40, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x22, 0x02, 0x0d, 0x00,+ 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20,+ 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x70,+ 0x6a, 0x22, 0x02, 0x41, 0x10, 0x71, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05,+ 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02,+ 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20,+ 0x05, 0x41, 0x10, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x21, 0x03, 0x0b, 0x20,+ 0x02, 0x41, 0x10, 0x49, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x03, 0x40,+ 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04,+ 0x20, 0x05, 0x29, 0x02, 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x20, 0x05,+ 0x29, 0x02, 0x10, 0x37, 0x02, 0x10, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02,+ 0x18, 0x37, 0x02, 0x18, 0x20, 0x04, 0x41, 0x20, 0x6a, 0x21, 0x04, 0x20,+ 0x05, 0x41, 0x20, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x41, 0x60, 0x6a, 0x22,+ 0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x02,+ 0x41, 0x08, 0x49, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00,+ 0x37, 0x02, 0x00, 0x20, 0x05, 0x41, 0x08, 0x6a, 0x21, 0x05, 0x20, 0x04,+ 0x41, 0x08, 0x6a, 0x21, 0x04, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x04,+ 0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x36,+ 0x02, 0x00, 0x20, 0x05, 0x41, 0x04, 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41,+ 0x04, 0x6a, 0x21, 0x04, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x02, 0x71,+ 0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, 0x2f, 0x00, 0x00, 0x3b, 0x00,+ 0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x02,+ 0x6a, 0x21, 0x05, 0x0b, 0x20, 0x02, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x01,+ 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00,+ 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,+ 0x20, 0x03, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20,+ 0x02, 0x41, 0x7f, 0x6a, 0x0e, 0x03, 0x03, 0x00, 0x01, 0x07, 0x0b, 0x20,+ 0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x20,+ 0x05, 0x41, 0x02, 0x6a, 0x28, 0x01, 0x00, 0x36, 0x02, 0x02, 0x20, 0x04,+ 0x20, 0x05, 0x41, 0x06, 0x6a, 0x29, 0x01, 0x00, 0x37, 0x02, 0x06, 0x20,+ 0x04, 0x41, 0x12, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x12, 0x6a, 0x21,+ 0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0e, 0x6a, 0x28, 0x01,+ 0x00, 0x21, 0x05, 0x41, 0x0e, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x04,+ 0x20, 0x05, 0x28, 0x02, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x20, 0x05,+ 0x41, 0x01, 0x6a, 0x28, 0x00, 0x00, 0x36, 0x02, 0x01, 0x20, 0x04, 0x20,+ 0x05, 0x41, 0x05, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, 0x04,+ 0x41, 0x11, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x11, 0x6a, 0x21, 0x01,+ 0x41, 0x0d, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00,+ 0x21, 0x05, 0x41, 0x0f, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x02, 0x40, 0x02,+ 0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20, 0x04, 0x21, 0x02,+ 0x20, 0x05, 0x21, 0x01, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x2d,+ 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x00, 0x01,+ 0x36, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x29, 0x00, 0x05, 0x37, 0x00,+ 0x05, 0x20, 0x04, 0x20, 0x05, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20,+ 0x04, 0x20, 0x05, 0x2d, 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41,+ 0x10, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x0b,+ 0x20, 0x03, 0x41, 0x08, 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04,+ 0x20, 0x05, 0x28, 0x02, 0x00, 0x22, 0x02, 0x3a, 0x00, 0x00, 0x20, 0x04,+ 0x20, 0x02, 0x41, 0x10, 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x02,+ 0x41, 0x08, 0x76, 0x3a, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x03,+ 0x6a, 0x28, 0x00, 0x00, 0x36, 0x02, 0x03, 0x20, 0x04, 0x20, 0x05, 0x41,+ 0x07, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x07, 0x20, 0x04, 0x41, 0x13,+ 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x13, 0x6a, 0x21, 0x01, 0x41, 0x0f,+ 0x21, 0x06, 0x20, 0x05, 0x41, 0x0f, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x05,+ 0x41, 0x0d, 0x21, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x6a, 0x20, 0x05,+ 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, 0x00, 0x37,+ 0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41,+ 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x04, 0x71,+ 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, 0x36, 0x00,+ 0x00, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04,+ 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x02, 0x71, 0x45,+ 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00,+ 0x20, 0x02, 0x41, 0x02, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x02, 0x6a,+ 0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x20,+ 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00,+ 0x0b, 0x88, 0x03, 0x02, 0x03, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x20, 0x02,+ 0x41, 0x21, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc,+ 0x0b, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x45, 0x0d,+ 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x20, 0x00,+ 0x6a, 0x22, 0x03, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20,+ 0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00,+ 0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x41, 0x7d,+ 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7e, 0x6a, 0x20,+ 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x07, 0x49, 0x0d, 0x00, 0x20,+ 0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x20,+ 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20,+ 0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, 0x41, 0x03, 0x71, 0x22, 0x04, 0x6a,+ 0x22, 0x05, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, 0x84,+ 0x08, 0x6c, 0x22, 0x03, 0x36, 0x02, 0x00, 0x20, 0x05, 0x20, 0x02, 0x20,+ 0x04, 0x6b, 0x41, 0x7c, 0x71, 0x22, 0x01, 0x6a, 0x22, 0x02, 0x41, 0x7c,+ 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x09, 0x49, 0x0d,+ 0x00, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x08, 0x20, 0x05, 0x20, 0x03,+ 0x36, 0x02, 0x04, 0x20, 0x02, 0x41, 0x78, 0x6a, 0x20, 0x03, 0x36, 0x02,+ 0x00, 0x20, 0x02, 0x41, 0x74, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20,+ 0x01, 0x41, 0x19, 0x49, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02,+ 0x18, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x14, 0x20, 0x05, 0x20, 0x03,+ 0x36, 0x02, 0x10, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x0c, 0x20, 0x02,+ 0x41, 0x70, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x6c,+ 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x68, 0x6a, 0x20,+ 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x64, 0x6a, 0x20, 0x03, 0x36,+ 0x02, 0x00, 0x20, 0x01, 0x20, 0x05, 0x41, 0x04, 0x71, 0x41, 0x18, 0x72,+ 0x22, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x20, 0x03,+ 0xad, 0x42, 0x81, 0x80, 0x80, 0x80, 0x10, 0x7e, 0x21, 0x06, 0x20, 0x05,+ 0x20, 0x02, 0x6a, 0x21, 0x02, 0x03, 0x40, 0x20, 0x02, 0x20, 0x06, 0x37,+ 0x03, 0x18, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x10, 0x20, 0x02, 0x20,+ 0x06, 0x37, 0x03, 0x08, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20,+ 0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x60, 0x6a, 0x22,+ 0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0xcc,+ 0x01, 0x01, 0x03, 0x7f, 0x20, 0x00, 0x21, 0x01, 0x02, 0x40, 0x02, 0x40,+ 0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00,+ 0x2d, 0x00, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x6b, 0x0f, 0x0b,+ 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d,+ 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41,+ 0x02, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01,+ 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22,+ 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00,+ 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03,+ 0x71, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20,+ 0x01, 0x41, 0x7b, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04,+ 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x28, 0x02,+ 0x00, 0x22, 0x03, 0x41, 0x7f, 0x73, 0x20, 0x03, 0x41, 0xff, 0xfd, 0xfb,+ 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x45, 0x0d,+ 0x00, 0x0b, 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20,+ 0x02, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x21,+ 0x02, 0x20, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b,+ 0x0b, 0x44, 0x00, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b,+ 0x0d, 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x41, 0x80, 0x80, 0x84, 0x80,+ 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x05, 0x74, 0x20, 0x00, 0x41, 0x03,+ 0x76, 0x41, 0x1f, 0x71, 0x72, 0x41, 0x80, 0x80, 0x84, 0x80, 0x00, 0x6a,+ 0x2d, 0x00, 0x00, 0x20, 0x00, 0x41, 0x07, 0x71, 0x76, 0x41, 0x01, 0x71,+ 0x0f, 0x0b, 0x20, 0x00, 0x41, 0xfe, 0xff, 0x0b, 0x49, 0x0b, 0x49, 0x01,+ 0x03, 0x7f, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, 0x45, 0x0d,+ 0x00, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x04,+ 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x47, 0x0d, 0x01, 0x20, 0x01,+ 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00,+ 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0c, 0x02, 0x0b,+ 0x0b, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, 0x0b, 0x20, 0x03, 0x0b,+ 0xf2, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, 0x03,+ 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03,+ 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20,+ 0x00, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x47, 0x0d,+ 0x00, 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b,+ 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03,+ 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d,+ 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20,+ 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7e,+ 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x02,+ 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45,+ 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01,+ 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41,+ 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, 0x04, 0x41,+ 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04,+ 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02,+ 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x7c, 0x6a,+ 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02,+ 0x21, 0x05, 0x20, 0x00, 0x21, 0x04, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x01,+ 0x02, 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01,+ 0x71, 0x46, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x20,+ 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x21,+ 0x00, 0x03, 0x40, 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x73, 0x22,+ 0x02, 0x41, 0x7f, 0x73, 0x20, 0x02, 0x41, 0xff, 0xfd, 0xfb, 0x77, 0x6a,+ 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x0d, 0x02, 0x20, 0x04,+ 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x05,+ 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x01,+ 0x0b, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x21, 0x02, 0x03, 0x40, 0x02,+ 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x02, 0x47, 0x0d, 0x00, 0x20,+ 0x04, 0x0f, 0x0b, 0x20, 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x05,+ 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, 0x0b,+ 0x67, 0x01, 0x02, 0x7f, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x02,+ 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20,+ 0x03, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00,+ 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01,+ 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x20, 0x00, 0x2d,+ 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a,+ 0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x20,+ 0x02, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03,+ 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x6b, 0x0b, 0x0c, 0x00, 0x20, 0x00,+ 0x41, 0x00, 0x10, 0x9b, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xbc, 0x02, 0x01,+ 0x06, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d,+ 0x00, 0x20, 0x00, 0x20, 0x00, 0x41, 0xff, 0x01, 0x71, 0x22, 0x02, 0x41,+ 0x03, 0x6e, 0x22, 0x03, 0x41, 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71,+ 0x41, 0x02, 0x74, 0x41, 0xc0, 0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02,+ 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x22, 0x04, 0x41, 0xa0, 0xa9, 0x84,+ 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0xd6, 0x00, 0x6c, 0x20, 0x03,+ 0x6a, 0x41, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x6c,+ 0x41, 0x0b, 0x76, 0x41, 0x06, 0x70, 0x20, 0x04, 0x41, 0x90, 0xbe, 0x84,+ 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x6a, 0x41, 0x02, 0x74, 0x41, 0xd0,+ 0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x03, 0x41, 0x08,+ 0x75, 0x21, 0x04, 0x02, 0x40, 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x22,+ 0x03, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, 0x04, 0x41, 0x00, 0x20, 0x03,+ 0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04,+ 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x41,+ 0x08, 0x76, 0x21, 0x04, 0x03, 0x40, 0x02, 0x40, 0x20, 0x02, 0x20, 0x03,+ 0x41, 0x01, 0x76, 0x22, 0x05, 0x20, 0x04, 0x6a, 0x22, 0x06, 0x41, 0x01,+ 0x74, 0x41, 0x90, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x22,+ 0x07, 0x47, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x06, 0x41, 0x01, 0x74, 0x41,+ 0x91, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x02, 0x74,+ 0x41, 0xd0, 0x9e, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x03,+ 0x41, 0xff, 0x01, 0x71, 0x22, 0x04, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20,+ 0x03, 0x41, 0x08, 0x75, 0x41, 0x00, 0x20, 0x04, 0x20, 0x01, 0x73, 0x6b,+ 0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, 0x01, 0x20, 0x01,+ 0x1b, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x20, 0x02,+ 0x20, 0x07, 0x49, 0x22, 0x07, 0x1b, 0x21, 0x04, 0x20, 0x05, 0x20, 0x03,+ 0x20, 0x05, 0x6b, 0x20, 0x07, 0x1b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b,+ 0x20, 0x00, 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x01, 0x10, 0x9b, 0x80,+ 0x80, 0x80, 0x00, 0x0b, 0x7b, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02,+ 0x0d, 0x00, 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00,+ 0x2d, 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01,+ 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x03, 0x40,+ 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22,+ 0x04, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x41,+ 0x00, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x20,+ 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x21,+ 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x0d, 0x00,+ 0x0b, 0x0b, 0x41, 0x00, 0x21, 0x03, 0x0b, 0x20, 0x03, 0x41, 0xff, 0x01,+ 0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, 0x0b, 0x0d, 0x00, 0x20, 0x00,+ 0x10, 0x9a, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x47, 0x0b, 0xbf, 0x09,+ 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41,+ 0x21, 0x4f, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x46, 0x0d, 0x02, 0x20,+ 0x01, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x6b, 0x41, 0x00, 0x20,+ 0x02, 0x41, 0x01, 0x74, 0x6b, 0x4b, 0x0d, 0x01, 0x0b, 0x20, 0x00, 0x20,+ 0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01,+ 0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40,+ 0x02, 0x40, 0x20, 0x00, 0x20, 0x01, 0x4f, 0x0d, 0x00, 0x02, 0x40, 0x20,+ 0x04, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03,+ 0x0c, 0x03, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, 0x0d, 0x00,+ 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x20,+ 0x02, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a,+ 0x00, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20,+ 0x00, 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20,+ 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45,+ 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01,+ 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41,+ 0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41,+ 0x02, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03,+ 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02,+ 0x41, 0x7d, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x6a,+ 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x6a,+ 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, 0x00,+ 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x41, 0x04,+ 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02,+ 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x04,+ 0x0d, 0x00, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00,+ 0x20, 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a,+ 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00,+ 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d,+ 0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d,+ 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x03, 0x6a, 0x22,+ 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,+ 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21,+ 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20,+ 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20,+ 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04,+ 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b,+ 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a,+ 0x22, 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a,+ 0x00, 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40,+ 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x06, 0x41, 0x02, 0x76, 0x41, 0x01,+ 0x6a, 0x41, 0x03, 0x71, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x41,+ 0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03,+ 0x40, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x20, 0x04, 0x20, 0x02, 0x6a, 0x28,+ 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x02,+ 0x20, 0x03, 0x41, 0x7f, 0x6a, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20,+ 0x06, 0x41, 0x0c, 0x49, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x70, 0x6a, 0x21,+ 0x05, 0x20, 0x00, 0x41, 0x70, 0x6a, 0x21, 0x06, 0x03, 0x40, 0x20, 0x06,+ 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x05, 0x20, 0x02,+ 0x6a, 0x22, 0x04, 0x41, 0x0c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00,+ 0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x28, 0x02,+ 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x04, 0x41,+ 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x04,+ 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x70, 0x6a, 0x22,+ 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d,+ 0x02, 0x20, 0x02, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, 0x41, 0x03, 0x71,+ 0x22, 0x04, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x7f, 0x6a, 0x21, 0x05,+ 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x21, 0x06, 0x20, 0x02, 0x21, 0x03, 0x03,+ 0x40, 0x20, 0x06, 0x20, 0x03, 0x6a, 0x20, 0x05, 0x20, 0x03, 0x6a, 0x2d,+ 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7f, 0x6a, 0x21, 0x03,+ 0x20, 0x04, 0x41, 0x7f, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20,+ 0x02, 0x41, 0x04, 0x49, 0x0d, 0x02, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21,+ 0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05,+ 0x20, 0x03, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x6a, 0x20, 0x04, 0x20, 0x03,+ 0x6a, 0x22, 0x02, 0x41, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00,+ 0x20, 0x01, 0x41, 0x02, 0x6a, 0x20, 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00,+ 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41,+ 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x20, 0x02,+ 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22,+ 0x03, 0x0d, 0x00, 0x0c, 0x03, 0x0b, 0x0b, 0x20, 0x05, 0x41, 0x04, 0x49,+ 0x0d, 0x00, 0x02, 0x40, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x41,+ 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x07, 0x71, 0x22, 0x02, 0x45, 0x0d,+ 0x00, 0x20, 0x05, 0x20, 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x05, 0x03,+ 0x40, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20,+ 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21,+ 0x03, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b,+ 0x20, 0x04, 0x41, 0x1c, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20,+ 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x01, 0x28,+ 0x02, 0x04, 0x36, 0x02, 0x04, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x08,+ 0x36, 0x02, 0x08, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02,+ 0x0c, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20,+ 0x03, 0x20, 0x01, 0x28, 0x02, 0x14, 0x36, 0x02, 0x14, 0x20, 0x03, 0x20,+ 0x01, 0x28, 0x02, 0x18, 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x01, 0x28,+ 0x02, 0x1c, 0x36, 0x02, 0x1c, 0x20, 0x01, 0x41, 0x20, 0x6a, 0x21, 0x01,+ 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, 0x20, 0x05, 0x41, 0x60, 0x6a,+ 0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45,+ 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x05, 0x41, 0x07, 0x71, 0x22,+ 0x02, 0x0d, 0x00, 0x20, 0x05, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x05,+ 0x41, 0x78, 0x71, 0x21, 0x04, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d,+ 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03,+ 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a,+ 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x41, 0x08, 0x49, 0x0d,+ 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00,+ 0x00, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20,+ 0x03, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x03, 0x20,+ 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x03, 0x20, 0x01, 0x2d,+ 0x00, 0x04, 0x3a, 0x00, 0x04, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x05,+ 0x3a, 0x00, 0x05, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x06, 0x3a, 0x00,+ 0x06, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x07, 0x3a, 0x00, 0x07, 0x20,+ 0x03, 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21,+ 0x01, 0x20, 0x04, 0x41, 0x78, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b,+ 0x20, 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x9c, 0x80, 0x80, 0x80,+ 0x00, 0x20, 0x00, 0x47, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x20, 0x46,+ 0x20, 0x00, 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x10,+ 0xa1, 0x80, 0x80, 0x80, 0x00, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x41, 0x50,+ 0x6a, 0x41, 0x0a, 0x49, 0x0b, 0x4d, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x20,+ 0x00, 0x10, 0x95, 0x80, 0x80, 0x80, 0x00, 0x6a, 0x21, 0x03, 0x02, 0x40,+ 0x20, 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00,+ 0x22, 0x04, 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, 0x00,+ 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a,+ 0x21, 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b,+ 0x0b, 0x20, 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, 0xef,+ 0x03, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,+ 0x02, 0x40, 0x20, 0x01, 0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x45, 0x0d,+ 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00,+ 0x47, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71,+ 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20,+ 0x02, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x00,+ 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x03, 0x3a, 0x00, 0x00, 0x02, 0x40,+ 0x20, 0x03, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x20, 0x02, 0x21, 0x05,+ 0x0c, 0x05, 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x02,+ 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40,+ 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d,+ 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00,+ 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x05, 0x20,+ 0x00, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22,+ 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x02,+ 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45,+ 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a,+ 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x06, 0x20, 0x00, 0x41, 0x03, 0x6a,+ 0x21, 0x03, 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47,+ 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x06, 0x41,+ 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03,+ 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04,+ 0x45, 0x0d, 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01,+ 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02,+ 0x41, 0x00, 0x47, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x06, 0x21, 0x01,+ 0x20, 0x05, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20,+ 0x05, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05,+ 0x21, 0x02, 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x02, 0x40, 0x20, 0x01,+ 0x2d, 0x00, 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x04, 0x0b,+ 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x28,+ 0x02, 0x00, 0x22, 0x00, 0x41, 0x7f, 0x73, 0x20, 0x00, 0x41, 0xff, 0xfd,+ 0xfb, 0x77, 0x6a, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x0d,+ 0x02, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04,+ 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02,+ 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b,+ 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01,+ 0x2d, 0x00, 0x00, 0x22, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x00,+ 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b, 0x20, 0x03, 0x41,+ 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20,+ 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00,+ 0x21, 0x05, 0x0b, 0x20, 0x03, 0x41, 0x00, 0x20, 0x05, 0x10, 0x94, 0x80,+ 0x80, 0x80, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02,+ 0x10, 0xa5, 0x80, 0x80, 0x80, 0x00, 0x1a, 0x20, 0x00, 0x0b, 0x17, 0x00,+ 0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, 0x0a, 0x49, 0x20, 0x00, 0x41, 0x20,+ 0x72, 0x41, 0x9f, 0x7f, 0x6a, 0x41, 0x06, 0x49, 0x72, 0x0b, 0x2a, 0x01,+ 0x03, 0x7f, 0x41, 0x00, 0x21, 0x01, 0x03, 0x40, 0x20, 0x00, 0x20, 0x01,+ 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x03, 0x21, 0x01,+ 0x20, 0x02, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x7c,+ 0x6a, 0x41, 0x02, 0x75, 0x0b, 0x45, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20,+ 0x01, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x00, 0x02,+ 0x40, 0x03, 0x40, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x00, 0x28, 0x02,+ 0x00, 0x22, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x20, 0x01, 0x47, 0x0d,+ 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x41, 0x00, 0x20, 0x02, 0x1b, 0x0f, 0x0b,+ 0x20, 0x00, 0x20, 0x00, 0x10, 0xa8, 0x80, 0x80, 0x80, 0x00, 0x41, 0x02,+ 0x74, 0x6a, 0x0b, 0x1d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x0d, 0x00, 0x41,+ 0x00, 0x0f, 0x0b, 0x41, 0x90, 0xc2, 0x84, 0x80, 0x00, 0x20, 0x00, 0x10,+ 0xa9, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, 0x47, 0x0b, 0x24, 0x01, 0x01,+ 0x7f, 0x41, 0x01, 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x41, 0x50, 0x6a,+ 0x41, 0x0a, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x96, 0x80, 0x80, 0x80,+ 0x00, 0x41, 0x00, 0x47, 0x21, 0x01, 0x0b, 0x20, 0x01, 0x0b, 0x0b, 0xf1,+ 0x42, 0x01, 0x00, 0x41, 0x80, 0x80, 0x04, 0x0b, 0xe8, 0x42, 0x12, 0x11,+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,+ 0x1f, 0x20, 0x21, 0x11, 0x22, 0x23, 0x24, 0x11, 0x25, 0x26, 0x27, 0x28,+ 0x29, 0x2a, 0x2b, 0x2c, 0x11, 0x2d, 0x2e, 0x2f, 0x10, 0x10, 0x30, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x31, 0x32, 0x33, 0x10, 0x34, 0x35,+ 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x37, 0x11, 0x11, 0x11, 0x11, 0x38, 0x11, 0x39, 0x3a, 0x3b, 0x3c,+ 0x3d, 0x3e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x40, 0x41, 0x11, 0x42,+ 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x11, 0x4b, 0x4c, 0x4d,+ 0x4e, 0x4f, 0x50, 0x51, 0x10, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,+ 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x10, 0x5e, 0x5f, 0x60, 0x10, 0x11, 0x11,+ 0x11, 0x61, 0x62, 0x63, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x64, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,+ 0x65, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,+ 0x66, 0x67, 0x10, 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x6a, 0x11, 0x11, 0x6b, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x6c,+ 0x6d, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6e, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6f, 0x70,+ 0x71, 0x72, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x73, 0x74,+ 0x75, 0x10, 0x10, 0x10, 0x10, 0x10, 0x76, 0x77, 0x10, 0x10, 0x10, 0x10,+ 0x78, 0x10, 0x10, 0x79, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff,+ 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xff, 0xff,+ 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0x03, 0x00, 0x1f, 0x50,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0xdf, 0xbc, 0x40, 0xd7, 0xff, 0xff, 0xfb, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xb6, 0x00, 0xff, 0xff, 0xff, 0x87,+ 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xfe, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xef, 0x1f, 0xfe, 0xe1, 0xff, 0x9f, 0x00, 0x00,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x07, 0x30, 0x04, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x1f,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xdf, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xf8, 0x03,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xdf,+ 0xe1, 0xff, 0xcf, 0xff, 0xfe, 0xff, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd,+ 0xc5, 0xe3, 0x9f, 0x59, 0x80, 0xb0, 0xcf, 0xff, 0x03, 0x10, 0xee, 0x87,+ 0xf9, 0xff, 0xff, 0xfd, 0x6d, 0xc3, 0x87, 0x19, 0x02, 0x5e, 0xc0, 0xff,+ 0x3f, 0x00, 0xee, 0xbf, 0xfb, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0xbf, 0x1b,+ 0x01, 0x00, 0xcf, 0xff, 0x00, 0x1e, 0xee, 0x9f, 0xf9, 0xff, 0xff, 0xfd,+ 0xed, 0xe3, 0x9f, 0x19, 0xc0, 0xb0, 0xcf, 0xff, 0x02, 0x00, 0xec, 0xc7,+ 0x3d, 0xd6, 0x18, 0xc7, 0xff, 0xc3, 0xc7, 0x1d, 0x81, 0x00, 0xc0, 0xff,+ 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xe3, 0xdf, 0x1d,+ 0x60, 0x07, 0xcf, 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd,+ 0xef, 0xe3, 0xdf, 0x1d, 0x60, 0x40, 0xcf, 0xff, 0x06, 0x00, 0xef, 0xdf,+ 0xfd, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdf, 0x5d, 0xf0, 0x80, 0xcf, 0xff,+ 0x00, 0xfc, 0xec, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xfb, 0x2f, 0x7f, 0x80,+ 0x5f, 0xff, 0xc0, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f,+ 0xff, 0x07, 0x3f, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf7,+ 0xff, 0xff, 0xaf, 0xff, 0xff, 0x3b, 0x5f, 0x20, 0xff, 0xf3, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0xfe,+ 0xff, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xff,+ 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf9, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d,+ 0xff, 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0x7f, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0xff,+ 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7,+ 0xff, 0x01, 0xff, 0xdf, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff,+ 0x0f, 0x00, 0xff, 0xdf, 0x0d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xcf, 0xff, 0xff, 0x01, 0x80, 0x10, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,+ 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f,+ 0xff, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0x00, 0xff, 0x03, 0xff, 0x03, 0x80, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0x0f, 0xff, 0x03, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xbf, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x7f, 0x00, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x01,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,+ 0x6f, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff, 0xff,+ 0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xaa, 0xff, 0xff,+ 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x5f, 0xdc, 0x1f,+ 0xcf, 0x0f, 0xff, 0x1f, 0xdc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00,+ 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x84, 0xfc, 0x2f, 0x3e, 0x50, 0xbd, 0xff, 0xf3, 0xe0, 0x43,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x78,+ 0x0c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0x7f,+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x03,+ 0x3e, 0x1f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x7f, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xf7, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x1f,+ 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,+ 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xfc, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x80, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0x2f, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xe8, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,+ 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x80,+ 0xff, 0x03, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x7f, 0x00, 0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x38, 0xff, 0xff,+ 0x3c, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xf7, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x03, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x7f, 0xf8,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,+ 0x00, 0x00, 0x7f, 0x00, 0xf8, 0xe0, 0xff, 0xfd, 0x7f, 0x5f, 0xdb, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x03, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x1f, 0x00, 0x00, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff,+ 0xff, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x7f, 0xfc, 0xfc, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef,+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xb7, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x07, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff,+ 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff,+ 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xff, 0xff, 0xff,+ 0xbf, 0x91, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff,+ 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0x37, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xf0,+ 0xef, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe,+ 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x3f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x00,+ 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00,+ 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x70, 0x00, 0xff, 0xff, 0xff, 0xff,+ 0x47, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00,+ 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff,+ 0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbd,+ 0xff, 0xbf, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01,+ 0xff, 0x03, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19,+ 0x81, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, 0x07, 0xff, 0x83, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0x00,+ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0x3f, 0x7f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x11, 0x00,+ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x3f, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xe7, 0xff, 0x07, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xe7, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff,+ 0x7f, 0x7f, 0x01, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff,+ 0xfc, 0xff, 0xff, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x7f, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xb4, 0xcb, 0x00,+ 0xff, 0x03, 0xbf, 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x01, 0xff, 0x03,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x03,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0x00, 0x00, 0x0f, 0x00, 0xff, 0x03, 0xf8, 0xff, 0xff, 0xe0, 0xff, 0xff,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff,+ 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf0, 0x00,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x07, 0xff, 0x1f, 0xff, 0x01, 0xff, 0x43, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x64, 0xde, 0xff, 0xeb, 0xef, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xe7, 0xdf, 0xdf, 0xff, 0xff,+ 0xff, 0x7b, 0x5f, 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff,+ 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff,+ 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f,+ 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xcf,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x3f, 0xff, 0x43,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x08,+ 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff,+ 0xff, 0xff, 0x96, 0xfe, 0xf7, 0x0a, 0x84, 0xea, 0x96, 0xaa, 0x96, 0xf7,+ 0xf7, 0x5e, 0xff, 0xfb, 0xff, 0x0f, 0xee, 0xfb, 0xff, 0x0f, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x39, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,+ 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0xbf, 0x1d, 0x00, 0x00, 0xe7,+ 0x02, 0x00, 0x00, 0x79, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x01,+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,+ 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x39, 0xff, 0xff, 0x00, 0x18,+ 0xff, 0xff, 0x01, 0x87, 0xff, 0xff, 0x00, 0xd4, 0xfe, 0xff, 0x00, 0xc3,+ 0x00, 0x00, 0x01, 0xd2, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xcd,+ 0x00, 0x00, 0x01, 0x4f, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcb,+ 0x00, 0x00, 0x01, 0xcf, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x01, 0xd3,+ 0x00, 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x01, 0xd5,+ 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0xd6, 0x00, 0x00, 0x01, 0xda,+ 0x00, 0x00, 0x01, 0xd9, 0x00, 0x00, 0x01, 0xdb, 0x00, 0x00, 0x00, 0x38,+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xff, 0xff, 0x01, 0x9f,+ 0xff, 0xff, 0x01, 0xc8, 0xff, 0xff, 0x02, 0x28, 0x24, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x33,+ 0xff, 0xff, 0x00, 0x26, 0xff, 0xff, 0x01, 0x7e, 0xff, 0xff, 0x01, 0x2b,+ 0x2a, 0x00, 0x01, 0x5d, 0xff, 0xff, 0x01, 0x28, 0x2a, 0x00, 0x00, 0x3f,+ 0x2a, 0x00, 0x01, 0x3d, 0xff, 0xff, 0x01, 0x45, 0x00, 0x00, 0x01, 0x47,+ 0x00, 0x00, 0x00, 0x1f, 0x2a, 0x00, 0x00, 0x1c, 0x2a, 0x00, 0x00, 0x1e,+ 0x2a, 0x00, 0x00, 0x2e, 0xff, 0xff, 0x00, 0x32, 0xff, 0xff, 0x00, 0x36,+ 0xff, 0xff, 0x00, 0x35, 0xff, 0xff, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x4b,+ 0xa5, 0x00, 0x00, 0x31, 0xff, 0xff, 0x00, 0x28, 0xa5, 0x00, 0x00, 0x44,+ 0xa5, 0x00, 0x00, 0x2f, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xff, 0x00, 0xf7,+ 0x29, 0x00, 0x00, 0x41, 0xa5, 0x00, 0x00, 0xfd, 0x29, 0x00, 0x00, 0x2b,+ 0xff, 0xff, 0x00, 0x2a, 0xff, 0xff, 0x00, 0xe7, 0x29, 0x00, 0x00, 0x43,+ 0xa5, 0x00, 0x00, 0x2a, 0xa5, 0x00, 0x00, 0xbb, 0xff, 0xff, 0x00, 0x27,+ 0xff, 0xff, 0x00, 0xb9, 0xff, 0xff, 0x00, 0x25, 0xff, 0xff, 0x00, 0x15,+ 0xa5, 0x00, 0x00, 0x12, 0xa5, 0x00, 0x02, 0x24, 0x4c, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x01,+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x54, 0x00, 0x00, 0x01, 0x74,+ 0x00, 0x00, 0x01, 0x26, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x40,+ 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, 0xda, 0xff, 0xff, 0x00, 0xdb,+ 0xff, 0xff, 0x00, 0xe1, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc1,+ 0xff, 0xff, 0x01, 0x08, 0x00, 0x00, 0x00, 0xc2, 0xff, 0xff, 0x00, 0xc7,+ 0xff, 0xff, 0x00, 0xd1, 0xff, 0xff, 0x00, 0xca, 0xff, 0xff, 0x00, 0xf8,+ 0xff, 0xff, 0x00, 0xaa, 0xff, 0xff, 0x00, 0xb0, 0xff, 0xff, 0x00, 0x07,+ 0x00, 0x00, 0x00, 0x8c, 0xff, 0xff, 0x01, 0xc4, 0xff, 0xff, 0x00, 0xa0,+ 0xff, 0xff, 0x01, 0xf9, 0xff, 0xff, 0x02, 0x1a, 0x70, 0x00, 0x01, 0x01,+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0,+ 0xff, 0xff, 0x01, 0x50, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0xf1,+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0,+ 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x01, 0x60, 0x1c, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0xd0, 0x97, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0xf8,+ 0xff, 0xff, 0x02, 0x05, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40,+ 0xf4, 0xff, 0x00, 0x9e, 0xe7, 0xff, 0x00, 0xc2, 0x89, 0x00, 0x00, 0xdb,+ 0xe7, 0xff, 0x00, 0x92, 0xe7, 0xff, 0x00, 0x93, 0xe7, 0xff, 0x00, 0x9c,+ 0xe7, 0xff, 0x00, 0x9d, 0xe7, 0xff, 0x00, 0xa4, 0xe7, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x38, 0x8a, 0x00, 0x00, 0x04, 0x8a, 0x00, 0x00, 0xe6,+ 0x0e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0xc5, 0xff, 0xff, 0x01, 0x41, 0xe2, 0xff, 0x02, 0x1d,+ 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0xf8, 0xff, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x4a,+ 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70,+ 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0xb6,+ 0xff, 0xff, 0x01, 0xf7, 0xff, 0xff, 0x00, 0xdb, 0xe3, 0xff, 0x01, 0x9c,+ 0xff, 0xff, 0x01, 0x90, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x82,+ 0xff, 0xff, 0x02, 0x05, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10,+ 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x1c, 0x00, 0x00, 0x01, 0x01,+ 0x00, 0x00, 0x01, 0xa3, 0xe2, 0xff, 0x01, 0x41, 0xdf, 0xff, 0x01, 0xba,+ 0xdf, 0xff, 0x00, 0xe4, 0xff, 0xff, 0x02, 0x0b, 0xb1, 0x00, 0x01, 0x01,+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0,+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xd6, 0xff, 0x01, 0x1a,+ 0xf1, 0xff, 0x01, 0x19, 0xd6, 0xff, 0x00, 0xd5, 0xd5, 0xff, 0x00, 0xd8,+ 0xd5, 0xff, 0x01, 0xe4, 0xd5, 0xff, 0x01, 0x03, 0xd6, 0xff, 0x01, 0xe1,+ 0xd5, 0xff, 0x01, 0xe2, 0xd5, 0xff, 0x01, 0xc1, 0xd5, 0xff, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0xa0, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, 0x0c, 0xbc, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xbc,+ 0x5a, 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, 0xfc, 0x75, 0xff, 0x01, 0xd8,+ 0x5a, 0xff, 0x00, 0x30, 0x00, 0x00, 0x01, 0xb1, 0x5a, 0xff, 0x01, 0xb5,+ 0x5a, 0xff, 0x01, 0xbf, 0x5a, 0xff, 0x01, 0xee, 0x5a, 0xff, 0x01, 0xd6,+ 0x5a, 0xff, 0x01, 0xeb, 0x5a, 0xff, 0x01, 0xd0, 0xff, 0xff, 0x01, 0xbd,+ 0x5a, 0xff, 0x01, 0xc8, 0x75, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,+ 0x68, 0xff, 0x00, 0x60, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,+ 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28,+ 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40,+ 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,+ 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,+ 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22,+ 0x00, 0x00, 0x00, 0xde, 0xff, 0xff, 0x30, 0x0c, 0x31, 0x0d, 0x78, 0x0e,+ 0x7f, 0x0f, 0x80, 0x10, 0x81, 0x11, 0x86, 0x12, 0x89, 0x13, 0x8a, 0x13,+ 0x8e, 0x14, 0x8f, 0x15, 0x90, 0x16, 0x93, 0x13, 0x94, 0x17, 0x95, 0x18,+ 0x96, 0x19, 0x97, 0x1a, 0x9a, 0x1b, 0x9c, 0x19, 0x9d, 0x1c, 0x9e, 0x1d,+ 0x9f, 0x1e, 0xa6, 0x1f, 0xa9, 0x1f, 0xae, 0x1f, 0xb1, 0x20, 0xb2, 0x20,+ 0xb7, 0x21, 0xbf, 0x22, 0xc5, 0x23, 0xc8, 0x23, 0xcb, 0x23, 0xdd, 0x24,+ 0xf2, 0x23, 0xf6, 0x25, 0xf7, 0x26, 0x20, 0x2d, 0x3a, 0x2e, 0x3d, 0x2f,+ 0x3e, 0x30, 0x3f, 0x31, 0x40, 0x31, 0x43, 0x32, 0x44, 0x33, 0x45, 0x34,+ 0x50, 0x35, 0x51, 0x36, 0x52, 0x37, 0x53, 0x38, 0x54, 0x39, 0x59, 0x3a,+ 0x5b, 0x3b, 0x5c, 0x3c, 0x61, 0x3d, 0x63, 0x3e, 0x65, 0x3f, 0x66, 0x40,+ 0x68, 0x41, 0x69, 0x42, 0x6a, 0x40, 0x6b, 0x43, 0x6c, 0x44, 0x6f, 0x42,+ 0x71, 0x45, 0x72, 0x46, 0x75, 0x47, 0x7d, 0x48, 0x82, 0x49, 0x87, 0x4a,+ 0x89, 0x4b, 0x8a, 0x4c, 0x8b, 0x4c, 0x8c, 0x4d, 0x92, 0x4e, 0x9d, 0x4f,+ 0x9e, 0x50, 0x45, 0x57, 0x7b, 0x1d, 0x7c, 0x1d, 0x7d, 0x1d, 0x7f, 0x58,+ 0x86, 0x59, 0x88, 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x8c, 0x5b, 0x8e, 0x5c,+ 0x8f, 0x5c, 0xac, 0x5d, 0xad, 0x5e, 0xae, 0x5e, 0xaf, 0x5e, 0xc2, 0x5f,+ 0xcc, 0x60, 0xcd, 0x61, 0xce, 0x61, 0xcf, 0x62, 0xd0, 0x63, 0xd1, 0x64,+ 0xd5, 0x65, 0xd6, 0x66, 0xd7, 0x67, 0xf0, 0x68, 0xf1, 0x69, 0xf2, 0x6a,+ 0xf3, 0x6b, 0xf4, 0x6c, 0xf5, 0x6d, 0xf9, 0x6e, 0xfd, 0x2d, 0xfe, 0x2d,+ 0xff, 0x2d, 0x50, 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54, 0x69,+ 0x55, 0x69, 0x56, 0x69, 0x57, 0x69, 0x58, 0x69, 0x59, 0x69, 0x5a, 0x69,+ 0x5b, 0x69, 0x5c, 0x69, 0x5d, 0x69, 0x5e, 0x69, 0x5f, 0x69, 0x82, 0x00,+ 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00,+ 0x89, 0x00, 0xc0, 0x75, 0xcf, 0x76, 0x80, 0x89, 0x81, 0x8a, 0x82, 0x8b,+ 0x85, 0x8c, 0x86, 0x8d, 0x70, 0x9d, 0x71, 0x9d, 0x76, 0x9e, 0x77, 0x9e,+ 0x78, 0x9f, 0x79, 0x9f, 0x7a, 0xa0, 0x7b, 0xa0, 0x7c, 0xa1, 0x7d, 0xa1,+ 0xb3, 0xa2, 0xba, 0xa3, 0xbb, 0xa3, 0xbc, 0xa4, 0xbe, 0xa5, 0xc3, 0xa2,+ 0xcc, 0xa4, 0xda, 0xa6, 0xdb, 0xa6, 0xe5, 0x6a, 0xea, 0xa7, 0xeb, 0xa7,+ 0xec, 0x6e, 0xf3, 0xa2, 0xf8, 0xa8, 0xf9, 0xa8, 0xfa, 0xa9, 0xfb, 0xa9,+ 0xfc, 0xa4, 0x26, 0xb0, 0x2a, 0xb1, 0x2b, 0xb2, 0x4e, 0xb3, 0x84, 0x08,+ 0x62, 0xba, 0x63, 0xbb, 0x64, 0xbc, 0x65, 0xbd, 0x66, 0xbe, 0x6d, 0xbf,+ 0x6e, 0xc0, 0x6f, 0xc1, 0x70, 0xc2, 0x7e, 0xc3, 0x7f, 0xc3, 0x7d, 0xcf,+ 0x8d, 0xd0, 0x94, 0xd1, 0xab, 0xd2, 0xac, 0xd3, 0xad, 0xd4, 0xb0, 0xd5,+ 0xb1, 0xd6, 0xb2, 0xd7, 0xc4, 0xd8, 0xc5, 0xd9, 0xc6, 0xda, 0x07, 0x08,+ 0x09, 0x0a, 0x0b, 0x0c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x0d, 0x06, 0x06, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x0f, 0x10, 0x11, 0x12, 0x06, 0x13, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x14, 0x15, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x16, 0x17, 0x06, 0x06,+ 0x06, 0x18, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x19, 0x06, 0x06, 0x06, 0x06, 0x1a, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x1b, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,+ 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x54, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x18, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07,+ 0x2b, 0x2b, 0x5b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x4a, 0x56,+ 0x56, 0x05, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x24, 0x50, 0x79, 0x31, 0x50, 0x31,+ 0x50, 0x31, 0x38, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x02, 0x4e, 0x0d, 0x0d,+ 0x4e, 0x03, 0x4e, 0x00, 0x24, 0x6e, 0x00, 0x4e, 0x31, 0x26, 0x6e, 0x51,+ 0x4e, 0x24, 0x50, 0x4e, 0x39, 0x14, 0x81, 0x1b, 0x1d, 0x1d, 0x53, 0x31,+ 0x50, 0x31, 0x50, 0x0d, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x1b, 0x53,+ 0x24, 0x50, 0x31, 0x02, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b,+ 0x5c, 0x7b, 0x14, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x49,+ 0x03, 0x48, 0x03, 0x78, 0x5c, 0x7b, 0x14, 0x00, 0x96, 0x0a, 0x01, 0x2b,+ 0x28, 0x06, 0x06, 0x00, 0x2a, 0x06, 0x2a, 0x2a, 0x2b, 0x07, 0xbb, 0xb5,+ 0x2b, 0x1e, 0x00, 0x2b, 0x07, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0xcd, 0x46, 0xcd, 0x2b, 0x00,+ 0x25, 0x2b, 0x07, 0x01, 0x06, 0x01, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x55, 0x56, 0x56, 0x02, 0x24, 0x81, 0x81, 0x81, 0x81, 0x81, 0x15, 0x81,+ 0x81, 0x81, 0x00, 0x00, 0x2b, 0x00, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1,+ 0xb2, 0xd1, 0x00, 0x00, 0xcd, 0xcc, 0x01, 0x00, 0xd7, 0xd7, 0xd7, 0xd7,+ 0xd7, 0x83, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x1c, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x4e, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x87, 0xa6,+ 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6,+ 0x87, 0xa6, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0c, 0x00, 0x0c, 0x2a, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07,+ 0x2a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56,+ 0x6c, 0x81, 0x15, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x6c,+ 0x03, 0x41, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x2c, 0x56, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x6c,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x56, 0x7a,+ 0x9e, 0x26, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25,+ 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x01, 0x2b, 0x2b,+ 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x39, 0x2b, 0x2b, 0x55,+ 0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56,+ 0x81, 0x37, 0x75, 0x5b, 0x7b, 0x5c, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x02,+ 0xac, 0x04, 0x00, 0x00, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b,+ 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x2b, 0x56, 0x56, 0x32, 0x13, 0x81, 0x57,+ 0x00, 0x6f, 0x81, 0x7e, 0xc9, 0xd7, 0x7e, 0x2d, 0x81, 0x81, 0x0e, 0x7e,+ 0x39, 0x7f, 0x6f, 0x57, 0x00, 0x81, 0x81, 0x7e, 0x15, 0x00, 0x7e, 0x03,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x07, 0x2b, 0x24, 0x2b, 0x97, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x80, 0x81, 0x81, 0x81, 0x81, 0x39, 0xbb, 0x2a, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,+ 0x81, 0x81, 0x81, 0x81, 0x81, 0xc9, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd0, 0x0d, 0x00,+ 0x4e, 0x31, 0x02, 0xb4, 0xc1, 0xc1, 0xd7, 0xd7, 0x24, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0xd7, 0xd7, 0x53, 0xc1, 0x47, 0xd4,+ 0xd7, 0xd7, 0xd7, 0x05, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50,+ 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x79, 0x5c, 0x7b, 0x5c, 0x7b,+ 0x4f, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b,+ 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x2b,+ 0x79, 0x14, 0x5c, 0x7b, 0x5c, 0x2d, 0x79, 0x2a, 0x5c, 0x27, 0x5c, 0x7b,+ 0x5c, 0x7b, 0x5c, 0x7b, 0xa4, 0x00, 0x0a, 0xb4, 0x5c, 0x7b, 0x5c, 0x7b,+ 0x4f, 0x03, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x48, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x07, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x00, 0x00, 0x00, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56,+ 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b,+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56,+ 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x27, 0x51, 0x6f, 0x77,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,+ 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x8e,+ 0x92, 0x97, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0xb4, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc9, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00,+ 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00,+ 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00,+ 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20,+ 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x04, 0x20,+ 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0x20,+ 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x28, 0x20,+ 0x00, 0x00, 0x29, 0x20, 0x00, 0x00, 0x5f, 0x20, 0x00, 0x00, 0x00, 0x30,+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x05, 0x04, 0x6e, 0x61,+ 0x6d, 0x65, 0x01, 0xc9, 0x04, 0x2c, 0x00, 0x2a, 0x5f, 0x5f, 0x69, 0x6d,+ 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f,+ 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65,+ 0x76, 0x69, 0x65, 0x77, 0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67,+ 0x65, 0x74, 0x01, 0x30, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,+ 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70,+ 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77,+ 0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73,+ 0x5f, 0x67, 0x65, 0x74, 0x02, 0x2b, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f,+ 0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e,+ 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69,+ 0x65, 0x77, 0x31, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69,+ 0x74, 0x03, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61,+ 0x6c, 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x04, 0x13, 0x75, 0x6e,+ 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x77, 0x65, 0x61, 0x6b,+ 0x3a, 0x6d, 0x61, 0x69, 0x6e, 0x05, 0x12, 0x5f, 0x5f, 0x77, 0x61, 0x73,+ 0x6d, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72,+ 0x79, 0x06, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x07, 0x0a, 0x72,+ 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x08, 0x06, 0x6d,+ 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x09, 0x04, 0x66, 0x72, 0x65, 0x65, 0x0a,+ 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x0b, 0x07, 0x72, 0x65, 0x61,+ 0x6c, 0x6c, 0x6f, 0x63, 0x0c, 0x05, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x0d,+ 0x0b, 0x5f, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x76, 0x6f, 0x69, 0x64,+ 0x0e, 0x0f, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x61, 0x72, 0x67,+ 0x73, 0x5f, 0x67, 0x65, 0x74, 0x0f, 0x15, 0x5f, 0x5f, 0x77, 0x61, 0x73,+ 0x69, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73,+ 0x5f, 0x67, 0x65, 0x74, 0x10, 0x10, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69,+ 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x11, 0x05,+ 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x12, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73,+ 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x74, 0x6f, 0x72, 0x73,+ 0x13, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x14, 0x06, 0x6d, 0x65,+ 0x6d, 0x73, 0x65, 0x74, 0x15, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e,+ 0x16, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x17, 0x06,+ 0x6d, 0x65, 0x6d, 0x63, 0x6d, 0x70, 0x18, 0x06, 0x6d, 0x65, 0x6d, 0x63,+ 0x68, 0x72, 0x19, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x1a, 0x08,+ 0x74, 0x6f, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x1b, 0x07, 0x63, 0x61,+ 0x73, 0x65, 0x6d, 0x61, 0x70, 0x1c, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70,+ 0x70, 0x65, 0x72, 0x1d, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70,+ 0x1e, 0x08, 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x1f, 0x07,+ 0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x20, 0x08, 0x69, 0x73, 0x77,+ 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x21, 0x07, 0x69, 0x73, 0x62, 0x6c, 0x61,+ 0x6e, 0x6b, 0x22, 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, 0x6e, 0x6b,+ 0x23, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, 0x24, 0x07,+ 0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x25, 0x09, 0x5f, 0x5f, 0x73,+ 0x74, 0x70, 0x6e, 0x63, 0x70, 0x79, 0x26, 0x07, 0x73, 0x74, 0x72, 0x6e,+ 0x63, 0x70, 0x79, 0x27, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, 0x69, 0x67,+ 0x69, 0x74, 0x28, 0x06, 0x77, 0x63, 0x73, 0x6c, 0x65, 0x6e, 0x29, 0x06,+ 0x77, 0x63, 0x73, 0x63, 0x68, 0x72, 0x2a, 0x08, 0x69, 0x73, 0x77, 0x73,+ 0x70, 0x61, 0x63, 0x65, 0x2b, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x6e,+ 0x75, 0x6d, 0x07, 0x33, 0x02, 0x00, 0x0f, 0x5f, 0x5f, 0x73, 0x74, 0x61,+ 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x01, 0x1f,+ 0x47, 0x4f, 0x54, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74,+ 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x5f, 0x5f, 0x6d, 0x65, 0x6d, 0x6f,+ 0x72, 0x79, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x09, 0x0a, 0x01, 0x00, 0x07,+ 0x2e, 0x72, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x00, 0x76, 0x09, 0x70, 0x72,+ 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x01, 0x0c, 0x70, 0x72, 0x6f,+ 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, 0x63,+ 0x6c, 0x61, 0x6e, 0x67, 0x56, 0x31, 0x37, 0x2e, 0x30, 0x2e, 0x36, 0x20,+ 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74,+ 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d,+ 0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,+ 0x74, 0x20, 0x36, 0x30, 0x30, 0x39, 0x37, 0x30, 0x38, 0x62, 0x34, 0x33,+ 0x36, 0x37, 0x31, 0x37, 0x31, 0x63, 0x63, 0x64, 0x62, 0x66, 0x34, 0x62,+ 0x35, 0x39, 0x30, 0x35, 0x63, 0x62, 0x36, 0x61, 0x38, 0x30, 0x33, 0x37,+ 0x35, 0x33, 0x66, 0x65, 0x31, 0x38, 0x29, 0x00, 0x39, 0x0f, 0x74, 0x61,+ 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,+ 0x73, 0x03, 0x2b, 0x0b, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d,+ 0x6f, 0x72, 0x79, 0x2b, 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,+ 0x2d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2b, 0x08, 0x73, 0x69,+ 0x67, 0x6e, 0x2d, 0x65, 0x78, 0x74+};+unsigned int STDLIB_WASM_LEN = 15582;
+ vendor/tree-sitter/lib/src/wasm_store.c view
@@ -0,0 +1,1847 @@+#include "tree_sitter/api.h"+#include "./parser.h"+#include <stdint.h>++#ifdef TREE_SITTER_FEATURE_WASM++#include "./alloc.h"+#include "./array.h"+#include "./atomic.h"+#include "./language.h"+#include "./lexer.h"+#include "./wasm/wasm-stdlib.h"+#include "./wasm_store.h"++#include <string.h>+#include <wasm.h>+#include <wasmtime.h>++#define array_len(a) (sizeof(a) / sizeof(a[0]))++// The following symbols from the C and C++ standard libraries are available+// for external scanners to use.+const char *STDLIB_SYMBOLS[] = {+ #include "./stdlib-symbols.txt"+};++// The contents of the `dylink.0` custom section of a wasm module,+// as specified by the current WebAssembly dynamic linking ABI proposal.+typedef struct {+ uint32_t memory_size;+ uint32_t memory_align;+ uint32_t table_size;+ uint32_t table_align;+} WasmDylinkInfo;++// WasmLanguageId - A pointer used to identify a language. This language id is+// reference-counted, so that its ownership can be shared between the language+// itself and the instances of the language that are held in wasm stores.+typedef struct {+ volatile uint32_t ref_count;+ volatile uint32_t is_language_deleted;+} WasmLanguageId;++// LanguageWasmModule - Additional data associated with a wasm-backed+// `TSLanguage`. This data is read-only and does not reference a particular+// wasm store, so it can be shared by all users of a `TSLanguage`. A pointer to+// this is stored on the language itself.+typedef struct {+ volatile uint32_t ref_count;+ WasmLanguageId *language_id;+ wasmtime_module_t *module;+ const char *name;+ char *symbol_name_buffer;+ char *field_name_buffer;+ WasmDylinkInfo dylink_info;+} LanguageWasmModule;++// LanguageWasmInstance - Additional data associated with an instantiation of+// a `TSLanguage` in a particular wasm store. The wasm store holds one of+// these structs for each language that it has instantiated.+typedef struct {+ WasmLanguageId *language_id;+ wasmtime_instance_t instance;+ int32_t external_states_address;+ int32_t lex_main_fn_index;+ int32_t lex_keyword_fn_index;+ int32_t scanner_create_fn_index;+ int32_t scanner_destroy_fn_index;+ int32_t scanner_serialize_fn_index;+ int32_t scanner_deserialize_fn_index;+ int32_t scanner_scan_fn_index;+} LanguageWasmInstance;++typedef struct {+ uint32_t reset_heap;+ uint32_t proc_exit;+ uint32_t abort;+ uint32_t assert_fail;+ uint32_t notify_memory_growth;+ uint32_t debug_message;+ uint32_t at_exit;+ uint32_t args_get;+ uint32_t args_sizes_get;+} BuiltinFunctionIndices;++// TSWasmStore - A struct that allows a given `Parser` to use wasm-backed+// languages. This struct is mutable, and can only be used by one parser at a+// time.+struct TSWasmStore {+ wasm_engine_t *engine;+ wasmtime_store_t *store;+ wasmtime_table_t function_table;+ wasmtime_memory_t memory;+ TSLexer *current_lexer;+ LanguageWasmInstance *current_instance;+ Array(LanguageWasmInstance) language_instances;+ uint32_t current_memory_offset;+ uint32_t current_function_table_offset;+ uint32_t *stdlib_fn_indices;+ BuiltinFunctionIndices builtin_fn_indices;+ wasmtime_global_t stack_pointer_global;+ wasm_globaltype_t *const_i32_type;+ bool has_error;+ uint32_t lexer_address;+};++typedef Array(char) StringData;++// LanguageInWasmMemory - The memory layout of a `TSLanguage` when compiled to+// wasm32. This is used to copy static language data out of the wasm memory.+typedef struct {+ uint32_t version;+ uint32_t symbol_count;+ uint32_t alias_count;+ uint32_t token_count;+ uint32_t external_token_count;+ uint32_t state_count;+ uint32_t large_state_count;+ uint32_t production_id_count;+ uint32_t field_count;+ uint16_t max_alias_sequence_length;+ int32_t parse_table;+ int32_t small_parse_table;+ int32_t small_parse_table_map;+ int32_t parse_actions;+ int32_t symbol_names;+ int32_t field_names;+ int32_t field_map_slices;+ int32_t field_map_entries;+ int32_t symbol_metadata;+ int32_t public_symbol_map;+ int32_t alias_map;+ int32_t alias_sequences;+ int32_t lex_modes;+ int32_t lex_fn;+ int32_t keyword_lex_fn;+ TSSymbol keyword_capture_token;+ struct {+ int32_t states;+ int32_t symbol_map;+ int32_t create;+ int32_t destroy;+ int32_t scan;+ int32_t serialize;+ int32_t deserialize;+ } external_scanner;+ int32_t primary_state_ids;+} LanguageInWasmMemory;++// LexerInWasmMemory - The memory layout of a `TSLexer` when compiled to wasm32.+// This is used to copy mutable lexing state in and out of the wasm memory.+typedef struct {+ int32_t lookahead;+ TSSymbol result_symbol;+ int32_t advance;+ int32_t mark_end;+ int32_t get_column;+ int32_t is_at_included_range_start;+ int32_t eof;+} LexerInWasmMemory;++static volatile uint32_t NEXT_LANGUAGE_ID;++// Linear memory layout:+// [ <-- stack | stdlib statics | lexer | language statics --> | serialization_buffer | heap --> ]+#define MAX_MEMORY_SIZE (128 * 1024 * 1024 / MEMORY_PAGE_SIZE)++/************************+ * WasmDylinkMemoryInfo+ ***********************/++static uint8_t read_u8(const uint8_t **p, const uint8_t *end) {+ return *(*p)++;+}++static inline uint64_t read_uleb128(const uint8_t **p, const uint8_t *end) {+ uint64_t value = 0;+ unsigned shift = 0;+ do {+ if (*p == end) return UINT64_MAX;+ value += (uint64_t)(**p & 0x7f) << shift;+ shift += 7;+ } while (*((*p)++) >= 128);+ return value;+}++static bool wasm_dylink_info__parse(+ const uint8_t *bytes,+ size_t length,+ WasmDylinkInfo *info+) {+ const uint8_t WASM_MAGIC_NUMBER[4] = {0, 'a', 's', 'm'};+ const uint8_t WASM_VERSION[4] = {1, 0, 0, 0};+ const uint8_t WASM_CUSTOM_SECTION = 0x0;+ const uint8_t WASM_DYLINK_MEM_INFO = 0x1;++ const uint8_t *p = bytes;+ const uint8_t *end = bytes + length;++ if (length < 8) return false;+ if (memcmp(p, WASM_MAGIC_NUMBER, 4) != 0) return false;+ p += 4;+ if (memcmp(p, WASM_VERSION, 4) != 0) return false;+ p += 4;++ while (p < end) {+ uint8_t section_id = read_u8(&p, end);+ uint32_t section_length = read_uleb128(&p, end);+ const uint8_t *section_end = p + section_length;+ if (section_end > end) return false;++ if (section_id == WASM_CUSTOM_SECTION) {+ uint32_t name_length = read_uleb128(&p, section_end);+ const uint8_t *name_end = p + name_length;+ if (name_end > section_end) return false;++ if (name_length == 8 && memcmp(p, "dylink.0", 8) == 0) {+ p = name_end;+ while (p < section_end) {+ uint8_t subsection_type = read_u8(&p, section_end);+ uint32_t subsection_size = read_uleb128(&p, section_end);+ const uint8_t *subsection_end = p + subsection_size;+ if (subsection_end > section_end) return false;+ if (subsection_type == WASM_DYLINK_MEM_INFO) {+ info->memory_size = read_uleb128(&p, subsection_end);+ info->memory_align = read_uleb128(&p, subsection_end);+ info->table_size = read_uleb128(&p, subsection_end);+ info->table_align = read_uleb128(&p, subsection_end);+ return true;+ }+ p = subsection_end;+ }+ }+ }+ p = section_end;+ }+ return false;+}++/*******************************************+ * Native callbacks exposed to wasm modules+ *******************************************/++ static wasm_trap_t *callback__abort(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ return wasmtime_trap_new("wasm module called abort", 24);+}++static wasm_trap_t *callback__debug_message(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ wasmtime_context_t *context = wasmtime_caller_context(caller);+ TSWasmStore *store = env;+ ts_assert(args_and_results_len == 2);+ uint32_t string_address = args_and_results[0].i32;+ uint32_t value = args_and_results[1].i32;+ uint8_t *memory = wasmtime_memory_data(context, &store->memory);+ printf("DEBUG: %s %u\n", &memory[string_address], value);+ return NULL;+}++static wasm_trap_t *callback__noop(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ return NULL;+}++static wasm_trap_t *callback__lexer_advance(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ wasmtime_context_t *context = wasmtime_caller_context(caller);+ ts_assert(args_and_results_len == 2);++ TSWasmStore *store = env;+ TSLexer *lexer = store->current_lexer;+ bool skip = args_and_results[1].i32;+ lexer->advance(lexer, skip);++ uint8_t *memory = wasmtime_memory_data(context, &store->memory);+ memcpy(&memory[store->lexer_address], &lexer->lookahead, sizeof(lexer->lookahead));+ return NULL;+}++static wasm_trap_t *callback__lexer_mark_end(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ TSWasmStore *store = env;+ TSLexer *lexer = store->current_lexer;+ lexer->mark_end(lexer);+ return NULL;+}++static wasm_trap_t *callback__lexer_get_column(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ TSWasmStore *store = env;+ TSLexer *lexer = store->current_lexer;+ uint32_t result = lexer->get_column(lexer);+ args_and_results[0].i32 = result;+ return NULL;+}++static wasm_trap_t *callback__lexer_is_at_included_range_start(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ TSWasmStore *store = env;+ TSLexer *lexer = store->current_lexer;+ bool result = lexer->is_at_included_range_start(lexer);+ args_and_results[0].i32 = result;+ return NULL;+}++static wasm_trap_t *callback__lexer_eof(+ void *env,+ wasmtime_caller_t* caller,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ TSWasmStore *store = env;+ TSLexer *lexer = store->current_lexer;+ bool result = lexer->eof(lexer);+ args_and_results[0].i32 = result;+ return NULL;+}++typedef struct {+ uint32_t *storage_location;+ wasmtime_func_unchecked_callback_t callback;+ wasm_functype_t *type;+} FunctionDefinition;++static void *copy(const void *data, size_t size) {+ void *result = ts_malloc(size);+ memcpy(result, data, size);+ return result;+}++static void *copy_unsized_static_array(+ const uint8_t *data,+ int32_t start_address,+ const int32_t all_addresses[],+ size_t address_count+) {+ int32_t end_address = 0;+ for (unsigned i = 0; i < address_count; i++) {+ if (all_addresses[i] > start_address) {+ if (!end_address || all_addresses[i] < end_address) {+ end_address = all_addresses[i];+ }+ }+ }++ if (!end_address) return NULL;+ size_t size = end_address - start_address;+ void *result = ts_malloc(size);+ memcpy(result, &data[start_address], size);+ return result;+}++static void *copy_strings(+ const uint8_t *data,+ int32_t array_address,+ size_t count,+ StringData *string_data+) {+ const char **result = ts_malloc(count * sizeof(char *));+ for (unsigned i = 0; i < count; i++) {+ int32_t address;+ memcpy(&address, &data[array_address + i * sizeof(address)], sizeof(address));+ if (address == 0) {+ result[i] = (const char *)-1;+ } else {+ const uint8_t *string = &data[address];+ uint32_t len = strlen((const char *)string);+ result[i] = (const char *)(uintptr_t)string_data->size;+ array_extend(string_data, len + 1, string);+ }+ }+ for (unsigned i = 0; i < count; i++) {+ if (result[i] == (const char *)-1) {+ result[i] = NULL;+ } else {+ result[i] = string_data->contents + (uintptr_t)result[i];+ }+ }+ return result;+}++static bool name_eq(const wasm_name_t *name, const char *string) {+ return strncmp(string, name->data, name->size) == 0;+}++static inline wasm_functype_t* wasm_functype_new_4_0(+ wasm_valtype_t* p1,+ wasm_valtype_t* p2,+ wasm_valtype_t* p3,+ wasm_valtype_t* p4+) {+ wasm_valtype_t* ps[4] = {p1, p2, p3, p4};+ wasm_valtype_vec_t params, results;+ wasm_valtype_vec_new(¶ms, 4, ps);+ wasm_valtype_vec_new_empty(&results);+ return wasm_functype_new(¶ms, &results);+}++#define format(output, ...) \+ do { \+ size_t message_length = snprintf((char *)NULL, 0, __VA_ARGS__); \+ *output = ts_malloc(message_length + 1); \+ snprintf(*output, message_length + 1, __VA_ARGS__); \+ } while (0)++WasmLanguageId *language_id_new(void) {+ WasmLanguageId *self = ts_malloc(sizeof(WasmLanguageId));+ self->is_language_deleted = false;+ self->ref_count = 1;+ return self;+}++WasmLanguageId *language_id_clone(WasmLanguageId *self) {+ atomic_inc(&self->ref_count);+ return self;+}++void language_id_delete(WasmLanguageId *self) {+ if (atomic_dec(&self->ref_count) == 0) {+ ts_free(self);+ }+}++static wasmtime_extern_t get_builtin_extern(+ wasmtime_table_t *table,+ unsigned index+) {+ return (wasmtime_extern_t) {+ .kind = WASMTIME_EXTERN_FUNC,+ .of.func = (wasmtime_func_t) {+ .store_id = table->store_id,+ .__private = index+ }+ };+}++static bool ts_wasm_store__provide_builtin_import(+ TSWasmStore *self,+ const wasm_name_t *import_name,+ wasmtime_extern_t *import+) {+ wasmtime_error_t *error = NULL;+ wasmtime_context_t *context = wasmtime_store_context(self->store);++ // Dynamic linking parameters+ if (name_eq(import_name, "__memory_base")) {+ wasmtime_val_t value = WASM_I32_VAL(self->current_memory_offset);+ wasmtime_global_t global;+ error = wasmtime_global_new(context, self->const_i32_type, &value, &global);+ ts_assert(!error);+ *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = global};+ } else if (name_eq(import_name, "__table_base")) {+ wasmtime_val_t value = WASM_I32_VAL(self->current_function_table_offset);+ wasmtime_global_t global;+ error = wasmtime_global_new(context, self->const_i32_type, &value, &global);+ ts_assert(!error);+ *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = global};+ } else if (name_eq(import_name, "__stack_pointer")) {+ *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_GLOBAL, .of.global = self->stack_pointer_global};+ } else if (name_eq(import_name, "__indirect_function_table")) {+ *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_TABLE, .of.table = self->function_table};+ } else if (name_eq(import_name, "memory")) {+ *import = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_MEMORY, .of.memory = self->memory};+ }++ // Builtin functions+ else if (name_eq(import_name, "__assert_fail")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.assert_fail);+ } else if (name_eq(import_name, "__cxa_atexit")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.at_exit);+ } else if (name_eq(import_name, "args_get")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.args_get);+ } else if (name_eq(import_name, "args_sizes_get")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.args_sizes_get);+ } else if (name_eq(import_name, "abort")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.abort);+ } else if (name_eq(import_name, "proc_exit")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.proc_exit);+ } else if (name_eq(import_name, "emscripten_notify_memory_growth")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.notify_memory_growth);+ } else if (name_eq(import_name, "tree_sitter_debug_message")) {+ *import = get_builtin_extern(&self->function_table, self->builtin_fn_indices.debug_message);+ } else {+ return false;+ }++ return true;+}++static bool ts_wasm_store__call_module_initializer(+ TSWasmStore *self,+ const wasm_name_t *export_name,+ wasmtime_extern_t *export,+ wasm_trap_t **trap+) {+ if (+ name_eq(export_name, "_initialize") ||+ name_eq(export_name, "__wasm_apply_data_relocs") ||+ name_eq(export_name, "__wasm_call_ctors")+ ) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ wasmtime_func_t initialization_func = export->of.func;+ wasmtime_error_t *error = wasmtime_func_call(context, &initialization_func, NULL, 0, NULL, 0, trap);+ ts_assert(!error);+ return true;+ } else {+ return false;+ }+}++TSWasmStore *ts_wasm_store_new(TSWasmEngine *engine, TSWasmError *wasm_error) {+ TSWasmStore *self = ts_calloc(1, sizeof(TSWasmStore));+ wasmtime_store_t *store = wasmtime_store_new(engine, self, NULL);+ wasmtime_context_t *context = wasmtime_store_context(store);+ wasmtime_error_t *error = NULL;+ wasm_trap_t *trap = NULL;+ wasm_message_t message = WASM_EMPTY_VEC;+ wasm_exporttype_vec_t export_types = WASM_EMPTY_VEC;+ wasmtime_extern_t *imports = NULL;+ wasmtime_module_t *stdlib_module = NULL;+ wasm_memorytype_t *memory_type = NULL;+ wasm_tabletype_t *table_type = NULL;++ // Define functions called by scanners via function pointers on the lexer.+ LexerInWasmMemory lexer = {+ .lookahead = 0,+ .result_symbol = 0,+ };+ FunctionDefinition lexer_definitions[] = {+ {+ (uint32_t *)&lexer.advance,+ callback__lexer_advance,+ wasm_functype_new_2_0(wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ (uint32_t *)&lexer.mark_end,+ callback__lexer_mark_end,+ wasm_functype_new_1_0(wasm_valtype_new_i32())+ },+ {+ (uint32_t *)&lexer.get_column,+ callback__lexer_get_column,+ wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ (uint32_t *)&lexer.is_at_included_range_start,+ callback__lexer_is_at_included_range_start,+ wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ (uint32_t *)&lexer.eof,+ callback__lexer_eof,+ wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ };++ // Define builtin functions that can be imported by scanners.+ BuiltinFunctionIndices builtin_fn_indices;+ FunctionDefinition builtin_definitions[] = {+ {+ &builtin_fn_indices.proc_exit,+ callback__abort,+ wasm_functype_new_1_0(wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.abort,+ callback__abort,+ wasm_functype_new_0_0()+ },+ {+ &builtin_fn_indices.assert_fail,+ callback__abort,+ wasm_functype_new_4_0(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.notify_memory_growth,+ callback__noop,+ wasm_functype_new_1_0(wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.debug_message,+ callback__debug_message,+ wasm_functype_new_2_0(wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.at_exit,+ callback__noop,+ wasm_functype_new_3_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.args_get,+ callback__noop,+ wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ {+ &builtin_fn_indices.args_sizes_get,+ callback__noop,+ wasm_functype_new_2_1(wasm_valtype_new_i32(), wasm_valtype_new_i32(), wasm_valtype_new_i32())+ },+ };++ // Create all of the wasm functions.+ unsigned builtin_definitions_len = array_len(builtin_definitions);+ unsigned lexer_definitions_len = array_len(lexer_definitions);+ for (unsigned i = 0; i < builtin_definitions_len; i++) {+ FunctionDefinition *definition = &builtin_definitions[i];+ wasmtime_func_t func;+ wasmtime_func_new_unchecked(context, definition->type, definition->callback, self, NULL, &func);+ *definition->storage_location = func.__private;+ wasm_functype_delete(definition->type);+ }+ for (unsigned i = 0; i < lexer_definitions_len; i++) {+ FunctionDefinition *definition = &lexer_definitions[i];+ wasmtime_func_t func;+ wasmtime_func_new_unchecked(context, definition->type, definition->callback, self, NULL, &func);+ *definition->storage_location = func.__private;+ wasm_functype_delete(definition->type);+ }++ // Compile the stdlib module.+ error = wasmtime_module_new(engine, STDLIB_WASM, STDLIB_WASM_LEN, &stdlib_module);+ if (error) {+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindCompile;+ format(+ &wasm_error->message,+ "failed to compile wasm stdlib: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }++ // Retrieve the stdlib module's imports.+ wasm_importtype_vec_t import_types = WASM_EMPTY_VEC;+ wasmtime_module_imports(stdlib_module, &import_types);++ // Find the initial number of memory pages needed by the stdlib.+ const wasm_memorytype_t *stdlib_memory_type;+ for (unsigned i = 0; i < import_types.size; i++) {+ wasm_importtype_t *import_type = import_types.data[i];+ const wasm_name_t *import_name = wasm_importtype_name(import_type);+ if (name_eq(import_name, "memory")) {+ const wasm_externtype_t *type = wasm_importtype_type(import_type);+ stdlib_memory_type = wasm_externtype_as_memorytype_const(type);+ }+ }+ if (!stdlib_memory_type) {+ wasm_error->kind = TSWasmErrorKindCompile;+ format(+ &wasm_error->message,+ "wasm stdlib is missing the 'memory' import"+ );+ goto error;+ }++ // Initialize store's memory+ uint64_t initial_memory_pages = wasmtime_memorytype_minimum(stdlib_memory_type);+ wasm_limits_t memory_limits = {.min = initial_memory_pages, .max = MAX_MEMORY_SIZE};+ memory_type = wasm_memorytype_new(&memory_limits);+ wasmtime_memory_t memory;+ error = wasmtime_memory_new(context, memory_type, &memory);+ if (error) {+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindAllocate;+ format(+ &wasm_error->message,+ "failed to allocate wasm memory: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }+ wasm_memorytype_delete(memory_type);+ memory_type = NULL;++ // Initialize store's function table+ wasm_limits_t table_limits = {.min = 1, .max = wasm_limits_max_default};+ table_type = wasm_tabletype_new(wasm_valtype_new(WASM_FUNCREF), &table_limits);+ wasmtime_val_t initializer = {.kind = WASMTIME_FUNCREF};+ wasmtime_table_t function_table;+ error = wasmtime_table_new(context, table_type, &initializer, &function_table);+ if (error) {+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindAllocate;+ format(+ &wasm_error->message,+ "failed to allocate wasm table: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }+ wasm_tabletype_delete(table_type);+ table_type = NULL;++ unsigned stdlib_symbols_len = array_len(STDLIB_SYMBOLS);++ // Define globals for the stack and heap start addresses.+ wasm_globaltype_t *const_i32_type = wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST);+ wasm_globaltype_t *var_i32_type = wasm_globaltype_new(wasm_valtype_new_i32(), WASM_VAR);++ wasmtime_val_t stack_pointer_value = WASM_I32_VAL(0);+ wasmtime_global_t stack_pointer_global;+ error = wasmtime_global_new(context, var_i32_type, &stack_pointer_value, &stack_pointer_global);+ ts_assert(!error);++ *self = (TSWasmStore) {+ .engine = wasmtime_engine_clone(engine),+ .store = store,+ .memory = memory,+ .function_table = function_table,+ .language_instances = array_new(),+ .stdlib_fn_indices = ts_calloc(stdlib_symbols_len, sizeof(uint32_t)),+ .builtin_fn_indices = builtin_fn_indices,+ .stack_pointer_global = stack_pointer_global,+ .current_memory_offset = 0,+ .current_function_table_offset = 0,+ .const_i32_type = const_i32_type,+ };++ // Set up the imports for the stdlib module.+ imports = ts_calloc(import_types.size, sizeof(wasmtime_extern_t));+ for (unsigned i = 0; i < import_types.size; i++) {+ wasm_importtype_t *type = import_types.data[i];+ const wasm_name_t *import_name = wasm_importtype_name(type);+ if (!ts_wasm_store__provide_builtin_import(self, import_name, &imports[i])) {+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "unexpected import in wasm stdlib: %.*s\n",+ (int)import_name->size, import_name->data+ );+ goto error;+ }+ }++ // Instantiate the stdlib module.+ wasmtime_instance_t instance;+ error = wasmtime_instance_new(context, stdlib_module, imports, import_types.size, &instance, &trap);+ ts_free(imports);+ imports = NULL;+ if (error) {+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "failed to instantiate wasm stdlib module: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }+ if (trap) {+ wasm_trap_message(trap, &message);+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "trapped when instantiating wasm stdlib module: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }+ wasm_importtype_vec_delete(&import_types);++ // Process the stdlib module's exports.+ for (unsigned i = 0; i < stdlib_symbols_len; i++) {+ self->stdlib_fn_indices[i] = UINT32_MAX;+ }+ wasmtime_module_exports(stdlib_module, &export_types);+ for (unsigned i = 0; i < export_types.size; i++) {+ wasm_exporttype_t *export_type = export_types.data[i];+ const wasm_name_t *name = wasm_exporttype_name(export_type);++ char *export_name;+ size_t name_len;+ wasmtime_extern_t export = {.kind = WASM_EXTERN_GLOBAL};+ bool exists = wasmtime_instance_export_nth(context, &instance, i, &export_name, &name_len, &export);+ ts_assert(exists);++ if (export.kind == WASMTIME_EXTERN_GLOBAL) {+ if (name_eq(name, "__stack_pointer")) {+ self->stack_pointer_global = export.of.global;+ }+ }++ if (export.kind == WASMTIME_EXTERN_FUNC) {+ if (ts_wasm_store__call_module_initializer(self, name, &export, &trap)) {+ if (trap) {+ wasm_trap_message(trap, &message);+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "trap when calling stdlib relocation function: %.*s\n",+ (int)message.size, message.data+ );+ goto error;+ }+ continue;+ }++ if (name_eq(name, "reset_heap")) {+ self->builtin_fn_indices.reset_heap = export.of.func.__private;+ continue;+ }++ for (unsigned j = 0; j < stdlib_symbols_len; j++) {+ if (name_eq(name, STDLIB_SYMBOLS[j])) {+ self->stdlib_fn_indices[j] = export.of.func.__private;+ break;+ }+ }+ }+ }++ if (self->builtin_fn_indices.reset_heap == UINT32_MAX) {+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "missing malloc reset function in wasm stdlib"+ );+ goto error;+ }++ for (unsigned i = 0; i < stdlib_symbols_len; i++) {+ if (self->stdlib_fn_indices[i] == UINT32_MAX) {+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(+ &wasm_error->message,+ "missing exported symbol in wasm stdlib: %s",+ STDLIB_SYMBOLS[i]+ );+ goto error;+ }+ }++ wasm_exporttype_vec_delete(&export_types);+ wasmtime_module_delete(stdlib_module);++ // Add all of the lexer callback functions to the function table. Store their function table+ // indices on the in-memory lexer.+ uint32_t table_index;+ error = wasmtime_table_grow(context, &function_table, lexer_definitions_len, &initializer, &table_index);+ if (error) {+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindAllocate;+ format(+ &wasm_error->message,+ "failed to grow wasm table to initial size: %.*s",+ (int)message.size, message.data+ );+ goto error;+ }+ for (unsigned i = 0; i < lexer_definitions_len; i++) {+ FunctionDefinition *definition = &lexer_definitions[i];+ wasmtime_func_t func = {function_table.store_id, *definition->storage_location};+ wasmtime_val_t func_val = {.kind = WASMTIME_FUNCREF, .of.funcref = func};+ error = wasmtime_table_set(context, &function_table, table_index, &func_val);+ ts_assert(!error);+ *(int32_t *)(definition->storage_location) = table_index;+ table_index++;+ }++ self->current_function_table_offset = table_index;+ self->lexer_address = initial_memory_pages * MEMORY_PAGE_SIZE;+ self->current_memory_offset = self->lexer_address + sizeof(LexerInWasmMemory);++ // Grow the memory enough to hold the builtin lexer and serialization buffer.+ uint32_t new_pages_needed = (self->current_memory_offset - self->lexer_address - 1) / MEMORY_PAGE_SIZE + 1;+ uint64_t prev_memory_size;+ wasmtime_memory_grow(context, &memory, new_pages_needed, &prev_memory_size);++ uint8_t *memory_data = wasmtime_memory_data(context, &memory);+ memcpy(&memory_data[self->lexer_address], &lexer, sizeof(lexer));+ return self;++error:+ ts_free(self);+ if (stdlib_module) wasmtime_module_delete(stdlib_module);+ if (store) wasmtime_store_delete(store);+ if (import_types.size) wasm_importtype_vec_delete(&import_types);+ if (memory_type) wasm_memorytype_delete(memory_type);+ if (table_type) wasm_tabletype_delete(table_type);+ if (trap) wasm_trap_delete(trap);+ if (error) wasmtime_error_delete(error);+ if (message.size) wasm_byte_vec_delete(&message);+ if (export_types.size) wasm_exporttype_vec_delete(&export_types);+ if (imports) ts_free(imports);+ return NULL;+}++void ts_wasm_store_delete(TSWasmStore *self) {+ if (!self) return;+ ts_free(self->stdlib_fn_indices);+ wasm_globaltype_delete(self->const_i32_type);+ wasmtime_store_delete(self->store);+ wasm_engine_delete(self->engine);+ for (unsigned i = 0; i < self->language_instances.size; i++) {+ LanguageWasmInstance *instance = &self->language_instances.contents[i];+ language_id_delete(instance->language_id);+ }+ array_delete(&self->language_instances);+ ts_free(self);+}++size_t ts_wasm_store_language_count(const TSWasmStore *self) {+ size_t result = 0;+ for (unsigned i = 0; i < self->language_instances.size; i++) {+ const WasmLanguageId *id = self->language_instances.contents[i].language_id;+ if (!id->is_language_deleted) {+ result++;+ }+ }+ return result;+}++static uint32_t ts_wasm_store__heap_address(TSWasmStore *self) {+ return self->current_memory_offset + TREE_SITTER_SERIALIZATION_BUFFER_SIZE;+}++static uint32_t ts_wasm_store__serialization_buffer_address(TSWasmStore *self) {+ return self->current_memory_offset;+}++static bool ts_wasm_store__instantiate(+ TSWasmStore *self,+ wasmtime_module_t *module,+ const char *language_name,+ const WasmDylinkInfo *dylink_info,+ wasmtime_instance_t *result,+ int32_t *language_address,+ char **error_message+) {+ wasmtime_error_t *error = NULL;+ wasm_trap_t *trap = NULL;+ wasm_message_t message = WASM_EMPTY_VEC;+ char *language_function_name = NULL;+ wasmtime_extern_t *imports = NULL;+ wasmtime_context_t *context = wasmtime_store_context(self->store);++ // Grow the function table to make room for the new functions.+ wasmtime_val_t initializer = {.kind = WASMTIME_FUNCREF};+ uint32_t prev_table_size;+ error = wasmtime_table_grow(context, &self->function_table, dylink_info->table_size, &initializer, &prev_table_size);+ if (error) {+ format(error_message, "invalid function table size %u", dylink_info->table_size);+ goto error;+ }++ // Grow the memory to make room for the new data.+ uint32_t needed_memory_size = ts_wasm_store__heap_address(self) + dylink_info->memory_size;+ uint32_t current_memory_size = wasmtime_memory_data_size(context, &self->memory);+ if (needed_memory_size > current_memory_size) {+ uint32_t pages_to_grow = (+ needed_memory_size - current_memory_size + MEMORY_PAGE_SIZE - 1) /+ MEMORY_PAGE_SIZE;+ uint64_t prev_memory_size;+ error = wasmtime_memory_grow(context, &self->memory, pages_to_grow, &prev_memory_size);+ if (error) {+ format(error_message, "invalid memory size %u", dylink_info->memory_size);+ goto error;+ }+ }++ // Construct the language function name as string.+ format(&language_function_name, "tree_sitter_%s", language_name);++ const uint64_t store_id = self->function_table.store_id;++ // Build the imports list for the module.+ wasm_importtype_vec_t import_types = WASM_EMPTY_VEC;+ wasmtime_module_imports(module, &import_types);+ imports = ts_calloc(import_types.size, sizeof(wasmtime_extern_t));++ for (unsigned i = 0; i < import_types.size; i++) {+ const wasm_importtype_t *import_type = import_types.data[i];+ const wasm_name_t *import_name = wasm_importtype_name(import_type);+ if (import_name->size == 0) {+ format(error_message, "empty import name");+ goto error;+ }++ if (ts_wasm_store__provide_builtin_import(self, import_name, &imports[i])) {+ continue;+ }++ bool defined_in_stdlib = false;+ for (unsigned j = 0; j < array_len(STDLIB_SYMBOLS); j++) {+ if (name_eq(import_name, STDLIB_SYMBOLS[j])) {+ uint16_t address = self->stdlib_fn_indices[j];+ imports[i] = (wasmtime_extern_t) {.kind = WASMTIME_EXTERN_FUNC, .of.func = {store_id, address}};+ defined_in_stdlib = true;+ break;+ }+ }++ if (!defined_in_stdlib) {+ format(+ error_message,+ "invalid import '%.*s'\n",+ (int)import_name->size, import_name->data+ );+ goto error;+ }+ }++ wasmtime_instance_t instance;+ error = wasmtime_instance_new(context, module, imports, import_types.size, &instance, &trap);+ wasm_importtype_vec_delete(&import_types);+ ts_free(imports);+ imports = NULL;+ if (error) {+ wasmtime_error_message(error, &message);+ format(+ error_message,+ "error instantiating wasm module: %.*s\n",+ (int)message.size, message.data+ );+ goto error;+ }+ if (trap) {+ wasm_trap_message(trap, &message);+ format(+ error_message,+ "trap when instantiating wasm module: %.*s\n",+ (int)message.size, message.data+ );+ goto error;+ }++ self->current_memory_offset += dylink_info->memory_size;+ self->current_function_table_offset += dylink_info->table_size;++ // Process the module's exports.+ bool found_language = false;+ wasmtime_extern_t language_extern;+ wasm_exporttype_vec_t export_types = WASM_EMPTY_VEC;+ wasmtime_module_exports(module, &export_types);+ for (unsigned i = 0; i < export_types.size; i++) {+ wasm_exporttype_t *export_type = export_types.data[i];+ const wasm_name_t *name = wasm_exporttype_name(export_type);++ size_t name_len;+ char *export_name;+ wasmtime_extern_t export = {.kind = WASM_EXTERN_GLOBAL};+ bool exists = wasmtime_instance_export_nth(context, &instance, i, &export_name, &name_len, &export);+ ts_assert(exists);++ // If the module exports an initialization or data-relocation function, call it.+ if (ts_wasm_store__call_module_initializer(self, name, &export, &trap)) {+ if (trap) {+ wasm_trap_message(trap, &message);+ format(+ error_message,+ "trap when calling data relocation function: %.*s\n",+ (int)message.size, message.data+ );+ goto error;+ }+ }++ // Find the main language function for the module.+ else if (name_eq(name, language_function_name)) {+ language_extern = export;+ found_language = true;+ }+ }+ wasm_exporttype_vec_delete(&export_types);++ if (!found_language) {+ format(+ error_message,+ "module did not contain language function: %s",+ language_function_name+ );+ goto error;+ }++ // Invoke the language function to get the static address of the language object.+ wasmtime_func_t language_func = language_extern.of.func;+ wasmtime_val_t language_address_val;+ error = wasmtime_func_call(context, &language_func, NULL, 0, &language_address_val, 1, &trap);+ ts_assert(!error);+ if (trap) {+ wasm_trap_message(trap, &message);+ format(+ error_message,+ "trapped when calling language function: %s: %.*s\n",+ language_function_name, (int)message.size, message.data+ );+ goto error;+ }++ if (language_address_val.kind != WASMTIME_I32) {+ format(+ error_message,+ "language function did not return an integer: %s\n",+ language_function_name+ );+ goto error;+ }++ ts_free(language_function_name);+ *result = instance;+ *language_address = language_address_val.of.i32;+ return true;++error:+ if (language_function_name) ts_free(language_function_name);+ if (message.size) wasm_byte_vec_delete(&message);+ if (error) wasmtime_error_delete(error);+ if (trap) wasm_trap_delete(trap);+ if (imports) ts_free(imports);+ return false;+}++static bool ts_wasm_store__sentinel_lex_fn(TSLexer *_lexer, TSStateId state) {+ return false;+}++const TSLanguage *ts_wasm_store_load_language(+ TSWasmStore *self,+ const char *language_name,+ const char *wasm,+ uint32_t wasm_len,+ TSWasmError *wasm_error+) {+ WasmDylinkInfo dylink_info;+ wasmtime_module_t *module = NULL;+ wasmtime_error_t *error = NULL;+ wasm_error->kind = TSWasmErrorKindNone;++ if (!wasm_dylink_info__parse((const unsigned char *)wasm, wasm_len, &dylink_info)) {+ wasm_error->kind = TSWasmErrorKindParse;+ format(&wasm_error->message, "failed to parse dylink section of wasm module");+ goto error;+ }++ // Compile the wasm code.+ error = wasmtime_module_new(self->engine, (const uint8_t *)wasm, wasm_len, &module);+ if (error) {+ wasm_message_t message;+ wasmtime_error_message(error, &message);+ wasm_error->kind = TSWasmErrorKindCompile;+ format(&wasm_error->message, "error compiling wasm module: %.*s", (int)message.size, message.data);+ wasm_byte_vec_delete(&message);+ goto error;+ }++ // Instantiate the module in this store.+ wasmtime_instance_t instance;+ int32_t language_address;+ if (!ts_wasm_store__instantiate(+ self,+ module,+ language_name,+ &dylink_info,+ &instance,+ &language_address,+ &wasm_error->message+ )) {+ wasm_error->kind = TSWasmErrorKindInstantiate;+ goto error;+ }++ // Copy all of the static data out of the language object in wasm memory,+ // constructing a native language object.+ LanguageInWasmMemory wasm_language;+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ const uint8_t *memory = wasmtime_memory_data(context, &self->memory);+ memcpy(&wasm_language, &memory[language_address], sizeof(LanguageInWasmMemory));++ if (wasm_language.version < LANGUAGE_VERSION_USABLE_VIA_WASM) {+ wasm_error->kind = TSWasmErrorKindInstantiate;+ format(&wasm_error->message, "language version %u is too old for wasm", wasm_language.version);+ goto error;+ }++ int32_t addresses[] = {+ wasm_language.alias_map,+ wasm_language.alias_sequences,+ wasm_language.field_map_entries,+ wasm_language.field_map_slices,+ wasm_language.field_names,+ wasm_language.keyword_lex_fn,+ wasm_language.lex_fn,+ wasm_language.lex_modes,+ wasm_language.parse_actions,+ wasm_language.parse_table,+ wasm_language.primary_state_ids,+ wasm_language.primary_state_ids,+ wasm_language.public_symbol_map,+ wasm_language.small_parse_table,+ wasm_language.small_parse_table_map,+ wasm_language.symbol_metadata,+ wasm_language.symbol_metadata,+ wasm_language.symbol_names,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.states : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.symbol_map : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.create : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.destroy : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.scan : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.serialize : 0,+ wasm_language.external_token_count > 0 ? wasm_language.external_scanner.deserialize : 0,+ language_address,+ self->current_memory_offset,+ };+ uint32_t address_count = array_len(addresses);++ TSLanguage *language = ts_calloc(1, sizeof(TSLanguage));+ StringData symbol_name_buffer = array_new();+ StringData field_name_buffer = array_new();++ *language = (TSLanguage) {+ .version = wasm_language.version,+ .symbol_count = wasm_language.symbol_count,+ .alias_count = wasm_language.alias_count,+ .token_count = wasm_language.token_count,+ .external_token_count = wasm_language.external_token_count,+ .state_count = wasm_language.state_count,+ .large_state_count = wasm_language.large_state_count,+ .production_id_count = wasm_language.production_id_count,+ .field_count = wasm_language.field_count,+ .max_alias_sequence_length = wasm_language.max_alias_sequence_length,+ .keyword_capture_token = wasm_language.keyword_capture_token,+ .parse_table = copy(+ &memory[wasm_language.parse_table],+ wasm_language.large_state_count * wasm_language.symbol_count * sizeof(uint16_t)+ ),+ .parse_actions = copy_unsized_static_array(+ memory,+ wasm_language.parse_actions,+ addresses,+ address_count+ ),+ .symbol_names = copy_strings(+ memory,+ wasm_language.symbol_names,+ wasm_language.symbol_count + wasm_language.alias_count,+ &symbol_name_buffer+ ),+ .symbol_metadata = copy(+ &memory[wasm_language.symbol_metadata],+ (wasm_language.symbol_count + wasm_language.alias_count) * sizeof(TSSymbolMetadata)+ ),+ .public_symbol_map = copy(+ &memory[wasm_language.public_symbol_map],+ (wasm_language.symbol_count + wasm_language.alias_count) * sizeof(TSSymbol)+ ),+ .lex_modes = copy(+ &memory[wasm_language.lex_modes],+ wasm_language.state_count * sizeof(TSLexMode)+ ),+ };++ if (language->field_count > 0 && language->production_id_count > 0) {+ language->field_map_slices = copy(+ &memory[wasm_language.field_map_slices],+ wasm_language.production_id_count * sizeof(TSFieldMapSlice)+ );++ // Determine the number of field map entries by finding the greatest index+ // in any of the slices.+ uint32_t field_map_entry_count = 0;+ for (uint32_t i = 0; i < wasm_language.production_id_count; i++) {+ TSFieldMapSlice slice = language->field_map_slices[i];+ uint32_t slice_end = slice.index + slice.length;+ if (slice_end > field_map_entry_count) {+ field_map_entry_count = slice_end;+ }+ }++ language->field_map_entries = copy(+ &memory[wasm_language.field_map_entries],+ field_map_entry_count * sizeof(TSFieldMapEntry)+ );+ language->field_names = copy_strings(+ memory,+ wasm_language.field_names,+ wasm_language.field_count + 1,+ &field_name_buffer+ );+ }++ if (language->max_alias_sequence_length > 0 && language->production_id_count > 0) {+ // The alias map contains symbols, alias counts, and aliases, terminated by a null symbol.+ int32_t alias_map_size = 0;+ for (;;) {+ TSSymbol symbol;+ memcpy(&symbol, &memory[wasm_language.alias_map + alias_map_size], sizeof(symbol));+ alias_map_size += sizeof(TSSymbol);+ if (symbol == 0) break;+ uint16_t value_count;+ memcpy(&value_count, &memory[wasm_language.alias_map + alias_map_size], sizeof(value_count));+ alias_map_size += value_count * sizeof(TSSymbol);+ }+ language->alias_map = copy(+ &memory[wasm_language.alias_map],+ alias_map_size * sizeof(TSSymbol)+ );+ language->alias_sequences = copy(+ &memory[wasm_language.alias_sequences],+ wasm_language.production_id_count * wasm_language.max_alias_sequence_length * sizeof(TSSymbol)+ );+ }++ if (language->state_count > language->large_state_count) {+ uint32_t small_state_count = wasm_language.state_count - wasm_language.large_state_count;+ language->small_parse_table_map = copy(+ &memory[wasm_language.small_parse_table_map],+ small_state_count * sizeof(uint32_t)+ );+ language->small_parse_table = copy_unsized_static_array(+ memory,+ wasm_language.small_parse_table,+ addresses,+ address_count+ );+ }++ if (language->version >= LANGUAGE_VERSION_WITH_PRIMARY_STATES) {+ language->primary_state_ids = copy(+ &memory[wasm_language.primary_state_ids],+ wasm_language.state_count * sizeof(TSStateId)+ );+ }++ if (language->external_token_count > 0) {+ language->external_scanner.symbol_map = copy(+ &memory[wasm_language.external_scanner.symbol_map],+ wasm_language.external_token_count * sizeof(TSSymbol)+ );+ language->external_scanner.states = (void *)(uintptr_t)wasm_language.external_scanner.states;+ }++ unsigned name_len = strlen(language_name);+ char *name = ts_malloc(name_len + 1);+ memcpy(name, language_name, name_len);+ name[name_len] = '\0';++ LanguageWasmModule *language_module = ts_malloc(sizeof(LanguageWasmModule));+ *language_module = (LanguageWasmModule) {+ .language_id = language_id_new(),+ .module = module,+ .name = name,+ .symbol_name_buffer = symbol_name_buffer.contents,+ .field_name_buffer = field_name_buffer.contents,+ .dylink_info = dylink_info,+ .ref_count = 1,+ };++ // The lex functions are not used for wasm languages. Use those two fields+ // to mark this language as WASM-based and to store the language's+ // WASM-specific data.+ language->lex_fn = ts_wasm_store__sentinel_lex_fn;+ language->keyword_lex_fn = (bool (*)(TSLexer *, TSStateId))language_module;++ // Clear out any instances of languages that have been deleted.+ for (unsigned i = 0; i < self->language_instances.size; i++) {+ WasmLanguageId *id = self->language_instances.contents[i].language_id;+ if (id->is_language_deleted) {+ language_id_delete(id);+ array_erase(&self->language_instances, i);+ i--;+ }+ }++ // Store this store's instance of this language module.+ array_push(&self->language_instances, ((LanguageWasmInstance) {+ .language_id = language_id_clone(language_module->language_id),+ .instance = instance,+ .external_states_address = wasm_language.external_scanner.states,+ .lex_main_fn_index = wasm_language.lex_fn,+ .lex_keyword_fn_index = wasm_language.keyword_lex_fn,+ .scanner_create_fn_index = wasm_language.external_scanner.create,+ .scanner_destroy_fn_index = wasm_language.external_scanner.destroy,+ .scanner_serialize_fn_index = wasm_language.external_scanner.serialize,+ .scanner_deserialize_fn_index = wasm_language.external_scanner.deserialize,+ .scanner_scan_fn_index = wasm_language.external_scanner.scan,+ }));++ return language;++error:+ if (module) wasmtime_module_delete(module);+ return NULL;+}++bool ts_wasm_store_add_language(+ TSWasmStore *self,+ const TSLanguage *language,+ uint32_t *index+) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ const LanguageWasmModule *language_module = (void *)language->keyword_lex_fn;++ // Search for this store's instance of the language module. Also clear out any+ // instances of languages that have been deleted.+ bool exists = false;+ for (unsigned i = 0; i < self->language_instances.size; i++) {+ WasmLanguageId *id = self->language_instances.contents[i].language_id;+ if (id->is_language_deleted) {+ language_id_delete(id);+ array_erase(&self->language_instances, i);+ i--;+ } else if (id == language_module->language_id) {+ exists = true;+ *index = i;+ }+ }++ // If the language module has not been instantiated in this store, then add+ // it to this store.+ if (!exists) {+ *index = self->language_instances.size;+ char *message;+ wasmtime_instance_t instance;+ int32_t language_address;+ if (!ts_wasm_store__instantiate(+ self,+ language_module->module,+ language_module->name,+ &language_module->dylink_info,+ &instance,+ &language_address,+ &message+ )) {+ ts_free(message);+ return false;+ }++ LanguageInWasmMemory wasm_language;+ const uint8_t *memory = wasmtime_memory_data(context, &self->memory);+ memcpy(&wasm_language, &memory[language_address], sizeof(LanguageInWasmMemory));+ array_push(&self->language_instances, ((LanguageWasmInstance) {+ .language_id = language_id_clone(language_module->language_id),+ .instance = instance,+ .external_states_address = wasm_language.external_scanner.states,+ .lex_main_fn_index = wasm_language.lex_fn,+ .lex_keyword_fn_index = wasm_language.keyword_lex_fn,+ .scanner_create_fn_index = wasm_language.external_scanner.create,+ .scanner_destroy_fn_index = wasm_language.external_scanner.destroy,+ .scanner_serialize_fn_index = wasm_language.external_scanner.serialize,+ .scanner_deserialize_fn_index = wasm_language.external_scanner.deserialize,+ .scanner_scan_fn_index = wasm_language.external_scanner.scan,+ }));+ }++ return true;+}++void ts_wasm_store_reset_heap(TSWasmStore *self) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ wasmtime_func_t func = {+ self->function_table.store_id,+ self->builtin_fn_indices.reset_heap+ };+ wasm_trap_t *trap = NULL;+ wasmtime_val_t args[1] = {+ {.of.i32 = ts_wasm_store__heap_address(self), .kind = WASMTIME_I32},+ };++ wasmtime_error_t *error = wasmtime_func_call(context, &func, args, 1, NULL, 0, &trap);+ ts_assert(!error);+ ts_assert(!trap);+}++bool ts_wasm_store_start(TSWasmStore *self, TSLexer *lexer, const TSLanguage *language) {+ uint32_t instance_index;+ if (!ts_wasm_store_add_language(self, language, &instance_index)) return false;+ self->current_lexer = lexer;+ self->current_instance = &self->language_instances.contents[instance_index];+ self->has_error = false;+ ts_wasm_store_reset_heap(self);+ return true;+}++void ts_wasm_store_reset(TSWasmStore *self) {+ self->current_lexer = NULL;+ self->current_instance = NULL;+ self->has_error = false;+ ts_wasm_store_reset_heap(self);+}++static void ts_wasm_store__call(+ TSWasmStore *self,+ int32_t function_index,+ wasmtime_val_raw_t *args_and_results,+ size_t args_and_results_len+) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ wasmtime_val_t value;+ bool succeeded = wasmtime_table_get(context, &self->function_table, function_index, &value);+ ts_assert(succeeded);+ ts_assert(value.kind == WASMTIME_FUNCREF);+ wasmtime_func_t func = value.of.funcref;++ wasm_trap_t *trap = NULL;+ wasmtime_error_t *error = wasmtime_func_call_unchecked(context, &func, args_and_results, args_and_results_len, &trap);+ if (error) {+ // wasm_message_t message;+ // wasmtime_error_message(error, &message);+ // fprintf(+ // stderr,+ // "error in wasm module: %.*s\n",+ // (int)message.size, message.data+ // );+ wasmtime_error_delete(error);+ self->has_error = true;+ } else if (trap) {+ // wasm_message_t message;+ // wasm_trap_message(trap, &message);+ // fprintf(+ // stderr,+ // "trap in wasm module: %.*s\n",+ // (int)message.size, message.data+ // );+ wasm_trap_delete(trap);+ self->has_error = true;+ }+}++static bool ts_wasm_store__call_lex_function(TSWasmStore *self, unsigned function_index, TSStateId state) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);+ memcpy(+ &memory_data[self->lexer_address],+ &self->current_lexer->lookahead,+ sizeof(self->current_lexer->lookahead)+ );++ wasmtime_val_raw_t args[2] = {+ {.i32 = self->lexer_address},+ {.i32 = state},+ };+ ts_wasm_store__call(self, function_index, args, 2);+ if (self->has_error) return false;+ bool result = args[0].i32;++ memcpy(+ &self->current_lexer->lookahead,+ &memory_data[self->lexer_address],+ sizeof(self->current_lexer->lookahead) + sizeof(self->current_lexer->result_symbol)+ );+ return result;+}++bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state) {+ return ts_wasm_store__call_lex_function(+ self,+ self->current_instance->lex_main_fn_index,+ state+ );+}++bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state) {+ return ts_wasm_store__call_lex_function(+ self,+ self->current_instance->lex_keyword_fn_index,+ state+ );+}++uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self) {+ wasmtime_val_raw_t args[1] = {{.i32 = 0}};+ ts_wasm_store__call(self, self->current_instance->scanner_create_fn_index, args, 1);+ if (self->has_error) return 0;+ return args[0].i32;+}++void ts_wasm_store_call_scanner_destroy(TSWasmStore *self, uint32_t scanner_address) {+ if (self->current_instance) {+ wasmtime_val_raw_t args[1] = {{.i32 = scanner_address}};+ ts_wasm_store__call(self, self->current_instance->scanner_destroy_fn_index, args, 1);+ }+}++bool ts_wasm_store_call_scanner_scan(+ TSWasmStore *self,+ uint32_t scanner_address,+ uint32_t valid_tokens_ix+) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);++ memcpy(+ &memory_data[self->lexer_address],+ &self->current_lexer->lookahead,+ sizeof(self->current_lexer->lookahead)+ );++ uint32_t valid_tokens_address =+ self->current_instance->external_states_address ++ (valid_tokens_ix * sizeof(bool));+ wasmtime_val_raw_t args[3] = {+ {.i32 = scanner_address},+ {.i32 = self->lexer_address},+ {.i32 = valid_tokens_address}+ };+ ts_wasm_store__call(self, self->current_instance->scanner_scan_fn_index, args, 3);+ if (self->has_error) return false;++ memcpy(+ &self->current_lexer->lookahead,+ &memory_data[self->lexer_address],+ sizeof(self->current_lexer->lookahead) + sizeof(self->current_lexer->result_symbol)+ );+ return args[0].i32;+}++uint32_t ts_wasm_store_call_scanner_serialize(+ TSWasmStore *self,+ uint32_t scanner_address,+ char *buffer+) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);+ uint32_t serialization_buffer_address = ts_wasm_store__serialization_buffer_address(self);++ wasmtime_val_raw_t args[2] = {+ {.i32 = scanner_address},+ {.i32 = serialization_buffer_address},+ };+ ts_wasm_store__call(self, self->current_instance->scanner_serialize_fn_index, args, 2);+ if (self->has_error) return 0;++ uint32_t length = args[0].i32;+ if (length > TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {+ self->has_error = true;+ return 0;+ }++ if (length > 0) {+ memcpy(+ ((Lexer *)self->current_lexer)->debug_buffer,+ &memory_data[serialization_buffer_address],+ length+ );+ }+ return length;+}++void ts_wasm_store_call_scanner_deserialize(+ TSWasmStore *self,+ uint32_t scanner_address,+ const char *buffer,+ unsigned length+) {+ wasmtime_context_t *context = wasmtime_store_context(self->store);+ uint8_t *memory_data = wasmtime_memory_data(context, &self->memory);+ uint32_t serialization_buffer_address = ts_wasm_store__serialization_buffer_address(self);++ if (length > 0) {+ memcpy(+ &memory_data[serialization_buffer_address],+ buffer,+ length+ );+ }++ wasmtime_val_raw_t args[3] = {+ {.i32 = scanner_address},+ {.i32 = serialization_buffer_address},+ {.i32 = length},+ };+ ts_wasm_store__call(self, self->current_instance->scanner_deserialize_fn_index, args, 3);+}++bool ts_wasm_store_has_error(const TSWasmStore *self) {+ return self->has_error;+}++bool ts_language_is_wasm(const TSLanguage *self) {+ return self->lex_fn == ts_wasm_store__sentinel_lex_fn;+}++static inline LanguageWasmModule *ts_language__wasm_module(const TSLanguage *self) {+ return (LanguageWasmModule *)self->keyword_lex_fn;+}++void ts_wasm_language_retain(const TSLanguage *self) {+ LanguageWasmModule *module = ts_language__wasm_module(self);+ ts_assert(module->ref_count > 0);+ atomic_inc(&module->ref_count);+}++void ts_wasm_language_release(const TSLanguage *self) {+ LanguageWasmModule *module = ts_language__wasm_module(self);+ ts_assert(module->ref_count > 0);+ if (atomic_dec(&module->ref_count) == 0) {+ // Update the language id to reflect that the language is deleted. This allows any wasm stores+ // that hold wasm instances for this language to delete those instances.+ atomic_inc(&module->language_id->is_language_deleted);+ language_id_delete(module->language_id);++ ts_free((void *)module->field_name_buffer);+ ts_free((void *)module->symbol_name_buffer);+ ts_free((void *)module->name);+ wasmtime_module_delete(module->module);+ ts_free(module);++ ts_free((void *)self->alias_map);+ ts_free((void *)self->alias_sequences);+ ts_free((void *)self->external_scanner.symbol_map);+ ts_free((void *)self->field_map_entries);+ ts_free((void *)self->field_map_slices);+ ts_free((void *)self->field_names);+ ts_free((void *)self->lex_modes);+ ts_free((void *)self->parse_actions);+ ts_free((void *)self->parse_table);+ ts_free((void *)self->primary_state_ids);+ ts_free((void *)self->public_symbol_map);+ ts_free((void *)self->small_parse_table);+ ts_free((void *)self->small_parse_table_map);+ ts_free((void *)self->symbol_metadata);+ ts_free((void *)self->symbol_names);+ ts_free((void *)self);+ }+}++#else++// If the WASM feature is not enabled, define dummy versions of all of the+// wasm-related functions.++void ts_wasm_store_delete(TSWasmStore *self) {+ (void)self;+}++bool ts_wasm_store_start(+ TSWasmStore *self,+ TSLexer *lexer,+ const TSLanguage *language+) {+ (void)self;+ (void)lexer;+ (void)language;+ return false;+}++void ts_wasm_store_reset(TSWasmStore *self) {+ (void)self;+}++bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state) {+ (void)self;+ (void)state;+ return false;+}++bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state) {+ (void)self;+ (void)state;+ return false;+}++uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self) {+ (void)self;+ return 0;+}++void ts_wasm_store_call_scanner_destroy(+ TSWasmStore *self,+ uint32_t scanner_address+) {+ (void)self;+ (void)scanner_address;+}++bool ts_wasm_store_call_scanner_scan(+ TSWasmStore *self,+ uint32_t scanner_address,+ uint32_t valid_tokens_ix+) {+ (void)self;+ (void)scanner_address;+ (void)valid_tokens_ix;+ return false;+}++uint32_t ts_wasm_store_call_scanner_serialize(+ TSWasmStore *self,+ uint32_t scanner_address,+ char *buffer+) {+ (void)self;+ (void)scanner_address;+ (void)buffer;+ return 0;+}++void ts_wasm_store_call_scanner_deserialize(+ TSWasmStore *self,+ uint32_t scanner_address,+ const char *buffer,+ unsigned length+) {+ (void)self;+ (void)scanner_address;+ (void)buffer;+ (void)length;+}++bool ts_wasm_store_has_error(const TSWasmStore *self) {+ (void)self;+ return false;+}++bool ts_language_is_wasm(const TSLanguage *self) {+ (void)self;+ return false;+}++void ts_wasm_language_retain(const TSLanguage *self) {+ (void)self;+}++void ts_wasm_language_release(const TSLanguage *self) {+ (void)self;+}++#endif
+ vendor/tree-sitter/lib/src/wasm_store.h view
@@ -0,0 +1,31 @@+#ifndef TREE_SITTER_WASM_H_+#define TREE_SITTER_WASM_H_++#ifdef __cplusplus+extern "C" {+#endif++#include "tree_sitter/api.h"+#include "./parser.h"++bool ts_wasm_store_start(TSWasmStore *self, TSLexer *lexer, const TSLanguage *language);+void ts_wasm_store_reset(TSWasmStore *self);+bool ts_wasm_store_has_error(const TSWasmStore *self);++bool ts_wasm_store_call_lex_main(TSWasmStore *self, TSStateId state);+bool ts_wasm_store_call_lex_keyword(TSWasmStore *self, TSStateId state);++uint32_t ts_wasm_store_call_scanner_create(TSWasmStore *self);+void ts_wasm_store_call_scanner_destroy(TSWasmStore *self, uint32_t scanner_address);+bool ts_wasm_store_call_scanner_scan(TSWasmStore *self, uint32_t scanner_address, uint32_t valid_tokens_ix);+uint32_t ts_wasm_store_call_scanner_serialize(TSWasmStore *self, uint32_t scanner_address, char *buffer);+void ts_wasm_store_call_scanner_deserialize(TSWasmStore *self, uint32_t scanner, const char *buffer, unsigned length);++void ts_wasm_language_retain(const TSLanguage *self);+void ts_wasm_language_release(const TSLanguage *self);++#ifdef __cplusplus+}+#endif++#endif // TREE_SITTER_WASM_H_
+ vendor/tree-sitter/lib/tree-sitter.pc.in view
@@ -0,0 +1,10 @@+prefix=@CMAKE_INSTALL_PREFIX@+libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@++Name: tree-sitter+Description: @PROJECT_DESCRIPTION@+URL: @PROJECT_HOMEPAGE_URL@+Version: @PROJECT_VERSION@+Libs: -L${libdir} -ltree-sitter+Cflags: -I${includedir}