[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter-2' - sc/inc sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Thu Sep 5 22:33:44 PDT 2013


 sc/inc/token.hxx                 |    7 ++
 sc/inc/types.hxx                 |    2 
 sc/source/core/data/types.cxx    |    7 +-
 sc/source/core/inc/interpre.hxx  |    1 
 sc/source/core/tool/interpr1.cxx |  121 ++-------------------------------------
 sc/source/core/tool/interpr4.cxx |   61 +++++++++++++++++--
 sc/source/core/tool/token.cxx    |    7 ++
 7 files changed, 85 insertions(+), 121 deletions(-)

New commits:
commit d5aaf6a40a3ca04498e35885c386f38e01f83d46
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Sep 6 01:18:26 2013 -0400

    Wrong place to apply implicit intersection. Do it at the very last.
    
    Change-Id: I4b1e9d136d45f169ad1c1efee2275bab7dfe0f49

diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index 32cdf5a..a852dd8 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -36,6 +36,12 @@
 // Matrix token constants.
 #define MATRIX_TOKEN_HAS_RANGE 1
 
+namespace sc {
+
+struct RangeMatrix;
+
+}
+
 class ScJumpMatrix;
 
 typedef ::std::vector< ScComplexRefData > ScRefList;
@@ -190,6 +196,7 @@ class ScMatrixRangeToken : public ScToken
     ScComplexRefData maRef;
 public:
     ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef );
+    ScMatrixRangeToken( const sc::RangeMatrix& rMat );
     ScMatrixRangeToken( const ScMatrixRangeToken& r );
 
     virtual sal_uInt8 GetByte() const;
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index f03ccc0..045d6b1 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -68,8 +68,10 @@ struct RangeMatrix
     ScMatrixRef mpMat;
     sal_Int32 mnCol1;
     sal_Int32 mnRow1;
+    sal_Int32 mnTab1;
     sal_Int32 mnCol2;
     sal_Int32 mnRow2;
+    sal_Int32 mnTab2;
 
     RangeMatrix();
 
diff --git a/sc/source/core/data/types.cxx b/sc/source/core/data/types.cxx
index 566d088..b45a0b1 100644
--- a/sc/source/core/data/types.cxx
+++ b/sc/source/core/data/types.cxx
@@ -12,11 +12,14 @@
 
 namespace sc {
 
-RangeMatrix::RangeMatrix() : mpMat(NULL), mnCol1(-1), mnRow1(-1), mnCol2(-1), mnRow2(-1) {}
+RangeMatrix::RangeMatrix() :
+    mpMat(NULL), mnCol1(-1), mnRow1(-1), mnTab1(-1), mnCol2(-1), mnRow2(-1), mnTab2(-1) {}
 
 bool RangeMatrix::isRangeValid() const
 {
-    return mnCol1 >= 0 && mnRow1 >= 0 && mnCol2 >= 0 && mnRow2 >= 0 && mnCol1 <= mnCol2 && mnRow1 <= mnRow2;
+    return mnCol1 >= 0 && mnRow1 >= 0 && mnTab1 >=0 &&
+        mnCol2 >= 0 && mnRow2 >= 0 && mnTab2 >= 0 &&
+        mnCol1 <= mnCol2 && mnRow1 <= mnRow2 && mnTab1 <= mnTab2;
 }
 
 }
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index bb9f919..b615b34 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -319,6 +319,7 @@ void PushExternalSingleRef(sal_uInt16 nFileId, const String& rTabName,
 void PushExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName,
                            SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                            SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
+void PushMatrix( const sc::RangeMatrix& rMat );
 void PushMatrix(const ScMatrixRef& pMat);
 void PushError( sal_uInt16 nError );
 /// Raw stack type without default replacements.
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index fd1d224..8708e7b 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1195,8 +1195,10 @@ sc::RangeMatrix ScInterpreter::CompareMat( ScCompareOptions* pOptions )
 
             aRes.mnCol1 = aMat[i].mnCol1;
             aRes.mnRow1 = aMat[i].mnRow1;
+            aRes.mnTab1 = aMat[i].mnTab1;
             aRes.mnCol2 = aMat[i].mnCol2;
             aRes.mnRow2 = aMat[i].mnRow2;
+            aRes.mnTab2 = aMat[i].mnTab2;
 
             for (SCSIZE j = 0; j < nC; ++j)
             {
@@ -1270,29 +1272,6 @@ ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions&
     return pResultMatrix;
 }
 
-namespace {
-
-double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos)
-{
-    if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2)
-    {
-        SCROW nOffset = rPos.Row() - rMat.mnRow1;
-        return rMat.mpMat->GetDouble(0, nOffset);
-    }
-
-    if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2)
-    {
-        SCROW nOffset = rPos.Col() - rMat.mnCol1;
-        return rMat.mpMat->GetDouble(nOffset, 0);
-    }
-
-    double fVal;
-    rtl::math::setNan(&fVal);
-    return fVal;
-}
-
-}
-
 void ScInterpreter::ScEqual()
 {
     if ( GetStackType(1) == svMatrix || GetStackType(2) == svMatrix )
@@ -1304,22 +1283,8 @@ void ScInterpreter::ScEqual()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal == 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareEqual();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() == 0 );
@@ -1337,22 +1302,8 @@ void ScInterpreter::ScNotEqual()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal != 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareNotEqual();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() != 0 );
@@ -1370,22 +1321,8 @@ void ScInterpreter::ScLess()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal < 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareLess();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() < 0 );
@@ -1403,22 +1340,8 @@ void ScInterpreter::ScGreater()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal > 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareGreater();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() > 0 );
@@ -1436,22 +1359,8 @@ void ScInterpreter::ScLessEqual()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal <= 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareLessEqual();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() <= 0 );
@@ -1469,22 +1378,8 @@ void ScInterpreter::ScGreaterEqual()
             return;
         }
 
-        if (aMat.isRangeValid())
-        {
-            // This matrix represents a range reference. Apply implicit intersection.
-            double fVal = applyImplicitIntersection(aMat, aPos);
-            if (rtl::math::isNan(fVal))
-            {
-                PushError(errCellNoValue);
-                return;
-            }
-
-            PushInt(fVal >= 0.0);
-            return;
-        }
-
         aMat.mpMat->CompareGreaterEqual();
-        PushMatrix(aMat.mpMat);
+        PushMatrix(aMat);
     }
     else
         PushInt( Compare() >= 0 );
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 7beb580..7288613 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1817,8 +1817,10 @@ sc::RangeMatrix ScInterpreter::PopRangeMatrix()
                         {
                             aRet.mnCol1 = rRef.Ref1.Col();
                             aRet.mnRow1 = rRef.Ref1.Row();
+                            aRet.mnTab1 = rRef.Ref1.Tab();
                             aRet.mnCol2 = rRef.Ref2.Col();
                             aRet.mnRow2 = rRef.Ref2.Row();
+                            aRet.mnTab2 = rRef.Ref2.Tab();
                         }
                     }
                 }
@@ -1953,6 +1955,19 @@ void ScInterpreter::PushExternalDoubleRef(
     }
 }
 
+void ScInterpreter::PushMatrix( const sc::RangeMatrix& rMat )
+{
+    if (!rMat.isRangeValid())
+    {
+        // Just push the matrix part only.
+        PushMatrix(rMat.mpMat);
+        return;
+    }
+
+    rMat.mpMat->SetErrorInterpreter(NULL);
+    nGlobalError = 0;
+    PushTempTokenWithoutError(new ScMatrixRangeToken(rMat));
+}
 
 void ScInterpreter::PushMatrix(const ScMatrixRef& pMat)
 {
@@ -3735,6 +3750,28 @@ void ScInterpreter::GlobalExit()
     DELETEZ(pGlobalStack);
 }
 
+namespace {
+
+double applyImplicitIntersection(const sc::RangeMatrix& rMat, const ScAddress& rPos)
+{
+    if (rMat.mnRow1 <= rPos.Row() && rPos.Row() <= rMat.mnRow2 && rMat.mnCol1 == rMat.mnCol2)
+    {
+        SCROW nOffset = rPos.Row() - rMat.mnRow1;
+        return rMat.mpMat->GetDouble(0, nOffset);
+    }
+
+    if (rMat.mnCol1 <= rPos.Col() && rPos.Col() <= rMat.mnCol2 && rMat.mnRow1 == rMat.mnRow2)
+    {
+        SCROW nOffset = rPos.Col() - rMat.mnCol1;
+        return rMat.mpMat->GetDouble(nOffset, 0);
+    }
+
+    double fVal;
+    rtl::math::setNan(&fVal);
+    return fVal;
+}
+
+}
 
 StackVar ScInterpreter::Interpret()
 {
@@ -4315,17 +4352,29 @@ StackVar ScInterpreter::Interpret()
                 }
                 break;
                 case svExternalDoubleRef:
-                case svMatrix :
                 {
                     ScMatrixRef xMat;
-                    if (pCur->GetType() == svMatrix)
-                        xMat = PopMatrix();
-                    else
-                        PopExternalDoubleRef(xMat);
-
+                    PopExternalDoubleRef(xMat);
                     QueryMatrixType(xMat, nRetTypeExpr, nRetIndexExpr);
                 }
                 break;
+                case svMatrix :
+                {
+                    sc::RangeMatrix aMat = PopRangeMatrix();
+                    if (aMat.isRangeValid())
+                    {
+                        // This matrix represents a range reference. Apply implicit intersection.
+                        double fVal = applyImplicitIntersection(aMat, aPos);
+                        if (rtl::math::isNan(fVal))
+                            PushError(errCellNoValue);
+                        else
+                            PushInt(fVal);
+                    }
+                    else
+                        // This is a normal matrix.
+                        QueryMatrixType(aMat.mpMat, nRetTypeExpr, nRetIndexExpr);
+                }
+                break;
                 case svExternalSingleRef:
                 {
                     ScExternalRefCache::TokenRef pToken;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 9f5a7e6..08455f5 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -38,6 +38,7 @@
 #include "externalrefmgr.hxx"
 #include "document.hxx"
 #include "refupdatecontext.hxx"
+#include "types.hxx"
 
 using ::std::vector;
 
@@ -807,6 +808,12 @@ bool ScMatrixToken::operator==( const FormulaToken& r ) const
 ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRef& p, const ScComplexRefData& rRef ) :
     ScToken(formula::svMatrix), mpMatrix(p), maRef(rRef) {}
 
+ScMatrixRangeToken::ScMatrixRangeToken( const sc::RangeMatrix& rMat ) :
+    ScToken(formula::svMatrix), mpMatrix(rMat.mpMat)
+{
+    maRef.InitRange(rMat.mnCol1, rMat.mnRow1, rMat.mnTab1, rMat.mnCol2, rMat.mnRow2, rMat.mnTab2);
+}
+
 ScMatrixRangeToken::ScMatrixRangeToken( const ScMatrixRangeToken& r ) :
     ScToken(r), mpMatrix(r.mpMatrix), maRef(r.maRef) {}
 


More information about the Libreoffice-commits mailing list