OSDN Git Service

mock的なシンプルGCの実装を開始。かなり構造が変わっていっているので、自分で意識しておくこと。
[simplecms/utakata.git] / test / parser_test.cpp
1 #include <iostream>
2 #include <sstream>
3 #include <string>
4 #include <functional>
5
6 #include "../simpletest.h"
7
8 #include "../textarrayformat.h"
9 #include "../unicode.h"
10 #include "../parser.h"
11 #include "../lexeme_id.h"
12 #include "../lexeme.h"
13 #include "../literal.h"
14
15 #include "../lexer.h"
16
17 #include "../tree.h"
18 #include "../utf8_transcoder.h"
19 #include "../reader.h"
20 #include "../object.h"
21
22
23 using namespace std;
24 using namespace utakata;
25
26 bool parser_test(smart_ptr<simpletest::SimpleTestAsserter> asserter)
27 {
28     std::stringstream ss;
29     ss << "==========" << endl;
30     ss << "(+ 12 24)" << endl;
31     ss << "==========" << endl;
32     ss << "(+ (- 12 \"hoge\") 24)" << endl;
33     ss << "==========" << endl;
34     ss << "((- 12 \"hoge\") '24)" << endl;
35     ss << "==========" << endl;
36     ss << "(define hoge (lambda () (- 12 24)))" << endl;
37
38     textarrayformat::TextArrayReader reader(ss);
39     smart_ptr<istream> formats(new stringstream(reader.get(2)));
40     smart_ptr<utakata::reader::StreamReader> st(
41         new utakata::reader::StreamReader(formats,
42                                           smart_ptr<transcoder::ITranscoder>(
43                                               new transcoder::UTF8Transcoder())));
44
45     std::vector<smart_ptr<lexeme::ILexeme> > lexemes;
46
47     smart_ptr<utakata::lexer::Lexer> lexer(new lexer::Lexer());
48
49     parser::Parser p(lexer);
50     // parserから生成されるオブジェクトは完全なdungring objectとなる。
51     // primitiveなデータに関しては、singletonなTypeHashを保持する、
52     // primitive factoryが利用される。
53     smart_ptr<interpreter::Object> t = p.parse(st);
54
55     // 先頭はconsであるはず。
56     asserter->check(t->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
57                     interpreter::Class<primitive::Cons>().class_name(), "cons error1");
58
59     // 更に内部についても、同様にConsであるはず。((の部分。
60     smart_ptr<interpreter::Object> o = DataCastor<primitive::Cons>(*t)->car();
61     asserter->check(o->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
62                     interpreter::Class<primitive::Cons>().class_name(), "cons error 2");
63
64     // さらにcarを取得してみる。ここでのcarはつまり `-` なのでシンボル
65     {
66         smart_ptr<interpreter::Object> o2 = DataCastor<primitive::Cons>(*o)->car();
67         asserter->check(o2->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
68                         interpreter::Class<primitive::Symbol>().class_name(), "symbol error1");
69     }
70
71     // cdrはリストなので、当然だがcons。
72     o = DataCastor<primitive::Cons>(*t)->cdr();
73     asserter->check(o->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
74                     interpreter::Class<primitive::Cons>().class_name(), "cons error 2");
75
76     {
77         // 数値が来ている。
78         smart_ptr<interpreter::Object> o2 = DataCastor<primitive::Cons>(*o)->car();
79         asserter->check(o2->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
80                         interpreter::Class<primitive::Number>().class_name(), "number error");
81     }
82
83     o = DataCastor<primitive::Cons>(*t)->cdr();
84     {
85         // 文字列が来ている。
86         smart_ptr<interpreter::Object> o2 = DataCastor<primitive::Cons>(*o)->car();
87         asserter->check(o2->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
88                         interpreter::Class<primitive::String>().class_name(), "string error");
89     }
90
91     // 末尾はnilオブジェクトになっている。nilオブジェクトは、全体で一
92     // 意なオブジェクトになっている?
93     {
94         // 文字列が来ている。
95         smart_ptr<interpreter::Object> o2 = DataCastor<primitive::Nil>(*o)->cdr();
96         asserter->check(o2->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
97                         interpreter::Class<primitive::Nil>().class_name(), "nil error");
98     }
99
100     // ここでcdrを取得すると、'24に繋がる。
101     o = DataCastor<primitive::Cons>(*t)->cdr();
102     o = DataCastor<primitive::Cons>(*o)->car();
103     smart_ptr<interpreter::Object> o2 = DataCastor<primitive::Cons>(*o)->car();
104     // ここでquoteである。
105     asserter->check(o2->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
106                         interpreter::Class<primitive::Quote>().class_name(), "nil Error");
107
108     // cdrはCons
109     o2 = DataCastor<primitive::Cons>(*o)->cdr();
110     smart_ptr<interpreter::Object> o3 = DataCastor<primitive::Cons>(*o2)->car();
111     asserter->check(o3->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
112                     interpreter::Class<primitive::Number>().class_name(), "nil Error");
113
114     o3 = DataCastor<primitive::Cons>(*o3)->cdr();
115     asserter->check(o3->getSpace()->getTypeDescripter()->getType()->getBaseHash(),
116                     interpreter::Class<primitive::Nil>().class_name(), "nil Error");
117     
118     return asserter->isOk();
119 }
120
121 // bool parser_test2(smart_ptr<simpletest::SimpleTestAsserter> asserter)
122 // {
123 //     // ss << "(define hoge (lambda () (- 12 24)))" << endl;
124 //     std::stringstream ss;
125 //     ss << "==========" << endl;
126 //     ss << "(+ 12 24)" << endl;
127 //     ss << "==========" << endl;
128 //     ss << "(+ (- 12 \"hoge\") 24)" << endl;
129 //     ss << "==========" << endl;
130 //     ss << "((- 12 \"hoge\") '24)" << endl;
131 //     ss << "==========" << endl;
132 //     ss << "(define hoge (lambda () (- 12 24)))" << endl;
133
134 //     textarrayformat::TextArrayReader reader(ss);
135 //     smart_ptr<istream> formats(new stringstream(reader.get(3)));
136 //     smart_ptr<utakata::reader::StreamReader> st(
137 //         new utakata::reader::StreamReader(formats,
138 //                                           smart_ptr<transcoder::ITranscoder>(
139 //                                               new transcoder::UTF8Transcoder())));
140 //     smart_ptr<utakata::lexer::Lexer> lexer(new utakata::lexer::Lexer());
141  
142 //     utakata::parser::Parser p(lexer);
143 //     smart_ptr<syntax::Tree> t = p.parse(st);
144 //     syntax::Tree::iterator it = t->begin();
145 //     asserter->check(it->first.toEnum(), syntax::DatumID::LIST, "list error1");
146
147 //     it = t->in_compound_begin(it);
148 //     asserter->check(it->first.toEnum(), syntax::DatumID::SYMBOL, "not define");
149 //     ++it;
150 //     asserter->check(it->first.toEnum(), syntax::DatumID::SYMBOL, "not hoge symbol1");
151
152 //     ++it;
153 //     asserter->check(it->first.toEnum(), syntax::DatumID::LIST, "not lambda list");
154 //     syntax::Tree::iterator it2 = t->in_compound_begin(it);
155 //     asserter->check(it2->first.toEnum(), syntax::DatumID::SYMBOL, "not lambda");
156 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::LIST, "not ()");
157
158 //     syntax::Tree::iterator it3 = t->in_compound_begin(it2);
159 //     asserter->check(it3->first.toEnum(), syntax::DatumID::NIL, "not in ()");
160
161 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::LIST, "not body form");
162 //     it2 = t->in_compound_begin(it2);
163 //     asserter->check(it2->first.toEnum(), syntax::DatumID::SYMBOL, "not +");
164 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::NUMBER, "not 12");
165 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::NUMBER, "not 24");
166 //     return asserter->isOk();
167 // }
168
169 // bool parser_test3(smart_ptr<simpletest::SimpleTestAsserter> asserter)
170 // {
171 //     // ss << "(define hoge (lambda () (- 12 24)))" << endl;
172 //     std::stringstream ss;
173 //     ss << "==========" << endl;
174 //     ss << "(+ 12 24)" << endl;
175 //     ss << "==========" << endl;
176 //     ss << "(+ (- 12 \"hoge\") 24)" << endl;
177 //     ss << "==========" << endl;
178 //     ss << "((- 12 \"hoge\") '24)" << endl;
179 //     ss << "==========" << endl;
180 //     ss << ",(hoge)" << endl;
181
182 //     textarrayformat::TextArrayReader reader(ss);
183 //     smart_ptr<istream> formats(new stringstream(reader.get(3)));
184 //     smart_ptr<utakata::reader::StreamReader> st(
185 //         new utakata::reader::StreamReader(formats,
186 //                                           smart_ptr<transcoder::ITranscoder>(
187 //                                               new transcoder::UTF8Transcoder())));
188
189 //     smart_ptr<utakata::lexer::Lexer> lexer(new utakata::lexer::Lexer());
190  
191 //     utakata::parser::Parser p(lexer);
192 //     smart_ptr<syntax::Tree> t = p.parse(st);
193 //     syntax::Tree::iterator it = t->begin();
194 //     asserter->check(it->first.toEnum(), syntax::DatumID::LIST, "list error to 3");
195
196 //     syntax::Tree::iterator it2 = t->in_compound_begin(it);
197
198 //     asserter->check(it2->first.toEnum(), syntax::DatumID::ABBREVIATIONS, "not abbrev");
199 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::LIST, "not list");
200
201 //     it2 = t->in_compound_begin(it2);
202 //     asserter->check(it2->first.toEnum(), syntax::DatumID::SYMBOL, "not hoge");
203
204 //     return asserter->isOk();
205 // }
206
207 // bool parser_test4(smart_ptr<simpletest::SimpleTestAsserter> asserter)
208 // {
209 //     // ss << "(define hoge (lambda () (- 12 24)))" << endl;
210 //     std::stringstream ss;
211 //     ss << "==========" << endl;
212 //     ss << "(+ 12 24)" << endl;
213 //     ss << "==========" << endl;
214 //     ss << "(+ (- 12 \"hoge\") 24)" << endl;
215 //     ss << "==========" << endl;
216 //     ss << "((- 12 \"hoge\") '24)" << endl;
217 //     ss << "==========" << endl;
218 //     ss << "'(hoge . 10)" << endl;
219
220 //     textarrayformat::TextArrayReader reader(ss);
221 //     smart_ptr<istream> formats(new stringstream(reader.get(3)));
222 //     smart_ptr<utakata::reader::StreamReader> st(
223 //         new utakata::reader::StreamReader(formats,
224 //                                           smart_ptr<transcoder::ITranscoder>(
225 //                                               new transcoder::UTF8Transcoder())));
226
227 //     smart_ptr<utakata::lexer::Lexer> lexer(new utakata::lexer::Lexer());
228  
229 //     utakata::parser::Parser p(lexer);
230 //     smart_ptr<syntax::Tree> t = p.parse(st);
231 //     syntax::Tree::iterator it = t->begin();
232 //     asserter->check(it->first.toEnum(), syntax::DatumID::LIST, "list error");
233
234 //     syntax::Tree::iterator it2 = t->in_compound_begin(it);
235
236 //     asserter->check(it2->first.toEnum(), syntax::DatumID::ABBREVIATIONS, "not abbrev");
237 //     asserter->check((++it2)->first.toEnum(), syntax::DatumID::LIST, "not list");
238
239 //     syntax::Tree::iterator it2_end = t->in_compound_end(it2);
240 //     it2 = t->in_compound_begin(it2);
241     
242 //     asserter->check(it2->first.toEnum(), syntax::DatumID::SYMBOL, "not hoge");
243 //     ++it2;
244 //     asserter->check(it2->first.toEnum(), syntax::DatumID::NUMBER, "not number");
245 //     // この時点で末尾。リスト中かつ、末尾がnilではない場合、cdrに値が設定されているものとする。
246 //     ++it2;
247 //     asserter->check(it2 == it2_end, true, "not end");
248
249 //     return asserter->isOk();
250 // }
251
252 int main(int argc, char *argv[])
253 {
254     simpletest::SimpleTestSuite suite("parser test");
255     suite.addTester(sfcr::screate(parser_test, suite.getAsserter()));
256     // suite.addTester(sfcr::screate(parser_test2, suite.getAsserter()));
257     // suite.addTester(sfcr::screate(parser_test3, suite.getAsserter()));
258     // suite.addTester(sfcr::screate(parser_test4, suite.getAsserter()));
259     suite.run();
260     return 0;
261 }