(69) Small Basic → VB に変換してみた
解析、というほど大げさな話でもないんですが。
Small Basic には「発行」機能が付いていまして、ボタンクリック一発で smallbasic.com に自分の作ったプログラムを登録・公開できるわけです。
公開されたプログラムは smallbasic.com の Web ページで実際に使ってみたりソースを読んだりできるんですが、本気でそのソースを読み解きたいなら、IDE にインポート (取り込む) という手もあるんですね。
てことで、ものはためし。
本気で読み解くつもりで、全エントリでご紹介した SOkoCute のソースを自分の手元の Small Basic IDE に取り込んでみることにします。
操作は簡単。
IDE の画面上部、「インポート」をクリックして、表示されたダイアログに取り込みたいプログラムのプログラム ID を入力してやればいいだけです。
SOkoCute のプログラム ID は、「soko」です。
で、[OK] ボタンをクリックすると、SOkoCute のソースコードが読み込まれるわけですね。
…って、1161 行もあるではありませんか。
正直、Small Basic IDE のエディタ機能は、あまりたいしたものではありません。
テキストエディタにインテリセンスが生えた程度のモノですので、数十行くらいのコードならともかく、これだけの量のロジックをたどっていくにはちょっとキビシいものがあります。
不要にキビシいのは嫌なので、ソースのトレースはVB でやることにしました。Visual Studio IDE は、かなりトレースやデバッグがしやすいです。CodeRush なんかが追加されていれば、もー最強です。
ということで、今度は画面上部の「VB に変換」 (これは私の環境オリジナルの用語です。インストールデフォルトでは「等級をつける」と表示されています。) をクリックします。
「VB に変換」 (これも私の環境オリジナル。デフォルトでは「VB に転送」と「VB に変換」がごっちゃに表示されます) ダイアログが表示されます。
VB への変換を行うと、できあがったソースやコンパイルされたプログラムがファイルとして保存されます。ので、このダイアログで保存先のフォルダを指定してやる必要があります。
VB を使っている方はお分かりかと思いますが、VB ソースのデフォルトの保存先は (ユーザーフォルダ)\Documents\Visual Studio 2008\Projects です。今回も、素直にここに SOkoCute 用のフォルダを作って、保存してもらうことにしました。
[次へ] ボタンをクリックしてしばらく待つと、Visual Studio IDE が起動され、できあがったソリューションが表示されます。これで変換終了です。
ソリューション名・プロジェクト名ともに Untitled 、プロジェクトの中の標準モジュール名も UntitledModule となっていますが、ソースそのものは SOkoCute の VB 変換版になっています。
さてこの VB 変換版、そのままでは動きません。エラーだらけだったりします。
もっとも多いエラーは、
エラー79 「Expression は値であるため、代入式のターゲットにすることはできません。」
という奴です。
これは、変数が宣言には単変数なのに、実際には配列変数として使われていることを指摘したエラーです。
Small Basic では変数は宣言なしにいきなり使えるんですが、VB では基本的にあらかじめ宣言しないと変数を使うことはできません。
で、Small Basic の変数は、ひとつの名前の変数を単変数として使うもよし、配列として使うもよし、プログラムの途中で添字の次元数を変えたり、いきなり単変数として使ってもいいようになっているんですが、VBではそんなふらふらした使い方はできません。
つまり、「VBに変換」機能は、Small Basic → VB に変換するときに元ソースで使っている変数をあぶり出して宣言しとかなきゃならないんですが、「配列かどうか」や「次元数」まではあぶり出しきれないんです。
ので、変換ソースで自動生成された変数の宣言文は、すべて単変数としての宣言になっています。
で、プログラム中で配列として使っているところが全部エラーになるわけです。
しかたがないので、ここは手で 1 個 1 個、エラー箇所で使われている配列変数を探して、その変数の宣言文を次元数を合わせた配列に書き直していきます。
ただし、VB では 配列の宣言時には要素数も合わせて記述する必要がある ということに気をつけてください。
つまり、
Dim block … block(0)(0) = " "
という変換ソースがあった場合、これを
Dim block(9)(15) … block(0)(0) = " "
という形には直せません。
エラー1 「配列の配列を初期化する場合、トップレベル配列に対してのみ境界を指定できます。」
となってしまいます。ここは、
Dim block(9, 15) … block(0, 0) = " "
と直さなきゃなりません。宣言部だけではなく、実際にその変数を使っているところのすべての添字も直さなきゃいけません。
あと、ひとつの変数を単変数で使っていたり配列として使っていたりする場合には、
エラー1 「型 ‘String’ の値を ‘Microsoft.SmallBasic.Library.Primitive の 1 次元配列の 1 次元配列’ に変換できません。」
のようなエラーも出てきます。
これは、使っている変数の次元に応じて、変数を振り分けてやることになります。
つまり、
Dim block As Primitive … block = "blockArray" … block(0, 0) = " "
のような使われ方をしている場合は、
Dim block0 As Primitive Dim block(9, 15) As Primitive … block0 = "blockArray" … block(0, 0) = " "
という感じの修正を行っていくわけです。
他にもいろんなエラーが出てきそうな感じですが、とりあえず SOkoCute は上記の修正で動作するようになりましたよ。
で、ですね。
VB への変換機能がなんでついているのかなー、というのが、私にはちょっと不思議なんですよ。
VB の文法に置き換わる、というよりは、Small Basic のライブラリを読み込んで、Small Basic の命令を VB の中で実行させているような作りですので、動作速度も Small Basic と変わりません。
Small Basic の文法だけわかればVB の勉強をしなくても、Small Basicなしの単体で配布できるプログラムが作れるよー、ということなんでしょうか。
(SmallBasicLibrary.dll やリソースファイルの同梱の必要性は置いておいて。)
もしそうだとすると、変換ソースに手を加えなければならない現状では、あまり目的を達せていないような気がします。
このへんは、今後のバージョンアップに期待、というところなのかもしれません。
逆に、ちょっと邪道気味ではありますが。
今回のお話のように、人様が作った Small Basic プログラムの研究をするのなら、VB に変換してからロジックを追っかけた方が絶対便利です。
まあそんなことができる方は、現時点ですでに VB をわかっている方なんだと思いますけれども。

考えてみれば、もともと Small Basic は実行と同時に EXE が作成され、かつランタイムや拡張機能 DLL などが EXEと同じフォルダに自動的にコピーされる仕様だったのでした。
フォルダごと渡してしまえば別に Small Basic IDE は実行に必要ないんですよね。
ので、本文での私の推察は事実誤認に基づいており、開発者がそこを目指しているとは考えにくいです。
一方で、Small Basic の文法をそのまま VB で実現しようとしているために、VB のソースとしてはかなり不自然な形になります。ので、「Small Basic を足がかりに VB を学び始めるツール」としてもあまりいい手法だとは思えません。
どう考えても、メリットが思いつきません。なんだろう、ほんとに。