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")
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
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")
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
#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_ */
+++ /dev/null
-#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_ */
+++ /dev/null
-// 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_ */
--- /dev/null
+#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`"));
+}
--- /dev/null
+// 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_ */
--- /dev/null
+#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`"));
+}
--- /dev/null
+// 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_ */
+++ /dev/null
-#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);
-}
-
+++ /dev/null
-// 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_ */
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_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;
// 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) {
#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);
--- /dev/null
+#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();
+}
+++ /dev/null
-#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;
-}