diff --git a/tools/gen-expr/.gitignore b/tools/gen-expr/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..90b7a4a7f44ac419c5b1ea44b7a1447aa0d55ae8 --- /dev/null +++ b/tools/gen-expr/.gitignore @@ -0,0 +1 @@ +.code.c diff --git a/tools/gen-expr/Makefile b/tools/gen-expr/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..ddddfaf85f361225a3551faa6d020fd2de208ea5 --- /dev/null +++ b/tools/gen-expr/Makefile @@ -0,0 +1,2 @@ +gen-expr: gen-expr.c + gcc -O2 -Wall -Werror -o $@ $< diff --git a/tools/gen-expr/gen-expr.c b/tools/gen-expr/gen-expr.c new file mode 100644 index 0000000000000000000000000000000000000000..eb829e15ccf51638de21d7a3ceb6aea28cb9ff21 --- /dev/null +++ b/tools/gen-expr/gen-expr.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +// this should be enough +static char buf[65536]; +static char *pbuf; + +#define format_buf(fmt, ...) pbuf += sprintf(pbuf, fmt, ##__VA_ARGS__) + +static inline uint32_t choose(uint32_t max) { + return rand() % max; +} + +static inline void gen_rand_op() { + char op_list[4] = {'+', '-', '*', '/'}; + format_buf("%c", op_list[choose(4)]); +} + +static inline void gen_num() { + format_buf("%uu", choose(64)); +} + +static inline void gen_space() { + char *space_list[3] = { + "", + " ", + " ", + }; + format_buf("%s", space_list[choose(3)]); +} + +static int nr_op = 0; + +static inline void gen_rand_expr() { + gen_space(); + switch (choose(4)) { + case 0: + if (nr_op == 0) gen_rand_expr(); + else gen_num(); + break; + case 1: + format_buf("("); + gen_rand_expr(); + format_buf(")"); + break; + default: + nr_op ++; + if (choose(2)) gen_rand_expr(); + else gen_num(); + gen_space(); + gen_rand_op(); + gen_space(); + if (choose(2)) gen_rand_expr(); + else gen_num(); + break; + } + gen_space(); +} + +void remove_u(char *p) { + char *q = p; + while ((q = strchr(q, 'u')) != NULL) { + // reuse code_buf + strcpy(code_buf, q + 1); + strcpy(q, code_buf); + } +} + +static char code_buf[65536]; +static char *code_format = +"#include \n" +"int main() { " +" unsigned result = %s; " +" printf(\"%%u\", result); " +" return 0; " +"}"; + +int main(int argc, char *argv[]) { + int seed = time(0); + srand(seed); + int loop = 1; + if (argc > 1) { + sscanf(argv[1], "%d", &loop); + } + int i; + for (i = 0; i < loop; i ++) { + nr_op = 0; + pbuf = buf; + + gen_rand_expr(); + + sprintf(code_buf, code_format, buf); + + FILE *fp = fopen(".code.c", "w"); + assert(fp != NULL); + fputs(code_buf, fp); + fclose(fp); + + int ret = system("gcc .code.c -o .expr"); + if (ret != 0) continue; + + fp = popen("./.expr", "r"); + assert(fp != NULL); + + int result; + fscanf(fp, "%d", &result); + pclose(fp); + remove_u(buf); + printf("%u %s\n", result, buf); + } + return 0; +}