2005年10月 6日

D言語のGCCフロントエンド

D言語GCCフロントエンド (GDC) があると知ったので試してみました。

 

インストール

Debian パッケージにはまだなっていないようなので、GDC 0.15 を GCC 3.4.4 とともにソースからビルドしてインストールしました。自分では試していませんが、 cygwin の場合は GDC はパッケージ化されていて簡単にインストールできるそうです。

% wget ftp://ftp.ring.gr.jp/pub/GNU/gcc/gcc-3.4.4/gcc-3.4.4.tar.bz2
% tar jxf gcc-3.4.4.tar.bz2
% cd gcc-3.4.4/gcc
% wget http://home.earthlink.net/~dvdfrdmn/d/gdc-0.15.tar.bz2
% tar jxf gdc-0.15.tar.bz2
% cd ..
% gcc/d/setup-gcc.sh
% mkdir build
% cd build
% ../configure --enable-languages=c,d,c++ --prefix=/usr/local/gcc-3.4
% make
% sudo make install

hello, world

次に hello, world をコンパイルして実行しました。

% cat hello.d
import std.cstream;
int main(char[][] args)
{
    dout.writeLine("hello, world");
    return 0;
}

% /usr/local/gcc-3.4/bin/gdc -o hello hello.d
% ./hello
hello, world

デマングリング (demangling)

hello のサイズは 520KB ほどになりました。 nm a.out を実行すると何やらたくさんシンボルが含まれています。 「_D3std6stream10ishexdigitFaZb」といったシンボル名は c++filt ではデマングリングできないので別の規則に従っているようです。

調べてみると dfilt.d というそれらしいものが見つかりました。そのままではコンパイルが通らなかったので、少々修正してコンパイルしてから nm hello | ./dfilt と実行すると、さきほどのシンボル名は bit std.stream.ishexdigit(char) と復元されました。

日本語の情報源

D言語についての日本語の情報は充実しています。D言語はとりわけゲーム開発によく使われているようです。

dfilt.d へのパッチ

このパッチは本家に 取り込んでもらえたので、もはや不要です。

% diff -u dfilt.d.orig dfilt.d |escapehtml
--- dfilt.d.orig        2004-09-12 19:06:11.000000000 +0900
+++ dfilt.d     2005-10-07 00:42:51.000000000 +0900
@@ -1,4 +1,4 @@
-private import std.stream;
+private import std.cstream;
 private import std.regexp;
 private import std.string;
 private import std.ctype;
@@ -39,13 +39,13 @@
         char[] all = "";
         try {
             int c;
-            while ((c = ins.getc()) != -1) {
+            while ((c = ins.getc()) != char.init) {
                 all ~= cast(char)c;
             }
         }
         catch (Error e) {}

-        char[][] lines = all.split("\n");
+        char[][] lines = std.string.split(all, "\n");
         foreach (char[] line; lines) {
             for (int i = 0; i < line.length-1; i++) {
                 if (line[i..i+2] == `_D` && (i == 0 || !issym(line[i-1]))) {
@@ -88,7 +88,7 @@
             }
             else {
                 // @@@ is it ok?
-                int sep = rfind(now, "_");
+                int sep = std.string.rfind(now, "_");
                 if (sep > 0) {
                     try {
                         int dummy = 0;
@@ -280,7 +280,7 @@
 else {
     int main(char[][] args) {
         Demangle d = new Demangle();
-        d.run(std.stream.stdin, std.stream.stdout);
+        d.run(din, dout);

         return 0;
     }