diff --git a/include/tree_sitter/parser.h b/include/tree_sitter/parser.h index 4d8cf0fb..4f7fc940 100644 --- a/include/tree_sitter/parser.h +++ b/include/tree_sitter/parser.h @@ -13,15 +13,15 @@ typedef struct TSTree TSTree; #define ts_lex_state_error 0 typedef struct { - TSInput input; - int debug; - const char *chunk; - size_t chunk_start; - size_t chunk_size; - size_t position_in_chunk; - size_t token_end_position; - size_t token_start_position; - int reached_end; + TSInput input; + int debug; + const char *chunk; + size_t chunk_start; + size_t chunk_size; + size_t position_in_chunk; + size_t token_end_position; + size_t token_start_position; + int reached_end; } TSLexer; TSLexer ts_lexer_make(); @@ -29,26 +29,26 @@ int ts_lexer_advance(TSLexer *lexer); TSTree * ts_lexer_build_node(TSLexer *lexer, TSSymbol symbol, int is_hidden); static inline size_t ts_lexer_position(const TSLexer *lexer) { - return lexer->chunk_start + lexer->position_in_chunk; + return lexer->chunk_start + lexer->position_in_chunk; } static inline char ts_lexer_lookahead_char(const TSLexer *lexer) { - return lexer->chunk[lexer->position_in_chunk]; + return lexer->chunk[lexer->position_in_chunk]; } static inline void ts_lexer_start_token(TSLexer *lexer) { - lexer->token_start_position = ts_lexer_position(lexer); + lexer->token_start_position = ts_lexer_position(lexer); } typedef unsigned short TSStateId; typedef struct { - size_t size; - struct { - TSTree *node; - TSStateId state; - int is_extra; - } *entries; + size_t size; + struct { + TSTree *node; + TSStateId state; + int is_extra; + } *entries; } TSStack; TSStack ts_stack_make(); @@ -61,41 +61,41 @@ TSTree * ts_stack_top_node(const TSStack *stack); size_t ts_stack_right_position(const TSStack *stack); typedef enum { - TSParseActionTypeError, - TSParseActionTypeShift, - TSParseActionTypeShiftExtra, - TSParseActionTypeReduce, - TSParseActionTypeReduceExtra, - TSParseActionTypeAccept, + TSParseActionTypeError, + TSParseActionTypeShift, + TSParseActionTypeShiftExtra, + TSParseActionTypeReduce, + TSParseActionTypeReduceExtra, + TSParseActionTypeAccept, } TSParseActionType; typedef struct { - TSParseActionType type; - union { - TSStateId to_state; - struct { - TSSymbol symbol; - unsigned short child_count; - }; - } data; + TSParseActionType type; + union { + TSStateId to_state; + struct { + TSSymbol symbol; + unsigned short child_count; + }; + } data; } TSParseAction; typedef struct { - size_t symbol_count; - const char **symbol_names; - const int *hidden_symbol_flags; - const TSParseAction *parse_table; - const TSStateId *lex_states; - TSTree * (* lex_fn)(TSParser *, TSStateId); + size_t symbol_count; + const char **symbol_names; + const int *hidden_symbol_flags; + const TSParseAction *parse_table; + const TSStateId *lex_states; + TSTree * (* lex_fn)(TSParser *, TSStateId); } TSParserConfig; struct TSParser { - TSLexer lexer; - TSStack stack; - int debug; - TSTree *lookahead; - TSTree *next_lookahead; - TSParserConfig config; + TSLexer lexer; + TSStack stack; + int debug; + TSTree *lookahead; + TSTree *next_lookahead; + TSParserConfig config; }; TSParser * ts_parser_make(TSParserConfig); @@ -106,84 +106,84 @@ void ts_parser_start(TSParser *parser, TSInput input, TSInputEdit *edit); TSTree * ts_parser_step(TSParser *parser); #define SYMBOL_NAMES \ -static const char *ts_symbol_names[] + static const char *ts_symbol_names[] #define HIDDEN_SYMBOLS \ -static const int ts_hidden_symbol_flags[SYMBOL_COUNT] + static const int ts_hidden_symbol_flags[SYMBOL_COUNT] #define LEX_STATES \ -static TSStateId ts_lex_states[STATE_COUNT] + static TSStateId ts_lex_states[STATE_COUNT] #define PARSE_TABLE \ -static const TSParseAction ts_parse_actions[STATE_COUNT][SYMBOL_COUNT] + static const TSParseAction ts_parse_actions[STATE_COUNT][SYMBOL_COUNT] #define LEX_FN() \ -static TSTree * ts_lex(TSParser *parser, TSStateId lex_state) + static TSTree * ts_lex(TSParser *parser, TSStateId lex_state) #define DEBUG_LEX(...) \ -if (parser->lexer.debug) { fprintf(stderr, "\n" __VA_ARGS__); } + if (parser->lexer.debug) { fprintf(stderr, "\n" __VA_ARGS__); } #define START_LEXER() \ -DEBUG_LEX("LEX %d", lex_state); \ -char lookahead; \ -next_state: \ -lookahead = ts_lexer_lookahead_char(&parser->lexer); \ -DEBUG_LEX("CHAR '%c'", lookahead); + DEBUG_LEX("LEX %d", lex_state); \ + char lookahead; \ + next_state: \ + lookahead = ts_lexer_lookahead_char(&parser->lexer); \ + DEBUG_LEX("CHAR '%c'", lookahead); #define START_TOKEN() \ -ts_lexer_start_token(&parser->lexer); + ts_lexer_start_token(&parser->lexer); #define ADVANCE(state_index) \ -{ \ + { \ DEBUG_LEX("ADVANCE %d", state_index); \ if (!ts_lexer_advance(&parser->lexer)) ACCEPT_TOKEN(ts_builtin_sym_end); \ lex_state = state_index; goto next_state; \ -} + } #define ACCEPT_TOKEN(symbol) \ -{ \ + { \ DEBUG_LEX("TOKEN %s", ts_symbol_names[symbol]); \ return ts_lexer_build_node(&parser->lexer, symbol, ts_hidden_symbol_flags[symbol]); \ -} + } #define LEX_ERROR() \ -{ \ + { \ DEBUG_LEX("ERROR"); \ return ts_lexer_build_node(&parser->lexer, ts_builtin_sym_error, 0); \ -} + } #define LEX_PANIC() \ -{ \ + { \ DEBUG_LEX("LEX ERROR: unexpected state %d", lex_state); \ return NULL; \ -} + } #define SHIFT(to_state_value) \ -{ .type = TSParseActionTypeShift, .data = { .to_state = to_state_value } } + { .type = TSParseActionTypeShift, .data = { .to_state = to_state_value } } #define SHIFT_EXTRA() \ -{ .type = TSParseActionTypeShiftExtra } + { .type = TSParseActionTypeShiftExtra } #define REDUCE_EXTRA(symbol_val) \ -{ .type = TSParseActionTypeReduceExtra, .data = { .symbol = symbol_val } } + { .type = TSParseActionTypeReduceExtra, .data = { .symbol = symbol_val } } #define REDUCE(symbol_val, child_count_val) \ -{ .type = TSParseActionTypeReduce, .data = { .symbol = symbol_val, .child_count = child_count_val } } + { .type = TSParseActionTypeReduce, .data = { .symbol = symbol_val, .child_count = child_count_val } } #define ACCEPT_INPUT() \ -{ .type = TSParseActionTypeAccept } + { .type = TSParseActionTypeAccept } #define EXPORT_PARSER(constructor_name) \ -TSParser * constructor_name() { \ + TSParser * constructor_name() { \ return ts_parser_make((TSParserConfig) { \ - .symbol_count = SYMBOL_COUNT, \ - .hidden_symbol_flags = ts_hidden_symbol_flags, \ - .parse_table = (const TSParseAction *)ts_parse_actions, \ - .lex_states = ts_lex_states, \ - .symbol_names = ts_symbol_names, \ - .lex_fn = ts_lex, \ + .symbol_count = SYMBOL_COUNT, \ + .hidden_symbol_flags = ts_hidden_symbol_flags, \ + .parse_table = (const TSParseAction *)ts_parse_actions, \ + .lex_states = ts_lex_states, \ + .symbol_names = ts_symbol_names, \ + .lex_fn = ts_lex, \ }); \ -} + } #ifdef __cplusplus } diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 8647297c..5b775371 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -8,16 +8,16 @@ extern "C" { #include typedef struct { - void *data; - const char * (* read_fn)(void *data, size_t *bytes_read); - int (* seek_fn)(void *data, size_t position); - void (* release_fn)(void *data); + void *data; + const char * (* read_fn)(void *data, size_t *bytes_read); + int (* seek_fn)(void *data, size_t position); + void (* release_fn)(void *data); } TSInput; typedef struct { - size_t position; - size_t bytes_inserted; - size_t bytes_removed; + size_t position; + size_t bytes_inserted; + size_t bytes_removed; } TSInputEdit; typedef unsigned short TSSymbol; diff --git a/src/runtime/document.c b/src/runtime/document.c index 1591b70c..f9817ba3 100644 --- a/src/runtime/document.c +++ b/src/runtime/document.c @@ -5,104 +5,104 @@ #include struct TSDocument { - TSParser *parser; - const TSTree *tree; - TSInput input; - size_t error_count; + TSParser *parser; + const TSTree *tree; + TSInput input; + size_t error_count; }; TSDocument * ts_document_make() { - TSDocument *document = malloc(sizeof(TSDocument)); - *document = (TSDocument) { - .input = (TSInput) {} - }; - return document; + TSDocument *document = malloc(sizeof(TSDocument)); + *document = (TSDocument) { + .input = (TSInput) {} + }; + return document; } void ts_document_free(TSDocument *document) { - if (document->parser) - ts_parser_free(document->parser); - if (document->input.release_fn) - document->input.release_fn(document->input.data); - free(document); + if (document->parser) + ts_parser_free(document->parser); + if (document->input.release_fn) + document->input.release_fn(document->input.data); + free(document); } void ts_document_set_parser(TSDocument *document, TSParser *parser) { - if (document->parser) - ts_parser_free(document->parser); - document->parser = parser; + if (document->parser) + ts_parser_free(document->parser); + document->parser = parser; } const TSTree * ts_document_tree(const TSDocument *document) { - return document->tree; + return document->tree; } const char * ts_document_string(const TSDocument *document) { - return ts_tree_string(document->tree, ts_parser_config(document->parser).symbol_names); + return ts_tree_string(document->tree, ts_parser_config(document->parser).symbol_names); } void ts_document_set_input(TSDocument *document, TSInput input) { - document->input = input; - document->tree = ts_parser_parse(document->parser, document->input, NULL); + document->input = input; + document->tree = ts_parser_parse(document->parser, document->input, NULL); } void ts_document_edit(TSDocument *document, TSInputEdit edit) { - document->tree = ts_parser_parse(document->parser, document->input, &edit); + document->tree = ts_parser_parse(document->parser, document->input, &edit); } const char * ts_document_symbol_name(const TSDocument *document, const TSTree *tree) { - return ts_parser_config(document->parser).symbol_names[tree->symbol]; + return ts_parser_config(document->parser).symbol_names[tree->symbol]; } typedef struct { - const char *string; - size_t position; - size_t length; + const char *string; + size_t position; + size_t length; } TSStringInput; const char * ts_string_input_read(void *d, size_t *bytes_read) { - TSStringInput *data = (TSStringInput *)d; - if (data->position >= data->length) { - *bytes_read = 0; - return ""; - } - size_t previous_position = data->position; - data->position = data->length; - *bytes_read = data->position - previous_position; - return data->string + previous_position; + TSStringInput *data = (TSStringInput *)d; + if (data->position >= data->length) { + *bytes_read = 0; + return ""; + } + size_t previous_position = data->position; + data->position = data->length; + *bytes_read = data->position - previous_position; + return data->string + previous_position; } int ts_string_input_seek(void *d, size_t position) { - TSStringInput *data = (TSStringInput *)d; - data->position = position; - return (position < data->length); + TSStringInput *data = (TSStringInput *)d; + data->position = position; + return (position < data->length); } TSInput ts_string_input_make(const char *string) { - TSStringInput *data = malloc(sizeof(TSStringInput)); - data->string = string; - data->position = 0; - data->length = strlen(string); - TSInput input = { - .data = (void *)data, - .read_fn = ts_string_input_read, - .seek_fn = ts_string_input_seek, - .release_fn = free, - }; - return input; + TSStringInput *data = malloc(sizeof(TSStringInput)); + data->string = string; + data->position = 0; + data->length = strlen(string); + TSInput input = { + .data = (void *)data, + .read_fn = ts_string_input_read, + .seek_fn = ts_string_input_seek, + .release_fn = free, + }; + return input; } void ts_document_set_input_string(TSDocument *document, const char *text) { - ts_document_set_input(document, ts_string_input_make(text)); + ts_document_set_input(document, ts_string_input_make(text)); } TSNode * ts_document_root_node(const TSDocument *document) { - return ts_node_make_root(document->tree, document->parser->config.symbol_names); + return ts_node_make_root(document->tree, document->parser->config.symbol_names); } TSNode * ts_document_get_node(const TSDocument *document, size_t pos) { - TSNode *root = ts_document_root_node(document); - TSNode *result = ts_node_leaf_at_pos(root, pos); - ts_node_release(root); - return result; + TSNode *root = ts_document_root_node(document); + TSNode *result = ts_node_leaf_at_pos(root, pos); + ts_node_release(root); + return result; } diff --git a/src/runtime/lexer.c b/src/runtime/lexer.c index a659058e..f4f42ac0 100644 --- a/src/runtime/lexer.c +++ b/src/runtime/lexer.c @@ -2,42 +2,42 @@ #include "runtime/tree.h" TSLexer ts_lexer_make() { - return (TSLexer) { - .chunk = NULL, - .debug = 0, - .chunk_start = 0, - .chunk_size = 0, - .position_in_chunk = 0, - .token_start_position = 0, - .token_end_position = 0, - .reached_end = 0 - }; + return (TSLexer) { + .chunk = NULL, + .debug = 0, + .chunk_start = 0, + .chunk_size = 0, + .position_in_chunk = 0, + .token_start_position = 0, + .token_end_position = 0, + .reached_end = 0 + }; } int ts_lexer_advance(TSLexer *lexer) { - static const char *empty_chunk = ""; - if (lexer->position_in_chunk + 1 < lexer->chunk_size) { - lexer->position_in_chunk++; - } else { - lexer->chunk_start += lexer->chunk_size; - lexer->chunk = lexer->input.read_fn(lexer->input.data, &lexer->chunk_size); - lexer->position_in_chunk = 0; - if (lexer->reached_end) { - return 0; - } - if (lexer->chunk_size == 0) { - lexer->reached_end = 1; - lexer->chunk = empty_chunk; - } + static const char *empty_chunk = ""; + if (lexer->position_in_chunk + 1 < lexer->chunk_size) { + lexer->position_in_chunk++; + } else { + lexer->chunk_start += lexer->chunk_size; + lexer->chunk = lexer->input.read_fn(lexer->input.data, &lexer->chunk_size); + lexer->position_in_chunk = 0; + if (lexer->reached_end) { + return 0; } - return 1; + if (lexer->chunk_size == 0) { + lexer->reached_end = 1; + lexer->chunk = empty_chunk; + } + } + return 1; } TSTree * ts_lexer_build_node(TSLexer *lexer, TSSymbol symbol, int is_hidden) { - size_t current_position = ts_lexer_position(lexer); - size_t size = current_position - lexer->token_start_position; - size_t offset = lexer->token_start_position - lexer->token_end_position; - lexer->token_end_position = current_position; - return ts_tree_make_leaf(symbol, size, offset, is_hidden); + size_t current_position = ts_lexer_position(lexer); + size_t size = current_position - lexer->token_start_position; + size_t offset = lexer->token_start_position - lexer->token_end_position; + lexer->token_end_position = current_position; + return ts_tree_make_leaf(symbol, size, offset, is_hidden); } diff --git a/src/runtime/node.c b/src/runtime/node.c index d23c32e8..fa490fae 100644 --- a/src/runtime/node.c +++ b/src/runtime/node.c @@ -2,100 +2,100 @@ #include "runtime/tree.h" TSNode * ts_node_make(const TSTree *tree, TSNode *parent, size_t index, size_t start_position, const char **names) { - if (parent) ts_node_retain(parent); - TSNode *result = malloc(sizeof(TSNode)); - *result = (TSNode) { - .ref_count = 1, - .parent = parent, - .index = index, - .content = tree, - .start_position = start_position, - .names = names, - }; - return result; + if (parent) ts_node_retain(parent); + TSNode *result = malloc(sizeof(TSNode)); + *result = (TSNode) { + .ref_count = 1, + .parent = parent, + .index = index, + .content = tree, + .start_position = start_position, + .names = names, + }; + return result; } TSNode * ts_node_make_root(const TSTree *tree, const char **names) { - while (ts_tree_is_wrapper(tree)) - tree = tree->children[0]; - return ts_node_make(tree, NULL, 0, 0, names); + while (ts_tree_is_wrapper(tree)) + tree = tree->children[0]; + return ts_node_make(tree, NULL, 0, 0, names); } void ts_node_retain(TSNode *node) { - node->ref_count++; + node->ref_count++; } void ts_node_release(TSNode *node) { - node->ref_count--; - if (node->ref_count == 0) { - if (node->parent) ts_node_release(node->parent); - free(node); - } + node->ref_count--; + if (node->ref_count == 0) { + if (node->parent) ts_node_release(node->parent); + free(node); + } } size_t ts_node_pos(const TSNode *node) { - return node->start_position + node->content->offset; + return node->start_position + node->content->offset; } size_t ts_node_size(const TSNode *node) { - return node->content->size; + return node->content->size; } int ts_node_eq(const TSNode *left, const TSNode *right) { - return ts_tree_equals(left->content, right->content); + return ts_tree_equals(left->content, right->content); } const char * ts_node_name(const TSNode *node) { - return node->names[node->content->symbol]; + return node->names[node->content->symbol]; } const char * ts_node_string(const TSNode *node) { - return ts_tree_string(node->content, node->names); + return ts_tree_string(node->content, node->names); } TSNode * ts_node_parent(TSNode *child) { - return child->parent; + return child->parent; } TSNode * ts_node_prev_sibling(TSNode *child) { - return ts_node_child(child->parent, child->index - 1); + return ts_node_child(child->parent, child->index - 1); } TSNode * ts_node_next_sibling(TSNode *child) { - return ts_node_child(child->parent, child->index + 1); + return ts_node_child(child->parent, child->index + 1); } size_t ts_node_child_count(const TSNode *parent) { - size_t result; - ts_tree_visible_children(parent->content, &result); - return result; + size_t result; + ts_tree_visible_children(parent->content, &result); + return result; } TSNode * ts_node_child(TSNode *parent, size_t index) { - size_t child_count; - TSChildWithPosition *children = ts_tree_visible_children(parent->content, &child_count); - if (child_count <= index) - return NULL; - size_t position = parent->start_position + children[index].position; - return ts_node_make(children[index].tree, parent, index, position, parent->names); + size_t child_count; + TSChildWithPosition *children = ts_tree_visible_children(parent->content, &child_count); + if (child_count <= index) + return NULL; + size_t position = parent->start_position + children[index].position; + return ts_node_make(children[index].tree, parent, index, position, parent->names); } TSNode * ts_node_leaf_at_pos(TSNode *parent, size_t position) { - size_t child_count; - TSChildWithPosition *children = ts_tree_visible_children(parent->content, &child_count); - for (size_t i = 0; i < child_count; i++) { - TSChildWithPosition child = children[i]; - size_t child_left = child.position + child.tree->offset; - if (child_left > position) - break; - if (child_left + child.tree->size > position) { - TSNode *node = ts_node_make(child.tree, parent, i, child.position, parent->names); - TSNode *result = ts_node_leaf_at_pos(node, position); - ts_node_release(node); - return result; - } + size_t child_count; + TSChildWithPosition *children = ts_tree_visible_children(parent->content, &child_count); + for (size_t i = 0; i < child_count; i++) { + TSChildWithPosition child = children[i]; + size_t child_left = child.position + child.tree->offset; + if (child_left > position) + break; + if (child_left + child.tree->size > position) { + TSNode *node = ts_node_make(child.tree, parent, i, child.position, parent->names); + TSNode *result = ts_node_leaf_at_pos(node, position); + ts_node_release(node); + return result; } + } - ts_node_retain(parent); - return parent; + ts_node_retain(parent); + return parent; } diff --git a/src/runtime/node.h b/src/runtime/node.h index d39e921a..825a319f 100644 --- a/src/runtime/node.h +++ b/src/runtime/node.h @@ -5,12 +5,12 @@ #include "runtime/tree.h" struct TSNode { - size_t ref_count; - size_t start_position; - size_t index; - const TSTree *content; - struct TSNode *parent; - const char **names; + size_t ref_count; + size_t start_position; + size_t index; + const TSTree *content; + struct TSNode *parent; + const char **names; }; TSNode * ts_node_make(const TSTree *tree, TSNode *parent, size_t index, size_t start_position, const char **names); diff --git a/src/runtime/parser.c b/src/runtime/parser.c index ab411884..29476792 100644 --- a/src/runtime/parser.c +++ b/src/runtime/parser.c @@ -8,56 +8,56 @@ */ static const TSParseAction * actions_for_state(TSParserConfig config, TSStateId state) { - return config.parse_table + (state * config.symbol_count); + return config.parse_table + (state * config.symbol_count); } static size_t breakdown_stack(TSParser *parser, TSInputEdit *edit) { - if (!edit) return 0; + if (!edit) return 0; - TSStack *stack = &parser->stack; - size_t position = 0; + TSStack *stack = &parser->stack; + size_t position = 0; - for (;;) { - TSTree *node = ts_stack_top_node(stack); - if (!node) break; + for (;;) { + TSTree *node = ts_stack_top_node(stack); + if (!node) break; - position = ts_stack_right_position(stack); - size_t child_count; - TSTree **children = ts_tree_children(node, &child_count); - if (position <= edit->position && !children) break; + position = ts_stack_right_position(stack); + size_t child_count; + TSTree **children = ts_tree_children(node, &child_count); + if (position <= edit->position && !children) break; - stack->size--; - position -= ts_tree_total_size(node); + stack->size--; + position -= ts_tree_total_size(node); - for (size_t i = 0; i < child_count && position < edit->position; i++) { - TSTree *child = children[i]; - TSStateId state = ts_stack_top_state(stack); - TSStateId next_state = actions_for_state(parser->config, state)[child->symbol].data.to_state; - ts_stack_push(stack, next_state, child); - ts_tree_retain(child); - position += ts_tree_total_size(child); - } - - ts_tree_release(node); + for (size_t i = 0; i < child_count && position < edit->position; i++) { + TSTree *child = children[i]; + TSStateId state = ts_stack_top_state(stack); + TSStateId next_state = actions_for_state(parser->config, state)[child->symbol].data.to_state; + ts_stack_push(stack, next_state, child); + ts_tree_retain(child); + position += ts_tree_total_size(child); } - return position; + ts_tree_release(node); + } + + return position; } static TSSymbol * expected_symbols(TSParser *parser, size_t *count) { - *count = 0; - const TSParseAction *actions = actions_for_state(parser->config, ts_stack_top_state(&parser->stack)); - for (size_t i = 0; i < parser->config.symbol_count; i++) - if (actions[i].type != TSParseActionTypeError) - (*count)++; + *count = 0; + const TSParseAction *actions = actions_for_state(parser->config, ts_stack_top_state(&parser->stack)); + for (size_t i = 0; i < parser->config.symbol_count; i++) + if (actions[i].type != TSParseActionTypeError) + (*count)++; - size_t n = 0; - TSSymbol *result = malloc(*count * sizeof(*result)); - for (TSSymbol i = 0; i < parser->config.symbol_count; i++) - if (actions[i].type != TSParseActionTypeError) - result[n++] = i; + size_t n = 0; + TSSymbol *result = malloc(*count * sizeof(*result)); + for (TSSymbol i = 0; i < parser->config.symbol_count; i++) + if (actions[i].type != TSParseActionTypeError) + result[n++] = i; - return result; + return result; } /* @@ -65,183 +65,185 @@ static TSSymbol * expected_symbols(TSParser *parser, size_t *count) { */ TSParser * ts_parser_make(TSParserConfig config) { - TSParser *result = malloc(sizeof(*result)); - *result = (TSParser) { - .lexer = ts_lexer_make(), - .stack = ts_stack_make(), - .debug = 0, - .config = config, - }; - return result; + TSParser *result = malloc(sizeof(*result)); + *result = (TSParser) { + .lexer = ts_lexer_make(), + .stack = ts_stack_make(), + .debug = 0, + .config = config, + }; + return result; } void ts_parser_free(TSParser *parser) { - if (parser->lookahead) ts_tree_release(parser->lookahead); - if (parser->next_lookahead) ts_tree_release(parser->next_lookahead); - ts_stack_delete(&parser->stack); - free(parser); + if (parser->lookahead) ts_tree_release(parser->lookahead); + if (parser->next_lookahead) ts_tree_release(parser->next_lookahead); + ts_stack_delete(&parser->stack); + free(parser); } void ts_parser_start(TSParser *parser, TSInput input, TSInputEdit *edit) { - if (!edit) ts_stack_shrink(&parser->stack, 0); - parser->lookahead = NULL; - parser->next_lookahead = NULL; + if (!edit) ts_stack_shrink(&parser->stack, 0); + parser->lookahead = NULL; + parser->next_lookahead = NULL; - size_t position = breakdown_stack(parser, edit); - input.seek_fn(input.data, position); + size_t position = breakdown_stack(parser, edit); + input.seek_fn(input.data, position); - parser->lexer = ts_lexer_make(); - parser->lexer.input = input; - ts_lexer_advance(&parser->lexer); + parser->lexer = ts_lexer_make(); + parser->lexer.input = input; + ts_lexer_advance(&parser->lexer); } void ts_parser_shift(TSParser *parser, TSStateId parse_state) { - if (ts_tree_is_extra(parser->lookahead)) - parse_state = ts_stack_top_state(&parser->stack); - ts_stack_push(&parser->stack, parse_state, parser->lookahead); - parser->lookahead = parser->next_lookahead; - parser->next_lookahead = NULL; + if (ts_tree_is_extra(parser->lookahead)) + parse_state = ts_stack_top_state(&parser->stack); + ts_stack_push(&parser->stack, parse_state, parser->lookahead); + parser->lookahead = parser->next_lookahead; + parser->next_lookahead = NULL; } void ts_parser_shift_extra(TSParser *parser) { - ts_tree_set_extra(parser->lookahead); - ts_parser_shift(parser, 0); + ts_tree_set_extra(parser->lookahead); + ts_parser_shift(parser, 0); } void ts_parser_reduce(TSParser *parser, TSSymbol symbol, size_t child_count) { - parser->next_lookahead = parser->lookahead; - parser->lookahead = ts_stack_reduce( - &parser->stack, - symbol, - child_count, - parser->config.hidden_symbol_flags, 1); + parser->next_lookahead = parser->lookahead; + parser->lookahead = ts_stack_reduce( + &parser->stack, + symbol, + child_count, + parser->config.hidden_symbol_flags, 1); } int ts_parser_reduce_extra(TSParser *parser, TSSymbol symbol) { - TSTree *top_node = ts_stack_top_node(&parser->stack); - if (top_node->symbol == symbol && !ts_tree_is_extra(top_node)) { - ts_parser_reduce(parser, symbol, 1); - ts_tree_set_extra(parser->lookahead); - return 1; - } else { - return 0; - } + TSTree *top_node = ts_stack_top_node(&parser->stack); + if (top_node->symbol == symbol && !ts_tree_is_extra(top_node)) { + ts_parser_reduce(parser, symbol, 1); + ts_tree_set_extra(parser->lookahead); + return 1; + } else { + return 0; + } } int ts_parser_handle_error(TSParser *parser) { - size_t count = 0; - const TSSymbol *inputs = expected_symbols(parser, &count); - TSTree *error = ts_tree_make_error(ts_lexer_lookahead_char(&parser->lexer), - count, - inputs, - 0, - 0); + size_t count = 0; + const TSSymbol *inputs = expected_symbols(parser, &count); + TSTree *error = ts_tree_make_error( + ts_lexer_lookahead_char(&parser->lexer), + count, + inputs, + 0, + 0); - for (;;) { - ts_tree_release(parser->lookahead); - size_t position = ts_lexer_position(&parser->lexer); - parser->lookahead = parser->config.lex_fn(parser, ts_lex_state_error); + for (;;) { + ts_tree_release(parser->lookahead); + size_t position = ts_lexer_position(&parser->lexer); + parser->lookahead = parser->config.lex_fn(parser, ts_lex_state_error); - int at_end = 0; - if (ts_lexer_position(&parser->lexer) == position) - at_end = !ts_lexer_advance(&parser->lexer); + int at_end = 0; + if (ts_lexer_position(&parser->lexer) == position) + at_end = !ts_lexer_advance(&parser->lexer); - if (at_end || parser->lookahead->symbol == ts_builtin_sym_end) { - ts_stack_push(&parser->stack, 0, error); - return 0; - } - - /* - * Unwind the stack, looking for a state in which this token - * may appear after an error. - */ - for (size_t j = 0; j < parser->stack.size; j++) { - size_t i = parser->stack.size - 1 - j; - TSStateId stack_state = parser->stack.entries[i].state; - TSParseAction action_on_error = actions_for_state(parser->config, stack_state)[ts_builtin_sym_error]; - if (action_on_error.type == TSParseActionTypeShift) { - TSStateId state_after_error = action_on_error.data.to_state; - if (actions_for_state(parser->config, state_after_error)[parser->lookahead->symbol].type != TSParseActionTypeError) { - ts_stack_shrink(&parser->stack, i + 1); - ts_stack_push(&parser->stack, state_after_error, error); - return 1; - } - } - } + if (at_end || parser->lookahead->symbol == ts_builtin_sym_end) { + ts_stack_push(&parser->stack, 0, error); + return 0; } + + /* + * Unwind the stack, looking for a state in which this token + * may appear after an error. + */ + for (size_t j = 0; j < parser->stack.size; j++) { + size_t i = parser->stack.size - 1 - j; + TSStateId stack_state = parser->stack.entries[i].state; + TSParseAction action_on_error = actions_for_state(parser->config, stack_state)[ts_builtin_sym_error]; + if (action_on_error.type == TSParseActionTypeShift) { + TSStateId state_after_error = action_on_error.data.to_state; + if (actions_for_state(parser->config, state_after_error)[parser->lookahead->symbol].type != TSParseActionTypeError) { + ts_stack_shrink(&parser->stack, i + 1); + ts_stack_push(&parser->stack, state_after_error, error); + return 1; + } + } + } + } } TSTree * ts_parser_tree_root(TSParser *parser) { - TSStack *stack = &parser->stack; - size_t node_count = 0; - for (size_t i = 0; i < stack->size; i++) { - TSTree *node = stack->entries[i].node; - if (!parser->config.hidden_symbol_flags[node->symbol]) - node_count++; - } + TSStack *stack = &parser->stack; + size_t node_count = 0; + for (size_t i = 0; i < stack->size; i++) { + TSTree *node = stack->entries[i].node; + if (!parser->config.hidden_symbol_flags[node->symbol]) + node_count++; + } - if (node_count > 1) - return ts_stack_reduce(stack, 2, stack->size, parser->config.hidden_symbol_flags, 0); - else - return ts_stack_top_node(stack); + if (node_count > 1) + return ts_stack_reduce(stack, 2, stack->size, parser->config.hidden_symbol_flags, 0); + else + return ts_stack_top_node(stack); } TSParseAction ts_parser_next_action(TSParser *parser) { - TSStateId state = ts_stack_top_state(&parser->stack); - if (!parser->lookahead) - parser->lookahead = parser->config.lex_fn(parser, parser->config.lex_states[state]); - return actions_for_state(parser->config, state)[parser->lookahead->symbol]; + TSStateId state = ts_stack_top_state(&parser->stack); + if (!parser->lookahead) + parser->lookahead = parser->config.lex_fn(parser, parser->config.lex_states[state]); + return actions_for_state(parser->config, state)[parser->lookahead->symbol]; } #define DEBUG_PARSE(...) \ -if (parser->debug) { fprintf(stderr, "\n" __VA_ARGS__); } + if (parser->debug) { fprintf(stderr, "\n" __VA_ARGS__); } TSTree * ts_parser_step(TSParser *parser) { - TSParseAction action = ts_parser_next_action(parser); - DEBUG_PARSE("LOOKAHEAD %s", parser->config.symbol_names[parser->lookahead->symbol]); - switch (action.type) { - case TSParseActionTypeShift: - DEBUG_PARSE("SHIFT %d", action.data.to_state); - ts_parser_shift(parser, action.data.to_state); - return NULL; - case TSParseActionTypeShiftExtra: - DEBUG_PARSE("SHIFT EXTRA"); - ts_parser_shift_extra(parser); - return NULL; - case TSParseActionTypeReduce: - DEBUG_PARSE("REDUCE %s %d", parser->config.symbol_names[action.data.symbol], action.data.child_count); - ts_parser_reduce(parser, action.data.symbol, action.data.child_count); - return NULL; - case TSParseActionTypeReduceExtra: - if (!ts_parser_reduce_extra(parser, action.data.symbol)) - goto error; - DEBUG_PARSE("REDUCE EXTRA"); - return NULL; - case TSParseActionTypeAccept: - DEBUG_PARSE("ACCEPT"); - return ts_parser_tree_root(parser); - case TSParseActionTypeError: - goto error; - default: - return NULL; - } + TSParseAction action = ts_parser_next_action(parser); + DEBUG_PARSE("LOOKAHEAD %s", parser->config.symbol_names[parser->lookahead->symbol]); + switch (action.type) { + case TSParseActionTypeShift: + DEBUG_PARSE("SHIFT %d", action.data.to_state); + ts_parser_shift(parser, action.data.to_state); + return NULL; + case TSParseActionTypeShiftExtra: + DEBUG_PARSE("SHIFT EXTRA"); + ts_parser_shift_extra(parser); + return NULL; + case TSParseActionTypeReduce: + DEBUG_PARSE("REDUCE %s %d", parser->config.symbol_names[action.data.symbol], action.data.child_count); + ts_parser_reduce(parser, action.data.symbol, action.data.child_count); + return NULL; + case TSParseActionTypeReduceExtra: + if (!ts_parser_reduce_extra(parser, action.data.symbol)) + goto error; + DEBUG_PARSE("REDUCE EXTRA"); + return NULL; + case TSParseActionTypeAccept: + DEBUG_PARSE("ACCEPT"); + return ts_parser_tree_root(parser); + case TSParseActionTypeError: + goto error; + default: + return NULL; + } + error: - DEBUG_PARSE("ERROR"); - if (!ts_parser_handle_error(parser)) - return ts_parser_tree_root(parser); - else - return NULL; + DEBUG_PARSE("ERROR"); + if (!ts_parser_handle_error(parser)) + return ts_parser_tree_root(parser); + else + return NULL; } const TSTree * ts_parser_parse(TSParser *parser, TSInput input, TSInputEdit *edit) { - ts_parser_start(parser, input, edit); + ts_parser_start(parser, input, edit); - for (;;) { - const TSTree *tree = ts_parser_step(parser); - if (tree) return tree; - } + for (;;) { + const TSTree *tree = ts_parser_step(parser); + if (tree) return tree; + } } TSParserConfig ts_parser_config(TSParser *parser) { - return parser->config; + return parser->config; } diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 8fcad287..6a6ab23c 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -7,77 +7,78 @@ static size_t INITIAL_STACK_SIZE = 100; static TSStateId INITIAL_STATE = 0; TSStack ts_stack_make() { - TSStack result = { - .entries = calloc(INITIAL_STACK_SIZE, sizeof(*result.entries)), - .size = 0, - }; - return result; + TSStack result = { + .entries = calloc(INITIAL_STACK_SIZE, sizeof(*result.entries)), + .size = 0, + }; + return result; } void ts_stack_delete(TSStack *stack) { - ts_stack_shrink(stack, 0); - free(stack->entries); + ts_stack_shrink(stack, 0); + free(stack->entries); } TSStateId ts_stack_top_state(const TSStack *stack) { - if (stack->size == 0) return INITIAL_STATE; - return stack->entries[stack->size - 1].state; + if (stack->size == 0) + return INITIAL_STATE; + return stack->entries[stack->size - 1].state; } TSTree * ts_stack_top_node(const TSStack *stack) { - if (stack->size == 0) return NULL; - return stack->entries[stack->size - 1].node; + if (stack->size == 0) + return NULL; + return stack->entries[stack->size - 1].node; } void ts_stack_push(TSStack *stack, TSStateId state, TSTree *node) { - stack->entries[stack->size].state = state; - stack->entries[stack->size].node = node; - stack->size++; - ts_tree_retain(node); + stack->entries[stack->size].state = state; + stack->entries[stack->size].node = node; + stack->size++; + ts_tree_retain(node); } void ts_stack_shrink(TSStack *stack, size_t new_size) { - for (size_t i = new_size; i < stack->size; i++) - ts_tree_release(stack->entries[i].node); - stack->size = new_size; + for (size_t i = new_size; i < stack->size; i++) + ts_tree_release(stack->entries[i].node); + stack->size = new_size; } size_t ts_stack_right_position(const TSStack *stack) { - size_t result = 0; - for (size_t i = 0; i < stack->size; i++) { - TSTree *node = stack->entries[i].node; - result += ts_tree_total_size(node); - } - return result; + size_t result = 0; + for (size_t i = 0; i < stack->size; i++) { + TSTree *node = stack->entries[i].node; + result += ts_tree_total_size(node); + } + return result; } TSTree * ts_stack_reduce(TSStack *stack, - TSSymbol symbol, - size_t child_count, - const int *hidden_symbol_flags, - int dont_count_extras) { + TSSymbol symbol, + size_t child_count, + const int *hidden_symbol_flags, + int dont_count_extras) { - // First, walk down the stack to determine which symbols will be reduced. - // The child node count is known ahead of time, but some children may be - // extra tokens, which don't count towards the child node count. - for (size_t i = 0; i < child_count; i++) { - TSTree *child = stack->entries[stack->size - 1 - i].node; - if (dont_count_extras && ts_tree_is_extra(child)) - child_count++; - } + // First, walk down the stack to determine which symbols will be reduced. + // The child node count is known ahead of time, but some children may be + // extra tokens, which don't count towards the child node count. + for (size_t i = 0; i < child_count; i++) { + TSTree *child = stack->entries[stack->size - 1 - i].node; + if (dont_count_extras && ts_tree_is_extra(child)) + child_count++; + } - size_t start_index = stack->size - child_count; - TSTree **children = calloc(child_count, sizeof(TSTree *)); - for (size_t i = 0; i < child_count; i++) - children[i] = stack->entries[start_index + i].node; + size_t start_index = stack->size - child_count; + TSTree **children = calloc(child_count, sizeof(TSTree *)); + for (size_t i = 0; i < child_count; i++) + children[i] = stack->entries[start_index + i].node; - TSTree *lookahead = ts_tree_make_node( - symbol, - child_count, - children, - hidden_symbol_flags[symbol] - ); + TSTree *lookahead = ts_tree_make_node( + symbol, + child_count, + children, + hidden_symbol_flags[symbol]); - ts_stack_shrink(stack, stack->size - child_count); - return lookahead; + ts_stack_shrink(stack, stack->size - child_count); + return lookahead; } diff --git a/src/runtime/tree.c b/src/runtime/tree.c index 74b4fbf7..ffa068db 100644 --- a/src/runtime/tree.c +++ b/src/runtime/tree.c @@ -4,181 +4,181 @@ #include "runtime/tree.h" static TSTree * ts_tree_make(TSSymbol symbol, size_t size, size_t offset, int is_hidden) { - TSTree *result = malloc(sizeof(TSTree)); - *result = (TSTree) { - .ref_count = 1, - .symbol = symbol, - .size = size, - .offset = offset, - .options = is_hidden ? TSTreeOptionsHidden : 0, - }; - return result; + TSTree *result = malloc(sizeof(TSTree)); + *result = (TSTree) { + .ref_count = 1, + .symbol = symbol, + .size = size, + .offset = offset, + .options = is_hidden ? TSTreeOptionsHidden : 0, + }; + return result; } TSTree * ts_tree_make_leaf(TSSymbol symbol, size_t size, size_t offset, int is_hidden) { - TSTree *result = ts_tree_make(symbol, size, offset, is_hidden); - result->child_count = 0; - result->children = NULL; - return result; + TSTree *result = ts_tree_make(symbol, size, offset, is_hidden); + result->child_count = 0; + result->children = NULL; + return result; } TSTree * ts_tree_make_node(TSSymbol symbol, size_t child_count, TSTree **children, int is_hidden) { - size_t size = 0, offset = 0, visible_child_count = 0; - for (size_t i = 0; i < child_count; i++) { - TSTree *child = children[i]; - ts_tree_retain(child); - if (i == 0) { - offset = child->offset; - size = child->size; - } else { - size += child->offset + child->size; - } - - if (ts_tree_is_visible(child)) - visible_child_count++; - else - visible_child_count += ts_tree_visible_child_count(child); + size_t size = 0, offset = 0, visible_child_count = 0; + for (size_t i = 0; i < child_count; i++) { + TSTree *child = children[i]; + ts_tree_retain(child); + if (i == 0) { + offset = child->offset; + size = child->size; + } else { + size += child->offset + child->size; } - TSTreeOptions options = 0; - if (is_hidden) - options |= TSTreeOptionsHidden; - if (child_count == 1 && (ts_tree_is_visible(children[0]) || ts_tree_is_wrapper(children[0]))) - options |= (TSTreeOptionsWrapper | TSTreeOptionsHidden); + if (ts_tree_is_visible(child)) + visible_child_count++; + else + visible_child_count += ts_tree_visible_child_count(child); + } - TSTree *result = malloc(sizeof(TSTree) + (visible_child_count * sizeof(TSChildWithPosition))); - *result = (TSTree) { - .ref_count = 1, - .symbol = symbol, - .size = size, - .offset = offset, - .options = options, - .children = children, - .child_count = child_count, - .visible_child_count = visible_child_count, - }; + TSTreeOptions options = 0; + if (is_hidden) + options |= TSTreeOptionsHidden; + if (child_count == 1 && (ts_tree_is_visible(children[0]) || ts_tree_is_wrapper(children[0]))) + options |= (TSTreeOptionsWrapper | TSTreeOptionsHidden); - TSChildWithPosition *visible_children = ts_tree_visible_children(result, NULL); + TSTree *result = malloc(sizeof(TSTree) + (visible_child_count * sizeof(TSChildWithPosition))); + *result = (TSTree) { + .ref_count = 1, + .symbol = symbol, + .size = size, + .offset = offset, + .options = options, + .children = children, + .child_count = child_count, + .visible_child_count = visible_child_count, + }; - for (size_t i = 0, visible_i = 0, child_position = 0; i < child_count; i++) { - TSTree *child = children[i]; - if (ts_tree_is_visible(child)) { - visible_children[visible_i] = (TSChildWithPosition) { - .tree = child, - .position = child_position - }; - visible_i++; - } else { - size_t granchild_count = 0; - TSChildWithPosition *grandchildren = ts_tree_visible_children(child, &granchild_count); - for (size_t j = 0; j < granchild_count; j++) { - visible_children[visible_i] = (TSChildWithPosition) { - .tree = grandchildren[j].tree, - .position = grandchildren[j].position + child_position - }; - visible_i++; - } - } + TSChildWithPosition *visible_children = ts_tree_visible_children(result, NULL); - child_position += child->offset + child->size; + for (size_t i = 0, visible_i = 0, child_position = 0; i < child_count; i++) { + TSTree *child = children[i]; + if (ts_tree_is_visible(child)) { + visible_children[visible_i] = (TSChildWithPosition) { + .tree = child, + .position = child_position + }; + visible_i++; + } else { + size_t granchild_count = 0; + TSChildWithPosition *grandchildren = ts_tree_visible_children(child, &granchild_count); + for (size_t j = 0; j < granchild_count; j++) { + visible_children[visible_i] = (TSChildWithPosition) { + .tree = grandchildren[j].tree, + .position = grandchildren[j].position + child_position + }; + visible_i++; + } } - return result; + child_position += child->offset + child->size; + } + + return result; } TSTree * ts_tree_make_error(char lookahead_char, size_t expected_input_count, const TSSymbol *expected_inputs, size_t size, size_t offset) { - TSTree *result = ts_tree_make(ts_builtin_sym_error, size, offset, 0); - result->lookahead_char = lookahead_char; - result->expected_input_count = expected_input_count; - result->expected_inputs = expected_inputs; - return result; + TSTree *result = ts_tree_make(ts_builtin_sym_error, size, offset, 0); + result->lookahead_char = lookahead_char; + result->expected_input_count = expected_input_count; + result->expected_inputs = expected_inputs; + return result; } void ts_tree_retain(TSTree *tree) { - tree->ref_count++; + tree->ref_count++; } void ts_tree_release(TSTree *tree) { - tree->ref_count--; - if (tree->ref_count == 0) { - size_t count; - TSTree **children = ts_tree_children(tree, &count); - for (size_t i = 0; i < count; i++) - ts_tree_release(children[i]); - free(tree->children); - free(tree); - } + tree->ref_count--; + if (tree->ref_count == 0) { + size_t count; + TSTree **children = ts_tree_children(tree, &count); + for (size_t i = 0; i < count; i++) + ts_tree_release(children[i]); + free(tree->children); + free(tree); + } } size_t ts_tree_total_size(const TSTree *tree) { - return tree->offset + tree->size; + return tree->offset + tree->size; } int ts_tree_equals(const TSTree *node1, const TSTree *node2) { - if (node1->symbol != node2->symbol) return 0; - if (node1->symbol == ts_builtin_sym_error) { - // check error equality - } else { - if (node1->child_count != node2->child_count) return 0; - for (size_t i = 0; i < node1->child_count; i++) - if (!ts_tree_equals(node1->children[i], node2->children[i])) return 0; - } - return 1; + if (node1->symbol != node2->symbol) return 0; + if (node1->symbol == ts_builtin_sym_error) { + // check error equality + } else { + if (node1->child_count != node2->child_count) return 0; + for (size_t i = 0; i < node1->child_count; i++) + if (!ts_tree_equals(node1->children[i], node2->children[i])) return 0; + } + return 1; } TSTree ** ts_tree_children(const TSTree *tree, size_t *count) { - if (!tree || tree->symbol == ts_builtin_sym_error) { - if (count) *count = 0; - return NULL; - } - if (count) *count = tree->child_count; - return tree->children; + if (!tree || tree->symbol == ts_builtin_sym_error) { + if (count) *count = 0; + return NULL; + } + if (count) *count = tree->child_count; + return tree->children; } static size_t write_lookahead_to_string(char *string, size_t limit, char lookahead) { - switch (lookahead) { - case '\0': - return snprintf(string, limit, ""); - default: - return snprintf(string, limit, "'%c'", lookahead); - } + switch (lookahead) { + case '\0': + return snprintf(string, limit, ""); + default: + return snprintf(string, limit, "'%c'", lookahead); + } } static size_t tree_write_to_string(const TSTree *tree, const char **symbol_names, char *string, size_t limit, int is_root) { - char *cursor = string; - char **writer = (limit > 0) ? &cursor : &string; - int visible = ts_tree_is_visible(tree); + char *cursor = string; + char **writer = (limit > 0) ? &cursor : &string; + int visible = ts_tree_is_visible(tree); - if (visible && !is_root) - cursor += snprintf(*writer, limit, " "); - - if (!tree) - return snprintf(*writer, limit, "(NULL)"); - if (tree->symbol == ts_builtin_sym_error) { - cursor += snprintf(*writer, limit, "(ERROR "); - cursor += write_lookahead_to_string(*writer, limit, tree->lookahead_char); - cursor += snprintf(*writer, limit, ")"); - return cursor - string; - } - - if (visible) { - cursor += snprintf(*writer, limit, "(%s", symbol_names[tree->symbol]); - is_root = 0; - } - - for (size_t i = 0; i < tree->child_count; i++) - cursor += tree_write_to_string(tree->children[i], symbol_names, *writer, limit, is_root); - - if (visible) - cursor += snprintf(*writer, limit, ")"); + if (visible && !is_root) + cursor += snprintf(*writer, limit, " "); + if (!tree) + return snprintf(*writer, limit, "(NULL)"); + if (tree->symbol == ts_builtin_sym_error) { + cursor += snprintf(*writer, limit, "(ERROR "); + cursor += write_lookahead_to_string(*writer, limit, tree->lookahead_char); + cursor += snprintf(*writer, limit, ")"); return cursor - string; + } + + if (visible) { + cursor += snprintf(*writer, limit, "(%s", symbol_names[tree->symbol]); + is_root = 0; + } + + for (size_t i = 0; i < tree->child_count; i++) + cursor += tree_write_to_string(tree->children[i], symbol_names, *writer, limit, is_root); + + if (visible) + cursor += snprintf(*writer, limit, ")"); + + return cursor - string; } char * ts_tree_string(const TSTree *tree, const char **symbol_names) { - static char SCRATCH_STRING[1]; - size_t size = tree_write_to_string(tree, symbol_names, SCRATCH_STRING, 0, 1) + 1; - char *result = malloc(size * sizeof(char)); - tree_write_to_string(tree, symbol_names, result, size, 1); - return result; + static char SCRATCH_STRING[1]; + size_t size = tree_write_to_string(tree, symbol_names, SCRATCH_STRING, 0, 1) + 1; + char *result = malloc(size * sizeof(char)); + tree_write_to_string(tree, symbol_names, result, size, 1); + return result; } diff --git a/src/runtime/tree.h b/src/runtime/tree.h index 5c43946e..252a82e0 100644 --- a/src/runtime/tree.h +++ b/src/runtime/tree.h @@ -8,67 +8,67 @@ extern "C" { #include "tree_sitter/runtime.h" typedef enum { - TSTreeOptionsHidden = 1, - TSTreeOptionsExtra = 2, - TSTreeOptionsWrapper = 4, + TSTreeOptionsHidden = 1, + TSTreeOptionsExtra = 2, + TSTreeOptionsWrapper = 4, } TSTreeOptions; struct TSTree { - TSSymbol symbol; - TSTreeOptions options; - size_t ref_count; - size_t offset; - size_t size; - union { - struct { - size_t child_count; - struct TSTree **children; - size_t visible_child_count; - }; - struct { - size_t expected_input_count; - const TSSymbol *expected_inputs; - char lookahead_char; - }; + TSSymbol symbol; + TSTreeOptions options; + size_t ref_count; + size_t offset; + size_t size; + union { + struct { + size_t child_count; + struct TSTree **children; + size_t visible_child_count; }; + struct { + size_t expected_input_count; + const TSSymbol *expected_inputs; + char lookahead_char; + }; + }; }; typedef struct { - TSTree *tree; - size_t position; + TSTree *tree; + size_t position; } TSChildWithPosition; static inline int ts_tree_is_extra(const TSTree *tree) { - return (tree->options & TSTreeOptionsExtra); + return (tree->options & TSTreeOptionsExtra); } static inline int ts_tree_is_visible(const TSTree *tree) { - return !(tree->options & TSTreeOptionsHidden); + return !(tree->options & TSTreeOptionsHidden); } static inline void ts_tree_set_extra(TSTree *tree) { - tree->options = (TSTreeOptions)(tree->options | TSTreeOptionsExtra); + tree->options = (TSTreeOptions)(tree->options | TSTreeOptionsExtra); } static inline int ts_tree_is_wrapper(const TSTree *tree) { - return (tree->options & TSTreeOptionsWrapper); + return (tree->options & TSTreeOptionsWrapper); } static inline size_t ts_tree_visible_child_count(const TSTree *tree) { - if (tree->symbol == ts_builtin_sym_error) - return 0; - else - return tree->visible_child_count; + if (tree->symbol == ts_builtin_sym_error) + return 0; + else + return tree->visible_child_count; } static inline TSChildWithPosition * ts_tree_visible_children(const TSTree *tree, size_t *count) { - if (tree->symbol == ts_builtin_sym_error || tree->visible_child_count == 0) { - if (count) *count = 0; - return NULL; - } else { - if (count) *count = tree->visible_child_count; - return (TSChildWithPosition *)(tree + 1); - } + if (tree->symbol == ts_builtin_sym_error || tree->visible_child_count == 0) { + if (count) *count = 0; + return NULL; + } else { + if (count) *count = tree->visible_child_count; + return (TSChildWithPosition *)(tree + 1); + } } TSTree * ts_tree_make_leaf(TSSymbol symbol, size_t size, size_t offset, int is_hidden);