Page 1
ELVMであらゆる言語から
PHPに変換しよう
Let's convert from any language to PHP by ELVM
2018-01-31 PHP勉強会@東京 #phpstudy
公開日:
by USAMI Kenta@tadsan
に東京都渋谷区のGMO Yoursで開催された『第122回 PHP勉強会@東京』でライトニングトーク(5分)として発表しました。
Let's convert from any language to PHP by ELVM
2018-01-31 PHP勉強会@東京 #phpstudy
好きな言語構造はgotoです
宣伝
昨晩書いたまじめ記事(当社比)
今日は話しません
前夜祭で話します
チケット購入しよう
はじめに
Let's convert from any language to PHP by ELVM
2018-01-31 PHP勉強会@東京 #phpstudy
「あらゆる」はオーバー
|←樹海|. ̄.|| ̄ オワタ┗(^o^ )┓三|| ┏┗ 三 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
まあ話を聞いてくれ
計算可能性
コンピュータで解ける問題
チューリングマシン
https://www.google.com/doodles/alan-turings-100th-birthday
チューリングさんが計算の可能性をつきつめたらこうなった
計算機で計算できる函数チャーチ=チューリングのテーゼ
パソコンで計算できる||チューリング機械と同じ
チューリングマシンを使ってチューリングマシンと同等のものを構成できる
万能チューリングマシン
ある計算機言語を使って万能チューリングマシンを構成できるとき、その言語はチューリング完全であると呼ぶ
万能?
ディスクにデータを書き込むとか、現在の時刻を知るとか、TCPパケットを送るとか、そういう魔法のような機械のことは想定してない
簡単な言語
Brainfuck
< > + - . , [ ]言語仕様8命令だけ
トークン意味
<ポインタを1進める
>ポインタを1戻す
+ポインタ位置の値を1加算
-ポインタ位置の値を1減算
.ポインタ位置に値を出力
,1バイト読込ポインタ位置に代入
[ポインタ位置の値が0なら]にジャンプ
]ポインタ位置の値が0でなければ[にジャンプ
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+
++++>-]<.>++++++++[<+++>-]<.++
http://www.kmonos.net/alang/etc/brainfuck.php
(神記事なのでゆっくり読んでほしい)
Brainfuckは言語仕様が非常に小さいので覚えるのは非常に簡単!
言語が簡単
||その言語で書くのが簡単
そんなわけはない
言語の簡単さと人間の読み書きの容易さは一致しない
難解プログラミング言語(Esolang)
Brainfuckのようなへんてこ言語をEsolangと呼ぶ
https://esolangs.org/wiki/Main_Page
(Brainfuckは言語仕様は非常にわかりやすいが、異常に難解なEsolangも当然ある)
話を戻す
Brainfuckはチューリング機械と同等
Brainfuckは万能チューリング機械
Brainfuckはチューリング完全
つまり
Brainfuckを実装できる言語はチューリング完全
PHPはチューリング完全かな?
PHPを使ってBrainfuckを実装してみよう
ELVM
ようやく話がここまできた
https://github.com/shinh/elvm
Shinichiro Hamajiさんが開発したコンパイラ
ELVMバイトコードから任意の言語にコンパイルできる
http://shinh.skr.jp/slide/elvm/009.html
PHPターゲットがなかったので追加しました
https://github.com/shinh/elvm/blob/master/target/php.c
ご存じの通りJavaScriptはPHPにそっくり!!
JavaScriptをPHPっぽく直せばそれだけで動くはず
そう思ってた頃が私にもありました
なぜなのか
JS版実装
static void js_emit_func_prologue(int func_id) {emit_line("");emit_line("var func%d = function() {", func_id);inc_indent();emit_line("while (%d <= pc && pc < %d && running) {",func_id * CHUNKED_FUNC_SIZE, (func_id + 1) *CHUNKED_FUNC_SIZE);inc_indent();
func1, func2のような無名函数が作られる
PHP Notice: Undefined variable: func0 in /Users/megurine/repo/elvm/out/00exit.eir.php on line 39
変数束縛
PHPは明示的に use($var) と書かないとレキシカルスコープを捕捉できない
/(^o^)\
まあ解決策はなくはないけど
いちばん楽だったのは
|\ __ / ピコーン_ (m) _ そうだ、goto|ミ|/ `´ \('A`)ノヽノヽくく
ネストが浅い!
コールスタックが深くならない
goto最高!
私からは異常です
