toge's diary

コンピュータ関連の趣味をつらつらと。

C++でxtalのIteratorを定義する

http://code.google.com/p/xtal-language/

まあこれだけ使い勝手のよい言語を世の中が放っておくはずもなく、どんどん有名になっていくわけで、嬉しい限りです。
さて、ちっとはxtalを使おうとしているところを見せようと思うのです。

お題は、id:xtalco:20070518 で紹介されている「(xtalで)オリジナルのIteratorを定義する」というもの。ならばC++側からIteratorを定義してしまえということで、やってみました。

#include "xtal/xtal.h"

class IterTest : public xtal::AnyImpl {
  int value_;
public:
  IterTest(int value) : value_(value) {
    set_class(xtal::TClass<IterTest>::get());
  }

  void iter_next(const xtal::VMachine& vm) {
    if (value_ > 10) {
      vm.return_result(xtal::Null());
      return;
    }
    vm.return_result(this, xtal::Any(value_));
    ++value_;
  }
};

int main() {
  // Xtalの初期化
  xtal::initialize();

  try {
    xtal::TClass<IterTest> itertest("IterTest"); // IterTest クラスを構築

    itertest.inherit(xtal::Iterator());
    itertest.def("new", xtal::New<IterTest, int>().param(xtal::Named("value", 0)));
    itertest.method("iter_first", &IterTest::iter_next);
    itertest.method("iter_next", &IterTest::iter_next);

    xtal::lib().def("IterTest", itertest);

    xtal::Any ret = xtal::lib().member("iterator");
  }
  catch(xtal::Any ex) {
    std::cout << ex << std::endl;
  }
  return 0;
}

で、xtalスクリプト側はこんな感じ

test : lib::IterTest(5); 
test{it.p;};

実行するとこうなります。

5
6
7
8
9
10

たぶん、AnyImplを継承するところと、コンストラクタでset_classするのがポイントっぽい。
なんにせよこれで野望の第1歩です。