aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile30
-rw-r--r--README9
-rw-r--r--examples/hello.bf1
-rw-r--r--src/bf.c38
-rw-r--r--src/include/bf.h9
-rw-r--r--src/include/util.h15
-rw-r--r--src/util.c65
8 files changed, 169 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..17fbe89
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+*.out
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ec33c3c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,30 @@
+name := bf
+cc := cc
+flags := -g
+sources := $(wildcard src/*.c)
+sources := $(filter-out src/parser.c, $(sources)) # exclude the incomplete parser for now.
+objects := $(sources:.c=.o)
+
+$(name): $(objects)
+ $(cc) $(objects) $(flags) -o ./$(name).out
+
+%.o: %.c include/%.h
+ $(cc) -c $(flags) $< -o $@
+
+install:
+ make
+ cp ./$(name).out /usr/local/bin/$(name)
+
+uninstall:
+ rm -f /usr/local/bin/$(name)
+
+clean:
+ rm -f ./$(name).out ./src/*.o
+
+me:
+ @[ "$(USER)" = "root" ] && echo "Okay." || echo "What? Make it yourself."
+
+a sandwich:
+ @exit
+
+.PHONY: install uninstall clean me a sandwich
diff --git a/README b/README
new file mode 100644
index 0000000..c7925b0
--- /dev/null
+++ b/README
@@ -0,0 +1,9 @@
+USAGE
+=====
+
+ $ bf <file> | gcc -x c -
+
+Example:
+
+ $ bf examples/hello.bf | gcc -o hello.out -x c -
+
diff --git a/examples/hello.bf b/examples/hello.bf
new file mode 100644
index 0000000..8fa0f72
--- /dev/null
+++ b/examples/hello.bf
@@ -0,0 +1 @@
+++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
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;
+}