8
5

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.

Brainfuck派生言語を簡単に作成するPHPライブラリをつくった

Posted at

なぜつくったのか

r-fxxkという、Brainfuck派生言語を簡単に作成するためのRubyライブラリがあります。たとえば、プログラミング言語フレンズ Kemonoは以下のような非常に簡単なコードで実装されています。

class Kemono < Brainfuck
  nxt "たのしー!"
  inc "たーのしー!"
  prv "すごーい!"
  dec "すっごーい!"
  opn "うわー!"
  cls "わーい!"
  put "なにこれなにこれ!"
  get "おもしろーい!"
end

PHPにも似たようなのが無いかなー、と思って探してみましたが、見つからなかったので作りました。コードはGitHubで公開しています。

つかいかた

インストール:

composer require ryo-utsunomiya/php-fxxk

Kemonoを実装してみます。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use BrainFuck\Mapping;
use BrainFuck\Language;

// Kemono の定義
$kemono = new Mapping([
    'たのしー!',
    'たーのしー!',
    'すごーい!',
    'すっごーい!',
    'うわー!',
    'わーい!',
    'なにこれなにこれ!',
    'おもしろーい!',
]);

// 「Hello World!」を出力するプログラムを生成
$program = $kemono->helloWorld();
echo $program . PHP_EOL;

// マッピングを使用してプログラム実行
$output = Language::withMapping($kemono)->run($program);

// プログラムの実行結果はintの配列になるので、
// intをasciiの値とみなして文字列として出力
foreach ($output as $char) {
    echo chr($char);
}

ちなみに、KemonoでHello World!を出力するプログラムは以下。

すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!なにこれなにこれ!たのしー!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!たのしー!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!たのしー!すごーい!すごーい!すごーい!たのしー!すごーい!たーのしー!たーのしー!たーのしー!たーのしー!すっごーい!おもしろーい!たのしー!すごーい!すごーい!うわー!たのしー!すごーい!うわー!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!うわー!うわー!すごーい!すごーい!すごーい!うわー!たのしー!すごーい!すごーい!うわー!たーのしー!たーのしー!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!すごーい!うわー!たのしー!うわー!すごーい!すごーい!すごーい!うわー!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!うわー!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!すっごーい!うわー!たのしー!すごーい!うわー!たのしー!うわー!

Mappingを継承したクラスを作ってもOKです。

<?php

namespace KemonoFriends;

use BrainFuck\Mapping;

class Kemono extends Mapping
{
    protected $mapping = [
        'たのしー!',
        'たーのしー!',
        'すごーい!',
        'すっごーい!',
        'うわー!',
        'わーい!',
        'なにこれなにこれ!',
        'おもしろーい!',
    ];
}

設計のポイント

BF系言語を翻訳して本家Brainfuckに変換し、Brainfuckインタープリタが変換後のコードを実行する、というのがこのライブラリのアーキテクチャです。

このライブラリにおいてキモになるのは、BF系言語 => Brainfuckの変換部分で、ここはMappingというクラスが担っています。

PHPで実装されたBrainfuckのインタープリタはいくつかありますが、ircmaxell/PHP-BrainFuckを使っています。クラスがきれいに分割されていて、拡張しやすそうだったので採用しました。

まなんだこと

当初は、スクラッチでBrainfuckインタープリタを作ろうとしてたのですが、意外と大変でした。特にループが難しく、プログラム中からループの内部だけを正規表現で抜き出そうとすると、コードのトークンが2文字程度でもバックトラック制限に引っかかります。

そこでr-fxxk等の実装を眺めてみたところ、インタープリタの部分はBrainfuckのままで、変換部分で工夫している、ということが分かったので、同じように実装しました。

あと、Packagistにライブラリを公開するのは初めてだったんですが、ソースがGitHubにあってcomposer.jsonに必要な情報が書いてあれば、簡単に公開できるということがわかりました。

8
5
0

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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?