diff --git a/Makefile b/Makefile index 15d2129..683a306 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ OBJECT := ${OBJECT:.c=.o} LIBS := sds.o LIBS := $(addprefix ${OBJECT.d}/,${LIBS}) -GENSOURCE := tbsp.yy.c tbsp.tab.c +GENSOURCE := tbsp.yy.c tbsp_c.yy.c tbsp.tab.c GENSOURCE := $(addprefix ${OBJECT.d}/,${GENSOURCE}) GENOBJECT := $(subst .c,.o,${GENSOURCE}) @@ -54,9 +54,12 @@ ${OBJECT.d}/%.o: ${LIB.d}/%.c ${COMPILE.c} -o $@ $< run: - ./${OUT} test/convert.tbsp > object/test.cpp - bake object/test.cpp - ./object/test.out test/input.md + #./${OUT} test/convert.tbsp > object/test.cpp + #bake object/test.cpp + #./object/test.out test/input.md + ./${OUT} test/function_collector.cpp.tbsp > object/function_collector.cpp + bake object//function_collector.cpp + ./object/function_collector.out object//function_collector.cpp clean: -rm ${GENSOURCE} diff --git a/source/TBSP_strings.inc b/source/TBSP_strings.inc index 7daba0a..7fcc1e5 100644 --- a/source/TBSP_strings.inc +++ b/source/TBSP_strings.inc @@ -38,6 +38,7 @@ char * tbtext(const char * const code, TSNode node) {\n\ }\n\ \n\ #define GET_TBTEXT tbtext(code, current_node)\n\ +#define GET_TBTEXT_FROM_NODE(n) tbtext(code, n)\n\ "; const char * const TBSP_case = "\ diff --git a/source/tbsp.l b/source/tbsp.l index 6ef64c5..0a4043f 100644 --- a/source/tbsp.l +++ b/source/tbsp.l @@ -16,11 +16,12 @@ identifier [a-zA-z][-a-zA-z0-9_]* %option nodefault %option noyywrap +%option nounput noinput %% . { yyless(0); BEGIN IN_DEFINITION_SECTION; } { -\%top[[:space:]]+\{ { +\%top[[:space:]]*\{ { code_caller = IN_DEFINITION_SECTION; BEGIN IN_CODE; return TOP; @@ -37,6 +38,9 @@ identifier [a-zA-z][-a-zA-z0-9_]* BEGIN IN_RULE_SECTION; return SEPARATOR; } +. { + yyerror("unknown shit"); + } } { @@ -45,7 +49,7 @@ identifier [a-zA-z][-a-zA-z0-9_]* BEGIN IN_CODE; } \} { ; } -[[:space:]]* { ; } +([[:space:]]|\n)* { ; } enter[[:space:]] { return ENTER; } leave[[:space:]] { return LEAVE; } {identifier} { @@ -81,6 +85,7 @@ leave[[:space:]] { return LEAVE; } return CODE_BLOB; } } + %% int tbsp_yy_init(void) { diff --git a/source/tbsp.y b/source/tbsp.y index 5c221fc..6e029ea 100644 --- a/source/tbsp.y +++ b/source/tbsp.y @@ -77,11 +77,14 @@ rule_section rule : rule_type rule_selector CODE_BLOB { + extern char * tbsp_c_expland_code(const char * const s); + char * code_blob_expanded = strdup(tbsp_c_expland_code($3)); + kv_push(rule_t, rules, (rule_t) { .type = $1 COMA .target = target_counter COMA .string = $2 COMA - .code = $3 COMA + .code = code_blob_expanded COMA }); ++target_counter; } @@ -103,13 +106,12 @@ code_section verbatim = $1; } ; - %% rule_vector_t rules; void yyerror(const char * const s) { - puts("yyerror"); + printf("error: %s", s); } void tbsp_tab_init(void) { diff --git a/source/tbsp_c.l b/source/tbsp_c.l new file mode 100644 index 0000000..b42cb61 --- /dev/null +++ b/source/tbsp_c.l @@ -0,0 +1,119 @@ +%{ + #define _GNU_SOURCE + #include + #include + + #include + #include + + kvec_t(char *) query; + static sds buffer; + + #define ECHOC(x) do { buffer = sdscatlen(buffer, &x, 1); } while(0) + #define ECHOS(x) do { buffer = sdscat(buffer, x); } while(0) + + extern char * expand_c_query(void); +%} +identifier [a-zA-z][a-zA-z0-9_]* + +%x IN_COMMENT IN_MULTILINE_COMMENT IN_STRING +%x IN_QUERY + +%option nodefault +%option noyywrap +%option nounput noinput + +%option prefix="tbsp_c_" +%% +\/\/ { + ECHOS(yytext); + BEGIN IN_COMMENT; + } +\/\* { + ECHOS(yytext); + BEGIN IN_COMMENT; + } +\" { + BEGIN IN_STRING; + } +\$\$ { + BEGIN IN_QUERY; + } +.|\n { + ECHOS(yytext); + } + +{ +\n { + ECHOS(yytext); + BEGIN INITIAL; + } +. { + ECHOS(yytext); + } +} + +{ +\*\/ { + ECHOS(yytext); + BEGIN INITIAL; + } +. { + ECHOS(yytext); + } +} + +{ +\\\" { + ECHOS(yytext); + } +\" { + ECHOS(yytext); + BEGIN INITIAL; + } +. { + ECHOS(yytext); + } +} + +{ +\-\> { ; } +{identifier} { + kv_push(char *, query, strdup(yytext)); + } +. { + char * expanded_query = expand_c_query(); + ECHOS(expanded_query); + free(expanded_query); + + ECHOS(yytext); + + BEGIN INITIAL; + } +} + +%% + +char * tbsp_c_expland_code(const char * const s) { + kv_init(query); + buffer = sdsnew(""); + + YY_BUFFER_STATE const b = yy_scan_string(s); + tbsp_c_lex(); + tbsp_c__delete_buffer(b); + + return buffer; +} + +// XXX this bleeds +char * expand_c_query(void) { + const char * const query_fmt = "ts_node_child_by_field_name(%s, \"%s\", strlen(\"%s\"))"; + char * r; + + r = (char *)"current_node"; + for (int i = 0; i < kv_size(query); i++) { + asprintf(&r, query_fmt, r, kv_A(query, i), kv_A(query, i)); + } + + return r; +} diff --git a/test/function_collector.cpp.tbsp b/test/function_collector.cpp.tbsp new file mode 100644 index 0000000..8eb5588 --- /dev/null +++ b/test/function_collector.cpp.tbsp @@ -0,0 +1,44 @@ +%top { + #include + #include + #include + + using namespace std; + + set functions; +} +%language cpp +%% + +enter function_definition { + char * name = GET_TBTEXT_FROM_NODE($$->declarator->declarator); + functions.insert(name); + free(name); +} + +%% + +// @BAKE g++ $@ -o $*.out $(pkg-config --cflags --libs tree-sitter tree-sitter-cpp) + +signed main(int argc, char * * argv) { + if (argc < 2) { + return 1; + } + + FILE* f = fopen(argv[1], "r"); + fseek(f, 0, SEEK_END); + int flen = ftell(f); + rewind(f); + char fstr[flen+1]; + fstr[flen] = '\00'; + fread(fstr, flen, sizeof(char), f); + fclose(f); + + tbtraverse(fstr); + + for (const auto &i : functions) { + puts(i.c_str()); + } + + return 0; +}