compute.cpp

Go to the documentation of this file.
00001 
00023 #include <cmath>
00024 #include <iostream>
00025 #include <vector>
00026 
00027 #include "popassert.h"
00028 #include "CVector3f.h"
00029 #include "compute.h"
00030 
00031 
00032 
00033 
00034 
00035 /*****************************************\
00036  *                                       *
00037  *  Beginning of the creator functions.  *
00038  *                                       *
00039 \*****************************************/
00040 
00041 
00048 CValue* CValue::GetNewAddition(CValue* pLeftOperand, CValue* pRightOperand)
00049 {
00050   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00051   POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00052 
00053   float Number1, Number2;
00054   if (pLeftOperand->IsConstant(&Number1) &&
00055       pRightOperand->IsConstant(&Number2))
00056     {
00057       Number1 += Number2;
00058       delete pLeftOperand;
00059       delete pRightOperand;
00060       return new CNumber(Number1);
00061     }
00062 
00063   // One bit for left value and the other one for right value
00064   switch ( (pLeftOperand->IsAddNeutralElem() << 1) +
00065            (pRightOperand->IsAddNeutralElem() << 0) )
00066     {
00067     case ( (0 << 1) + (0 << 0) ):
00068       return (new CAddition(pLeftOperand, pRightOperand));
00069       break;
00070     case ( (1 << 1) + (0 << 0) ):
00071       delete pLeftOperand;
00072       return pRightOperand;
00073       break;
00074     case ( (0 << 1) + (1 << 0) ):
00075       delete pRightOperand;
00076       return pLeftOperand;
00077       break;
00078     default:
00079       // Should not happen
00080       POP_ILLEGAL("Should not get here");
00081       return NULL;
00082       break;
00083     }
00084 }
00085 
00086 
00093 CValue* CValue::GetNewSubstraction(CValue* pLeftOperand, CValue* pRightOperand)
00094 {
00095   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00096   POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00097 
00098   float Number1, Number2;
00099   if (pLeftOperand->IsConstant(&Number1) &&
00100       pRightOperand->IsConstant(&Number2))
00101     {
00102       Number1 -= Number2;
00103       delete pLeftOperand;
00104       delete pRightOperand;
00105       return (new CNumber(Number1));
00106     }
00107 
00108   // One bit for left value and the other one for right value
00109   switch ( (pLeftOperand->IsAddNeutralElem() << 1) +
00110            (pRightOperand->IsAddNeutralElem() << 0) )
00111     {
00112     case ( (0 << 1) + (0 << 0) ):
00113       return (new CSubstraction(pLeftOperand, pRightOperand));
00114       break;
00115     case ( (1 << 1) + (0 << 0) ):
00116       delete pLeftOperand;
00117       return (new COpposite(pRightOperand));
00118       break;
00119     case ( (0 << 1) + (1 << 0) ):
00120       delete pRightOperand;
00121       return pLeftOperand;
00122       break;
00123     default:
00124       // Should not happen
00125       POP_ILLEGAL("Should not get here");
00126       return NULL;
00127       break;
00128     }
00129 }
00130 
00131 
00138 CValue* CValue::GetNewProduct(CValue* pLeftOperand, CValue* pRightOperand)
00139 {
00140   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00141   POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00142 
00143   float Number1, Number2;
00144   if (pLeftOperand->IsConstant(&Number1)
00145       && pRightOperand->IsConstant(&Number2))
00146     {
00147       Number1 *= Number2;
00148       delete pLeftOperand;
00149       delete pRightOperand;
00150       return (new CNumber(Number1));
00151     }
00152 
00153   // One bit for left value and the other one for right value
00154   switch ( (pLeftOperand->IsConstant() << 1) +
00155            (pRightOperand->IsConstant() << 0) )
00156     {
00157     case ( (0 << 1) + (0 << 1) ):
00158       return (new CProduct(pLeftOperand, pRightOperand));
00159       break;
00160     case ( (1 << 1) + (0 << 0) ):
00161       if ( pLeftOperand->IsMultAbsorbElem() )
00162         {
00163           delete pLeftOperand;
00164           delete pRightOperand;
00165           return (new CNumber(0));
00166         }
00167       else if (pLeftOperand->IsMultNeutralElem())
00168         {
00169           delete pLeftOperand;
00170           return pRightOperand;
00171         }
00172       else
00173         {
00174           return (new CProduct(pLeftOperand, pRightOperand));
00175         }
00176       break;
00177     case ( (0 << 1) + (1 << 0) ):
00178       if ( pRightOperand->IsMultAbsorbElem() )
00179         {
00180           delete pLeftOperand;
00181           delete pRightOperand;
00182           return (new CNumber(0));
00183         }
00184       else if (pRightOperand->IsMultNeutralElem())
00185         {
00186           delete pRightOperand;
00187           return pLeftOperand;
00188         }
00189       else
00190         {
00191           return (new CProduct(pLeftOperand, pRightOperand));
00192         }
00193       break;
00194     default:
00195       // Should not happen
00196       POP_ILLEGAL("Should not get here");
00197       return NULL;
00198       break;
00199     }
00200 }
00201 
00202 
00209 CValue* CValue::GetNewDivision(CValue* pLeftOperand, CValue* pRightOperand)
00210 {
00211   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00212   POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00213 
00214   float Number1, Number2;
00215   if (pLeftOperand->IsConstant(&Number1) &&
00216       pRightOperand->IsConstant(&Number2))
00217     {
00218       if (Number2 == 0)
00219         throw;
00220 
00221       Number1 /= Number2;
00222       delete pLeftOperand;
00223       delete pRightOperand;
00224       return (new CNumber(Number1));
00225     }
00226 
00227   // One bit for left value and the other one for right value
00228   switch ( (pLeftOperand->IsConstant() << 1) +
00229            (pRightOperand->IsConstant() << 0) )
00230     {
00231     case ( (0 << 1) + (0 << 1) ):
00232       return (new CDivision(pLeftOperand, pRightOperand));
00233       break;
00234     case ( (1 << 1) + (0 << 0) ):
00235       if ( pLeftOperand->IsMultAbsorbElem() )
00236         {
00237           delete pLeftOperand;
00238           delete pRightOperand;
00239           return (new CNumber(0));
00240         }
00241       else
00242         {
00243           return (new CDivision(pLeftOperand, pRightOperand));
00244         }
00245       break;
00246     case ( (0 << 1) + (1 << 0) ):
00247       if ( pRightOperand->IsMultAbsorbElem() )
00248         {
00249           throw;
00250         }
00251       else if (pRightOperand->IsMultNeutralElem())
00252         {
00253           delete pRightOperand;
00254           return pLeftOperand;
00255         }
00256       else
00257         {
00258           return (new CDivision(pLeftOperand, pRightOperand));
00259         }
00260       break;
00261     default:
00262       // Should not happen
00263       POP_ILLEGAL("Should not get here");
00264       return NULL;
00265       break;
00266     }
00267 }
00268 
00269 
00276 CValue* CValue::GetNewOpposite(CValue* pLeftOperand)
00277 {
00278   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00279 
00280   float Number;
00281   if (pLeftOperand->IsConstant(&Number))
00282     {
00283       delete pLeftOperand;
00284       return (new CNumber(-Number));
00285     }
00286   else
00287     {
00288       return (new COpposite(pLeftOperand) );
00289     }
00290 }
00291 
00298 CValue* CValue::GetNewSqrt(CValue* pLeftOperand)
00299 {
00300   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00301 
00302   float Number;
00303   if (pLeftOperand->IsConstant(&Number))
00304     {
00305       delete pLeftOperand;
00306 
00307       if (Number < 0)
00308         throw;
00309 
00310       return (new CNumber(sqrtf(Number)));
00311     }
00312   else
00313     {
00314       return (new CSqrt(pLeftOperand));
00315     }
00316 }
00317 
00324 CValue* CValue::GetNewSin(CValue* pLeftOperand)
00325 {
00326   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00327 
00328   float Number;
00329   if (pLeftOperand->IsConstant(&Number))
00330     {
00331       delete pLeftOperand;
00332       return (new CNumber(sinf(Number)));
00333     }
00334   else
00335     {
00336       return (new CSin(pLeftOperand) );
00337     }
00338 }
00339 
00346 CValue* CValue::GetNewCos(CValue* pLeftOperand)
00347 {
00348   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00349 
00350   float Number;
00351   if (pLeftOperand->IsConstant(&Number))
00352     {
00353       delete pLeftOperand;
00354       return (new CNumber(cosf(Number)));
00355     }
00356   else
00357     {
00358       return (new CCos(pLeftOperand) );
00359     }
00360 }
00361 
00368 CValue* CValue::GetNewTan(CValue* pLeftOperand)
00369 {
00370   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00371 
00372   float Number;
00373   if (pLeftOperand->IsConstant(&Number))
00374     {
00375       delete pLeftOperand;
00376       return (new CNumber(tanf(Number)));
00377     }
00378   else
00379     {
00380       return (new CTan(pLeftOperand) );
00381     }
00382 }
00383 
00390 CValue* CValue::GetNewExp(CValue* pLeftOperand)
00391 {
00392   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00393 
00394   float Number;
00395   if (pLeftOperand->IsConstant(&Number))
00396     {
00397       delete pLeftOperand;
00398       return (new CNumber(expf(Number)));
00399     }
00400   else
00401     {
00402       return (new CExp(pLeftOperand) );
00403     }
00404 }
00405 
00412 CValue* CValue::GetNewLn(CValue* pLeftOperand)
00413 {
00414   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00415 
00416   float Number;
00417   if (pLeftOperand->IsConstant(&Number))
00418     {
00419       delete pLeftOperand;
00420       return (new CNumber(logf(Number)));
00421     }
00422   else
00423     {
00424       return (new CLn(pLeftOperand) );
00425     }
00426 }
00427 
00434 CValue* CValue::GetNewPow(CValue* pLeftOperand, CValue* pRightOperand)
00435 {
00436   POP_ASSERT(pLeftOperand != NULL, "Using a NULL pointer");
00437   POP_ASSERT(pRightOperand != NULL, "Using a NULL pointer");
00438 
00439   float Number1, Number2;
00440   if (pLeftOperand->IsConstant(&Number1) &&
00441       pRightOperand->IsConstant(&Number2))
00442     {
00443       if (Number1 == 0 && Number2 == 0)
00444         {
00445           throw;
00446         }
00447 
00448       Number1 = pow(Number1, Number2);
00449       delete pLeftOperand;
00450       delete pRightOperand;
00451       // Check for NaN
00452       if ( Number1 == Number1 )
00453         {
00454           return (new CNumber(Number1));
00455         }
00456       else
00457         {
00458           throw;
00459           return NULL;
00460         }
00461     }
00462 
00463   // One bit for left value and the other one for right value
00464   switch ( (pLeftOperand->IsConstant() << 1) +
00465            (pRightOperand->IsConstant() << 0) )
00466     {
00467     case ( (0 << 1) + (0 << 1) ):
00468       return (new CPow(pLeftOperand, pRightOperand));
00469       break;
00470     case ( (1 << 1) + (0 << 0) ):
00471       if ( pLeftOperand->IsMultAbsorbElem() )
00472         {
00473           delete pLeftOperand;
00474           delete pRightOperand;
00475           return new CNumber(0);
00476         }
00477       else if ( pLeftOperand->IsMultNeutralElem() )
00478         {
00479           delete pLeftOperand;
00480           delete pRightOperand;
00481           return (new CNumber(1));
00482         }
00483       else
00484         {
00485           return (new CPow(pLeftOperand, pRightOperand));
00486         }
00487       break;
00488     case ( (0 << 1) + (1 << 0) ):
00489       if ( pRightOperand->IsMultAbsorbElem() )
00490         {
00491           delete pRightOperand;
00492           return pLeftOperand;
00493           return (new CNumber(1));
00494         }
00495       else if ( pRightOperand->IsMultNeutralElem() )
00496         {
00497           delete pRightOperand;
00498           return (pLeftOperand);
00499         }
00500       else
00501         {
00502           return (new CPow(pLeftOperand, pRightOperand));
00503         }
00504       break;
00505     default:
00506       // Should not happen
00507       POP_ILLEGAL("Should not get here");
00508       return NULL;
00509       break;
00510     }
00511 }
00512 
00513 
00514 
00515 
00516 
00517 /***********************************\
00518  *                                 *
00519  *  Beginning of the constructors  *
00520  *                                 *
00521 \***********************************/
00522 
00526 CAddition::CAddition(CValue* pLeftOperand, CValue* pRightOperand)
00527   : COperation(pLeftOperand, pRightOperand)
00528 {
00529 }
00530 
00534 CSubstraction::CSubstraction(CValue* pLeftOperand, CValue* pRightOperand)
00535   : COperation(pLeftOperand, pRightOperand)
00536 {
00537 }
00538 
00542 CProduct::CProduct(CValue* pLeftOperand, CValue* pRightOperand)
00543   : COperation(pLeftOperand, pRightOperand)
00544 {
00545 }
00546 
00550 CDivision::CDivision(CValue* pLeftOperand, CValue* pRightOperand)
00551   : COperation(pLeftOperand, pRightOperand)
00552 {
00553 }
00554 
00558 COpposite::COpposite(CValue* pLeftOperand)
00559   : COperation(pLeftOperand, NULL)
00560 {
00561 }
00562 
00566 CSqrt::CSqrt(CValue* pLeftOperand)
00567   : COperation(pLeftOperand, NULL)
00568 {
00569 }
00570 
00574 CSin::CSin(CValue* pLeftOperand)
00575   : COperation(pLeftOperand, NULL)
00576 {
00577 }
00578 
00582 CCos::CCos(CValue* pLeftOperand)
00583   : COperation(pLeftOperand, NULL)
00584 {
00585 }
00586 
00590 CTan::CTan(CValue* pLeftOperand)
00591   : COperation(pLeftOperand, NULL)
00592 {
00593 }
00594 
00598 CExp::CExp(CValue* pLeftOperand)
00599   : COperation(pLeftOperand, NULL)
00600 {
00601 }
00602 
00606 CLn::CLn(CValue* pLeftOperand)
00607   : COperation(pLeftOperand, NULL)
00608 {
00609 }
00610 
00614 CPow::CPow(CValue* pLeftOperand, CValue* pRightOperand)
00615   : COperation(pLeftOperand, pRightOperand)
00616 {
00617 }
00618 
00622 CVariable::CVariable(TYPE_VARIABLE Type)
00623 {
00624   m_Type = Type;
00625 }
00626 
00630 CNumber::CNumber(float Number)
00631 {
00632   m_Number = Number;
00633 }
00634 
00635 
00636 
00637 
00638 /******************************************\
00639  *                                        *
00640  *  Beginning of the GetCopy() functions  *
00641  *                                        *
00642 \******************************************/
00643 
00648 CValue* CAddition::GetCopy() const
00649 {
00650   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00651   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00652 
00653   return new CAddition(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00654 }
00655 
00660 CValue* CSubstraction::GetCopy() const
00661 {
00662   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00663   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00664 
00665   return new CSubstraction(m_pLeftOperand->GetCopy(),
00666                            m_pRightOperand->GetCopy());
00667 }
00668 
00673 CValue* CProduct::GetCopy() const
00674 {
00675   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00676   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00677 
00678   return new CProduct(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00679 }
00680 
00685 CValue* CDivision::GetCopy() const
00686 {
00687   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00688   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00689 
00690   return new CDivision(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00691 }
00692 
00697 CValue* COpposite::GetCopy() const
00698 {
00699   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00700 
00701   return new COpposite(m_pLeftOperand->GetCopy());
00702 }
00703 
00708 CValue* CSqrt::GetCopy() const
00709 {
00710   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00711 
00712   return new CSqrt(m_pLeftOperand->GetCopy());
00713 }
00714 
00719 CValue* CSin::GetCopy() const
00720 {
00721   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00722 
00723   return new CSin(m_pLeftOperand->GetCopy());
00724 }
00725 
00730 CValue* CCos::GetCopy() const
00731 {
00732   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00733 
00734   return new CCos(m_pLeftOperand->GetCopy());
00735 }
00736 
00741 CValue* CTan::GetCopy() const
00742 {
00743   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00744 
00745   return new CTan(m_pLeftOperand->GetCopy());
00746 }
00747 
00752 CValue* CExp::GetCopy() const
00753 {
00754   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00755 
00756   return new CExp(m_pLeftOperand->GetCopy());
00757 }
00758 
00763 CValue* CLn::GetCopy() const
00764 {
00765   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00766 
00767   return new CLn(m_pLeftOperand->GetCopy());
00768 }
00769 
00774 CValue* CPow::GetCopy() const
00775 {
00776   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00777   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00778 
00779   return new CPow(m_pLeftOperand->GetCopy(), m_pRightOperand->GetCopy());
00780 }
00781 
00785 CValue* CVariable::GetCopy() const
00786 {
00787   return new CVariable(m_Type);
00788 }
00789 
00793 CValue* CNumber::GetCopy() const
00794 {
00795   return new CNumber(m_Number);
00796 }
00797 
00798 
00799 
00800 
00801 /******************************************\
00802  *                                        *
00803  *  Beginning of the Compute() functions  *
00804  *                                        *
00805 \******************************************/
00806 
00810 float CAddition::Compute(const CVector3f& Point) const
00811 {
00812   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00813   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00814 
00815   return (m_pLeftOperand->Compute(Point) + m_pRightOperand->Compute(Point));
00816 }
00817 
00821 float CSubstraction::Compute(const CVector3f& Point) const
00822 {
00823   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00824   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00825 
00826   return (m_pLeftOperand->Compute(Point) - m_pRightOperand->Compute(Point));
00827 }
00828 
00832 float CProduct::Compute(const CVector3f& Point) const
00833 {
00834   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00835   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00836 
00837   return (m_pLeftOperand->Compute(Point) * m_pRightOperand->Compute(Point));
00838 }
00839 
00843 float CDivision::Compute(const CVector3f& Point) const
00844 {
00845   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00846   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00847 
00848   return (m_pLeftOperand->Compute(Point) / m_pRightOperand->Compute(Point));
00849 }
00850 
00854 float COpposite::Compute(const CVector3f& Point) const
00855 {
00856   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00857 
00858   return (-(m_pLeftOperand->Compute(Point)));
00859 }
00860 
00864 float CSqrt::Compute(const CVector3f& Point) const
00865 {
00866   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00867 
00868   return (sqrtf(m_pLeftOperand->Compute(Point)));
00869 }
00870 
00874 float CSin::Compute(const CVector3f& Point) const
00875 {
00876   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00877 
00878   return (sinf(m_pLeftOperand->Compute(Point)));
00879 }
00880 
00884 float CCos::Compute(const CVector3f& Point) const
00885 {
00886   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00887 
00888   return (cosf(m_pLeftOperand->Compute(Point)));
00889 }
00890 
00894 float CTan::Compute(const CVector3f& Point) const
00895 {
00896   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00897 
00898   return (tanf(m_pLeftOperand->Compute(Point)));
00899 }
00900 
00904 float CExp::Compute(const CVector3f& Point) const
00905 {
00906   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00907 
00908   return (expf(m_pLeftOperand->Compute(Point)));
00909 }
00910 
00914 float CLn::Compute(const CVector3f& Point) const
00915 {
00916   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00917 
00918   return (logf(m_pLeftOperand->Compute(Point)));
00919 }
00920 
00924 float CPow::Compute(const CVector3f& Point) const
00925 {
00926   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00927   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00928 
00929   return (powf(m_pLeftOperand->Compute(Point), m_pRightOperand->Compute(Point)));
00930 }
00931 
00936 float CVariable::Compute(const CVector3f& Point) const
00937 {
00938   switch (m_Type)
00939     {
00940     case (TYPE_X): return Point.x; break;
00941     case (TYPE_Y): return Point.y; break;
00942     case (TYPE_Z): return Point.z; break;
00943     default: POP_ILLEGAL("Should not get here"); return 0; break;
00944     }
00945 }
00946 
00950 float CNumber::Compute(const CVector3f& Point) const
00951 {
00952   return m_Number;
00953 }
00954 
00955 
00956 
00957 
00958 
00959 /*****************************************\
00960  *                                       *
00961  *  Beginning of the Derive() functions  *
00962  *                                       *
00963 \*****************************************/
00964 
00971 CValue* CAddition::Derive(TYPE_VARIABLE Type) const
00972 {
00973   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00974   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00975 
00976   return GetNewAddition(m_pLeftOperand->Derive(Type),
00977                         m_pRightOperand->Derive(Type));
00978 }
00979 
00986 CValue* CSubstraction::Derive(TYPE_VARIABLE Type) const
00987 {
00988   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
00989   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
00990 
00991   return GetNewSubstraction(m_pLeftOperand->Derive(Type),
00992                             m_pRightOperand->Derive(Type));
00993 }
00994 
01001 CValue* CProduct::Derive(TYPE_VARIABLE Type) const
01002 {
01003   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01004   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01005 
01006   return GetNewAddition(GetNewProduct(m_pLeftOperand->Derive(Type),
01007                                       m_pRightOperand->GetCopy()),
01008                         GetNewProduct(m_pLeftOperand->GetCopy(),
01009                                       m_pRightOperand->Derive(Type)));
01010 }
01011 
01019 CValue* CDivision::Derive(TYPE_VARIABLE Type) const
01020 {
01021   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01022   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01023 
01024   CValue* Numerator =
01025     GetNewSubstraction(
01026                        GetNewProduct(m_pLeftOperand->Derive(Type),
01027                                      m_pRightOperand->GetCopy()),
01028                        GetNewProduct(m_pLeftOperand->GetCopy(),
01029                                      m_pRightOperand->Derive(Type))
01030                        );
01031 
01032   CValue* Denominator = GetNewPow(m_pRightOperand->GetCopy(), new CNumber(2));
01033 
01034   return GetNewDivision(Numerator, Denominator);
01035 }
01036 
01044 CValue* COpposite::Derive(TYPE_VARIABLE Type) const
01045 {
01046   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01047 
01048   return GetNewOpposite(m_pLeftOperand->Derive(Type));
01049 }
01050 
01058 CValue* CSqrt::Derive(TYPE_VARIABLE Type) const
01059 {
01060   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01061 
01062   return GetNewDivision( m_pLeftOperand->Derive(Type),
01063                          GetNewProduct(new CNumber(2),
01064                                        GetNewSqrt(m_pLeftOperand->GetCopy())));
01065 }
01066 
01073 CValue* CSin::Derive(TYPE_VARIABLE Type) const
01074 {
01075   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01076 
01077   return GetNewProduct(GetNewCos(m_pLeftOperand->GetCopy()),
01078                        m_pLeftOperand->Derive(Type));
01079 }
01080 
01087 CValue* CCos::Derive(TYPE_VARIABLE Type) const
01088 {
01089   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01090 
01091   return GetNewProduct(GetNewOpposite(GetNewSin(m_pLeftOperand->GetCopy())),
01092                        m_pLeftOperand->Derive(Type));
01093 }
01094 
01103 CValue* CTan::Derive(TYPE_VARIABLE Type) const
01104 {
01105   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01106 
01107   return GetNewDivision(m_pLeftOperand->Derive(Type),
01108                         GetNewPow(GetNewCos(m_pLeftOperand->GetCopy()),
01109                                   new CNumber(2)));
01110 }
01111 
01118 CValue* CExp::Derive(TYPE_VARIABLE Type) const
01119 {
01120   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01121 
01122   return GetNewProduct(GetNewExp(m_pLeftOperand->GetCopy()),
01123                        m_pLeftOperand->Derive(Type));
01124 }
01125 
01135 CValue* CPow::Derive(TYPE_VARIABLE Type) const
01136 {
01137   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01138   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01139 
01140   float Number;
01141   if (m_pRightOperand->IsConstant(&Number))
01142     {
01143       return GetNewProduct(GetNewProduct(new CNumber(Number), 
01144                                          m_pLeftOperand->Derive(Type)),
01145                            GetNewPow(m_pLeftOperand->GetCopy(),
01146                                      new CNumber(Number - 1)));
01147     }
01148   else
01149     {
01150       // Left part of the parenthesis
01151       CValue* pLeftOperand =
01152         GetNewProduct(m_pRightOperand->Derive(Type),
01153                       GetNewLn(m_pLeftOperand->GetCopy()));
01154 
01155       // Right part of the parenthesis
01156       CValue* pRightOperand =
01157         GetNewDivision(GetNewProduct(m_pRightOperand->GetCopy(),
01158                                      m_pLeftOperand->Derive(Type)),
01159                        m_pLeftOperand->GetCopy());
01160 
01161       return GetNewProduct(this->GetCopy(),
01162                            GetNewAddition(pLeftOperand, pRightOperand));
01163     }
01164 }
01165 
01173 CValue* CLn::Derive(TYPE_VARIABLE Type) const
01174 {
01175   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01176 
01177   return GetNewDivision(m_pLeftOperand->Derive(Type), m_pLeftOperand->GetCopy());
01178 }
01179 
01186 CValue* CVariable::Derive(TYPE_VARIABLE Type) const
01187 {
01188   if (Type == m_Type)
01189     return new CNumber(1);
01190   else
01191     return new CNumber(0);
01192 }
01193 
01200 CValue* CNumber::Derive(TYPE_VARIABLE Type) const
01201 {
01202   return new CNumber(0);
01203 }
01204 
01205 
01206 
01207 
01208 
01209 /****************************************\
01210  *                                      *
01211  *  Beginning of the Print() functions  *
01212  *                                      *
01213 \****************************************/
01214 
01219 void CAddition::Print(std::ostream& o) const
01220 {
01221   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01222   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01223 
01224   o << '(';
01225   m_pLeftOperand->Print(o);
01226   o << '+';
01227   m_pRightOperand->Print(o);
01228   o << ')';
01229 }
01230 
01235 void CSubstraction::Print(std::ostream& o) const
01236 {
01237   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01238   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01239 
01240   o << '(';
01241   m_pLeftOperand->Print(o);
01242   o << '-';
01243   m_pRightOperand->Print(o);
01244   o << ')';
01245 }
01246 
01251 void CProduct::Print(std::ostream& o) const
01252 {
01253   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01254   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01255 
01256   o << '(';
01257   m_pLeftOperand->Print(o);
01258   o << '*';
01259   m_pRightOperand->Print(o);
01260   o << ')';
01261 }
01262 
01267 void CDivision::Print(std::ostream& o) const
01268 {
01269   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01270   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01271 
01272   o << '(';
01273   m_pLeftOperand->Print(o);
01274   o << '/';
01275   m_pRightOperand->Print(o);
01276   o << ')';
01277 }
01278 
01283 void COpposite::Print(std::ostream& o) const
01284 {
01285   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01286 
01287   o << "(-";
01288   m_pLeftOperand->Print(o);
01289   o << ')';
01290 }
01291 
01296 void CSqrt::Print(std::ostream& o) const
01297 {
01298   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01299 
01300   o << "sqrt(";
01301   m_pLeftOperand->Print(o);
01302   o << ')';
01303 }
01304 
01309 void CSin::Print(std::ostream& o) const
01310 {
01311   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01312 
01313   o << "sin(";
01314   m_pLeftOperand->Print(o);
01315   o << ')';
01316 }
01317 
01322 void CCos::Print(std::ostream& o) const
01323 {
01324   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01325 
01326   o << "cos(";
01327   m_pLeftOperand->Print(o);
01328   o << ')';
01329 }
01330 
01335 void CTan::Print(std::ostream& o) const
01336 {
01337   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01338 
01339   o << "tan(";
01340   m_pLeftOperand->Print(o);
01341   o << ')';
01342 }
01343 
01348 void CExp::Print(std::ostream& o) const
01349 {
01350   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01351 
01352   o << "exp(";
01353   m_pLeftOperand->Print(o);
01354   o << ')';
01355 }
01356 
01361 void CLn::Print(std::ostream& o) const
01362 {
01363   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01364 
01365   o << "ln(";
01366   m_pLeftOperand->Print(o);
01367   o << ')';
01368 }
01369 
01374 void CPow::Print(std::ostream& o) const
01375 {
01376   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01377   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01378 
01379   m_pLeftOperand->Print(o);
01380   o << '^';
01381   m_pRightOperand->Print(o);
01382 }
01383 
01388 void CVariable::Print(std::ostream& o) const
01389 {
01390   switch (m_Type)
01391     {
01392     case (TYPE_X): o << 'x'; break;
01393     case (TYPE_Y): o << 'y'; break;
01394     case (TYPE_Z): o << 'z'; break;
01395     default: POP_ILLEGAL("Should not get here"); break;
01396     }
01397 }
01398 
01403 void CNumber::Print(std::ostream& o) const
01404 {
01405   o << m_Number;
01406 }
01407 
01408 
01409 
01410 
01411 
01412 inline void BEFORE_PUSH(std::vector<char>& v, int& i)
01413 {
01414   ++i;
01415 
01416   if (i > 8)
01417     {
01418       v.push_back('\xd9');
01419       v.push_back('\xf6'); // fdecstp
01420 
01421       v.push_back('\x83');
01422       v.push_back('\xec');
01423       v.push_back('\x04'); // subl   $4,%esp
01424 
01425       v.push_back('\xd9');
01426       v.push_back('\x14');
01427       v.push_back('\x24'); // fsts   (%esp)
01428 
01429       v.push_back('\xdd');
01430       v.push_back('\xc0'); // ffree  %st(0)
01431 
01432       v.push_back('\xd9');
01433       v.push_back('\xf7'); // fincstp
01434     }
01435 }
01436 
01437 inline void AFTER_POP(std::vector<char>& v, int& i)
01438 {
01439   if (i > 8)
01440     {
01441       v.push_back('\xd9');
01442       v.push_back('\x04');
01443       v.push_back('\x24'); // flds   (%esp)
01444 
01445       v.push_back('\xd9');
01446       v.push_back('\xf7'); // fincstp
01447 
01448       v.push_back('\x83');
01449       v.push_back('\xc4');
01450       v.push_back('\x04'); // addl   $4,%esp
01451     }
01452 
01453   --i;
01454 }
01455 
01456 /******************************************\
01457  *                                        *
01458  *  Beginning of the Compile() functions  *
01459  *                                        *
01460 \******************************************/
01461 
01462 void CAddition::Compile(std::vector<char>& v, int& i) const
01463 {
01464   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01465   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01466 
01467   m_pLeftOperand->Compile(v, i);
01468   m_pRightOperand->Compile(v, i);
01469 
01470   v.push_back('\xde');
01471   v.push_back('\xc1'); // faddp
01472 
01473   AFTER_POP(v, i);
01474 }
01475 
01476 
01477 void CSubstraction::Compile(std::vector<char>& v, int& i) const
01478 {
01479   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01480   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01481 
01482   m_pLeftOperand->Compile(v, i);
01483   m_pRightOperand->Compile(v, i);
01484 
01485   v.push_back('\xde');
01486   v.push_back('\xe9'); // fsubrp
01487 
01488   AFTER_POP(v, i);
01489 }
01490 
01491 void CProduct::Compile(std::vector<char>& v, int& i) const
01492 {
01493   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01494   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01495 
01496   m_pLeftOperand->Compile(v, i);
01497   m_pRightOperand->Compile(v, i);
01498 
01499   v.push_back('\xde');
01500   v.push_back('\xc9'); // fmulp
01501 
01502   AFTER_POP(v, i);
01503 }
01504 
01505 void CDivision::Compile(std::vector<char>& v, int& i) const
01506 {
01507   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01508   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01509 
01510   m_pLeftOperand->Compile(v, i);
01511   m_pRightOperand->Compile(v, i);
01512 
01513   v.push_back('\xde');
01514   v.push_back('\xf9'); // fdivrp
01515 
01516   AFTER_POP(v, i);
01517 }
01518 
01519 void COpposite::Compile(std::vector<char>& v, int& i) const
01520 {
01521   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01522 
01523   m_pLeftOperand->Compile(v, i);
01524 
01525   v.push_back('\xd9');
01526   v.push_back('\xe0'); // fdivrp
01527 }
01528 
01529 void CSqrt::Compile(std::vector<char>& v, int& i) const
01530 {
01531   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01532 
01533   m_pLeftOperand->Compile(v, i);
01534 
01535   v.push_back('\xd9');
01536   v.push_back('\xfa'); // fsqrt
01537 }
01538 
01539 void CSin::Compile(std::vector<char>& v, int& i) const
01540 {
01541   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01542 
01543   m_pLeftOperand->Compile(v, i);
01544 
01545   v.push_back('\xd9');
01546   v.push_back('\xfe'); // fsin
01547 }
01548 
01549 void CCos::Compile(std::vector<char>& v, int& i) const
01550 {
01551   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01552 
01553   m_pLeftOperand->Compile(v, i);
01554 
01555   v.push_back('\xd9');
01556   v.push_back('\xff'); // fcos
01557 }
01558 
01559 void CTan::Compile(std::vector<char>& v, int& i) const
01560 {
01561   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01562 
01563   m_pLeftOperand->Compile(v, i);
01564 
01565   BEFORE_PUSH(v, i);
01566 
01567   v.push_back('\xd9');
01568   v.push_back('\xf2'); // fptan
01569 
01570   v.push_back('\xdd');
01571   v.push_back('\xc0'); // ffree  %st(0)
01572 
01573   v.push_back('\xd9');
01574   v.push_back('\xf7'); // fincstp
01575 
01576   AFTER_POP(v, i);
01577 }
01578 
01579 void CExp::Compile(std::vector<char>& v, int& i) const
01580 {
01581   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01582 
01583   m_pLeftOperand->Compile(v, i);
01584 
01585   // compute e^b
01586   // on stack => b
01587 
01588   BEFORE_PUSH(v, i);
01589 
01590   v.push_back('\xd9');
01591   v.push_back('\xea'); // fldl2e
01592   // on stack => log2(e) : b
01593 
01594   v.push_back('\xde');
01595   v.push_back('\xc9'); // fmulp
01596   // on stack => b*log2(e)
01597 
01598   v.push_back('\xd9');
01599   v.push_back('\xe8'); // fld1
01600   // on stack => 1 : b*log2(e)
01601 
01602   BEFORE_PUSH(v, i);
01603 
01604   v.push_back('\xd9');
01605   v.push_back('\xc1'); // fld     %st(1)
01606   // on stack => b*log2(e) : 1 : b*log2(e)
01607 
01608   v.push_back('\xd9');
01609   v.push_back('\xfc'); // frndint
01610   // on stack => int(b*log2(e)) : 1 : b*log2(e)
01611 
01612   v.push_back('\xd9');
01613   v.push_back('\xca'); // fxch    %st(2)
01614   // on stack => b*log2(e) : 1 : int(b*log2(e))
01615 
01616   v.push_back('\xd8');
01617   v.push_back('\xe2'); // fsub    %st(2),%st
01618   // on stack => frac(b*log2(e)) : 1 : int(b*log2(e))
01619 
01620   v.push_back('\xd9');
01621   v.push_back('\xf0'); // f2xm1
01622   // on stack => 2^frac(b*log2(e))-1 : 1 : int(b*log2(e))
01623 
01624   v.push_back('\xde');
01625   v.push_back('\xc1'); // faddp   %st,%st(1)
01626   // on stack => 2^frac(b*log2(e)) : int(b*log2(e))
01627 
01628   AFTER_POP(v, i);
01629 
01630   // 2^frac(b*log2(e))*2^int(b*log2(e))=2^(b*log2(e))=e^b
01631 
01632   v.push_back('\xd9');
01633   v.push_back('\xfd'); // fscale
01634   // on stack => e^b : int(b*log2(e))
01635 
01636   v.push_back('\xd9');
01637   v.push_back('\xc9'); // fxch
01638   // on stack => int(b*log2(e)) : e^b
01639 
01640 
01641   v.push_back('\xdd');
01642   v.push_back('\xc0'); // ffree  %st(0)
01643 
01644   v.push_back('\xd9');
01645   v.push_back('\xf7'); // fincstp
01646   // on stack => e^b
01647 
01648   AFTER_POP(v, i);
01649 }
01650 
01651 void CLn::Compile(std::vector<char>& v, int& i) const
01652 {
01653   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01654 
01655   m_pLeftOperand->Compile(v, i);
01656 
01657   // compute ln(x)
01658   // on stack => x
01659 
01660   BEFORE_PUSH(v, i);
01661 
01662   v.push_back('\xd9');
01663   v.push_back('\xe8'); // fld1
01664   // on stack => 1 : x
01665 
01666   BEFORE_PUSH(v, i);
01667 
01668   v.push_back('\xd9');
01669   v.push_back('\xea'); // fldl2e
01670   // on stack => log2(e) : 1 : x
01671 
01672   v.push_back('\xd9');
01673   v.push_back('\xca'); // fxch    %st(2)
01674   // on stack => x : 1 : log2(e)
01675 
01676   v.push_back('\xd9');
01677   v.push_back('\xf1'); // fyl2x
01678   // on stack => 1*log2(x) : log2(e)
01679 
01680   AFTER_POP(v, i);
01681 
01682   v.push_back('\xde');
01683   v.push_back('\xf1'); // fdivp
01684   // on stack => log2(x) / log2(e) = ln(x)
01685 
01686   AFTER_POP(v, i);
01687 }
01688 
01689 void CPow::Compile(std::vector<char>& v, int& i) const
01690 {
01691   POP_ASSERT(m_pLeftOperand != NULL, "Using a NULL pointer");
01692   POP_ASSERT(m_pRightOperand != NULL, "Using a NULL pointer");
01693 
01694   m_pLeftOperand->Compile(v, i);
01695   m_pRightOperand->Compile(v, i);
01696 
01697   // compute a^b
01698   // on stack => b : a
01699 
01700   bool entier = false;
01701   float exponent = 0;
01702   if (m_pRightOperand->IsConstant(&exponent))
01703     entier = (exponent == (int) exponent);
01704 
01705   if (entier)
01706     {
01707       v.push_back('\xdb');
01708       v.push_back('\x54');
01709       v.push_back('\x24');
01710       v.push_back('\xfc'); // fistl   -4(%esp)
01711 
01712       v.push_back('\xdd');
01713       v.push_back('\xc0'); // ffree   %st(0)
01714 
01715       v.push_back('\xd9');
01716       v.push_back('\xf7'); // fincstp
01717 
01718       v.push_back('\xd9');
01719       v.push_back('\xe8'); // fld1
01720 
01721       v.push_back('\xd9');
01722       v.push_back('\xc9'); // fxch
01723 
01724       v.push_back('\x8b');
01725       v.push_back('\x54');
01726       v.push_back('\x24');
01727       v.push_back('\xfc'); // movl    -4(%esp),%edx
01728 
01729       v.push_back('\x83');
01730       v.push_back('\xfa');
01731       v.push_back('\x00'); // cmpl    $0,%edx
01732 
01733       v.push_back('\x7f');
01734       v.push_back('\x04'); // jg      27
01735 
01736       v.push_back('\xf7');
01737       v.push_back('\xda'); // negl    %edx
01738 
01739       v.push_back('\xd8');
01740       v.push_back('\xf9'); // fdivr   %st(1),%st
01741 
01742       v.push_back('\xd1');
01743       v.push_back('\xea'); // shrl    $1,%edx
01744 
01745       v.push_back('\x73');
01746       v.push_back('\x02'); // jnc     38
01747 
01748       v.push_back('\xdc');
01749       v.push_back('\xc9'); // fmul    %st,%st(1)
01750 
01751       v.push_back('\x83');
01752       v.push_back('\xfa');
01753       v.push_back('\x00'); // cmpl    $0,%edx
01754 
01755       v.push_back('\x74');
01756       v.push_back('\x04'); // je      41
01757 
01758       v.push_back('\xd8');
01759       v.push_back('\xc8'); // fmul    %st(0),%st
01760 
01761       v.push_back('\xeb');
01762       v.push_back('\xf1'); // jmp     32
01763 
01764       v.push_back('\xdd');
01765       v.push_back('\xc0'); // ffree   %st(0)
01766 
01767       v.push_back('\xd9');
01768       v.push_back('\xf7'); // fincstp
01769     }
01770   else
01771     {
01772       v.push_back('\xd9');
01773       v.push_back('\xc9'); // fxch
01774       // on stack => a : b
01775 
01776       v.push_back('\xd9');
01777       v.push_back('\xf1'); // fyl2x
01778       // on stack => b*log2(a)
01779 
01780       v.push_back('\xd9');
01781       v.push_back('\xe8'); // fld1
01782       // on stack => 1 : b*log2(a)
01783 
01784       BEFORE_PUSH(v, i);
01785 
01786       v.push_back('\xd9');
01787       v.push_back('\xc1'); // fld     %st(1)
01788       // on stack => b*log2(a) : 1 : b*log2(a)
01789 
01790       v.push_back('\xd9');
01791       v.push_back('\xfc'); // frndint
01792       // on stack => int(b*log2(a)) : 1 : b*log2(a)
01793 
01794       v.push_back('\xd9');
01795       v.push_back('\xca'); // fxch    %st(2)
01796       // on stack => b*log2(a) : 1 : int(b*log2(a))
01797 
01798       v.push_back('\xd8');
01799       v.push_back('\xe2'); // fsub    %st(2),%st
01800       // on stack => frac(b*log2(a)) : 1 : int(b*log2(a))
01801 
01802       v.push_back('\xd9');
01803       v.push_back('\xf0'); // f2xm1
01804       // on stack => 2^frac(b*log2(a))-1 : 1 : int(b*log2(a))
01805 
01806       v.push_back('\xde');
01807       v.push_back('\xc1'); // faddp   %st,%st(1)
01808       // on stack => 2^frac(b*log2(a)) : int(b*log2(a))
01809 
01810       AFTER_POP(v, i);
01811 
01812       // 2^frac(b*log2(a))*2^int(b*log2(a))=2^(b*log2(a))=a^b
01813 
01814       v.push_back('\xd9');
01815       v.push_back('\xfd'); // fscale
01816       // on stack => a^b : int(b*log2(a))
01817 
01818       v.push_back('\xd9');
01819       v.push_back('\xc9'); // fxch
01820       // on stack => int(b*log2(a)) : a^b
01821 
01822 
01823       v.push_back('\xdd');
01824       v.push_back('\xc0'); // ffree  %st(0)
01825 
01826       v.push_back('\xd9');
01827       v.push_back('\xf7'); // fincstp
01828       // on stack => a^b
01829     }
01830 
01831   AFTER_POP(v, i);
01832 }
01833 
01834 void CVariable::Compile(std::vector<char>& v, int& i) const
01835 {
01836   BEFORE_PUSH(v, i);
01837 
01838   v.push_back('\xd9');
01839   v.push_back('\x40');
01840   v.push_back(m_Type*4); // flds 4*m_Type(%eax)
01841 }
01842 
01843 void CNumber::Compile(std::vector<char>& v, int& i) const
01844 {
01845   BEFORE_PUSH(v, i);
01846 
01847   v.push_back('\xd9');
01848   v.push_back('\x05');
01849 
01850   v.push_back((char)((int)&m_Number));
01851   v.push_back((char)((int)&m_Number >> 8));
01852   v.push_back((char)((int)&m_Number >> 16));
01853   v.push_back((char)((int)&m_Number >> 24)); // flds   &m_Number
01854 }
01855 
01856 

Generated on Fri Dec 5 03:20:33 2008 for Mathematical Ray-tracer by  doxygen 1.5.4