文字列からシンボル取りたい。
文字列からシンボルがほしいときがたまにあります。
たとえば
a = 2; b = 3; assert(u!("a + b = #{a+b}") == "a + b = 5");
みたいな物を作りたいときとか。
というか今日の更新はそんなのを作ろうとして、あまりにめんどくて挫折した残骸だったり
が、そんな機能はDにないので自前で頑張りましょう。
とりあえず適当に("a",a)のようなタプルのリストを予め作ってみました。
当然、用意してない識別子は使用不可(使えねー)
適当にこんな感じに作った。
http://d.shinh.org/html/toy/kurimura/symtable.html
読めばわかると思いますけど超力任せ。これは、ひどい。
こんなん自力で書いてられんので、
スクリプトで自動生成してるからまだマシ?
http://d.shinh.org/html/toy/kurimura/tablegen.html
とりあえず利用例
import symtable; void main(){ void loop(int n){ // シンボルテーブルの作成 mixin SymTable; // nという名前をテーブルから取り出してシンボルを得る if(getId!("n")==0)return; getId!("printf")("%d\n",getId!("n")); getId!("loop")(getId!("n")-1); } loop(10); }
ついでに文字列で計算をさせてみた。
int flag; int main(){ if(flag == 0) flag =1; else return 100; int a = 2,b = 3,c=10; /** Calc型を使ったオブジェクト指向プログラミング */ // Calc型のインスタンス変数dを生成 mixin Calc d; //dに計算をさせてみる。戻り値はr mixin d.calc!("a+b+c+main") r; //rのメンバ変数に結果が入ってるので表示 printf("%d\n",r.result); return 0; } import symtable; template find(char[]s,char c){ static if(s.length == 0)const find = 0; else static if(s[0] == c)const find = 0; else const find = .find!(s[1..s.length],c)+1; } template Calc(){ mixin SymTable; //D言語はカリー化をサポートしています。 alias .calc!(getId) calc; } template calc(alias getId){ template calc(char[]s){ static if(s.length == 0)auto result = 0; else static if(find!(s,'+')==s.length)alias getId!(s) result; else{mixin calc!(s[find!(s,'+')+1..$]) right; auto result = getId!(s[0 .. find!(s,'+')]) + right.result; } } }
...うーん自分で書いててなんだけど、コレはなんの役にも立たなさそ。
色々とDの制限*1を越えるために汚くなってるし。
というか、やっぱ組み込みでシンボルを取る機能ください。Walterたん
*1:典型的なのは関数の中でtemplateを定義できない