Mercurial > hg > Papers > 2019 > anatofuz-thesis
view paper/chapter2.tex @ 15:83760be3f57f
add chapter2.tex
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 07 Feb 2019 19:54:30 +0900 |
parents | |
children | 6be34793a3e2 |
line wrap: on
line source
\chapter{Perl6} \section{Perl6の概要} Perl6は現在開発が勧められているプログラミング言語である。 スクリプト言語Perl5の次期バージョンとして当初は開発されていたが、 現在では互換性の無さなどから別言語として開発されている。 Perl6は仕様と実装が分離されており、 現在はテストスイートであるRoastが仕様となっている。 実装は歴史的に様々なものが開発されており、 Haskellで実装されたPugs、 Pythonとの共同実行環境を目指したParrotなどが存在する。 PugsやParrotは現在は歴史的な実装となっており、 開発は行われていない。 現在の主要な実装であるRakudoは、 Parrotと入れ替わる形で実装が進んでいる。 RakudoはParrot時代に考案された、 NQP(NotQuitPerl)を用いてPerl6を実装し、 NQPはVMによって評価される。 RakudoのVMはPerl6専用のVMであるMoarVM、 Java実行環境であるJVM、 Javascriptが選択可能である。 JVM、 Javascriptの動作環境はMoarVMと比較して実装されていない処理などが多数あり、 現在はMoarVMが主流なVMとして利用されている。 MoarVMはC言語で実装されており、 NQPはNQP自身で記述されている。 \section{NQP} NQPとはRakudoにおけるPerl6の実装に利用されているプログラミング言語である。 NQP自体は、 Perl6のサブセットとして開発されている。 基本文法などはPerl6に準拠しているが、 変数を束縛で宣言する。インクリメント演算子が一部利用できない。 Perl6に存在する関数などが一部利用できないなどの制約が存在する。 実際にNQPで記述したコードを に示す。 Perl6はNQPで記述されている為、 Perl6におけるVMはNQPの実行を目標として開発されている。 NQP自体もNQPで記述されており、 NQPのビルドには予め用意されたMoarVMなどのVMバイトコードによるNQPインタプリタが必要となる。 MoarVMを利用する場合、 MoarVMの実行バイナリであるmoarに対して、 ライブラリパスなどを予め用意したNQPインタプリタのバイトコードに設定する。 設定はオプションで与える事が可能であり、 moarを実行することでNQPのインタプリタが起動する。 NQPのビルドには、 このNQPインタプリタをまず利用し、 NQP自体のソースコードを入力して与え、 ターゲットとなるVMのバイトコードを生成する。 このバイトコードはNQPソースコードから生成されたNQPインタプリタのバイトコードであり、 次にこのバイトコードをライブラリとしてmoarに与え、 再びNQPをビルドする。 2度ビルドする事により、 ソースコードからビルドされたNQPバイトコードでNQP自身をビルドする事が出来たため、 処理系自身をその処理系でビルドするセルフビルドが達成出来たことになる。 2度目のビルドの際に生成されたNQPインタプリタの事を小文字のnqpと呼び、これがNQPのインタプリタのコマンドとなる。 \section{Rakudo} RakudoとはNQPによって記述され、 MoarVM、 JVM、 Javascript上で動作するPerl6の実装である。 Rakudo自体はNQPで記述されている箇所と、 Rakudo自身で記述されている箇所が混在する。 ビルド時にはNQPインタプリタが必要となる為、 ソースコードからビルドする際は予めNQPインタプリタであるnqpをビルドする必要が存在する。 図\ref{fig:gotoWithTheEnv}にこの様子を表した。 \begin{lstlisting}[frame=lrbt,label=gotoWithTheEnv,caption={環境付き継続}] __code cs(__code (*ret)(int, void*), void *env){ /* C0 */ goto ret(1, env); } int funcB(){ /* B0 */ goto cs(__return, __environment); /* B1 (never reached). */ return -1; } int funcA(){ /* A0 */ int retval; retval = funcB(); /* A1 */ printf("retval = %d\n", retval); /* retval should not be -1 but be 1. */ return 0; } \end{lstlisting} このように、環境付き継続を用いることで C、CbC 間の処理の移動が可能になる。 %Data Gear はデータの単位であり、int や文字列などの Primitive Type を持っている。 %Code Gear は 任意の数の Input Data Gear を参照して処理を行い、Output Data Gear を出力し処理を終える。 %また、接続された Data Gear 以外には参照を行わない。 %処理やデータの構造が Code Gear、Data Gear に閉じているため、これにより実行時間、メモリ使用量などを予測可能なものにすることが可能になる。