{
HandlerData data(gc);
data.status.push(PS_INIT);
-
- while(true) {
+
+ while(!data.status.empty()) {
if(data.status.top() != PS_ERROR)
{
- data.lexm = lexer_->lex(strm);
+ if (data.chain)
+ {
+ data.chain = false;
+ }
+ else
+ {
+ data.lexm = lexer_->lex(strm);
+ }
+
if(data.lexm.isNull() ||
data.lexm->getID() == lexeme::LexemeID::eos)
{
}
// stackのtopにはmainが殘ったままなので、data.stackのtopを追加してやる。
-
smart_ptr<data::Object> ret(new data::Object(data.stack.top()));
return ret;
}
{
// 開き括弧である場合、compoundsに新しくpushして返る。
data.compounds.push(std::vector<data::Object>());
-// data.stack.push(data::Object(false,
-// data.gc.add(util::makeCons())));
data.status.push(PS_LIST);
}
else if(data.lexm->getID() == lexeme::LexemeID::string ||
data.lexm->getID() == lexeme::LexemeID::boolean)
{
// それぞれの場合、単純にstackに各オブジェクトをpushする。
- data.stack.push(
- data::Object(false,
- data.gc.add(makePrimitiveFromLexeme(data.lexm))));
+
+ data::Object o = data::Object(false,
+ data.gc.add(makePrimitiveFromLexeme(data.lexm)));
+ if (data.compounds.empty())
+ {
+ data.stack.push(o);
+ }
+ else
+ {
+ data.compounds.top().push_back(o);
+ }
}
else if(isAbbrev(data.lexm))
{
bool ListHandler::exec_(HandlerData& data)
{
// list の開始部分である場合。
- data.status.pop();
if(data.lexm->getID() == lexeme::LexemeID::openParenthesis)
{
// 更にcompoundsに追加して積む。
data.compounds.push(std::vector<data::Object>());
-// data.stack.push(data::Object(false,
-// data.gc.add(util::makeCons())));
data.status.push(PS_LIST);
}
else if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
data.status.pop();
if(data.lexm->getID() == lexeme::LexemeID::closeParenthesis)
{
- // topに積んであるものを、topの一段下にあるConsの末尾に追加する。
- // 追加とは言っても、実際にはcdrに直接設定するため、ちょっとだけ意味が違う。
- data::Object tmp = data.stack.top(); data.stack.pop();
- data::Object obj = util::getLastCons(data.stack.top());
- data::DataCastor<interpreter::primitive::Cons>()(obj)->setCdr(tmp);
+ // stackの頂点とcompoundsのトップを取得する。
+<<<<<<< HEAD
+=======
+ data::Object t = data.stack.top(); data.stack.pop();
+>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d
+ std::vector<data::Object> v = data.compounds.top(); data.compounds.pop();
+ // vectorをConsへと変換するには、次のようにして後ろからやっていく
+ // 方式が一番面倒がない。
+ // 1. cdrをstackのtop、carをvectorの末尾であるデータとしたconsを作成する。
+ // 2. vectorの次のデータをcar、前のconsをcdrとしたconsを作成する。
+ // 3. 先頭まで続ける。
+
+<<<<<<< HEAD
+=======
+ //
+>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d
+ {
+ // 後ろから前に向かっていく。
+ std::vector<data::Object>::reverse_iterator begin = v.rbegin(),
+ end = v.rend();
+ // ちょっと面倒すぎるなこれ。
+<<<<<<< HEAD
+ // cdrにcompoundsの末尾を、carにその前を設定する。
+ data::Object o = data::Object(
+ false, data.gc.add(
+ util::makeCons(begin[1], begin[0]))
+ );
+ begin += 2;
+=======
+ data::Object o = data::Object(
+ false, data.gc.add(
+ util::makeCons(*begin, o))
+ );
+ ++begin;
+>>>>>>> 6403bdd4479dc5a3e6ca42aa2dc9b0dc4d6bf71d
+ for (; begin != end; ++begin)
+ {
+ // 順次oに再設定していく。
+ o = data::Object(
+ false, data.gc.add(
+ util::makeCons(*begin, o)));
+ }
+
+ if (!data.compounds.empty())
+ {
+ data.compounds.top().push_back(o);
+ }
+ else
+ {
+ data.stack.push(o);
+ }
+ }
// ここまでは、すべてDataSpace内部のDataEntityを対象に処理しているため、
// Objectで正しく受け渡しができていれば問題は発生しない。
else
{
// まだcompoundsが存在している場合には、これを返すようにする。
+ data::Object c = data::Object(
+ false, data.gc.add(util::makeCons(
+ v[1],
+ data::Object(false, data.gc.add(util::makeNil()))
+ )));
data::Object o =
data::Object(false,
- data.gc.add(util::makeCons(v[0], v[1])));
+ data.gc.add(util::makeCons(v[0], c)));
if (!data.compounds.empty())
{
data.compounds.top().push_back(o);
}
data.status.pop();
+ data.chain = true;
return true;
}