00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00031
00032
00033
00034
00035 #ifdef __GNUG__
00036 #pragma implementation "Function.cpp"
00037 #endif
00038
00039
00040 #include "mc/mcprec.h"
00041 #include <wx/filename.h>
00042 #ifdef __BORLANDC__
00043 #pragma hdrstop
00044 #endif
00045
00046 #ifndef mcPRECOMP
00047 #include <wx/textfile.h>
00048 #include <wx/gdicmn.h>
00049
00050
00051 #include "mc/MathCore.h"
00052 #include "mc/Function.h"
00053 #include "mc/Symbol.h"
00054 #include "mc/Number.h"
00055 #endif
00056
00057
00058 mcIMPLEMENT_MAIN_CLASS(mcFunction, mcExpElement);
00059
00060
00061
00062 int mcFunctionHelpers::sgui_nSpaceLeftRight = 0;
00063 int mcFunctionHelpers::sgui_nSpaceAboveBelow = 0;
00064
00065
00066
00067 #ifdef mcUSE_WXSCRIPT
00068 wxScriptFunctionArray mcFunction::arrFunctions(wxT("mc"));
00069 #else
00070 wxScriptFunctionArray mcFunction::arrFunctions;
00071 #endif
00072
00073
00074
00075
00076
00077 mcKey *mcFunctionHelpers::sgui_pNewFunction = NULL;
00078
00079
00080
00081
00082
00083
00084
00085
00086 int mcFunction::data_GetFunctionType(mcElement *s, int n)
00087 {
00088 wxString str;
00089
00090
00091
00092 for (int i=0; i < n; i++) {
00093 if (s[i].data_GetType() == mcET_SYMBOL) {
00094
00095
00096 str += mcSymbol(s[i]).data_GetSymbol();
00097
00098 } else {
00099
00100
00101 return mcFUNCTION_TYPE_NOTFOUND;
00102 }
00103 }
00104
00105
00106 return data_GetFunctionType(str);
00107 }
00108
00109 int mcFunction::data_GetFunctionType(const wxString &str)
00110 {
00111 #ifdef mcUSE_WXSCRIPT
00112
00113 for (int f=0; f < (int)arrFunctions.GetCount(); f++) {
00114
00115
00116
00117 wxString tmp = mcFunction::arrFunctions.GetName(f);
00118 if (str.Left(tmp.Len()) == tmp)
00119 return f;
00120 }
00121 #endif
00122
00123
00124 return mcFUNCTION_TYPE_NOTFOUND;
00125 }
00126
00127 bool mcFunction::LoadScriptFile(const wxString &name)
00128 {
00129 #ifdef mcUSE_WXSCRIPT
00130 wxScriptFile *f = NULL;
00131
00132
00133 if ((f = wxScriptInterpreter::Load(name)) == NULL)
00134 return FALSE;
00135
00136
00137 wxScriptFunctionArray arr;
00138 wxScriptInterpreter::GetTotalFunctionList(arr);
00139
00140
00141 wxString str = arrFunctions.GetPrefixToStrip();
00142 arrFunctions.DeepCopy(&arr);
00143 arrFunctions.SetPrefixToStrip(str);
00144
00145
00146 mcSAFE_DELETE(f);
00147
00148 return TRUE;
00149
00150 #else
00151
00152
00153 return FALSE;
00154 #endif
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 #ifdef __MCDEBUG__
00166
00167 wxString mcFunctionHelpers::data_BaseDebug(long flags) const
00168 {
00169 int n = mcMathCore::Get()->m_nIndentationStep;
00170
00171 return wxT("mcFunction [\n") +
00172 data_GetNameObj().data_GetDebug(n, flags) +
00173 data_GetArgObj().data_GetDebug(n, flags) +
00174 wxT("----------------------------------------- mcFunction ]");
00175 }
00176
00177 #endif
00178
00179 void mcFunctionHelpers::data_CreateSub()
00180 {
00181 data_DestroyExpSub(FALSE);
00182
00183 mcPolynomial mysub;
00184 mdata_pSub = mysub;
00185 mdata_pSub.gui_SetAsExpOf(this);
00186 }
00187
00188 void mcFunctionHelpers::data_SetFncType(int n)
00189 {
00190 mdata_nFncType = n;
00191
00192
00193 wxString newname;
00194
00195 if (n == mcFUNCTION_TYPE_NOTSET)
00196 newname = wxEmptyString;
00197 else
00198 #ifdef mcUSE_WXSCRIPT
00199 newname = mcFunction::arrFunctions.GetName(mdata_nFncType);
00200 #else
00201 newname = wxT("fnc");
00202 #endif
00203
00204
00205 data_SetName(newname);
00206 }
00207
00208 wxString mcFunctionHelpers::data_GetName() const
00209 {
00210
00211 wxString name = data_GetNameObj().data_GetText().RemoveLast();
00212 return name;
00213 }
00214
00215 void mcFunctionHelpers::data_CheckName()
00216 {
00217 #ifdef mcUSE_WXSCRIPT
00218 wxString ret = mcFunction::arrFunctions.GetName(mdata_nFncType);
00219
00220
00221 mcASSERT(ret == data_GetName(), wxT("hmmm, something wrong"));
00222 #endif
00223 }
00224
00225 wxScriptFunction *mcFunctionHelpers::data_GetScript() const
00226 {
00227 #ifdef mcUSE_WXSCRIPT
00228 return mcFunction::arrFunctions.Get(data_GetFncType());
00229 #else
00230 return NULL;
00231 #endif
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 void mcFunctionHelpers::gui_DoRecalcBaseSize()
00243 {
00244 data_GetNameObj().gui_RecalcSize();
00245 data_GetArgObj().gui_RecalcSize();
00246
00247
00248
00249 mgui_szBase.SetWidth(mcMAX(gui_GetNameOffsetx()+gui_GetSizeOfName().GetWidth(),
00250 gui_GetArgOffsetx()+gui_GetSizeOfArg().GetWidth()));
00251
00252
00253 mgui_szBase.SetHeight(mcMAX(gui_GetNameOffsety()+ gui_GetSizeOfName().GetHeight(),
00254 gui_GetArgOffsety()+gui_GetSizeOfArg().GetHeight()));
00255 }
00256
00257 mcInputRes mcFunctionHelpers::gui_BaseInput(const mcKey &key, mcElement *pnew)
00258 {
00259 mcInputRes res = mcIR_OKAY;
00260 int n;
00261
00262
00263 if (gui_isBeginKey(key) != FALSE &&
00264 !data_hasProperty(mcEP_INITIALIZED)) {
00265
00266
00267 Init();
00268
00269 return mcIR_OKAY;
00270 }
00271
00272 switch (mgui_nCursorPos) {
00273 case mcFUNCTION_INSIDENAME:
00274
00275
00276 if (gui_HandleSubExpEditKeys(key) == mcIR_OKAY)
00277 return mcIR_OKAY;
00278
00279 res = data_GetNameObj().gui_Input(key, pnew);
00280
00281
00282 n=mcFunction::data_GetFunctionType(data_GetName());
00283
00284
00285
00286
00287
00288
00289 if (n!=mcFUNCTION_TYPE_NOTFOUND &&
00290 mcFunction::arrFunctions.GetName(n) == data_GetName())
00291 data_SetFncType(n);
00292 else
00293 mdata_nFncType = -1;
00294
00295
00296 if (data_GetName().IsEmpty())
00297 res = mcIR_DELETE_THIS;
00298
00299
00300 switch (res) {
00301 case mcIR_OKAY:
00302 case mcIR_DELETE_PREVIOUS:
00303 break;
00304
00305 case mcIR_DELETE_NEXT:
00306 mcMathCore::Get()->SyntaxError(wxT("Cannot delete this bracket"));
00307 res = mcIR_OKAY;
00308 break;
00309
00310 case mcIR_DIRECT_DELETE:
00311 case mcIR_REPLACE_THIS:
00312 case mcIR_DELETE_THIS:
00313 return mcIR_DELETE_THIS;
00314 }
00315 break;
00316
00317 case mcFUNCTION_INSIDEARG:
00318 res = data_GetArgObj().gui_Input(key, pnew);
00319
00320
00321 if (res == mcIR_DISTRIBUTE)
00322 res = mcIR_DELETE_THIS;
00323 break;
00324
00325 default:
00326 mcASSERT(0, wxT("unhandled cursor pos"));
00327 }
00328
00329 gui_RecalcSize();
00330
00331 return res;
00332 }
00333
00334 int mcFunctionHelpers::gui_DrawBase(wxDC &hDC, int Offsetx, int Offsety,
00335 long flags, const wxPoint &pt) const
00336 {
00337 long fname=mcDRW_USEPOINT, farg=mcDRW_USEPOINT;
00338 wxPoint ptname = pt, ptarg = pt;
00339 int r = 0;
00340
00341
00342 wxPoint nameorg(Offsetx+gui_GetNameOffsetx(), Offsety+gui_GetNameOffsety());
00343 wxPoint argorg(Offsetx+gui_GetArgOffsetx(), Offsety+gui_GetArgOffsety());
00344
00345 if (flags & mcDRW_USEPOINT) {
00346
00347
00348 wxRect namerc(nameorg, gui_GetSizeOfName());
00349 wxRect argrc(argorg, gui_GetSizeOfArg());
00350
00351 if (namerc.Inside(pt)) {
00352
00353
00354
00355 farg = mcDRW_NONACTIVE;
00356 ptarg = wxDefaultPosition;
00357
00358 } else if (argrc.Inside(pt)) {
00359
00360 r = 1;
00361 ptname = wxDefaultPosition;
00362 fname = mcDRW_NONACTIVE;
00363 }
00364 }
00365
00366
00367
00368 bool breg = data_isRegistered();
00369 data_GetNameObj().gui_Draw(hDC, nameorg.x, nameorg.y,
00370 fname, 0, (breg ? NULL : wxRED));
00371
00372
00373 int r2 = data_GetArgObj().gui_Draw(hDC, argorg.x, argorg.y, farg, ptarg);
00374
00375
00376 return (r == 0 ? data_GetID() : r2);
00377 }
00378
00379 mcInsertRes mcFunctionHelpers::gui_BaseInsert(const mcElement &toinsert, mcElement *newelem)
00380 {
00381 return mcINSR_OKAY;
00382 }
00383
00384 mcMoveCursorRes mcFunctionHelpers::gui_BaseMoveCursor(mcMoveCursorFlag flag, long modifiers)
00385 {
00386 mcMoveCursorRes res;
00387
00388 switch (mgui_nCursorPos) {
00389 case mcFUNCTION_INSIDENAME:
00390 res = data_GetNameObj().gui_MoveCursor(flag, modifiers);
00391
00392 switch (res) {
00393 case mcMCR_OKAY:
00394 break;
00395
00396 case mcMCR_SETFOCUS_PREVIOUS:
00397 case mcMCR_SETFOCUS_ABOVE:
00398 case mcMCR_SETFOCUS_BELOW:
00399 return res;
00400
00401 case mcMCR_SETFOCUS_NEXT:
00402
00403 if (data_hasProperty(mcEP_HASEXPONENT))
00404 gui_EditExpSub(TRUE);
00405 else if (data_hasProperty(mcEP_HASSUBSCRIPT))
00406 gui_EditExpSub(FALSE);
00407 else {
00408
00409 mgui_nCursorPos = mcFUNCTION_INSIDEARG;
00410 data_GetArgObj().gui_SetCursorPos(mcCP_BEGIN);
00411 gui_BaseMoveCursor(mcMCF_RIGHT, modifiers);
00412 }
00413 break;
00414
00415 default:
00416 mcASSERT(0, wxT("unhandled cursor pos"));
00417 }
00418 break;
00419
00420
00421 case mcFUNCTION_INSIDEARG:
00422 res = data_GetArgObj().gui_MoveCursor(flag, modifiers);
00423
00424 switch (res) {
00425 case mcMCR_OKAY:
00426 break;
00427
00428 case mcMCR_SETFOCUS_NEXT:
00429 case mcMCR_SETFOCUS_ABOVE:
00430 case mcMCR_SETFOCUS_BELOW:
00431 return res;
00432
00433 case mcMCR_SETFOCUS_PREVIOUS:
00434 mcASSERT(0, wxT("the cursor should never be placed on the leftmost point ")
00435 wxT("of the bracket: see the end of this function"));
00436
00437
00438
00439
00440 break;
00441
00442 default:
00443 mcASSERT(0, wxT("unhandled cursor pos"));
00444 }
00445 break;
00446
00447 default:
00448 mcASSERT(0, wxT("unhandled cursor pos"));
00449 }
00450
00451
00452
00453 if (mgui_nCursorPos == mcFUNCTION_INSIDEARG &&
00454 data_GetArgObj().gui_GetCursorPos().isBegin()) {
00455
00456 if (data_hasProperty(mcEP_HASEXPONENT))
00457 gui_EditExpSub(TRUE);
00458 else if (data_hasProperty(mcEP_HASSUBSCRIPT))
00459 gui_EditExpSub(FALSE);
00460 else {
00461
00462 mgui_nCursorPos = mcFUNCTION_INSIDENAME;
00463 data_GetNameObj().gui_SetCursorPos(mcCP_END);
00464 }
00465 }
00466
00467 return mcMCR_OKAY;
00468 }
00469
00470 mcMoveCursorRes mcFunctionHelpers::gui_MoveCursor(mcMoveCursorFlag flag, long modifiers)
00471 {
00472 mcMoveCursorRes n = mcMCR_OKAY;
00473
00474 mcASSERT(mgui_bExpRight, wxT("A function should always have the exponent ")
00475 wxT("placed on the right of the function name"));
00476
00477 if (gui_isCursorInExpSub(TRUE)) {
00478
00479 n = gui_ExpSubMoveCursor(TRUE, flag, modifiers);
00480
00481 } else if (gui_isCursorInExpSub(FALSE)) {
00482
00483 n = gui_ExpSubMoveCursor(FALSE, flag, modifiers);
00484
00485 } else if (gui_isCursorInBase()) {
00486
00487 mcMoveCursorRes r = gui_BaseMoveCursor(flag, modifiers);
00488
00489 switch (r) {
00490 case mcMCR_SETFOCUS_NEXT:
00491 case mcMCR_SETFOCUS_PREVIOUS:
00492 case mcMCR_CANNOT_SETFOCUS:
00493 case mcMCR_OKAY:
00494 return r;
00495
00496 case mcMCR_SETFOCUS_BELOW:
00497
00498
00499 if (data_hasProperty(mcEP_HASSUBSCRIPT))
00500 gui_EditExpSub(FALSE);
00501 else
00502 return mcMCR_SETFOCUS_BELOW;
00503 break;
00504
00505 case mcMCR_SETFOCUS_ABOVE:
00506
00507
00508 if (data_hasProperty(mcEP_HASEXPONENT))
00509 gui_EditExpSub(TRUE);
00510 else
00511 return mcMCR_SETFOCUS_ABOVE;
00512 break;
00513 }
00514 }
00515
00516 return n;
00517 }
00518
00519 int mcFunctionHelpers::gui_BaseMoveCursorUsingPoint(wxDC &dc, const wxPoint &pt)
00520 {
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 return mcMCR_CANNOT_SETFOCUS;
00544 }
00545
00546 int mcFunctionHelpers::gui_GetBaseRelCursorPos(wxDC &hDC, wxPoint *pt) const
00547 {
00548 int res = 0;
00549
00550 switch (mgui_nCursorPos) {
00551 case mcFUNCTION_INSIDENAME:
00552 res = data_GetNameObj().gui_GetRelCursorPos(hDC, pt);
00553 pt->x += gui_GetNameOffsetx();
00554 pt->y += gui_GetNameOffsety();
00555 break;
00556
00557 case mcFUNCTION_INSIDEARG:
00558 res = data_GetArgObj().gui_GetRelCursorPos(hDC, pt);
00559 pt->x += gui_GetArgOffsetx();
00560 pt->y += gui_GetArgOffsety();
00561 break;
00562
00563 default:
00564 mcASSERT(0, wxT("unhandled cursor pos"));
00565 }
00566
00567 return res;
00568 }
00569
00570 void mcFunctionHelpers::gui_GetBaseCursorPos(mcCursorPos &cp) const
00571 {
00572 if (mgui_nCursorPos == mcFUNCTION_INSIDENAME &&
00573 data_GetNameObj().gui_GetCursorPos().isBegin()) {
00574 cp.gui_Push(mcCP_BEGIN);
00575 return;
00576 }
00577
00578
00579 if (mgui_nCursorPos == mcFUNCTION_INSIDEARG &&
00580 data_GetArgObj().gui_GetCursorPos().isEnd()) {
00581 cp.gui_Push(mcCP_END);
00582 return;
00583 }
00584
00585 cp.gui_Push(mgui_nCursorPos);
00586 }
00587
00588 void mcFunctionHelpers::gui_EditBase()
00589 {
00590
00591 mgui_nCursorPos = mcFUNCTION_INSIDENAME;
00592 mgui_nCursorLoc = mcECL_INSIDEBASE;
00593 }
00594
00595 void mcFunctionHelpers::gui_EditBaseAndSetPos(const mcCursorPos &cp)
00596 {
00597 gui_EditBase();
00598 data_GetNameObj().gui_SetCursorPos(cp);
00599 }
00600
00601 void mcFunctionHelpers::gui_SetCursorPos(const mcCursorPos &code)
00602 {
00603 if (code.isBegin()) {
00604
00605
00606
00607 mgui_nCursorPos = mcFUNCTION_INSIDENAME;
00608 data_GetNameObj().gui_SetCursorPos(mcCP_BEGIN);
00609
00610 } else {
00611
00612
00613
00614 mgui_nCursorPos = mcFUNCTION_INSIDEARG;
00615 data_GetArgObj().gui_SetCursorPos(mcCP_END);
00616 }
00617 }
00618
00619 void mcFunctionHelpers::gui_Setup(int fnc)
00620 {
00621 data_SetFncType(fnc);
00622
00623
00624
00625
00626
00627
00628 data_GetArgObj().data_GetContent().gui_AddNewEmptyMonomial();
00629
00630
00631 mcASSERT(mcFunction::arrFunctions.GetCount() != 0, wxT("No function registered ?!?"));
00632 data_SetFncType(0);
00633
00634 data_AddProperty(mcEP_INITIALIZED);
00635 gui_RecalcSize();
00636 }
00637
00638 wxSize mcFunctionHelpers::gui_GetSizeOfArg() const
00639 { return data_GetArgObj().gui_GetSize(); }
00640
00641 wxSize mcFunctionHelpers::gui_GetSizeOfName() const
00642 { return data_GetNameObj().gui_GetSize(); }
00643
00644
00645
00646
00647
00648
00649 int mcFunctionHelpers::gui_GetArgOffsetx() const
00650 { return mcMAX(gui_GetExpSubOffsetx(TRUE)+gui_GetExpSubSize(TRUE).GetWidth(),
00651 gui_GetExpSubOffsetx(FALSE)+gui_GetExpSubSize(FALSE).GetWidth()); }
00652
00653 int mcFunctionHelpers::gui_GetArgOffsety() const
00654 { return 0; }
00655
00656
00657
00658
00659
00660
00661 int mcFunctionHelpers::gui_GetNameOffsetx() const
00662 { return 0; }
00663
00664 int mcFunctionHelpers::gui_GetNameOffsety() const
00665 { return (gui_GetBaseSize().GetHeight() - gui_GetSizeOfName().GetHeight())/2; }
00666
00667
00668
00669
00670
00671 int mcFunctionHelpers::gui_GetExpOffsetx() const
00672 { return gui_GetSizeOfName().GetWidth(); }
00673
00674 int mcFunctionHelpers::gui_GetExpOffsety() const
00675 { return gui_GetNameOffsety(); }
00676
00677
00678
00679
00680
00681
00682 int mcFunctionHelpers::gui_GetSubOffsetx() const
00683 { return gui_GetExpOffsetx(); }
00684
00685 int mcFunctionHelpers::gui_GetSubOffsety() const
00686 { return gui_GetNameOffsety()+gui_GetSizeOfName().GetHeight(); }
00687
00688
00689
00690 #define HANDLE_EXPSUB() \
00691 switch (r) { \
00692 case mcMCR_SETFOCUS_NEXT: \
00693 mgui_nCursorPos = mcFUNCTION_INSIDEARG; \
00694 data_GetArgObj().gui_SetCursorPos(mcCP_BEGIN); \
00695 gui_BaseMoveCursor(mcMCF_RIGHT, modifiers); \
00696 break; \
00697 \
00698 case mcMCR_SETFOCUS_PREVIOUS: \
00699 gui_EditBaseAndSetPos(mcCP_END); \
00700 break; \
00701 \
00702 case mcMCR_SETFOCUS_BELOW: \
00703 gui_EditBase(); \
00704 break; \
00705 \
00706 case mcMCR_SETFOCUS_ABOVE: \
00707 return mcMCR_SETFOCUS_ABOVE; \
00708 }
00709
00710 mcMoveCursorRes mcFunctionHelpers::gui_ExpMoveCursor(mcMoveCursorFlag flag, long modifiers)
00711 {
00712 if (mgui_nCursorPos == mcECL_INSIDEEXPONENT) {
00713
00714
00715
00716 int r = data_GetExp().gui_MoveCursor(flag, modifiers);
00717
00718 HANDLE_EXPSUB();
00719
00720 } else {
00721
00722
00723 mcASSERT(0, wxT("In a mcFunction, the cursor can be only placed on the base ")
00724 wxT("or _inside_ the exponent; never at the begin/end of the exp/sub"));
00725 }
00726
00727 return mcMCR_OKAY;
00728 }
00729
00730
00731 void mcFunctionHelpers::gui_CheckSub()
00732 {
00733 mcPolynomial p = data_GetSub();
00734 if (p.data_isArrayEmpty())
00735 p.gui_AddNewEmptyMonomial();
00736 }
00737
00738 mcMoveCursorRes mcFunctionHelpers::gui_SubMoveCursor(mcMoveCursorFlag flag, long modifiers)
00739 {
00740 if (mgui_nCursorPos == mcECL_INSIDESUBSCRIPT) {
00741
00742
00743
00744 int r = data_GetSub().gui_MoveCursor(flag, modifiers);
00745
00746 HANDLE_EXPSUB();
00747
00748 } else {
00749
00750 mcASSERT(0, wxT("In a mcFunction, the cursor can be only placed on the base ")
00751 wxT("or _inside_ the subscript; never at the begin/end of the exp/sub"));
00752 }
00753
00754 return mcMCR_OKAY;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 bool mcFunctionHelpers::io_isBeginChar(const wxString &str) const
00766 {
00767
00768 return io_isFunctionBeginChar(str);
00769 }
00770
00771 bool mcFunctionHelpers::io_isFunctionBeginChar(const wxString &str)
00772 {
00773 int n = mcFunction::data_GetFunctionType(str);
00774 if (n != -1) {
00775
00776
00777
00778 #ifdef mcUSE_WXSCRIPT
00779 int len = mcFunction::arrFunctions.GetName(n).Len();
00780 #else
00781 int len = 0;
00782 #endif
00783
00784 wxString br = str.Right(str.Len()-len);
00785 for (int i=0; i < (int)br.Len(); i++)
00786 if (mcBracketHelpers::io_isBracketBeginChar(br.GetChar(i)))
00787 return TRUE;
00788 return FALSE;
00789 }
00790
00791 return FALSE;
00792 }
00793
00794 wxXml2Node mcFunctionHelpers::io_GetBaseMathML(bool bGetPresentation) const
00795 {
00796
00797
00798 wxXml2Node n = data_GetNameObj().io_GetMathML(bGetPresentation);
00799
00800
00801 n.SetName(wxT("mi"));
00802 return n;
00803 }
00804
00805 wxXml2Node mcFunctionHelpers::io_GetMathML(bool bGetPresentation) const
00806 {
00807 wxXml2Node maintag(wxXML_ELEMENT_NODE, wxXml2EmptyDoc, wxT("mrow"));
00808 wxXml2Node op(wxXML_TEXT_NODE, wxXml2EmptyDoc, wxT("mo"), wxT("⁡"));
00809 wxXml2Node exptag(mcExpElementHelpers::io_GetMathML(bGetPresentation));
00810 wxXml2Node arg(data_GetArgObj().io_GetMathML(bGetPresentation));
00811
00812
00813
00814 maintag.AddChild(exptag);
00815
00816
00817 maintag.AddChild(op);
00818
00819
00820 maintag.AddChild(arg);
00821
00822 return maintag;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 wxString mcFunctionHelpers::io_GetBaseInlinedExpr() const
00846 {
00847
00848 wxString str = data_GetNameObj().io_GetInlinedExpr();
00849 str += data_GetArgObj().io_GetInlinedExpr();
00850
00851
00852 if (data_hasProperty(mcEP_HASSUBSCRIPT)) {
00853
00854 str.RemoveLast();
00855 str += wxT(", ") + data_GetSub().io_GetInlinedExpr();
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 if (data_hasProperty(mcEP_HASEXPONENT)) {
00867
00868 str.Prepend(wxT("("));
00869 str.Append(wxT(")"));
00870 }
00871
00872 return str;
00873 }
00874
00875 bool mcFunctionHelpers::io_ImportPresentationMathML(wxXml2Node tag, wxString &pErr)
00876 {
00877 mcASSERT(0, wxT(""));
00878 return TRUE;
00879 }
00880
00881 void mcFunctionHelpers::io_GetExpSubInlinedToken(wxString &subexp)
00882 {
00883
00884
00885
00886
00887
00888
00889 subexp = subexp.BeforeFirst(wxT('+'));
00890 subexp = subexp.BeforeFirst(wxT('-'));
00891 subexp = subexp.BeforeFirst(wxT('('));
00892 return;
00893 }
00894
00895 wxArrayString mcFunctionHelpers::io_ImportArgument(const wxString &arg, int *count, wxString &pErr)
00896 {
00897 wxArrayString argarr;
00898
00899
00900 if (!mcBracketHelpers::gui_isLeftParenthesis(arg.GetChar(0))) {
00901
00902
00903 pErr = wxT("a left parenthesis should be placed here");
00904 return argarr;
00905 }
00906
00907 int i, nestlevel=0, begin=1;
00908 for (i=0; i < (int)arg.Len(); i++) {
00909
00910
00911 if (mcBracketHelpers::gui_isLeftParenthesis(arg.GetChar(i))) nestlevel++;
00912 if (mcBracketHelpers::gui_isRightParenthesis(arg.GetChar(i))) nestlevel--;
00913
00914 if (arg.GetChar(i) == wxT(',')) {
00915
00916 argarr.Add(arg.Mid(begin, i-begin));
00917 begin = i+1;
00918 }
00919
00920 if (nestlevel == 0) { i++; break; }
00921 }
00922
00923
00924 argarr.Add(arg.Mid(begin, i-1-begin));
00925 *count = i;
00926
00927 return argarr;
00928 }
00929
00930 bool mcFunctionHelpers::io_ImportInlinedExpr(const wxString &str, int *count, wxString &pErr)
00931 {
00932
00933 data_SetFncType(mcFunction::data_GetFunctionType(str));
00934 int n = data_GetFncType();
00935 mcASSERT(n != -1, wxT("Error in mcFunctionHelpers::io_isBeginChar"));
00936
00937
00938 wxString arg = str.Right(str.Len()-data_GetName().Len());
00939 wxString subexp(arg);
00940 io_GetExpSubInlinedToken(subexp);
00941 arg.Remove(0, subexp.Len());
00942
00943
00944 wxArrayString args = io_ImportArgument(arg, count, pErr);
00945 if (args.IsEmpty()) return FALSE;
00946
00947
00948 arg = args[0];
00949 arg = wxT("(") + arg + wxT(")");
00950
00951
00952 *count = data_GetName().Len()+subexp.Len()+arg.Len();
00953
00954
00955 if (!data_GetArgObj().io_ImportInlinedExpr(arg, &n, pErr))
00956 return FALSE;
00957 mcASSERT((int)arg.Len() == n,
00958 wxT("The argument has not been completely imported..."));
00959
00960
00961 bool bexp = (subexp.GetChar(0) == wxT('^'));
00962 bool bsub = (subexp.GetChar(0) == wxT('_'));
00963 wxString toimport(subexp);
00964 toimport.Remove(0, 1);
00965 n = 0;
00966
00967
00968 if (bexp) {
00969
00970
00971
00972 data_CreateExpSub(TRUE);
00973
00974 if (!data_GetExp().io_ImportInlinedExpr(toimport, &n, pErr))
00975 return FALSE;
00976 }
00977
00978
00979 if (bsub) {
00980
00981
00982
00983 data_CreateExpSub(FALSE);
00984
00985 if (!data_GetSub().io_ImportInlinedExpr(toimport, &n, pErr))
00986 return FALSE;
00987 }
00988
00989 mcASSERT((int)toimport.Len() == n,
00990 wxT("Exp/sub has not been completely imported..."));
00991
00992
00993 io_PostProcessChildren();
00994
00995
00996 mcIOLOG(wxT("mcFunctionHelpers::io_ImportInlinedExpr [%s]"), mcTXTTHIS);
00997 return TRUE;
00998 }
00999
01000
01001
01002
01003
01004
01005
01006
01007 mcRealValue mcFunctionHelpers::math_EvaluateBase() const
01008 {
01009 mcRealValue arg = data_GetArgObj().math_Evaluate();
01010
01011
01012 if (!arg.isValid())
01013 return *mcRealValue::pNAN;
01014
01015 #ifdef mcUSE_WXSCRIPT
01016 wxScriptVar returnvalue, argument;
01017 argument.Set(wxSTG_DOUBLE, arg.GetDouble());
01018 if (!data_GetScript()->Exec(returnvalue, &argument))
01019 return *mcRealValue::pNAN;
01020
01021 return returnvalue.GetContentDouble();
01022
01023 #else
01024
01025 return *mcRealValue::pNAN;
01026
01027 #endif
01028 }
01029
01030 mcExpSimRes mcFunctionHelpers::math_SimplifyBase(long flags, mcElement *pnew)
01031 {
01032 mcExpSimRes r = data_GetArgObj().math_Simplify(flags, pnew);
01033 if (r != mcESR_DONE) return r;
01034
01035
01036
01037 if (data_GetArgObj().math_isConstant()) {
01038
01039
01040 mcRealValue val = math_Evaluate();
01041 if (val == *mcRealValue::pNAN)
01042 return mcESR_DONE;
01043
01044 mcNumber replacement(val);
01045 (*pnew) = replacement;
01046 return mcESR_REPLACE_THIS;
01047 }
01048
01049 return mcESR_DONE;
01050 }
01051
01052 mcExpSimRes mcFunctionHelpers::math_ExpandBase(long flags, mcElement *pnew)
01053 {
01054
01055 return data_GetArgObj().math_Expand(flags, pnew);
01056
01057 }
01058
01059 mcMathType mcFunctionHelpers::math_GetBaseMathType() const
01060 {
01061
01062
01063 mcMathType res = data_GetArgObj().math_GetMathType();;
01064
01065
01066 return res;
01067 }
01068
01069
01070