【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

1.0リリース

独自言語Andromedaのコンパイラver.1.0をリリースしました。

開発当初から自分自身のコンパイル(セルフホスティング)を最初の目標にして、達成した段階で1.0としてリリースすると決めていました。実用性や完成度よりもセルフホスティングを優先したため、バグに気付いてもコーディングで回避できるものは修正を後回しにしています。今後のリリースでバグを潰していく予定です。

特徴

  • コンパイラはAndromeda自身で記述されているため、自分自身をコンパイルできます。
  • 言語の外見はActionScript風です。言語機能は劣化C#です。
  • ライブラリは.NET風ですが、名前空間はありません。.NET準拠は目指しません。.NETの知識で見当が付く程度のものです。
  • 出力するバイナリはWin32(x86)です。将来的にはx86以外にも対応予定です。

使い方

  1. アーカイブをダウンロードすると、コンパイラとソースが入っています。
  2. COMPILER.exeをクリックして実行します。
  3. 自分自身をコンパイルしてadmc.exeを出力します。admc.exeはタイムスタンプ以外はCOMPILER.exeと同一のバイナリです。
  4. サンプルはサブディレクトリの中にtestsという名前で入っています。_build.batをクリックするとサンプルがコンパイルされます。

エクスプローラからの操作を念頭にしているため、コマンドラインアプリケーションでも最後に[Enter]を待って停止する仕様です。

開発動機

なぜコンパイラを作ったか、です。

  • コンパイラが出力するアセンブリを眺めているうちに、出力させてみたくなった。
  • ユーザーと開発者の壁を少しでも低くするため、アプリケーションの配布アーカイブにソースとコンパイラを同梱して、開発環境を構築しなくてもビルドできるようにしたかった。
  • 言語処理系を作るならOS開発も視野に入れたかった。そのためネイティブコンパイラに拘った。
  • ヘッダにプロトタイプを書くのが面倒だったので、前方参照できる言語が欲しかった。

開発を振り返る

開発開始からセルフホスティングまで4年を費やしました(半分くらいは開発停止期間)。転機となった出来事を列挙します。一度諦めた後、ちょっとしたことの積み重ねから、一気にセルフホスティングに突き進みました。

  • id:n7shi:20070108 C#でPEを出力するプログラムを作ってみた。
  • id:n7shi:20070722 XMLでASTを直接記述してコンパイルしてみた。この時点ではパーサを作る気がなかったため、汎用パーサが流用できるXMLを使用した。XML系の一種というノリでLLPMLと称した。
  • id:n7shi:20070926 IEEE 754 単精度浮動小数点数の算出をLLPMLで書いたところ、あまりの冗長さに閉口した。このままではセルフホスティングに到達できないという危機感を抱いた。
  • id:n7shi:20070930 XML中に中置記法の数式を埋め込めるようにした。HTMLでのタグ間のテキストをイメージ。
  • id:n7shi:20080123 関数や構造体をActionScript風の構文で記述できるようにした。関数をfunctionで明示したり、名前の後ろにコロンで区切って型名を記述する構文は、先読みの必要がなくパーサの実装が簡単だったため。この時点では一時しのぎと考えていて、独自言語にまで突っ走ろうとは思っていなかった。
  • id:n7shi:20080915 独自言語要素がどんどん膨張していったのでAndromedaという名前を付けた。この時点ではルート要素は依然としてXMLのままで、外見はHTMLの中に記述するJavaScriptPHPに似ていた。
  • id:n7shi:20080926 FreeBSD上で動かしてみた。当時のコンパイラC#で記述していたため、コンパイルはMonoで実行はWineという変則的な環境で動かしていた。
  • 20081005(日記なし) XMLを廃止。拡張子.admのソースにAndromedaだけを記述するようになった。
  • id:n7shi:20081019 セルフホスティングへの第一歩として、Andromedaだけで作ったプログラムからPEバイナリを出力できるようになった。LLPMLが完全なx86依存だったのを反省して、早い段階からARM対応を取り入れようとした。
  • id:n7shi:20090308 Andromedaだけでコンパイラを書き始めるという意気込みが空回りして、セカンドシステム症候群に陥った。セルフホスティングには到達できないと判断して開発を停止。
  • id:n7shi:20090310 開発を振り返ってスライドを作成。某所で発表するために作成したスライドだったが、イベントが中止になったため未発表。ブログ上のみでの掲載。
  • id:n7shi:20090726 高校生言語開発者として話題になったid:takuto_hさんのCyanとYellowをSilverlight上でホスティング。コードがきれいに書かれていて感激した。
  • id:n7shi:20090727 勢い余ってAndromedaもSilverlight化。Silverlightで言語をホスティングするのも悪くないと思い始める。
  • id:n7shi:20101213 HaskellFFIが思ったより素直だったので、Andromedaで出力したDLLとリンクして遊ぶ。
  • id:n7shi:20101226 C#からF#へのトランスレータSilverlightホスティング。これ自体がトランスレートされた代物だというネタ。言語処理系をSilverlightで動かすという路線を踏襲しつつ、言語変換の有用性に気付く。

適当に作ったC#のパーサでもサポートする構文を制限すれば比較的簡単に変換できたのを見て、AndromedaのコンパイラC#からAndromedaに変換すれば良いと気付きました。年末から正月にかけて、トランスレータを作りながらひたすらAndromedaに変換し続けました。

サポートしていない構文は変換前にC#側で直して、動作が変わらないことを確認後、Andromedaに変換しました。変換だけに冬休みの大半を費やしました。

変換完了後いきなりセルフホスティングを試みましたが、すぐに落ちてあえなく撃沈。テストコードの動作結果を比較しながら地道にバグを見つけては回避(修正ではない)していきました。そしてセルフホスティングができるようにはなりましたが、とんでもなく遅い代物でした。C#の1/100以下。

シンボルのルックアップに使っているHashtableが、名前と違ってハッシュせずにリニアサーチしていたのが原因でした。ハッシュ関数を実装したところ、動作速度はC#の1/3〜1/5くらいまで向上しました。Andromedaのコンパイラは最適化を一切行っていないため、このくらいの速度は想定範囲内でした。そのためセルフホスティング到達と判断しました。

Andromeda用に書いたGUIライブラリやサンプルなどを盛り込んで1.0リリースとしました。

最後に

セカンドシステム症候群をトランスレータで乗り越えるという展開は、当初想定していなかったものでした。振り返ればその方向への流れはあったのですが、直前まで意識することはありませんでした。そのパターンは今後も続きそうな気がします。