Implement enum-strs
This commit is contained in:
parent
18103df342
commit
043cfd687c
11
Makefile
11
Makefile
|
|
@ -1,7 +1,7 @@
|
|||
CC := gcc -g -Og -std=c23 -Wall -Wextra -Wpedantic -Isrc -ltree-sitter
|
||||
CC := gcc -g -Og -std=c23 -Wall -Wextra -Wpedantic -Isrc -ltree-sitter -Ibuild
|
||||
|
||||
build/bin/cgen: src/main.c | build/.build-dirs
|
||||
$(CC) deps/tree-sitter-c/src/parser.c $^ -o build/bin/cgen
|
||||
build/bin/cgen: src/main.c build/gen/.queries | build/.build-dirs
|
||||
$(CC) deps/tree-sitter-c/src/parser.c $< -o build/bin/cgen
|
||||
|
||||
.PHONY: run
|
||||
run: build/bin/cgen
|
||||
|
|
@ -9,8 +9,13 @@ run: build/bin/cgen
|
|||
|
||||
build/.build-dirs: Makefile
|
||||
mkdir -p build/bin
|
||||
mkdir -p build/gen
|
||||
touch build/.build-dirs
|
||||
|
||||
build/gen/.queries: src/gen_enum.tsq | build/.build-dirs
|
||||
xxd -i src/gen_enum.tsq > build/gen/gen_enum_tsq.h
|
||||
touch build/gen/.queries
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf build
|
||||
|
|
|
|||
|
|
@ -10,6 +10,27 @@
|
|||
"-Wextra",
|
||||
"-Wpedantic",
|
||||
"-Isrc",
|
||||
"-Ibuild",
|
||||
"-o",
|
||||
"build/bin/cgen",
|
||||
"deps/tree-sitter-c/src/parser.c"
|
||||
],
|
||||
"directory": "/home/n/src/cgen",
|
||||
"file": "/home/n/src/cgen/deps/tree-sitter-c/src/parser.c",
|
||||
"output": "/home/n/src/cgen/build/bin/cgen"
|
||||
},
|
||||
{
|
||||
"arguments": [
|
||||
"/nix/store/1ciadcliylyyi9vx21id9vi1p1mayjn8-gcc-wrapper-14.2.0/bin/gcc",
|
||||
"-c",
|
||||
"-g",
|
||||
"-Og",
|
||||
"-std=c23",
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wpedantic",
|
||||
"-Isrc",
|
||||
"-Ibuild",
|
||||
"-o",
|
||||
"build/bin/cgen",
|
||||
"src/main.c"
|
||||
|
|
|
|||
|
|
@ -11,12 +11,13 @@
|
|||
pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
gdb
|
||||
gcc15
|
||||
gcc14
|
||||
valgrind
|
||||
strace
|
||||
llvmPackages_17.clang-tools
|
||||
bear
|
||||
tree-sitter
|
||||
tinyxxd
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,18 @@
|
|||
(enum_specifier
|
||||
name: (type_identifier)? @enum_name
|
||||
body: (enumerator_list
|
||||
(enumerator
|
||||
name: (identifier) @enum_variant)?))
|
||||
[
|
||||
(translation_unit
|
||||
(type_definition
|
||||
(enum_specifier
|
||||
name: (type_identifier)? @enum_name
|
||||
body: (enumerator_list
|
||||
((enumerator name: (identifier) @enum_variant) ","?)*
|
||||
)) @enum_spec
|
||||
declarator: (type_identifier) @enum_declarator_name
|
||||
))
|
||||
|
||||
(translation_unit
|
||||
(enum_specifier
|
||||
name: (type_identifier)? @enum_name
|
||||
body: (enumerator_list
|
||||
((enumerator name: (identifier) @enum_variant) ","?)*
|
||||
)) @enum_spec)
|
||||
]
|
||||
|
|
|
|||
86
src/main.c
86
src/main.c
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <tree_sitter/api.h>
|
||||
|
||||
#include "gen/gen_enum_tsq.h"
|
||||
|
||||
TSLanguage const *tree_sitter_c(void);
|
||||
|
||||
char const *USAGE = "\
|
||||
|
|
@ -25,9 +27,6 @@ size_t read_stdin(char *buf, size_t buf_cap) {
|
|||
return at - buf;
|
||||
}
|
||||
|
||||
char const gen_enum_query_str[] = {
|
||||
#embed "./gen_enum.tsq", '\0'
|
||||
};
|
||||
void gen_enum_strs() {
|
||||
size_t buf_cap = 2 << 16;
|
||||
char *buf = calloc(buf_cap, sizeof(*buf));
|
||||
|
|
@ -40,22 +39,91 @@ void gen_enum_strs() {
|
|||
TSTree *tree = ts_parser_parse_string(parser, nullptr, buf, buf_len);
|
||||
TSNode root_node = ts_tree_root_node(tree);
|
||||
|
||||
char *string = ts_node_string(root_node);
|
||||
printf("%s\n", string);
|
||||
|
||||
uint32_t err_offset = 0;
|
||||
TSQueryError err = {};
|
||||
TSQuery *query = ts_query_new(
|
||||
lang_c,
|
||||
gen_enum_query_str,
|
||||
strlen(gen_enum_query_str),
|
||||
(char*)src_gen_enum_tsq,
|
||||
src_gen_enum_tsq_len,
|
||||
&err_offset,
|
||||
&err
|
||||
);
|
||||
if (err != TSQueryErrorNone) {
|
||||
printf("query error %d near: %s\n", err, gen_enum_query_str + err_offset);
|
||||
printf("query error %d near: %s\n", err, src_gen_enum_tsq + err_offset);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
uint32_t cap_id_poison = 2 << 16;
|
||||
uint32_t cap_id_enum_name = cap_id_poison;
|
||||
uint32_t cap_id_enum_variant = cap_id_poison;
|
||||
uint32_t cap_id_enum_declarator_name = cap_id_poison;
|
||||
uint32_t cap_count = ts_query_capture_count(query);
|
||||
for (uint32_t i = 0; i < cap_count; ++i) {
|
||||
uint32_t len = 0;
|
||||
char const *name = ts_query_capture_name_for_id(query, i, &len);
|
||||
|
||||
if (!strncmp(name, "enum_name", len)) {
|
||||
cap_id_enum_name = i;
|
||||
}
|
||||
|
||||
if (!strncmp(name, "enum_variant", len)) {
|
||||
cap_id_enum_variant = i;
|
||||
}
|
||||
|
||||
if (!strncmp(name, "enum_declarator_name", len)) {
|
||||
cap_id_enum_declarator_name = i;
|
||||
}
|
||||
}
|
||||
|
||||
TSQueryCursor *qc = ts_query_cursor_new();
|
||||
ts_query_cursor_exec(qc, query, root_node);
|
||||
|
||||
TSQueryMatch match = {};
|
||||
while (ts_query_cursor_next_match(qc, &match)) {
|
||||
char const *poison = "POISON";
|
||||
char const *enum_name = poison;
|
||||
size_t enum_name_len = strlen(poison);
|
||||
|
||||
size_t enum_variants_cap = 512;
|
||||
struct {
|
||||
char const *start;
|
||||
size_t len;
|
||||
} enum_variants[enum_variants_cap] = {};
|
||||
size_t enum_variants_len = 0;
|
||||
for (uint32_t i = 0; i < match.capture_count; ++i) {
|
||||
TSQueryCapture cap = match.captures[i];
|
||||
|
||||
uint32_t start = ts_node_start_byte(cap.node);
|
||||
uint32_t end = ts_node_end_byte(cap.node);
|
||||
uint32_t len = end - start;
|
||||
char const *at = buf + start;
|
||||
|
||||
if (
|
||||
cap.index == cap_id_enum_name
|
||||
|| cap.index == cap_id_enum_declarator_name
|
||||
) {
|
||||
enum_name = at;
|
||||
enum_name_len = len;
|
||||
}
|
||||
|
||||
if (
|
||||
cap.index == cap_id_enum_variant
|
||||
&& enum_variants_len < enum_variants_cap
|
||||
) {
|
||||
enum_variants[enum_variants_len].len = len;
|
||||
enum_variants[enum_variants_len].start = at;
|
||||
|
||||
enum_variants_len++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("char const *%.*s_strs[] = {\n", (int)enum_name_len, enum_name);
|
||||
for (size_t i = 0; i < enum_variants_len; ++i) {
|
||||
typeof(enum_variants[0]) evar = enum_variants[i];
|
||||
printf("\t[%.*s] = \"%.*s\",\n", (int)evar.len, evar.start, (int)evar.len, evar.start);
|
||||
}
|
||||
printf("};\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue