軽量Rubyのコンパイラ・オプション

軽量Rubyコンパイラのオプション-Bの正体を追っかけました。

mrubyのソースコードを読んでみたところ、このオプションはどうやらmrubyプログラムのインタープリタ内部表現を、バイナリ文字列としてC言語の配列で表し出力するようです。大雑把に言うと*.mrbをC言語の文字列配列に変換したモノのだと言えます。

さて、このバイナリをどうやって利用するかと言うと、次のようなコード(C言語)で利用すれば良さそうです。

#include "mruby.h"
#include "irep.h"
#include "mruby/string.h"
#include "mruby/proc.h"
#include "dump.h"

/* mbrc -Bhello hello.rb の出力 */
const char hello[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x39,
0x30,0x30,0x30,0x30,0x4d,0x41,0x54,0x5a,0x20,0x20,0x20,0x20,0x30,0x30,0x30,0x39,
0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x83,0x00,0x01,0x00,0x00,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0xb3,0xd8,0x00,0x00,0x00,0x45,0x53,0x43,0x00,0x02,0x00,0x04,
0x00,0x02,0x6f,0x28,0x00,0x00,0x00,0x05,0x01,0x00,0x00,0x06,0x01,0x80,0x00,0x3d,
0x02,0x00,0x00,0x05,0x01,0x00,0x00,0xa0,0x00,0x00,0x00,0x4a,0xf5,0x07,0x00,0x00,
0x00,0x01,0x0f,0x00,0x0c,0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64,
0x21,0x2b,0xac,0x00,0x00,0x00,0x01,0x00,0x04,0x70,0x75,0x74,0x73,0x24,0x89,0x00,
0x00,0x00,0x00,
};
/* ここまで */

int
main(int argc, char **argv)
{
  mrb_state *mrb = mrb_open();
  int n = -1;

  n = mrb_read_irep(mrb, (char*)hello);
  if (n >= 0) {
    mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value());
  }

  return n;
}

祝! 軽量Rubyが公開

チョット目を離している隙に、軽量Ruby(mruby)が公開された様ですね。
 Rails Hub情報局: ついに軽量Rubyの「mruby」のソースコードが公開!
 軽量Rubyことmrubyのソースコードが公開されました - miyohide's blog


早速、GitHubからスナップショットを拾って来てビルドしてみました。
ビルド環境はCygwinです。make一発でインタプリタ(mruby)、コンパイラ(mrbc)、組込みサンプル(mrubysample)ができるようです。

$ ls -l bin
合計 5952
 -rwxr-xr-x 1 shoz なし 1994838 4月  23 07:22 mrbc.exe
 -rwxr-xr-x 1 shoz なし 2025635 4月  23 07:22 mruby.exe
 -rwxr-xr-x 1 shoz なし 2022095 4月  23 07:22 mrubysample.exe

コンパイラmrbcでは次のオプションが使えます。

ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]
Usage: ./mrbc [switches] programfile
  switches:
  -c           check syntax only
  -o  place the output into 
  -v           print version number, then trun on verbose mode
  -B   binary  output in C language format
  -C     function  output in C language format
  --verbose    run at verbose mode
  --version    print the version
  --copyright  print the copyright

オプション-Cは、RubyのコードをC言語の関数にトランスレートするようです。できたC言語ソースコードをmrubyのライブラリと合わせてコンパイル/リンクすることで、ターゲットのアプリに組み込めるようにしているのでしょう。

puts "hello world!"

このRubyのコードから下のようなC言語ソースコードができます。mrb_open()で得たmrb_state構造体をhello()の引数に渡せば動くようです。

#include "mruby.h"
#include "irep.h"
#include "mruby/string.h"
#include "mruby/proc.h"

static mrb_code iseq_0[] = {
  0x01000006,
  0x0180003d,
  0x02000005,
  0x010000a0,
  0x0000004a,
};

void
hello(mrb_state *mrb)
{
  int n = mrb->irep_len;
  int idx = n;
  mrb_irep *irep;

  mrb_add_irep(mrb, idx+1);

  irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));
  irep->idx = idx++;
  irep->flags = 0 | MRB_ISEQ_NOFREE;
  irep->nlocals = 2;
  irep->nregs = 4;
  irep->ilen = 5;
  irep->iseq = iseq_0;
  irep->slen = 1;
  irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*1);
  irep->syms[0] = mrb_intern(mrb, "puts");
  irep->plen = 1;
  irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*1);
  irep->pool[0] = mrb_str_new(mrb, "hello world!", 12);

  mrb->irep_len = idx;

  extern mrb_value mrb_top_self(mrb_state *mrb);
  mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
}
int
main()
{
  mrb_state *mrb = mrb_open();
  hello(mrb);
  return 0;
}

オプション-Bを指定すると下の様なソースコードが得られます。Riteのバイトコードでしょうか? はっきりしたことは分かりません。

const char hello[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x39,
0x30,0x30,0x30,0x30,0x4d,0x41,0x54,0x5a,0x20,0x20,0x20,0x20,0x30,0x30,0x30,0x39,
0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x83,0x00,0x01,0x00,0x00,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0xb3,0xd8,0x00,0x00,0x00,0x45,0x53,0x43,0x00,0x02,0x00,0x04,
0x00,0x02,0x6f,0x28,0x00,0x00,0x00,0x05,0x01,0x00,0x00,0x06,0x01,0x80,0x00,0x3d,
0x02,0x00,0x00,0x05,0x01,0x00,0x00,0xa0,0x00,0x00,0x00,0x4a,0xf5,0x07,0x00,0x00,
0x00,0x01,0x0f,0x00,0x0c,0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64,
0x21,0x2b,0xac,0x00,0x00,0x00,0x01,0x00,0x04,0x70,0x75,0x74,0x73,0x24,0x89,0x00,
0x00,0x00,0x00,
};

さて、仮想マシンソースコードはsrc/vm.cにあります。中身をちょこっと見たところ、バイトコードの分岐はswich/case文による実装とDirect Threaded codeによる実装の2種類が用意されています‥‥"goto *optable[ほにゃら];"の書き方は gcc拡張機能でしたっけ? デフォールトではDirect Threaded code版になっているようです。

Hello! Python - 3 Interacting with the world

Chapter3まで読みました。このChapterでは、「電池付いてます」‥‥え〜っと標準ライブラリの使い方を学びます。

ライブラリのimportの仕方からモジュールの利用法、ファイルの読み書き、ディレクトリのトレースなどを見て行きます。プログラム課題は、md5を利用したファイル比較ツールの設計・インプリメントです。また、辞書型の使い方も学びます。

例によって、そこかしこにプログラム設計の金言がちらばめられています。たとえば、

You’ll need to avoid the temptation of reinventing the wheel. If a tool has already been written that solves your problem, it’s generally better to use that, or at least include it in your script if possible.

とかね。

P4thを公開しました

大昔に作ったFORTH言語の実装を公開します(ここ)。名付けてP4th(ピコFORTH)です。

ルネサスSH4Aのマイコン・ボードのデバッグモニタに、簡易言語(DSL)として組み込むことを目的に設計したものです。...が、結局使わず我楽多置き場行きになっていました。いわゆるFORTH言語 - 仮想スタックマシンです。超安直かつ非力な実装です。

M4マクロで書かれたThisForthと言う処理系を参考にしましたが、P4thはすべてC/C++で記述しています。ちょっと変わっている点は、Perlスクリプトで辞書用のC/C++ソースコードを生成している辺りでしょうか。マイコン毎の専用組み込みワードのC/C++ソースを用意すれば、それらからPerlスクリプトで手間要らずに辞書のソースを準備できるといったところを狙っています。

おっと、Google Codeにアップしたコードは、Windowsで動きます....大して面白くないですが :-P

クレア・オースチンの芽がすくすくと

先日買ってきたクレア・オースチンですが、新芽が伸びて葉を広げ始めました。
もう少し大きくならないと判りませんが、光沢が少なく柔らかい葉になるのかな? この手の葉は、梅雨時の病気がチョット心配です。

右に伸びている枝は、上の部分には芽が出てこない様なので、短く切ることにしました。先端に近い芽ほど良く伸びる性質 - 頂芽優性 - を狙った剪定ですが、思ったようにいくかどうかはお楽しみです。

甲府も大分暖かくなってきました。近所の大学の桜はほぼ満開です。バラが咲き始めるまで、あとひと月半ぐらいでしょうか。

Hello! Python - 2 Hunt the Wumpus

以前紹介した「Hello! Python」のChapter2を読み終えました。Chapter1はPythonの紹介+インストール手順の様なのでスキップです。

Chapter2では「Hunt the Wumpus」というテキスト・ベースのゲームを題材として作成します*1。変数やループ、関数などPython基本的な機能を学んでいくのですが、それよりもプログラム設計のテクニック、知恵、哲学といったところに力点が置かれた内容になっています。なるほど"something different"です。

「最初は小さく、だんだんとインクリメンタルにプログラムの機能を増やして行きましょう」とか、「プログラムが大きくなってきたら、コードを見直して可読性が悪くならないようにシンプルに書き直しましょう」とか、一人前のプログラマが身に付けているべき知恵を教えています*2。たとえば、Simplifyについてのコラムには次の様なチェックリストが載っています。

❂Use meaningful names for both variables and functions.
❂Use white space to separate different sections of program.
❂Store values in intermediate variables.
❂Break up functions so that they do one thing well.
❂Limit the amount of shared state that functions use, and be clear about what that shared state is.

尤も、本のタイトルから判るようにビギナー向けの本なので、掲載されたコードの解説は詳しくかつ判りやすく書かれています。ビギナーの方も安心して読めます。英語も、私にも読めるぐらいやさしい英語が使われています。

この様な教科書(?)が日本語でもドンドン出てくれば良いのになぁと思う今日このごろです。

*1:そう言えば、Rogueなんてゲームもありましたね。

*2:私の世代だと「ソフトウェア作法」で学んだ事柄ですね。

薔薇クレア・オースチンを買ってきました

単身赴任の仮暮らしだからとずっと我慢していましたが、これだけ陽気が良くなるとやっぱり土をいじりたくなり、我慢できずに薔薇を買ってきました。

ここ山梨では、コマツガーデンさんがバラ専門のナーセリーとして有名(後藤みどりさんのお店)なので、軽自動車を転がし覗きに行きました。お店についてビックリ、ベンツをはじめ高級外車がところ狭しと何台も留まっているではないですか。ちょっと場違いなところに来たかなと思いつつ、バラ苗を物色して回りました。

品揃えはざっと100種ぐらいでしょうか。オールドローズイングリッシュローズ(David Austin)が半々ぐらいで、フレンチローズ(Delbard)はほんの少しといった感じです。これだけの種類があると、次から次へと目移りし、なかなか一鉢が決まりません。この花の形でもう少し花びらが丸いのはないかな、クライミングでなくブッシュの方がコンパクトで良いんだけどな、モスクの香りも良いなと...薔薇は花の形、色、大きさ、香り、樹形、葉の形などなど千差万別なので毎度のことながら迷ってしまいます。尤も、まだ見ぬ花を想像しつつ迷っているこのひと時が薔薇好きにとっては至福のひと時かなとも思います。

いろいろ迷った挙句、イングリッシュローズのクレア・オースチンを選びました。品種ふだの写真によるとカップ咲きの少しクリーム掛かった白バラです。香りは強いミルラ系のようです。ん?! 品種名にオースチンとついていますね。もしやと思いネットで調べてみると、David Austin氏の娘さんの名前のようです。育種家が身内の名前をつけると言うことは余程自身のある品種と言うことでしょうか? 花が咲くのが楽しみです。
バラ苗専門店のコマツガーデン - 13-14 大苗・新苗カタログ イングリッシュローズ2


さて、ベンツetc.の正体ですが、どうやら後藤みどりさんのガーデニング教室が行われていたようで、その教室にセレブな奥様方(?)が詰め掛けていたようです。う〜む、ガーデニングって基本農作業なんだけどな。日焼けはするは、土や薔薇の棘で手や爪は傷だらけになるは、虫を見つけりゃ摘んで殺さなきゃならないはってコトを分かってるんだろうか。まぁ、お店は繁盛している様だったので良しとしますか。


最後に、お店でチョット良さそうなものを見つけました。くるカラです。え〜っと、胡桃の殻です。バークチップとかの代わりに胡桃の殻をマルチングに使うというアイデア...はなまるです。丸っこくて見た目がなんとも面白いです。くるカラ.ネットから直接入手できるようです。
くるカラ.ネット – くるみの殻販売