OSDN Git Service

マージ。
[simplecms/utakata.git] / parser.cpp
index e9fff01..f639079 100755 (executable)
@@ -72,12 +72,20 @@ smart_ptr<data::Object> parser::Parser::parse(smart_ptr<reader::StreamReader>& s
 {
     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)
             {
@@ -94,7 +102,6 @@ smart_ptr<data::Object> parser::Parser::parse(smart_ptr<reader::StreamReader>& s
     }
 
     // stackのtopにはmainが殘ったままなので、data.stackのtopを追加してやる。
-
     smart_ptr<data::Object> ret(new data::Object(data.stack.top()));
     return ret;
 }
@@ -172,8 +179,6 @@ bool InitHandler::exec_(HandlerData& data)
     {
         // 開き括弧である場合、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 ||
@@ -183,9 +188,17 @@ bool InitHandler::exec_(HandlerData& data)
             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))
     {
@@ -214,13 +227,10 @@ bool InitHandler::exec_(HandlerData& data)
 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)
@@ -339,11 +349,58 @@ bool DotEndHandler::exec_(HandlerData& data)
     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で正しく受け渡しができていれば問題は発生しない。
@@ -375,9 +432,14 @@ bool AbbrevHandler::exec_(HandlerData& data)
     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);
@@ -389,6 +451,7 @@ bool AbbrevHandler::exec_(HandlerData& data)
     }
 
     data.status.pop();
+    data.chain = true;
 
     return true;
 }