diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bf.c | 38 | ||||
-rw-r--r-- | src/include/bf.h | 9 | ||||
-rw-r--r-- | src/include/util.h | 15 | ||||
-rw-r--r-- | src/util.c | 65 |
4 files changed, 127 insertions, 0 deletions
diff --git a/src/bf.c b/src/bf.c new file mode 100644 index 0000000..dec7aa3 --- /dev/null +++ b/src/bf.c @@ -0,0 +1,38 @@ +#include "include/util.h" +#include "include/bf.h" + +void bf_run(char* src, FILE* out) { + fprintf(out, "#include <stdio.h>\n"); + fprintf(out, "#include <stdlib.h>\n"); + + fprintf(out, "int main(){\n"); + fprintf(out, "char b[30000];\n"); // create memory buffer + fprintf(out, "char*p=b;\n"); // create pointer + + while (*src != '\0') { + switch (*src) { + case '>': fprintf(out, "p++;\n"); break; // move pointer right + case '<': fprintf(out, "p--;\n"); break; // move pointer left + case '+': fprintf(out, "++*p;\n"); break; // increment cell + case '-': fprintf(out, "--*p;\n"); break; // decrement cell + case '[': fprintf(out, "while(*p){\n"); break; // begin loop + case ']': fprintf(out, "}\n"); break; // end loop + case '.': fprintf(out, "putchar(*p);\n"); break; // print cell + case ',': fprintf(out, "*p=getchar();\n");break; // set cell from stdin + // ignore all other chars + } + src++; + } + + fprintf(out, "exit(0);\nreturn 0;\n}\n"); +} + +int main(int argc, char** argv) { + char* src = (argc - 1)? + util_src_from_fpath(fopen(argv[1], "rb")): + util_src_from_stdin(); + + bf_run(src, stdout); + free(src); + return 0; +} diff --git a/src/include/bf.h b/src/include/bf.h new file mode 100644 index 0000000..611f685 --- /dev/null +++ b/src/include/bf.h @@ -0,0 +1,9 @@ +#ifndef BF_H +#define BF_H + +#include <stdlib.h> +#include <stdio.h> + +void bf_run(char* src, FILE* out); + +#endif diff --git a/src/include/util.h b/src/include/util.h new file mode 100644 index 0000000..4a41ec6 --- /dev/null +++ b/src/include/util.h @@ -0,0 +1,15 @@ +#ifndef UTIL_H +#define UTIL_H + +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +void util_die(const char* fmt, ...); // print msg and exit +void util_log(const char* fmt, ...); // print msg +char* util_get_src(char* arg); // parse argtuments +char* util_src_from_stdin(); // get source from stdin +char* util_src_from_fpath(FILE* f); // get source from file path + +#endif diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..b36558b --- /dev/null +++ b/src/util.c @@ -0,0 +1,65 @@ +#include "include/util.h" + +void util_die(const char* fmt, ...) { + va_list ap; + fprintf(stderr, "[\e[31m==\e[0m] "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +void util_log(const char* fmt, ...) { + va_list ap; + fprintf(stderr, "[\e[36m===\e[0m] "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +char* util_get_src(char* arg) { + if (arg) { + FILE* f = fopen(arg, "rb"); + return util_src_from_fpath(f); + } else { + return util_src_from_stdin(); + } +} + +char* util_src_from_stdin() { + size_t len = 0; + char* src = calloc(len, sizeof(char)); + + while (src[len - 1] != '%') { + char c = getchar(); + src = realloc(src, (len + sizeof(char))); + memcpy(src + len, &c, sizeof(char)); + len += sizeof(char); + } + + src[len - 1] = '\0'; // drop the last '%' char + + return src; +} + +char* util_src_from_fpath(FILE* f) { + if (!f) { + util_die("source file not found"); + } + + fseek(f, 0L, SEEK_END); + long fsize = ftell(f); + rewind(f); + + char* src = calloc(1, fsize + 1); + + if ((fread(src, fsize, 1, f) != 1) || !src) { + fclose(f); + free(src); + util_die("could not read source file"); + } + + return src; +} |