diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index b9d13915..8673b059 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -33,7 +33,7 @@ extern "C" { #define PARSE_FN() \ static const ts_tree * \ -ts_parse(void *data, ts_input input) +ts_parse(void *data, ts_input input, ts_input_edit *edit) #define LEX_FN() \ static ts_tree * \ @@ -59,9 +59,7 @@ ts_parser constructor_name() { \ #define START_PARSER() \ ts_lr_parser *parser = (ts_lr_parser *)data; \ -ts_lr_parser_reset(parser); \ -parser->lexer.input = input; \ -ts_lexer_advance(&parser->lexer); \ +ts_lr_parser_initialize(parser, input, edit); \ next_state: #define LOOKAHEAD_SYM() \ @@ -264,11 +262,15 @@ static ts_lr_parser * ts_lr_parser_make() { return result; } -static void ts_lr_parser_reset(ts_lr_parser *parser) { +static void ts_lr_parser_initialize(ts_lr_parser *parser, ts_input input, ts_input_edit *edit) { ts_stack_shrink(&parser->stack, 0); parser->lookahead = NULL; parser->next_lookahead = NULL; + + input.seek_fn(input.data, 0); parser->lexer = ts_lexer_make(); + parser->lexer.input = input; + ts_lexer_advance(&parser->lexer); } static ts_symbol ts_lr_parser_lookahead_sym(const ts_lr_parser *parser) { @@ -283,9 +285,8 @@ static void ts_lr_parser_shift(ts_lr_parser *parser, state_id parse_state) { } static void ts_lr_parser_reduce(ts_lr_parser *parser, ts_symbol symbol, int immediate_child_count, const int *collapse_flags) { - ts_tree *lookahead = ts_stack_reduce(&parser->stack, symbol, immediate_child_count, collapse_flags); parser->next_lookahead = parser->lookahead; - parser->lookahead = lookahead; + parser->lookahead = ts_stack_reduce(&parser->stack, symbol, immediate_child_count, collapse_flags); } static int ts_lr_parser_handle_error(ts_lr_parser *parser, size_t count, const ts_symbol *expected_symbols) { diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 21492e52..64f39d80 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -48,14 +48,20 @@ typedef struct { } ts_input; typedef struct { - const ts_tree * (* parse_fn)(void *data, ts_input input); - void (* free_fn)(void *data); - const char **symbol_names; - void *data; - } ts_parser; + size_t position; + size_t bytes_inserted; + size_t bytes_removed; + } ts_input_edit; - const ts_tree * ts_parser_parse(ts_parser *, ts_input); - void ts_parser_free(ts_parser *); +typedef struct { + const ts_tree * (* parse_fn)(void *data, ts_input input, ts_input_edit *edit); + void (* free_fn)(void *data); + const char **symbol_names; + void *data; +} ts_parser; + +const ts_tree * ts_parser_parse(ts_parser *, ts_input, ts_input_edit *edit); +void ts_parser_free(ts_parser *); typedef struct ts_document ts_document; @@ -64,7 +70,7 @@ void ts_document_free(ts_document *doc); void ts_document_set_parser(ts_document *doc, ts_parser parser); void ts_document_set_input(ts_document *doc, ts_input input); void ts_document_set_input_string(ts_document *doc, const char *text); -void ts_document_edit(ts_document *doc, size_t position, size_t deleted_bytes, size_t inserted_bytes); +void ts_document_edit(ts_document *doc, ts_input_edit edit); const ts_tree * ts_document_tree(const ts_document *doc); const char * ts_document_string(const ts_document *doc); diff --git a/spec/runtime/parser_spec.cc b/spec/runtime/parser_spec.cc index 3b48bf11..380f7001 100644 --- a/spec/runtime/parser_spec.cc +++ b/spec/runtime/parser_spec.cc @@ -48,7 +48,11 @@ describe("parsing", [&]() { string inserted_text(", \"key2\": 4 "); reader->content.insert(position, inserted_text); - ts_document_edit(doc, position, 0, inserted_text.length()); + ts_document_edit(doc, { + .position = position, + .bytes_removed = 0, + .bytes_inserted = inserted_text.length() + }); }); it("updates the parse tree", [&]() { @@ -64,7 +68,7 @@ describe("parsing", [&]() { )); }); - it_skip("re-reads only the changed portion of the input", [&]() { + it("re-reads only the changed portion of the input", [&]() { AssertThat(reader->chunks_read, Equals(vector({ "" }))); diff --git a/src/runtime/document.c b/src/runtime/document.c index 46fbcea4..d625180c 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -30,12 +30,11 @@ const char * ts_document_string(const ts_document *document) { void ts_document_set_input(ts_document *document, ts_input input) { document->input = input; - document->tree = ts_parser_parse(&document->parser, input); + document->tree = ts_parser_parse(&document->parser, input, NULL); } -void ts_document_edit(ts_document *document, size_t position, size_t bytes_removed, size_t bytes_inserted) { - document->input.seek_fn(document->input.data, 0); - document->tree = ts_parser_parse(&document->parser, document->input); +void ts_document_edit(ts_document *document, ts_input_edit edit) { + document->tree = ts_parser_parse(&document->parser, document->input, &edit); } typedef struct { diff --git a/src/runtime/parser.c b/src/runtime/parser.c index c7f3a86a..211e422b 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -1,7 +1,7 @@ #include "tree_sitter/runtime.h" -const ts_tree * ts_parser_parse(ts_parser *parser, ts_input input) { - return parser->parse_fn(parser->data, input); +const ts_tree * ts_parser_parse(ts_parser *parser, ts_input input, ts_input_edit *edit) { + return parser->parse_fn(parser->data, input, edit); } void ts_parser_free(ts_parser *parser) { diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 75a2ff1a..2425df14 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -13,6 +13,7 @@ typedef struct { } ts_stack; static int INITIAL_STACK_SIZE = 100; +static int INITIAL_STATE = 0; ts_stack ts_stack_make() { ts_stack result = { @@ -23,7 +24,7 @@ ts_stack ts_stack_make() { } state_id ts_stack_top_state(const ts_stack *stack) { - if (stack->size == 0) return 0; + if (stack->size == 0) return INITIAL_STATE; return stack->entries[stack->size - 1].state; }