はじめに 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

Choices Vote
大変参考になった7  
参考になった0  
あまり参考にならなかった0  
まったく参考にならなかった0  

No comment. コメント​/Articles​/D言語でマクロのようなものEdit

Name:

Front page   Edit Freeze Diff Backup Upload Copy Rename ReloadPrint View   New Page Page list Search Recent changes   Help   RSS of recent changes (RSS 1.0) RSS of recent changes (RSS 2.0) RSS of recent changes (RSS Atom) Powered by xpWiki
Counter: 2735, today: 1, yesterday: 1
Princeps date: 2012-03-27 (Tue) 21:43:29
Last-modified: 2012-03-27 (Tue) 21:43:29 (JST) (3166d) by ゲスト
メインメニュー

ログイン

ユーザー名:


パスワード:





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

Menu