From 418543ed8d974b06b71694da5c71059eb45897b5 Mon Sep 17 00:00:00 2001 From: c Date: Sat, 25 Nov 2023 22:52:11 -0500 Subject: Initial commit. --- .gitignore | 2 ++ Makefile | 30 +++++++++++++++++++++++++ README | 9 ++++++++ examples/hello.bf | 1 + src/bf.c | 38 +++++++++++++++++++++++++++++++ src/include/bf.h | 9 ++++++++ src/include/util.h | 15 +++++++++++++ src/util.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 169 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README create mode 100644 examples/hello.bf create mode 100644 src/bf.c create mode 100644 src/include/bf.h create mode 100644 src/include/util.h create mode 100644 src/util.c 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 | 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 \n"); + fprintf(out, "#include \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 +#include + +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 +#include +#include +#include + +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; +} -- cgit v1.2.3