OSDN Git Service

parser_testを再作成。
authorderui <derutakayu@user.sourceforge.jp>
Sun, 14 Feb 2010 14:18:30 +0000 (23:18 +0900)
committerderui <derutakayu@user.sourceforge.jp>
Sun, 14 Feb 2010 14:18:30 +0000 (23:18 +0900)
datum syntaxを表現するためのdatum.*を一部作成。

15 files changed:
Rakefile
Rakefile.in
lib/binary_tree.h
src/datum_id.h [deleted file]
src/object.h [deleted file]
src/parser/datum.cpp [new file with mode: 0644]
src/parser/datum.h [new file with mode: 0755]
src/parser/datum_base.cpp [new file with mode: 0644]
src/parser/datum_base.h [new file with mode: 0755]
src/parser/syntax_tree.cpp [deleted file]
src/parser/syntax_tree.h [deleted file]
test/binary_tree_test.cpp
test/datum_test.cpp
test/parser_test.cpp [new file with mode: 0755]
test/parser_test.cpp.bk [deleted file]

index 139fb01..e403d94 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -14,11 +14,12 @@ includes = " "
 includes += "-I. -I."
 
 # lists of compile dependency objects
-SRCS = FileList["./src/**/*.cpp", "./lib/**/*.cpp"]
-SRCS_ALL = FileList[SRCS, "./src/**/*.h", "./lib/**/*.h"]
+TOP_DIR = File.expand_path "."
+SRCS = FileList[File.join(TOP_DIR, "src/**/*.cpp"), File.join(TOP_DIR, "lib/**/*.cpp")]
+SRCS_ALL = FileList[SRCS, File.join(TOP_DIR, "src/**/*.h"), File.join(TOP_DIR, "lib/**/*.h")]
 OBJS = SRCS.ext("o")
 DEPS = SRCS.ext("mf")
-TEST_SRCS = FileList["./test/*.cpp"]
+TEST_SRCS = FileList[File.join(TOP_DIR, "test/*.cpp")]
 TEST_OBJECTS = TEST_SRCS.ext("o")
 TEST_OBJECTS.include(OBJS)
 TEST_DEPS = TEST_SRCS.ext("mf")
@@ -30,38 +31,38 @@ EXEEXT = ""
 CLEAN.include(OBJS, TEST_OBJECTS, DEPS)
 CLOBBER.include(TEST_PROGRAMS)
 
-task "default" => ["depend_resolution", "compile"]
-task "test" => ["depend_resolution", "compile", "test_execute"]
-
-task "depend_resolution" => DEPS do |t|
-  t.prerequisites.each { |f|
-    import f.source
-  }
-end
+task "default" => ["compile"]
+task "test" => ["compile", "test_execute"]
 
 desc "Compile all sources "
 task "compile" => OBJS do |t|
 end
 
+DEPS.each { |f|
+  depname = File.split(f)
+  depname[1] = File.basename(depname[1], ".mf") + ".cpp"
+  desc "make #{f} dependencies"
+  file "#{f}" => [File.join(depname)]
+}
+
+DEPS.each { |f| import f}
+
 rule "_test#{EXEEXT}" => TEST_OBJECTS do |t|
-  fullpath = File.expand_path t.name
   base = File.split(t.name);
   base[1] = File.basename(base[1], EXEEXT) + ".o"
   sh "#{CC} -o #{File.expand_path(t.name)} #{ldflags} #{cflags} #{includes} #{OBJS.join(' ')} ./test/gtest/gtest-all.o #{File.join(base)} "
 end
 
 rule '.o' => '.cpp' do |t|
-  fullpath = File.expand_path t.source
   depname = File.split(t.source)
   depname[1] = File.basename(depname[1], ".cpp") + ".mf"
-  sh "#{CC} #{ldflags} #{cflags} #{includes} -c #{fullpath} -o #{t.name}"
+  sh "#{CC} #{ldflags} #{cflags} #{includes} -c #{t.source} -o #{t.name}"
 end
 
 rule '.mf' => '.cpp' do |t|
-  fullpath = File.expand_path t.source
   depname = File.split(t.source)
   depname[1] = File.basename(depname[1], ".cpp") + ".mf"
-  sh "#{CC} -MM -MF #{File.join(depname[0], depname[1])} #{ldflags} #{cflags} #{includes} #{fullpath}"
+  sh "#{CC} -MM -MF #{File.join(depname[0], depname[1])} #{ldflags} #{cflags} #{includes} #{t.source}"
   import File.join(depname[0], depname[1])
 end
 
index 8207ce3..eca693d 100644 (file)
@@ -14,11 +14,12 @@ includes = " "
 includes += "-I. -I@top_srcdir@"
 
 # lists of compile dependency objects
-SRCS = FileList["@top_srcdir@/src/**/*.cpp", "@top_srcdir@/lib/**/*.cpp"]
-SRCS_ALL = FileList[SRCS, "@top_srcdir@/src/**/*.h", "@top_srcdir@/lib/**/*.h"]
+TOP_DIR = File.expand_path "@top_srcdir@"
+SRCS = FileList[File.join(TOP_DIR, "src/**/*.cpp"), File.join(TOP_DIR, "lib/**/*.cpp")]
+SRCS_ALL = FileList[SRCS, File.join(TOP_DIR, "src/**/*.h"), File.join(TOP_DIR, "lib/**/*.h")]
 OBJS = SRCS.ext("o")
 DEPS = SRCS.ext("mf")
-TEST_SRCS = FileList["@top_srcdir@/test/*.cpp"]
+TEST_SRCS = FileList[File.join(TOP_DIR, "test/*.cpp")]
 TEST_OBJECTS = TEST_SRCS.ext("o")
 TEST_OBJECTS.include(OBJS)
 TEST_DEPS = TEST_SRCS.ext("mf")
@@ -30,38 +31,38 @@ EXEEXT = "@EXEEXT@"
 CLEAN.include(OBJS, TEST_OBJECTS, DEPS)
 CLOBBER.include(TEST_PROGRAMS)
 
-task "default" => ["depend_resolution", "compile"]
-task "test" => ["depend_resolution", "compile", "test_execute"]
-
-task "depend_resolution" => DEPS do |t|
-  t.prerequisites.each { |f|
-    import f.source
-  }
-end
+task "default" => ["compile"]
+task "test" => ["compile", "test_execute"]
 
 desc "Compile all sources "
 task "compile" => OBJS do |t|
 end
 
+DEPS.each { |f|
+  depname = File.split(f)
+  depname[1] = File.basename(depname[1], ".mf") + ".cpp"
+  desc "make #{f} dependencies"
+  file "#{f}" => [File.join(depname)]
+}
+
+DEPS.each { |f| import f}
+
 rule "_test#{EXEEXT}" => TEST_OBJECTS do |t|
-  fullpath = File.expand_path t.name
   base = File.split(t.name);
   base[1] = File.basename(base[1], EXEEXT) + ".o"
   sh "#{CC} -o #{File.expand_path(t.name)} #{ldflags} #{cflags} #{includes} #{OBJS.join(' ')} ./test/gtest/gtest-all.o #{File.join(base)} "
 end
 
 rule '.o' => '.cpp' do |t|
-  fullpath = File.expand_path t.source
   depname = File.split(t.source)
   depname[1] = File.basename(depname[1], ".cpp") + ".mf"
-  sh "#{CC} #{ldflags} #{cflags} #{includes} -c #{fullpath} -o #{t.name}"
+  sh "#{CC} #{ldflags} #{cflags} #{includes} -c #{t.source} -o #{t.name}"
 end
 
 rule '.mf' => '.cpp' do |t|
-  fullpath = File.expand_path t.source
   depname = File.split(t.source)
   depname[1] = File.basename(depname[1], ".cpp") + ".mf"
-  sh "#{CC} -MM -MF #{File.join(depname[0], depname[1])} #{ldflags} #{cflags} #{includes} #{fullpath}"
+  sh "#{CC} -MM -MF #{File.join(depname[0], depname[1])} #{ldflags} #{cflags} #{includes} #{t.source}"
   import File.join(depname[0], depname[1])
 end
 
index 835560c..fa7d7fb 100755 (executable)
 #ifndef _UTAKATA_LIB_BINARY_TREE_H_
 #define _UTAKATA_LIB_BINARY_TREE_H_
 
+namespace akebono {
+namespace binary_tree_detail {
 
+// 内部でleafなどとして扱われるnode構造体です。この構造体公開はされますが、
+// 実際にアクセスすることはできません。
+template <typename T>
+struct node {
+  node() : parent_(NULL), left_(NULL), right_(NULL), 
+           next_sibling_(NULL), prev_sibling_(NULL), data_() {}
+  node(const T& data) : parent_(NULL), left_(NULL), right_(NULL),
+                        next_sibling_(NULL), prev_sibling_(NULL),
+                        data_(data) {}
+  node<T>* parent_;
+  node<T>* left_;
+  node<T>* right_;
+  // 同じ親に接続されている前後のnodeを指します。
+  // ただし、二分木の場合、左ノードの場合はnext_sibling_に右ノードが、
+  // 右ノードの場合はpref_sibling_に左ノードが設定され、
+  // それぞれprev/nextはNULLが設定されます。
+  node<T>* next_sibling_;
+  node<T>* prev_sibling_;
+
+  T data_;
+};
+
+
+// 渡されたT型のポインタから、次に進むべきデータを判別するための
+// traverserです。
+// pre_orderは、根・左部分木・右部分木の順にtreeへのアクセスを行います。
+// 渡された段階で、すでに根にアクセスされているため、この場合は
+// 左、右、親の順にチェックを行います。
+// また、一つ前にアクセスしたデータを記憶しており、一つ前にアクセスした
+// データが、渡されたデータのどの位置に該当するのかをチェックし、
+// 次を観測します。
+template <typename T>
+struct pre_order {
+  // 渡されたtargetに対して、次のデータに行くかどうかをチェックします。
+  // left、rightの両方が存在しない場合、parent_のnext_siblingが存在するか
+  // どうかを再帰的にチェックします。
+  bool has_next(const node<T>* target) const {
+    const node<T>* now_target = target;
+
+    if (!now_target) {
+      return false;
+    }
+
+    if (target->left_ || target->right_) {
+      return true;
+    }
+
+    while (now_target->next_sibling_ == NULL) {
+      if (!now_target->parent_) {
+        return false;
+      }
+      now_target = now_target->parent_;
+    }
+    return true;
+  }
+
+  // 渡されたtargetから、次に進むべきデータを返します。
+  // has_nextがfalseを返却する場合、NULLが返却されます。
+  node<T>* next(node<T>* target) {
+    if (target->left_) {
+      return target->left_;
+    } else if (target->right_) {
+      return target->right_;
+    }
+
+    node<T>* now_target = target;
+    while (now_target->next_sibling_ == NULL) {
+      now_target = now_target->parent_;
+      if (now_target == NULL) {
+        return now_target;
+      }
+    }
+    return now_target->next_sibling_;
+  }
+};
+
+} // end of namespace binary_tree
+
+// 汎用的な二分木テンプレートを提供します。
+// テンプレート引数は、第一引数が利用する型、第二引数が、二分木の
+// 探索方法を設定します。
+// 二分木の探索方法は、in_order、pre_order、post_orderが用意されて
+// います。
+// デフォルトで用意されている探索方法については、すべてakebono::binary_tree_detail
+// に用意されています。
+// 内部ノードへのアクセスは可能ですが、get_*、has_*による間接的アクセスが
+// 推奨されます。
+template <typename T,
+          template<typename S> class Traverse =
+          akebono::binary_tree_detail::pre_order>
+class binary_tree {
+ public:
+
+  // 内部のnodeを利用し、また渡されたtraverserに基づいて、nodeの探索を行います。
+  struct iterator {
+
+    // コピーコンストラクタ、及びデフォルトコンストラクタです。
+    iterator() : node_(NULL), traverser_() {}
+    iterator(const iterator& it) : node_(it.node_),
+                                   traverser_(it.traverser_) {}
+    explicit iterator(binary_tree_detail::node<T>* convert) : node_(convert), traverser_() {}
+
+    ~iterator() {}
+
+    // 渡されたiteratorとの比較を行います。内部で保持しているnode_が
+    // 同一位置を指していることが条件となります。
+    bool operator==(const iterator& it) const {return node_ == it.node_;}
+    bool operator!=(const iterator& it) const {return !(*this == it);}
+
+    // 現在指しているnode内のデータへアクセスします。
+    // node内部ではTとしてのみ保持しているため、変則的にしています。
+    const T& operator*() const {return node_->data_;}
+    const T* operator->() const {return &(node_->data_);}
+    T& operator*() {return node_->data_;}
+    T* operator->() {return &(node_->data_);}
+
+    // 現在指しているnode_を次の要素を指すように変更します。この際、
+    // Traverseで指定されたTraverserを利用します。
+    // Traverse::has_nextは、渡されたnode_のアクセスを行うかどうかを
+    // 表し、Traverse::nextは、次にアクセスすべきnode_を返します。
+    iterator& operator++() {
+      node_ = traverser_.next(node_);
+      return *this;
+    }
+
+    iterator operator++(int) {
+      iterator tmp(*this);
+      node_ = traverser_.next(node_);
+      return tmp;
+    }
+
+    // 各データを格納しているnodeです。node内では、単純にデータを保持
+    // しているため、取得したポインタを操作することは許可されません。
+    binary_tree_detail::node<T>* node_;
+
+    // operator++によって、二分木の探索を行うためのtraverserです。
+    Traverse<T> traverser_;
+  };
+
+  // 番兵として機能するend_を設定します。
+  binary_tree() : root_(new binary_tree_detail::node<T>()),
+                  end_(new binary_tree_detail::node<T>()) {
+    root_->parent_ = NULL;
+    root_->left_   = NULL;
+    root_->right_  = NULL;
+    root_->next_sibling_ = end_;
+    root_->prev_sibling_ = NULL;
+
+    end_->parent_ = NULL;
+    end_->left_ = NULL;
+    end_->right_ = NULL;
+    end_->prev_sibling_ = root_;
+    end_->next_sibling_ = NULL;
+  }
+
+  virtual ~binary_tree() {
+    if (root_) {delete root_;}
+    if (end_) {delete end_;}
+  }
+
+  // rootを指すiteratorを作成して返します。
+  iterator begin() {
+    return iterator(root_);
+  }
+
+  // end_を指すiteratorを返却します。
+  iterator end() {
+    return iterator(end_);
+  }
+
+  // 渡されたiteratorの左側に新規に葉を作成し、dataを設定します。
+  // 正常に終了した場合、新規に作成された葉を指すiteratorが
+  // 返されます。
+  // 正常に終了しなかった場合、end()で返されるiteratorと同一のiteratorが返されます。
+  iterator set_left(const iterator& target,
+                    const T& data) {
+    if (target == end()) {
+      return end();
+    }
+
+    binary_tree_detail::node<T>* target_node = target.node_;
+    target_node->left_ = new binary_tree_detail::node<T>(data);
+
+    target_node->left_->parent_ = target_node;
+    target_node->left_->next_sibling_ = target_node->right_;
+
+    if (target_node->right_) {
+      target_node->right_->prev_sibling_ = target_node->left_;
+    }
+    iterator ret(target_node->left_);
+    return ret;
+  }
+
+  // 渡されたiteratorの右側に新規に葉を作成し、dataを設定します。
+  // 正常に終了した場合、新規に作成された葉を指すiteratorが
+  // 返されます。
+  iterator set_right(const iterator& target,
+                     const T& data) {
+    if (target == end()) {
+      return end();
+    }
+
+    binary_tree_detail::node<T>* target_node = target.node_;
+    target_node->right_ = new binary_tree_detail::node<T>(data);
+
+    target_node->right_->parent_ = target_node;
+    target_node->right_->prev_sibling_ = target_node->left_;
+
+    if (target_node->left_) {
+      target_node->left_->next_sibling_ = target_node->right_;
+    }
+    iterator ret(target_node->right_);
+    return ret;
+  }
+
+ private:
+
+  // 二分木のルートとして設定されます。デフォルトではend_を指しています。
+  // root_がend_を指している場合、binary_tree::empty()がtrueを返します。
+  binary_tree_detail::node<T>* root_;
+
+  // 常に二分木の末尾として設定されます。ここでの二分木の末尾とは、
+  // 探索を行う型によって変動します。
+  binary_tree_detail::node<T>* end_;
+};
+} // end of namespace akebono
 
 #endif /* _UTAKATA_LIB_BINARY_TREE_H_ */
diff --git a/src/datum_id.h b/src/datum_id.h
deleted file mode 100755 (executable)
index 17f53dd..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _DATUM_ID_H_
-#define _DATUM_ID_H_
-
-// datumで示される構文データの各ID
-
-#include <string>
-
-namespace utakata {
-
-namespace syntax {
-
-class DatumID {
- public:
-  enum private_DATUMID_ {
-    STRING        = 0,                  // <string>
-    ABBREVIATIONS = 1,                  // 各abbrev prefix
-    SYMBOL        = 2,                  // <symbol>
-    NUMBER        = 3,                  // <number>
-    CHARACTOR     = 4,                  // <charactor>
-    BOOLEAN       = 5,                  // <boolean>
-    BYTEVECTOR    = 6,                  // <bytevector>
-    VECTOR        = 7,                  // <vector>
-    LIST          = 8,                  // <list>
-    LITERAL       = 9,                  // <lexeme datum>
-    NIL           = 10,
-  };
-
- private:
-
-  typedef private_DATUMID_ DATUMID_;
-  DATUMID_ S_;
-
-  template<DATUMID_> class Literal;
-
- public:
-
-  template<DATUMID_ S>
-  explicit DatumID(const Literal<S>&) : S_(S) {}
-
-  DATUMID_ toEnum() const {return S_;}
-
-  friend bool operator==(DatumID s, DatumID t) {return s.S_ == t.S_;}
-  friend bool operator!=(DatumID s, DatumID t) {return !(s == t);}
-
-  static const Literal<STRING>           string;
-  static const Literal<ABBREVIATIONS>    abbreviations;
-  static const Literal<SYMBOL>           symbol;
-  static const Literal<NUMBER>           number;
-  static const Literal<CHARACTOR>        charactor;
-  static const Literal<BOOLEAN>          boolean;
-  static const Literal<BYTEVECTOR>       byteVector;
-  static const Literal<VECTOR>           vector;
-  static const Literal<LIST>             list;
-  static const Literal<LITERAL>       literal;
-  static const Literal<NIL>              nil;
-};
-
-// 内部クラスかつ、単に該当するEnumを返すだけのクラステンプレート
-template<DatumID::private_DATUMID_ S>
-class DatumID::Literal : private DatumID {
- public:
-
-  DatumID::private_DATUMID_ toEnum() const {return S;}
-
- private:
-
-  friend class DatumID;
-  // 暗黙的なコピーコンストラクタを利用する。
-  Literal() : DatumID(*this) {}
-  ~Literal() {}
-
-  void* operator new(size_t size);
-  void operator delete(void* pointer);
-  void operator=(const Literal& literal);
-  void* operator&() const;
-};
-};
-};
-
-#endif /* _DATUM_ID_H_ */
diff --git a/src/object.h b/src/object.h
deleted file mode 100755 (executable)
index aa8f313..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-// Base Object-interface of utakata
-//
-// Scheme中の全ての実体オブジェクト(数値、文字列、リスト、配列...)の
-// 基底となるインターフェースの定義。
-// Scheme中で表われる全てのオブジェクトはこのインターフェースを継承
-// し、実装しなければなりません。
-//
-// example
-// -------
-// class Hoge : public IObject {
-//  public:
-//   Hoge();
-//   ~Hoge() {}
-//   std::string ToString() const {return "hoge";}
-// };
-
-#ifndef _DEVELOP_UTAKATA_SRC_OBJECT_H_
-#define _DEVELOP_UTAKATA_SRC_OBJECT_H_
-
-#include <vector>
-#include "lib/uncopyable.h"
-
-namespace utakata {
-
-namespace unicode {
-class UniString;
-class UniChar;
-}
-
-namespace interpreter {
-
-class Environment;
-class IObject : private akebono::uncopyable {
-  // scheme中の実体オブジェクトのベースとなる基底クラスです。
-  // scheme中の全ての実体オブジェクトは、この基底クラスを定義する
-  // 必要があります。
-  // これらの基底クラスは、デフォルトで存在する全てのオブジェクトに対して
-  // Compositeであり、各オブジェクトについて不正である処理については
-  // exception::NotImplementedException例外がthrowされます。
-  // IObject経由で生成されたオブジェクトは、GCに強制的に登録され、
-  // GC経由で削除が行われます。
-  //
-  // IObjectはSchemeにおけるオブジェクトの内部表現として取り扱われます。
-  // Schemeオブジェクトの定義として、原則的にコピーは行われないため、
-  // operator=及びコピーコンストラクタは提供されません。
-  // (akebono::uncopyableインターフェースにおいて無効化されています)
- public:
-  IObject() {}
-  virtual ~IObject() {}
-
-  // オブジェクトのコピーを生成して返します。
-  virtual IObject* Clone() const = 0;
-
-  // このオブジェクトの文字列表現を返します。
-  // 返した文字列表現は、外部によって展開されます。
-  virtual unicode::UniString* ToString() const = 0;
-
-  // オブジェクトを評価します。オブジェクトの評価時には、現在の
-  // 環境が渡されます。Evalの結果として、任意のオブジェクトを返却します。
-  virtual IObject* Eval(interpreter::Environment* env) = 0;
-
-  /// consオブジェクトに対するインターフェースです。
-
-  // Consのcar部に設定されているIObjectを返します。
-  virtual IObject* GetCar();
-
-  // Consのcdr部に設定されているIObjectを返します。
-  virtual IObject* GetCdr();
-
-  // Consのcar部にオブジェクトを設定します。
-  virtual void SetCar(IObject* car);
-
-  // Consのcdr部にオブジェクトを設定します。
-  virtual void SetCdr(IObject* cdr);
-
-  /// Booleanオブジェクトに対するインターフェースです。
-
-  // 内部のboolean値を取得します。
-  virtual bool GetBoolean() const;
-
-  // 内部のboolean値を設定します。
-  virtual void SetBoolean(bool b);
-
-  /// Symbolオブジェクトに対するインターフェースです。
-
-  // シンボル名を取得します。
-  virtual const unicode::UniString& GetSymbolName() const;
-
-  // バインドされているオブジェクトを取得します。
-  virtual IObject* GetBindObject();
-
-  // シンボルへオブジェクトをバインドします。
-  virtual void SetBindObject(const IObject* object);
-
-  /// Stringオブジェクトに対するインターフェースです。
-
-  // 設定されている文字列を取得します。
-  virtual const unicode::UniString& GetString() const;
-
-  /// Numberオブジェクトに対するインターフェースです。
-
-  // 設定されているNumericオブジェクトを取得します。
-  virtual int GetNumber() const;
-
-  // Numericオブジェクトを設定します。
-  virtual void SetNumber(int num);
-
-  /// Charactorオブジェクトに対するインターフェースです。
-
-  // 設定されている文字を取得します。
-  virtual const unicode::UniChar& GetCharactor() const;
-
-  /// Vectorオブジェクトに対するインターフェースです。
-
-  // 配列への参照を取得します。
-  virtual std::vector<IObject*>& GetVector();
-
-  /// Bytevectorオブジェクトに対するインターフェースです。
-
-  // ByteVectorへの参照を取得します。
-  virtual std::vector<IObject*>& GetBytevector();
-};
-};
-};
-
-#endif /* _DEVELOP_UTAKATA_SRC_OBJECT_H_ */
diff --git a/src/parser/datum.cpp b/src/parser/datum.cpp
new file mode 100644 (file)
index 0000000..0080d7c
--- /dev/null
@@ -0,0 +1,97 @@
+#include "src/exception_macro.h"
+#include "src/exception_std.h"
+#include "src/parser/datum.h"
+#include "src/unicode.h"
+
+namespace datum = utakata::datum;
+namespace unicode = utakata::unicode;
+namespace exception = utakata::exception;
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetCar(datum::IDatumBase* car) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetCar`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetCdr(datum::IDatumBase* cdr) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetCdr`"));
+}
+
+// 宣言のコメントを参照して下さい。
+bool datum::IDatumBase::GetBoolean() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBoolean`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBoolean(bool b) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBoolean`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniString& datum::IDatumBase::GetSymbolName() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetSymbolName`"));
+}
+
+// 宣言のコメントを参照して下さい。
+datum::IDatumBase* datum::IDatumBase::GetBindObject() {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBindObject`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBindObject(const datum::IDatumBase* object) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBindObject`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniString& datum::IDatumBase::GetString() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetString`"));
+}
+
+// 宣言のコメントを参照して下さい。
+int datum::IDatumBase::GetNumber() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetNumber`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetNumber(int number) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetNumber`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniChar& datum::IDatumBase::GetCharactor() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetCharactor`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetVector() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetVector`"));
+}
+
+void datum::IDatumBase::SetVector(const std::vector<datum::IDatumBase*>& vector) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetVector`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetBytevector() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBytevector`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBytevector(const std::vector<datum::IDatumBase*>& vector) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBytevector`"));
+}
diff --git a/src/parser/datum.h b/src/parser/datum.h
new file mode 100755 (executable)
index 0000000..beeec4d
--- /dev/null
@@ -0,0 +1,111 @@
+// Schemeにおけるdatum analyticsの結果として得られる構文木の内部として保持される
+// オブジェクトです。
+// datumの種類は確定しているため、全てのインターフェースは統一されます。
+// datumは、環境を元にEvalすることで、それぞれのインターフェース毎に
+// 異なった結果を返却します。
+#ifndef _UTAKATA_SRC_PARSER_DATUM_H_
+#define _UTAKATA_SRC_PARSER_DATUM_H_
+
+#include "src/parser/datum_base.h"
+
+namespace utakata {
+
+namespace unicode {
+class UniString;
+class UniChar;
+}
+
+namespace datum {
+
+class Environment;
+
+// datumにおける<string>を表現するためのクラスです。
+// 単純に文字列のみを保持し、それを返します。datumはcopyされないことが
+// 前提となっているため、文字列本体は内部においてscoped_ptrで保持され
+// ます。
+class String : public IDatumBase {
+ public:
+  explicit String(const unicode::UniString& string)
+      : string_(new unicode::UniString(string)) {}
+  virtual ~String() {}
+
+  // このオブジェクトの文字列表現を返します。
+  // 返した文字列表現は、外部によって展開されます。
+  virtual const unicode::UniString& ToString() const;
+
+  // オブジェクトを評価します。オブジェクトの評価時には、現在の
+  // 環境が渡されます。Evalの結果として、任意のオブジェクトを返却します。
+  virtual IDatumBase* Eval(interpreter::Environment* env);
+
+  // 設定されている文字列を取得します。
+  virtual const unicode::UniString& GetString() const;
+
+  virtual datum::DatumType type() const {return datum::kString;}
+
+ private:
+
+  // 内部で保持される文字列です。オリジナルも同一となります。
+  scoped_ptr<unicode::UniString> string_;
+};
+
+// datum syntaxにおける<symbol>を表現するためのクラスです。
+// stringと同じく、symbolを構成する文字列のみを保持します。
+class Symbol : public IDatumBase {
+ public:
+  explicit Symbol(const unicode::UniString& symbol)
+      : symbol_(new unicode::UniString& string) {}
+  virtual ~Symbol() {}
+
+  // このオブジェクトの文字列表現を返します。
+  // 返した文字列表現は、外部によって展開されます。
+  virtual const unicode::UniString& ToString() const;
+
+  // オブジェクトを評価します。オブジェクトの評価時には、現在の
+  // 環境が渡されます。Evalの結果として、任意のオブジェクトを返却します。
+  virtual IDatumBase* Eval(interpreter::Environment* env);
+
+  // シンボル名を返します。ToStringと同一値を返します。
+  virtual const unicode::UniString& GetSymbolName() const;
+
+  virtual datum::DatumType type() const {return datum::kSymbol;}
+
+ private:
+
+  // 内部で保持される文字列です。オリジナルも同一となります。
+  akebono::scoped_ptr<unicode::UniString> symbol_;
+};
+
+class Charactor : public IDatumBase {
+ public:
+  explicit Charactor(const unicode::UniString& charactor_name,
+                     const unicode::UniChar& charactor)
+      : charactor_(new unicode::UniChar(charactor)),
+        charactor_name_(new unicode::UniString(charactor_name)) {}
+  virtual ~Charactor() {}
+
+  // このオブジェクトの文字列表現を返します。
+  // 返した文字列表現は、外部によって展開されます。
+  virtual const unicode::UniString& ToString() const;
+
+  // オブジェクトを評価します。オブジェクトの評価時には、現在の
+  // 環境が渡されます。Evalの結果として、任意のオブジェクトを返却します。
+  virtual IDatumBase* Eval(interpreter::Environment* env);
+
+  // 現在保持しているcharactor_を返却します。
+  virtual const unicode::UniChar& GetCharactor() const;
+
+  virtual datum::DatumType type() const {return datum::kCharactor;}
+
+ private:
+
+  // 実際に内部で保持する文字コードです。
+  akebono::scoped_ptr<unicode::UniChar> charactor_;
+
+  // 評価前の文字列です。ToStringで返されます。
+  akebono::scoped_ptr<unicode::UniString> charactor_name_;
+};
+
+};
+};
+
+#endif /* _UTAKATA_SRC_PARSER_DATUM_H_ */
diff --git a/src/parser/datum_base.cpp b/src/parser/datum_base.cpp
new file mode 100644 (file)
index 0000000..0080d7c
--- /dev/null
@@ -0,0 +1,97 @@
+#include "src/exception_macro.h"
+#include "src/exception_std.h"
+#include "src/parser/datum.h"
+#include "src/unicode.h"
+
+namespace datum = utakata::datum;
+namespace unicode = utakata::unicode;
+namespace exception = utakata::exception;
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetCar(datum::IDatumBase* car) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetCar`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetCdr(datum::IDatumBase* cdr) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetCdr`"));
+}
+
+// 宣言のコメントを参照して下さい。
+bool datum::IDatumBase::GetBoolean() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBoolean`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBoolean(bool b) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBoolean`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniString& datum::IDatumBase::GetSymbolName() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetSymbolName`"));
+}
+
+// 宣言のコメントを参照して下さい。
+datum::IDatumBase* datum::IDatumBase::GetBindObject() {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBindObject`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBindObject(const datum::IDatumBase* object) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBindObject`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniString& datum::IDatumBase::GetString() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetString`"));
+}
+
+// 宣言のコメントを参照して下さい。
+int datum::IDatumBase::GetNumber() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetNumber`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetNumber(int number) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetNumber`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const unicode::UniChar& datum::IDatumBase::GetCharactor() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetCharactor`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetVector() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetVector`"));
+}
+
+void datum::IDatumBase::SetVector(const std::vector<datum::IDatumBase*>& vector) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetVector`"));
+}
+
+// 宣言のコメントを参照して下さい。
+const std::vector<datum::IDatumBase*>& datum::IDatumBase::GetBytevector() const {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `GetBytevector`"));
+}
+
+// 宣言のコメントを参照して下さい。
+void datum::IDatumBase::SetBytevector(const std::vector<datum::IDatumBase*>& vector) {
+  THROW_EXCEPTION_(exception::NotImplementedException,
+                   unicode::Convert("Not implemented `SetBytevector`"));
+}
diff --git a/src/parser/datum_base.h b/src/parser/datum_base.h
new file mode 100755 (executable)
index 0000000..0a5bfd1
--- /dev/null
@@ -0,0 +1,110 @@
+// Schemeにおけるdatum analyticsの結果として得られる構文木の内部として保持される
+// オブジェクトです。
+// datumの種類は確定しているため、全てのインターフェースは統一されます。
+// datumは、環境を元にEvalすることで、それぞれのインターフェース毎に
+// 異なった結果を返却します。
+#ifndef _UTAKATA_SRC_PARSER_DATUM_BASE_H_
+#define _UTAKATA_SRC_PARSER_DATUM_BASE_H_
+
+#include <vector>
+#include "lib/uncopyable.h"
+
+namespace utakata {
+
+namespace unicode {
+class UniString;
+class UniChar;
+}
+
+namespace datum {
+
+// IDatumBaseが実装するDatumを表現します。
+// ただし、元々のdatumと1:1で対応するものではなく、listはkConsの集合体、
+// abbrev prefixはkSymbolへの置き換えが行われています。
+enum DatumType {
+  kString = 0,
+  kSymbol,
+  kCons,
+  kVector,
+  kByteVector,
+  kNumber,
+  kCharactor,
+  kBoolean,
+}
+
+class Environment;
+
+// <datum>を表現するためのクラスです。このクラスにおいては、すべてのdatum
+// を表現するに十分なインターフェースを提供します。
+// それぞれのdatumに不要なインターフェースについては、標準で
+// datum::NotImplementException例外が発生されるようになっています。
+// また、datumはデータ構造をそのまま表現するため、コピーは不可能となっています。
+// compound datumの内、listについては、consのみで表現され、データは実際には
+// 保持しません。
+class IDatumBase : private akebono::uncopyable {
+ public:
+  IDatumBase() {}
+  virtual ~IDatumBase() {}
+
+  // このオブジェクトの文字列表現を返します。
+  // 返した文字列表現は、外部によって展開されます。
+  virtual const unicode::UniString& ToString() const = 0;
+
+  // オブジェクトを評価します。オブジェクトの評価時には、現在の
+  // 環境が渡されます。Evalの結果として、任意のオブジェクトを返却します。
+  virtual IDatumBase* Eval(interpreter::Environment* env) = 0;
+
+  /// Booleanオブジェクトに対するインターフェースです。
+
+  // 内部のboolean値を取得します。
+  virtual bool GetBoolean() const;
+
+  // 内部のboolean値を設定します。
+  virtual void SetBoolean(bool b);
+
+  /// Symbolオブジェクトに対するインターフェースです。
+
+  // シンボル名を取得します。
+  virtual const unicode::UniString& GetSymbolName() const;
+
+  /// Stringオブジェクトに対するインターフェースです。
+
+  // 設定されている文字列を取得します。
+  virtual const unicode::UniString& GetString() const;
+
+  /// Numberオブジェクトに対するインターフェースです。
+
+  // 設定されているNumericオブジェクトを取得します。
+  virtual int GetNumber() const;
+
+  // Numericオブジェクトを設定します。
+  virtual void SetNumber(int num);
+
+  /// Charactorオブジェクトに対するインターフェースです。
+
+  // 設定されている文字を取得します。
+  virtual const unicode::UniChar& GetCharactor() const;
+
+  /// Vectorオブジェクトに対するインターフェースです。
+
+  // 配列への参照を取得します。
+  virtual const std::vector<IDatumBase*>& GetVector() const;
+
+  // 配列を設定します。
+  virtual void SetVector(const std::vector<IDatumBase*>& vector);
+
+  /// Bytevectorオブジェクトに対するインターフェースです。
+
+  // ByteVectorへの参照を取得します。
+  virtual const std::vector<IDatumBase*>& GetBytevector() const;
+
+  // Bytevectorを設定します。
+  virtual void SetBytevector(const std::vector<IDatumBase*>& vector);
+
+  // datum::DatumTypeによって表現されるDatumを返します。
+  virtual datum::DatumType type() const = 0;
+};
+};
+};
+
+#endif /* _UTAKATA_SRC_PARSER_DATUM_BASE_H_ */
diff --git a/src/parser/syntax_tree.cpp b/src/parser/syntax_tree.cpp
deleted file mode 100755 (executable)
index fd877fa..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-#include <iostream>
-
-#include <assert.h>
-#include <exception>
-
-#include "tree.h"
-#include <stack>
-
-#include "unicode.h"
-#include "literal_data.h"
-#include "literal.h"
-#include "datum_id.h"
-
-using namespace utakata;
-using namespace utakata::literal;
-using namespace utakata::unicode;
-using namespace utakata::syntax;
-
-// 原則としてそれぞれ単純に呼びだされるのみ。
-
-struct Tree::TreeNode
-{
-    TreeNode (node_pair p) : list(), datum (p) {}
-
-    std::vector<smart_ptr<TreeNode> > list;
-
-    // datumの型と値の両方を保持する。
-    Tree::node_pair datum;
-};
-
-////////////////////////////
-// syntax::Tree::iterator //
-////////////////////////////
-
-syntax::Tree::iterator::iterator () : current_()
-{
-}
-
-syntax::Tree::iterator::iterator (const Tree::iterator& i)
-{
-    swap (i);
-}
-
-syntax::Tree::iterator& syntax::Tree::iterator::operator=(const Tree::iterator& rh)
-{
-    iterator it (rh);
-    swap (it);
-    return *this;
-}
-
-void syntax::Tree::iterator::swap (const Tree::iterator& t)
-{
-    current_ = t.current_;
-}
-
-Tree::iterator& Tree::iterator::operator++ ()
-{
-    // car,cdr をそれぞれ巡回する。 car,cdr それぞれに移動する場合には、
-    // it を元の tree に渡して取得する。
-    // 巡回の順序は次の通りとする。
-    // cons -> cdr に繋がっている cons
-    // ただし、 cdr に繋がっている cons が literal の場合、以降は進むことが
-    // 無く、また list として判定されることはない。
-
-    ++current_;
-    return *this;
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> >& Tree::iterator::operator*()
-{
-    // 現在の current_が指す node のリテラルを返す。
-    return (*current_)->datum;
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> >* Tree::iterator::operator->()
-{
-    // 現在の current_が指す node のリテラルを返す。
-    return &((*current_)->datum);
-}
-
-bool Tree::iterator::operator==(const Tree::iterator& rh)
-{
-    // node_が指す先が同一かどうかを返す。
-    // 但し、自身か相手のいずれかが nil である場合だけは例外的に、単純に DatumID のみの
-    // 比較になる。
-    return current_ == rh.current_;
-}
-
-//////////////////
-// syntax::Tree //
-//////////////////
-
-Tree::Tree () : node_()
-{
-    // 初期値を設定する。
-    // smart_ptr<TreeNode> p(new TreeNode(makeNilList()));
-    // 最後尾には常にnilがいることにする。
-}
-
-Tree::iterator Tree::begin ()
-{
-    // 開始点を示すデータを返す。
-    iterator it;
-    it.current_ = node_.begin();
-    return it;
-}
-
-Tree::iterator Tree::end ()
-{
-    // 終了地点を示す部分を返す。
-    iterator it;
-    it.current_ = node_.end();
-    return it;
-}
-
-void Tree::push_back(node_pair datum)
-{
-    // 渡されたdatumを、現在保持しているデータ型に追加する。
-    smart_ptr<TreeNode> p(new TreeNode(datum));
-    node_.insert(node_.end(), p);
-}
-
-void Tree::push_back(Tree::iterator it, Tree::iterator it2,
-                     node_pair datum)
-{
-    // itとit2までを、datumで設定されたdatumidであるcompound datum
-    // に格納して追加する。
-    smart_ptr<TreeNode> p(new TreeNode(datum));
-    p->list.insert(p->list.end(), it.current_, it2.current_);
-    node_.insert(node_.end(), p);
-}
-
-Tree::iterator Tree::in_compound_begin(Tree::iterator it)
-{
-    // itがcompound datumである場合に、compound datumの内部リストを返す。
-    if (isCompoundDatum(it))
-    {
-        iterator ret;
-        ret.current_ = (*it.current_)->list.begin();
-        return ret;
-    }
-    else
-    {
-        // 違う場合には、endを返すことにする。
-        return end();
-    }
-}
-
-Tree::iterator Tree::in_compound_end(Tree::iterator it)
-{
-    // itがcompound datumである場合に、compound datumの内部リストを返す。
-    if (isCompoundDatum(it))
-    {
-        iterator ret;
-        ret.current_ = (*it.current_)->list.end();
-        return ret;
-    }
-    else
-    {
-        // 違う場合には、endを返すことにする。
-        return end();
-    }
-}
-
-//////////////////////
-// helper functions //
-//////////////////////
-
-bool syntax::isCompoundDatum(Tree::iterator it)
-{
-    if (it->first == syntax::DatumID::list ||
-        it->first == syntax::DatumID::vector ||
-        it->first == syntax::DatumID::byteVector)
-    {
-        return true;
-    }
-    else
-    {
-        return false;
-    }
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeCompoundDatum (
-    DatumID id)
-{
-    // datum_id が list である node_pair を返す。
-    return std::pair<DatumID, smart_ptr<literal::Literal> >(id, smart_ptr<literal::Literal>());
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeNilList ()
-{
-    // datum_id が nil である node_pair を返す。
-    return std::pair<DatumID, smart_ptr<literal::Literal> >(
-        DatumID(DatumID::nil), smart_ptr<literal::Literal>());
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeLexemeDatum (smart_ptr<literal::Literal> l,
-    DatumID id)
-{
-    // datum_id が各 lexeme であり、 literal として l を持つ
-    // datum を返す。
-    return std::pair<DatumID, smart_ptr<literal::Literal> >(
-        id, l);
-}
-
-std::pair<DatumID, smart_ptr<literal::Literal> > syntax::makeAbbreviation (smart_ptr<literal::Literal> l)
-{
-    // datum_id が literal であり、 literal として l を持つ
-    // datum を返す。
-    return std::pair<DatumID, smart_ptr<literal::Literal> >(
-        DatumID (DatumID::abbreviations), l);
-}
-
diff --git a/src/parser/syntax_tree.h b/src/parser/syntax_tree.h
deleted file mode 100755 (executable)
index a332c2b..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// syntax_tree.h  -  declared `SyntaxTree` that it used by Parser
-// Parserクラスより利用される、内部の構文木を構築します。
-// 内部構文木は、構文データのみで表現される、構文データを表現するための
-// クラスとなります。
-// 内部では、lexer::Tokenより解析されたObjectクラスの派生クラスをそれぞれ
-// 保持します。内部的には、すべてobject::Consによって連接されたリストとして
-// 表現されます。
-#ifndef _UTAKATA_SRC_PARSER_SYNTAX_TREE_H_
-#define _UTAKATA_SRC_PARSER_SYNTAX_TREE_H_
-
-#include "lib/smart_ptr.h"
-#include <utility>              // std::pair
-#include <vector>
-
-namespace utakata {
-namespace unicode {
-class UniString;
-};
-
-namespace syntax {
-
-class DatumID;
-
-// データ構文を表現する、Lexemeから構築された構文木を表現します。
-// 内部では、Lexemeより作成された各プリミティブオブジェクトを保持し、
-// 完全なデータ構文木を作成します。
-// このデータ構文木は任意の数のdatumを含むことができますが、全体を構築
-// する際、表面上は一つだけcompound datumを含んでいるパターンが想定されます。
-class SyntaxTree {
-  // 実装でのみ定義される。
-  struct TreeNode;
-
- public:
-
-  class iterator {
-   public:
-    // ツリーを巡回し、そのノードの literal を取得することを可能とする。
-    iterator ();
-    iterator (const iterator& s);
-
-    ~iterator () {}
-
-    iterator& operator=(const iterator& rh);
-    iterator& operator++ ();
-    node_pair& operator*();
-    node_pair* operator->();
-
-    // 一致するかどうかを返す
-    bool operator==(const iterator& rh);
-    bool operator!=(const iterator& rh) {
-      return ! (*this == rh);
-    }
-
-    // 現在位置を表すiterator
-    std::vector<smart_ptr<TreeNode> >::iterator current_;
-
-   private:
-
-    void swap (const iterator& s);
-
-  };
- public:
-
-  Tree ();
-  virtual ~Tree () {}
-
-  // 現在の Tree の先頭=root node と、 end = 次に指す場所が存在しない
-  // node を返す。
-  iterator begin ();
-  iterator end ();
-
-  // push_backによって追加を行う。
-  void push_back (node_pair datum);
-  void push_back (iterator b, iterator e, node_pair datum);
-
-  // itが指すnodeの内部listの先頭を返す。
-  iterator in_compound_begin(iterator it);
-  iterator in_compound_end(iterator it);
-
-  size_t size() const {return node_.size();}
-
- private:
-
-  std::vector<smart_ptr<TreeNode> > node_;
-
-};
-
-// 渡した iterator が list datum であるかどうかを返す。
-bool isCompoundDatum (Tree::iterator node);
-
-// 渡した node が literal であるかどうかを返す。
-bool isLiteral (Tree::iterator node);
-
-// 各 datum を表す std::pair を作成するためのヘルパ関数。
-std::pair<DatumID, smart_ptr<literal::Literal> > makeCompoundDatum (
-    DatumID id);
-
-std::pair<DatumID, smart_ptr<literal::Literal> > makeNilList ();
-std::pair<DatumID, smart_ptr<literal::Literal> > makeLexemeDatum (smart_ptr<literal::Literal> l,
-                                                                  DatumID id);
-std::pair<DatumID, smart_ptr<literal::Literal> > makeAbbreviation (smart_ptr<literal::Literal> l);
-
-// 渡したtreeの内容を文字列に変換する。
-//        smart_ptr<unicode::UniString> treeToValue(Tree& t);
-};
-
-};
-
-#endif /* _UTAKATA_SRC_PARSER_SYNTAX_TREE_H_ */
index 9ad41db..064848b 100755 (executable)
@@ -19,7 +19,6 @@ TEST(BinaryTreeTest, PreorderUse) {
       string_tree.begin(), left, right;
 
   // Return begin() is top of `string_tree`. It is root.
-  top = string_tree.insert(top, "root");
   left = string_tree.set_left(top, "child1");
   right = string_tree.set_right(top, "child2");
 
@@ -27,69 +26,65 @@ TEST(BinaryTreeTest, PreorderUse) {
   string_tree.set_left(right, "right child1");
   string_tree.set_right(right, "right child2");
 
-  akebono::binary_tree<std::string>::inorder_iterator top =
-      string_tree.preorder_begin();
-
-  EXPECT_EQ(*top, "root"); ++top;
+  top = string_tree.begin();
+  top++;
   EXPECT_EQ(*top, "child1"); top++;
   EXPECT_EQ(*top, "left child1"); ++top;
   EXPECT_EQ(*top, "child2"); ++top;
   EXPECT_EQ(*top, "right child1"); ++top;
   EXPECT_EQ(*top, "right child2"); ++top;
-  EXPECT_EQ(top, string_tree.preorder_end());
-}
-
-TEST(BinaryTreeTest, PostorderUse) {
-  akebono::binary_tree<std::string> string_tree;
-  akebono::binary_tree<std::string>::iterator top =
-      string_tree.begin(), left, right;
-
-  // Return begin() is top of `string_tree`. It is root.
-  top = string_tree.insert(top, "root");
-  left = string_tree.set_left(top, "child1");
-  right = string_tree.set_right(top, "child2");
-
-  string_tree.set_right(left, "left child1");
-  string_tree.set_left(right, "right child1");
-  string_tree.set_right(right, "right child2");
-
-  akebono::binary_tree<std::string>::inorder_iterator top =
-      string_tree.postorder_begin();
-
-  EXPECT_EQ(*top, "left child1"); top++;
-  EXPECT_EQ(*top, "child1"); ++top;
-  EXPECT_EQ(*top, "right child1"); ++top;
-  EXPECT_EQ(*top, "right child2"); ++top;
-  EXPECT_EQ(*top, "child2"); ++top;
-  EXPECT_EQ(*top, "root"); ++top;
-  EXPECT_EQ(top, string_tree.preorder_end());
+  EXPECT_TRUE(top == string_tree.end());
 }
 
-TEST(BinaryTreeTest, InorderUse) {
-  akebono::binary_tree<std::string> string_tree;
-  akebono::binary_tree<std::string>::iterator top =
-      string_tree.begin(), left, right;
-
-  // Return begin() is top of `string_tree`. It is root.
-  top = string_tree.insert(top, "root");
-  left = string_tree.set_left(top, "child1");
-  right = string_tree.set_right(top, "child2");
-
-  string_tree.set_right(left, "left child1");
-  string_tree.set_left(right, "right child1");
-  string_tree.set_right(right, "right child2");
-
-  akebono::binary_tree<std::string>::inorder_iterator top =
-      string_tree.inorder_begin();
-
-  EXPECT_EQ(*top, "left child1"); top++;
-  EXPECT_EQ(*top, "child1"); ++top;
-  EXPECT_EQ(*top, "root"); ++top;
-  EXPECT_EQ(*top, "right child1"); ++top;
-  EXPECT_EQ(*top, "child2"); ++top;
-  EXPECT_EQ(*top, "right child2"); ++top;
-  EXPECT_EQ(top, string_tree.inorder_end());
-}
+// TEST(BinaryTreeTest, PostorderUse) {
+//   akebono::binary_tree<std::string> string_tree;
+//   akebono::binary_tree<std::string>::iterator top =
+//       string_tree.begin(), left, right;
+
+//   // Return begin() is top of `string_tree`. It is root.
+//   left = string_tree.set_left(top, "child1");
+//   right = string_tree.set_right(top, "child2");
+
+//   string_tree.set_right(left, "left child1");
+//   string_tree.set_left(right, "right child1");
+//   string_tree.set_right(right, "right child2");
+
+//   akebono::binary_tree<std::string>::inorder_iterator top =
+//       string_tree.postorder_begin();
+
+//   EXPECT_EQ(*top, "left child1"); top++;
+//   EXPECT_EQ(*top, "child1"); ++top;
+//   EXPECT_EQ(*top, "right child1"); ++top;
+//   EXPECT_EQ(*top, "right child2"); ++top;
+//   EXPECT_EQ(*top, "child2"); ++top;
+//   EXPECT_EQ(*top, "root"); ++top;
+//   EXPECT_EQ(top, string_tree.preorder_end());
+// }
+
+// TEST(BinaryTreeTest, InorderUse) {
+//   akebono::binary_tree<std::string> string_tree;
+//   akebono::binary_tree<std::string>::iterator top =
+//       string_tree.begin(), left, right;
+
+//   // Return begin() is top of `string_tree`. It is root.
+//   left = string_tree.set_left(top, "child1");
+//   right = string_tree.set_right(top, "child2");
+
+//   string_tree.set_right(left, "left child1");
+//   string_tree.set_left(right, "right child1");
+//   string_tree.set_right(right, "right child2");
+
+//   akebono::binary_tree<std::string>::inorder_iterator top =
+//       string_tree.inorder_begin();
+
+//   EXPECT_EQ(*top, "left child1"); top++;
+//   EXPECT_EQ(*top, "child1"); ++top;
+//   EXPECT_EQ(*top, "root"); ++top;
+//   EXPECT_EQ(*top, "right child1"); ++top;
+//   EXPECT_EQ(*top, "child2"); ++top;
+//   EXPECT_EQ(*top, "right child2"); ++top;
+//   EXPECT_EQ(top, string_tree.inorder_end());
+// }
 
 TEST(BinaryTreeTest, SExpLikeUse) {
   akebono::binary_tree<std::string> string_tree;
@@ -98,27 +93,30 @@ TEST(BinaryTreeTest, SExpLikeUse) {
 
   // Return begin() is top of `string_tree`. It is root.
   // create tree from SExp as "((child1 3) child2 (hoge) (huga))"
-  top = string_tree.insert(top, "root");
-  left = string_tree.set_left(top, "child1");
-  left = string_tree.set_right(left, "3");
-  right = string_tree.set_right(top, "child2");
+  left = string_tree.set_left(top, "left_cons");
+  left = string_tree.set_left(left, "child1");
+  left = string_tree.set_right(left, "right_cons1");
+  left = string_tree.set_left(left, "3");
+  right = string_tree.set_right(top, "right_cons2");
+  right = string_tree.set_left(right, "child2");
   left = string_tree.set_right(right, "hoge_cons");
-  left = string_tree.set_left(left, "hoge");
-  right = string_tree.set_right(right, "huga_cons");
+  string_tree.set_left(left, "hoge");
+  right = string_tree.set_right(left, "huga_cons");
   right = string_tree.set_left(right, "huga");
 
-  akebono::binary_tree<std::string>::preorder_iterator top =
-      string_tree.inorder_begin();
+  top = string_tree.begin();++top;
 
-  EXPECT_EQ(*top, "root"); top++;       // it's not uses
+  EXPECT_EQ(*top, "left_cons"); ++top;
   EXPECT_EQ(*top, "child1"); ++top;
+  EXPECT_EQ(*top, "right_cons1"); ++top;
   EXPECT_EQ(*top, "3"); ++top;
+  EXPECT_EQ(*top, "right_cons2"); ++top;
   EXPECT_EQ(*top, "child2"); ++top;
   EXPECT_EQ(*top, "hoge_cons"); ++top;  // it's not uses
   EXPECT_EQ(*top, "hoge"); ++top;
   EXPECT_EQ(*top, "huga_cons"); ++top;  // it's not uses
   EXPECT_EQ(*top, "huga"); ++top;
-  EXPECT_EQ(top, string_tree.inorder_end());
+  EXPECT_TRUE(top == string_tree.end());
 }
 
 int main(int argc, char** argv) {
index 7833589..eb52e5b 100755 (executable)
@@ -1,48 +1,48 @@
 #include <iostream>
 #include <test/gtest/gtest.h>
-#include "lib/smart_ptr.h"
-#include "src/datum.h"
-#include "src/object.h"
-#include "src/unicode.h"
+// #include "lib/smart_ptr.h"
+// #include "src/datum.h"
+// #include "src/object.h"
+// #include "src/unicode.h"
 
-namespace data = utakata::data;
-namespace interpreter = utakata::interpreter;
-namespace unicode = utakata::unicode;
-namespace datum = utakata::datum;
+// namespace data = utakata::data;
+// namespace interpreter = utakata::interpreter;
+// namespace unicode = utakata::unicode;
+// namespace datum = utakata::datum;
 
-using namespace akebono;
+// using namespace akebono;
 
-class TestObject : public interpreter::IObject {
- public:
-  virtual ~TestObject() {}
+// class TestObject : public interpreter::IObject {
+//  public:
+//   virtual ~TestObject() {}
 
-  interpreter::IObject* Clone() const {
-    return NULL;
-  }
+//   interpreter::IObject* Clone() const {
+//     return NULL;
+//   }
 
-  unicode::UniString* ToString() const {
-    return NULL;
-  }
+//   unicode::UniString* ToString() const {
+//     return NULL;
+//   }
 
-  interpreter::IObject* Eval(interpreter::Environment* env) {
-    return NULL;
-  }
-};
+//   interpreter::IObject* Eval(interpreter::Environment* env) {
+//     return NULL;
+//   }
+// };
 
-TEST(DatumTest, LexemeDatumTest) {
-  smart_ptr<datum::IDatumBase> symbol(new datum::Symbol(
-      unicode::Convert("symbol")));
+// TEST(DatumTest, LexemeDatumTest) {
+//   smart_ptr<datum::IDatumBase> symbol(new datum::Symbol(
+//       unicode::Convert("symbol")));
 
-  smart_ptr<datum::IDatumBase> str(new datum::String(
-      unicode::Convert("\"string\"")));
+//   smart_ptr<datum::IDatumBase> str(new datum::String(
+//       unicode::Convert("\"string\"")));
 
-  smart_ptr<datum::IDatumBase> number(new datum::Number(
-      unicode::Convert("102")));
+//   smart_ptr<datum::IDatumBase> number(new datum::Number(
+//       unicode::Convert("102")));
 
-  smart_ptr<datum::IDatumBase> boolean(new datum::Boolean(
-      unicode::Convert("#t")));
+//   smart_ptr<datum::IDatumBase> boolean(new datum::Boolean(
+//       unicode::Convert("#t")));
   
-}
+// }
 
 int main(int argc, char** argv) {
   testing::InitGoogleTest(&argc, argv);
diff --git a/test/parser_test.cpp b/test/parser_test.cpp
new file mode 100755 (executable)
index 0000000..a03bf4e
--- /dev/null
@@ -0,0 +1,145 @@
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <functional>
+
+#include "lib/textarrayformat.h"
+#include "src/unicode.h"
+#include "src/parser/datum_parser.h"
+#include "src/lexer/lexer.h"
+
+#include "lib/binary_tree.h"
+#include "src/utf8_transcoder.h"
+#include "src/string_reader.h"
+
+namespace textarrayformat = utility::textarrayformat;
+namespace lexer = utakata::lexer;
+namespace unicode = utakata::unicode;
+namespace reader = utakata::reader;
+namespace transcoder = utakata::transcoder;
+
+class SchemeLexerTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    gen.reset(new textarrayformat::TextArrayGenerator("========="));
+    gen->Punctuate("#|\n \
+   The FACT procedure computes the factorial\n \
+ of a non-negative integer.\n \
+|#\n \
+(define fact\n \
+  (lambda (n)\n \
+    ;; base case\n \
+    (if (= n 0)\n \
+        #;(= n 1)\n \
+        1       ; identity of *\n \
+        (* n (fact (- n '1))))))");
+    gen->Punctuate("(define test () (print 'hoge `huga))");
+  }
+
+  akebono::scoped_ptr<textarrayformat::TextArrayGenerator> gen;
+};
+
+TEST(ParserTest, LexemeToDatum) {
+  textarrayformat::TextArrayReader textarray(*gen);
+
+  reader::StringReader sr(textarray.GetBlockAt(0));
+  reader::EncodingReader reader(&sr, new transcoder::UTF8Transcoder);
+  
+  lexer::SchemeLexer lexer;
+  parser::DatumParser parser;
+  parser.set_parser_creater(new lexer::SchemeLexerCreater());
+
+  akebono::scoped_ptr<akebono::binary_tree<datum::Datum> > tree(
+      parser.Parse(&reader));
+
+  akebono::binary_tree<datum::Datum>::iterator it = tree->begin();
+  
+  EXPECT_EQ(it->type(), datum::Datum::kCons);
+  ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->ToString(), unicode::Convert("define"));
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("define")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->ToString(), unicode::Convert("fact"));
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("fact")); ++it;
+
+  // (lambda
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("lambda")); ++it;
+
+  // (n)
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+
+  // (if
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("if")); ++it;
+
+  // (= n 0)
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("=")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kNumber);
+  EXPECT_EQ(it->ToString(), unicode::Convert("0")); ++it;
+
+  // 1
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kNumber);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("1")); ++it;
+
+  // (* n
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("*")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+
+  // (fact
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("fact")); ++it;
+
+  // (- n
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("-")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("n")); ++it;
+
+  // '1
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kSymbol);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("quote")); ++it;
+
+  EXPECT_EQ(it->type(), datum::Datum::kCons); ++it;
+  EXPECT_EQ(it->type(), datum::Datum::kNumber);
+  EXPECT_EQ(it->GetSymbolName(), unicode::Convert("1")); ++it;
+}
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/parser_test.cpp.bk b/test/parser_test.cpp.bk
deleted file mode 100755 (executable)
index ca4b9a4..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-#include <iostream>
-#include <sstream>
-#include <string>
-#include <functional>
-
-#include "../simpletest.h"
-
-#include "../textarrayformat.h"
-#include "../unicode.h"
-#include "../parser.h"
-#include "../lexeme_id.h"
-#include "../lexeme.h"
-
-#include "../lexer.h"
-
-#include "../tree.h"
-#include "../utf8_transcoder.h"
-#include "../reader.h"
-#include "../object.h"
-#include "../gc.h"
-#include "../type.h"
-#include "../primitive.h"
-#include "../data_castor.h"
-#include "../data_structure.h"
-#include "../primitive_class.h"
-
-using namespace std;
-using namespace utakata;
-
-data::Object cadr(interpreter::primitive::Cons* c)
-{
-    return data::DataCastor<interpreter::primitive::Cons>()(c->cdr())->car();
-}
-
-data::Object cdar(interpreter::primitive::Cons* c)
-{
-    return data::DataCastor<interpreter::primitive::Cons>()(c->car())->cdr();
-}
-
-interpreter::primitive::Cons* tocons(data::Object o)
-{
-    return data::DataCastor<interpreter::primitive::Cons>()(o);
-}
-
-
-bool parser_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
-    std::stringstream ss;
-    ss << "==========" << endl;
-    ss << "(+ 12 24)" << endl;
-    ss << "==========" << endl;
-    ss << "(+ (- 12 \"hoge\") 24)" << endl;
-    ss << "==========" << endl;
-    ss << "((- 12 \"hoge\") '24)" << endl;
-    ss << "==========" << endl;
-    ss << "(define hoge (lambda () (- 12 24)))" << endl;
-
-    textarrayformat::TextArrayReader reader(ss);
-    smart_ptr<istream> formats(new stringstream(reader.get(2)));
-    smart_ptr<utakata::reader::StreamReader> st(
-        new utakata::reader::StreamReader(formats,
-                                          smart_ptr<transcoder::ITranscoder>(
-                                              new transcoder::UTF8Transcoder())));
-
-    std::vector<smart_ptr<lexeme::ILexeme> > lexemes;
-
-    smart_ptr<utakata::lexer::Lexer> lexer(new lexer::Lexer());
-
-    parser::Parser p(lexer);
-    // parserから生成されるオブジェクトは完全なdungring objectとなる。
-    // primitiveなデータに関しては、singletonなTypeHashを保持する、
-    // primitive factoryが利用される。
-    gc::GarbageCollector gc;
-    smart_ptr<data::Object> t = p.parse(st, gc);
-
-    // 先頭はconsであるはず。
-    interpreter::primitive::PrimitiveClass<interpreter::primitive::Cons> consclass;
-    asserter->check(data::instanceof(*t, type::Type(
-                                         consclass.class_name())), true,
-                    "cons error1");
-
-    // 更に内部についても、同様にConsであるはず。((の部分。
-    data::Object o = data::DataCastor<interpreter::primitive::Cons>()(*t)->car();
-    asserter->check(data::instanceof(o, type::Type(consclass.class_name())), true,
-                    "cons error 2");
-
-    // さらにcarを取得してみる。ここでのcarはつまり `-` なのでシンボル
-    {
-        using namespace utakata::interpreter::primitive;
-        data::Object o2 = data::DataCastor<interpreter::primitive::Cons>()(o)->car();
-        asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<Symbol>().class_name())), true,
-                        "symbol error1");
-    }
-
-    // cdrはリストなので、当然だがcons。
-    o = data::DataCastor<interpreter::primitive::Cons>()(o)->cdr();
-    asserter->check(data::instanceof(o, type::Type(consclass.class_name())), true,
-                    "cons error 2");
-
-    {
-        // 数値が来ている。
-        using namespace utakata::interpreter::primitive;
-        
-        data::Object o2 = data::DataCastor<interpreter::primitive::Cons>()(o)->car();
-        asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<Number>().class_name())), true,
-                        "number error");
-    }
-
-    o = data::DataCastor<interpreter::primitive::Cons>()(o)->cdr();
-    {
-        // 文字列が来ている。
-        using namespace utakata::interpreter::primitive;
-        
-        data::Object o2 = data::DataCastor<interpreter::primitive::Cons>()(o)->car();
-        asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<String>().class_name())), true,
-                        "string error");
-    }
-
-    // ここでcdrを取得すると、'24に繋がる。
-    o = data::DataCastor<interpreter::primitive::Cons>()(*t)->cdr();
-    o = data::DataCastor<interpreter::primitive::Cons>()(o)->car();
-    data::Object o2 = data::DataCastor<interpreter::primitive::Cons>()(o)->car();
-
-    
-    // ここでquoteである。
-    asserter->check(data::instanceof(o2, type::Type(interpreter::primitive::PrimitiveClass<interpreter::primitive::Quote>().class_name())), true,
-                    "quote Error");
-
-    // cdrはCons
-    o2 = data::DataCastor<interpreter::primitive::Cons>()(o)->cdr();
-    {
-        // 数値が来ている。
-        using namespace utakata::interpreter::primitive;
-        
-        data::Object o3 = data::DataCastor<interpreter::primitive::Cons>()(o2)->car();
-        asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<Number>().class_name())), true,
-                        "number error");
-    }
-
-    data::Object o3 = data::DataCastor<interpreter::primitive::Cons>()(o2)->cdr();
-    asserter->check(data::instanceof(o3, type::Type(interpreter::primitive::PrimitiveClass<
-                                                    interpreter::primitive::Nil>().class_name())), true,
-                    "nil Error");
-    
-    return asserter->isOk();
-}
-
-bool parser_test2(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
-    std::stringstream ss;
-    ss << "==========" << endl;
-    ss << "(+ 12 24)" << endl;
-    ss << "==========" << endl;
-    ss << "(+ (- 12 \"hoge\") (14 . 1))" << endl;
-    ss << "==========" << endl;
-    ss << "((- 12 \"hoge\") '24)" << endl;
-    ss << "==========" << endl;
-    ss << "(define hoge (lambda () (- 12 24)))" << endl;
-
-    textarrayformat::TextArrayReader reader(ss);
-    smart_ptr<istream> formats(new stringstream(reader.get(1)));
-    smart_ptr<utakata::reader::StreamReader> st(
-        new utakata::reader::StreamReader(formats,
-                                          smart_ptr<transcoder::ITranscoder>(
-                                              new transcoder::UTF8Transcoder())));
-
-    std::vector<smart_ptr<lexeme::ILexeme> > lexemes;
-
-    smart_ptr<utakata::lexer::Lexer> lexer(new lexer::Lexer());
-
-    parser::Parser p(lexer);
-    // parserから生成されるオブジェクトは完全なdungring objectとなる。
-    // primitiveなデータに関しては、singletonなTypeHashを保持する、
-    // primitive factoryが利用される。
-    gc::GarbageCollector gc;
-    smart_ptr<data::Object> t = p.parse(st, gc);
-
-    using namespace utakata::interpreter::primitive;
-
-    data::Object o = tocons(*t)->car();
-    // ここはシンボル
-    asserter->check(data::instanceof(o, type::Type(PrimitiveClass<Symbol>().class_name())),
-        true);
-
-    o = tocons(*t)->cdr();
-    asserter->check(data::instanceof(o, type::Type(PrimitiveClass<Cons>().class_name())),
-        true);
-
-    // (- 12 "hoge")
-    data::Object o2 = tocons(o)->car();
-    asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<Cons>().class_name())),
-        true);
-
-    data::Object o3 = tocons(o2)->car();
-    asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<Symbol>().class_name())),
-        true);
-
-    // 12
-    o3 = cadr(tocons(o2));
-    asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<Number>().class_name())),
-        true);
-
-    // "hoge"
-    o3 = cadr(tocons(tocons(o2)->cdr()));
-    asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<String>().class_name())),
-        true);
-
-    // ((14 . 1))
-    o2 = tocons(o)->cdr();
-
-    // (14 . 1)
-    o2 = tocons(o2)->car();
-
-    // 14
-    o3 = tocons(o2)->car();
-    asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<Number>().class_name())),
-                    true, "dot first");
-
-    // 1
-    o3 = tocons(o2)->cdr();
-    asserter->check(data::instanceof(o3, type::Type(PrimitiveClass<Number>().class_name())),
-                    true, "dot second");
-
-    return asserter->isOk();
-}
-
-bool parser_test3(smart_ptr<simpletest::SimpleTestAsserter> asserter)
-{
-    std::stringstream ss;
-    ss << "==========" << endl;
-    ss << "(+ 12 24)" << endl;
-    ss << "==========" << endl;
-    ss << "(+ (- 12 \"hoge\") (14 . 1))" << endl;
-    ss << "==========" << endl;
-    ss << "((- 12 \"hoge\") '24)" << endl;
-    ss << "==========" << endl;
-    ss << "(define hoge (lambda () (- 12 24)))" << endl;
-
-    textarrayformat::TextArrayReader reader(ss);
-    smart_ptr<istream> formats(new stringstream(reader.get(3)));
-    smart_ptr<utakata::reader::StreamReader> st(
-            new utakata::reader::StreamReader(formats,
-                                              smart_ptr<transcoder::ITranscoder>(
-                                                      new transcoder::UTF8Transcoder())));
-
-    std::vector<smart_ptr<lexeme::ILexeme> > lexemes;
-
-    smart_ptr<utakata::lexer::Lexer> lexer(new lexer::Lexer());
-
-    parser::Parser p(lexer);
-    // parserから生成されるオブジェクトは完全なdungring objectとなる。
-    // primitiveなデータに関しては、singletonなTypeHashを保持する、
-    // primitive factoryが利用される。
-    gc::GarbageCollector gc;
-    smart_ptr<data::Object> t = p.parse(st, gc);
-
-    using namespace utakata::interpreter::primitive;
-
-    data::Object o = tocons(*t)->car();
-    // define
-    asserter->check(data::instanceof(o, type::Type(PrimitiveClass<Symbol>().class_name())),
-                    true, "symbol define");
-
-    // (hoge (lambda () (- 12 24)))
-    o = tocons(*t)->cdr();
-    data::Object o2 = tocons(o)->car();
-    // hoge
-    asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<Symbol>().class_name())),
-                    true, "symbol hoge");
-
-    // ((lambda () (- 12 24)))
-    o = tocons(o)->cdr();
-    // (lambda () (- 12 24))
-    o2 = tocons(o)->car();
-    asserter->check(data::instanceof(o2, type::Type(PrimitiveClass<Cons>().class_name())),
-                    true, "cons");
-
-    // lambda
-    asserter->check(data::instanceof(tocons(o2)->car(),
-                                     type::Type(PrimitiveClass<Cons>().class_name())),
-                    true, "lambda");
-
-    // nil
-    data::Object o3 = tocons(o2)->cdr();
-    asserter->check(data::instanceof(tocons(o3)->car(),
-                                     type::Type(PrimitiveClass<Nil>().class_name())),
-                    true, "nil");
-
-    // ((- 12 24)) -> (- 12 24)
-    o3 = cadr(tocons(o3));
-    asserter->check(data::instanceof(tocons(o3)->car(),
-                                     type::Type(PrimitiveClass<Symbol>().class_name())),
-                    true, "-");
-
-    // 12
-    asserter->check(data::instanceof(cadr(tocons(o3)),
-                                     type::Type(PrimitiveClass<Number>().class_name())),
-                    true, "12");
-
-    // (12 24)
-    data::Object o4 = tocons(o3)->cdr();
-    asserter->check(data::instanceof(cadr(tocons(o4)),
-                                     type::Type(PrimitiveClass<Number>().class_name())),
-                    true, "24");
-
-    o4 = tocons(o4)->cdr();
-    asserter->check(data::instanceof(cadr(tocons(o4)),
-                                     type::Type(PrimitiveClass<Nil>().class_name())),
-                    true, "nil");
-
-
-    return asserter->isOk();
-}
-
-int main(int argc, char *argv[])
-{
-    simpletest::SimpleTestSuite suite("parser test");
-    suite.addTester(sfcr::screate(parser_test, suite.getAsserter()));
-    suite.addTester(sfcr::screate(parser_test2, suite.getAsserter()));
-    // suite.addTester(sfcr::screate(parser_test3, suite.getAsserter()));
-    // suite.addTester(sfcr::screate(parser_test4, suite.getAsserter()));
-    suite.run();
-    return 0;
-}