tbsp/source/tbc.cpp
2024-09-12 22:22:23 +02:00

106 lines
2.1 KiB
C++

#include <stdio.h>
#include <string.h>
extern "C" {
#include <tree_sitter/api.h>
extern const TSLanguage * tree_sitter_c(void);
}
int tbtraverse(const char * const code) {
// init
TSParser * parser;
TSTree * tree;
TSTreeCursor cursor;
TSNode current_node;
TSNode previous_node;
parser = ts_parser_new();
ts_parser_set_language(parser, tree_sitter_c());
tree = ts_parser_parse_string(parser, NULL, code, strlen(code));
cursor = ts_tree_cursor_new(ts_tree_root_node(tree));
current_node = ts_tree_root_node(tree);
// meat
do {
current_node = ts_tree_cursor_current_node(&cursor);
const char * previous_node_type = NULL;
int tblen = ts_node_end_byte(current_node) - ts_node_start_byte(current_node);
char * tbtext = (char *)malloc(sizeof(char) * (tblen + 1));
memcpy(tbtext, code + ts_node_start_byte(current_node), tblen);
tbtext[tblen] = '\0';
// XXX INJECTION
if (!strcmp("function_definition", ts_node_type(current_node))) {
puts("ack");
puts(tbtext);
goto end;
}
if (!strcmp("number_literal", ts_node_type(current_node))) {
puts("++");
goto end;
}
end:
free(tbtext);
} while ([&] {
bool r = false;
previous_node = current_node;
if (ts_tree_cursor_goto_first_child(&cursor)
|| ts_tree_cursor_goto_next_sibling(&cursor)) {
r = true;
goto eval;
}
while (ts_tree_cursor_goto_parent(&cursor)) {
if (!strcmp(ts_node_type(current_node), "translation_unit")) {
r = false;
break;
}
if (ts_tree_cursor_goto_next_sibling(&cursor)) {
r = true;
}
eval:
if (!strcmp("function_definition", ts_node_type(previous_node))) {
puts("^^df");
goto end;
}
end:
if (r) { break; }
}
return r;
}());
// deinit
ts_tree_delete(tree);
ts_parser_delete(parser);
ts_tree_cursor_delete(&cursor);
return 0;
}
// @BAKE g++ $@ $(pkg-config --cflags --libs tree-sitter tree-sitter-c) -ggdb
signed main() {
tbtraverse("int main() { return 0; }");
}