はじめに anchor.png Edit

少し前にツイッターで「D言語にはマクロが無い!!」ということが話題になり、さらにCTFE使えばライブラリ的に実現可能と聞いたので、実際に可能かどうか検証してみました。

CTFEに関しては、SampleCodes​/D言語文法​/コンパイル時実行関連​/1を参照してください。

Page Top

方法 anchor.png Edit

方針としては、

  1. ソースを文字列リテラルとして書く。
  2. preprocess関数でプリプロセスする。
  3. 戻ってきた文字列をmixinする。

こんな感じです。簡単ですね。

Page Top

preprocess関数を書く anchor.png Edit

実装は以下のようになりました。

Everything is expanded.Everything is shortened.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
-
-
-
|
!
!
|
!
 
-
|
-
|
-
|
|
-
|
!
|
-
|
!
!
-
|
!
|
!
import std.array;
size_t indexOf(string src, char ch){
    foreach(i, c; src){
        if(c == ch){
            return i;
        }
    }
    return -1;
}
 
string preprocess(string src){
    string[string] macros;
    while(true){
        auto start = indexOf(src, '#');
        if(start != -1){
            auto end = start + indexOf(src[start..$], '\n');
            auto strs = src[start..end].split();
            if(strs[0] == "#define"){
                macros[strs[1]] = strs[2];
            }
            src = src[0..start] ~ src[end..$];
        }else{
            break;
        }
    }
    foreach(str; macros.keys){
        src = src.replace(str, macros[str]);
    }
    return src;
}

std.string.indexOfは残念ながらCTFEableではなかったのでindexOfを自前で実装しました。

上の実装は引数なし#defineにしか対応してなかったり、色々と穴があったりしますが、マクロが可能かどうか検証できればいいのでまあ大丈夫でしょう。

Page Top

実際に試してみる anchor.png Edit

上のpreprocess関数を使って動くかどうか試してみます。

とりあえず以下のようなソースでやってみましょう。

Everything is expanded.Everything is shortened.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 
 
 
 
 
 
 
 
 
 
 
 
mixin(preprocess(q"src
 
import std.stdio;
#define VOID void
#define MAIN main
#define INT int
 
VOID MAIN(){
    writeln(q{MAIN});
}
 
src"));
Page Top

実行結果 anchor.png Edit

1
main

うまく動いているように見えます。

Page Top

結論 anchor.png Edit

D言語でマクロっぽいことはライブラリ的に可能です。言語仕様にはマクロは無いですけどね。

今回は引数なし#defineにしか対応してない貧弱なpreprocess関数を使ったせいで出来ることが限定されてましたが、

頑張れば#ifdefなどに対応することも理論上できるはずです。ただし#includeを除く。

Page Top

展望 anchor.png Edit

上のような方法を取れば、例えばXMLをCTFEで処理してmixinという風なこともできます。

D言語が書きたくない人はXMLで書いてみるといいんじゃないでしょうか。

さらにimport式を使えば、外部ファイルをコンパイル時に読み込むことができるので、

全くD言語でないプログラミング言語で書かれたファイルをdmdにコンパイルさせることが理論上できます。

実は、すでにbrainf*ckはdmdでコンパイルできたりします。

D言語すごいねー

Page Top

投票とコメント anchor.png Edit

選択肢 投票
大変参考になった7  
参考になった0  
あまり参考にならなかった0  
まったく参考にならなかった0  

コメントはありません。 コメント​/Articles​/D言語でマクロのようなもの編集

お名前:

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 1619, today: 1, yesterday: 0
初版日時: 2012-03-27 (火) 21:43:29
最終更新: 2012-03-27 (火) 21:43:29 (JST) (1919d) by ゲスト
メインメニュー

ログイン

ユーザー名:


パスワード:





パスワード紛失  |新規登録

Menu