0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

楽しい脳コネ

0
Last updated at Posted at 2019-11-18

今回は、ちょっと暇つぶしに作ったブレインファックのインタープリタです。
何番煎じかは知りません。

ブレインファックとは、

ウィキペディアでしか情報を見ていないのでよく知らないですが、命令8個でチューリング完全だそうです。
ショートコーディングのネタになってる言語です。

インタープリタとは、

インタープリタとは、あらかじめ計算してオブジェクトコードにしておくコンパイラと違い、実行時に逐次翻訳して実行するモノです。

難しかったことは、

'['と']'の実装がちゃんと発想がわかないと解けないです。
ほかの命令は簡単ですが、これが動かなければループが使えないので、ここだけはまじめに書きました。
あと、入出力は外部で設定できるようにしてあるので、インタープリタそのものは概ねピュアです。

マルチステート・ウルトラふぁっく

クラスオブジェクトになっているので、複数確保してもその関係は切れています。
では、各各を複数のスレッドに投げて、何かタスクをさせることもできるはずです。
それを生かす何か案はないでしょうか??

免責

デバッグはしていますが、完全ではないことがあります。

追記

コメント欄にmain.cppの改良案が出ています。
ちょっと面白いので暇があれば参照してみると面白いかもです。

コード

Brainfuck.h
# pragma once

# include <vector>
# include <string>
# include <cstdint>

//https://ja.wikipedia.org/wiki/Brainfuck


template<class T>
class BrainFuck {
	typedef std::vector<T> MemoryType;
public:
	bool Initialize(const std::size_t& MemSize, const std::string& Code_) {
		Memory.clear();
		Memory.resize(MemSize);
		Index = 0;
		PC = 0;
		Code = Code_;
		return true;
	}
	bool Interpret() {
		auto I = [](auto& o) {std::cin >> o; };
		auto O = [](auto& o) {std::cout << o; };
		auto E = [](BrainFuck& o) {std::cerr << "out of code :\' " << o.GetCode()[o.CodeIndex()] << "\' at " << o.CodeIndex() << std::endl; };
		return Interpret(O, I, E);
	}
	template <class OF, class IF, class EF>
	bool Interpret(OF Output, IF Input, EF Error) {
		for (PC; PC < Code.size(); PC++) {
			switch (Code[PC]) {
			case '>':
				Index = (Index + 1) % Memory.size();
				break;
			case '<':
				Index = (((Index - 1) + (Memory.size()))) % Memory.size();
				break;
			case '+':
				Memory[Index]++;
				break;
			case '-':
				Memory[Index]--;
				break;
			case '.':
				Output(Memory[Index]);
				break;
			case ',':
				Input(Memory[Index]);
				break;
			case '[':
				if (Memory[Index] == 0) { DoCodeForward(); }
				break;
			case ']':
				if (Memory[Index] != 0) { DoCodeBackward(); }
				break;
			case 'b'://break interpret. //not standard.
				return true;
			case ' ':
				break;
			default:
				Error(*this);
				break;
			}
		}
		return true;
	}
	const std::string& GetCode() const {
		return Code;
	}
	const MemoryType& GetMemory() const {
		return Memory;
	}
	const std::size_t CodeIndex() const {
		return PC;
	}
	const std::size_t ProgramIndex() const {
		return Index;
	}

protected:
	bool DoCodeForward() {
		std::size_t B = 0;
		std::size_t E = 0;
		std::size_t i = 0;
		for (i = PC; i < Code.size(); i++) {
			if (Code[i] == '[')B++;
			if (Code[i] == ']')E++;
			if (B == E) break;
		}
		PC = i;
		return B == E;
	}

	bool DoCodeBackward() {
		std::size_t B = 0;
		std::size_t E = 0;
		std::intmax_t i = 0;
		for (i = PC; i >= 0; i--) {
			if (Code[i] == '[')B++;
			if (Code[i] == ']')E++;
			if (B == E) break;
		}
		if (i >= 0) { PC = i; }
		return B == E;
	}

protected:
	std::string Code;
	std::size_t PC = 0;
	MemoryType Memory;
	std::size_t Index = 0;
};
main.cpp
# include <iostream>
# include "BrainFuck.h"

//http://hakugetu.so.land.to/program/brainfuck/1-4.php

int main() {
	BrainFuck<char> BF;
	//BrainFuck<int> BF;

	std::string Hello = "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++. > -.------------.<++++++++.--------.++ + .------.--------.>+.";
	std::string FuzzBuzz = "++++++[->++++ >> +> +> -<<<< < ] > [<++++ >> ++ + > ++++ >> ++ + > ++++ + > ++++ + >>>>>>++ >> ++ <<<<<<<<<<<<< < -]<++++>++ + > -- > ++ + > -> > --->++ >> > ++++ + [->++ > ++ << ]<<<<<<<<<<[->- [>>>>>> > ] > [<++ + >. > .>>>>.. >> > +< ]<<<<<-[>>>>]>[<++++ + >. > . > .. >> > +< ]>>>>+<-[<< < ]< [[-<< +>> ]>> > +> +<<<<<<[-> > +> +> -<<<<] < ] >> [[-]< ] > [>> > [> . << . << < ]<[.<<<<]>] > .<<<<<<<<<< < ]";
	std::string Prime = ">++++[<++++++++>-]>++++++++[<++++++>-]<++.<.> +.<.> ++.<.> ++.<.> ------..<.> .++.<.> --.++++++.<.> ------. > ++ + [<++ + >-] < -.<.> ------ - . + .<.> -.++++++ + .<.>------.--.<.> ++.++++.<.> -- - .-- - .<.> ++ + . - .<.> +.++ + .<.> --.--.<.> ++.++++.<.>-- - .---- - .<.> ++++ + . + .<.> .------.<.> ++++++.----.<.> ++++.++.<.> -.---- - .<.> ++++ + . + .<.> .--.";
	std::string S1 = "++++[>++++[>++++<-]<-]>>.";//64?
	std::string S2 = "++[>+<-]>.";//basic test.

	auto I = [](auto& o) {std::cin >> o; };
	auto O = [](auto& o) {std::cout << o; };
	auto E = [](auto& o) {std::cerr << "out of code :\' " << o.GetCode()[o.CodeIndex()] << "\' at " << o.CodeIndex() << std::endl; };

	//BF.Initialize(256, S1);
	//BF.Initialize(16, Hello);
	//BF.Initialize(256, FuzzBuzz);
	BF.Initialize(256, Prime);
	//BF.Interpret();
	BF.Interpret(O,I,E);
	return 0;
}
0
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?