From 87b7bddd71740f255ce4257659aa69038408d329 Mon Sep 17 00:00:00 2001 From: olari Date: Sat, 25 May 2019 19:06:58 +0300 Subject: [PATCH] Add brainfuck.cpp --- cpp/brainfuck/Makefile | 2 + cpp/brainfuck/brainfuck.cpp | 87 +++++++++++++++++++++++++++++++++++++ cpp/brainfuck/cat.bf | 1 + cpp/brainfuck/helloworld.bf | 1 + 4 files changed, 91 insertions(+) create mode 100644 cpp/brainfuck/Makefile create mode 100644 cpp/brainfuck/brainfuck.cpp create mode 100644 cpp/brainfuck/cat.bf create mode 100644 cpp/brainfuck/helloworld.bf diff --git a/cpp/brainfuck/Makefile b/cpp/brainfuck/Makefile new file mode 100644 index 0000000..37345b0 --- /dev/null +++ b/cpp/brainfuck/Makefile @@ -0,0 +1,2 @@ +all: + g++ -std=c++17 -O2 brainfuck.cpp -lstdc++fs -o brainfuck diff --git a/cpp/brainfuck/brainfuck.cpp b/cpp/brainfuck/brainfuck.cpp new file mode 100644 index 0000000..2215d79 --- /dev/null +++ b/cpp/brainfuck/brainfuck.cpp @@ -0,0 +1,87 @@ +#include + +#include +#include +#include + +#include +#include + +#include + +std::string get_file_contents(std::ifstream& file_stream) { + std::string file_string; + + file_stream.seekg(0, std::ios::end); + file_string.resize(file_stream.tellg()); + file_stream.seekg(0, std::ios::beg); + + file_stream.read(&file_string[0], file_string.size()); + + return file_string; +} + +std::string get_brainfuck_code(const std::string& file) { + std::string code; + + for (auto c : file) { + switch (c) { + case '>': case '<': + case '+': case '-': + case '.': case ',': + case '[': case ']': + code.push_back(c); + } + } + + return code; +} + +template +struct bf_context_t { + std::array cells; + std::stack scope; + std::uintptr_t ptr; +}; + +int main(int argc, char* argv[]) { + if (argc < 2) { + std::cout << "Usage: " << argv[0] << std::endl; + return 1; + } + + const std::string file_path = argv[1]; + + if (!std::filesystem::exists(file_path)) { + std::cout << "Could not find file." << std::endl; + return 1; + } + + std::ifstream file_stream(file_path); + + if (!file_stream) { + std::cout << "Could not open file." << std::endl; + return 1; + } + + const std::string file_contents = get_file_contents(file_stream); + const std::string bf_code = get_brainfuck_code(file_contents); + + // by default, std::cin skips whitespace + std::cin >> std::noskipws; + + auto ctx = bf_context_t{}; + + for (auto ip = 0; ip < bf_code.length(); ++ip) { + switch (bf_code[ip]) { + case '>': ++ctx.ptr; break; + case '<': --ctx.ptr; break; + case '+': ++ctx.cells[ctx.ptr]; break; + case '-': --ctx.cells[ctx.ptr]; break; + case '.': std::cout << (char)ctx.cells[ctx.ptr]; break; + case ',': std::cin >> ctx.cells[ctx.ptr]; break; + case '[': ctx.scope.push(ip); break; + case ']': if (ctx.cells[ctx.ptr]) ip = ctx.scope.top() - 1; ctx.scope.pop(); break; + } + } +} diff --git a/cpp/brainfuck/cat.bf b/cpp/brainfuck/cat.bf new file mode 100644 index 0000000..58e93e5 --- /dev/null +++ b/cpp/brainfuck/cat.bf @@ -0,0 +1 @@ +,[.[-],] diff --git a/cpp/brainfuck/helloworld.bf b/cpp/brainfuck/helloworld.bf new file mode 100644 index 0000000..8fa0f72 --- /dev/null +++ b/cpp/brainfuck/helloworld.bf @@ -0,0 +1 @@ +++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.