Perl6の内部表現
|
Takahiro Shimizu
|
このセッションの内容
- Perl6の主要な実装であるRakudoの内部構造を探ります
- Rakudoの内部で利用されているVMや, Perl6のサブセットなどについて探索します
- スクリプト言語で主に使われているバイトコードインタプリタの気持ちになります
Perl6とは
- 当初Perl5の時期バージョンとして開発されていたプログラミング言語
- 仕様と実装が分離しており, 現在はテストが仕様となっている
- 実装は複数存在しているが,現在主流な実装はRakudoとなっている
- 言語的にはスクリプト言語であり, 漸進的型付き言語となっている
- MoarVM, JVMで動作する
Perl6のソースコード概要
- Perl5の文法とは比較的変更が多い
- 変数がオブジェクトと化した事により, 変数からsayメソッドを呼ぶことが可能
my $str_value = 'hello world!';
$str_value.say; # hello world!
- Perl5と同様に,変数にはデフォルトでは型がないような振る舞いをする
my $sample_value = 'hello world!';
$sample_value.say; # hello world!
$sample_value = '31';
$sample_value.say; # 31
say($sample_value * 3);
Perl6の言語的な特徴
- 漸進的型付き言語である為, 型を強制することも可能となる
my Int $int_value = 31;
$int_value = "hello"; # Compile error!
$ perl6 type_invalid.p6
Type check failed in assignment to $int_value; expected Int but got Str ("hello")
in block <unit> at type_invalid.p6 line 4
Perl6の言語的な特徴
- 型を独自に定義することも可能
- 入力の型によって実行する関数を変える事などができる
my subset Fizz of Int where * %% 3;
my subset Buzz of Int where * %% 5;
my subset FizzBuzz of Int where Fizz&Buzz;
my subset Number of Int where none Fizz|Buzz;
proto sub fizzbuzz ($) { * }
multi sub fizzbuzz (FizzBuzz) { "FuzzBuzz" }
multi sub fizzbuzz (Fizz) { "Fizz" }
multi sub fizzbuzz (Buzz) { "Buzz" }
multi sub fizzbuzz (Number $number) { $number }
fizzbuzz($_).say for 1..15;
スクリプト言語処理系
- スクリプト言語は入力として与えられたソースコードを、 直接評価せずにバイトコードにコンパイルする形式が主流となっている
- その為スクリプト言語の実装は大きく2つで構成されている
- バイトコードに変換するフロントエンド部分
- バイトコードを解釈する仮想機械
Perl6の処理系の構成
- Perl6の処理系は現在はRakudoと呼ばれる(歴史上複数存在する)
- Rakudoは3つのレイヤーから構成されている
- Perl6インタプリタ
- Perl6インタプリタを記述するPerl6のサブセットNQP
- Perl6のバイトコードを解釈するMoarVM
- このうちPerl6インタプリタとNQPはNQP自身で記述されている
- MoarVMはC言語で記述されている
Perl6とNQP
- NQP(NotQuitPerl Perlっぽい別の言語)でRakudoを記述している
- NQPもNQPで記述されている為、 セルフビルド(自分自身で自分自身をコンパイルする)を行う
- NQPはPerl6の文法をベースにしているが、 制約がいくつか存在する
#! nqp
sub fib($n) {
$n < 2 ?? $n !! fib($n-1) + fib($n - 2);
}
my $N := 29;
my $t0 := nqp::time_n();
my $z := fib($N);
my $t1 := nqp::time_n();
nqp::say("fib($N) = " ~ fib($N));
nqp::say("time = " ~ ($t1-$t0));
プログラミング言語とVM
- 最近のスクリプト言語は、 ソースコードを直接解釈せず、バイトコードに変換しVMが評価する
- 全体的な処理速度の向上の為
- 実装を分離することでの見通しの良さ
- 言語処理系の実行にのみ動作するVM(プロセスVM)
- 他言語の環境
Perl6のVMの構成
- MoarVMと呼ばれるVM
- C言語で記述されている
- レジスタマシン
- 型情報を持つレジスタに対しての演算として処理される
- LuaJITなどを利用したJITコンパイルなども可能
- Perl6やNQPは、MoarVMに対してライブラリなどを設定して起動する
バイトコード
- Perl6も、Rakudo/NQPはバイトコードに変換され、 バイトコードをVMが実行する
- バイトコード実行部分は、 命令に対応するバイト列を読み込み、 解釈し、 次の命令を読み取ることを繰り返す